So I want to build a map application with backbone(probably using Leaflet.js). I have a few ideas on how to design this, and I was wondering if there was a common design pattern on how to do this.
The map will eventually be integrated with other visualizations - for example if I select a marker on the map something will happen in another visualization. I must also be able to conduct geo-searches on the markers in the map.
There are two ways I thought of doing this -
1.Have a backbone model per marker, have a collection of markers, have a Map View that works on this collection. So whenever this collection changes, re-render the map.
2.Have a model called MapModel that holds json, and have a data function that filters the json (based on a geosearch or something). The Map then simply renders this json.
The advantage of 1 is that I think it would be easy to do selections, but as my map may deal with tens of thousands, to hundreds of thousands of objects, I feel like things would be very very slow.
Is there another way to do this, or which one of the two ideas I've had is preferable?
Thanks
I've been working on exactly the same problem, I do not claim to have found a "common design pattern", but I can tell you what I did.
I created a MapModel which contains the info necessary to make the map: for instance a collection of stores if you want to put stores on your map.
Then I created a View of the map with no collection of markers: the problem is that a group of markers in leaflet is supposed to be grouped in a L.LayerGroup class (for instance to control when they are added or removed - example). So it feels very clumsy to have the markers in a LayerGroup and in a collection disguised as models.
So I created a layerGroup holding all the markers, this layer being a property of the MapView. If your app is complex, you may even create a subView for each layer.
When you want to filter you filter on the model, which is easy since it's a backbone collection, then you render the View.
my map may deal with tens of thousands, to hundreds of thousands of objects
That's problematic. It's impossible to place such a huge number of markers on webmap, you should plan how to deal with it (a popular plugin)
Related
I have a procedurally generated game using tilemaps for easier generation and pathfinding, and I need to be able to have musltiple layers for things like seperate depths for different groups of objects, but the room data is specified at the creation of the map, not at the creation of the layer, unless something like tiled is used, which I can't use due to the fact that my game will be procedurally generated. I could go through the array and place individual tiles with a loop, but is there any other solution that I'm missing? Thanks!
You could do the something I mentioned in this answer, basicly, creating two maps with the same dimensions, set the z-order with setDepth, and if the map above has transparent tiles, or tiles with the ID -1, the map below should be visible.
I personally never used it for larger maps, but I assume it should not cause performance issue, and is an easy solution.
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.
I'm using Bing Maps to show locations of stores. The store information is being populated from a dynamic JSON response. On page load, the map loads local stores with pushpins and infoboxes. When the map pans, I want to keep the pins that are already on the map where they are, and create additional pins of stores within the radius of the map's bounding box, and remove them when they leave the radius (all while keeping the original store pushpins).
Right now, I'm at the point of populating the map, and adding the new pushpins as the map pans. However, I'm kind of lost when it comes to removing the new pins, while maintaining the original ones. From my Google searches, and research, I think I'd want to create two entitiy layers for the pins, and then remove the pins on the second entity layer as the map pans around, while re-populating with new store pins.
Does this make sense? Does anyone have any idea how to create pins on two separate entity layers, and then remove the pins on one of the layers?
Thanks!
You need to add the pushpins in two different EntityCollection (they're like Shape layer), see: http://msdn.microsoft.com/en-us/library/gg427616.aspx
If you added the secondary pushpins in a separate entity collection, then you can call clear() on the specific entity collection to remove the secondary pushpins and add the new ones without removing your main pushpins.
If you need more help, let us know.