markerclusterer info windows
Let me say I am still fairly new to google maps and javascript. i've been mixing together the google store locator tutorial with some other stuff. So far, I am using marker clusterer plus (link), basically the same as marker clusterer for google maps api v3 but with some added functionality like mouse overs and stuff like that. I'm trying to get an info window to come up when you mouse over a cluster.
working demo here. here is my full index code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Google Maps AJAX + mySQL/PHP Example</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
<script src="markerclusterer.js" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var map;
var markers = [];
var infoWindow;
var locationSelect;
var markerCluster = null;
var m;
var p = [];
var contentString;
function load() {
map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(40, -100),
zoom: 4,
mapTypeId: 'roadmap',
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
});
infoWindow = new google.maps.InfoWindow();
locationSelect = document.getElementById("locationSelect");
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
if (markerNum != "none"){
google.maps.event.trigger(markers[markerNum], 'click');
}
};
}
function searchLocations() {
var address = document.getElementById("addressInput").value;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) 开发者_开发百科{
searchLocationsNear(results[0].geometry.location);
} else {
alert(address + ' not found');
}
});
}
function clearLocations() {
infoWindow.close();
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers.length = 0;
locationSelect.innerHTML = "";
var option = document.createElement("option");
option.value = "none";
option.innerHTML = "See all results:";
locationSelect.appendChild(option);
}
function searchLocationsNear(center) {
clearLocations();
var radius = document.getElementById('radiusSelect').value;
var searchUrl = 'genxml.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius;
downloadUrl(searchUrl, function(data) {
var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerNodes.length; i++) {
var name = markerNodes[i].getAttribute("name");
var address = markerNodes[i].getAttribute("address");
var distance = parseFloat(markerNodes[i].getAttribute("distance"));
var foodID = markerNodes[i].getAttribute("foodID");
var restaurantName = markerNodes[i].getAttribute("restaurantName");
var latlng = new google.maps.LatLng(
parseFloat(markerNodes[i].getAttribute("lat")),
parseFloat(markerNodes[i].getAttribute("lng")));
createOption(name, distance, i);
createMarker(latlng, name, address, distance, foodID, restaurantName);
bounds.extend(latlng);
}
map.fitBounds(bounds);
locationSelect.style.visibility = "visible";
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
google.maps.event.trigger(markers[markerNum], 'click');
};
var clusterOptions = { zoomOnClick: false }
var markerCluster = new MarkerClusterer(map, markers, clusterOptions);
var contentString = 'This is an example';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(markerCluster, "mouseover", function (c) {
infowindow.open(map,marker);
//alert(contentString);
//log("mouseover: ");
//log("—Center of cluster: " + c.getCenter());
//log("—Number of managed markers in cluster: " + c.getSize());
});
// google.maps.event.addListener(markerCluster, "mouseout", function (c) {
//log("mouseout: ");
// log("—Center of cluster: " + c.getCenter());
// log("—Number of managed markers in cluster: " + c.getSize());
// });
});
}
function createMarker(latlng, name, address, distance, foodID, restaurantName) {
var html = "<b>" + name + "</b> <br/>" + address + "<br/>" + distance + "<br/>" + foodID + ": the food id" + "<br/>" + restaurantName;
var marker = new google.maps.Marker({
map: map,
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
markers.push(marker);
}
function createOption(name, distance, num) {
var option = document.createElement("option");
option.value = num;
option.innerHTML = name + "(" + distance.toFixed(1) + ")";
locationSelect.appendChild(option);
}
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.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser).parseFromString(str, 'text/xml');
}
}
function doNothing() {}
//]]>
function log(h) {
document.getElementById("log").innerHTML += h + "<br />";
}
</script>
</head>
<body style="margin:0px; padding:0px;" onLoad="load()">
<div>
<input type="text" id="addressInput" size="10"/>
<select id="radiusSelect">
<option value="25" selected>25mi</option>
<option value="100">100mi</option>
<option value="200">200mi</option>
</select>
<input type="button" onClick="searchLocations()" value="Search"/>
</div>
<div><select id="locationSelect" style="width:100%;visibility:hidden"></select></div>
<div id="map" style="width: 100%; height: 80%"></div>
<div id="log"></div>
</body>
</html>
Basically it comes down to this part, which I may just be putting in the wrong place:
var contentString = 'This is an example';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(markerCluster, "mouseover", function (c) {
infowindow.open(map,marker);
I thought I was doing the info window correctly, but it isn't coming up. I know the mouseover works because the commented out alert works when i test it. any ideas what I am doing wrong?
infoWindow.Open has two overloads
infoWindow.Open(map, marker)
infoWindow.Open(map)
Since you wanto to add it to a cluster (not a marker) you should use the second one
You must set the position getting the center of the cluster
google.maps.event.addListener(markerCluster, "mouseover", function (mCluster) {
infowindow.content += "<div>Something<\/div>";
infowindow.setPosition(mCluster.getCenter());
infowindow.open(map);
});
I know it works because I just did it
google maps api v3 + infoBubble in markerClusterer
you've got infowindow.open(map,marker);
but I don't see where you create marker (apart from the local variable in your createMarkers function, which you can't really access at this point). Shouldn't that be infowindow.open(map,markerCluster);
Another suggestion. The second parameter is where the infowindow gets anchored to. However, you don't need it. When you create your infowindow, you can set a position property (i.e. use the same lat/lng as the marker has). Then you can just call infowindow.open(map);
Below is how I solved that with Google Maps API v3 and Marker Clusterer. I've also addes some offset for the infoWindow so that it doesn't open in the center of the cluster, but little bit above of it.
// Define map variables
var map = new google.maps.Map(document.getElementById('mymap', {
zoom: 9,
center: {lat: 50, lng: 10}
});
var infoWindow = new google.maps.InfoWindow();
var markerCluster = new MarkerClusterer(map, markers, {zoomOnClick: false});
// Add listener for clusterclick event
markerCluster.addListener('clusterclick', function(cluster) {
// Optional: Set some offset for latitude,
// so that the InfoWindow opens a bit above the cluster
var offset = 0.1 / Math.pow(2, map.getZoom());
infoWindow.setContent('<div>Some content</div>');
infoWindow.setPosition({
lat: cluster.center_.lat() * (1 + offset),
lng: cluster.center_.lng()
});
infoWindow.open(map);
});
Raphael Isidro's solution didn't work for me. Oddly enough, the marker text was empty and it was being positioned at grid (0,0) of my screen.
This worked perfectly for me:
var markerCluster = new MarkerClusterer(map, my_markers ,{zoomOnClick: false});
google.maps.event.addListener(markerCluster, 'clusterclick', function(cluster) {
var content = '';
// Convert lat/long from cluster object to a usable MVCObject
var info = new google.maps.MVCObject;
info.set('position', cluster.center_);
iw.close();
iw.setContent('<h1>Hi this is my Info Window</h1>');
iw.open(map, info);
});
Working example here: See http://krisarnold.com/2010/10/15/adding-info-windows-to-map-clusters-with-google-maps-api-v3/
精彩评论