Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor more #6

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 42 additions & 18 deletions src/L.Geodesic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@
var r2d = 180.0/Math.PI;
var earthR = 6367000.0; // earth radius in meters (doesn't have to be exact)

function segmentFn (start, end, line) {
var segments = Math.floor(Math.abs(line.dLng * earthR / this.options.segmentsCoeff));
if (segments<2) { return false; }
line.segments = segments;
}

// 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
// points code that have been seen
function geodesicConvertLine (start, end, convertedPoints) { // push intermediate points into convertedPoints

function geoLine (start, end, limitFn) {
var lng1 = start.lng * d2r;
var lng2 = end.lng * d2r;
var dLng = lng1-lng2;
var line = {
lng1: lng1,
lng2: lng2,
dLng: dLng
}

var segments = Math.floor(Math.abs(dLng * earthR / this.options.segmentsCoeff));
if (segments < 2) { return; }

// maths based on https://edwilliams.org/avform.htm#Int
if (limitFn && false === this[limitFn](start, end, line)) {
return;
}

// pre-calculate some constant values for the loop
var lat1 = start.lat * d2r;
Expand All @@ -30,16 +39,26 @@
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))
// maths based on https://edwilliams.org/avform.htm#Int
line.getIntPointLat = function (lng) {
return Math.atan(
(sinLat1CosLat2 * Math.sin(lng-lng2) - sinLat2CosLat1 * Math.sin(lng-lng1))
/ cosLat1CosLat2SinDLng
);
convertedPoints.push(L.latLng(iLat*r2d, iLng*r2d));
}
return line;
}

function geodesicConvertLine (start, end, convertedPoints) { // push intermediate points into convertedPoints
var line = this_geoLine(start, end, '_segmentFn');
if (!line) { return; }

for (var i=1; i < line.segments; i++) {
var iLng = line.lng1-line.dLng*(i/line.segments);
var iLat = line.getIntPointLat(iLng);
convertedPoints.push(L.latLng(iLat*r2d, iLng*r2d));
}
}

// iterate pairs of connected vertices with fn(), adding new intermediate vertices (if returned)
function processPoly (latlngs, fn) {
Expand All @@ -59,7 +78,7 @@
return result;
}

function geodesicConvertLines (latlngs) {
function processWrapped (latlngs, fn) {
if (latlngs.length === 0) {
return [];
}
Expand All @@ -73,29 +92,34 @@
// within +-180 degrees
latlngs = latlngs.map(function (a) { return L.latLng(a.lat, a.lng-lngOffset).wrap(); });

var geodesiclatlngs = this._processPoly(latlngs,this._geodesicConvertLine);
latlngs = fn.call(this, latlngs);

// 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;
return latlngs.map(function (a) { return L.latLng(a.lat, a.lng+lngOffset); });
}

var polyOptions = {
segmentsCoeff: 5000
};

var PolyMixin = {
_segmentFn: segmentFn,

_geoLine: geoLine,

_geodesicConvertLine: geodesicConvertLine,

_processPoly: processPoly,

_geodesicConvertLines: geodesicConvertLines,
_processWrapped: processWrapped,

_geodesicConvert: function () {
this._latlngs = this._geodesicConvertLines(this._latlngsinit);
this._latlngs = this._processWrapped(this._latlngsinit, function (latlngs) {
return this._processPoly(latlngs, this._geodesicConvertLine);
});

this._convertLatLngs(this._latlngs); // update bounds
},

Expand Down