How to limit zoom and tilt in a 3D map
UPDATED: | POSTED: | by Stefan Schüttenkopf
In this tutorial we walk you through the steps to limit the zoom as well as the tilt for your 3D application in order to increase performance.
Code injection to your 3D browser application
Go to Studio → Browser → M.Apps
and click on the Open in editor
icon.
Go to Studio -> Browser -> M.Apps and click on the Open in editor icon.
function main() {
window.map.stores.navigation.pitchBounds3D = {minPitch: -90, maxPitch: -40};
window.map.stores.navigation.altitudeBounds3D = {minAltitude: 20, maxAltitude: 2000};
}
pitchBounds3D
In the above mentioned example the user is allowed to tilt to a maximum degree of 50°.
minPitch
By default -90°, which means nadir = straight down look
maxPitch
The maximum tilt angle. Must be between -90° and 0°. For Google-like tilt you have to set the value to -34°, which gives you an tilt angle of 66°
altitudeBounds3D
In the above mentioned example the user is allowed to zoom in to a "flight height" of 20m and to zoom out to 2000m.
If you want to have an advanced tutorial - please read on
Combine flight height with visibility of layers
This advanced tutorial takes the above learned code snippet and combine it with the visibility changes of layers in your 3D map.
import { PerspectiveCamera } from '@luciad/ria/view/camera/PerspectiveCamera';
import * as ReferenceProvider from '@luciad/ria/reference/ReferenceProvider';
import * as TransformationFactory from '@luciad/ria/transformation/TransformationFactory';
import { LayerTreeNode } from '@luciad/ria/view/LayerTreeNode';
function findLayerByName(name: string) {
function _findLayerByName(name: string, node: LayerTreeNode) {
if(node.label === name)
return node;
for(let child of node.children) {
let result = _findLayerByName(name, child);
if(result)
return result;
}
return undefined;
}
for(let childNode of window.map.layerTree.children) {
let result = _findLayerByName(name, childNode);
if(result)
return result;
}
return undefined;
}
function applyFlightHeightSwitch(flightHeightUpperBound: number, layername: string) {
const localCRS = ReferenceProvider.getReference("EPSG:xxxxx");
const localToWorld = TransformationFactory.createTransformation(window.map.reference, localCRS);
const ThemeName = findLayerByName(layername);
const allChildren = window.map.getAllLayers(ThemeName);
let savedState: any = undefined;
window.map.on('MapChange', () => {
const camera = window.map.camera as PerspectiveCamera;
const wgs84Point = localToWorld.transform(camera.eyePoint);
if(wgs84Point.z > flightHeightUpperBound && savedState === undefined) {
savedState = {};
allChildren.forEach(c => {
savedState[c.id] = c.visible;
c.visible = false;
})
} else if(wgs84Point.z < flightHeightUpperBound && savedState !== undefined) {
allChildren.forEach(c => {
if(savedState[c.id]) {
c.visible = savedState[c.id];
}
});
savedState = undefined;
}
})
}
Line 31
: EPSG:xxxxx
defines the EPSG code of your local CRS
Now you can use applyFlightHeightSwitch
function within the main
function of your browser application and as per definition you have to set the flightHeightUpperBounds
in metre and the themeName
, for which the layers should get invisible.
function main() {
applyFlightHeightSwitch(700, 'Photovoltaik');
}