12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- // https://en.wikipedia.org/wiki/Rhumb_line
- var helpers_1 = require("@turf/helpers");
- var invariant_1 = require("@turf/invariant");
- /**
- * Returns the destination {@link Point} having travelled the given distance along a Rhumb line from the
- * origin Point with the (varant) given bearing.
- *
- * @name rhumbDestination
- * @param {Coord} origin starting point
- * @param {number} distance distance from the starting point
- * @param {number} bearing varant bearing angle ranging from -180 to 180 degrees from north
- * @param {Object} [options={}] Optional parameters
- * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
- * @param {Object} [options.properties={}] translate properties to destination point
- * @returns {Feature<Point>} Destination point.
- * @example
- * var pt = turf.point([-75.343, 39.984], {"marker-color": "F00"});
- * var distance = 50;
- * var bearing = 90;
- * var options = {units: 'miles'};
- *
- * var destination = turf.rhumbDestination(pt, distance, bearing, options);
- *
- * //addToMap
- * var addToMap = [pt, destination]
- * destination.properties['marker-color'] = '#00F';
- */
- function rhumbDestination(origin, distance, bearing, options) {
- if (options === void 0) { options = {}; }
- var wasNegativeDistance = distance < 0;
- var distanceInMeters = helpers_1.convertLength(Math.abs(distance), options.units, "meters");
- if (wasNegativeDistance)
- distanceInMeters = -Math.abs(distanceInMeters);
- var coords = invariant_1.getCoord(origin);
- var destination = calculateRhumbDestination(coords, distanceInMeters, bearing);
- // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)
- // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678
- destination[0] +=
- destination[0] - coords[0] > 180
- ? -360
- : coords[0] - destination[0] > 180
- ? 360
- : 0;
- return helpers_1.point(destination, options.properties);
- }
- /**
- * Returns the destination point having travelled along a rhumb line from origin point the given
- * distance on the given bearing.
- * Adapted from Geodesy: http://www.movable-type.co.uk/scripts/latlong.html#rhumblines
- *
- * @private
- * @param {Array<number>} origin - point
- * @param {number} distance - Distance travelled, in same units as earth radius (default: metres).
- * @param {number} bearing - Bearing in degrees from north.
- * @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres).
- * @returns {Array<number>} Destination point.
- */
- function calculateRhumbDestination(origin, distance, bearing, radius) {
- // φ => phi
- // λ => lambda
- // ψ => psi
- // Δ => Delta
- // δ => delta
- // θ => theta
- radius = radius === undefined ? helpers_1.earthRadius : Number(radius);
- var delta = distance / radius; // angular distance in radians
- var lambda1 = (origin[0] * Math.PI) / 180; // to radians, but without normalize to 𝜋
- var phi1 = helpers_1.degreesToRadians(origin[1]);
- var theta = helpers_1.degreesToRadians(bearing);
- var DeltaPhi = delta * Math.cos(theta);
- var 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;
- }
- var 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
- var q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);
- var DeltaLambda = (delta * Math.sin(theta)) / q;
- var lambda2 = lambda1 + DeltaLambda;
- return [
- (((lambda2 * 180) / Math.PI + 540) % 360) - 180,
- (phi2 * 180) / Math.PI,
- ]; // normalise to −180..+180°
- }
- exports.default = rhumbDestination;
|