Hi All,
I am a student completing a masters dissertation at UCL in London.
I’m using Cesium to try and display and (hopefully) perform analysis on a 3D City Mesh (3D tileset .b3dm).
I am new to Cesium and have limited programming experience so please forgive any naivety in this post.
At the moment I am trying to get the position of where a user clicks with the left mouse button. This is with the view to add two points and then measure the distance between them, to say measure the height of a building in the model/mesh.
I have so far been able to get the position in Cartesian coordinates using scene.pick() and then convert these to Cartographic coordinates using Cesium.Cartographic.fromCartesian().
However, when the user clicks on a point on the model I want the coordinates they have click on to be displayed in a label.
I am trying to use Cesium.CesiumMath.toDegrees(‘The cartographic position’.longitude/latitude) to extract the long and lat values to display in the label.
When I do this I am getting an error in the console when I do this saying 'Uncaught TypeError: Cannot read property ‘toDegrees of undefined’.
To me this seems to suggest that the Cartogaphic position returned from Cesium.Cartographic.fromCartesian() is giving the type error when this is used with Cesium.CesiumMath.toDegrees()?
I know in the Cesium Docs it states when using scene.pick() method on a 3D Tiles Tileset a Cesium3DTileFeature object will be returned so maybe this could be the issue too?
Any help would be highly appreciated.
Cheers,
Chris
Please see my code below along with the console messages. Debugging being done in Sandcastle running locally currently.
var viewer = new Cesium.Viewer(‘cesiumContainer’);
var scene = viewer.scene;
// Creates an empty variable for the click event handler and the cartogrpahic position of mouse click
var handler;
var cartographic;
// Adds variables to record the mouse position
var mousePosition;
Sandcastle.addDefaultToolbarButton(‘Show Cartographic Position on Mouse Over’, function() {
var entity = viewer.entities.add({
label : {
show : false,
showBackground : true,
font : ‘14px monospace’,
horizontalOrigin : Cesium.HorizontalOrigin.LEFT,
verticalOrigin : Cesium.VerticalOrigin.TOP,
pixelOffset : new Cesium.Cartesian2(1, 0),
heightReference : Cesium.HeightReference.RELATIVE_TO_GROUND
}
});
// Mouse over the globe to see the cartographic position
handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function(click) {
var pickedLocation = scene.pick(click.position);
var cartesian = scene.pickPosition(click.position);
console.log("Cartesian Location is: " + cartesian); // Outputs the location of the click to the console to hceck it is correct
// Creates a if loop to check that the pickPosition method is supported and the pickedPosition variable contains a value
if (scene.pickPositionSupported && Cesium.defined(cartesian)) {
var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
console.log("Cartographic location is: " + cartographic);
var longitude = Cesium.CesiumMath.toDegrees(cartographic.longitude);
var latitude = Cesium.CesiumMath.toDegrees(cartographic.latitude);
var altitude = cartographic.height;
var altitudeString = Math.round(altitude).toString();
entity.position = cartesian;
entity.label.show = true;
entity.label.text =
'Lon: ’ + (longitude) +
'\nLat: ’ + (latitude) +
'\nHeight: ’ + (altitudeString);
} else {
entity.label.show = false;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url : ‘https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles’,
requestWaterMask : true,
requestVertexNormals : true
});
// Add tileset to Cesium
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url : ‘http://localhost:8080/gx_data’
// shadows : ShadowMode.CAST_ONLY
}));
// Defines a function to fly to Bath
function goToBath() {
Sandcastle.declare(goToBath);
viewer.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(-2.354662, 51.391676, 5000)
});
}
// Adds a button for the fly to Bath method
Sandcastle.addToolbarButton(‘Go To Bath’, function(){
goToBath();
Sandcastle.highlight(goToBath);
});
// Adds a shadow toggle button to the viewer
Sandcastle.addToggleButton(‘Shadows’, viewer.shadows, function(checked) {
viewer.shadows = checked;
});
Console Messages:
Documentation not available. Please run the “generateDocumentation” build script to generate Cesium documentation.
This application is using Cesium’s default Bing Maps key. Please create a new key for the application as soon as possible and prior to deployment by visiting https://www.bingmapsportal.com/, and provide your key to Cesium by setting the Cesium.BingMapsApi.defaultKey property before constructing the CesiumWidget or any other object that uses the Bing Maps API.
This tile uses a lowercase refine “replace”. Instead use “REPLACE”.
This b3dm header is using the legacy format [batchLength] [batchTableByteLength]. The new format is [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] from https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/TileFormats/Batched3DModel/README.md.
The glTF in this b3dm uses the semantic BATCHID
. Application-specific semantics should be prefixed with an underscore: _BATCHID
.
Cartesian Location is: (3984441.506698334, -163139.4569894213, 4961186.248175986) // The Cartesian position returned
Cartographic location is: (-0.04092126458066583, 0.897022717868518, 78.8359452697764) // The cartographic position returned
Uncaught TypeError: Cannot read property ‘toDegrees’ of undefined (on line 36) // The error received