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

Exception in LatLngBounds.intersects() with chunkedLoading #743

Closed
taleteller opened this issue Dec 16, 2016 · 11 comments · Fixed by #891
Closed

Exception in LatLngBounds.intersects() with chunkedLoading #743

taleteller opened this issue Dec 16, 2016 · 11 comments · Fixed by #891

Comments

@taleteller
Copy link

I am currently working on a Map Application loading 1000+ of markers via ajax, clustering them using markerclusters. When enabling chunkedLoading, and only then, I randomly experience the following exception while dragging:

TypeError: ne2 is undefined
L.LatLngBounds.prototype.intersects()
L.MarkerCluster<._recursively()
L.MarkerCluster<._recursivelyRemoveChildrenFromMap()
L.MarkerClusterGroup<._moveEnd()
L.Evented<.fire()
L.Map.Drag<._onDragEnd()
L.Evented<.fire()
L.Draggable<.finishDrag()
L.Draggable<._onUp()
L.DomEvent._on/handler()

It happens in the function L.LatLngBounds.prototype.intersects() being called from L.MarkerCluster._recursively(). Since there is no better way to update lots of markers against an external loaded set, updating is done by calling clearLayers() and addLayers(). I have tested this issue on recent Firefox and Google Chrome.

Of course the marker update function is bound to "zoomend dragend", and the mass update calls seem to conflict with the event MarkerClusters is binding itself for clustering functionality, therefore trying to check intersection of already gone markers. Since there is no exception handling, the map cannot be dragged anymore after failing as above.

I think there should either be exception handling, validity or timing checks with chunkedLoading enabled.

@danzel
Copy link
Member

danzel commented Jan 25, 2017

Hmm, so you are calling clearLayers while the chunkedLoading is still going on?
If you could make a reproducing test case that'd be great to help investigate this.

@lax20attack
Copy link

I may have stumbled on to the same issue.

The bounds are not valid when trying to see if they intersect.

3-2-2017 12-12-34 pm

A potential solution would be to check if the bounds is valid before seeing if they intersect.

3-2-2017 12-17-49 pm

Hope this helps.

@danzel
Copy link
Member

danzel commented Mar 6, 2017

Why are the bounds not valid?

@MickaelBergem
Copy link

I happen to face the same issue or at least a close one, reproducible when I try to zoom / move the map during the building/rendering of the clusters. I'll try to see if I can reproduce it.

My bug:

vendor.js:11 Uncaught TypeError: Cannot read property 'lat' of undefined
    at n.LatLngBounds.intersects (vendor.js:11)
    at e._recursively (vendor.js:16)
    at e._recursively (vendor.js:16)
    at e._recursively (vendor.js:16)
    at e._recursivelyAddChildrenToMap (vendor.js:16)
    at vendor.js:16
    at e._recursively (vendor.js:16)
    at e._recursively (vendor.js:16)
    at e._animationZoomIn (vendor.js:16)
    at e._mergeSplitClusters (vendor.js:16)

I'll also post a more verbose stacktrace if necessary.

@ghybs
Copy link
Contributor

ghybs commented Jun 4, 2017

@MickaelBergem
Copy link

@ghybs I have the exact same issue and your answer looks totaly right to me: MCG does not maintain a valid state between each chunkedLoad, triggering this warning (and errors sometimes although I wasn't able to reproduce it) when the map is resized, zoomed, or dragged.

I see three high-level solutions:

  • queue the map events during rendering and apply them after loading is complete
  • make sure the internal state is valid at the end of each chunk
  • if it is possible, generate the layer in a chunked manner but only bind the layer to the map after loading completed

I have no knowledge of the inner architecture of neither leaflet nor MCG so I may certainly be misunderstanding the problem / the possible solutions.

@davidmann4
Copy link

fixed this by disabling chunked loading, only was an issue on IOS in a webview though ... strange bug!

@boldtrn
Copy link
Contributor

boldtrn commented Feb 27, 2018

Wouldn't #816 fix this issue? I tried to write a test for this, but I cannot get the current set of tests to run (also see failing Travis build), which is kind of essential before adding a new test.
Update: I tried #816 and it didn't fix the issue for me.

As a temporary fix it might be possible to use the chunckProgress function. It doesn't work for my use case though.

@boldtrn
Copy link
Contributor

boldtrn commented Feb 28, 2018

Why are the bounds not valid?

@danzel I did some debugging and it seems that a child in MarkerCluster#recursively can contain the attribute _boundsNeedUpdate = true and empty bounds. As mentioned before this happens with chunkedLoading.

If fixed this locally using this code:

for (i = childClusters.length - 1; i >= 0; i--) {
   c = childClusters[i];
   if (c._boundsNeedUpdate) {
      c._recalculateBounds();
   }
   if (boundsToApplyTo.intersects(c._bounds)) {
      c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);
   }
}

I think this code is pretty performance critical, so I also tried:

if (c._boundsNeedUpdate) {
   continue;
}

Both seem to work. I have seen the issue with missing bounds quite often. I only clear the markerCluster partially and once it's cleared I instantly pump in new data (so I am not sure if this could be the reason). I remove the markers using the MarkerClusterGroup#removeLayers method.

I can create a PR if you want or feel free to go ahead :). I am not sure if I can create a test though.

@wurmrobert
Copy link

wurmrobert commented Apr 3, 2018

I´m using Angular Version 5.2.9.
I have exact the same problem:
Error: Uncaught (in promise): TypeError: Cannot read property 'lat' of undefined

It´s the same like the marker-clustering-realworld.10000 example:

`
private async initMap() {
var map = L.map('map', {
center: [47.8094900, 13.0550100],
zoom: 12
});

	L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', {
		maxZoom: 18,
		attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="http://cartodb.com/attributions">CartoDB</a>',
		subdomains: 'abcd'
	}).addTo(map);

	var addressPoints = [
		[-37.8133062833, 175.2721598, "3"],
		[-37.8129763667, 175.2714296333, "10"],
		[-37.81369515, 175.2714571167, "11"]
	];
	var markers = L.markerClusterGroup();

	for (var i = 0; i < addressPoints.length; i++) {
		var a: any = addressPoints[i];
		var title = a[2];
		var marker = L.marker(new L.LatLng(a[0], a[1]), { title: title });
		marker.bindPopup(title);
		markers.addLayer(marker);
	}

	map.addLayer(markers);
}

`

@antholord
Copy link

Hi, I am still getting this same error when opening the map. It happens specifically when used in conjuction with the Leaflet.pm lib used to draw shapes. It's possibly caused by adding a new shape on the map in the middle of the chunked loading process. Disabling chunkLoading fixes it.

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

Successfully merging a pull request may close this issue.

9 participants