Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
.setDefaults([
{
id: "openstreetmap.org",
label: "OpenStreetMap contributors",
link: "https://www.openstreetmap.org/copyright"
}
]);
// snippet:vislib_hello_animation_example_2.ts
// let the camera float over the map, looking straight down
sampleMapView.camera.position.set(0, 0, 1000);
// center the camera somewhere around Berlin geo locations
sampleMapView.geoCenter = new GeoCoordinates(52.518611, 13.376111, 0);
// Let the camera look down at 45 degrees:
sampleMapView.camera.rotateX(MathUtils.degToRad(45));
// Instantiate the default map controls, allowing the user to pan around freely, even while
// the animation is running.
const controls = new MapControls(sampleMapView);
// Create a simple rotation to animate the scene:
const rotationAnimation = new CameraRotationAnimation(
sampleMapView,
controls,
{
repeat: Infinity,
duration: 30000
},
"rotationAnimation"
);
export function rotate(
mapView: MapView,
deltaYawDeg: number,
deltaPitchDeg: number = 0,
maxTiltAngleRad = Math.PI / 4
) {
// 1. Apply yaw: rotate around the vertical axis.
mapView.camera.rotateOnWorldAxis(
mapView.projection.type === ProjectionType.Spherical
? cache.vector3[0].copy(mapView.camera.position).normalize()
: cache.vector3[0].set(0, 0, 1),
MathUtils.degToRad(-deltaYawDeg)
);
mapView.camera.updateMatrixWorld();
// 2. Apply pitch: rotate around the camera's local X axis.
if (deltaPitchDeg === 0) {
return;
}
const pitch = MapViewUtils.extractAttitude(mapView, mapView.camera).pitch;
// `maxTiltAngle` is equivalent to a `maxPitchAngle` in flat projections.
let newPitch = THREE.Math.clamp(
pitch + THREE.Math.degToRad(deltaPitchDeg),
0,
maxTiltAngleRad
);
// In sphere projection, the value of a maximum pitch is smaller than the value of the
// maximum tilt, as the curvature of the surface adds up to it.
// C1->E1 = tan(tilt) * z.
// then E1->D2 is expressed with:
// E1->D2 = C1->D2 - C1->E1
// For computing D1->E1, we may use similar formulas, firstly calculate C1->D1:
// C1->D1 = tan(tilt - fov/2) * z
// and then D1->E1:
// D1->E1 = C1->E1 - C1->D1
const cameraAltitude = this.getCameraAltitude(camera, projection);
const cameraPitch = this.getCameraTiltAngle(camera, projection);
// Angle between z and c2, note, the fov is vertical, otherwise we would need to
// translate it using aspect ratio:
// let aspect = camera.aspect > 1 ? camera.aspect : 1 / camera.aspect;
const aspect = 1;
// Half fov angle in radians
const halfFovAngleRad = MathUtils.degToRad((camera.fov * aspect) / 2);
// Angle between z and c2
const biggerAngleRad = cameraPitch + halfFovAngleRad;
// Angle between z and c1
const smallerAngleRad = cameraPitch - halfFovAngleRad;
// Length C1->E1
const projectionEyeVector = Math.tan(cameraPitch) * cameraAltitude;
// Length C1->D2
const projectionHighEdge = Math.tan(biggerAngleRad) * cameraAltitude;
// Length E1->D2
const projectionRightSide = projectionHighEdge - projectionEyeVector;
// Length of C1->D1
const projectionLowEdge = Math.tan(smallerAngleRad) * cameraAltitude;
// Length D1->E1
const projectionLeftSide = projectionEyeVector - projectionLowEdge;
const applyTransformControls = () => {
// Apply helper camera offset to main (map view) camera.
this.mapView.camera.position.add(cameraRelativeToEye.position);
// Make sure that pitch limit contraint is preserved
const ypr = MapViewUtils.extractYawPitchRoll(cameraRelativeToEye.quaternion);
ypr.pitch = Math.max(
Math.min(ypr.pitch, MathUtils.degToRad(this.mapControls.maxPitchAngle)),
0
);
// Finally apply rotation from transformation gizmo.
this.mapControls.setRotation(
MathUtils.radToDeg(ypr.yaw),
MathUtils.radToDeg(ypr.pitch)
);
// Reset RTE camera orientation according to constraints applied.
cameraRelativeToEye.copy(this.mapView.camera);
// Reset RTE camera position to origin.
cameraRelativeToEye.position.setScalar(0);
transformControls.update();
};
applyTransformControls();