How do I auto zoom to view multiple markers using the Google Geocoding API? - google-maps-api-3

I'm using the Google Geocoding API to build a map that puts markers on whichever locations are requested. At the moment it auto-zooms to each location individually - how do I use fit Bounds to make it zoom to all the locations, i.e. if Sydney is input first, then London, how do I ask it to auto-zoom so the user can view both?
I'm very new to this so any advice welcome!
I've tried many different way to use bounds, fit Bounds, marker.length etc but none of it works or makes much sense to me.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 45.1497, lng: 100.0943},
zoom: 3
});
var geocoder = new google.maps.Geocoder()
var step1 = location.href.split("?")[1].split("=")[1]
$("#address1").val(step1);
geocodeAddress1(geocoder, map);
$(".steps").keypress(function() {
if (event.which == 13) {
geocodeAddress(geocoder, map);
}
})
};
var labelIndex = 0;
function geocodeAddress1(geocoder, resultsMap) {
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var address = $("#address1").val();
geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
label: labels[labelIndex++ % labels.length],
position: results[0].geometry.location
});
} else {
alert('Search not successful: ' + status);
}
})
};
function geocodeAddress(geocoder, resultsMap) {
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var nextstep = "#".concat(event.target.id);
debugger;
var address = $(nextstep).val();
geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
label: labels[labelIndex++ % labels.length],
position: results[0].geometry.location
});
} else {
alert('Search not successful: ' + status);
}
})
};

You need to store all the markers/loations first in an array each time you click "Geocode", then call bounds.extend() for each location searched to contain the given point and lastly call resultsMap.fitBounds() to set the viewport to contain the given bounds.
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location
});
markerCount++;
markers[markerCount] = marker;
// extend the bounds here to consider each location
bounds.extend(results[0].geometry.location);
// then call fitBounts()
resultsMap.fitBounds(bounds);
Here's a working sample in JSFiddle.
Hope it helps!

Related

Can I modify this code to detect whether a street view image is available in Google Maps API?

I have to admit, I wing it a bit with Google Maps API. A lot of copy and pasting and basic edits. This code works really well unless a street view image is not available. What is the easiest way to detect no image and hid the pano div? Or the other way round, display it if there is an image:
function googleMap() {
var geocoder = new google.maps.Geocoder();
if (geocoder) {
alert('<?php echo $phoneDirectory->Address; ?>');
geocoder.geocode({ 'address': '<?php echo $phoneDirectory->Address; ?>' }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var googleLat = results[0].geometry.location.lat();
var googleLong = results[0].geometry.location.lng();
//alert(googleLat + ", " + googleLong);
var fenway = new google.maps.LatLng(googleLat,googleLong);
var mapOptions = {
center: fenway,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById('map_canvas'), mapOptions);
var panoramaOptions = {
position: fenway,
pov: {
heading: 0,
pitch: 0
}
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById('pano'),panoramaOptions);
map.setStreetView(panorama);
// **** ADDED TO GET WORKING!!! *****
var client = new google.maps.StreetViewService();
client.getPanoramaByLocation(fenway, 50, function(result, status) {
if (status == "ZERO_RESULTS") {
// Hide street view div
$('#pano').css("display", "none");
}
});
googleMapLoaded = true;
}
else {
alert('No results found: ' + status);
}
});
}
}
Check this
If there are no nearby panoramas the result is ZERO_RESULTS

Creating multiple individual info windows alongside multiple markers in Google Maps

My project searches the eBay API (using PHP and returns simpleXML) and returns the postcodes of multiple items (5 at the moment). Then uses this information to plot markers on a Google map on my website. What I am trying to do is create multiple info windows along with these markers so I can also return information from the eBay auction and put it in the info window (link to auction, picture of item etc.) but I am having no luck! I cannot seem to get the closures right in my loop and I keep getting the last postcode in the array displayed in the info window rather than the postcode actually associated with that marker (just doing this for test purposes).
What am I doing wrong? Any information will be helpful.
This is my code at the moment:
for (var i = 0; i < msg.length; i++) {
info = msg[i];
console.log(info);
geocoder.geocode( { 'address': msg[i]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
icon: image,
position: results[0].geometry.location
})
listenMarker(marker);
markerBounds.extend(results[0].geometry.location);
map.fitBounds(markerBounds);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function listenMarker (marker){
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(info);
infoWindow.open(map, this);
});
You are need to use a function closure on the geocoder call as well (not tested), looks like you might have a problem with your listMarker function also (seems to be missing the definition of "info", if you are depending on the global value of that, that could be your problem):
function geocodeAddress(msg)
{
geocoder.geocode( { 'address': msg}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
icon: image,
position: results[0].geometry.location
})
listenMarker(marker, msg);
markerBounds.extend(results[0].geometry.location);
map.fitBounds(markerBounds);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
for (var i = 0; i < msg.length; i++) {
info = msg[i];
console.log(info);
geocodeAddress(msg[i]);
}
function listenMarker (marker, info){
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(info);
infoWindow.open(map, this);
});

On failed Geocoding map is not setting to supplied coordinates

I am initializing the Google map using following code:
function googleMapinitialize(fenceAddIn){
var fenceAdd=new google.maps.LatLng(37.2146,121.5545);
var mapProp = {
center:fenceAdd,
zoom:30,
mapTypeId:google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById("fenceMap"),mapProp);
var geocoder = new google.maps.Geocoder();
var location = fenceAddIn; //"2001 Gateway PI, San Jose, CA";
if(!geocoder) {
geocoder = new google.maps.Geocoder();
}
var geocoderRequest = {
address: location
}
var myCity = null;
var marker = null;
var infowindow = null;
geocoder.geocode(geocoderRequest, function(results, status) {
if (status =="" || status == google.maps.GeocoderStatus.ZERO_RESULTS){
alert("'" + location + "' not found!!!");
map.setCenter(fenceAdd);
} else if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
fenceAdd = new google.maps.LatLng(results[0].geometry.location.hb,results[0].geometry.location.ib);
if (!marker) {
marker = new google.maps.Marker({
map: map,
raiseOnDrag:false,
draggable:true
});
marker.setPosition(results[0].geometry.location);
google.maps.event.addListener(marker,'click',function(){
if (!infowindow) {
infowindow = new google.maps.InfoWindow({
disableAutoPan:true,
maxWidth:100
});
}
var content = '<strong>' + results[0].formatted_address + '</strong>';
infowindow.setContent(content);
infowindow.setPosition(results[0].geometry.location);
infowindow.open(map, marker);
});
}
}
myCity = new google.maps.Circle({
center:fenceAdd,
radius:125,
strokeColor:"#0000ff",
strokeOpacity:0.1,
strokeWeight:0.1,
fillColor:"#0000ff",
fillOpacity:0.20,
map:map
});
google.maps.event.addListener(map, 'click', function(){
infowindow.close();
});
google.maps.event.addListener(map, 'dblclick', function(){
window.open("<%=request.getContextPath() %>/jsp/googleMapPopup.jsp?fenceAddress="+$('#haddr').val(),'ADDRESSMAP','height=400,width=600');
});
});
}
I am sending a address which is geocoded and the position marked by a pin on the map. But in case when the geocoding fails the map is centered around china. So to overcome this I am resetting the map center to the original lat long and drawing the circle on it. When I debugged the code I saw that the coordinates are getting set properly but the map is still showing the china map.
Can some tell me how to reset the map location in this case?
Your fenceAdd coordinates default to China:
206 Provincial Road, Muping, Yantai, Shandong, China (37.21401, 121.5955285)
If you don't want the map to center there, change those coordinates.

Google Maps Pass value of dragend to variable

Ok I spent 2 days working on this time for some help :) Everything works fine with the code now I just need to make the marker draggable and update Lat and Lng values. At present the code captures lat and lng via current position as well as via entering a location on the web page. The value of _Lat and _lng are then submitted the a database. I need the user to be able to drag the marker to fine tune the location and update _lat and _lng prior to the database submit. I have made the marker draggable but I can't figure out how to add the dragend code so that it dynamically updates the value of lat and _lng prior to the database submit. I don't need to update anything on the web page just I need to update the _lat and _lng values that get posted to the database. Here is the existing code:
Thanks
var gmap;
var gmarker;
var geocoder;
function initialize() {
// Get here center of map - by default - San Francisco center
var center = new google.maps.LatLng(37.47, -122.25);
var mapOptions = {
center: center,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
geocoder = new google.maps.Geocoder()
gmap = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
// Set inner position of map to form parameters
$('input[name="_lat"]').val(37.47);
$('input[name="_lng"]').val(-122.25);
gmarker = new google.maps.Marker({
map: gmap,
position: center,
icon: '/static/internal/images/mapicon.png',
draggable: true
});
google.maps.event.addListener(gmap, 'click', function(event) {
gmarker.setPosition(event.latLng);
$('input[name="_lat"]').val(event.latLng.lat());
$('input[name="_lng"]').val(event.latLng.lng());
});
navigator.geolocation.getCurrentPosition(function(position){
var _lng = position.coords.longitude;
var _lat = position.coords.latitude;
$('input[name="_lng"]').val(_lng);
$('input[name="_lat"]').val(_lat);
var new_position = new google.maps.LatLng(_lat, _lng);
gmap.setCenter(new_position);
gmarker.setPosition(new_position);
})
}
function showAddress(address) {
if (geocoder) {
geocoder.geocode(
{'address': address},
function(results, status) {
if (status != google.maps.GeocoderStatus.OK) {
alert(address + " not found");
} else {
gmap.setCenter(results[0].geometry.location);
gmarker.setPosition(results[0].geometry.location);
$('input[name="_lat"]').val(results[0].geometry.location.lat());
$('input[name="_lng"]').val(results[0].geometry.location.lng());
}
}
);
}
}
listen to the position_changed-event of the marker:
google.maps.event.addListener(gmarker, 'position_changed', function() {
$('input[name="_lat"]').val(this.getPosition().lat());
$('input[name="_lng"]').val(this.getPosition().lng());
});
Your click event is on map it should be on marker
Change
google.maps.event.addListener(gmap, 'click', function(event) {
To
google.maps.event.addListener(gmarker, 'click', function(event) {

Google Maps API geocode function problem

Ok, I'm fooling around with Google Maps API v3 and I bumped into a problem. I don't know if its the API or just some JS error i made.
Problem:
addMarkerFromAdress() function calls on geocodeFromAdress() which returns coordinates back to addMarkerFromAdress(). But returned value is "undefined".
As a debug i added two alert outputs, one in addMarkerFromAdress() and one in geocodeFromAdress(). What troubles me is that the alert() in addMarkerFromAdress() seems to fire off before any value is returned. Why?
Source:
<script type="text/javascript">
var geocoder;
var map;
function initializeGoogleMaps() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(0, 0);
var myOptions = {
zoom: 1,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function geocodeFromAdress(address) {
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latLng = results[0].geometry.location;
alert(latLng); //Outputs coordinates, but is for some reason outputted 2nd
return latLng;
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function addMarkerFromAdress(address, title){
var latLng = geocodeFromAdress(address);
alert(latLng); //Outputs "undefined", but is for some reason outputted 1st
map.setCenter(latLng);
var marker = new google.maps.Marker({
map: map,
position: latLng
});
}
window.onload = function () {
initializeGoogleMaps();
addMarkerFromAdress('Berlin, Germany', 'Berlin');
}
</script>
See that function passed as the second argument to geocoder.geocode()? that is where you should be calling addMarkerFromAddress. Due to the asynchronous nature of the geocode request, the alert after var latLng = geocodeFromAdress(address); is firing before the response is returned with the lat long values.
Something like this should do it
<script type="text/javascript">
var geocoder;
var map;
function initializeGoogleMaps() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(0, 0);
var myOptions = {
zoom: 1,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function geocodeFromAdress(address, title) {
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latLng = results[0].geometry.location;
addMarkerFromAdress(latLng, title);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function addMarkerFromAdress(latLng, title){
map.setCenter(latLng);
var marker = new google.maps.Marker({
map: map,
position: latLng
});
}
window.onload = function () {
initializeGoogleMaps();
geocodeFromAdress('Berlin, Germany', 'Berlin');
}
</script>

Resources