mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
89 lines
2.2 KiB
JavaScript
89 lines
2.2 KiB
JavaScript
// constants
|
|
var TAU = 2 * Math.PI;
|
|
const EQUATORIAL_RADIUS = 6.3781370E6;
|
|
const POLAR_RADIUS = 6.3567523E6;
|
|
|
|
|
|
export function geoLatToMeters(dLat) {
|
|
return dLat * (TAU * POLAR_RADIUS / 360);
|
|
}
|
|
|
|
|
|
export function geoLonToMeters(dLon, atLat) {
|
|
return Math.abs(atLat) >= 90 ? 0 :
|
|
dLon * (TAU * EQUATORIAL_RADIUS / 360) * Math.abs(Math.cos(atLat * (Math.PI / 180)));
|
|
}
|
|
|
|
|
|
export function geoMetersToLat(m) {
|
|
return m / (TAU * POLAR_RADIUS / 360);
|
|
}
|
|
|
|
|
|
export function geoMetersToLon(m, atLat) {
|
|
return Math.abs(atLat) >= 90 ? 0 :
|
|
m / (TAU * EQUATORIAL_RADIUS / 360) / Math.abs(Math.cos(atLat * (Math.PI / 180)));
|
|
}
|
|
|
|
|
|
export function geoMetersToOffset(meters, tileSize) {
|
|
tileSize = tileSize || 256;
|
|
return [
|
|
meters[0] * tileSize / (TAU * EQUATORIAL_RADIUS),
|
|
-meters[1] * tileSize / (TAU * POLAR_RADIUS)
|
|
];
|
|
}
|
|
|
|
|
|
export function geoOffsetToMeters(offset, tileSize) {
|
|
tileSize = tileSize || 256;
|
|
return [
|
|
offset[0] * TAU * EQUATORIAL_RADIUS / tileSize,
|
|
-offset[1] * TAU * POLAR_RADIUS / tileSize
|
|
];
|
|
}
|
|
|
|
|
|
// Equirectangular approximation of spherical distances on Earth
|
|
export function geoSphericalDistance(a, b) {
|
|
var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2);
|
|
var y = geoLatToMeters(a[1] - b[1]);
|
|
return Math.sqrt((x * x) + (y * y));
|
|
}
|
|
|
|
|
|
// scale to zoom
|
|
export function geoScaleToZoom(k, tileSize) {
|
|
tileSize = tileSize || 256;
|
|
var log2ts = Math.log(tileSize) * Math.LOG2E;
|
|
return Math.log(k * TAU) / Math.LN2 - log2ts;
|
|
}
|
|
|
|
|
|
// zoom to scale
|
|
export function geoZoomToScale(z, tileSize) {
|
|
tileSize = tileSize || 256;
|
|
return tileSize * Math.pow(2, z) / TAU;
|
|
}
|
|
|
|
|
|
// returns info about the node from `nodes` closest to the given `point`
|
|
export function geoSphericalClosestNode(nodes, point) {
|
|
var minDistance = Infinity, distance;
|
|
var indexOfMin;
|
|
|
|
for (var i in nodes) {
|
|
distance = geoSphericalDistance(nodes[i].loc, point);
|
|
if (distance < minDistance) {
|
|
minDistance = distance;
|
|
indexOfMin = i;
|
|
}
|
|
}
|
|
|
|
if (indexOfMin !== undefined) {
|
|
return { index: indexOfMin, distance: minDistance, node: nodes[indexOfMin] };
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|