1

I'm having issues using Leaflet while trying to add a large set of points to a canvas rendered layer.

I'm creating +85.000 points using a code similar to the following one:

First I load a quadtree with all my points, a single point is a class with some other specific stuff, but regarding the leaflet stuff we have the following code:

var myCanvasRenderer = L.canvas({ paneName });

var geojsonMarkerOptions = { fillColor: "#AFC5CA", color: "#000", weight: 1, opacity: 1, fillOpacity: 0.8, stroke: false, renderer: myCanvasRenderer, pane: paneName }

point.circle = L.circle(latlng, 0.5, myHandler.geojsonMarkerOptions);

Then the point is added to a quadtree. When the map is moved, I handle to event to draw the points inside the viewport, the point itself is drawn calling the following method:

circle.addTo(myLayer);

I've limited the drawing to 20.000 points. Stopping the process when this limit is reached and measured the time using console.Time

With the circle.addTo call, the process takes about 80 seconds to draw the 20.000 points. Commenting that call, the process takes about 8 seconds to "draw" the 20.000 points. ("draw" because not is really drawn)

  • All the points must be drawn, so solutions that involve clustering points are not an option.
  • I must have an handler to the drawn circle, because later in the application I need to show / hide some points or change their color

How can I speed up the drawing of the points? Is there anything similar to a "bulkAdd" method in the leaflet library?

Thanks in advance for your help

  • 1
    Have you tried the `preferCanvas` map option? – ghybs Jul 12 '17 at 15:41
  • Hello ghybs, I've not tried that option because I'm already setting the canvas in the renderer property of the geojsonMarkerOptions that are passed to the circle. So, the circles are already drawn on a Canvas and not in a SVG renderer – Eduardo Poças Jul 13 '17 at 16:47

1 Answers1

1

What very probably happens is that your Circles are actually not drawn on your specified Canvas.

You can use your browser DOM inspector to check.

In Leaflet 1.x.x, the radius of the Circle is specified as radius option, instead of 2nd argument:

L.circle([50.5, 30.5], {radius: 200}).addTo(map);

Therefore in your code, the 2nd argument 0.5 has no effect, and your 3rd argument (myHandler.geojsonMarkerOptions) has no effect either, leading to not using your canvas.

ghybs
  • 47,565
  • 6
  • 74
  • 99
  • Hello, I've updated to code to not use the deprecated method but only the new one, so I've passed the radius: 0.5 parameter to my geojsonMarkerOptions and invoked the constructor with only two parameters. However this did not solve the problem as it is still taking about 80 secs to draw 20K points – Eduardo Poças Jul 15 '17 at 11:17
  • Make sure you correctly use Canvas, e.g. using your DOM inspector as stated above. I have an example with 100k circle markers here: https://stackoverflow.com/questions/43015854/large-dataset-of-markers-or-dots-in-leaflet/43019740#43019740 It loads in a few seconds on my machine. Replacing them by Circles gives similar performance. – ghybs Jul 15 '17 at 17:53
  • I've checked and we're using correctly the canvas renderer. There are no DOM entities associated to each circle. I've checked your answer in the question you suggested and also checked your fiddle example: https://jsfiddle.net/sgu5dc0k/. If you zoom out that same example you'll see that the map hangs and is unable to answer to the 100K points. i.e. it only works with the 100K points because it is NOT rendering them as they are outside the viewport. – Eduardo Poças Jul 16 '17 at 21:11
  • Well you should investigate on that. I have no problem at all rendering the entire world with 100k points all on screen. – ghybs Jul 16 '17 at 21:21