1 |
|
2 | (function (global, factory) {
|
3 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('leaflet')) :
|
4 | typeof define === 'function' && define.amd ? define(['exports', 'leaflet'], factory) :
|
5 | (global = global || self, factory((global.L = global.L || {}, global.L.geodesic = {}), global.L));
|
6 | }(this, (function (exports, L) { 'use strict';
|
7 |
|
8 | |
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | var extendStatics = function(d, b) {
|
25 | extendStatics = Object.setPrototypeOf ||
|
26 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
27 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
28 | return extendStatics(d, b);
|
29 | };
|
30 |
|
31 | function __extends(d, b) {
|
32 | extendStatics(d, b);
|
33 | function __() { this.constructor = d; }
|
34 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
35 | }
|
36 |
|
37 | var __assign = function() {
|
38 | __assign = Object.assign || function __assign(t) {
|
39 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
40 | s = arguments[i];
|
41 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
42 | }
|
43 | return t;
|
44 | };
|
45 | return __assign.apply(this, arguments);
|
46 | };
|
47 |
|
48 | function __spreadArrays() {
|
49 | for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
50 | for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
51 | for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
52 | r[k] = a[j];
|
53 | return r;
|
54 | }
|
55 |
|
56 | var GeodesicCore = (function () {
|
57 | function GeodesicCore(options) {
|
58 | this.options = { wrap: true, steps: 3 };
|
59 | this.ellipsoid = {
|
60 | a: 6378137,
|
61 | b: 6356752.3142,
|
62 | f: 1 / 298.257223563
|
63 | };
|
64 | this.options = __assign(__assign({}, this.options), options);
|
65 | }
|
66 | GeodesicCore.prototype.toRadians = function (degree) {
|
67 | return degree * Math.PI / 180;
|
68 | };
|
69 | GeodesicCore.prototype.toDegrees = function (radians) {
|
70 | return radians * 180 / Math.PI;
|
71 | };
|
72 | |
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 | GeodesicCore.prototype.mod = function (n, p) {
|
80 | var r = n % p;
|
81 | return r < 0 ? r + p : r;
|
82 | };
|
83 | |
84 |
|
85 |
|
86 |
|
87 |
|
88 | GeodesicCore.prototype.wrap360 = function (degrees) {
|
89 | if (0 <= degrees && degrees < 360) {
|
90 | return degrees;
|
91 | }
|
92 | else {
|
93 | return this.mod(degrees, 360);
|
94 | }
|
95 | };
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | GeodesicCore.prototype.wrap = function (degrees, max) {
|
103 | if (max === void 0) { max = 360; }
|
104 | if (-max <= degrees && degrees <= max) {
|
105 | return degrees;
|
106 | }
|
107 | else {
|
108 | return this.mod((degrees + max), 2 * max) - max;
|
109 | }
|
110 | };
|
111 | |
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | GeodesicCore.prototype.direct = function (start, bearing, distance, maxInterations) {
|
123 | if (maxInterations === void 0) { maxInterations = 100; }
|
124 | var φ1 = this.toRadians(start.lat);
|
125 | var λ1 = this.toRadians(start.lng);
|
126 | var α1 = this.toRadians(bearing);
|
127 | var s = distance;
|
128 | var ε = Number.EPSILON * 1000;
|
129 | var _a = this.ellipsoid, a = _a.a, b = _a.b, f = _a.f;
|
130 | var sinα1 = Math.sin(α1);
|
131 | var cosα1 = Math.cos(α1);
|
132 | var tanU1 = (1 - f) * Math.tan(φ1), cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1;
|
133 | var σ1 = Math.atan2(tanU1, cosα1);
|
134 | var sinα = cosU1 * sinα1;
|
135 | var cosSqα = 1 - sinα * sinα;
|
136 | var uSq = cosSqα * (a * a - b * b) / (b * b);
|
137 | var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
138 | var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
139 | var σ = s / (b * A), sinσ = null, cosσ = null, Δσ = null;
|
140 | var cos2σₘ = null;
|
141 | var σʹ = null, iterations = 0;
|
142 | do {
|
143 | cos2σₘ = Math.cos(2 * σ1 + σ);
|
144 | sinσ = Math.sin(σ);
|
145 | cosσ = Math.cos(σ);
|
146 | Δσ = B * sinσ * (cos2σₘ + B / 4 * (cosσ * (-1 + 2 * cos2σₘ * cos2σₘ) -
|
147 | B / 6 * cos2σₘ * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σₘ * cos2σₘ)));
|
148 | σʹ = σ;
|
149 | σ = s / (b * A) + Δσ;
|
150 | } while (Math.abs(σ - σʹ) > ε && ++iterations < maxInterations);
|
151 | if (iterations >= maxInterations) {
|
152 | throw new EvalError("Direct vincenty formula failed to converge after " + maxInterations + " iterations \n (start=" + start.lat + "/" + start.lng + "; bearing=" + bearing + "; distance=" + distance + ")");
|
153 | }
|
154 | var x = sinU1 * sinσ - cosU1 * cosσ * cosα1;
|
155 | var φ2 = Math.atan2(sinU1 * cosσ + cosU1 * sinσ * cosα1, (1 - f) * Math.sqrt(sinα * sinα + x * x));
|
156 | var λ = Math.atan2(sinσ * sinα1, cosU1 * cosσ - sinU1 * sinσ * cosα1);
|
157 | var C = f / 16 * cosSqα * (4 + f * (4 - 3 * cosSqα));
|
158 | var dL = λ - (1 - C) * f * sinα * (σ + C * sinσ * (cos2σₘ + C * cosσ * (-1 + 2 * cos2σₘ * cos2σₘ)));
|
159 | var λ2 = λ1 + dL;
|
160 | var α2 = Math.atan2(sinα, -x);
|
161 | return {
|
162 | lat: this.toDegrees(φ2),
|
163 | lng: this.toDegrees(λ2),
|
164 | bearing: this.wrap360(this.toDegrees(α2))
|
165 | };
|
166 | };
|
167 | |
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 | GeodesicCore.prototype.inverse = function (start, dest, maxInterations, mitigateConvergenceError) {
|
177 | if (maxInterations === void 0) { maxInterations = 100; }
|
178 | if (mitigateConvergenceError === void 0) { mitigateConvergenceError = true; }
|
179 | var p1 = start, p2 = dest;
|
180 | var φ1 = this.toRadians(p1.lat), λ1 = this.toRadians(p1.lng);
|
181 | var φ2 = this.toRadians(p2.lat), λ2 = this.toRadians(p2.lng);
|
182 | var π = Math.PI;
|
183 | var ε = Number.EPSILON;
|
184 |
|
185 | var _a = this.ellipsoid, a = _a.a, b = _a.b, f = _a.f;
|
186 | var dL = λ2 - λ1;
|
187 | var tanU1 = (1 - f) * Math.tan(φ1), cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1;
|
188 | var tanU2 = (1 - f) * Math.tan(φ2), cosU2 = 1 / Math.sqrt((1 + tanU2 * tanU2)), sinU2 = tanU2 * cosU2;
|
189 | var antipodal = Math.abs(dL) > π / 2 || Math.abs(φ2 - φ1) > π / 2;
|
190 | var λ = dL, sinλ = null, cosλ = null;
|
191 | var σ = antipodal ? π : 0, sinσ = 0, cosσ = antipodal ? -1 : 1, sinSqσ = null;
|
192 | var cos2σₘ = 1;
|
193 | var sinα = null, cosSqα = 1;
|
194 | var C = null;
|
195 | var λʹ = null, iterations = 0;
|
196 | do {
|
197 | sinλ = Math.sin(λ);
|
198 | cosλ = Math.cos(λ);
|
199 | sinSqσ = (cosU2 * sinλ) * (cosU2 * sinλ) + (cosU1 * sinU2 - sinU1 * cosU2 * cosλ) * (cosU1 * sinU2 - sinU1 * cosU2 * cosλ);
|
200 | if (Math.abs(sinSqσ) < ε) {
|
201 | break;
|
202 | }
|
203 | sinσ = Math.sqrt(sinSqσ);
|
204 | cosσ = sinU1 * sinU2 + cosU1 * cosU2 * cosλ;
|
205 | σ = Math.atan2(sinσ, cosσ);
|
206 | sinα = cosU1 * cosU2 * sinλ / sinσ;
|
207 | cosSqα = 1 - sinα * sinα;
|
208 | cos2σₘ = (cosSqα !== 0) ? (cosσ - 2 * sinU1 * sinU2 / cosSqα) : 0;
|
209 | C = f / 16 * cosSqα * (4 + f * (4 - 3 * cosSqα));
|
210 | λʹ = λ;
|
211 | λ = dL + (1 - C) * f * sinα * (σ + C * sinσ * (cos2σₘ + C * cosσ * (-1 + 2 * cos2σₘ * cos2σₘ)));
|
212 | var iterationCheck = antipodal ? Math.abs(λ) - π : Math.abs(λ);
|
213 | if (iterationCheck > π) {
|
214 | throw new EvalError('λ > π');
|
215 | }
|
216 | } while (Math.abs(λ - λʹ) > 1e-12 && ++iterations < maxInterations);
|
217 | if (iterations >= maxInterations) {
|
218 | if (mitigateConvergenceError) {
|
219 | return this.inverse(start, new L.LatLng(dest.lat, dest.lng - 0.01), maxInterations, mitigateConvergenceError);
|
220 | }
|
221 | else {
|
222 | throw new EvalError("Inverse vincenty formula failed to converge after " + maxInterations + " iterations \n (start=" + start.lat + "/" + start.lng + "; dest=" + dest.lat + "/" + dest.lng + ")");
|
223 | }
|
224 | }
|
225 | var uSq = cosSqα * (a * a - b * b) / (b * b);
|
226 | var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
227 | var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
228 | var Δσ = B * sinσ * (cos2σₘ + B / 4 * (cosσ * (-1 + 2 * cos2σₘ * cos2σₘ) -
|
229 | B / 6 * cos2σₘ * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σₘ * cos2σₘ)));
|
230 | var s = b * A * (σ - Δσ);
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | var α1 = Math.abs(sinSqσ) < ε ? 0 : Math.atan2(cosU2 * sinλ, cosU1 * sinU2 - sinU1 * cosU2 * cosλ);
|
236 | var α2 = Math.abs(sinSqσ) < ε ? π : Math.atan2(cosU1 * sinλ, -sinU1 * cosU2 + cosU1 * sinU2 * cosλ);
|
237 | return {
|
238 | distance: s,
|
239 | initialBearing: Math.abs(s) < ε ? NaN : this.wrap360(this.toDegrees(α1)),
|
240 | finalBearing: Math.abs(s) < ε ? NaN : this.wrap360(this.toDegrees(α2))
|
241 | };
|
242 | };
|
243 | |
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 | GeodesicCore.prototype.intersection = function (firstPos, firstBearing, secondPos, secondBearing) {
|
255 | var φ1 = this.toRadians(firstPos.lat);
|
256 | var λ1 = this.toRadians(firstPos.lng);
|
257 | var φ2 = this.toRadians(secondPos.lat);
|
258 | var λ2 = this.toRadians(secondPos.lng);
|
259 | var θ13 = this.toRadians(firstBearing);
|
260 | var θ23 = this.toRadians(secondBearing);
|
261 | var Δφ = φ2 - φ1, Δλ = λ2 - λ1;
|
262 | var π = Math.PI;
|
263 | var ε = Number.EPSILON;
|
264 |
|
265 | var δ12 = 2 * Math.asin(Math.sqrt(Math.sin(Δφ / 2) * Math.sin(Δφ / 2)
|
266 | + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2)));
|
267 | if (Math.abs(δ12) < ε) {
|
268 | return firstPos;
|
269 | }
|
270 |
|
271 | var cosθa = (Math.sin(φ2) - Math.sin(φ1) * Math.cos(δ12)) / (Math.sin(δ12) * Math.cos(φ1));
|
272 | var cosθb = (Math.sin(φ1) - Math.sin(φ2) * Math.cos(δ12)) / (Math.sin(δ12) * Math.cos(φ2));
|
273 | var θa = Math.acos(Math.min(Math.max(cosθa, -1), 1));
|
274 | var θb = Math.acos(Math.min(Math.max(cosθb, -1), 1));
|
275 | var θ12 = Math.sin(λ2 - λ1) > 0 ? θa : 2 * π - θa;
|
276 | var θ21 = Math.sin(λ2 - λ1) > 0 ? 2 * π - θb : θb;
|
277 | var α1 = θ13 - θ12;
|
278 | var α2 = θ21 - θ23;
|
279 | if (Math.sin(α1) === 0 && Math.sin(α2) === 0) {
|
280 | return null;
|
281 | }
|
282 | if (Math.sin(α1) * Math.sin(α2) < 0) {
|
283 | return null;
|
284 | }
|
285 | var cosα3 = -Math.cos(α1) * Math.cos(α2) + Math.sin(α1) * Math.sin(α2) * Math.cos(δ12);
|
286 | var δ13 = Math.atan2(Math.sin(δ12) * Math.sin(α1) * Math.sin(α2), Math.cos(α2) + Math.cos(α1) * cosα3);
|
287 | var φ3 = Math.asin(Math.min(Math.max(Math.sin(φ1) * Math.cos(δ13) + Math.cos(φ1) * Math.sin(δ13) * Math.cos(θ13), -1), 1));
|
288 | var Δλ13 = Math.atan2(Math.sin(θ13) * Math.sin(δ13) * Math.cos(φ1), Math.cos(δ13) - Math.sin(φ1) * Math.sin(φ3));
|
289 | var λ3 = λ1 + Δλ13;
|
290 | return new L.LatLng(this.toDegrees(φ3), this.toDegrees(λ3));
|
291 | };
|
292 | GeodesicCore.prototype.midpoint = function (start, dest) {
|
293 |
|
294 |
|
295 |
|
296 | var φ1 = this.toRadians(start.lat);
|
297 | var λ1 = this.toRadians(start.lng);
|
298 | var φ2 = this.toRadians(dest.lat);
|
299 | var Δλ = this.toRadians(dest.lng - start.lng);
|
300 |
|
301 | var A = { x: Math.cos(φ1), y: 0, z: Math.sin(φ1) };
|
302 | var B = { x: Math.cos(φ2) * Math.cos(Δλ), y: Math.cos(φ2) * Math.sin(Δλ), z: Math.sin(φ2) };
|
303 |
|
304 | var C = { x: A.x + B.x, y: A.y + B.y, z: A.z + B.z };
|
305 | var φm = Math.atan2(C.z, Math.sqrt(C.x * C.x + C.y * C.y));
|
306 | var λm = λ1 + Math.atan2(C.y, C.x);
|
307 | return new L.LatLng(this.toDegrees(φm), this.toDegrees(λm));
|
308 | };
|
309 | return GeodesicCore;
|
310 | }());
|
311 |
|
312 | var GeodesicGeometry = (function () {
|
313 | function GeodesicGeometry(options) {
|
314 | this.geodesic = new GeodesicCore();
|
315 | this.steps = (options && options.steps !== undefined) ? options.steps : 3;
|
316 | }
|
317 | |
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | GeodesicGeometry.prototype.recursiveMidpoint = function (start, dest, iterations) {
|
333 | var geom = [start, dest];
|
334 | var midpoint = this.geodesic.midpoint(start, dest);
|
335 | if (iterations > 0) {
|
336 | geom.splice.apply(geom, __spreadArrays([0, 1], this.recursiveMidpoint(start, midpoint, iterations - 1)));
|
337 | geom.splice.apply(geom, __spreadArrays([geom.length - 2, 2], this.recursiveMidpoint(midpoint, dest, iterations - 1)));
|
338 | }
|
339 | else {
|
340 | geom.splice(1, 0, midpoint);
|
341 | }
|
342 | return geom;
|
343 | };
|
344 | |
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 |
|
353 |
|
354 |
|
355 | GeodesicGeometry.prototype.line = function (start, dest) {
|
356 | return this.recursiveMidpoint(start, dest, Math.min(8, this.steps));
|
357 | };
|
358 | GeodesicGeometry.prototype.multiLineString = function (latlngs) {
|
359 | var _this = this;
|
360 | var multiLineString = [];
|
361 | latlngs.forEach(function (linestring) {
|
362 | var segment = [];
|
363 | for (var j = 1; j < linestring.length; j++) {
|
364 | segment.splice.apply(segment, __spreadArrays([segment.length - 1, 1], _this.line(linestring[j - 1], linestring[j])));
|
365 | }
|
366 | multiLineString.push(segment);
|
367 | });
|
368 | return multiLineString;
|
369 | };
|
370 | GeodesicGeometry.prototype.lineString = function (latlngs) {
|
371 | return this.multiLineString([latlngs])[0];
|
372 | };
|
373 | |
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 | GeodesicGeometry.prototype.splitLine = function (startPosition, destPosition) {
|
386 | var antimeridianWest = {
|
387 | point: new L.LatLng(89.9, -180.0000001),
|
388 | bearing: 180
|
389 | };
|
390 | var antimeridianEast = {
|
391 | point: new L.LatLng(89.9, 180.0000001),
|
392 | bearing: 180
|
393 | };
|
394 |
|
395 | var start = new L.LatLng(startPosition.lat, startPosition.lng);
|
396 | var dest = new L.LatLng(destPosition.lat, destPosition.lng);
|
397 | start.lng = this.geodesic.wrap(start.lng, 360);
|
398 | dest.lng = this.geodesic.wrap(dest.lng, 360);
|
399 | if ((dest.lng - start.lng) > 180) {
|
400 | dest.lng = dest.lng - 360;
|
401 | }
|
402 | else if ((dest.lng - start.lng) < -180) {
|
403 | dest.lng = dest.lng + 360;
|
404 | }
|
405 | var result = [[new L.LatLng(start.lat, this.geodesic.wrap(start.lng, 180)), new L.LatLng(dest.lat, this.geodesic.wrap(dest.lng, 180))]];
|
406 |
|
407 | if ((start.lng >= -180) && (start.lng <= 180)) {
|
408 |
|
409 | if (dest.lng < -180) {
|
410 | var bearing = this.geodesic.inverse(start, dest).initialBearing;
|
411 | var intersection = this.geodesic.intersection(start, bearing, antimeridianWest.point, antimeridianWest.bearing);
|
412 | if (intersection) {
|
413 | result = [[start, intersection], [new L.LatLng(intersection.lat, intersection.lng + 360), new L.LatLng(dest.lat, dest.lng + 360)]];
|
414 | }
|
415 | }
|
416 |
|
417 | else if (dest.lng > 180) {
|
418 | var bearing = this.geodesic.inverse(start, dest).initialBearing;
|
419 | var intersection = this.geodesic.intersection(start, bearing, antimeridianEast.point, antimeridianEast.bearing);
|
420 | if (intersection) {
|
421 | result = [[start, intersection], [new L.LatLng(intersection.lat, intersection.lng - 360), new L.LatLng(dest.lat, dest.lng - 360)]];
|
422 | }
|
423 | }
|
424 | }
|
425 |
|
426 | else if ((dest.lng >= -180) && (dest.lng <= 180)) {
|
427 |
|
428 | if (start.lng < -180) {
|
429 | var bearing = this.geodesic.inverse(start, dest).initialBearing;
|
430 | var intersection = this.geodesic.intersection(start, bearing, antimeridianWest.point, antimeridianWest.bearing);
|
431 | if (intersection) {
|
432 | result = [[new L.LatLng(start.lat, start.lng + 360), new L.LatLng(intersection.lat, intersection.lng + 360)], [intersection, dest]];
|
433 | }
|
434 | }
|
435 |
|
436 | else if (start.lng > 180) {
|
437 | var bearing = this.geodesic.inverse(start, dest).initialBearing;
|
438 | var intersection = this.geodesic.intersection(start, bearing, antimeridianWest.point, antimeridianWest.bearing);
|
439 | if (intersection) {
|
440 | result = [[new L.LatLng(start.lat, start.lng - 360), new L.LatLng(intersection.lat, intersection.lng - 360)], [intersection, dest]];
|
441 | }
|
442 | }
|
443 | }
|
444 | return result;
|
445 | };
|
446 | |
447 |
|
448 |
|
449 |
|
450 |
|
451 |
|
452 |
|
453 |
|
454 |
|
455 |
|
456 | GeodesicGeometry.prototype.splitMultiLineString = function (multilinestring) {
|
457 | var _this = this;
|
458 | var result = [];
|
459 | multilinestring.forEach(function (linestring) {
|
460 | if (linestring.length === 1) {
|
461 | result.push(linestring);
|
462 | }
|
463 | else {
|
464 | var segment = [];
|
465 | for (var j = 1; j < linestring.length; j++) {
|
466 | var split = _this.splitLine(linestring[j - 1], linestring[j]);
|
467 | segment.pop();
|
468 | segment = segment.concat(split[0]);
|
469 | if (split.length > 1) {
|
470 | result.push(segment);
|
471 | segment = split[1];
|
472 | }
|
473 | }
|
474 | result.push(segment);
|
475 | }
|
476 | });
|
477 | return result;
|
478 | };
|
479 | GeodesicGeometry.prototype.wrapMultiLineString = function (multilinestring) {
|
480 | var result = [];
|
481 | multilinestring.forEach(function (linestring) {
|
482 | var resultLine = [];
|
483 | var previous = null;
|
484 |
|
485 | linestring.forEach(function (point) {
|
486 | if (previous === null) {
|
487 | resultLine.push(point);
|
488 | previous = point;
|
489 | }
|
490 | else {
|
491 | var diff = point.lng - previous.lng;
|
492 | var offset = Math.sign(diff / 180) * Math.ceil(Math.abs(diff / 180));
|
493 | if (Math.abs(diff) > 180) {
|
494 | resultLine.push(new L.LatLng(point.lat, point.lng - offset * 180));
|
495 | }
|
496 | else {
|
497 | resultLine.push(new L.LatLng(point.lat, point.lng));
|
498 | }
|
499 |
|
500 | }
|
501 | });
|
502 | result.push(resultLine);
|
503 |
|
504 | });
|
505 | return result;
|
506 | };
|
507 | |
508 |
|
509 |
|
510 |
|
511 |
|
512 |
|
513 |
|
514 |
|
515 | GeodesicGeometry.prototype.circle = function (center, radius) {
|
516 | var vertices = [];
|
517 | for (var i = 0; i < this.steps; i++) {
|
518 | var point = this.geodesic.direct(center, 360 / this.steps * i, radius);
|
519 | vertices.push(new L.LatLng(point.lat, point.lng));
|
520 | }
|
521 |
|
522 | vertices.push(new L.LatLng(vertices[0].lat, vertices[0].lng));
|
523 | return vertices;
|
524 | };
|
525 | |
526 |
|
527 |
|
528 |
|
529 |
|
530 | GeodesicGeometry.prototype.splitCircle = function (linestring) {
|
531 | var result = [];
|
532 | result = this.splitMultiLineString([linestring]);
|
533 |
|
534 |
|
535 | if (result.length === 3) {
|
536 | result[2] = __spreadArrays(result[2], result[0]);
|
537 | result.shift();
|
538 | }
|
539 | return result;
|
540 | };
|
541 | |
542 |
|
543 |
|
544 |
|
545 |
|
546 |
|
547 | GeodesicGeometry.prototype.distance = function (start, dest) {
|
548 | return this.geodesic.inverse(new L.LatLng(start.lat, this.geodesic.wrap(start.lng, 180)), new L.LatLng(dest.lat, this.geodesic.wrap(dest.lng, 180))).distance;
|
549 | };
|
550 | GeodesicGeometry.prototype.multilineDistance = function (multilinestring) {
|
551 | var _this = this;
|
552 | var dist = [];
|
553 | multilinestring.forEach(function (linestring) {
|
554 | var segmentDistance = 0;
|
555 | for (var j = 1; j < linestring.length; j++) {
|
556 | segmentDistance += _this.distance(linestring[j - 1], linestring[j]);
|
557 | }
|
558 | dist.push(segmentDistance);
|
559 | });
|
560 | return dist;
|
561 | };
|
562 | GeodesicGeometry.prototype.updateStatistics = function (points, vertices) {
|
563 | var stats = {};
|
564 | stats.distanceArray = this.multilineDistance(points);
|
565 | stats.totalDistance = stats.distanceArray.reduce(function (x, y) { return x + y; }, 0);
|
566 | stats.points = 0;
|
567 | points.forEach(function (item) {
|
568 | stats.points += item.reduce(function (x) { return x + 1; }, 0);
|
569 | });
|
570 | stats.vertices = 0;
|
571 | vertices.forEach(function (item) {
|
572 | stats.vertices += item.reduce(function (x) { return x + 1; }, 0);
|
573 | });
|
574 | return stats;
|
575 | };
|
576 | return GeodesicGeometry;
|
577 | }());
|
578 |
|
579 | function instanceOfLatLngLiteral(object) {
|
580 | return ((typeof object === "object")
|
581 | && (object !== null)
|
582 | && ('lat' in object)
|
583 | && ('lng' in object)
|
584 | && (typeof object.lat === "number")
|
585 | && (typeof object.lng === "number"));
|
586 | }
|
587 | function instanceOfLatLngTuple(object) {
|
588 | return ((object instanceof Array)
|
589 | && (typeof object[0] === "number")
|
590 | && (typeof object[1] === "number"));
|
591 | }
|
592 | function instanceOfLatLngExpression(object) {
|
593 | if (object instanceof L.LatLng) {
|
594 | return true;
|
595 | }
|
596 | else if (instanceOfLatLngTuple(object)) {
|
597 | return true;
|
598 | }
|
599 | else if (instanceOfLatLngLiteral(object)) {
|
600 | return true;
|
601 | }
|
602 | else {
|
603 | return false;
|
604 | }
|
605 | }
|
606 | function latlngExpressiontoLatLng(input) {
|
607 | if (input instanceof L.LatLng) {
|
608 | return input;
|
609 | }
|
610 | else if (instanceOfLatLngTuple(input)) {
|
611 | return new L.LatLng(input[0], input[1]);
|
612 | }
|
613 | else if (instanceOfLatLngLiteral(input)) {
|
614 | return new L.LatLng(input.lat, input.lng);
|
615 | }
|
616 | else {
|
617 | throw new Error("L.LatLngExpression expected. Unknown object found.");
|
618 | }
|
619 | }
|
620 | function latlngExpressionArraytoLatLngArray(input) {
|
621 | var latlng = [];
|
622 | var _loop_1 = function (group) {
|
623 |
|
624 | if (instanceOfLatLngExpression(group)) {
|
625 | var sub_1 = [];
|
626 | input.forEach(function (point) {
|
627 | sub_1.push(latlngExpressiontoLatLng(point));
|
628 | });
|
629 | latlng.push(sub_1);
|
630 | return "break";
|
631 | }
|
632 |
|
633 | else if (group instanceof Array) {
|
634 | if (instanceOfLatLngExpression(group[0])) {
|
635 | var sub_2 = [];
|
636 | group.forEach(function (point) {
|
637 | sub_2.push(latlngExpressiontoLatLng(point));
|
638 | });
|
639 | latlng.push(sub_2);
|
640 | }
|
641 | else {
|
642 | throw new Error("L.LatLngExpression[] | L.LatLngExpression[][] expected. Unknown object found.");
|
643 | }
|
644 | }
|
645 | else {
|
646 | throw new Error("L.LatLngExpression[] | L.LatLngExpression[][] expected. Unknown object found.");
|
647 | }
|
648 | };
|
649 | for (var _i = 0, input_1 = input; _i < input_1.length; _i++) {
|
650 | var group = input_1[_i];
|
651 | var state_1 = _loop_1(group);
|
652 | if (state_1 === "break")
|
653 | break;
|
654 | }
|
655 | return latlng;
|
656 | }
|
657 |
|
658 | |
659 |
|
660 |
|
661 | var GeodesicLine = (function (_super) {
|
662 | __extends(GeodesicLine, _super);
|
663 | function GeodesicLine(latlngs, options) {
|
664 | var _this = _super.call(this, [], options) || this;
|
665 |
|
666 | _this.defaultOptions = { wrap: true, steps: 3 };
|
667 |
|
668 | _this.statistics = {};
|
669 |
|
670 | _this.points = [];
|
671 | L.Util.setOptions(_this, __assign(__assign({}, _this.defaultOptions), options));
|
672 | _this.geom = new GeodesicGeometry(_this.options);
|
673 | if (latlngs !== undefined) {
|
674 | _this.setLatLngs(latlngs);
|
675 | }
|
676 | return _this;
|
677 | }
|
678 |
|
679 | GeodesicLine.prototype.updateGeometry = function () {
|
680 | var geodesic = [];
|
681 | geodesic = this.geom.multiLineString(this.points);
|
682 | this.statistics = this.geom.updateStatistics(this.points, geodesic);
|
683 | if (this.options.wrap) {
|
684 | var split = this.geom.splitMultiLineString(geodesic);
|
685 | _super.prototype.setLatLngs.call(this, split);
|
686 | }
|
687 | else {
|
688 | _super.prototype.setLatLngs.call(this, this.geom.wrapMultiLineString(geodesic));
|
689 | }
|
690 | };
|
691 | |
692 |
|
693 |
|
694 |
|
695 | GeodesicLine.prototype.setLatLngs = function (latlngs) {
|
696 | this.points = latlngExpressionArraytoLatLngArray(latlngs);
|
697 | this.updateGeometry();
|
698 | return this;
|
699 | };
|
700 | |
701 |
|
702 |
|
703 |
|
704 |
|
705 | GeodesicLine.prototype.addLatLng = function (latlng, latlngs) {
|
706 | var point = latlngExpressiontoLatLng(latlng);
|
707 | if (this.points.length === 0) {
|
708 | this.points.push([point]);
|
709 | }
|
710 | else {
|
711 | if (latlngs === undefined) {
|
712 | this.points[this.points.length - 1].push(point);
|
713 | }
|
714 | else {
|
715 | latlngs.push(point);
|
716 | }
|
717 | }
|
718 | this.updateGeometry();
|
719 | return this;
|
720 | };
|
721 | |
722 |
|
723 |
|
724 |
|
725 | GeodesicLine.prototype.fromGeoJson = function (input) {
|
726 | var latlngs = [];
|
727 | var features = [];
|
728 | if (input.type === "FeatureCollection") {
|
729 | features = input.features;
|
730 | }
|
731 | else if (input.type === "Feature") {
|
732 | features = [input];
|
733 | }
|
734 | else if (["MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon"].includes(input.type)) {
|
735 | features = [{
|
736 | type: "Feature",
|
737 | geometry: input,
|
738 | properties: {}
|
739 | }];
|
740 | }
|
741 | else {
|
742 | console.log("[Leaflet.Geodesic] fromGeoJson() - Type \"" + input.type + "\" not supported.");
|
743 | }
|
744 | features.forEach(function (feature) {
|
745 | switch (feature.geometry.type) {
|
746 | case "MultiPoint":
|
747 | case "LineString":
|
748 | latlngs = __spreadArrays(latlngs, [L.GeoJSON.coordsToLatLngs(feature.geometry.coordinates, 0)]);
|
749 | break;
|
750 | case "MultiLineString":
|
751 | case "Polygon":
|
752 | latlngs = __spreadArrays(latlngs, L.GeoJSON.coordsToLatLngs(feature.geometry.coordinates, 1));
|
753 | break;
|
754 | case "MultiPolygon":
|
755 | feature.geometry.coordinates.forEach(function (item) {
|
756 | latlngs = __spreadArrays(latlngs, L.GeoJSON.coordsToLatLngs(item, 1));
|
757 | });
|
758 | break;
|
759 | default:
|
760 | console.log("[Leaflet.Geodesic] fromGeoJson() - Type \"" + feature.geometry.type + "\" not supported.");
|
761 | }
|
762 | });
|
763 | if (latlngs.length) {
|
764 | this.setLatLngs(latlngs);
|
765 | }
|
766 | return this;
|
767 | };
|
768 | |
769 |
|
770 |
|
771 |
|
772 |
|
773 |
|
774 | GeodesicLine.prototype.distance = function (start, dest) {
|
775 | return this.geom.distance(latlngExpressiontoLatLng(start), latlngExpressiontoLatLng(dest));
|
776 | };
|
777 | return GeodesicLine;
|
778 | }(L.Polyline));
|
779 |
|
780 | |
781 |
|
782 |
|
783 | var GeodesicCircleClass = (function (_super) {
|
784 | __extends(GeodesicCircleClass, _super);
|
785 | function GeodesicCircleClass(center, options) {
|
786 | var _this = _super.call(this, [], options) || this;
|
787 | _this.defaultOptions = { wrap: true, steps: 24, fill: true, noClip: true };
|
788 | _this.statistics = {};
|
789 | L.Util.setOptions(_this, __assign(__assign({}, _this.defaultOptions), options));
|
790 |
|
791 | var extendedOptions = _this.options;
|
792 | _this.radius = (extendedOptions.radius === undefined) ? 1000 * 1000 : extendedOptions.radius;
|
793 | _this.center = (center === undefined) ? new L.LatLng(0, 0) : latlngExpressiontoLatLng(center);
|
794 | _this.geom = new GeodesicGeometry(_this.options);
|
795 |
|
796 | _this.update();
|
797 | return _this;
|
798 | }
|
799 | |
800 |
|
801 |
|
802 | GeodesicCircleClass.prototype.update = function () {
|
803 | var circle = this.geom.circle(this.center, this.radius);
|
804 | this.statistics = this.geom.updateStatistics([[this.center]], [circle]);
|
805 |
|
806 | this.statistics.totalDistance = this.geom.multilineDistance([circle]).reduce(function (x, y) { return x + y; }, 0);
|
807 | if (this.options.wrap) {
|
808 | var split = this.geom.splitCircle(circle);
|
809 | _super.prototype.setLatLngs.call(this, split);
|
810 | }
|
811 | else {
|
812 | _super.prototype.setLatLngs.call(this, circle);
|
813 | }
|
814 | };
|
815 | |
816 |
|
817 |
|
818 |
|
819 |
|
820 | GeodesicCircleClass.prototype.distanceTo = function (latlng) {
|
821 | var dest = latlngExpressiontoLatLng(latlng);
|
822 | return this.geom.distance(this.center, dest);
|
823 | };
|
824 | |
825 |
|
826 |
|
827 |
|
828 |
|
829 | GeodesicCircleClass.prototype.setLatLng = function (center, radius) {
|
830 | this.center = latlngExpressiontoLatLng(center);
|
831 | this.radius = radius ? radius : this.radius;
|
832 | this.update();
|
833 | };
|
834 | |
835 |
|
836 |
|
837 |
|
838 |
|
839 | GeodesicCircleClass.prototype.setRadius = function (radius, center) {
|
840 | this.radius = radius;
|
841 | this.center = center ? latlngExpressiontoLatLng(center) : this.center;
|
842 | this.update();
|
843 | };
|
844 | return GeodesicCircleClass;
|
845 | }(L.Polyline));
|
846 |
|
847 | if (typeof window.L !== "undefined") {
|
848 | window.L.Geodesic = GeodesicLine;
|
849 | window.L.geodesic = function () {
|
850 | var args = [];
|
851 | for (var _i = 0; _i < arguments.length; _i++) {
|
852 | args[_i] = arguments[_i];
|
853 | }
|
854 | return new (GeodesicLine.bind.apply(GeodesicLine, __spreadArrays([void 0], args)))();
|
855 | };
|
856 | window.L.GeodesicCircle = GeodesicCircleClass;
|
857 | window.L.geodesiccircle = function () {
|
858 | var args = [];
|
859 | for (var _i = 0; _i < arguments.length; _i++) {
|
860 | args[_i] = arguments[_i];
|
861 | }
|
862 | return new (GeodesicCircleClass.bind.apply(GeodesicCircleClass, __spreadArrays([void 0], args)))();
|
863 | };
|
864 | }
|
865 |
|
866 | exports.GeodesicCircleClass = GeodesicCircleClass;
|
867 | exports.GeodesicLine = GeodesicLine;
|
868 |
|
869 | Object.defineProperty(exports, '__esModule', { value: true });
|
870 |
|
871 | })));
|