Cartesian3 converting terrain

There is a Cartesian3 {x: -1270054.670468495, y: 5643182.82695817, z: 2678382.5261573032}
It has no height. How to turn it into a high Cartesian3,It is similar to heightReference: HeightReference.RELATIVE_TO_GROUND set by entity?

Or entity is set to heightReference: HeightReference.RELATIVE_TO_GROUND, how to get the actual cartesian3?

1 Like

Hi @mcck! It was my understanding that the third coordinate in Cartesian3 represented elevation. Can you please share some more details on your high-level goals here?

I want DOM to be positioned on a point。Unfortunately, the elevation of cartesian3 is 0,DOM is not positioned correctly

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <!-- Include the CesiumJS JavaScript and CSS files -->
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.89/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.89/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
  <style>
	html,body,#cesiumContainer{
		height: 100%;
		width: 100%;
		padding: 0;
		margin: 0;
	}
	
	#tips{
		position: fixed;
		width: 100px;
		height: 100px;
		line-height: 100px;
		background-color: #FFF;
		text-align: center;
	}
  </style>
</head>
<body>
  <div id="cesiumContainer"></div>
  <div id="tips">hello</div>
  <script>
    Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NDE1MWIyMC02N2VmLTQwMzktOGQyNS0wMGY0MGVhOGQ5MDciLCJpZCI6NzUzNDMsImlhdCI6MTYzODUxNjc2MH0.NZMzdh31fcCJoL8tmcd46XdxTqiV_WoL4C9B3R5N-kM';

    const viewer = new Cesium.Viewer('cesiumContainer', {
      terrainProvider: Cesium.createWorldTerrain()
    });
    viewer.camera.setView({
      destination : Cesium.Cartesian3.fromDegrees(100.23040561319219, 25.623343397054466, 4000),
	  orientation : {
        heading : Cesium.Math.toRadians(-100),
        pitch : Cesium.Math.toRadians(-15.0),
      }
    });
	
	
	// Add a point
	
	let cartesian3 = Cesium.Cartesian3.fromDegrees(100.1751884398384, 25.617734639164404); // Only longitude and latitude,No elevation
	
	let point = viewer.entities.add({
     position: cartesian3,
     point: {
        color: Cesium.Color.WHITE,
        pixelSize: 10,
		heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 1
      }
    });
	
	let windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3);
	let tipDom = document.getElementById('tips');
	tipDom.style.top = windowPosition.x + 'px';
	tipDom.style.left = windowPosition.y + 'px';
	
	let eventHandler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
	eventHandler.setInputAction(() => {
		let pos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3); // No elevation, tipdom positioning error
		if (pos) {
			tipDom.style.top = pos.y + 'px';
			tipDom.style.left = pos.x + 'px';
		}

	}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	
	
  </script>
  
  
  <script>
	
	new Cesium.ScreenSpaceEventHandler(viewer.canvas).setInputAction((action) => {
		console.log("屏幕:", action.position);
		
		let cartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(action.position), viewer.scene);
		console.log("Cartesian3:", cartesian3);
		
		let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
		console.log("经纬度:", {
			latitude: Cesium.Math.toDegrees(cartographic.latitude),
			longitude: Cesium.Math.toDegrees(cartographic.longitude),
			height: cartographic.height
		});
	}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  </script>
 </div>
</body>
</html>

Hey @sam.rothstein and @mcck , here is a picture what describes the xyz coordinates of cartesian. Their origin is the center of the earth:

The solution is, just add the targeted height as 3rd parameter to Cesium.Cartesian3.fromDegrees(...);

Best, Lennart

1 Like

But I don’t have the third parameter, elevation,Can it be calculated

Oh, now I understand.

Yes, it can be calculated from your Cartesian, but the one you provided in the first post has actually a height of 4.656612873077393e-10 so its ~0.
Anyways, here is a Sandcastle link with height-calculation: link

If you need heigth, either you need some source of height-information or set it to a random height.

1 Like

Maybe I can’t describe it clearly, but I may have found a way

let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
let longitude = Cesium.Math.toDegrees(cartographic.longitude);
let latitude = Cesium.Math.toDegrees(cartographic.latitude);
let height = viewer.scene.globe.getHeight(cartographic);
let cartesian3Height = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <!-- Include the CesiumJS JavaScript and CSS files -->
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.89/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.89/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
  <style>
	html,body,#cesiumContainer{
		height: 100%;
		width: 100%;
		padding: 0;
		margin: 0;
	}
	
	#tips{
		position: fixed;
		width: 100px;
		height: 100px;
		line-height: 100px;
		background-color: #FFF;
		text-align: center;
	}
  </style>
</head>
<body>
  <div id="cesiumContainer"></div>
  <div id="tips">hello</div>
  <script>
    Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NDE1MWIyMC02N2VmLTQwMzktOGQyNS0wMGY0MGVhOGQ5MDciLCJpZCI6NzUzNDMsImlhdCI6MTYzODUxNjc2MH0.NZMzdh31fcCJoL8tmcd46XdxTqiV_WoL4C9B3R5N-kM';

    const viewer = new Cesium.Viewer('cesiumContainer', {
      terrainProvider: Cesium.createWorldTerrain()
    });
    viewer.camera.setView({
      destination : Cesium.Cartesian3.fromDegrees(100.23040561319219, 25.623343397054466, 4000),
	  orientation : {
        heading : Cesium.Math.toRadians(-100),
        pitch : Cesium.Math.toRadians(-15.0),
      }
    });
	
	
	// Add a point
	
	let cartesian3 = Cesium.Cartesian3.fromDegrees(100.1751884398384, 25.617734639164404); // Only longitude and latitude,No elevation
	
	let point = viewer.entities.add({
     position: cartesian3,
     point: {
        color: Cesium.Color.WHITE,
        pixelSize: 10,
		heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 1
      }
    });
	
	let tipDom = document.getElementById('tips');
	
	
	
	
	let eventHandler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
	eventHandler.setInputAction(() => {
	
		let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
		let longitude = Cesium.Math.toDegrees(cartographic.longitude);
		let latitude = Cesium.Math.toDegrees(cartographic.latitude);
		let height = viewer.scene.globe.getHeight(cartographic);
		let cartesian3Height = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
		
		let pos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3Height); // No elevation, tipdom positioning error
		if (pos) {
			tipDom.style.top = pos.y + 'px';
			tipDom.style.left = pos.x + 'px';
		}

	}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	
	
  </script>
  
  
  <script>
	
	new Cesium.ScreenSpaceEventHandler(viewer.canvas).setInputAction((action) => {
		console.log("屏幕:", action.position);
		
		let cartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(action.position), viewer.scene);
		console.log("Cartesian3:", cartesian3);
		
		let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
		console.log("经纬度:", {
			latitude: Cesium.Math.toDegrees(cartographic.latitude),
			longitude: Cesium.Math.toDegrees(cartographic.longitude),
			height: cartographic.height
		});
	}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  </script>
 </div>
</body>
</html>
1 Like

Thats indeed a viable solution!
Be aware that terrain needs some time to load, so until it is loaded you will get height = undefined with this method. But as you put it in a EventHandler it should not be a problem in this case.

Best Lennart

1 Like

OK, my problem has been solved. Thank you very much

It sounds like you sorted this out but nobody explained the fundamental nature of the problem.

Cartesian3 is for representing x/y/z coordinates in 3D space relative to the center of the earth. What you’re actually talking about is GPS coordinates on the surface of the earth. Cesium represents this concept with Cartographic. Latitude and longitude are natively stored in radians (angle across the ellipsoid’s surface), but the structure is commonly constructed using Cartographic.fromDegrees. If you model your position using Cartographic, you can easily modify the altitude (above ellipsoid surface) by changing its height property. Cartographics can be converted to Cartesian3 using the static Cartograhic.toCartesian function.

1 Like