From e0ee3ac2abedc99fe3ce629602eaa7919216b363 Mon Sep 17 00:00:00 2001 From: qnstie Date: Wed, 17 Jul 2013 16:16:23 +0200 Subject: [PATCH 01/32] Extended redraw() method to fix behavior during editing --- src/L.Geodesic.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index b23ff88..9771e00 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -10,20 +10,21 @@ }, setLatLngs: function (latlngs) { this._latlngsinit = this._convertLatLngs(latlngs); - this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); return this.redraw(); }, addLatLng: function (latlng) { this._latlngsinit.push(L.latLng(latlng)); - this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); return this.redraw(); }, spliceLatLngs: function () { // (Number index, Number howMany) var removed = [].splice.apply(this._latlngsinit, arguments); this._convertLatLngs(this._latlngsinit); - this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); this.redraw(); return removed; + }, + redraw: function() { + this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); + return Klass.prototype.redraw.call(this); } }); } From 8ba3c19848b88dbd29bff940109e476e43b7891d Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Thu, 1 Aug 2013 00:12:46 +0100 Subject: [PATCH 02/32] commit start of work, so no files are pending for new release --- src/L.Geodesic.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 9771e00..7da6306 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -102,6 +102,13 @@ } });*/ +//TODO: finish this... + L.GeodesicCircle = L.Path.extend({ + initialise: function (latlng, radius, options) { + L.Path.prototype.initialise.call(this, options); + } + }); + L.geodesicPolyline = function (latlngs, options) { return new L.GeodesicPolyline(latlngs, options); From 243ef1431f7cfa4f68043092cea3c21c09d443f3 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Fri, 2 Aug 2013 07:21:04 +0100 Subject: [PATCH 03/32] first attempt at geodesic circles - for #292 (alsao see #201 and #425) --- src/L.Geodesic.js | 91 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 7da6306..2885681 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -102,11 +102,85 @@ } });*/ -//TODO: finish this... - L.GeodesicCircle = L.Path.extend({ - initialise: function (latlng, radius, options) { - L.Path.prototype.initialise.call(this, options); - } + + L.GeodesicCircle = L.Polygon.extend({ + initialize: function (latlng, radius, options) { + this._latlng = L.latLng(latlng); + this._mRadius = radius; + + points = this._calcPoints(); + + L.Polygon.prototype.initialize.call(this, points, options); + }, + + options: { + fill: true + }, + + setLatLng: function (latlng) { + this._latlng = L.latLng(latlng); + points = this._calcPoints(); + this.setLatLngs(points); + }, + + setRadius: function (radius) { + this._mRadius = radius; + points = this._calcPoints(); + this.setLatLngs(points); + + }, + + getLatLng: function () { + return this._latlng; + }, + + getRadius: function() { + return this._mRadius; + }, + + + _calcPoints: function() { + var R = 6378137; //earth radius in meters (approx - taken from leaflet source code) + var d2r = L.LatLng.DEG_TO_RAD; + var r2d = L.LatLng.RAD_TO_DEG; +//console.log("geodesicCircle: radius = "+this._mRadius+"m, centre "+this._latlng.lat+","+this._latlng.lng); + + // circle radius as an angle from the centre of the earth + var radRadius = this._mRadius / R * Math.PI; +//console.log(" (radius in radians "+radRadius); + + // pre-calculate various values used for every point on the circle + var centreLat = this._latlng.lat * d2r; + var centreLng = this._latlng.lng * d2r; + + var cosCentreLat = Math.cos(centreLat); + var sinCentreLat = Math.sin(centreLat); + + var cosRadRadius = Math.cos(radRadius); + var sinRadRadius = Math.sin(radRadius); + + var calcLatLngAtAngle = function(angle) { + var lat = Math.asin(sinCentreLat*cosRadRadius + cosCentreLat*sinRadRadius*Math.cos(angle)); + + var lon = centreLng + Math.asin( Math.sin(angle) * sinRadRadius / cosCentreLat ) + + return L.latLng(lat * r2d,lon * r2d); + } + + + var segments = Math.max(32,Math.floor(this._mRadius/1000)); +//console.log(" (drawing circle as "+segments+" lines)"); + var points = []; + for (var i=0; i Date: Fri, 2 Aug 2013 07:31:03 +0100 Subject: [PATCH 04/32] fix geodesic circle radius - was scaling the radius by PI --- src/L.Geodesic.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 2885681..e250cae 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -146,7 +146,8 @@ //console.log("geodesicCircle: radius = "+this._mRadius+"m, centre "+this._latlng.lat+","+this._latlng.lng); // circle radius as an angle from the centre of the earth - var radRadius = this._mRadius / R * Math.PI; + var radRadius = this._mRadius / R; + //console.log(" (radius in radians "+radRadius); // pre-calculate various values used for every point on the circle From 066e6bd3e13f62f91d160a67c334401502852b83 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sun, 4 Aug 2013 20:49:58 +0100 Subject: [PATCH 05/32] in geodesic line calculation, add the final point unmodified rather than running through the maths fix #471 - and is a slight optimisation --- src/L.Geodesic.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index e250cae..3b59a7b 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -48,7 +48,11 @@ d = Math.atan2(Math.sqrt( Math.pow(Math.cos(lat2) * Math.sin(dLng), 2) + Math.pow(Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng), 2) ), Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLng)); segments = Math.ceil(d * R / maxlength); - for (i = 1; i <= segments; i++) { + // loop starts at 1 - we don't add the very first point + // loop ends before 'segments' is reached - we don't add the very last point here but outside the loop + // (this was to fix a bug - https://github.com/jonatkins/ingress-intel-total-conversion/issues/471 + // rounding errors? maths bug? not sure - but it solves the issue! and is a slight optimisation) + for (i = 1; i < segments; i++) { // http://williams.best.vwh.net/avform.htm#Intermediate f = i / segments; A = Math.sin((1-f)*d) / Math.sin(d); @@ -61,6 +65,8 @@ convertedPoints.push(L.latLng([fLat, fLng])); } + // push the final point unmodified + convertedPoints.push(L.latLng(endLatlng)); } L.geodesicConvertLines = function (latlngs, fill) { From 0ff610fbf2716a8a46981f68382ba6260e447149 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sun, 20 Oct 2013 22:55:55 +0100 Subject: [PATCH 06/32] fix geodesic circle - formula had errors! https://plus.google.com/108582664457219405296/posts/CoNTvk5i4xF --- src/L.Geodesic.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 3b59a7b..3ab8ae5 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -168,10 +168,9 @@ var calcLatLngAtAngle = function(angle) { var lat = Math.asin(sinCentreLat*cosRadRadius + cosCentreLat*sinRadRadius*Math.cos(angle)); + var lng = centreLng + Math.atan2(Math.sin(angle)*sinRadRadius*cosCentreLat, cosRadRadius-sinCentreLat*Math.sin(lat)); - var lon = centreLng + Math.asin( Math.sin(angle) * sinRadRadius / cosCentreLat ) - - return L.latLng(lat * r2d,lon * r2d); + return L.latLng(lat * r2d,lng * r2d); } From 87fa20bf67a9e387011922cce922b99f2898aeea Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sun, 27 Oct 2013 16:06:35 +0000 Subject: [PATCH 07/32] geodesic lines - improved handling of lines that cross the antimeridian works fine as long as the longitude difference is under 180 degrees --- src/L.Geodesic.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 3ab8ae5..f20e7e8 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -38,7 +38,7 @@ lat1, lat2, lng1, lng2, dLng, d, segments, f, A, B, x, y, z, fLat, fLng; - dLng = Math.abs(endLatlng.lng - startLatlng.lng) * d2r; + dLng = (endLatlng.lng - startLatlng.lng) * d2r; lat1 = startLatlng.lat * d2r; lat2 = endLatlng.lat * d2r; lng1 = startLatlng.lng * d2r; @@ -54,14 +54,15 @@ // rounding errors? maths bug? not sure - but it solves the issue! and is a slight optimisation) for (i = 1; i < segments; i++) { // http://williams.best.vwh.net/avform.htm#Intermediate + // modified to handle longitude above +-180 degrees f = i / segments; A = Math.sin((1-f)*d) / Math.sin(d); B = Math.sin(f*d) / Math.sin(d); - x = A * Math.cos(lat1) * Math.cos(lng1) + B * Math.cos(lat2) * Math.cos(lng2); - y = A * Math.cos(lat1) * Math.sin(lng1) + B * Math.cos(lat2) * Math.sin(lng2); - z = A * Math.sin(lat1) + B * Math.sin(lat2); + x = A * Math.cos(lat1) * Math.cos(0) + B * Math.cos(lat2) * Math.cos(dLng); + y = A * Math.cos(lat1) * Math.sin(0) + B * Math.cos(lat2) * Math.sin(dLng); + z = A * Math.sin(lat1) + B * Math.sin(lat2); fLat = r2d * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))); - fLng = r2d * Math.atan2(y, x); + fLng = r2d * (Math.atan2(y, x)+lng1); convertedPoints.push(L.latLng([fLat, fLng])); } From a563ae4dda47137105d5ca9cd5e3d68c0ee8778e Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Thu, 21 Nov 2013 05:30:21 +0000 Subject: [PATCH 08/32] geodesic lines: improve the handling for lines that extend beyond the antimeridian. no odd straight line segments leaflet doesn't have particularly great handling for this, but this is a reasonable measure for now --- src/L.Geodesic.js | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index f20e7e8..0480b8d 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -71,14 +71,28 @@ } L.geodesicConvertLines = function (latlngs, fill) { - var i, j, len, geodesiclatlngs = []; - for (i = 0, len = latlngs.length; i < len; i++) { + if (latlngs.length == 0) { + return []; + } + + for (var i = 0, len = latlngs.length; i < len; i++) { if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') { return; } latlngs[i] = L.latLng(latlngs[i]); } - + + // geodrsic calculations have issues when crossing the anti-meridian. so offset the points + // so this isn't an issue, then add back the offset afterwards + // a center longitude would be ideal - but the start point logitude will be 'good enougn' + var lngOffset = latlngs[0].lng; + + // points are wrapped after being offset relative to the first point coordinate, so they're + // within +-180 degrees + latlngs = latlngs.map(function(a){ return L.latLng(a.lat, a.lng-lngOffset).wrap(); }); + + var geodesiclatlngs = []; + if(!fill) { geodesiclatlngs.push(latlngs[0]); } @@ -88,6 +102,12 @@ if(fill) { geodesicConvertLine(latlngs[len], latlngs[0], geodesiclatlngs); } + + // now add back the offset subtracted above. no wrapping here - the drawing code handles + // things better when there's no sudden jumps in coordinates. yes, lines will extend + // beyond +-180 degrees - but they won't be 'broken' + geodesiclatlngs = geodesiclatlngs.map(function(a){ return L.latLng(a.lat, a.lng+lngOffset); }); + return geodesiclatlngs; } From fc1868774bf02b5837f22b6872ae538d6b22ded0 Mon Sep 17 00:00:00 2001 From: Mike Castle Date: Fri, 22 Nov 2013 23:31:05 -0800 Subject: [PATCH 09/32] Spell checking, d-g. --- src/L.Geodesic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 0480b8d..7799f22 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -82,9 +82,9 @@ latlngs[i] = L.latLng(latlngs[i]); } - // geodrsic calculations have issues when crossing the anti-meridian. so offset the points + // geodesic calculations have issues when crossing the anti-meridian. so offset the points // so this isn't an issue, then add back the offset afterwards - // a center longitude would be ideal - but the start point logitude will be 'good enougn' + // a center longitude would be ideal - but the start point logitude will be 'good enough' var lngOffset = latlngs[0].lng; // points are wrapped after being offset relative to the first point coordinate, so they're From 0c87d3c02d6dcc4eb6c38bc2dd1c6750c4c13dd4 Mon Sep 17 00:00:00 2001 From: Mike Castle Date: Sun, 24 Nov 2013 00:19:25 -0800 Subject: [PATCH 10/32] Spell checking, s-z, plus a couple of missed ones. --- src/L.Geodesic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 7799f22..1fabb19 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -84,7 +84,7 @@ // geodesic calculations have issues when crossing the anti-meridian. so offset the points // so this isn't an issue, then add back the offset afterwards - // a center longitude would be ideal - but the start point logitude will be 'good enough' + // a center longitude would be ideal - but the start point longitude will be 'good enough' var lngOffset = latlngs[0].lng; // points are wrapped after being offset relative to the first point coordinate, so they're From 1e3a9a2d79db51c2e070b9c54ce146c9eda8b096 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sun, 15 Dec 2013 06:08:54 +0000 Subject: [PATCH 11/32] work-around for mobile-specific geodesic line drawing issue - appears to be an odd rounding problem not ideal, but better than the current situation --- src/L.Geodesic.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 1fabb19..3a4e350 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -52,19 +52,23 @@ // loop ends before 'segments' is reached - we don't add the very last point here but outside the loop // (this was to fix a bug - https://github.com/jonatkins/ingress-intel-total-conversion/issues/471 // rounding errors? maths bug? not sure - but it solves the issue! and is a slight optimisation) - for (i = 1; i < segments; i++) { - // http://williams.best.vwh.net/avform.htm#Intermediate - // modified to handle longitude above +-180 degrees - f = i / segments; - A = Math.sin((1-f)*d) / Math.sin(d); - B = Math.sin(f*d) / Math.sin(d); - x = A * Math.cos(lat1) * Math.cos(0) + B * Math.cos(lat2) * Math.cos(dLng); - y = A * Math.cos(lat1) * Math.sin(0) + B * Math.cos(lat2) * Math.sin(dLng); - z = A * Math.sin(lat1) + B * Math.sin(lat2); - fLat = r2d * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))); - fLng = r2d * (Math.atan2(y, x)+lng1); - - convertedPoints.push(L.latLng([fLat, fLng])); + // UPDATE: there still seem to be rounding errors on relatively short links - but only on mobile. + // let's only add intermediate points if there's two or more + if (segments >= 3) { + for (i = 1; i < segments; i++) { + // http://williams.best.vwh.net/avform.htm#Intermediate + // modified to handle longitude above +-180 degrees + f = i / segments; + A = Math.sin((1-f)*d) / Math.sin(d); + B = Math.sin(f*d) / Math.sin(d); + x = A * Math.cos(lat1) * Math.cos(0) + B * Math.cos(lat2) * Math.cos(dLng); + y = A * Math.cos(lat1) * Math.sin(0) + B * Math.cos(lat2) * Math.sin(dLng); + z = A * Math.sin(lat1) + B * Math.sin(lat2); + fLat = r2d * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))); + fLng = r2d * (Math.atan2(y, x)+lng1); + + convertedPoints.push(L.latLng([fLat, fLng])); + } } // push the final point unmodified convertedPoints.push(L.latLng(endLatlng)); From 964e3d49d2892e1497b8cd144be3cf8cb195f030 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Thu, 19 Dec 2013 03:30:57 +0000 Subject: [PATCH 12/32] geodesic line drawing: alternative intermediate point calculation code - based on simpler lon->lat formula rather than N intermediate points more than good enough for line drawing, and hopefully will avoid odd rounding issues seen on mobile --- src/L.Geodesic.js | 86 ++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 3a4e350..50e8a77 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -28,52 +28,54 @@ } }); } - - function geodesicConvertLine(startLatlng, endLatlng, convertedPoints) { - var i, - R = 6378137, // earth radius in meters (doesn't have to be exact) - maxlength = 5000, // meters before splitting - d2r = L.LatLng.DEG_TO_RAD, - r2d = L.LatLng.RAD_TO_DEG, - lat1, lat2, lng1, lng2, dLng, d, segments, - f, A, B, x, y, z, fLat, fLng; - - dLng = (endLatlng.lng - startLatlng.lng) * d2r; - lat1 = startLatlng.lat * d2r; - lat2 = endLatlng.lat * d2r; - lng1 = startLatlng.lng * d2r; - lng2 = endLatlng.lng * d2r; - - // http://en.wikipedia.org/wiki/Great-circle_distance - d = Math.atan2(Math.sqrt( Math.pow(Math.cos(lat2) * Math.sin(dLng), 2) + Math.pow(Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng), 2) ), Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLng)); - - segments = Math.ceil(d * R / maxlength); - // loop starts at 1 - we don't add the very first point - // loop ends before 'segments' is reached - we don't add the very last point here but outside the loop - // (this was to fix a bug - https://github.com/jonatkins/ingress-intel-total-conversion/issues/471 - // rounding errors? maths bug? not sure - but it solves the issue! and is a slight optimisation) - // UPDATE: there still seem to be rounding errors on relatively short links - but only on mobile. - // let's only add intermediate points if there's two or more - if (segments >= 3) { - for (i = 1; i < segments; i++) { - // http://williams.best.vwh.net/avform.htm#Intermediate - // modified to handle longitude above +-180 degrees - f = i / segments; - A = Math.sin((1-f)*d) / Math.sin(d); - B = Math.sin(f*d) / Math.sin(d); - x = A * Math.cos(lat1) * Math.cos(0) + B * Math.cos(lat2) * Math.cos(dLng); - y = A * Math.cos(lat1) * Math.sin(0) + B * Math.cos(lat2) * Math.sin(dLng); - z = A * Math.sin(lat1) + B * Math.sin(lat2); - fLat = r2d * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))); - fLng = r2d * (Math.atan2(y, x)+lng1); - - convertedPoints.push(L.latLng([fLat, fLng])); + + // alternative geodesic line intermediate points function + // as north/south lines have very little curvature in the projection, we cam use longitude (east/west) seperation + // to calculate intermediate points. hopeefully this will avoid the rounding issues seen in the full intermediate + // points code that have been seen + function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { + var R = 6378137; // earth radius in meters (doesn't have to be exact) + var d2r = L.LatLng.DEG_TO_RAD; + var r2d = L.LatLng.RAD_TO_DEG; + + // maths based on http://williams.best.vwh.net/avform.htm#Int + + var lat1 = startLatLng.lat * d2r; + var lat2 = endLatLng.lat * d2r; + var lng1 = startLatLng.lng * d2r; + var lng2 = endLatLng.lng * d2r; + + var dLng = lng2-lng1; + + var segments = Math.floor(Math.abs(dLng * R / 5000)); + + if (segments > 1) { + // pre-calculate some constant values for the loop + var sinLat1 = Math.sin(lat1); + var sinLat2 = Math.sin(lat2); + var cosLat1 = Math.cos(lat1); + var cosLat2 = Math.cos(lat2); + + var sinLat1CosLat2 = sinLat1*cosLat2; + var sinLat2CosLat1 = sinLat2*cosLat1; + + var cosLat1CosLat2SinDLng = cosLat1*cosLat2*Math.sin(dLng); + + for (var i=1; i < segments; i++) { + var iLng = lng1+dLng*(i/segments); + var iLat = Math.atan( (sinLat1CosLat2*Math.sin(lng2-iLng) + sinLat2CosLat1*Math.sin(iLng-lng1)) + / cosLat1CosLat2SinDLng) + + var point = L.latLng ( [iLat*r2d, iLng*r2d] ); + convertedPoints.push(point); } } - // push the final point unmodified - convertedPoints.push(L.latLng(endLatlng)); + + convertedPoints.push(L.latLng(endLatLng)); } + + L.geodesicConvertLines = function (latlngs, fill) { if (latlngs.length == 0) { return []; From 07615648c1a5f1ba9ab997fe1aa7471c840b3b63 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Sun, 5 Jan 2014 22:45:23 +0000 Subject: [PATCH 13/32] increase min line segments used for geodesic circles - improves portal range circles at smaller sizes --- src/L.Geodesic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 50e8a77..fde1a7c 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -201,7 +201,7 @@ } - var segments = Math.max(32,Math.floor(this._mRadius/1000)); + var segments = Math.max(48,Math.floor(this._mRadius/1000)); //console.log(" (drawing circle as "+segments+" lines)"); var points = []; for (var i=0; i Date: Sat, 22 Mar 2014 01:46:51 +0000 Subject: [PATCH 14/32] geodesic: remove dependancy on L.LatLng.DEG_TO_RAD/RAD_TO_DEG, in preperation for leaflet 0.8 --- src/L.Geodesic.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index fde1a7c..aeb9a88 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -35,8 +35,8 @@ // points code that have been seen function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { var R = 6378137; // earth radius in meters (doesn't have to be exact) - var d2r = L.LatLng.DEG_TO_RAD; - var r2d = L.LatLng.RAD_TO_DEG; + var d2r = Math.PI/180.0; + var r2d = 180.0/Math.PI; // maths based on http://williams.best.vwh.net/avform.htm#Int @@ -174,8 +174,8 @@ _calcPoints: function() { var R = 6378137; //earth radius in meters (approx - taken from leaflet source code) - var d2r = L.LatLng.DEG_TO_RAD; - var r2d = L.LatLng.RAD_TO_DEG; + var d2r = Math.PI/180.0; + var r2d = 180.0/Math.PI; //console.log("geodesicCircle: radius = "+this._mRadius+"m, centre "+this._latlng.lat+","+this._latlng.lng); // circle radius as an angle from the centre of the earth From b8d2450d3d7be8d85c270e5229439eb372f14ac0 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Thu, 12 Mar 2015 20:47:05 +0000 Subject: [PATCH 15/32] earth radius: change leaflet and leaflet-draw to use the radius value used by the s2 geometry library this library is used in the ingress backend, so distance calculation, etc are far closer if we use the value from that --- src/L.Geodesic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index aeb9a88..64cd249 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -34,7 +34,7 @@ // to calculate intermediate points. hopeefully this will avoid the rounding issues seen in the full intermediate // points code that have been seen function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { - var R = 6378137; // earth radius in meters (doesn't have to be exact) + var R = 6367000.0; // earth radius in meters (doesn't have to be exact) var d2r = Math.PI/180.0; var r2d = 180.0/Math.PI; @@ -173,7 +173,7 @@ _calcPoints: function() { - var R = 6378137; //earth radius in meters (approx - taken from leaflet source code) + var R = 6367000.0; //earth radius in meters (approx - taken from leaflet source code) var d2r = Math.PI/180.0; var r2d = 180.0/Math.PI; //console.log("geodesicCircle: radius = "+this._mRadius+"m, centre "+this._latlng.lat+","+this._latlng.lng); From 8a3729da54975ff9a5aba1795b0a3751d423c69b Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 10 May 2019 11:18:49 +0300 Subject: [PATCH 16/32] external: L.Geodesic.js: add workaround to fix GeodesicCircle drawing/editing process fix https://github.com/IITC-CE/ingress-intel-total-conversion/issues/178 upstream report: https://github.com/Leaflet/Leaflet/issues/6656 --- src/L.Geodesic.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 64cd249..8841533 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -140,6 +140,8 @@ initialize: function (latlng, radius, options) { this._latlng = L.latLng(latlng); this._mRadius = radius; + this._radius = 11; // stub property to workaround https://github.com/IITC-CE/ingress-intel-total-conversion/issues/178 + // upstream report: https://github.com/Leaflet/Leaflet/issues/6656 points = this._calcPoints(); From 205ff945d598d51316e030510c0d146a5e09fc45 Mon Sep 17 00:00:00 2001 From: johndoe Date: Sat, 3 Aug 2019 09:36:03 +0300 Subject: [PATCH 17/32] L.GeodesicCircle: change private property name _mRadius => _radius --- src/L.Geodesic.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 8841533..142f767 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -139,12 +139,8 @@ L.GeodesicCircle = L.Polygon.extend({ initialize: function (latlng, radius, options) { this._latlng = L.latLng(latlng); - this._mRadius = radius; - this._radius = 11; // stub property to workaround https://github.com/IITC-CE/ingress-intel-total-conversion/issues/178 - // upstream report: https://github.com/Leaflet/Leaflet/issues/6656 - - points = this._calcPoints(); - + this._radius = options.radius; // note: https://github.com/Leaflet/Leaflet/issues/6656 + var points = this._calcPoints(); L.Polygon.prototype.initialize.call(this, points, options); }, @@ -159,8 +155,8 @@ }, setRadius: function (radius) { - this._mRadius = radius; - points = this._calcPoints(); + this._radius = radius; + var points = this._calcPoints(); this.setLatLngs(points); }, @@ -170,7 +166,7 @@ }, getRadius: function() { - return this._mRadius; + return this._radius; }, @@ -178,10 +174,10 @@ var R = 6367000.0; //earth radius in meters (approx - taken from leaflet source code) var d2r = Math.PI/180.0; var r2d = 180.0/Math.PI; -//console.log("geodesicCircle: radius = "+this._mRadius+"m, centre "+this._latlng.lat+","+this._latlng.lng); +//console.log("geodesicCircle: radius = "+this._radius+"m, centre "+this._latlng.lat+","+this._latlng.lng); // circle radius as an angle from the centre of the earth - var radRadius = this._mRadius / R; + var radRadius = this._radius / R; //console.log(" (radius in radians "+radRadius); @@ -203,7 +199,7 @@ } - var segments = Math.max(48,Math.floor(this._mRadius/1000)); + var segments = Math.max(48,Math.floor(this._radius/1000)); //console.log(" (drawing circle as "+segments+" lines)"); var points = []; for (var i=0; i Date: Fri, 2 Aug 2019 17:01:30 +0300 Subject: [PATCH 18/32] cleanup and minor fixes - `points` variable was undeclared - eslint: no-undef, eqeqeq, semi, no-trailing-spaces - fix url, fix mistypes in comments - clean up obsolete MultiPoly* code (that was already commented out) - remove unused `spliceLatLngs` - make L.GeodesicCircle constructor signature compatible to Leaflet 1.x L.Circle - update README.md --- README.md | 22 +++++++++++----- src/L.Geodesic.js | 66 +++++++++++++---------------------------------- 2 files changed, 34 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index ceeeca7..1944ab8 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,24 @@ -[Leaflet.Geodesic](http://fragger.github.io/Leaflet.Geodesic/) +[Leaflet.Geodesic][example] ================ -### Description -Geodesic polylines and polygons for [Leaflet](https://github.com/Leaflet/Leaflet) +Description +----------- + +Geodesic polylines, polygons and circles for [Leaflet](https://github.com/Leaflet/Leaflet) 1.x Adds: ``` L.GeodesicPolyline( latlngs, options? ) + L.GeodesicPolygon( latlngs, options? ) -L.GeodesicMultiPolyline( latlngs, options? ) -L.GeodesicMultiPolygon( latlngs, options? ) + +L.GeodesicCircle( latlng, options? ) +L.GeodesicCircle( latlng, radius, options? ) -- obsolete way ``` -These will follow the curvature of the Earth and are used just like the normal versions of the constructors that are rendered as straight lines on the screen \ No newline at end of file + +These will follow the curvature of the Earth and are used just like the normal versions of the constructors that are rendered as straight lines on the screen. + +See **[example]**. + + +[example]: https://raw.githack.com/IITC-CE/Leaflet.Geodesic/master/examples/index.html diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 142f767..ed76d42 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -16,12 +16,6 @@ this._latlngsinit.push(L.latLng(latlng)); return this.redraw(); }, - spliceLatLngs: function () { // (Number index, Number howMany) - var removed = [].splice.apply(this._latlngsinit, arguments); - this._convertLatLngs(this._latlngsinit); - this.redraw(); - return removed; - }, redraw: function() { this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); return Klass.prototype.redraw.call(this); @@ -30,15 +24,15 @@ } // alternative geodesic line intermediate points function - // as north/south lines have very little curvature in the projection, we cam use longitude (east/west) seperation - // to calculate intermediate points. hopeefully this will avoid the rounding issues seen in the full intermediate + // as north/south lines have very little curvature in the projection, we can use longitude (east/west) seperation + // to calculate intermediate points. hopefully this will avoid the rounding issues seen in the full intermediate // points code that have been seen function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { var R = 6367000.0; // earth radius in meters (doesn't have to be exact) var d2r = Math.PI/180.0; var r2d = 180.0/Math.PI; - // maths based on http://williams.best.vwh.net/avform.htm#Int + // maths based on https://edwilliams.org/avform.htm#Int var lat1 = startLatLng.lat * d2r; var lat2 = endLatLng.lat * d2r; @@ -64,7 +58,7 @@ for (var i=1; i < segments; i++) { var iLng = lng1+dLng*(i/segments); var iLat = Math.atan( (sinLat1CosLat2*Math.sin(lng2-iLng) + sinLat2CosLat1*Math.sin(iLng-lng1)) - / cosLat1CosLat2SinDLng) + / cosLat1CosLat2SinDLng); var point = L.latLng ( [iLat*r2d, iLng*r2d] ); convertedPoints.push(point); @@ -77,7 +71,7 @@ L.geodesicConvertLines = function (latlngs, fill) { - if (latlngs.length == 0) { + if (latlngs.length === 0) { return []; } @@ -115,29 +109,18 @@ geodesiclatlngs = geodesiclatlngs.map(function(a){ return L.latLng(a.lat, a.lng+lngOffset); }); return geodesiclatlngs; - } - - L.GeodesicPolyline = geodesicPoly(L.Polyline, 0); - L.GeodesicPolygon = geodesicPoly(L.Polygon, 1); - - //L.GeodesicMultiPolyline = createMulti(L.GeodesicPolyline); - //L.GeodesicMultiPolygon = createMulti(L.GeodesicPolygon); - - /*L.GeodesicMultiPolyline = L.MultiPolyline.extend({ - initialize: function (latlngs, options) { - L.MultiPolyline.prototype.initialize.call(this, L.geodesicConvertLines(latlngs), options); - } - });*/ + }; - /*L.GeodesicMultiPolygon = L.MultiPolygon.extend({ - initialize: function (latlngs, options) { - L.MultiPolygon.prototype.initialize.call(this, L.geodesicConvertLines(latlngs), options); - } - });*/ + L.GeodesicPolyline = geodesicPoly(L.Polyline, false); + L.GeodesicPolygon = geodesicPoly(L.Polygon, true); L.GeodesicCircle = L.Polygon.extend({ - initialize: function (latlng, radius, options) { + initialize: function (latlng, options, legacyOptions) { + if (typeof options === 'number') { + // Backwards compatibility with 0.7.x factory (latlng, radius, options?) + options = L.extend({}, legacyOptions, {radius: options}); + } this._latlng = L.latLng(latlng); this._radius = options.radius; // note: https://github.com/Leaflet/Leaflet/issues/6656 var points = this._calcPoints(); @@ -150,7 +133,7 @@ setLatLng: function (latlng) { this._latlng = L.latLng(latlng); - points = this._calcPoints(); + var points = this._calcPoints(); this.setLatLngs(points); }, @@ -158,7 +141,6 @@ this._radius = radius; var points = this._calcPoints(); this.setLatLngs(points); - }, getLatLng: function () { @@ -169,9 +151,8 @@ return this._radius; }, - _calcPoints: function() { - var R = 6367000.0; //earth radius in meters (approx - taken from leaflet source code) + var R = 6367000.0; //earth radius in meters var d2r = Math.PI/180.0; var r2d = 180.0/Math.PI; //console.log("geodesicCircle: radius = "+this._radius+"m, centre "+this._latlng.lat+","+this._latlng.lng); @@ -196,7 +177,7 @@ var lng = centreLng + Math.atan2(Math.sin(angle)*sinRadRadius*cosCentreLat, cosRadRadius-sinCentreLat*Math.sin(lat)); return L.latLng(lat * r2d,lng * r2d); - } + }; var segments = Math.max(48,Math.floor(this._radius/1000)); @@ -205,7 +186,7 @@ for (var i=0; i Date: Sun, 4 Aug 2019 18:57:11 +0300 Subject: [PATCH 19/32] update example get rid of unneeded submodules and dependencies --- .gitmodules | 6 ------ examples/index.html | 33 +++++++++++++++++++++------------ examples/lib/Leaflet | 1 - examples/lib/leaflet-tilejson | 1 - examples/osm.tilejson.js | 17 ----------------- examples/style.css | 11 ----------- 6 files changed, 21 insertions(+), 48 deletions(-) delete mode 100644 .gitmodules delete mode 160000 examples/lib/Leaflet delete mode 160000 examples/lib/leaflet-tilejson delete mode 100644 examples/osm.tilejson.js delete mode 100644 examples/style.css diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 4aaf2d2..0000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "examples/lib/Leaflet"] - path = examples/lib/Leaflet - url = https://github.com/Leaflet/Leaflet.git -[submodule "examples/lib/leaflet-tilejson"] - path = examples/lib/leaflet-tilejson - url = https://github.com/kartena/leaflet-tilejson.git diff --git a/examples/index.html b/examples/index.html index 1542c08..c4b7a0e 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,22 +1,31 @@ + Leaflet.Geodesic example - - - + + + +
- - - - - - \ No newline at end of file + diff --git a/examples/lib/Leaflet b/examples/lib/Leaflet deleted file mode 160000 index c1d410f..0000000 --- a/examples/lib/Leaflet +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c1d410f2703f0832618c997225e7360f6a292c58 diff --git a/examples/lib/leaflet-tilejson b/examples/lib/leaflet-tilejson deleted file mode 160000 index 94eead1..0000000 --- a/examples/lib/leaflet-tilejson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 94eead167b606af9cb736eefe5c3b04fc7a75e2f diff --git a/examples/osm.tilejson.js b/examples/osm.tilejson.js deleted file mode 100644 index ddc579c..0000000 --- a/examples/osm.tilejson.js +++ /dev/null @@ -1,17 +0,0 @@ -window.osmTileJSON = { - "tilejson": "2.0.0", - "name": "OpenStreetMap", - "description": "A free editable map of the whole world.", - "version": "1.0.0", - "attribution": "© OpenStreetMap contributors, CC-BY-SA", - "scheme": "xyz", - "tiles": [ - "http://a.tile.openstreetmap.org/${z}/${x}/${y}.png", - "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png", - "http://c.tile.openstreetmap.org/${z}/${x}/${y}.png" - ], - "minzoom": 2, - "maxzoom": 18, - "bounds": [ -180, -85, 180, 85 ], - "center": [ 11.9, 57.7, 8 ] -}; \ No newline at end of file diff --git a/examples/style.css b/examples/style.css deleted file mode 100644 index 4a3966b..0000000 --- a/examples/style.css +++ /dev/null @@ -1,11 +0,0 @@ -html, body { - height: 100%; - padding: 0; - margin: 0; -} - -#map { - position: absolute; - width: 100%; - height: 100%; -} \ No newline at end of file From 8b7f6d1c0dea87681d0e8da55bfdb9175bde82e1 Mon Sep 17 00:00:00 2001 From: johndoe Date: Mon, 5 Aug 2019 11:36:37 +0300 Subject: [PATCH 20/32] add examples/circle.html --- examples/circle.html | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/circle.html diff --git a/examples/circle.html b/examples/circle.html new file mode 100644 index 0000000..7198f1d --- /dev/null +++ b/examples/circle.html @@ -0,0 +1,50 @@ + + + + Leaflet.Geodesic example + + + + + + + +
+ + + From 4713e0788d4a1ee2b7bc002afd1d94014d3349de Mon Sep 17 00:00:00 2001 From: johndoe Date: Mon, 5 Aug 2019 12:23:21 +0300 Subject: [PATCH 21/32] update README.md --- README.md | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1944ab8..10ffeae 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,44 @@ [Leaflet.Geodesic][example] ================ -Description ------------ +Geodesic polylines, polygons and circles for [Leaflet](https://github.com/Leaflet/Leaflet) 1.x. -Geodesic polylines, polygons and circles for [Leaflet](https://github.com/Leaflet/Leaflet) 1.x +These will follow the curvature of the Earth and are used just like the normal versions of the constructors that are rendered as straight lines on the screen. -Adds: -``` -L.GeodesicPolyline( latlngs, options? ) +[example]: https://raw.githack.com/IITC-CE/Leaflet.Geodesic/master/examples/index.html -L.GeodesicPolygon( latlngs, options? ) -L.GeodesicCircle( latlng, options? ) -L.GeodesicCircle( latlng, radius, options? ) -- obsolete way -``` +`L.GeodesicPolyline` +------------------ -These will follow the curvature of the Earth and are used just like the normal versions of the constructors that are rendered as straight lines on the screen. +**L.geodesicPolyline**( _latlngs_, <[Polyline options]> _options?_) -See **[example]**. +- [Example] +[Polyline options]: https://leafletjs.com/reference-1.5.0.html#polyline-option -[example]: https://raw.githack.com/IITC-CE/Leaflet.Geodesic/master/examples/index.html + +`L.GeodesicPolygon` +------------------ + +**L.geodesicPolygon**( _latlngs_, <[Polyline options]> _options?_) + + +`L.GeodesicCircle` +------------------ + +**L.geodesicCircle**(<[LatLng]> _latlng_, <[Circle options]> _options?_) + +- [Example][example-circle] + +[example-circle]: https://raw.githack.com/IITC-CE/Leaflet.Geodesic/master/examples/circle.html + +
+(obsolete way) + + +**L.geodesicCircle**(<[LatLng]> _latlng_, _radius_, <[Circle options]> _options?_) +
+ +[LatLng]: https://leafletjs.com/reference-1.5.0.html#latlng +[Circle options]: https://leafletjs.com/reference-1.5.0.html#circle-option From 39c4fbace00eb74c921222b72b3cd61ca9d9615c Mon Sep 17 00:00:00 2001 From: johndoe Date: Mon, 5 Aug 2019 13:21:30 +0300 Subject: [PATCH 22/32] use constants --- src/L.Geodesic.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index ed76d42..08730c9 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -1,4 +1,9 @@ (function () { + // constants + var d2r = Math.PI/180.0; + var r2d = 180.0/Math.PI; + var earthR = 6367000.0; // earth radius in meters (doesn't have to be exact) + function geodesicPoly(Klass, fill) { return Klass.extend({ initialize: function (latlngs, options) { @@ -28,9 +33,6 @@ // to calculate intermediate points. hopefully this will avoid the rounding issues seen in the full intermediate // points code that have been seen function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { - var R = 6367000.0; // earth radius in meters (doesn't have to be exact) - var d2r = Math.PI/180.0; - var r2d = 180.0/Math.PI; // maths based on https://edwilliams.org/avform.htm#Int @@ -41,7 +43,7 @@ var dLng = lng2-lng1; - var segments = Math.floor(Math.abs(dLng * R / 5000)); + var segments = Math.floor(Math.abs(dLng * earthR / 5000)); if (segments > 1) { // pre-calculate some constant values for the loop @@ -152,13 +154,10 @@ }, _calcPoints: function() { - var R = 6367000.0; //earth radius in meters - var d2r = Math.PI/180.0; - var r2d = 180.0/Math.PI; //console.log("geodesicCircle: radius = "+this._radius+"m, centre "+this._latlng.lat+","+this._latlng.lng); // circle radius as an angle from the centre of the earth - var radRadius = this._radius / R; + var radRadius = this._radius / earthR; //console.log(" (radius in radians "+radRadius); From e6e8bf4a972e70b4d905bec86fdbbede877853bd Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 14:38:36 +0300 Subject: [PATCH 23/32] style issues very minor (mostly) space-related changes --- src/L.Geodesic.js | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 08730c9..6077a0a 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -4,24 +4,28 @@ var r2d = 180.0/Math.PI; var earthR = 6367000.0; // earth radius in meters (doesn't have to be exact) - function geodesicPoly(Klass, fill) { + function geodesicPoly (Klass, fill) { return Klass.extend({ initialize: function (latlngs, options) { Klass.prototype.initialize.call(this, L.geodesicConvertLines(latlngs, fill), options); this._latlngsinit = this._convertLatLngs(latlngs); }, + getLatLngs: function () { return this._latlngsinit; }, + setLatLngs: function (latlngs) { this._latlngsinit = this._convertLatLngs(latlngs); return this.redraw(); }, + addLatLng: function (latlng) { this._latlngsinit.push(L.latLng(latlng)); return this.redraw(); }, - redraw: function() { + + redraw: function () { this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); return Klass.prototype.redraw.call(this); } @@ -32,7 +36,7 @@ // as north/south lines have very little curvature in the projection, we can use longitude (east/west) seperation // to calculate intermediate points. hopefully this will avoid the rounding issues seen in the full intermediate // points code that have been seen - function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { + function geodesicConvertLine (startLatLng, endLatLng, convertedPoints) { // maths based on https://edwilliams.org/avform.htm#Int @@ -62,7 +66,7 @@ var iLat = Math.atan( (sinLat1CosLat2*Math.sin(lng2-iLng) + sinLat2CosLat1*Math.sin(iLng-lng1)) / cosLat1CosLat2SinDLng); - var point = L.latLng ( [iLat*r2d, iLng*r2d] ); + var point = L.latLng(iLat*r2d, iLng*r2d); convertedPoints.push(point); } } @@ -71,7 +75,6 @@ } - L.geodesicConvertLines = function (latlngs, fill) { if (latlngs.length === 0) { return []; @@ -91,24 +94,24 @@ // points are wrapped after being offset relative to the first point coordinate, so they're // within +-180 degrees - latlngs = latlngs.map(function(a){ return L.latLng(a.lat, a.lng-lngOffset).wrap(); }); + latlngs = latlngs.map(function (a) { return L.latLng(a.lat, a.lng-lngOffset).wrap(); }); var geodesiclatlngs = []; - if(!fill) { + if (!fill) { geodesiclatlngs.push(latlngs[0]); } for (i = 0, len = latlngs.length - 1; i < len; i++) { geodesicConvertLine(latlngs[i], latlngs[i+1], geodesiclatlngs); } - if(fill) { + if (fill) { geodesicConvertLine(latlngs[len], latlngs[0], geodesiclatlngs); } // now add back the offset subtracted above. no wrapping here - the drawing code handles // things better when there's no sudden jumps in coordinates. yes, lines will extend // beyond +-180 degrees - but they won't be 'broken' - geodesiclatlngs = geodesiclatlngs.map(function(a){ return L.latLng(a.lat, a.lng+lngOffset); }); + geodesiclatlngs = geodesiclatlngs.map(function (a) { return L.latLng(a.lat, a.lng+lngOffset); }); return geodesiclatlngs; }; @@ -149,18 +152,15 @@ return this._latlng; }, - getRadius: function() { + getRadius: function () { return this._radius; }, - _calcPoints: function() { -//console.log("geodesicCircle: radius = "+this._radius+"m, centre "+this._latlng.lat+","+this._latlng.lng); + _calcPoints: function () { // circle radius as an angle from the centre of the earth var radRadius = this._radius / earthR; -//console.log(" (radius in radians "+radRadius); - // pre-calculate various values used for every point on the circle var centreLat = this._latlng.lat * d2r; var centreLng = this._latlng.lng * d2r; @@ -171,27 +171,24 @@ var cosRadRadius = Math.cos(radRadius); var sinRadRadius = Math.sin(radRadius); - var calcLatLngAtAngle = function(angle) { + var calcLatLngAtAngle = function (angle) { var lat = Math.asin(sinCentreLat*cosRadRadius + cosCentreLat*sinRadRadius*Math.cos(angle)); var lng = centreLng + Math.atan2(Math.sin(angle)*sinRadRadius*cosCentreLat, cosRadRadius-sinCentreLat*Math.sin(lat)); return L.latLng(lat * r2d,lng * r2d); }; - var segments = Math.max(48,Math.floor(this._radius/1000)); -//console.log(" (drawing circle as "+segments+" lines)"); var points = []; for (var i=0; i Date: Fri, 23 Aug 2019 15:04:53 +0300 Subject: [PATCH 24/32] refactor: _geodesicConvertLine* are methods now --- src/L.Geodesic.js | 72 ++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 6077a0a..630cdb2 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -4,34 +4,6 @@ var r2d = 180.0/Math.PI; var earthR = 6367000.0; // earth radius in meters (doesn't have to be exact) - function geodesicPoly (Klass, fill) { - return Klass.extend({ - initialize: function (latlngs, options) { - Klass.prototype.initialize.call(this, L.geodesicConvertLines(latlngs, fill), options); - this._latlngsinit = this._convertLatLngs(latlngs); - }, - - getLatLngs: function () { - return this._latlngsinit; - }, - - setLatLngs: function (latlngs) { - this._latlngsinit = this._convertLatLngs(latlngs); - return this.redraw(); - }, - - addLatLng: function (latlng) { - this._latlngsinit.push(L.latLng(latlng)); - return this.redraw(); - }, - - redraw: function () { - this._latlngs = this._convertLatLngs(L.geodesicConvertLines(this._latlngsinit, fill)); - return Klass.prototype.redraw.call(this); - } - }); - } - // alternative geodesic line intermediate points function // as north/south lines have very little curvature in the projection, we can use longitude (east/west) seperation // to calculate intermediate points. hopefully this will avoid the rounding issues seen in the full intermediate @@ -75,7 +47,7 @@ } - L.geodesicConvertLines = function (latlngs, fill) { + function geodesicConvertLines (latlngs, fill) { if (latlngs.length === 0) { return []; } @@ -102,10 +74,10 @@ geodesiclatlngs.push(latlngs[0]); } for (i = 0, len = latlngs.length - 1; i < len; i++) { - geodesicConvertLine(latlngs[i], latlngs[i+1], geodesiclatlngs); + this._geodesicConvertLine(latlngs[i], latlngs[i+1], geodesiclatlngs); } if (fill) { - geodesicConvertLine(latlngs[len], latlngs[0], geodesiclatlngs); + this._geodesicConvertLine(latlngs[len], latlngs[0], geodesiclatlngs); } // now add back the offset subtracted above. no wrapping here - the drawing code handles @@ -114,7 +86,42 @@ geodesiclatlngs = geodesiclatlngs.map(function (a) { return L.latLng(a.lat, a.lng+lngOffset); }); return geodesiclatlngs; - }; + } + + + function geodesicPoly (Klass, fill) { + return Klass.extend({ + _geodesicConvertLine: geodesicConvertLine, + + _geodesicConvertLines: geodesicConvertLines, + + initialize: function (latlngs, options) { + Klass.prototype.initialize.call(this, this._geodesicConvertLines(latlngs, fill), options); + this._latlngsinit = this._convertLatLngs(latlngs); + }, + + getLatLngs: function () { + return this._latlngsinit; + }, + + setLatLngs: function (latlngs) { + this._latlngsinit = this._convertLatLngs(latlngs); + return this.redraw(); + }, + + addLatLng: function (latlng) { + this._latlngsinit.push(L.latLng(latlng)); + return this.redraw(); + }, + + redraw: function () { + this._latlngs = this._convertLatLngs(this._geodesicConvertLines(this._latlngsinit, fill)); + return Klass.prototype.redraw.call(this); + } + + }); + } + L.GeodesicPolyline = geodesicPoly(L.Polyline, false); L.GeodesicPolygon = geodesicPoly(L.Polygon, true); @@ -189,6 +196,7 @@ return points; } + }); From f09bbd3e441deb6490fc2195bfe683180b5f624e Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 16:11:24 +0300 Subject: [PATCH 25/32] distinguish polygons using instanceof (instead of additional argument `fill`) --- src/L.Geodesic.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 630cdb2..e59f094 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -47,7 +47,7 @@ } - function geodesicConvertLines (latlngs, fill) { + function geodesicConvertLines (latlngs) { if (latlngs.length === 0) { return []; } @@ -70,13 +70,15 @@ var geodesiclatlngs = []; - if (!fill) { + // var isPolygon = this.options.fill; // !wrong: L.Draw use options.fill with polylines + var isPolygon = this instanceof L.Polygon; + if (!isPolygon) { geodesiclatlngs.push(latlngs[0]); } for (i = 0, len = latlngs.length - 1; i < len; i++) { this._geodesicConvertLine(latlngs[i], latlngs[i+1], geodesiclatlngs); } - if (fill) { + if (isPolygon) { this._geodesicConvertLine(latlngs[len], latlngs[0], geodesiclatlngs); } @@ -89,14 +91,14 @@ } - function geodesicPoly (Klass, fill) { + function geodesicPoly (Klass) { return Klass.extend({ _geodesicConvertLine: geodesicConvertLine, _geodesicConvertLines: geodesicConvertLines, initialize: function (latlngs, options) { - Klass.prototype.initialize.call(this, this._geodesicConvertLines(latlngs, fill), options); + Klass.prototype.initialize.call(this, this._geodesicConvertLines(latlngs), options); this._latlngsinit = this._convertLatLngs(latlngs); }, @@ -115,7 +117,7 @@ }, redraw: function () { - this._latlngs = this._convertLatLngs(this._geodesicConvertLines(this._latlngsinit, fill)); + this._latlngs = this._convertLatLngs(this._geodesicConvertLines(this._latlngsinit)); return Klass.prototype.redraw.call(this); } @@ -123,8 +125,8 @@ } - L.GeodesicPolyline = geodesicPoly(L.Polyline, false); - L.GeodesicPolygon = geodesicPoly(L.Polygon, true); + L.GeodesicPolyline = geodesicPoly(L.Polyline); + L.GeodesicPolygon = geodesicPoly(L.Polygon); L.GeodesicCircle = L.Polygon.extend({ From 4d54906f5f3a7e81b1c3b25fb86157fe2ad009c0 Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 16:31:56 +0300 Subject: [PATCH 26/32] minor change in inheritance use common mixin instead of custom factory function --- src/L.Geodesic.js | 56 ++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index e59f094..071ba6e 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -90,44 +90,40 @@ return geodesiclatlngs; } + var PolyMixin = { + _geodesicConvertLine: geodesicConvertLine, - function geodesicPoly (Klass) { - return Klass.extend({ - _geodesicConvertLine: geodesicConvertLine, + _geodesicConvertLines: geodesicConvertLines, - _geodesicConvertLines: geodesicConvertLines, - - initialize: function (latlngs, options) { - Klass.prototype.initialize.call(this, this._geodesicConvertLines(latlngs), options); - this._latlngsinit = this._convertLatLngs(latlngs); - }, - - getLatLngs: function () { - return this._latlngsinit; - }, - - setLatLngs: function (latlngs) { - this._latlngsinit = this._convertLatLngs(latlngs); - return this.redraw(); - }, + initialize: function (latlngs, options) { + L.Polyline.prototype.initialize.call(this, this._geodesicConvertLines(latlngs), options); + this._latlngsinit = this._convertLatLngs(latlngs); + }, - addLatLng: function (latlng) { - this._latlngsinit.push(L.latLng(latlng)); - return this.redraw(); - }, + getLatLngs: function () { + return this._latlngsinit; + }, - redraw: function () { - this._latlngs = this._convertLatLngs(this._geodesicConvertLines(this._latlngsinit)); - return Klass.prototype.redraw.call(this); - } + setLatLngs: function (latlngs) { + this._latlngsinit = this._convertLatLngs(latlngs); + return this.redraw(); + }, - }); - } + addLatLng: function (latlng) { + this._latlngsinit.push(L.latLng(latlng)); + return this.redraw(); + }, + redraw: function () { + this._latlngs = this._convertLatLngs(this._geodesicConvertLines(this._latlngsinit)); + return L.Path.prototype.redraw.call(this); + } + }; - L.GeodesicPolyline = geodesicPoly(L.Polyline); - L.GeodesicPolygon = geodesicPoly(L.Polygon); + L.GeodesicPolyline = L.Polyline.extend(PolyMixin); + delete PolyMixin.options; // workaround for https://github.com/Leaflet/Leaflet/pull/6766/ + L.GeodesicPolygon = L.Polygon.extend(PolyMixin); L.GeodesicCircle = L.Polygon.extend({ initialize: function (latlng, options, legacyOptions) { From c303d67f3cad30ea89cc9b7affd6532162f4bf7d Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 17:19:10 +0300 Subject: [PATCH 27/32] replace precision-related constants with options So it's now possible to override values, e.g.: ``` L.GeodesicCircle.mergeOptions({ // default: segmentsCoeff: 500, // 1000 segmentsMin: 96 // 48 }); var polyOptions = { segmentsCoeff: 500 }; // 5000 L.GeodesicPolyline.mergeOptions(polyOptions); L.GeodesicPolygon.mergeOptions(polyOptions); ``` --- src/L.Geodesic.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 071ba6e..779c283 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -19,7 +19,7 @@ var dLng = lng2-lng1; - var segments = Math.floor(Math.abs(dLng * earthR / 5000)); + var segments = Math.floor(Math.abs(dLng * earthR / this.options.segmentsCoeff)); if (segments > 1) { // pre-calculate some constant values for the loop @@ -90,11 +90,17 @@ return geodesiclatlngs; } + var polyOptions = { + segmentsCoeff: 5000 + }; + var PolyMixin = { _geodesicConvertLine: geodesicConvertLine, _geodesicConvertLines: geodesicConvertLines, + options: polyOptions, + initialize: function (latlngs, options) { L.Polyline.prototype.initialize.call(this, this._geodesicConvertLines(latlngs), options); this._latlngsinit = this._convertLatLngs(latlngs); @@ -122,10 +128,15 @@ L.GeodesicPolyline = L.Polyline.extend(PolyMixin); - delete PolyMixin.options; // workaround for https://github.com/Leaflet/Leaflet/pull/6766/ + PolyMixin.options = polyOptions; // workaround for https://github.com/Leaflet/Leaflet/pull/6766/ L.GeodesicPolygon = L.Polygon.extend(PolyMixin); L.GeodesicCircle = L.Polygon.extend({ + options: { + segmentsCoeff: 1000, + segmentsMin: 48 + }, + initialize: function (latlng, options, legacyOptions) { if (typeof options === 'number') { // Backwards compatibility with 0.7.x factory (latlng, radius, options?) @@ -137,10 +148,6 @@ L.Polygon.prototype.initialize.call(this, points, options); }, - options: { - fill: true - }, - setLatLng: function (latlng) { this._latlng = L.latLng(latlng); var points = this._calcPoints(); @@ -183,7 +190,8 @@ return L.latLng(lat * r2d,lng * r2d); }; - var segments = Math.max(48,Math.floor(this._radius/1000)); + var o = this.options; + var segments = Math.max(o.segmentsMin,Math.floor(this._radius/o.segmentsCoeff)); var points = []; for (var i=0; i Date: Fri, 23 Aug 2019 19:04:16 +0300 Subject: [PATCH 28/32] refactor: more consistent set of overriden methods --- src/L.Geodesic.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 779c283..d5dfa60 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -99,29 +99,34 @@ _geodesicConvertLines: geodesicConvertLines, + _geodesicConvert: function () { + this._latlngs = this._geodesicConvertLines(this._latlngsinit); + this._convertLatLngs(this._latlngs); // update bounds + }, + options: polyOptions, initialize: function (latlngs, options) { - L.Polyline.prototype.initialize.call(this, this._geodesicConvertLines(latlngs), options); - this._latlngsinit = this._convertLatLngs(latlngs); + L.Polyline.prototype.initialize.call(this, latlngs, options); + this._geodesicConvert(); }, getLatLngs: function () { return this._latlngsinit; }, - setLatLngs: function (latlngs) { + _setLatLngs: function (latlngs) { + this._bounds = L.latLngBounds(); this._latlngsinit = this._convertLatLngs(latlngs); - return this.redraw(); }, - addLatLng: function (latlng) { - this._latlngsinit.push(L.latLng(latlng)); - return this.redraw(); + _defaultShape: function () { + var latlngs = this._latlngsinit; + return L.LineUtil.isFlat(latlngs) ? latlngs : latlngs[0]; }, redraw: function () { - this._latlngs = this._convertLatLngs(this._geodesicConvertLines(this._latlngsinit)); + this._geodesicConvert(); return L.Path.prototype.redraw.call(this); } }; From 43a1a786d62d6219c1c188866c03ddb071e6fd17 Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 19:14:05 +0300 Subject: [PATCH 29/32] remove convertLatLngs-related loop this._geodesicConvertLines expects normalized coords array --- src/L.Geodesic.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index d5dfa60..3b0b1c0 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -52,13 +52,6 @@ return []; } - for (var i = 0, len = latlngs.length; i < len; i++) { - if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') { - return; - } - latlngs[i] = L.latLng(latlngs[i]); - } - // geodesic calculations have issues when crossing the anti-meridian. so offset the points // so this isn't an issue, then add back the offset afterwards // a center longitude would be ideal - but the start point longitude will be 'good enough' @@ -75,7 +68,7 @@ if (!isPolygon) { geodesiclatlngs.push(latlngs[0]); } - for (i = 0, len = latlngs.length - 1; i < len; i++) { + for (var i = 0, len = latlngs.length - 1; i < len; i++) { this._geodesicConvertLine(latlngs[i], latlngs[i+1], geodesiclatlngs); } if (isPolygon) { From 4a57cf962ffac6bac11ac12c0d566414ea7884b1 Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 19:24:06 +0300 Subject: [PATCH 30/32] refactor _processPoly from _geodesicConvertLines --- src/L.Geodesic.js | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 3b0b1c0..57dead4 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -47,6 +47,22 @@ } + function processPoly (latlngs, fn) { + var result = []; + + // var isPolygon = this.options.fill; // !wrong: L.Draw use options.fill with polylines + var isPolygon = this instanceof L.Polygon; + if (isPolygon) { + latlngs.push(latlngs[0]); + } else { + result.push(latlngs[0]); + } + for (var i = 0, len = latlngs.length - 1; i < len; i++) { + fn.call(this, latlngs[i], latlngs[i+1], result); + } + return result; + } + function geodesicConvertLines (latlngs) { if (latlngs.length === 0) { return []; @@ -61,19 +77,7 @@ // within +-180 degrees latlngs = latlngs.map(function (a) { return L.latLng(a.lat, a.lng-lngOffset).wrap(); }); - var geodesiclatlngs = []; - - // var isPolygon = this.options.fill; // !wrong: L.Draw use options.fill with polylines - var isPolygon = this instanceof L.Polygon; - if (!isPolygon) { - geodesiclatlngs.push(latlngs[0]); - } - for (var i = 0, len = latlngs.length - 1; i < len; i++) { - this._geodesicConvertLine(latlngs[i], latlngs[i+1], geodesiclatlngs); - } - if (isPolygon) { - this._geodesicConvertLine(latlngs[len], latlngs[0], geodesiclatlngs); - } + var geodesiclatlngs = this._processPoly(latlngs,this._geodesicConvertLine); // now add back the offset subtracted above. no wrapping here - the drawing code handles // things better when there's no sudden jumps in coordinates. yes, lines will extend @@ -90,6 +94,8 @@ var PolyMixin = { _geodesicConvertLine: geodesicConvertLine, + _processPoly: processPoly, + _geodesicConvertLines: geodesicConvertLines, _geodesicConvert: function () { From 2b502e852b9fcb34614e3f553c517a22e97012b4 Mon Sep 17 00:00:00 2001 From: johndoe Date: Fri, 23 Aug 2019 19:33:05 +0300 Subject: [PATCH 31/32] refactor geodesicConvertLine reformat "Latitude of point on GC" formula to exactly match ref: http://www.edwilliams.org/avform.htm#Int remove excessive L.LatLng constructor --- src/L.Geodesic.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 57dead4..69e82f4 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -8,42 +8,39 @@ // as north/south lines have very little curvature in the projection, we can use longitude (east/west) seperation // to calculate intermediate points. hopefully this will avoid the rounding issues seen in the full intermediate // points code that have been seen - function geodesicConvertLine (startLatLng, endLatLng, convertedPoints) { + function geodesicConvertLine (start, end, convertedPoints) { - // maths based on https://edwilliams.org/avform.htm#Int - - var lat1 = startLatLng.lat * d2r; - var lat2 = endLatLng.lat * d2r; - var lng1 = startLatLng.lng * d2r; - var lng2 = endLatLng.lng * d2r; - - var dLng = lng2-lng1; + var lng1 = start.lng * d2r; + var lng2 = end.lng * d2r; + var dLng = lng1-lng2; var segments = Math.floor(Math.abs(dLng * earthR / this.options.segmentsCoeff)); if (segments > 1) { + // maths based on https://edwilliams.org/avform.htm#Int + // pre-calculate some constant values for the loop + var lat1 = start.lat * d2r; + var lat2 = end.lat * d2r; var sinLat1 = Math.sin(lat1); var sinLat2 = Math.sin(lat2); var cosLat1 = Math.cos(lat1); var cosLat2 = Math.cos(lat2); - var sinLat1CosLat2 = sinLat1*cosLat2; var sinLat2CosLat1 = sinLat2*cosLat1; - var cosLat1CosLat2SinDLng = cosLat1*cosLat2*Math.sin(dLng); for (var i=1; i < segments; i++) { - var iLng = lng1+dLng*(i/segments); - var iLat = Math.atan( (sinLat1CosLat2*Math.sin(lng2-iLng) + sinLat2CosLat1*Math.sin(iLng-lng1)) - / cosLat1CosLat2SinDLng); - - var point = L.latLng(iLat*r2d, iLng*r2d); - convertedPoints.push(point); + var iLng = lng1-dLng*(i/segments); + var iLat = Math.atan( + (sinLat1CosLat2 * Math.sin(iLng-lng2) - sinLat2CosLat1 * Math.sin(iLng-lng1)) + / cosLat1CosLat2SinDLng + ); + convertedPoints.push(L.latLng(iLat*r2d, iLng*r2d)); } } - convertedPoints.push(L.latLng(endLatLng)); + convertedPoints.push(end); } From deb6da8f3e086b78760242992a367030cdfe3420 Mon Sep 17 00:00:00 2001 From: johndoe Date: Sat, 22 Feb 2020 11:16:44 +0200 Subject: [PATCH 32/32] geodesicConvertLine: push only intermediate points for the sake of greater consistency start/end points added in processPoly --- src/L.Geodesic.js | 51 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/L.Geodesic.js b/src/L.Geodesic.js index 69e82f4..5276ea0 100644 --- a/src/L.Geodesic.js +++ b/src/L.Geodesic.js @@ -8,42 +8,40 @@ // as north/south lines have very little curvature in the projection, we can use longitude (east/west) seperation // to calculate intermediate points. hopefully this will avoid the rounding issues seen in the full intermediate // points code that have been seen - function geodesicConvertLine (start, end, convertedPoints) { + function geodesicConvertLine (start, end, convertedPoints) { // push intermediate points into convertedPoints var lng1 = start.lng * d2r; var lng2 = end.lng * d2r; var dLng = lng1-lng2; var segments = Math.floor(Math.abs(dLng * earthR / this.options.segmentsCoeff)); - - if (segments > 1) { - // maths based on https://edwilliams.org/avform.htm#Int - - // pre-calculate some constant values for the loop - var lat1 = start.lat * d2r; - var lat2 = end.lat * d2r; - var sinLat1 = Math.sin(lat1); - var sinLat2 = Math.sin(lat2); - var cosLat1 = Math.cos(lat1); - var cosLat2 = Math.cos(lat2); - var sinLat1CosLat2 = sinLat1*cosLat2; - var sinLat2CosLat1 = sinLat2*cosLat1; - var cosLat1CosLat2SinDLng = cosLat1*cosLat2*Math.sin(dLng); - - for (var i=1; i < segments; i++) { - var iLng = lng1-dLng*(i/segments); - var iLat = Math.atan( - (sinLat1CosLat2 * Math.sin(iLng-lng2) - sinLat2CosLat1 * Math.sin(iLng-lng1)) - / cosLat1CosLat2SinDLng - ); - convertedPoints.push(L.latLng(iLat*r2d, iLng*r2d)); - } + if (segments < 2) { return; } + + // maths based on https://edwilliams.org/avform.htm#Int + + // pre-calculate some constant values for the loop + var lat1 = start.lat * d2r; + var lat2 = end.lat * d2r; + var sinLat1 = Math.sin(lat1); + var sinLat2 = Math.sin(lat2); + var cosLat1 = Math.cos(lat1); + var cosLat2 = Math.cos(lat2); + var sinLat1CosLat2 = sinLat1*cosLat2; + var sinLat2CosLat1 = sinLat2*cosLat1; + var cosLat1CosLat2SinDLng = cosLat1*cosLat2*Math.sin(dLng); + + for (var i=1; i < segments; i++) { + var iLng = lng1-dLng*(i/segments); + var iLat = Math.atan( + (sinLat1CosLat2 * Math.sin(iLng-lng2) - sinLat2CosLat1 * Math.sin(iLng-lng1)) + / cosLat1CosLat2SinDLng + ); + convertedPoints.push(L.latLng(iLat*r2d, iLng*r2d)); } - - convertedPoints.push(end); } + // iterate pairs of connected vertices with fn(), adding new intermediate vertices (if returned) function processPoly (latlngs, fn) { var result = []; @@ -56,6 +54,7 @@ } for (var i = 0, len = latlngs.length - 1; i < len; i++) { fn.call(this, latlngs[i], latlngs[i+1], result); + result.push(latlngs[i+1]); } return result; }