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

Function "closest" adds extra points to layers #59

Open
aver-ua opened this issue Sep 15, 2016 · 6 comments · Fixed by #60
Open

Function "closest" adds extra points to layers #59

aver-ua opened this issue Sep 15, 2016 · 6 comments · Fixed by #60
Assignees
Labels

Comments

@aver-ua
Copy link

aver-ua commented Sep 15, 2016

There is an issue, described in title
Please see this plunk
Click to set markers and see in console how latlngs of polygon grows.
It seems to me, that it happens because function "slice()" does not makes deep copy for nested arrays (line 205 in source)

@mdartic mdartic mentioned this issue Sep 19, 2016
@mdartic
Copy link
Member

mdartic commented Sep 19, 2016

You're right.
Check 0.7.2, I let you close the issue if it's ok for you.

@mdartic mdartic reopened this Sep 19, 2016
@aver-ua
Copy link
Author

aver-ua commented Sep 19, 2016

@mdartic,
I cheked 0.7.2 in my app, but I got an errors "Uncaught TypeError: Converting circular structure to JSON".
Simple code like in my previous post works correct, but more complex - no.
I try to figure out what was going on...

@aver-ua aver-ua closed this as completed Sep 19, 2016
@aver-ua
Copy link
Author

aver-ua commented Sep 20, 2016

@mdartic,
My investigation shows, that "closest" raises errors "Uncaught TypeError: Converting circular structure to JSON" in conjuction with Leaflet.Editable, Leaflet.Snap and GeoJSON layers.
I can't provide (yet) test case (plunk, for example), that illustrates this issue.
But I found workaround for me. I changed the line in source
latlngs = JSON.parse(JSON.stringify(layer.getLatLngs().slice(0)));
to

function deepClone(arr) {
  var len = arr.length;
  var newArr = new Array(len);
  for (var i=0; i<len; i++) {
    if ((Array.isArray(arr[i]))&&(!(arr[i] instanceof L.LatLng))) 
      newArr[i] = deepClone(arr[i]);
    else 
      newArr[i] = arr[i].clone();
  }
  return newArr;
}       
latlngs=deepClone(layer.getLatLngs().slice(0));

@peterlawless
Copy link

@aver-ua thanks for the fix, worked perfectly for me.

@mdartic mdartic self-assigned this Aug 8, 2017
@mdartic
Copy link
Member

mdartic commented Aug 8, 2017

@aver-ua sorry to be so late, but do you have now a small example to be integrate in a test ?
could be useful to remember this after fixing it.
if not, I'll integrate your deepClone method.

@aver-ua
Copy link
Author

aver-ua commented Nov 2, 2023

@mdartic sorry to be so so so late...
i found in my leaflet.geometryutil.js following code for closest function

closest: function (map, layer, latlng, vertices) {

function extractLatLngs(arr,latlngs) {
if ((arr instanceof Array)&&(arr[0] instanceof L.LatLng)) {
    for (var j=0;j<arr.length;j++)
     latlngs.push(arr[j]);
    latlngs.push(arr[0]);// we need also last segment!
}
else 
 for (var i=0;i<arr.length;i++)
  extractLatLngs(arr[i],latlngs);
} 

    if (typeof layer.getLatLngs != 'function')
        layer = L.polyline(layer);
	
    var latlngs = [],
        mindist = Infinity,
        result = null,
        i, n, distance;
		
	if (layer instanceof L.Polygon) {
	    extractLatLngs(layer.getLatLngs(),latlngs);			
	} else latlngs=layer.getLatLngs().slice(0);


    // Lookup vertices
    if (vertices) {
        for(i = 0, n = latlngs.length; i < n; i++) {
            var ll = latlngs[i];
            distance = L.GeometryUtil.distance(map, latlng, ll);
            if (distance < mindist) {
                mindist = distance;
                result = ll;
                result.distance = distance;
            }
        }
        return result;
    }

    // Keep the closest point of all segments
    for (i = 0, n = latlngs.length; i < n-1; i++) {
        var latlngA = latlngs[i],
            latlngB = latlngs[i+1];                
        distance = L.GeometryUtil.distanceSegment(map, latlng, latlngA, latlngB);
        if (distance <= mindist) {
            mindist = distance;
            result = L.GeometryUtil.closestOnSegment(map, latlng, latlngA, latlngB);
            result.distance = distance;
        }
    }
    return result;
}

moreover, the previous version with deepClone is commented out.
and it worked for more than 5 years without any problems. there is no problem with "extra points" and GeoJSON layers.
i don't know who is an author of this code... it seems to me that it's not me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants