How to close infobox on zoom out - google-maps

I have a map with some markers and markerclusters and it's working fine. I added InfoBoxes to them and they work but the problem is, when I zoom out and an InfoBox is open, the marker will disappear (and get aded to the markercluster) and the box will stay there, open with no marker below.
I could work with the simple solution of having all infoboxes close on zoom change but I can't even achieve that. The problem I have is that inside my listener I can't access my markers for some reason. Here is my code:
var infoList = [];
function initialize() {
var mapOptions = {
...
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
var imageUrl = 'pin.png';
var markers = [];
var markerImage = new google.maps.MarkerImage(imageUrl, new google.maps.Size(51, 71));
for (var i = 0; i < data.photos.length; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude, dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage,
title: dataPhoto.photo_title
});
boxText = document.createElement("div"),
infoboxOptions = {
alignBottom:true,
content: boxText,
disableAutoPan: false,
maxWidth: 0,
pixelOffset: new google.maps.Size(-60, -70),
zIndex: null,
boxStyle: {
width: "280px"
},
closeBoxMargin: "12px 4px 2px 2px",
closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
infoBoxClearance: new google.maps.Size(1, 1),
isHidden: false,
pane: "floatPane",
enableEventPropagation: false
};
markers.push(marker);
markers[i].infobox = new InfoBox(infoboxOptions);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
markers[i].infobox.open(map, this);
map.panTo(latLng);
}
})(marker, i));
}
var markerCluster = new MarkerClusterer(map, markers);
google.maps.event.addListener(map, 'zoom_changed', function(markers){
/*Here markers is undefined*/
if (! markers.length) { return; }
for (i in markers) {
markers[i].infoBox.close();
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);

You are creating a new "markers" variable inside the zoom_changed listener. Remove "markers" from the arguments list:
google.maps.event.addListener(map, 'zoom_changed', function(){
if (! markers.length) { return; }
for (i in markers) {
markers[i].infobox.close();
}
});
Your code is not consistent, the property of marker that you are creating is:
markers[i].infobox = new InfoBox(infoboxOptions);
I changed the above (should have been obvious to you in the debugger).

As you mentioned, if you want to close all info window in you map at zoom out or zoom in then you can use this code. It will Help you.
google.maps.event.addListener(map, 'zoom_changed', function() {
infoWindow.close();
});

Related

Creating Geotagged Marker Alongside a Multiple Markers in Google Maps

I've been stuck on this issue for a while now and could really use some help. In a Google Map, I have a list of markers which are being treated as a markerArray, with their own custom icons. But along with displaying those markers, I would like for it to create a marker which is placed at the users geotagged location. I have tried merging the suggestions I've come across here on stack overflow, and have successfully gotten the users browser to center the map based off of geolocation, but whenever I try to add a marker outside of the standard var=locations, all of the markers disappear. I am providing my working code, which simply lacks the feature to add the "current location" marker. If anyone has any input, I'd be thrilled.
var map = null;
var markerArray = [];
function initialize() {
var myOptions = {
zoom: 13,
center: new google.maps.LatLng(40.746613, -73.990109),
mapTypeControl: false,
navigationControl: false,
streetViewControl: false,
zoomControl: false,
styles: [{featureType:"landscape",stylers:[{saturation:-100},{lightness:65},{visibility:"on"}]},{featureType:"poi",stylers:[{saturation:-100},{lightness:51},{visibility:"simplified"}]},{featureType:"road.highway",stylers:[{saturation:-100},{visibility:"simplified"}]},{featureType:"road.arterial",stylers:[{saturation:-100},{lightness:30},{visibility:"on"}]},{featureType:"road.local",stylers:[{saturation:-100},{lightness:40},{visibility:"on"}]},{featureType:"transit",stylers:[{saturation:-100},{visibility:"simplified"}]},{featureType:"administrative.province",stylers:[{visibility:"off"}]/**/},{featureType:"administrative.locality",stylers:[{visibility:"off"}]},{featureType:"administrative.neighborhood",stylers:[{visibility:"on"}]/**/},{featureType:"water",elementType:"labels",stylers:[{visibility:"on"},{lightness:-25},{saturation:-100}]},{featureType:"water",elementType:"geometry",stylers:[{hue:"#ffff00"},{lightness:-25},{saturation:-97}]}]
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
});
}
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
var locations = [
['90 West Apartment', 40.709943, -74.014430, 7, 'images/pin2.png'],
['Caffe Vita', 40.719652, -73.988411, 6, 'images/pin1.png'],
['Croxleys Ale House', 40.722480, -73.983386, 5, 'images/pin1.png'],
['Grays Papaya', 40.778291, -73.981829, 4, 'images/pin2.png'],
['The Back Room', 40.718723, -73.986913, 3, 'images/pin1.png'],
['MUD Coffee', 40.729912, -73.990678, 2, 'images/pin1.png'],
['Nurse Bettie', 40.718820, -73.986863, 1, 'pin2.png']];
for (var i = 0; i < locations.length; i++) {
createMarker(new google.maps.LatLng(locations[i][1], locations[i][2]),locations[i][0], locations[i][3], locations[i][4]);
}
mc.addMarkers(markerArray, true);
}
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50)
});
function createMarker(latlng, myTitle, myNum, myIcon) {
var contentString = myTitle;
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: myIcon,
zIndex: Math.round(latlng.lat() * -100000) << 5,
title: myTitle
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
markerArray.push(marker);
}
window.onload = initialize;
Let's try this.
Put this in your initialize(): navigator.geolocation.getCurrentPosition(showPosition);
Then define showPosition:
var showPosition = function (position) {
var userLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
// Do whatever you want with userLatLng.
var marker = new google.maps.Marker({
position: userLatLng,
title: 'Your Location',
map: map
});
}

Infobox doesn't show up in Google Maps

I'm trying to display data on a marker on Google Maps using Infoboxes from my database (using API v3). The fact is with Infowindows it worked perfectly but I want to style them and that's the reason I've switched to Infobox. But they don't show up as I expected like Infowindows.
ViewMap.php
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
<script type="text/javascript">
var infowindow;
var map;
var infobox;
function initialize() {
var myLatlng = new google.maps.LatLng(6.796396,79.877823);
var myOptions = {
zoom: 13,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
var transitLayer = new google.maps.TransitLayer();
transitLayer.setMap(map);
downloadUrl("generateXml.php", function(data) {
data = xmlParse(data);
var markers = data.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
bounds.extend(latlng);
var marker = createMarker(markers[i].getAttribute("nom"),markers[i].getAttribute("descripcio"), latlng);
}
map.fitBounds(bounds);
});
}
function createMarker(nom,descripcio,latlng) {
var marker = new google.maps.Marker({
title:nom,
position: latlng,
map: map
});
infobox = new InfoBox({
content: descripcio,
disableAutoPan: false,
maxWidth: 150,
pixelOffset: new google.maps.Size(-140, 0),
zIndex: null,
boxStyle: {
background: "url('http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/examples/tipbox.gif') no-repeat",
opacity: 0.75,
width: "280px"
},
closeBoxMargin: "12px 4px 2px 2px",
closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
infoBoxClearance: new google.maps.Size(1, 1)
});
google.maps.event.addListener(marker, 'click', function() {
infobox.open(map, marker);
map.panTo(latlng);
});
return marker;
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
</script>
See this example page from google. I've used this as a template and it works great. https://developers.google.com/maps/articles/phpsqlajax_v3
InfoBox requires the maps-API, you must load the maps-API before infobox.js
Additionally:
You are using the same InfoBox for each marker(stored in the global infobox-variable, this variable will be overwritten on each call of createMarker, so the last marker will define the InfoBox used for each marker).
The descripcio-attribute of the last created marker is empty, that's why the infoboxes don't have any content.
Solution: add the var-keyword to make the infobox private:
var infobox = new InfoBox({/*options*/})

Markerclusterer and infowindow v3 is not working properly

I have used the sample code from google for markerclusterer. I added a code to display the coordinate of the marker in an infowindow for the markerclusterer v3 but the problem is it only loads the last marker latlang into the window: Can anyone help to resolve this issue.
function initialize() {
var center = new google.maps.LatLng(37.4419, -122.1419);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
var markers = [];
for (var i = 0; i < 100; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude,
dataPhoto.longitude);
var info = dataPhoto.photo_id;
var marker = new google.maps.Marker({
position: latLng
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setPosition(latLng);
infowindow.setContent(latLng.toString());
infowindow.open(map,marker);
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
}
google.maps.event.addDomListener(window, 'load', initialize);
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
</script>`
Here I found the answer using the hint #geocodezip provided. The event addListener should be changed as follows:
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(marker.position.toString());
infowindow.open(map, marker);
}
})(marker, i));

Implementing MarkerClusterer to Google Maps API

I know this has been covered a lot before and its a simple tweak to make it work but that's making it all the more frustrating.
I'm new to Google Maps API V3 and Javascript as a whole. I've managed to make a map with markers on but I'm wanting to implement the marker clusterer feature.
My code is as follows:
<script type="text/javascript">
var markers = [
['Wathegar', 58.443420, -3.247061, '/Projects/Wathegar/', '/images/MapsIcons/operational.png'],
['Wathegar 2', 58.436726, -3.216505, '/Projects/Wathegar_2/', '/images/MapsIcons/consented.png'],
['Sibmister', 58.570869, -3.429623, '/Projects/Sibmister/', '/images/MapsIcons/planning.png'],
['Humbleburn', 54.851982, -1.651425, '/Projects/Humbleburn/', '/images/MapsIcons/planning.png'],
['Achlachan', 58.449348, -3.452797, '/Projects/Achlachan/', '/images/MapsIcons/pre-planning.png'],
['Bonwick', 53.955025, -0.227451, '/Projects/Bonwick/', '/images/MapsIcons/pre-planning.png'],
['Garton', 54.033081, -0.494127, '/Projects/Garton/', '/images/MapsIcons/pre-planning.png'],
['Hill of Lybster', 58.603081, -3.679004, '/Projects/Hill-of-Lybster/', '/images/MapsIcons/planning.png'],
['Moota', 54.710442, -3.331947, '/Projects/Moota/', '/images/MapsIcons/pre-planning.png'],
['Sherburn Stone', 54.770432, -1.4593797, '/Projects/Sherburn-Stone/', '/images/MapsIcons/pre-planning.png'],
['Spring Brook', 53.498360, -1.624646, '/Projects/Spring_Brook/', '/images/MapsIcons/pre-planning.png'],
['Sunnyside', 55.387691, -3.949585, '/Projects/Sunnyside/', '/images/MapsIcons/pre-planning.png'],
['Thacksons Well', 52.955578, -0.759824, '/Projects/Thacksons_Well/', '/images/MapsIcons/pre-planning.png'],
];
function initializeMaps() {
var latlng = new google.maps.LatLng( 56.2, -2,5);
var myOptions = {
zoom: 6,
center:latlng,
mapTypeId: google.maps.MapTypeId.HYBRID,
mapTypeControl: false,
panControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
streetViewControl: false,
};
var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
var infowindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
map: map,
url:markers[i][3],
icon:markers[i][4]
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = this.url;
});
}
}
</script>
I've tried rebuilding it in the format used in this example along with a few other blogs but I don't have a good enough understanding of JS to know what I need to do.
Any help would be greatly appreciated.
Thanks!
The format of the JSON is OK, it doesn't have any effect to the MarkerClusterer.
What you are missing is to create a instance of the MarkerClusterer and to add the markers to this instance:
var mc = new MarkerClusterer(map),//MarkerClusterer-instance
marker, i;
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
map: map,
url:markers[i][3],
icon:markers[i][4]
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = this.url;
});
mc.addMarker(marker);//add the marker to the MarkerClusterer
}
Please note: the linked page uses the MarkerClusterer for Maps-API-V2, for V3 use this updated Version:
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer_compiled.js
You can also push all markers at single go to MarkerClusterer
var marker, i;
var markersArray = [];
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
map: map,
url:markers[i][3],
icon:markers[i][4]
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = this.url;
});
markersArray.push(marker);
}
var mc = new MarkerClusterer(map,markersArray),//MarkerClusterer-instance which add all markers to the MarkerClusterer

GoogleMap Markers are Not Clickable on the Mobile Devices

GoogleMap Markers are Not Clickable on the Mobile Devices (Touch Screens).
But, ok on any PC, so I can't figure out what is the point.
Here is my code:
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(60.037760, -44.100494),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var locations = [
['4lvin', 60.074433, -44.011917],
['5irius', 60.037760, -44.100494]
];
for (var i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent('<h2>'+locations[i][0]+'</h2>\n<a>Read more..</a>');
infowindow.open(map, this);
}
})(marker, i));
}
But then, when i use the following codes (the formal way of google for "google.maps.event.addListener"), Markers are showing only the same InfoWindows.
var infowindow = new google.maps.InfoWindow({content: locations[i][0]});
new google.maps.event.addListener( marker, 'click', function() {
infowindow.open(map,this);
});
The problem is because you're doing a loop, you need to use a closure, otherwise all markers will just get the content you want to associate with the last marker. Your first bit of code is doing this correctly. Suggest you change to do the same again:
var infowindow = new google.maps.InfoWindow({content: locations[i][0]});
google.maps.event.addListener( marker, 'click', function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map,this);
}
})(marker, i));
I found the following solution :
1. create marker with option
"optimized: false" : ex => new google.maps.Marker({..., optimized: false, ...});
adding another event listener
google.maps.event.addDomListener(marker, "click", function() {...});
From google forum