My question is about updating the data in leaflet.
Let's assume that we have geojson which we are changing into vector tiles using geojson-vt.js and displaying it on the leaflet map.
Similiary as there: geojson-vt example
Then i'm receiving an event / notifiaction that some linestring was changed, for example thise linestrings have a attribute color, which is using when displaying data, and this value has changed.
Then i want to update my map, but i dont want to recalculate, and redraw all tiles, but only this tiles where was change. How to do that?
It cannot be done. geojson-vt only allows for creating new geojson-vt instances, not updating them. Updating data in the internal structures is too complicated, and doesn't give any big advantages. This also means it's not possible to get a list of changed tiles, or even a list of tiles containing the updated geometry.
If this is really critical for your application, consider studying the code for geojson-vt for yourself, and proposing a solution.
If you have a set of static features and a set of possibly-changing features, consider making separate holders for them.
Related
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.
I am using React Mapbox GL in my project and as i use Marker for about 10000 data points and performance is not that good. I have read the documentation and it says
Note: When rendering many objects, avoid using Markers as it will negatively affect performance. Use Layers and Features instead.
How to use Layers and Feature to display markers?
To render something with layers and features, put one or more Feature components inside of a Layer component. You can give each Feature a position using the coordinates prop.
Now, what's left over is to style these features. How you do this depends on what your markers previously contained, but for example, if you'd like to draw circles for each of the positions, you can set the Layer's type to circle and under the paint prop, provide values for circle-color and circle-radius (these are described in the mapbox-gl API docs.
For drawing images for each coordinate, you can use the icon-image layout property on the Layer (you would have to either use a preexisting icon or upload one to Mapbox Studio).
You can see some sample code in the demos, for example the all-shapes demo styles data with circles.
I'm trying to add real-time, web-socket event-based data to my map.
Everytime I get a point, I must add it/update it on map.
What's the best option?
A) Create a FeatureCollection and add a source and respective layer. When updating, change the FeatureCollection and call setData();
B) For every point, create a different source and layer. When updating, just change the respective source and call setData();
I really don't believe B) is the best option, I'm just not sure about the perfomance of option A) (or I'm thinking about the former the wrong way).
I'd say it somewhere between the two. For Mapbox Draw I use two layers, one for features that are being edited and one for features that aren't changing. In your case, you'd want to create a layer for every 100 features. This is because Mapbox GL has to recut the geojson into tiles every time you add a feature so limiting the number of features that have to be reviewed is wise. That said, lots of layers will be a problem too.
While I said 100 features above, you'll want to play around with this number a bunch. It will be about finding the right balance between number of layers and number of features in a source.
I Want to display a raster layer on to my page using ArcGIS javascript API.
Loading Feature layer is easy and pretty forward but the raster layer is giving me hard time.
Here is the the MapService: http://ags.servirlabs.net/ArcGIS/rest/services/ReferenceNode/TRMM_30DAY/MapServer/0
which is Raster layer.
Do you have any ideas on how to do this?
How you add a map service layer depends on whether or not the service is cached. Look at http://ags.servirlabs.net/ArcGIS/rest/services/ReferenceNode/TRMM_30DAY/MapServer in a browser and see the following:
Single Fused Map Cache: false
Because it's not cached, you must use ArcGISDynamicMapServiceLayer, not ArcGISTiledMapServiceLayer. If it were cached, you could use either one.
map.addLayer(new esri.layers.ArcGISDynamicMapServiceLayer(
"http://ags.servirlabs.net/ArcGIS/rest/services/ReferenceNode/TRMM_30DAY/MapServer"));
Note that if you had a service with multiple layers in it and you wanted to display only a subset of them, you would create an ArcGISDynamicMapServiceLayer and then use its setVisibleLayers method to set which layers should be visible. In this case, you don't need to worry about it, because your map has only one layer in it.
You can add raster layers to your map using the ArcGISTiledMapService layer, for example:
// assuming 'map' is a reference to your map
map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer("http://ags.servirlabs.net/ArcGIS/rest/services/ReferenceNode/TRMM_30DAY/MapServer"));
There are some good examples on the ArcGIS JavaScript API site here:
https://developers.arcgis.com/en/javascript/jssamples/#tiled_layers
One thing to be aware of with tiled layers is that you can only add tiled layers to your map if they are using the same spatial reference. You can't add a layer as a tiled layer with a different spatial reference as it's cache of tiles have already been produced using it's spatial reference. You can add a layer as a Dynamic layer to re-project it.
I want to implement my own clustering algorithm using this Virtual Earth javascript API: http://msdn.microsoft.com/en-us/library/cc966716.aspx
However, the VE engine calls my cluster function once for every shape in the layer. This makes it very slow!
It seems to me that VE should put all the shapes into a layer, then ask my function to cluster them. Not repeatedly call cluster!
Why does the VE engine do this? Is there another way to do client side clustering with this API?
More Information: I am loading the shapes from a GeoRSS feed.
The custom clustering algorithm method will only get called once for that VEShapeLayer.
Adam Byram,
There's not much difference in between using the VEMap.AddShape method and adding a VEShapeLayer to the map with all the Shapes inside. The AddShape method adds the Shape to the "default" ShapeLayer, which is the ShapeLayer with 0 (zero) index, and adding a VEShapeLayer adds a new layer in addition the the existing "default" layer.
It is probable that if you are using VEMap.AddShape to add the VEShape object to the map, that it is calling your clusting algorithm method everytime a VEShape is added to the Map. This would be correct behavior since it will need to re-calculate the clustering each time a shape is added.
To improve overall performance when adding all the shapes to the map, and to get VE to call your custom algorithm method only once when adding all the shapes; you can create a VEShapeLayer, add all the Shapes to it, then add that shape layer to the map. This will cause VE to only do the rendering of all the Shapes once (at time of loading them all) instead of each and every time you add a single VEShape.
It should only be calling your code once per VEShapeLayer - otherwise, clustering is pointless since you can't cluster a single shape. Are you using VEMap.AddShape instead of adding VEShape objects to a VEShapeLayer? If so, try creating a single VEShapeLayer, add it to the VEMap, and then add all VEShape objects to the shape layer instead of the map.