Calling map.fitBounds() Multiple Times in Google Maps API v3.0 - google-maps

I've just begun using the Google Maps API (v3.0) and have had a good deal of success so far. I am loading a set of objects with Latitude & Longitude values from a database, passing them into my script, and looping over them in the script in order to add them to the map.
I am using the "bounds.extend() / map.fitBounds()" method of setting the map's zoom & bounds (see code below), which works as expected the first time around; however, if I clear out the existing markers, fetch another set of objects, and do the same thing on the same map instance, it sets the bounds incorrectly, usually resulting in a minimum zoom (an astronaut's view).
My suspicion is that my map object has some memory of the previous set of bounds that I've given it and that I need to find a way to clear these bounds before assigning my new ones, but I really can't be too sure.
Any help is greatly appreciated!
var locationList = [];
for (var i = 0; i < mapPoints.length; i++) { // mapPoints is a collection of DTOs
var mapPoint = mapPoints[i];
var location = new google.maps.LatLng(mapPoint.Latitude, mapPoint.Longitude);
locationList.push(location);
var marker = new google.maps.Marker({
map: map,
icon: '/Content/images/map/' + mapPoint.Status.Icon,
shadow: '/Content/images/map/shadow.png',
position: location
});
markers.push(marker); // markers is an Array that is managed outside this loop
}
var bounds = new google.maps.LatLngBounds();
for (var j = 0; j < locationList.length; j++)
bounds.extend(locationList[j]);
map.fitBounds(bounds);

This isn't the answer, so to speak, but a (slightly hacky) workaround that I discovered on a thread in the Google Maps Javascript API v3 group:
//map.fitBounds(bounds);
setTimeout( function() { map.fitBounds( bounds ); }, 1 );

if the above answer doesn't work for you (it didn't for me), the problem might lie in bootstrap (assuming you're using it). bootstrap modals specifically generate all sorts of wonky behaviour when i embed a map object in it.. curiously correcting itself if/when i drop an 'alert' in there.. in any case, i solved all my problems by just building my own modal (ie, not using bootstraps modals).

Related

Google Maps Drawing Iterate all shapes on overlay

I have been toying around with Google Maps Drawing tools v3. If a user creates a new polygon, I used this example to be able to track the location of the polygons:
getpaths() polygons google maps api
Code:
var polygons = [];
google.maps.event.addDomListener(drawingManager, 'polygoncomplete', function (polygon) {
polygons.push(polygon);
console.log("polygon complete");
});
google.maps.event.addDomListener(savebutton, 'click', function () {
document.getElementById("savedatapolygon").value = "";
console.log(polygons.length);
for (var i = 0; i < polygons.length; i++) {
var polygonBounds = polygons[i].getPath();
// Iterate over the polygonBounds vertices.
var PolyNum = i
console.log(PolyNum);
polygonBounds.forEach(function (xy, i) {
console.log('Coordinate: ' + PolyNum + ':' + i + '<br>' + xy.lat() + ',' + xy.lng());
});
}
});
This is fine for when a user creates a Polygon, but what if they delete the Polygon? The data is still stored in the array. I can't seem to find a method to either track which array was deleted or have it iterate through all shapes at the end when the user clicks save. Looking through the console, I can see that there might be a unique id assigned to each shape called __gm_id:, but i'm not sure if this would be the best way to track it.
The other strange thing is that when you edit a shape, those changes are somehow getting updated to the polygon array even though there is nothing in the code stating that it should.
Google examples show the way to delete an object is to use:
selectedShape.setMap(null);
I found it easier to track the the polygon end result by making the visibility false instead of deleting:
selectedShape.setOptions({ visible: false });
That way, when reading the array you can check if it is invisible:
polygons[i].getVisible()
That in the codebehind you can deal with the data however you want when saving the coordinates. You will get everything that was made, but can choose to only save the shapes that are visible.

Control Google Map zoom level with a hyperlink

How can I control the Zoom Level of my Google Map with hyperlinks? For instance I want three defined levels (Location in UK, UK in Europe, Europe in the World). Clicking on these links will display the map with a different zoom level.
I'm using Google Maps API v3
That shouldn't be too difficult to do.
When you create the map, you get a reference to the map object, e.g.
var mapOptions = {mapTypeId: google.maps.MapTypeId.TERRAIN};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
Once you have the object, you can zoom to a specific level like this:
function zoomToLevel() {
map.setZoom(8);
}
So you'd just need to set the click event of your hyperlink to run the javascript function:
Zoom to level 8
For what you're doing though, it might be better to get the map to select it's own zoom level based on the area. This function is actually zooming to show the Pyrenees, but the idea could be used for any area, as long as your points are at diagonally opposite corners:
function zoomPyrenees() {
var startPoint;
var endPoint;
var boundsPyrenees;
startPoint = new google.maps.LatLng(43.373403, -1.774107);
endPoint = new google.maps.LatLng(42.482463, 3.129875);
boundsPyrenees = new google.maps.LatLngBounds();
boundsPyrenees.extend(startPoint);
boundsPyrenees.extend(endPoint);
map.fitBounds(boundsPyrenees);
}

Calculate the initial best center AND best initial zoom depending on a list of location

Dear all. I'm pretty new in coding with location, so be nice.
I have a list of location (lat & lng), that could be really anywhere (ie : all in the same city ; one in bangladesh and one in paris...).
When initializing google map, I would like to center on the barycentre on these location.
So this is my first question : How to calculate a barycentre with location object
Then, I would also like the initial map do display all the location (markers). So this is a problem of zoom, and is my second question : How to calculate the zoom in a google map so that all the markers on the map are displayed
I hope I've been clear. Also, take note that I was meaning barycentre with all points coefed to 1.
Best regards.
To zoom to include a set of results:
var locations = new google.maps.LatLngBounds();
...
function zoomToViewports(locations) {
var bounds = new google.maps.LatLngBounds();
for (var i in locations) {
bounds.union(locations[i].geometry.viewport);
}
map.fitBounds(bounds);
}
Having done that, the barycentre is in the middle of the screen, so if you actually need it's value it's easily calculated [(max(lat)-min(lat)/2,(max(lng)-min(lng)/2]
HTH?
You are welcome to lift the JS from this page on my website, which does what you describe

Marker Manager not showing markers

I am having problems using the MarkerManager. Somehow Markers added with the MarkerManager do not show up, though i do mgr.refresh(); It works when i use basic map.addOverlay(marker); but not when using mgr.addMarker(marker);. Weird. Hope someone here can help.
Here's the relevant code:
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
bounds = new GLatLngBounds();
map.setCenter(new GLatLng(48.25, 11.00), 4);
mgr = new MarkerManager(map, mgr_options);
markers = createSpotMarkers(spots); // parsing spots, extending bounds, creating Array of GMarkers etc, pretty basic and seems not be relevant.
mgr.addMarkers(markers); // does not work
map.addOverlay(markers[0]); // works
mgr.addMarker(markers[0]); // does not work either
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds)-1);
mgr.refresh();
}
It looks like the API for MarkerManager expects 3 arguments to addMarkers, of which the 3rd seems to be optional. The second, however, doesn't. If the API doesn't help, then a blog post showing example usage might. Good luck!

Google Maps: How can I change the z-index of a Marker?

There are about 100 markers on a google map plus there is one special marker that needs to be visible. Currently, the markers around it hide it totally or partially when the map is zoomed out. I need that marker to be fully visible and I think keeping it on top of all other markers should do the trick. But I cannot find a way to modify its stacking order (z-index).
This is for Google Maps API 2.
For Google Maps API 3 use the setZIndex(zIndex:number) of the marker.
See:
http://code.google.com/apis/maps/documentation/javascript/reference.html#Marker
Use the zIndexProcess option in GMarkerOptions when you create the marker that you want on top. For example:
var pt = new GLatLng(42.2659, -83.74861);
var marker = new GMarker(pt, {zIndexProcess: function() { return 9999; }});
map.addOverlay(marker);
I believe the default is to have a z-index that is the latitude of the point of the marker, so this should be fairly safe at bringing a single marker to the front. Further, this was just a simple example; you can set the z-index of all your markers in whatever simple or complex way you want. Another example is to have two functions: one for special markers and one for the rest.
var pt1 = new GLatLng(42.2659, -83.74861);
var pt2 = new GLatLng(42.3000, -83.74000);
var marker1 = new GMarker(pt1, {zIndexProcess: specialMarker});
var marker2 = new GMarker(pt2, {zIndexProcess: normalMarker});
map.addOverlay(marker1);
map.addOverlay(marker2);
function specialMarker() {
return 9999;
}
function normalMarker() {
return Math.floor(Math.random()*1000);
}
Adding on to jhanifen's answer, if you want to get your one special marker to be on top of all the rest, set it's zIndex to google.maps.Marker.MAX_ZINDEX + 1. This will make sure that it is on top of any marker on the map.