Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export default function destination<p>(
origin: Coord,
distance: number,
bearing: number,
options: {
units?: Units,
properties?: P,
} = {},
): Feature {
// Handle input
const coordinates1 = getCoord(origin);
const longitude1 = degreesToRadians(coordinates1[0]);
const latitude1 = degreesToRadians(coordinates1[1]);
const bearingRad = degreesToRadians(bearing);
const radians = lengthToRadians(distance, options.units);
// Main
const latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +
Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad));
const longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),
Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));
const lng = radiansToDegrees(longitude2);
const lat = radiansToDegrees(latitude2);
return point([lng, lat], options.properties);
}
</p>
function calculateRhumbBearing(from: number[], to: number[]) {
// φ => phi
// Δλ => deltaLambda
// Δψ => deltaPsi
// θ => theta
const phi1 = degreesToRadians(from[1]);
const phi2 = degreesToRadians(to[1]);
let deltaLambda = degreesToRadians((to[0] - from[0]));
// if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian:
if (deltaLambda > Math.PI) { deltaLambda -= 2 * Math.PI; }
if (deltaLambda < -Math.PI) { deltaLambda += 2 * Math.PI; }
const deltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4));
const theta = Math.atan2(deltaLambda, deltaPsi);
return (radiansToDegrees(theta) + 360) % 360;
}
export default function bearing(start: Coord, end: Coord, options: {
final?: boolean,
} = {}): number {
// Reverse calculation
if (options.final === true) { return calculateFinalBearing(start, end); }
const coordinates1 = getCoord(start);
const coordinates2 = getCoord(end);
const lon1 = degreesToRadians(coordinates1[0]);
const lon2 = degreesToRadians(coordinates2[0]);
const lat1 = degreesToRadians(coordinates1[1]);
const lat2 = degreesToRadians(coordinates2[1]);
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
const b = Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
return radiansToDegrees(Math.atan2(a, b));
}
export default function bearing(start: Coord, end: Coord, options: {
final?: boolean,
} = {}): number {
// Reverse calculation
if (options.final === true) { return calculateFinalBearing(start, end); }
const coordinates1 = getCoord(start);
const coordinates2 = getCoord(end);
const lon1 = degreesToRadians(coordinates1[0]);
const lon2 = degreesToRadians(coordinates2[0]);
const lat1 = degreesToRadians(coordinates1[1]);
const lat2 = degreesToRadians(coordinates2[1]);
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
const b = Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
return radiansToDegrees(Math.atan2(a, b));
}
function destination(origin, distance, bearing, options) {
// Optional parameters
options = options || {};
if (!helpers.isObject(options)) throw new Error('options is invalid');
var units = options.units;
var properties = options.properties;
// Handle input
var coordinates1 = invariant.getCoord(origin);
var longitude1 = helpers.degreesToRadians(coordinates1[0]);
var latitude1 = helpers.degreesToRadians(coordinates1[1]);
var bearing_rad = helpers.degreesToRadians(bearing);
var radians = helpers.lengthToRadians(distance, units);
// Main
var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +
Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearing_rad));
var longitude2 = longitude1 + Math.atan2(Math.sin(bearing_rad) * Math.sin(radians) * Math.cos(latitude1),
Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));
var lng = helpers.radiansToDegrees(longitude2);
var lat = helpers.radiansToDegrees(latitude2);
return helpers.point([lng, lat], properties);
}
function calculateRhumbBearing(from: number[], to: number[]) {
// φ => phi
// Δλ => deltaLambda
// Δψ => deltaPsi
// θ => theta
const phi1 = degreesToRadians(from[1]);
const phi2 = degreesToRadians(to[1]);
let deltaLambda = degreesToRadians((to[0] - from[0]));
// if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian:
if (deltaLambda > Math.PI) { deltaLambda -= 2 * Math.PI; }
if (deltaLambda < -Math.PI) { deltaLambda += 2 * Math.PI; }
const deltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4));
const theta = Math.atan2(deltaLambda, deltaPsi);
return (radiansToDegrees(theta) + 360) % 360;
}
export default function destination<p>(
origin: Coord,
distance: number,
bearing: number,
options: {
units?: Units,
properties?: P,
} = {},
): Feature {
// Handle input
const coordinates1 = getCoord(origin);
const longitude1 = degreesToRadians(coordinates1[0]);
const latitude1 = degreesToRadians(coordinates1[1]);
const bearingRad = degreesToRadians(bearing);
const radians = lengthToRadians(distance, options.units);
// Main
const latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +
Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad));
const longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),
Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));
const lng = radiansToDegrees(longitude2);
const lat = radiansToDegrees(latitude2);
return point([lng, lat], options.properties);
}
</p>
function calculateRhumbDestination(origin: number[], distance: number, bearing: number, radius?: number) {
// φ => phi
// λ => lambda
// ψ => psi
// Δ => Delta
// δ => delta
// θ => theta
radius = (radius === undefined) ? earthRadius : Number(radius);
const delta = distance / radius; // angular distance in radians
const lambda1 = origin[0] * Math.PI / 180; // to radians, but without normalize to 𝜋
const phi1 = degreesToRadians(origin[1]);
const theta = degreesToRadians(bearing);
const DeltaPhi = delta * Math.cos(theta);
let phi2 = phi1 + DeltaPhi;
// check for some daft bugger going past the pole, normalise latitude if so
if (Math.abs(phi2) > Math.PI / 2) { phi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2; }
const DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4));
// E-W course becomes ill-conditioned with 0/0
const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);
const DeltaLambda = delta * Math.sin(theta) / q;
const lambda2 = lambda1 + DeltaLambda;
return [((lambda2 * 180 / Math.PI) + 540) % 360 - 180, phi2 * 180 / Math.PI]; // normalise to −180..+180°
}
export function lnglatDistance(
coordinates1: [number, number],
coordinates2: [number, number],
units?: Units,
): number {
const dLat = degreesToRadians(coordinates2[1] - coordinates1[1]);
const dLon = degreesToRadians(coordinates2[0] - coordinates1[0]);
const lat1 = degreesToRadians(coordinates1[1]);
const lat2 = degreesToRadians(coordinates2[1]);
const a =
Math.pow(Math.sin(dLat / 2), 2) +
Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);
return radiansToLength(
2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)),
(units = 'meters'),
);
}