Skip to content

Instantly share code, notes, and snippets.

@AbelVM
Created July 3, 2024 12:33
Show Gist options
  • Save AbelVM/b1d53213db7f5f45d9d823ad390d2319 to your computer and use it in GitHub Desktop.
Save AbelVM/b1d53213db7f5f45d9d823ad390d2319 to your computer and use it in GitHub Desktop.
Little MapLibre extension to easily set the PoV
/*
Abel Vázquez Montoro, 2022
https://github.com/maplibre/maplibre-gl-js/issues/1599
This function sets the camera PoV based on the 3D point the user want to focus on
and the attitude of the camera.
Parameters:
* center: latlng object of the observed point,
* elevation: meters above sea level of the observed point (default: 0)
* exageration: if Terrain3D is used, this should be the same exageration value (default: 1)
* bearing: camera bearing (default 0)
* pitch: camera pitch (default: 45)
* hover: number of zoom levels to back off the camera (default: 2)
*/
const lookat = function (o) {
// Defaults
const defaultconfig = {
'bearing': 0,
'pitch': 45,
'elevation': 0,
'exageration': 1,
'hover': 2
};
o = Object.assign(defaultconfig, o);
const
r = Math.PI / 180,
e = o.elevation * o.exageration,
d = e / Math.tan(o.pitch * r),
dx = d * Math.sin(o.bearing * r),
dy = d * Math.cos(o.bearing * r);
const
mercatorCenter = maplibregl.MercatorCoordinate.fromLngLat(o.center, 0),
mercatorCenterProjected = new maplibregl.MercatorCoordinate(
mercatorCenter.x + (dx * mercatorCenter.meterInMercatorCoordinateUnits()),
mercatorCenter.y + (-dy * mercatorCenter.meterInMercatorCoordinateUnits()),
0);
this.jumpTo({
'center': mercatorCenterProjected.toLngLat(),
'bearing': o.bearing,
'pitch': o.pitch
});
/*
Dolly zoom:
Ref: https://en.wikipedia.org/wiki/Dolly_zoom#Calculating_distances
*/
const
circumferenceAtEquator = 2 * Math.PI * 6378137,
zoom = Math.log2(circumferenceAtEquator / (2 * e * Math.tan(this.transform._fov / 2)));
this.setZoom(zoom - o.hover);
};
maplibregl.Map.prototype.lookAt = lookat;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment