VITALIFY.ASIA logo

PLATEAU × ODPT: Những bài học khi kết hợp dữ liệu 3D thành phố và tàu thời gian thực trên Cesium

Bài viết chia sẻ kinh nghiệm tích hợp mô hình đô thị 3D PLATEAU với dữ liệu tàu ODPT trên Cesium. Từ hệ tọa độ, 3D Tiles, LOD và schema thiếu ổn định đến suy luận tuyến, nội suy vị trí, OSM và bảo mật API, bài viết làm rõ đâu là dữ liệu thật, đâu là dữ liệu suy luận trong bản đồ 3D realtime.

Thinh Tran
PLATEAU × ODPT: Những bài học khi kết hợp dữ liệu 3D thành phố và tàu thời gian thực trên Cesium
Nội dung bài viết

Khi xây dựng demo bản đồ 3D Nhật Bản với Cesium, việc kết hợp PLATEAU — dữ liệu mô hình 3D thành phố của MLIT — và ODPT — dữ liệu giao thông công cộng, bao gồm vị trí tàu theo thời gian thực — thoạt nhìn có vẻ khá đơn giản.

Một bên cung cấp thành phố 3D, một bên cung cấp tàu đang chạy. Chỉ cần đặt hai nguồn dữ liệu lên cùng một bản đồ là xong?

Thực tế không đơn giản như vậy.

Cả PLATEAU và ODPT đều là những nguồn dữ liệu mở rất hữu ích, nhưng mỗi nguồn lại có những giới hạn riêng về coordinate system, schema, độ ổn định của dữ liệu, hiệu năng và khả năng liên kết giữa các dataset.

Trong quá trình phát triển demo cesium-plateau, chúng tôi đã gặp khá nhiều vấn đề thú vị. Một số vấn đề có thể giải quyết bằng code, nhưng một số khác buộc phải chấp nhận một mức độ sai số nhất định và thiết kế hệ thống theo hướng best-effort.

Bài viết này tổng hợp những vấn đề quan trọng nhất và cách project xử lý chúng.

0:00
/1:04

1. PLATEAU 3D Tiles: Thành phố 3D không chỉ đơn giản là load một tileset

PLATEAU cung cấp building và bridge dưới dạng 3D Tiles, có thể stream trực tiếp thông qua tileset.json mà không cần backend riêng hoặc Cesium ion token.

Điều này rất thuận tiện, nhưng khi đưa dữ liệu vào Cesium, một số vấn đề bắt đầu xuất hiện.


2. Tại sao building lại "lơ lửng" trên mặt đất?

Một trong những vấn đề đầu tiên dễ nhận thấy là một số tòa nhà có khoảng hở vài chục mét so với mặt đất.

Nguyên nhân nằm ở sự khác biệt giữa hệ quy chiếu độ cao.

PLATEAU sử dụng độ cao dựa trên geoid JGD2011, trong khi Cesium đặt tileset dựa trên ellipsoid WGS84.

Khi nhìn thẳng từ trên xuống, khoảng hở này có thể khó nhận ra. Nhưng chỉ cần nghiêng camera, khoảng trống giữa building và mặt đường sẽ trở nên rất rõ.

Không có một giá trị offset chính xác cho mọi nơi

Một cách đơn giản là cộng hoặc trừ một giá trị cố định vào height của toàn bộ tileset.

Tuy nhiên, geoid–ellipsoid separation thay đổi theo từng khu vực. Vì vậy, không tồn tại một giá trị offset duy nhất có thể áp dụng chính xác cho toàn bộ Tokyo.

Project chọn cách dịch toàn bộ tileset theo phương pháp tuyến tại tâm bounding sphere, thay vì đơn giản thay đổi global Z-axis.

Giá trị offset được điều chỉnh runtime thông qua setHeightOffset.

Điều này cho phép tinh chỉnh vị trí building theo từng khu vực mà không cần hard-code một giá trị cố định.


3. Đừng lưu trực tiếp URL asset của PLATEAU

Một vấn đề khác ít rõ ràng hơn xuất hiện khi làm việc với URL của dataset.

Mỗi khi MLIT re-process lại dữ liệu của một ward, asset path hoặc hash trên CDN có thể thay đổi.

Nếu application lưu trực tiếp URL asset hiện tại, URL đó có thể trở thành 404 sau lần refresh dataset tiếp theo.

Giải pháp: dùng datacatalog endpoint

Thay vì lưu URL CDN trực tiếp, project sử dụng endpoint ổn định của MLIT:

datacatalog/3dtiles/<ward>-bldg-lod2-...

Endpoint này hoạt động như một lớp index để resolve tới tileset.json thực tế.

Đổi lại, mỗi ward phải thực hiện thêm một network request nhỏ, nhưng đổi lấy lợi ích quan trọng hơn: link tới dataset không bị chết khi MLIT re-process dữ liệu.


4. Texture đẹp nhưng không phải lúc nào cũng tốt

PLATEAU có các phiên bản LOD2 có texture ảnh thật.

Nhìn rất đẹp khi zoom gần.

Nhưng khi zoom out, hiệu năng bắt đầu trở thành vấn đề.

Một tile có texture có thể lớn hơn phiên bản không texture từ khoảng 3–10 lần. Trong một số trường hợp, kích thước mỗi tile lên tới vài MB.

Khi zoom ra xa, Cesium có thể phải tải hơn 100 tile cùng lúc.

Điểm nghẽn lúc này không nhất thiết là số lượng request đồng thời mà là băng thông cần thiết để tải dữ liệu.

Vì sao project chọn lod2-notexture?

Project chấp nhận bỏ texture ảnh thật để đổi lấy tốc độ ổn định hơn.

Building được tô màu lại bằng 3D Tiles Style, dựa trên những thuộc tính như:

  • Height
  • Usage
  • Flood risk

Điều này đặc biệt phù hợp với các visualization cần phân tích dữ liệu hơn là chỉ hiển thị thành phố đẹp mắt.


5. Bridge không giống Building

PLATEAU không tổ chức bridge giống building.

Building sử dụng scheme bldg, trong khi bridge sử dụng brid.

Ngoài ra, bridge không có phiên bản notexture nhẹ tương ứng.

Đáng chú ý hơn, không phải cả 23 ward đều có dữ liệu bridge. Khoảng một phần ba số ward không có bridge dataset.

Vì vậy, việc một bridge tileset rỗng không nên được xem là lỗi.

Project xử lý bridge như một layer độc lập:

  • Buildings
  •     └── Building Tileset
  • Bridges
  •     └── Bridge Tileset

setBridgesVisible cũng được tách riêng khỏi building.

Ward không có bridge được coi là trạng thái bình thường thay vì retry request hoặc hiển thị warning.


6. Một field undefined có thể crash toàn bộ render loop

Một trong những lỗi khó chịu nhất đến từ 3D Tiles Style.

Ví dụ field:

  • bldg:measuredHeight

không thể sử dụng trực tiếp với shorthand ${...} vì tên field chứa dấu “:”.

Thay vào đó cần sử dụng:

  • ${feature['bldg:measuredHeight']}

Nhưng đó vẫn chưa phải vấn đề lớn nhất.

Một số feature có thể không có field này. Nếu expression thực hiện phép so sánh như:

  • height >= 100

với một giá trị undefined, Cesium có thể ném RuntimeError.

Điều nguy hiểm là đây không chỉ là lỗi của một feature.

Nó có thể làm crash toàn bộ render loop.

Giải pháp

Ép kiểu trước khi so sánh:

  • Number(${feature['bldg:measuredHeight']})

Number(undefined) tạo ra NaN.

Khi đó phép so sánh trả về false, và feature sẽ rơi xuống nhánh màu mặc định thay vì làm hỏng toàn bộ scene.

Đây là một nguyên tắc khá quan trọng khi viết Cesium style:

Đừng giả định rằng mọi feature đều có đầy đủ property.


7. PLATEAU không phải lúc nào cũng trả về enum

Một ví dụ khác là:

  • bldg:usage

Có thể trả về trực tiếp label tiếng Nhật như:

  • 業務施設
  • 商業施設

thay vì một enum code cố định.

Ngoài ra, không có danh sách đầy đủ tất cả giá trị có thể xuất hiện.

Vì vậy, project không cố giả định rằng mapping hiện tại là hoàn chỉnh.

Thay vào đó:

  • Known value
  •     ↓
  • Matched category
  •     ↓
  • Category color
  • Unknown value
  •     ↓
  • Neutral fallback color

Một giá trị chưa biết được xem là chưa phân loại, thay vì coi đó là lỗi.


8. Flood risk: Một con sông, một field?

Đây là một trong những ví dụ thú vị nhất về vấn đề schema.

PLATEAU có các field hazard liên quan tới từng hệ thống sông. Tên field có thể thay đổi tùy khu vực.

Chỉ trong hai ward đã quan sát được tới 7 tên field khác nhau.

Nếu application chọn một field cụ thể của một con sông, nó có thể vô tình hiển thị "an toàn" ở một ward khác đơn giản vì con sông đó không chảy qua khu vực đó.

Trade-off

Project quyết định sử dụng một field về storm surge có tên nhất quán giữa các ward.

Điều này không đại diện cho toàn bộ các kịch bản ngập lụt từ sông, nhưng đổi lại application có một property nhất quán trên toàn bộ khu vực.

Đây là một trade-off quan trọng:

Một dataset nhất quán nhưng phạm vi hẹp đôi khi hữu ích hơn một dataset rộng nhưng schema không ổn định.


9. Load và unload ward theo khoảng cách

Tokyo có 23 ward. Nếu load toàn bộ building tileset cùng lúc, application sẽ phải xử lý một lượng dữ liệu rất lớn.

Project sử dụng ba thông số:

  • LOAD_DISTANCE_METERS
  • UNLOAD_DISTANCE_METERS
  • MAX_ACTIVE_WARDS

Ban đầu, khoảng cách được tính dựa trên vị trí 3D đầy đủ của camera.

Nhưng cách này tạo ra một vấn đề.

Ở Home view, camera có thể cao khoảng 1200m, khiến khoảng cách tới ward vượt threshold ngay lập tức. Kết quả là không ward nào được load.

Giải pháp

Khoảng cách chỉ được tính dựa trên projection của camera xuống mặt đất, bỏ qua độ cao camera.

Project cũng sử dụng hysteresis:

  • Load:   2500m
  • Unload: 4500m

Nếu chỉ sử dụng một threshold duy nhất, camera di chuyển qua lại quanh boundary có thể khiến tileset liên tục:

  • Load → Unload → Load → Unload

Hai threshold khác nhau giúp tránh tình trạng này.

Ngoài ra:

  • MAX_ACTIVE_WARDS = 5

đảm bảo số ward đang active luôn được giới hạn.

Nếu vượt quá giới hạn, ward ở xa nhất sẽ bị unload.


10. Cesium 60 FPS không phải lúc nào cũng cần thiết

Một scene Cesium gần như đứng yên vẫn có thể render liên tục ở 60 FPS.

Điều này có nghĩa GPU vẫn hoạt động liên tục dù camera không thay đổi.

Project sử dụng:

  • requestRenderMode: true

để chỉ render lại khi scene thực sự có thay đổi.

Ngoài ra:

  • maximumScreenSpaceError: 24
  • skipLevelOfDetail
  • cullRequestsWhileMoving

được sử dụng để giảm lượng dữ liệu và request không cần thiết.

Một thử nghiệm khác là dynamicScreenSpaceError.

Tuy nhiên, trong view gần và gần như thẳng đứng, nó tạo ra hiện tượng LOD nhấp nháy ngay cả khi camera đứng yên.

Vì vậy, project chọn maximumScreenSpaceError cố định thay vì dynamic.


11. ODPT: Có realtime data không có nghĩa là mọi thứ đều realtime

Sau khi xử lý PLATEAU, phần khó tiếp theo là ODPT.

ODPT cung cấp dữ liệu về:

  • Train position
  • Stations
  • Railway
  • Timetable

Trong project, ODPT và Overpass được proxy thông qua backend để bảo vệ consumer key.


12. GTFS-Realtime không cho biết trực tiếp train đang chạy tuyến nào

Đây là một trong những giới hạn lớn nhất của dữ liệu realtime.

Trong GTFS-Realtime feed của JR East, TripDescriptor có tripId, nhưng không có routeId.

Project thử join tripId với catalog odpt:Train, nhưng kết quả là:

0/415 tripId match với trainNumber.

Có nghĩa hai hệ thống ID không thể join trực tiếp.

Vì vậy không thể chắc chắn rằng:

"Train này đang chạy tuyến X."

Giải pháp: suy luận từ vị trí

Project sử dụng vị trí tàu và tìm railway polyline gần nhất trong khoảng 330m.

Kết quả được xem là:

best-effort route inference

Thay vì giả vờ rằng đây là dữ liệu chính xác tuyệt đối.

Đây là một điểm quan trọng khi xây dựng hệ thống visualization từ open data:

Khi source data không cung cấp thông tin trực tiếp, hãy nói rõ đâu là dữ liệu thật và đâu là dữ liệu suy luận.


13. 5 operator nhưng chỉ JR East có train realtime

ODPT có dữ liệu cho nhiều operator:

  • JR East
  • Tokyo Metro
  • Toei
  • Yurikamome
  • Rinkai

Tuy nhiên, trong Challenge 2026, chỉ feed GTFS-Realtime của JR East còn hoạt động.

Các feed của bốn operator còn lại trả về 404.

Điều đó dẫn tới một thiết kế khá rõ ràng:

  • Stations / Railway
  •     ├── JR East
  •     ├── Tokyo Metro
  •     ├── Toei
  •     ├── Yurikamome
  •     └── Rinkai
  • Realtime Train Animation
  •     └── JR East

Không cố retry những endpoint không tồn tại giúp giảm request không cần thiết và tránh tạo cảm giác rằng application đang gặp lỗi.


14. Poll mỗi 20 giây nhưng tàu chỉ đổi vị trí mỗi 40–90 giây

Đây là một ví dụ điển hình về sự khác biệt giữa API polling frequency và data update frequency.

Client poll feed mỗi 20 giây.

Nhưng khi theo dõi cùng một vehicle ID, phần lớn response trả về cùng tọa độ như lần trước.

Vị trí thật của tàu thường chỉ thay đổi sau khoảng:

40–90 giây.

Nếu mỗi lần nhận dữ liệu mới lại snap marker trực tiếp tới vị trí mới, animation sẽ giống:

  • ●──────────────●
  • ^              ^
  • old            new

Tàu đứng yên khá lâu rồi đột nhiên teleport.

Client-side interpolation

Project nội suy giữa vị trí cũ và mới.

Feed được cập nhật theo chu kỳ khoảng 20 giây, trong khi animation tick chạy mỗi 300ms.

Nhờ vậy:

  • Server
  • old position ───────── new position
  • Client
  •      smooth interpolation
  • ●──●──●──●──●──●──●──●

Tàu chuyển động mượt hơn dù dữ liệu nguồn cập nhật khá thưa.


15. ODPT có thứ tự ga, nhưng không có hình dạng đường ray

ODPT cung cấp stationOrder và tọa độ của các station.

Cách đơn giản nhất là nối:

  • Station A ───────── Station B

Nhưng railway thật không chạy theo đường thẳng.

Nếu chỉ nối hai điểm, đường ray có thể:

  • xuyên qua building
  • xuyên qua đường phố
  • đi sai hướng ở các đoạn cong

Kết hợp ODPT với OpenStreetMap

Project sử dụng Overpass để lấy các OSM way có:

  • railway=rail

Sau đó xây dựng một railway graph.

Giữa từng cặp station liên tiếp, thuật toán tìm đường ngắn nhất trên graph để lấy ra railway polyline gần với hình dạng thực tế.

Như vậy:

  • ODPT
  • Station A ───── Station B
  •      │              │
  •      ↓              ↓
  •         OSM Railway Graph
  •               ↓
  •        Realistic Railway Path

Đây là ví dụ điển hình về việc một nguồn dữ liệu cung cấp semantic information, trong khi nguồn khác cung cấp geometry.

Kết hợp hai nguồn giúp tạo ra kết quả tốt hơn nhiều so với việc sử dụng riêng từng nguồn.


16. Nhưng shortest path vẫn có thể chọn nhầm đường ray

Tokyo có rất nhiều railway chạy song song.

Ví dụ:

  • Yamanote
  • Chuo-Sobu Local
  • Keihin-Tohoku

Một station có thể nằm gần nhiều railway node.

Nếu chỉ:

  1. Snap station A vào node gần nhất
  2. Snap station B vào node gần nhất
  3. Tìm shortest path

thì thuật toán có thể chọn hai node nằm trên hai railway song song khác nhau.

Kết quả là path có thể vòng rất xa.

Một trường hợp Tokyo → Kanda từng tạo ra path khoảng 7km, trong khi khoảng cách thực tế chỉ khoảng 1.2km.

Có tổng cộng 27/204 cặp station gặp lỗi dạng này.

Multi-source / multi-target Dijkstra

Thay vì bắt đầu từ đúng một node, thuật toán bắt đầu từ tất cả node nằm trong bán kính snap quanh station đầu.

Tương tự, thuật toán dừng khi gặp node nằm trong bán kính snap của station đích.

Kết quả là thuật toán có thể chọn railway connection trực tiếp nhất thay vì bị khóa vào một node gần nhất.

Sau khi thay đổi:

Worst detour ratio giảm từ 24x xuống 1.6x trên 27 cặp lỗi.

Đây là một cải thiện rất lớn chỉ bằng cách thay đổi cách chọn điểm bắt đầu và kết thúc của graph search.


17. Tàu có thể "nhảy" giữa hai tuyến song song

Ngay cả khi railway polyline đã được xây dựng chính xác, việc match train vào railway theo khoảng cách gần nhất vẫn có một vấn đề.

Một train thực tế có thể liên tục được match:

  • Chuo-Sobu Local
  •         ↓
  • Sobu Rapid
  •         ↓
  • Chuo-Sobu Local

Hai railway quá gần nhau khiến nearest-distance matching không ổn định.

Điều này đặc biệt dễ nhận thấy trong animation.

Khi railway ID thay đổi, arc-length position cũng thay đổi theo, khiến tàu có thể trông như đang lùi lại.

Pin railway ID

Project quyết định ưu tiên sự ổn định.

Sau khi vehicle được match vào một railway:

  • Vehicle
  •    ↓
  • Railway matched
  •    ↓
  • PIN railway ID

Các poll tiếp theo sẽ tiếp tục sử dụng railway đó.

Chỉ tìm railway mới khi railway hiện tại không còn hợp lệ.

Nhờ vậy animation ổn định hơn nhiều so với việc mỗi poll đều tìm nearest railway.


18. Không phải operator nào cũng có đủ dữ liệu để dựng railway

Một vấn đề khác nằm ở station coordinates.

Chỉ station record của JR East trên Challenge 2026 có:

  • geo:long
  • geo:lat

Bốn operator còn lại không có tọa độ trong nguồn dữ liệu này.

Không có tọa độ thì không thể dùng station làm anchor để ghép với OSM railway graph.

Do đó project chỉ dựng railway polyline cho:

  • ODPT_TRAIN_OPERATOR_IDS = JR East

Đây là lựa chọn thực tế hơn so với việc cố tạo một polyline không đáng tin cậy cho các operator còn thiếu dữ liệu.


19. Consumer key không nên xuất hiện trong browser

ODPT consumer key gắn với tài khoản đăng ký và không nên được đưa trực tiếp vào frontend.

Nếu client gọi API trực tiếp:

  • Browser
  •    ↓
  • ODPT

thì key có thể bị expose.

Project sử dụng backend proxy:

  • Browser
  •    ↓
  • /api/odpt/*
  •    ↓
  • Server
  •    ↓
  • ODPT

Tương tự, dữ liệu railway từ Overpass đi qua:

  • /api/osm/railways

Key chỉ tồn tại ở server.

Ngoài vấn đề bảo mật, server còn giúp kiểm soát rate limit và cache.

Rate limit khoảng 20 request/phút/IP cũng ảnh hưởng trực tiếp tới việc thiết kế polling interval của client.


20. Timetable không có holiday calendar thật

Một hạn chế khác của ODPT timetable là calendar.

JR East timetable chỉ phân biệt:

  • Weekday
  • SaturdayHoliday

Nó không cung cấp lịch holiday thực tế.

Ví dụ một ngày lễ rơi vào thứ Hai vẫn có thể bị xem như một weekday.

Project chấp nhận giới hạn này và sử dụng weekday/weekend approximation.

Một chi tiết thú vị khác là timetable có thể biểu diễn thời gian như:

  • 25:10

thay vì:

  • 01:10

Thực tế điều này lại khá thuận tiện.

Nếu xử lý thời gian dưới dạng minutes from midnight mà không giới hạn ở 1439 phút, 25:10 tự nhiên được đặt sau 23:59.

Không cần thêm một logic đặc biệt cho giờ sau nửa đêm.


21. Một vấn đề riêng của Cesium: BoxGraphics không có scaleByDistance

Để train trông giống một toa tàu thật, project chuyển marker từ point sang BoxGraphics.

Nhưng BoxGraphics không có sẵn:

  • disableDepthTestDistance
  • scaleByDistance

Hai property này rất hữu ích với PointGraphics hoặc BillboardGraphics.

Giải pháp

Project tự tính kích thước box dựa trên khoảng cách:

  • Camera
  •    ↓
  • distance to train
  •    ↓
  • calculate dimensions
  •    ↓
  • resize BoxGraphics

Kích thước 3D được điều chỉnh mỗi tick để kích thước hiển thị trên màn hình gần như ổn định ở nhiều mức zoom khác nhau.

Đổi lại, project giữ lại occlusion thật:

Nếu building nằm trước train, train có thể bị building che.

Đây được xem là một lựa chọn thiết kế chấp nhận được vì nó làm scene 3D tự nhiên hơn.


22. Những vấn đề phát hiện trong quá trình test

Ngoài các vấn đề đã được xử lý, quá trình test còn phát hiện hai issue chưa được giải quyết hoàn toàn.

Train status luôn hiển thị "Unknown"

GTFS-Realtime trả về currentStatus dưới dạng enum số:

  • 0
  • 1
  • 2

Trong khi UI lookup table lại sử dụng key dạng string:

  • INCOMING_AT
  • STOPPED_AT
  • IN_TRANSIT_TO

Do đó việc lookup bằng số không bao giờ match.

Cách xử lý được đề xuất là map enum number sang enum name trước:

  • 0 → INCOMING_AT
  • 1 → STOPPED_AT
  • 2 → IN_TRANSIT_TO

Sau đó mới đưa vào bảng label của UI.


Click vào train đang dừng ở station luôn chọn station

Đây là vấn đề về picking trong Cesium.

Station marker đang sử dụng:

  • disableDepthTestDistance: Infinity

nên luôn nằm trên depth test.

Trong khi train sử dụng BoxGraphics và vẫn chịu depth test bình thường.

Khi train dừng đúng tại station:

  • Train
  • Station

click có thể luôn trả về station thay vì train.

Giải pháp được đề xuất là áp dụng logic tương tự drillPick:

  • Top pick = Station
  •         ↓
  • Check nearby train
  •         ↓
  • Train exists?
  •         ↓
  •      Pick Train

Như vậy train có thể được ưu tiên khi nó đang nằm cùng pixel với station.


23. Những bài học lớn hơn

Sau khi kết hợp PLATEAU, ODPT, OSM và Cesium, có một số bài học quan trọng có thể áp dụng cho những dự án visualization khác.

1. Open data không có nghĩa là data hoàn hảo

Dữ liệu mở có thể thiếu:

  • field
  • enum
  • coordinate
  • realtime update
  • stable ID
  • geometry

Không nên thiết kế application dựa trên giả định rằng schema luôn đầy đủ.


2. Phải phân biệt "data thật" và "data suy luận"

Ví dụ:

  • Train position
  • → Real data
  • Train route
  • → Best-effort inference

Hai loại dữ liệu này cần được xử lý và hiển thị với mức độ tin cậy khác nhau.


3. Geometry và semantic data có thể bổ sung cho nhau

ODPT biết:

Station A → Station B

OSM biết:

Railway thực tế đi như thế nào.

Kết hợp hai nguồn cho kết quả tốt hơn nhiều so với việc chỉ dùng một nguồn.


4. Stability đôi khi quan trọng hơn accuracy tuyệt đối

Ví dụ train có thể được match vào railway gần nhất mỗi lần poll.

Về lý thuyết, điều này có vẻ "chính xác" hơn.

Nhưng nếu railway thay đổi liên tục giữa hai đường song song, animation sẽ rất tệ.

Pin railway ID giúp kết quả ổn định hơn.

Trong visualization realtime:

Một kết quả hơi sai nhưng ổn định thường tốt hơn một kết quả thay đổi liên tục.


5. Performance không chỉ là FPS

Khi làm bản đồ 3D lớn, performance còn liên quan đến:

  • Network bandwidth
  • Number of active tiles
  • LOD
  • GPU rendering
  • Request frequency
  • Memory usage
  • Data update frequency

Ví dụ texture PLATEAU gây vấn đề chủ yếu vì bandwidth, trong khi Cesium render loop lại gây vấn đề về GPU/power consumption.

Cần xác định đúng bottleneck trước khi tối ưu.


Kết luận

Việc kết hợp PLATEAU và ODPT trong Cesium không đơn giản chỉ là:

  • Load 3D buildings + Load train positions = Realtime 3D city

Thực tế cần giải quyết cả một chuỗi vấn đề từ coordinate system, unstable asset URL, LOD, missing dataset, undefined properties, schema không nhất quán cho tới realtime feed, railway matching, graph routing, interpolation và API security.

Quan trọng hơn, nhiều vấn đề không thể "fix" hoàn toàn vì giới hạn nằm ngay trong dữ liệu nguồn.

Khi đó, cách tiếp cận hiệu quả nhất là:

Hiểu rõ giới hạn của dữ liệu → xác định trade-off → chọn phương án đủ tốt → làm rõ đâu là dữ liệu thật và đâu là suy luận.

Đó cũng là điều khiến việc xây dựng một bản đồ 3D realtime từ open data trở thành một bài toán thú vị hơn rất nhiều so với việc chỉ hiển thị một vài tileset và marker trên Cesium.

Đừng để ý tưởng chỉ nằm trên giấy. Với tốc độ và sự linh hoạt đã được chứng minh qua 1.000+ dự án, chúng tôi sẽ giúp doanh nghiệp của bạn bứt phá.

Quay lại Blog

Bài viết liên quan

PLATEAU Tokyo 23-Ku: Khám phá Tokyo qua bản đồ 3D, giao thông và dữ liệu môi trườngGeospatial & GIS

PLATEAU Tokyo 23-Ku: Khám phá Tokyo qua bản đồ 3D, giao thông và dữ liệu môi trường

PLATEAU Tokyo 23-Ku kết hợp mô hình đô thị 3D với dữ liệu JR East, xe buýt Toei, Bike Share, giao thông JARTIC, lượng mưa JMA và chất lượng không khí. Bài viết giới thiệu cách Cesium và 3D Tiles tạo môi trường trực quan hóa chung cho Smart City và Urban Digital Twin.

Thinh Tran
Lạc Bước Vào Lòng Đất Kỳ Vĩ: Khi Cả Thế Giới Hang Động Thu Nhỏ Trong Tầm Mắt Bạn3D

Lạc Bước Vào Lòng Đất Kỳ Vĩ: Khi Cả Thế Giới Hang Động Thu Nhỏ Trong Tầm Mắt Bạn

Cave Explorer biến dữ liệu quét hang động thực thành trải nghiệm 3D tương tác trên web bằng Point Cloud, 3D Tiles, LOD và real-time rendering. Bài viết giải thích quy trình dữ liệu, bài toán hiệu năng trình duyệt, thám hiểm từ xa, bảo tồn di sản số và các hướng phát triển tiếp theo.

Thinh Tran
“Digital Twin” của bạn có đang chỉ là một mô hình 3D đắt tiền? Bản chất không nằm ở “hình thức” mà ở “đồng bộ trạng thái”Digital Twin

“Digital Twin” của bạn có đang chỉ là một mô hình 3D đắt tiền? Bản chất không nằm ở “hình thức” mà ở “đồng bộ trạng thái”

Một mô hình 3D đẹp chưa đủ để trở thành Digital Twin. Bài viết giải thích vì sao đồng bộ trạng thái mới là cốt lõi, sự khác nhau giữa Digital Model và Digital Shadow, vì sao không phải lúc nào cũng cần thời gian thực, khi nào 3D hữu ích và 5 câu hỏi cần trả lời trước khi triển khai.

Toshihiko Nagaoka
I'm Duper, ask me anything!