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.
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.
Leaflet JS - Is it possible query?
In a nut shell, what I am trying to do is this:
Using the latest version of Leaflet JS, I want to know if its possible to have multiple markers, in a single location, display in a single popup.
No, it's not possible.
You should pre-process your data beforehand, so that several data points with the same coordinates collapse into the same marker & popup.
In other words: iterate through your data points, and for every data point check if a marker exists in that location. If it does, add data to the marker's properties or popup; if it doesn't, create a new marker. The specific algorithm will depend on the nature of your data. You might also want to use a more complex data structure, such as r-trees, if your data set is large.
There's also the quick&dirty option of using marker clusters, disabling spiderifying, then using custom code for the event handlers of the cluster marker. That's pretty much the same algorithm defined above, only that the marker cluster algorithm takes care of locating nearby data points.
I made a similar map, and exactly as described by Ivan, I used markerCluster plugin and on cluster click action disabled the spiderfy. I then used 'custom code for the event handlers of the cluster marker' to show multiple markers' data in one single outside div.
An example can be found here .
And there is a tutorial describing exactly what you are looking for here, but also using markerCluster js.
Hope it can help others people too !
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.
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.