Determining if a marker is visible in Google Maps - javascript

I am developing a Google Maps application and I've run into this problem. I need to remove all markers which are out of bounds from the map.
Is there any simple way of doing this, besides keeping an array and looking at the latlng of each marker?
I cannot use MarkerManager because I have way too many points. I don't want to use clearOverlays() because it would close any open marker.
Any help would be appreciated.

If you don't want to look at each marker individually then cluster them into some sets initially and calculate the bounds of the set.
You can then show or hide the sets depending on what is currently showing on the map (you can find the boundary of the map using GMap2.getBounds() ).
How many points are we talking about?
Update
A. About 65K.
I can see why you can't create 65K GMarkers when the page loads. That will take over 5 seconds.
I'd cluster them into groups of 200 ish and when the edge of the group gets within a 1/4 map width outside of the displayed edge then find, create markers and display the adjacent group. It it goes outside of 1/2 a map width of the outside edge then hide the group.
Other alternatives are to use a third party library such as
Cluster Marker - http://googlemapsapi.martinpearman.co.uk/articles.php?cat_id=1
Clusterer - http://www.acme.com/javascript/#Clusterer

Related

Google Maps Api Marker Cluster Activate?

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.

Centering Leaflet map with getbounds and related issues

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.

Placing markers for 6000+ locations using Google Maps (or some other web & mobile platform)

The closest example of what I'm trying to accomplish is a store locator. I have 6,000+ locations that need to be plotted onto a map of Canada.
My original plan was to use Google maps to place markers on each location, but it doesn't make sense to plot them all every time someone attempts to view the map, or various parts of the map.
How does one only put markers on the locations in view? Do I have to send the geo data of all 6000 locations to the client each time they load the map?
Is this doable with maps? (I'm sure it's got to be) Or is there a better service for this kind of thing?
Definitely do not draw all the locations at the same time if they are not all visible. Consider using MarkerManager (article here) or MarkerLight (code: http://gmaps-samples.googlecode.com/svn/trunk/manymarkers/, demo: http://gmaps-samples.googlecode.com/svn/trunk/manymarkers/randommarkers.html). If your initial map and data is such that all the markers would be visible initially, this is definitely the way to go.
You can also use the GEvent object (docs) to detect a "move" event, then check the current display coordinates, draw any that are in bounds. This is the best route if your initial map is too zoomed or small, and/or your marker set is too large to fit on the map's initial view. Your user will be moving the map around, so you can react to that movement and only draw the relevant markers. Take a look at http://econym.org.uk/gmap/gevent.htm for a list of other GEvent events (couldn't find an official list on the API), you might also want to watch "zoom" events.
The two methods can also be combined.
You can use getBounds() to determine the viewable portion of the map. I'd use this data to request from the server all locations within those bounds. Use the bounds_changed event to monitor changes to the viewport and request additional locations as necessary. You'll probably want to set either a minimum zoom level, or maximum number of results to avoid displaying too many locations than is reasonable. Eg, when the map is zoomed out to display all of Canada in a single view.

Make google maps polyline appear below street names?

I'm making a subway map. The "transit" option on the official google maps shows their polyline below street/town names, but I can't figure out how to make mine do the same. Changing the zIndex to 0 (or negative numbers) doesn't work. Anyone know how to do this? Thanks.
Google Maps has several panes where the map components are being placed. Unfortunately for you the map tiles are placed below all those panes. Z-index has no effect if something is in higher pane, it only affects the order of overlays in the same pane.
Moreover map tiles are single images where all the map data are rendered. Therefore you can't place an overlay below some of the data rendered on the map tiles.
Theoretically, there might be a way to achieve this, but it's very difficult and I'm not even sure if it would work. Using styled maps you could create a base map type and an overlay map type. And then you could try to place the polylines between those two map types. Be sure there are many drawbacks:
I haven't tried to use styled map as an overlay map type so I'm not sure it would work.
Overlay map type is placed in the lowest map pane just above the base map. But polylines that are offered by Google Maps are rendered in higher pane and you can't place them into the lowest map pane.
Therefore it would be necessary to create your own special overlay layer or overlay map type containing the polylines. That is a lot of work! And then add it to the lowest map pane below the overlay map type.
OK, that's theory. Lots of hacking and uncertain outcome. I wouldn't do it that way!

Google Maps (v3) filter by map movement

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.

Categories

Resources