Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current zoom in Cesium

Tags:

cesium

I need to create a setZoom() function in Cesium. For that, I believe I need to evaluate the current zoom so I can decide if I have to use the zoomIn or zoomOut to show what the user asks.

Does anyone know if it's possible to get the zoom level from the map when using Cesium? Or any other solution... Any tips are very welcome.

Does the function getMagnitude() does the trick?

Thanks!

Solution:

I put together all the tips emackey gave to me and got the following code:

var iniPos = new Cesium.Cartesian3();
iniPos = this.viewer.camera.position;
var cartographic = new Cesium.Cartographic();
cartographic.height = zoom * 1000;
cartographic.longitude = iniPos.x;
cartographic.latitude = iniPos.y;
var newPos = new Cesium.Cartesian3();
Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic, newPos);
this.viewer.camera.setView({
    position: newPos
});

With that I'm able to define the height of the camera to a zoom parameter defined by the user.

like image 428
Pri Santos Avatar asked Oct 20 '15 12:10

Pri Santos


1 Answers

Cesium's default view is a 3D globe with a perspective view. A typical 2D zoom level number doesn't fully describe the different resolutions that Cesium's camera can see. Take a minute to read my full answer to Determining the Map Scale of the Viewed Globe for a better explanation.

EDIT 1: The camera.getMagnitude function gets the "magnitude of the camera's position" which really means the distance to the center of the Earth. This is probably not what you want, instead you want the altitude of the cartographic position.

EDIT 2: I've added a code snippet here that has buttons on it to set the camera's height to various altitudes. Click "Run code snippet" at the bottom to see this in action, or copy just the JavaScript portion of this into Sandcastle to run it there. Note that this works best when the camera is looking straight down, as it moves the camera to a specific height without altering the lat/lon. If the camera is off-axis, the mouse can "zoom" the camera along the look vector, which alters all three cartographic coordinates (lat, lon, and alt) at the same time. It's a trickier calculation to move the camera to a specific height along that line, I don't have code for that handy and it might not really be what you want anyway. Give this a try, see if it works for you.

var viewer = new Cesium.Viewer('cesiumContainer', {
    navigationHelpButton: false,
    animation: false,
    timeline: false
});

var cartographic = new Cesium.Cartographic();
var cartesian = new Cesium.Cartesian3();
var camera = viewer.scene.camera;
var ellipsoid = viewer.scene.mapProjection.ellipsoid;
var toolbar = document.getElementById('toolbar');
toolbar.innerHTML = '<div id="hud"></div>' +
    '<button type="button" class="cesium-button" id="h1km">1km height</button>' +
    '<button type="button" class="cesium-button" id="h10km">10km height</button>' +
    '<button type="button" class="cesium-button" id="h500km">500km height</button>';

toolbar.setAttribute('style', 'background: rgba(42,42,42,0.9); border-radius: 5px;');

var hud = document.getElementById('hud');

viewer.clock.onTick.addEventListener(function(clock) {
    ellipsoid.cartesianToCartographic(camera.positionWC, cartographic);
    hud.innerHTML =
        'Lon: ' + Cesium.Math.toDegrees(cartographic.longitude).toFixed(3) + ' deg<br/>' +
        'Lat: ' + Cesium.Math.toDegrees(cartographic.latitude).toFixed(3) + ' deg<br/>' +
        'Alt: ' + (cartographic.height * 0.001).toFixed(1) + ' km';
});

function setHeightKm(heightInKilometers) {
    ellipsoid.cartesianToCartographic(camera.position, cartographic);
    cartographic.height = heightInKilometers * 1000;  // convert to meters
    ellipsoid.cartographicToCartesian(cartographic, cartesian);
    camera.position = cartesian;
}

document.getElementById('h1km').addEventListener('click', function() {
    setHeightKm(1);
}, false);

document.getElementById('h10km').addEventListener('click', function() {
    setHeightKm(10);
}, false);

document.getElementById('h500km').addEventListener('click', function() {
    setHeightKm(500);
}, false);
html, body, #cesiumContainer {
    width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
    font-family: sans-serif; color: #edffff;
}
#toolbar {
    padding: 2px 5px;
    position: absolute;
    top: 5px;
    left: 5px;
}
<link href="http://cesiumjs.org/Cesium/Build/Cesium/Widgets/widgets.css" 
      rel="stylesheet"/>
<script src="http://cesiumjs.org/Cesium/Build/Cesium/Cesium.js"></script>
<div id="cesiumContainer"></div>
<div id="toolbar"></div>
like image 96
emackey Avatar answered Oct 30 '22 17:10

emackey