OSM model curvature and local tangent planes

Hi all,

(lots of text for context, skip to bolded section for main point)

The Cesium Ion OSM asset comes in b3dms, which hold gltf models. The gltf models are y-up, so must be transformed to z-up for Unreal Engine.

I wrote code to pull in and render the models. Everything works great and lines up except for OSM models that are very large. For example, the model with Burj Khalifa (6\83\23.b3dm) has bounds (231302, 233758, 207066), which is huge!

When I transform 23.b3dm to z-up, it doesn’t show buildings in the right place. However, if I modify the transform rotation by a very small amount, it does line up. For example, all the smaller models line up precisely with transform rotation of (Pitch=0.000000,Yaw=90,Roll=180). However, 23.b3dm requires (Pitch=0.000000,Yaw=90.27,Roll=181.368). Other large b3dms require similar very small adjustments to line things up. For example, the b3dm with the Pentagon requires (Pitch=0.000000,Yaw=90.05,Roll=180.87).

I originally thought this was a precision issue in Unreal, so I did the transform manually using doubles instead of floats and got the similar results.

After banging my head on the wall for awhile, I believe the issue is the curvature of the Earth. Curvature is roughly 3138m at 200km (https://earthcurvature.com). If I adjust the verts’ Z upward based on distance from model origin, they are about at the surface, but their longitude/latitude is wrong since I’m adjusting straight up. I’m fitting the OSM data to local tangent planes (ENU), so the curvature of the Earth built into the models causes the models to go below the tangent plane.

My request is to modify your OSM generation algorithm so the models are small enough to only negligibly be effected by the curvature of the Earth. That way the models can be rendered to globes and tangent planes without issue.

Let me know what you think.


Hi all,

You can flatten the curvature of the OSM models by getting the ECEF coordinates of each vertex, then converting from ECEF to longitude/latitude/HAE. Once you have long/lat/HAE, you can figure out correct location for the vertex in ENU.

After reading in the model, you should have the ECEF and the rotation of the model. You can get ECEF of each vertex by by using the model’s transform to transform the local position of each vertex to global (ECEF).

Happy to help if anyone else runs into this and can’t figure it out.