In a previous blog post, I had tried to speed up rendering of leaflet markers using an image. While I think this still presents an interesting approach for rendering dense map points, I didn’t think the 50k points should have caused a slowdown. Furthermore, there were two other issues:

  1. When zooming in closely, you can see the pixelation from the image. The generated image needs to balance size and generation speed.
  2. The leaflet native library does not scroll smoothly - there seems to be plugins that handle this but I wanted something that would work out of the box.

This video shows the issue:

The MaplibreGL project has matured a lot since I last looked at it, and seems to take care of the issue. Scrolling is much smoother now:

I used MapLibre’s sources and layers primitives, which seem to draw GL meshes directly, as panning and scrolling speed are smooth. However, a 3px map points is too dense when zoomed out, and so it would be better if the map points could resize dynamically according to map zoom. I think this is more than possible, but for now, I had luck simply specifying layers to be drawn at different zoom levels:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
map.addLayer({
  'id': 'baskets',
  'type': 'circle',
  'source': 'baskets',
  'paint': {
    'circle-color': DSNY_COLOR,
    'circle-radius': 1.2,
    'circle-opacity': 0.5
  }
});

map.addLayer({
  'id': 'baskets-zoomed-1',
  'type': 'circle',
  'source': 'baskets',
  'minzoom': 13,
  'paint': {
    'circle-color': DSNY_COLOR,
    'circle-radius': 2,
    'circle-opacity': 0.5
  }
});

map.addLayer({
  'id': 'baskets-zoomed-2',
  'type': 'circle',
  'source': 'baskets',
  'minzoom': 14,
  'paint': {
    'circle-color': DSNY_COLOR,
    'circle-radius': 2.5,
    'circle-opacity': 0.8
  }
});

This ensures that when zoomed out, the map looks less cluttered, but points are still visible when zoomed in.