I'm using a static google map, but really this problem could apply to any maps project. I want to divide a map into multiple quadrants (of say 50x50 pixels) and label the columns as A, B, C.... and the rows as 1, 2, 3...
Next I plan to do something like,
1) Find the markers which are the farthest north, east, south, and west
2) Use that info to to define the bounding boxes of each row and column box
3) Classify each marker by its row and column (Example Marker 1 = [A,2])
A few requirements,
I don't know the zoom level because I let Google set the zoom level appropriately for me and I would rather not use an algorithm that is dependent on a zoom level. I do however know the locations of all of the markers that are shown on the map.
Here is an example of a map that I would like to classify the markers for,
static map example link.
I found these which look like a good start,
Resource 1, Resource 2
But I think I'm still in need of some help getting started. Can anyone help write out some pseudo code or post a few more resources? I'm kind of in a rut at the moment.
Thanks! Much appreciated of any help!
Ok two days into this I finally got it. Thought I would share my thoughts with people who stumble upon this later.
Following the PHP code on this site and for translating lat,lng pairs to pixel coordinates, I was able to classify the individual pixel row by the x value and the column by the pixels y value.
To calculate the zoom level, I determine the maxLat, maxLng, minLat, and minLng values defined by the collection of markers. Then I calculated the bounds of the map at a given zoom level. Finally I used a brute force method of checking if the new bounds of the map determined by the zoom level would include the bounds defined by the max,min lat,lng values of the collection of markers. Starting at zoom level 21 (max zoom on google maps) I decrement the zoom level until I find a zoom level that includes all the markers.
It seems, that the zoom level that is calculated in this method matches Google's preset zoom level selected automatically if you do not provide a zoom level for a static map.
In PHP there is a nice library to do all of this here.
Related
I am creating an application that downloads images from maps using the Google Maps Static API. I would want to decide the zoom level when having markers on the map (right now the zoom is set automatically so that all markers are shown in the image). Does anyone know if this is possible?
Right now the zoom is set automatically so that all markers are shown in the image
You are halfway there. Once done, get the resulting the zoom level: map.getZoom();
However, I think your app violates Google's terms as it is forbidden to copy their content.
According to the documentation, you can use the center and zoom parameters to configure the map (they aren't required with markers):
Location Parameters
center (required if markers not present) defines the center of the map, equidistant from all edges of the map. This parameter takes a location as either a comma-separated {latitude,longitude} pair (e.g. "40.714728,-73.998672") or a string address (e.g. "city hall, new york, ny") identifying a unique location on the face of the earth. For more information, see Locations below.
zoom (required if markers not present) defines the zoom level of the map, which determines the magnification level of the map. This parameter takes a numerical value corresponding to the zoom level of the region desired. For more information, see zoom levels below.
example URL:
https://maps.googleapis.com/maps/api/staticmap?center=42,-72&zoom=5&size=400x400&markers=color:blue%7Clabel:S%7C11211%7C11206%7C11222&format=jpg
resulting image:
I am writing some code which clusters markers on a Google map. The clustering algorithm relies on knowing how many degrees latitude and longitude are currently visible to the user, as I break the map into a grid of n/map_pixels_width x n/map_pixels_height squares and need to know how many degrees of lat/lon are in each square to know which square each marker point belongs to.
Under normal circumstances where the map does not wrap this is relatively easy to calculate using getBounds() on the Google Map object and doing the calculations to figure out the latitudinal and longitudinal distances between the returned North-East and Sout-West points. Where I'm running into issues is where the map is zoomed out to the extent that it wraps the entire Earth > 1 times. For example, I can zoom out the map so that the entire Earth is "tiled" 5 times over which equates to 360 * 5 = 1800 longitudinal degrees and, but then the call to getBounds() no longer provides useful information:
m.getBounds().getNorthEast().lat()
88.31833020528785
m.getBounds().getNorthEast().lng()
180
m.getBounds().getSouthWest().lat()
-88.5485785544835
m.getBounds().getSouthWest().lng()
-180
Basically, the longitudes getBounds() reports are just the min and max for one whole globe which says nothing about how many times the Earth is repeated. Although Google Maps doesn't tile the map vertically (it just inserts gray filing space if zoomed out far enough), I have conceptually the same problem -- I need to know how many total degrees of space the vertical area would consume.
Is there a way to get the total number of visible longitudinal degrees?
So based on this answer to another question, I found a (hackish) way to solve this. Basically, the Google Maps OverlayView class has a getProjection() method returning a MapCanvasProjection object, which in turn has a getWorldWidth() method which returns the width of the world at the current zoom level in pixels. So the way to solve the problem then is to:
Add a dummy OverlayView to the map that doesn't actually present an overlay.
Get the overlay's projection.
Get the world width from the projection.
Calculate the number of visible longitudinal degrees as pixel_width_of_map_element / world_width_in_pixels * 360
It would be better if there were a way to do this without creating a dummy overlay, but this method seems to work.
I need to display around 50,000 markers on the map. But i was able to plot only 10000 points. I thought of implementing this way correct me if i'm wrong...
Instead of fetching whole data at once just fetch points that are in the viewport and depending on the zoomlevel.
ex:google maps: at one zoomlevel only states are shows if we zoom in further cities are shown
I'm stuck with the zoomlevel.. how to relate zoomlevel and viewport.Is there any algorithm or formulae that helps in getting the lat long values or it needs to be hardcoded in the database like for particular lat-lon this is the zoomlevel range so while fetching range is checked.
i'm using openlayers bbox feature to get the bounds
Thanx in advance
google.maps.Map.getBounds() will return the lat/long bounds of the viewport.
50,000 markers is a lot compared to what Google Maps can handle; you would have to be way zoomed in to have few enough markers to be under the limits. You might do better by creating custom tiles with dots instead of markers. You can see an example at
http://maps.webfoot.com/demos/election2008/
Scroll down to the third overlay to see dots; select zip codes to see LOTS of dots.
What is the most effcient approach to check if there are any markers within a viewport?
A perfect solution wouldn't require checking all the markers one-by-one if it's contained by the viewport.
The best solution that I came up with is to
on the application launch, create an array with reference to markers - sorted by 1 coordinate, i.e. latitude
get viewport's bounds with GMap2.getBounds() (as paullb suggested)
take lower latitude of viewport boundaries and look for it in the array (fastest to achieve with binary search)
check if every following marker fits within the viewport (up to marker's latitude <= viewport's upper latitude).
Use GMap2.getBounds() to find the bounding box. The use GLatLngBounds.containsLatLng() to check each marker to see if it is visible.
Alternatively you could try and use the same approach with the Marker Cluster if the value of each cluster is stored in an easily accessible way. (haven't looked myself)
I want to show limited numbers of markers(let's take 50 or so...) at all zoom level and in a manner that markers covers all entire Google map display.
So, If I am viewing whole world in map, it will show markers all over the world not to exceed a certain number, and the if I zoomed to USA it will only show previous number of markers only inside USA.
And then again if I moved to Canada , then the map should show markers of Canada only.
I am not able to
- put makers on visible region over the map on limited distances
i.e. all the visible markers maintaining somewhat some distance from each other.
You might want to look into 'clustering' or 'bunching' the points into one. It doesn't do exactly what you are describing, but it will effectively limit the number of markers you have when you are zoomed out, and 'uncluster' them once you zoom in.
There are quite a few ways (all third party - the Google API doesn't support it yet), you could have a look here at one called ClusterMarker: http://googlemapsapi.martinpearman.co.uk/articles.php?cat_id=1.
You should use a marker manager!
See http://code.google.com/p/gmaps-utility-library-dev/ and http://gmaps-utility-library.googlecode.com/svn/trunk/markermanager/