javascript 标记群集信息窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7642728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 00:47:06  来源:igfitidea点击:

markerclusterer info windows

javascriptgoogle-maps-api-3google-maps-markersinfowindowmarkerclusterer

提问by thindery

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.

让我说我对谷歌地图和 javascript 还是很陌生。我一直在将谷歌商店定位器教程与其他一些东西混合在一起。到目前为止,我正在使用标记群集器 plus(链接),与用于 google maps api v3 的标记群集器基本相同,但具有一些附加功能,例如鼠标悬停等。当您将鼠标悬停在集群上时,我试图让信息窗口出现。

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("&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>

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?

我以为我正确地做了信息窗口,但它没有出现。我知道鼠标悬停是有效的,因为在我测试时注释掉的警报有效。任何想法我做错了什么?

回答by Raphael Isidro

infoWindow.Open has two overloads

infoWindow.Open 有两个重载

 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

谷歌地图 api v3 + 标记集群中的 infoBubble

回答by duncan

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

你有,infowindow.open(map,marker);但我没有看到你在哪里创建标记(除了 createMarkers 函数中的局部变量,此时你无法真正访问)。不应该是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 positionproperty (i.e. use the same lat/lng as the marker has). Then you can just call infowindow.open(map);

另一个建议。第二个参数是信息窗口被锚定的位置。但是,您不需要它。创建信息窗口时,您可以设置位置属性(即使用与标记相同的纬度/经度)。然后你可以打电话infowindow.open(map);

回答by Agey

Raphael Isidro's solutiondidn't work for me. Oddly enough, the marker text was empty and it was being positioned at grid (0,0) of my screen.

Raphael Isidro 的解决方案对我不起作用。奇怪的是,标记文本是空的,它被定位在我屏幕的网格 (0,0) 处。

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/

这里的工作示例:参见http://krisarnold.com/2010/10/15/adding-info-windows-to-map-clusters-with-google-maps-api-v3/

回答by Елин Й.

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.

下面是我如何使用 Google Maps API v3 和 Marker Clusterer 解决这个问题。我还为 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);
});