Created
July 3, 2024 12:33
-
-
Save AbelVM/b1d53213db7f5f45d9d823ad390d2319 to your computer and use it in GitHub Desktop.
Little MapLibre extension to easily set the PoV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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