@progress/kendo-charts
Version:
Kendo UI platform-independent Charts library
202 lines (166 loc) • 6.15 kB
JavaScript
import {
Class,
deepExtend,
deg,
rad,
round,
defined
} from '../common';
import {
datums
} from './datums';
function toSquare(value) {
return value * value;
}
var math = Math,
abs = math.abs,
atan = math.atan,
atan2 = math.atan2,
cos = math.cos,
sin = math.sin,
tan = math.tan;
export var Location = (function (Class) {
function Location(lat, lng) {
Class.call(this);
this.initProperties();
if (arguments.length === 1) {
this.lat = lat[0];
this.lng = lat[1];
} else {
this.lat = lat;
this.lng = lng;
}
}
if ( Class ) Location.__proto__ = Class;
Location.prototype = Object.create( Class && Class.prototype );
Location.prototype.constructor = Location;
Location.prototype.initProperties = function initProperties () {
deepExtend(this, {
DISTANCE_ITERATIONS: 100,
DISTANCE_CONVERGENCE: 1e-12,
DISTANCE_PRECISION: 2,
FORMAT: '{0:N6}{1:N6}'
});
};
Location.prototype.toArray = function toArray () {
return [
this.lat,
this.lng
];
};
Location.prototype.equals = function equals (loc) {
return loc && loc.lat === this.lat && loc.lng === this.lng;
};
Location.prototype.clone = function clone () {
return new Location(this.lat, this.lng);
};
Location.prototype.round = function round$1 (precision) {
this.lng = round(this.lng, precision);
this.lat = round(this.lat, precision);
return this;
};
Location.prototype.wrap = function wrap () {
this.lng = this.lng % 180;
this.lat = this.lat % 90;
return this;
};
Location.prototype.distanceTo = function distanceTo (dest, datum) {
return this.greatCircleTo(dest, datum).distance;
};
Location.prototype.destination = function destination (distance, initialBearing, initialDatum) {
var bearing = rad(initialBearing);
var datum = initialDatum || datums.WGS84;
var fromLat = rad(this.lat);
var fromLng = rad(this.lng);
var dToR = distance / datum.a;
var lat = math.asin(sin(fromLat) * cos(dToR) + cos(fromLat) * sin(dToR) * cos(bearing));
var lng = fromLng + atan2(sin(bearing) * sin(dToR) * cos(fromLat), cos(dToR) - sin(fromLat) * sin(lat));
return new Location(deg(lat), deg(lng));
};
Location.prototype.greatCircleTo = function greatCircleTo (initialDest, initialDatum) {
var this$1 = this;
var dest = Location.create(dest);
var datum = initialDatum || datums.WGS84;
if (!dest || this.clone().round(8).equals(dest.clone().round(8))) {
return {
distance: 0,
azimuthFrom: 0,
azimuthTo: 0
};
}
// See http://en.wikipedia.org/wiki/Vincenty's_formulae#Notation
// o == sigma
// A == alpha
var a = datum.a;
var b = datum.b;
var f = datum.f;
var L = rad(dest.lng - this.lng);
var U1 = atan((1 - f) * tan(rad(this.lat)));
var sinU1 = sin(U1);
var cosU1 = cos(U1);
var U2 = atan((1 - f) * tan(rad(dest.lat)));
var sinU2 = sin(U2);
var cosU2 = cos(U2);
var lambda = L;
var prevLambda;
var i = this.DISTANCE_ITERATIONS;
var converged = false;
var sinLambda;
var cosLambda;
var sino;
var cosA2;
var coso;
var cos2om;
var sigma;
while (!converged && i-- > 0) {
sinLambda = sin(lambda);
cosLambda = cos(lambda);
sino = math.sqrt(toSquare(cosU2 * sinLambda) + toSquare(cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
coso = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
sigma = atan2(sino, coso);
var sinA = cosU1 * cosU2 * sinLambda / sino;
cosA2 = 1 - toSquare(sinA);
cos2om = 0;
if (cosA2 !== 0) {
cos2om = coso - 2 * sinU1 * sinU2 / cosA2;
}
prevLambda = lambda;
var C = f / 16 * cosA2 * (4 + f * (4 - 3 * cosA2));
lambda = L + (1 - C) * f * sinA * (sigma + C * sino * (cos2om + C * coso * (-1 + 2 * toSquare(cos2om))));
converged = abs(lambda - prevLambda) <= this$1.DISTANCE_CONVERGENCE;
}
var u2 = cosA2 * (toSquare(a) - toSquare(b)) / toSquare(b);
var A = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));
var B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2)));
var deltao = B * sino * (cos2om + B / 4 * (coso * (-1 + 2 * toSquare(cos2om)) - B / 6 * cos2om * (-3 + 4 * toSquare(sino)) * (-3 + 4 * toSquare(cos2om))));
var azimuthFrom = atan2(cosU2 * sinLambda, cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
var azimuthTo = atan2(cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
return {
distance: round(b * A * (sigma - deltao), this.DISTANCE_PRECISION),
azimuthFrom: deg(azimuthFrom),
azimuthTo: deg(azimuthTo)
};
};
// IE < 9 doesn't allow to override toString on definition
Location.prototype.toString = function toString () {
// return kendo.format(this.FORMAT, this.lat, this.lng);
return String(this.lat) + "," + String(this.lng);
};
Location.fromLngLat = function fromLngLat (lngAndLat) {
return new Location(lngAndLat[1], lngAndLat[0]);
};
Location.fromLatLng = function fromLatLng (lngAndLat) {
return new Location(lngAndLat[0], lngAndLat[1]);
};
Location.create = function create (a, b) {
if (defined(a)) {
if (a instanceof Location) {
return a.clone();
} else if (arguments.length === 1 && a.length === 2) {
return Location.fromLatLng(a);
}
return new Location(a, b);
}
};
return Location;
}(Class));