I am able to display a Google Maps map on a web site and load hundreds of markers for the current map area and display them. The problem is how to behave when the map is zoomed in/out or is moved, so the map area changes.
There is a part of the map that is the same than before, and so are the markers in it. But there is a part of the map that is new and new markers should be added.
Right now I am doing the simplest solution, clearing all markers, retrieving markers for the current map area and add them. This produces a flickery effect on the markers (obviously) due to clear and add immediately after.
What is a efficient way to deal with this situation?
Is there a way to check if a marker has already been added to the map?
You can use a marker cluster or a clustering algorithm to group marker that are close together when you zoom out and ungroup them when you zoom in. It can significantly reduce the database query time and the map drawing. A good solution is a kd-tree.
To check if a marker has been added to the map, call the getMap method of the marker and if it returns a map object, it has been added.
To check if a marker is in the visible area of the map, you can call the getBounds method on the map which returns a LatLngBounds. Then call the contains method of the returned LatLngBounds passing the coordinates of the marker.
Hope this helps
Related
I have a list of geojson polygons that i am showing on my map, i am trying to determine, based on the current bounds of the map, if any part of the polygon is on the map. Any ideas as far as functions in the api to determine this?
I have tried the bounds.contains() method but it looks like that needs a specific point rather than an area.
Eric, I think you can get a center point of each polygon and set marker to it. So you can use it to represent a polygon.
I'm using Google Maps to set some markers. I have things setup so that when an item in a list is hovered on the marker will highlight.
This is done easy enough by keep a hash of the markers. So that when I hover over an item it just updates the icon in the marker.
this.markers[hoverItem.id].setIcon('/img/map/active-marker.png');
This works just fine. However I'm also using the marker-clusterer-plus plugin with Google Maps. The problem I'm having is to highlight the cluster icon if the marker is inside.
I can't find away to access the cluster object of the marker. Is there anyway to access or set it somehow?
Looking at the code...:
...you'd probably need to call MarkerClusterer.getClusters to get all the clusters.
Then loop through them, perhaps then calling Cluster.getMarkers and checking if your marker is in each cluster's array of markers.
Cluster.isMarkerInClusterBounds and Cluster.isMarkerAlreadyAdded_ might also be useful.
I ran into a leaflet issue but I can't solve it. May be there's a easy solution I don't know.
So basically centering a map of grouped markers isn't so difficult and can be done like the following:
var markerLayer = L.featureGroup(marker)
.addTo(map);
var bounds = markerLayer.getBounds();
map.fitBounds(bounds);
where marker is an array of markers. But my problem is that the marker array information I send to this code are generated by another system. So basically the marker can be far apart in the map or they can be really close.
When the markers are far apart the code above works perfectly and centers the map. However if the markers are really close (for example if they are from the same street), or better yet if there is only one marker problems arise. This is because getbounds will give me a rectangle that is so small that leaflet breaks (and this is of no use for the user as well). I mean the map basically tries to zoom in to that marker. So my question is how do I limit the zoom. For example if there is only marker in the map I want the map to show the marker and few streets around it.
You can give a maxZoom to the map and the fitBounds will not override it.
The method map.fitBounds takes a parameter called maxZoom. This way you can have two maxZooms, one for the map and one for fitBounds.
I'm converting a mapping utility from Gmap to Bing. In Google Maps, you can easily add markers to the map, and each time you add a marker, you add the location of the marker to a bounds object, then call setBounds() on the map to recenter the map to fit all markers.
I cannot find a similar method to work with Bing Maps, and the docs are pretty lousy compared to Google's.
So far I've got the map created and markers added-- but the map stays stuck at the initial view, rather than updating to fit the markers.
Is there an equivalent of the setBounds method for the Bing javascript API, or is there another way to handle this?
The way to do this in Bing is:
1) Use the LocationRect.fromLocations function (http://msdn.microsoft.com/en-us/library/gg427621.aspx) to create a bounding box from your pushpins locations
2) pass the LocationRect created in one to the map objects setViewFunction as part of the ViewOptions parameter http://msdn.microsoft.com/en-us/library/gg427628.aspx
I have a store locator that displays stores as markers on the map and lists them in a sidebar. There are ~600 stores and they are all loaded at once on the page load via AJAX. So I have access to all them in an array at all times. Now, the functionality I want is that when the user moves/zooms around in the viewport, I get the bounds of the current area being displayed and filter the results in the sidebar (the array of locations, each location has a lat and long) based on whether or not they would be in that area being displayed. Then I would draw the markers of the relevant locations. Basically, whatever locations would be viewable in the viewport would also be listed in the sidebar, staying in sync.
Could someone point me in the right direction to implement this? Does this even sound like an efficient way of handling this functionality?
You need to write a handler for bounds_changed event (more documentation here)
google.maps.event.addListener(map, 'bounds_changed', function(){
// your logic here - map.getBounds() will give you the updated bounds
});
As for efficiency, loading everything at once is probably not the most scalable approach. What if you have 6000 stores next year or you add additional data for every store? A better approach is to pass the bounds back to the server using an AJAX call and only return stores that fall into the area.
You can attach moves/zooms event to the map and basically do a bound check to hide/show markers within the viewing bound. You can achieve this using LatLngBounds(sw?:LatLng, ne?:LatLng) and check the markers LatLng against the map's current bounds using getBounds();. Furthermore within LatLngBounds there's a method to check to see if the LatLtn is within Bounds contains(latLng:LatLng). So you would loop through your markers' LatLng and check against it.
Google Map API LatLngBounds
and
Google Map API Map
As far as the sidebar goes, if you have markers saved then you can just remove or hide the associated locations on the sidebar.