s2-tools
Version:
A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.
344 lines • 11.3 kB
JavaScript
import { EARTH_RADIUS_EQUATORIAL, EARTH_RADIUS_POLAR } from '../../space/planets/earth';
import { IJtoST, STtoIJ, quadraticSTtoUV as STtoUV, quadraticUVtoST as UVtoST, XYZtoFace, XYZtoFaceUV, faceUVtoXYZ, faceUVtoXYZGL, lonLatToXYZ, lonLatToXYZGL, xyzToLonLat, } from './coords';
import { fromS2Point as idFromS2Point, toUV as idToUV } from '../id';
/**
* Convert a lon-lat coord to an XYZ Point using the left-hand-rule
* @param lon The longitude in degrees
* @param lat The latitude in degrees
* @returns The XYZ Point
*/
export function fromLonLat(lon, lat) {
return lonLatToXYZ(lon, lat);
}
/**
* Convert a lon-lat coord to an XYZ Point using the right-hand-rule.
* This function takes longitude and latitude as input and returns the corresponding XYZ coordinates.
* @param lon The longitude in degrees.
* @param lat The latitude in degrees.
* @returns The XYZ Point representing the provided longitude and latitude.
*/
export function fromLonLatGL(lon, lat) {
// Convert longitude and latitude to XYZ coordinates using the right-hand rule.
return lonLatToXYZGL(lon, lat);
}
/**
* Convert a u-v coordinate to an XYZ Point.
* @param face - The face of the S2 cell.
* @param u - The u-coordinate on the face.
* @param v - The v-coordinate on the face.
* @returns The XYZ Point representing the given u-v coordinates.
*/
export function fromUV(face, u, v) {
// Convert the given u-v coordinates to an XYZ Point using the left-hand rule.
return faceUVtoXYZ(face, u, v);
}
/**
* Convert an s-t coordinate to an XYZ Point.
* @param face - The face of the S2 cell.
* @param s - The s-coordinate on the face.
* @param t - The t-coordinate on the face.
* @returns The XYZ Point representing the given s-t coordinates.
*/
export function fromST(face, s, t) {
// Convert the given s-t coordinates to u-v coordinates.
const u = STtoUV(s);
const v = STtoUV(t);
// Convert the u-v coordinates to an XYZ Point.
return fromUV(face, u, v);
}
/**
* Convert an i-j coordinate to an XYZ Point.
* @param face - The face of the S2 cell.
* @param i - The i-coordinate on the face.
* @param j - The j-coordinate on the face.
* @returns The XYZ Point representing the given i-j coordinates.
*/
export function fromIJ(face, i, j) {
// Convert the given i-j coordinates to s-t coordinates.
const s = IJtoST(i);
const t = IJtoST(j);
// Convert the s-t coordinates to an XYZ Point.
return fromST(face, s, t);
}
/**
* Convert an S2CellID to an XYZ Point.
* @param id - The S2CellID to convert.
* @returns The XYZ Point representing the given S2CellID.
*/
export function fromS2CellID(id) {
// Decompose the S2CellID into its constituent parts: face, u, and v.
const [face, u, v] = idToUV(id);
// Use the decomposed parts to construct an XYZ Point.
return fromUV(face, u, v);
}
/**
* Convert an Face-U-V coord to an XYZ Point using the right-hand-rule
* @param face - The face of the S2 cell.
* @param u - The u-coordinate on the face.
* @param v - The v-coordinate on the face.
* @returns The XYZ Point representing the given Face-U-V coordinates.
*/
export function fromUVGL(face, u, v) {
// Convert the given Face-U-V coordinates to an XYZ Point using the right-hand rule.
return faceUVtoXYZGL(face, u, v);
}
/**
* Convert an Face-S-T coord to an XYZ Point using the right-hand-rule
* @param face - The face of the S2 cell.
* @param s - The s-coordinate on the face.
* @param t - The t-coordinate on the face.
* @returns The XYZ Point representing the given Face-S-T coordinates.
*/
export function fromSTGL(face, s, t) {
// Convert the given Face-S-T coordinates to an XYZ Point using the right-hand rule.
// First, convert the s-t coordinates to u-v coordinates.
const [u, v] = [STtoUV(s), STtoUV(t)];
// Then, convert the u-v coordinates to an XYZ Point.
return fromUVGL(face, u, v);
}
/**
* Convert an XYZ Point to a Face-U-V coord
* @param xyz - The XYZ Point to convert.
* @returns - The Face-U-V coordinates representing the given XYZ Point.
*/
export function toUV(xyz) {
// Convert the given XYZ Point to Face-U-V coordinates using the right-hand rule.
return XYZtoFaceUV(xyz);
}
/**
* Convert an XYZ Point to a Face-S-T coord
* @param xyz - The XYZ Point to convert.
* @returns - The Face-S-T coordinates representing the given XYZ Point.
*/
export function toST(xyz) {
// Convert the given XYZ Point to Face-U-V coordinates.
const [face, u, v] = toUV(xyz);
// Convert the U-V coordinates to S-T coordinates using the inverse of the
// UVtoST function.
return [face, UVtoST(u), UVtoST(v)];
}
/**
* Convert an XYZ Point to a Face-I-J coord
* @param xyz - The XYZ Point to convert.
* @param level - The zoom level of the result. If not provided, the result will have 30 bits of precision.
* @returns The Face-I-J coordinates representing the given XYZ Point.
*/
export function toIJ(xyz, level) {
// Convert the given XYZ Point to Face-S-T coordinates.
const [face, s, t] = toST(xyz);
// Convert the S-T coordinates to I-J coordinates using the STtoIJ function.
let i = STtoIJ(s);
let j = STtoIJ(t);
// If a level is provided, shift the I-J coordinates to the right by (30 - level) bits.
if (level !== undefined) {
i = i >> (30 - level);
j = j >> (30 - level);
}
// Return the Face-I-J coordinates.
return [face, i, j];
}
/**
* Convert an XYZ Point to a lon-lat coord
* @param xyz - The XYZ Point to convert.
* @returns The lon-lat coordinates representing the given XYZ Point.
*/
export function toLonLat(xyz) {
return xyzToLonLat(xyz);
}
/**
* Convert an XYZ Point to an S2CellID
* @param xyz - The XYZ Point to convert.
* @returns The S2CellID representing the given XYZ Point.
*/
export function toS2CellID(xyz) {
return idFromS2Point(xyz);
}
/**
* Take an XYZ Point and add another XYZ Point to it
* @param a - The XYZ Point to add to.
* @param b - The XYZ Point to add.
* @returns - The XYZ Point with the added XYZ Point.
*/
export function add(a, b) {
return [a[0] + b[0], a[1] + b[1], a[2] + b[2]];
}
/**
* Take an XYZ Point and add another XYZ Point to it
* @param a - The XYZ Point to add to.
* @param b - The XYZ Point to add.
*/
export function addMut(a, b) {
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}
/**
* Take an XYZ Point and add an n to each component
* @param xyz - The XYZ Point to add to.
* @param n - The amount to add.
* @returns - The XYZ Point with the added amount.
*/
export function addScalar(xyz, n) {
return [xyz[0] + n, xyz[1] + n, xyz[2] + n];
}
/**
* Take an XYZ Point and subtract another XYZ Point from it
* @param a - The XYZ Point to subtract from.
* @param b - The XYZ Point to subtract.
* @returns - The XYZ Point with the subtracted XYZ Point.
*/
export function sub(a, b) {
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
}
/**
* Take an XYZ Point and subtract an n from each component
* @param xyz - The XYZ Point to subtract from.
* @param n - The amount to subtract.
* @returns - The XYZ Point with the subtracted amount.
*/
export function subScalar(xyz, n) {
return [xyz[0] - n, xyz[1] - n, xyz[2] - n];
}
/**
* Take an XYZ Point and multiply it by another XYZ Point
* @param a - The XYZ Point to multiply.
* @param b - The XYZ Point to multiply.
* @returns - The XYZ Point with the multiplied XYZ Point.
*/
export function mul(a, b) {
return [a[0] * b[0], a[1] * b[1], a[2] * b[2]];
}
/**
* Take an XYZ Point and multiply each component by n
* @param xyz - The XYZ Point to multiply.
* @param n - The amount to multiply.
* @returns - The XYZ Point with the multiplied amount.
*/
export function mulScalar(xyz, n) {
return [xyz[0] * n, xyz[1] * n, xyz[2] * n];
}
/**
* Take an XYZ Point and divide it by another XYZ Point
* @param a - The XYZ Point to divide.
* @param b - The XYZ Point to divide by.
* @returns - The XYZ Point with the multiplied XYZ Point.
*/
export function div(a, b) {
return [a[0] / b[0], a[1] / b[1], a[2] / b[2]];
}
/**
* Take an XYZ Point and divide each component by n
* @param xyz - The XYZ Point to divide.
* @param n - The amount to divide by.
* @returns - The XYZ Point with the multiplied amount.
*/
export function divScalar(xyz, n) {
return [xyz[0] / n, xyz[1] / n, xyz[2] / n];
}
/**
* Take an XYZ Point and divide each component by n
* @param xyz - The XYZ Point to divide.
* @param n - The amount to divide by.
*/
export function divMutScalar(xyz, n) {
xyz[0] /= n;
xyz[1] /= n;
xyz[2] /= n;
}
/**
* Take an XYZ Point and divide each component by its length
* @param xyz - The XYZ Point to divide.
* @returns - The XYZ Point with the divided amount.
*/
export function normalize(xyz) {
const len = length(xyz);
xyz[0] /= len;
xyz[1] /= len;
xyz[2] /= len;
return xyz;
}
/**
* Get the length of the XYZ Point
* @param xyz - The XYZ Point
* @returns - The length of the XYZ Point
*/
export function length(xyz) {
return Math.sqrt(norm2(xyz));
}
/**
* Get the squared length of the XYZ Point with itself
* @param xyz - The XYZ Point
* @returns - The squared length of the XYZ Point
*/
export function norm2(xyz) {
return dot(xyz, xyz);
}
/**
* Invert the XYZ Point
* @param xyz - The XYZ Point
* @returns - The inverted XYZ Point
*/
export function invert(xyz) {
const [x, y, z] = xyz;
return [-x, -y, -z];
}
/**
* dot returns the standard dot product of a and b.
* @param a - The first XYZ Point
* @param b - The second XYZ Point
* @returns - The dot product of the two XYZ Points
*/
export function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
/**
* Get the corss product of two XYZ Points
* @param a - The first XYZ Point
* @param b - The second XYZ Point
* @returns - The cross product of the two XYZ Points
*/
export function cross(a, b) {
return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
}
/**
* Get the distance between two XYZ Points using Earth's size
* @param a - The first XYZ Point
* @param b - The second XYZ Point
* @returns - The distance between the two XYZ Points
*/
export function distanceEarth(a, b) {
a[0] *= EARTH_RADIUS_EQUATORIAL;
b[0] *= EARTH_RADIUS_EQUATORIAL;
a[1] *= EARTH_RADIUS_EQUATORIAL;
b[1] *= EARTH_RADIUS_EQUATORIAL;
a[2] *= EARTH_RADIUS_POLAR;
b[2] *= EARTH_RADIUS_POLAR;
return distance(a, b);
}
/**
* Get the distance between two XYZ Points
* @param a - The first XYZ Point
* @param b - The second XYZ Point
* @returns - The raw distance between the two XYZ Points. Highly inaccurate for large distances
*/
export function distance(a, b) {
const { sqrt, pow, abs } = Math;
return sqrt(pow(abs(b[0] - a[0]), 2) + pow(abs(b[1] - a[1]), 2) + pow(abs(b[2] - a[2]), 2));
}
/**
* @param a - The first XYZ Point
* @param b - The second XYZ Point
* @returns - The angle between the two XYZ Points
*/
export function angle(a, b) {
return Math.atan2(length(cross(a, b)), dot(a, b));
}
/**
* Find the S2 Hilbert Face of the XYZ Point [0, 6)
* @param xyz - The XYZ Point
* @returns - The S2 Hilbert Face
*/
export function getFace(xyz) {
return XYZtoFace(xyz);
}
//# sourceMappingURL=point.js.map