54

I want to render about 10.000 markers or dots on a leaflet map. I already did it the regular way and I found it is way slower compared to Google Maps. I'm looking for a way to render multiple elements without getting the performance issues.

Is there a way to do this with Leaflet?

Update: I don't want to plot with bright dots that can't handle events. I want to actually paint markers with different colors and events.

AFP_555
  • 2,392
  • 4
  • 25
  • 45
  • Possible duplicate of [Plotting 140K points in leafletjs](http://stackoverflow.com/questions/37043791/plotting-140k-points-in-leafletjs) – ghybs Mar 25 '17 at 14:11
  • I actually want to draw dots or markers with different characteristics. Color, shape... etc. Not just create an overlay. – AFP_555 Mar 25 '17 at 14:33
  • 1
    You can give a try with Circle Markers (you can adjust their colour) on a [Canvas](http://leafletjs.com/reference-1.0.3.html#map-prefercanvas) – ghybs Mar 25 '17 at 14:35
  • Are circle markers faster than regular markers? Is it possible to change the color of the 140K points? I implemented it before asking, but I couldn't change the color of the dots. – AFP_555 Mar 25 '17 at 14:36
  • If you use canvas, yes, it is faster. For the color, it is just a matter of option when instantiating it. – ghybs Mar 25 '17 at 14:39
  • I feel like people in Stackoverflow really like downvoting questions. If you think the question is too broad, maybe tell me why and I'll try to re-adjust it. This way I can make a better question, you can answer it and we can build a better knowledge base and healthier community. I've read many Meta posts about StackOverflow non-constructive attitude but only recently I've lived it. – AFP_555 Mar 25 '17 at 14:42
  • @ghybs could you please tell me how to change the color of the dots with canvas. I already implemented that solution but I didn't find an option for the color. I'm not sure if it is possible. – AFP_555 Mar 25 '17 at 14:48
  • Use [Circle Markers](http://leafletjs.com/reference-1.0.3.html#circlemarker) with [`color` option](http://leafletjs.com/reference-1.0.3.html#path-color) – ghybs Mar 25 '17 at 14:58
  • Is this what you mean by using CircleMarkers with Canvas? var myRenderer = L.canvas({ padding: 0.5 }); var circle = L.circleMarker( center, { renderer: myRenderer } ); – AFP_555 Mar 25 '17 at 15:09
  • @ghybs Holy crap. Amazing. Post it as the answer and I'll check it. It does work and it's super fast. – AFP_555 Mar 25 '17 at 15:23

5 Answers5

116

The performance issue is due to the fact that each marker is an individual DOM element. Browsers struggle in rendering thousands of them.

In your case, an easy workaround would be instead to use Circle Markers and have them rendered on a Canvas (e.g. using map preferCanvas option, or with a specific canvas renderer that you pass as renderer option for each of your Circle Marker). That is how Google Maps works by default: its markers are actually drawn on a Canvas.

var map = L.map('map', {
    preferCanvas: true
});
var circleMarker = L.circleMarker(latLng, {
    color: '#3388ff'
}).addTo(map);

or

var map = L.map('map');
var myRenderer = L.canvas({ padding: 0.5 });
var circleMarker = L.circleMarker(latLng, {
    renderer: myRenderer,
    color: '#3388ff'
}).addTo(map);

With this solution, each Circle Marker is no longer an individual DOM element, but instead is drawn by Leaflet onto a single Canvas, which is much easier to handle for the browser.

Furthermore, Leaflet still tracks the mouse position and related events and triggers the corresponding events on your Circle Markers, so that you can still listen to such events (like mouse click, etc.).

Demo with 100k points: https://jsfiddle.net/sgu5dc0k/

ghybs
  • 47,565
  • 6
  • 74
  • 99
  • Is it possible to add an anchor to the circle marker or show any customized svgs in the canvas? – LASkuma Sep 21 '18 at 20:24
  • @LASkuma I am not sure I fully understand your question, especially about the anchor. As for [drawing SVG on a canvas](https://stackoverflow.com/questions/3768565/drawing-an-svg-file-on-a-html5-canvas), that is [totally up to you](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas). There should be some [Leaflet plugins](https://leafletjs.com/plugins.html) providing ways to use fancy icons, e.g. [Leaflet.Canvas-Markers](https://github.com/eJuke/Leaflet.Canvas-Markers). Please feel free to open a new question with detailed description of your issue. – ghybs Sep 23 '18 at 01:04
  • solved the problem little bit, but on zooming in and out it's hanging. Any solution for this? – Gaurav Paliwal Nov 02 '18 at 13:56
  • 1
    @GauravPaliwal please feel free to open your own question with details of your specific issue and reproduction code. – ghybs Nov 03 '18 at 07:08
7

[2019]

Maybe a little too late but Pedro Vicente's answer seems to be the best option out there. Leaflet.glify ( https://github.com/robertleeplummerjr/Leaflet.glify.) is good but you don't have options other than create a dot, shapes and line on your map. (no customization yet.) PixiOverlay works with native/custom markers. It also has nice visualization (animation,scaling,etc..) It also works in IE 11. For me it's a must if you're dealing with tons of markers. go try it out https://github.com/manubb/Leaflet.PixiOverlay

P.S Glify and PixiOverlay are both utilizing WebGL so performance varies on your users' computer.

Lex Dacs
  • 161
  • 3
  • 10
  • 1
    I'm not sure about that because L.glify have totally different API instead of Leaflet. So, It's more logical to switch to just another production ready webGl based map – Travnikov.dev Feb 17 '20 at 11:54
  • In my view the different API is a *good* thing as you don't have to create a new object for every point; you can add a bunch of points in an array. – Nicholas Riley Apr 23 '20 at 14:03
5

You should check https://github.com/robertleeplummerjr/Leaflet.glify. It provides way of rendering leaflet points and polygons using web gl, allowing to scale more easily.

It's also available for the people that uses R to produce their leaflet: https://github.com/tim-salabim/leaflet.glify

The R version is super easy.

Bastien
  • 3,007
  • 20
  • 38
5

I got good results with the official Leaflet plugin PixiOverlay. https://github.com/manubb/Leaflet.PixiOverlay

Pedro Vicente
  • 681
  • 2
  • 9
  • 21
1

You can check out the marker cluster, it can cluster your map till you zoom into get the detail. I am currently working on loading real estate information and it seems to solve problem with more than 300000 loations to place on the map.

https://github.com/Leaflet/Leaflet.markercluster