I’ve been implementing the concept from this mapbox blog to animate 3d routes from GPS activities into my fitness app – Trackster.
Everything works great for GPS activities that are at ~sealevel. When the altitude increases, it gets increasingly skewed.
Here is an example activity at sea level
Here is an example of the ugly version in Quito, Ecuador (9.9k feet in altitude)
Feels like I’m just not understanding why the altitude is throwing off the newly calculated coordinates by so much?? Here is the algorithm used to get the camera position.
computeCameraPosition(
pitch,
bearing,
targetPosition,
altitude,
previousCameraPosition = null,
smooth = false
) {
function lerp(start, end, amt) {
return (1 - amt) * start + amt * end
}
var bearingInRadian = bearing / 57.29;
var pitchInRadian = (90 - pitch) / 57.29;
var altFac = (altitude / Math.tan(pitchInRadian))
var d = Math.cos( targetPosition.lat * (Math.PI/180) ) * (40075000 / 360)
var latDiff = (altFac * Math.cos(-bearingInRadian)) / this.latRadFac // 111320 m/degree latitude
var lngDiff = ( altFac * Math.sin(-bearingInRadian)) / d;
var correctedLng = targetPosition.lng + (lngDiff);
var correctedLat = targetPosition.lat - (latDiff);
const newCameraPosition = {
lng: correctedLng,
lat: correctedLat
};
if (smooth) {
if (previousCameraPosition) {
const SMOOTH_FACTOR = 0.9
newCameraPosition.lng = lerp(newCameraPosition.lng, previousCameraPosition.lng, SMOOTH_FACTOR);
newCameraPosition.lat = lerp(newCameraPosition.lat, previousCameraPosition.lat, SMOOTH_FACTOR);
}
}
return newCameraPosition
},