Plotting 140K points in leafletjs - leaflet

I'm new to leafletjs. Been working on cesiumjs for a while and we are trying leaflet now. The main reason for the switch is to see if there's a huge performance difference.
In Cesium, I had a collection of primitive points that I plotted. What's the most efficient way of plotting 140K points in leafletjs? Using markers or creating individual little circles?
I am also thinking of using the clustering plugin (http://leafletjs.com/2012/08/20/guest-post-markerclusterer-0-1-released.html), so please share any thoughts on performance.

You have 2 common options:
Display your points in a Canvas-based layer, like using Circle Markers and force rendering them on a Canvas instead of SVG (see also Leaflet MaskCanvas plugin). Circle Markers, even on a canvas, still emit events, so you can detect "click" etc.
Use a clustering plugin, like Leaflet.markercluster plugin that you mention for exampe. It can handle your 140k points, depending on the client's computer performance (see https://github.com/Leaflet/Leaflet.markercluster#handling-lots-of-markers and demo http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.50000.html with 50k points, but note that the demo uses an old version of the plugin, whereas the current version is even faster).
Trying to display your 140k points without Canvas or clustering will crash your browser for sure.

If you want to render more than 100k markers, you can use Supercluster library, because Leaflet.markercluster loading of >100k markers could take more than 30 seconds.
I created a github repo to compare initial loading of Leaflet.markercluster and Supercluster.

Related

Mapbox GL - transition animations for unclustering and for active feature

In Mapbox GL JS, I'm looking to use clustering + use a different icon for one feature which is currently defined as "active". I want the necessary transitions (unclustering + change of the active feature) to be animated, but can't find a way of making this all happen.
Mapbox provides an example showing how to implement clusters, which uses different layers for the clusters and for non-clustered features. This technique can also be used for rendering the "active" feature in its own layer with a different image. When a cluster breaks ("unclusters") into features, it basically gets removed from the clusters layer, and the features get added to the "unclustered" features layer. But this doesn't allow adding a transition animation, since there isn't really a transition here. I would like to show the cluster splitting into features, with each feature moving to its respective location.
Any ideas how to solve this?
Some ideas that don't quite provide a full answer:
Use Leaflet with the markercluster plugin and its "spider" behavior for clustering. This works and provides a nice "spider" transition animation for unclustering. However there is no "official" binding between leaflet and Mapbox GL, so I'm reluctant to use that (there is just this which I would need to modify and it's based on undocumented Mapbox internals). Also I'm now sure whether this is good or bad performance-wise with thousands of features. And I know from experience that adding an animation to modify the shape of Leaflet markers (for active/inactive transitions) doesn't really work.
Use markers in Mapbox, instead of layers, but then how to do any sort of clustering?
I can't think of any reasonable way to implement this just using Mapbox GL JS, short of learning WebGL and implementing a custom source.
But I wouldn't write off the Leaflet+Mapbox approach - in my experience, the performance is ok (though I haven't tested with clusters or what you're trying to do).
There is a similar approach with OpenLayers: https://openlayers.org/en/latest/examples/mapbox-layer.html I have also used this and it worked fine.
Finally, it seems there are quite a few Leaflet and OpenLayers libraries that specifically solve the animated clustering issue: https://gis.stackexchange.com/questions/17250/how-to-create-animated-cluster-markers-in-openlayers-leaflet (And most of these answers are very old, so perhaps there are more libraries now).

How to write text onto a mapbox vector tile

I want to label stations on my map, and I would like to clusterize the stops at different zoom levels to filter them down. So as you zoom out all you get is the start and end, and then finally a single label start->end.
How do I render a text label on a vector tile ?
I could fetch the stations as a geojson and reload on zoom change if there's no easy way to do this with tiles.
Is there a reason you need to encode your data differently per-zoom-level in the tiles or are you mainly concerned with displaying data differently per-zoom-level? If the latter, I would recommend looking for an approach that focuses more on styling the vector tiles you already have rather than trying to generate those tiles in a more complex fashion. You could try using a zoom function to style your data. If you're using Mapbox Studio, you can also set zoom-specific style rules in the Studio UI, which is the route you'll probably want to go if you're using Leaflet (I see the Leaflet tag in your post but it's not entirely clear what your implementation looks like).
If the former, you may need to use a tool like Tippecanoe. This route will likely be a bit more complex, but gives you fine-grained control over how your vector tiles are generated. Keep in mind that once you've created your tiles using Tippecanoe, you'll still need to style them somehow.

Marker versus point feature?

When should one use a marker instead of a feature layer of points in Mapbox?
Points layers can be updated and styled dynamically using all the styling tools of Mapbox GL JS. Features in points layers can also be clicked, presenting a popup just like with a marker.
Given this, when would one want to use a marker?
As Andrew mentioned there are two sides two this:
Accessibility
Markers are implemented as DOM elements and thus can be included in the tab order and can be given accessibility attributes
Animation
As markers are DOM elements animating them is quite easy with a bit of CSS & JS. You can animate points on a circle layer too, but its much more of a hassle.
Small point count
The number of markers/points you can display at once is somewhat limited by what the DOM can manage. My suggestion is that, if you have more than 500 points to display, you should opt for a circle layer instead of markers (this is a very rough estimates and depends on other parameters as well, animation, point size etc.). Using a circle layer you will hit - depending on the hardware - a limit in the 10s of thounds of points.

Mysterious "markers" using Leaflet (with Omnivore and the MapQuest plugins)

I'm using Leaflet (with omnivore and the MapQuest tile plugins) to display a map with colored polygons. The map and polygons look/work fine, but there are these mysterious blue markers everywhere.
There's nothing in the JS about markers at all, and if I comment out the polygon.addTo(map); line, the markers disappear. So they're definitely related to the polygons, even though they're not directly positioned on the polygons.
Any idea why the markers are appearing, or how I can make them disappear?
SOLVED: It turns out that the problem was that I'm using MSSQL's ".Reduce(n)" function to simplify the polygons (for performance), and if you simplify the polygons too far, the results have "Point(...)" items in them - which leaflet renders as markers!
Now, off to figure out why MSSQL is turning things into points...
Welcome to SO!
Most probably your polygon variable is a Leaflet GeoJSON Layer Group built by the omnivore plugin, and the data you feed it with contains "Point" type geometries.
If you do not specify anything special to handle these points, Leaflet will render them with this default blue marker icon.
In that case, you could simply filter out those point features, whether after omnivore processing (use the ready event) or using a custom GeoJSON Layer Group with its filter option. There should be other posts describing such solutions.
See e.g. Mapbox: Filtering out markers in a Leaflet Omnivore KML layer
If you are not in this case, you would have to provide more information for people to be able to help you. Typically code that you use to build your polygon layer and sample data.

Mapbox Studio - layer ordering / z-index

I am following the source quickstart tutorial. I have followed the tutorial all the way through, and am having trouble displaying the earthquake data (red circles) above the land vectors.
According to the symbol drawing order documentation:
“Higher” layers obscure “lower” ones.
However I'm not finding this to be the case. Please see attached screenshot:
The 'earthquakes' layer is the 'higher' layer, I think. I am using the 'Comic!' base map styles. Since the road lines also appear to 'mask off' the land vectors and show the earthquake data below, I'm wondering if this is causing the issue, but looking through the styles there's nothing obvious I can see.
Thanks for any help.
The documentation is correct, however the comp-op family of CartoCSS properties affect how the colors of different layers interact with each other. In this case, the marker-comp-op: screen from the quickstart example was designed to work well over a darker satellite background, but becomes nearly invisible over solid white.
If you remove the marker-comp-op property or change it to a different compositing operation such as multiply the earthquake markers should show up fine.