How to set Height offset after set clampToGround is true in geojson

Hello @lzio,

I’m sorry, but this isn’t something that CesiumJS currently has support for. If we get a lot of requests for this functionality, we will consider adding it in the future.

Best regards,

Hannah
Cesium Staff

1 Like

A solution for you is to simply clone the geoJSON, iterate it and find and offset all heights in coordinates, and then push that to Cesium. Don’t know if you’re using files locally or externally, you may need to act as a proxy, but we need more info for that. If this need further clarification, let me know.

Cheers,

Alex

1 Like

Hi Alexander_Johannesen,

I used local geoJSON file and haven’t tried this way,so i really don’t know what should i do.
My geoJSON only have polygon boundary information, how to iterate it to get all heights in coordinates

Thank you in advance,

lzio

Hi there,

There’s a couple of ways, possibly more, depending on your developer skills.

First is to use some library for GeoJSON parsing; read the file, then update objects generated, then stream objects to Cesium or save locally and then send that. There are NPM packages for this, just search for it, or go heavy with leafletJS or TurfJS (recommended). In Leaflet there’s some offset API, going from memory, that might do the job for you, but it’s going to take a bit of noodling around.

Second option is a more brute force, where you either write a small parser yourself or go through the file with nifty RegEx to find all coords with a third parameter. GeoJSON typically looks like;

"geometry": { "type": "Point", "coordinates": [ 168.302917, -46.593605, 43.2 ] }

So, you’re looking for a set of [ … ] in the vicinity of ‘coordinates’ (or somesuch), with two commas in them; those will be your height, so adjust them accordingly, purely in a string fashion. GeoJSON is 2D first, so just remember that there’s a good possibility that these arrays only have x/y | long/lat values in there which you need to cater to (either ignore, or convert them to something average, depending).

Option 1 is probably easier, but if you want to learn a ton about GeoJSON and parsing I’d recommend option 2, with https://geojson.org/ as your guiding friend.

Cheers,

Alex

Hi Alexander_Johannesen

Thank you for your patient reply, it’s really helpful to me to figure out the solution.

After i checked TurfJS and option 2, i’m so sorry but i still don’t understand how to combine cesium terrain and 2D geoJSON data. Unfortunately, it works on polyline but polygon only get all heights in geojson coordinates is useless because it’s just boundary information. I also need to create a face cover the terrain like the picture that i showed above. That means after i got all interpolation coordinates with height, if all the coordinates be rebuilt with height, it seems like some drawing face rules need to use.

Best

lzio

Ok, so are you saying you don’t have the heights in the coordinates in the GeoJSON?

If so, your next option is to sample the terrain for its height at every point coming from the GeoJSON. So, read the file, get the 2D coordinates, load your Cesium world, and then loop over the points (in world coordinates) and use sampleTerrain() to get the height for each point. Update coordinates to 3D in your GeoJSON accordingly, and create a polygon with the updated coordinates.

Apart from that, maybe I simply don’t understand the problem. :slight_smile:

Cheers,

Alex

Hello,

I ran into a problem similar to yours recently. And I found sampleTerrain() function very useful.
There is also a Sandcastle Demo shows the output feature like this. (Cesium Sandcastle to Terrain.html)


The polyline looks “clamped to the mountain” with each point 10 meters offset upon the mountain surface.

Hope it Helps.
Best,
Yujie

Hi,
The sandcastle is not working for me, could you please update it or something?
I’d like to take a look at how you did this.
Thanks,
Ahmed

1 Like

@AIR

Welcome to the community! :airplane: Which sandcastle is not working for you? I would be happy to help out once I know a little bit more about your issue :grinning:

-Sam

Hi @sam.rothstein

I am referring to the post just before mine from @yujiezhang125 (Profile - yujiezhang125 - Cesium Community).

What I am trying to do is get the elevation value of the terrain when the long and lat (in degrees) values are known. Then I will use this to manipulate the camera for a “street view” type of look.

Any help would be greatly appreciated.

Thanks in advance,
Ahmed

1 Like

@AIR

Thank you very much for the clarification! I opened up the sandcastle demo that you are referring to and got the error

Unable to load demo named Clamp. Redirecting to HelloWorld.

Clearly, the demo is broken. @yujiezhang125 can you please repost the demo with a working link?

-Sam

@sam.rothstein

Yeah, that appears to be the case for me as well.
In case @yujiezhang125 is inactive, do you happen to know a nice way of doing what I’d like to do?

@AIR

I currently do not know of a simple solution to your problem. I will investigate this further as the week progresses. In the meantime, you should check out our Elevation Band Material sandcastle demo. This demo colors the terrain based on altitude and is thus somewhat related to your use case.

It also seems like the following community forum thread addresses this issue.

Let me know what you think of these resources. I am looking forward to learning more!

-Sam

Hi there @AIR,

Just saw your question, and, umm, is what you’re trying to do is sample the terrain at a known long/lat coord? Because scene.sampleTerrainMostDetailed() does exactly that; it returns a promise with the height adjusted. Let me know if that’s what you’re after.

Cheers,

Alex

Hi Alexander, that seems like what I need but promises are slightly delayed…and I want it to be instant.

@Alexander_Johannesen Also, is there a way to wait for the promise to return and then do something after that’s done?

Hiya,

You won’t get it instant, but if you’re only sampling one or two coordinates, it’s pretty instant all the same, just give it a try;

var positions = [ ... ];
var samplePromise = Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, positions);
samplePromise.then ( result => {
   // do something with the result array of height sampled coords
});

More here;
https://cesium.com/learn/cesiumjs/ref-doc/sampleTerrainMostDetailed.html

Cheers,

Alex

1 Like

Hi Ahmed,

Sorry for my late response.
This is a new link of the demo Sandcastle demo I mentioned above:

Does it work for you?

Thanks,
Yujie

Just to clarify, you need to open the “Sample line positions and draw with depth test disabled” option of “Clamp to Terrain” demo in Sandcastle Gallery.


Thank you all. I’ll take a look and keep working on it.

1 Like