4

讓我說我還是相當新的谷歌地圖和JavaScript。我一直在混合谷歌商店定位器教程和其他一些東西。到目前爲止,我使用標記聚合器加(link),基本上與谷歌地圖api v3的標記聚合器相同,但具有一些附加功能,如鼠標懸停等。當您將鼠標懸停在羣集上時,我試圖獲得一個信息窗口。markerclusterer信息窗口

工作演示here。這裏是我完整的索引代碼:

<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("&mdash;Center of cluster: " + c.getCenter()); 
      //log("&mdash;Number of managed markers in cluster: " + c.getSize()); 
     }); 
     // google.maps.event.addListener(markerCluster, "mouseout", function (c) { 
      //log("mouseout: "); 
     // log("&mdash;Center of cluster: " + c.getCenter()); 
     // log("&mdash;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> 

基本上它歸結到這一部分,我可能只是在錯誤的地方來放:

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); 

我以爲我是在做正確的信息窗口,但它不會出現。我知道鼠標懸停的作品,因爲當我測試它時,註釋掉的警報有效。任何想法我做錯了什麼?

回答

8

infoWindow.Open有兩個重載

infoWindow.Open(map, marker) 
infoWindow.Open(map) 

既然你wanto將其添加到集羣(未標記),你應該使用第二個

您必須設置獲得集羣的中心位置

google.maps.event.addListener(markerCluster, "mouseover", function (mCluster) {  
    infowindow.content += "<div>Something<\/div>"; 
    infowindow.setPosition(mCluster.getCenter()); 
    infowindow.open(map); 
}); 

我知道它的作品,因爲我只是做了它

google maps api v3 + infoBubble in markerClusterer

0

你有infowindow.open(map,marker);但我看不到你在哪裏創建標記(除了你的createMarkers函數中的局部變量,在這一點上你不能真正訪問)。這不應該是infowindow.open(map,markerCluster);

另一個建議。第二個參數是infowindow被錨定到的位置。但是,你不需要它。當你創建你的infowindow時,你可以設置一個的位置屬性(即使用與標記相同的經緯度)。然後,你可以叫infowindow.open(map);

+0

感謝您的建議。我嘗試過,但仍然沒有什麼區別。 – thindery

+0

第二個建議? – duncan

0

Raphael Isidro's solution對我不起作用。奇怪的是,標記文本是空的,它被放置在我的屏幕的網格(0,0)處。

這完美的工作對我來說:

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); 
}); 

工作示例這裏: 見http://krisarnold.com/2010/10/15/adding-info-windows-to-map-clusters-with-google-maps-api-v3/

0

下面是我如何解決了與谷歌地圖API v3和標記聚類器。我還爲infoWindow添加了一些偏移量,這樣它就不會在集羣的中心打開,而是在它的上方一點點。

// 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); 
});