如果用户缩小并且标记被吸收到 MarkerClusterer 集群中,则关闭标记上的 InfoWindow

Close InfoWindow on markers if user zooms out and marker is absorbed into MarkerClusterer cluster

我正在将 markerclustererplus 与 Google 地图一起使用。我有多个标记,并且已将其设置为一次只显示一个 InfoWindow。如果用户单击标记,则会出现一个信息窗口。如果用户缩小并且标记被吸收到一个簇中,信息窗口就会消失。这可以。如果用户立即放大,并且标记从群集中分离并变得可见,则信息窗口再次出现。我希望这样,如果用户缩小并且标记被吸收到一个簇中,那么 InfoWindow 实际上被关闭/删除,并且调用特定的用户定义函数。

我尝试了很多方法,包括 中的建议。信息窗口不会关闭。 link里面的答案比较老,所以我想知道目前是否有替代方案。

编辑:对于之前不完整的代码,我们深表歉意。我正在使用 MarkerClustererPlus v1.2.7.

这里是JSfiddle.

<!DOCTYPE html>
<html>
<head>
  <title>Google Maps Marker Example</title>

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBchuqg8C9g8o_o9I5vqxSiiHxdOFBmpHU" async defer></script>
<script src="https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js"></script>
<script type="text/javascript" src="mark.js"></script>

  <style>
    #map {
      width: 500px;
      height: 500px;
      border: thin solid black;
    }
  </style>
</head>
<body onload="loadMap();">
  <h1>Google Maps Marker Example</h1>
  <div id="map"></div>
</body>
</html>


var map;

function loadMap() {

    map = new google.maps.Map(document.getElementById('map'), {
        center: {
            lat: -41.75,
            lng: 172.75
        },
        zoom: 4
    });
    
    addMarkers();
}
var WeatherStations = [{
        "stn": 719460,
        "wban": 99999,
        "StationName": "FORT SIMPSON",
        "FIPS": "CA",
        "Latitude": 61.759998322,
        "Longitude": -121.2369995,
        "Elevation_m": 169,
        "NOAAReadings": 14952
    }, {
        "stn": 935970,
        "wban": 99999,
        "StationName": "CAPE CAMPBELL AWS",
        "FIPS": "NZ",
        "Latitude": -41.71699905,
        "Longitude": 174.26699829,
        "Elevation_m": 32,
        "NOAAReadings": 12174
    },
    {
        "stn": 934360,
        "wban": 99999,
        "StationName": "WELLINGTON INTL",
        "FIPS": "NZ",
        "Latitude": -41.32699966,
        "Longitude": 174.80499268,
        "Elevation_m": 12,
        "NOAAReadings": 9914
    }, {
        "stn": 937090,
        "wban": 99999,
        "StationName": "HAAST AWS",
        "FIPS": "NZ",
        "Latitude": -43.86700058,
        "Longitude": 169,
        "Elevation_m": 5,
        "NOAAReadings": 14371
    },
    {
        "stn": 935270,
        "wban": 99999,
        "StationName": "FAREWELL SPIT AWS",
        "FIPS": "NZ",
        "Latitude": -40.54999924,
        "Longitude": 173,
        "Elevation_m": 3,
        "NOAAReadings": 11575
    }, {
        "stn": 935460,
        "wban": 99999,
        "StationName": "NELSON AERODROME AWS",
        "FIPS": "NZ",
        "Latitude": -41.29999924,
        "Longitude": 173.19999695,
        "Elevation_m": 6,
        "NOAAReadings": 10557
    },
    {
        "stn": 937800,
        "wban": 99999,
        "StationName": "CHRISTCHURCH INTL",
        "FIPS": "NZ",
        "Latitude": -43.48899841,
        "Longitude": 172.53199768,
        "Elevation_m": 38,
        "NOAAReadings": 14933
    }, {
        "stn": 938050,
        "wban": 99999,
        "StationName": "PUYSEGUR POINT AWS",
        "FIPS": "NZ",
        "Latitude": -46.15000153,
        "Longitude": 166.6000061,
        "Elevation_m": 44,
        "NOAAReadings": 10493
    },
    {
        "stn": 939940,
        "wban": 99999,
        "StationName": "RAOUL ISLAND AWS",
        "FIPS": "NZ",
        "Latitude": -29.25,
        "Longitude": -177.9329987,
        "Elevation_m": 50,
        "NOAAReadings": 11001
    }
];

var styles = [
    [{
        url: "https://i.imgur.com/4dzjY47.png",
        height: 47,
        width: 48,
        anchorText: [14, 0],
        textColor: '#fff',
        textSize: 11
    }, {
        url: 'https://i.imgur.com/My5Cgpd.png',
        height: 47,
        width: 48,
        anchorText: [14, 0],
        textColor: '#fff',
        textSize: 11
    }, {
        url: 'https://i.imgur.com/t7SvOax.png',
        height: 47,
        width: 48,
        anchorText: [14, 0],
        textColor: '#fff',
        textSize: 11
    }]
];

var prev_infowindow = false; // to close previously-opened infowindows
var dataSourceType = 0; // 0 = grid; 1 = weatherstation
var gStn;
var gWban;
var gMarkerLat;
var gMarkerLng;
var gMarkerName;
var iw;
var iwClosed = false;
var curMark;
var infowindow;

function addMarkers() 
{
    infowindow = new google.maps.InfoWindow();

    var markers = [];

    for (var i = 0; i < WeatherStations.length; i++) {
        var latLng = new google.maps.LatLng(WeatherStations[i].Latitude, WeatherStations[i].Longitude)

        var marker = new google.maps.Marker({
            position: latLng,
            map: map,
            visible: true,
            zIndex: 10,

        });

        var content = "<div id='" + WeatherStations[i].stn + " '> <div class='scrollfix'><b>" + WeatherStations[i].StationName + "</b>";

        google.maps.event.addListener(marker, 'click', (function(marker, content, infowindow) {
            return function() {
                curMark = this;
                // Close already-opened InfoWindow
                if (prev_infowindow) {
                    prev_infowindow.close();
                }

                prev_infowindow = infowindow;

                infowindow.setContent(content);
                infowindow.open(map, marker);
            };
        })(marker, content, infowindow));


        google.maps.event.addListener(marker, 'map_changed', function() {

            var clusters = markerClusterer.getClusters(); // use the get clusters method which returns an array of objects

            for (let i = 0, l = clusters.length; i < l; i++) {
                const markers = clusters[i].getMarkers();
                for (const m of markers) {
                    if (m === curMark && markers.length > 1) {


                        try {
                            if (infowindow !== null) {

                                infowindow.close();
                                infowindow = null;
                            }
                            if (prev_infowindow) {
                                prev_infowindow.close();
                            }

                        } catch (ee) {}
                    }
                }
            }
        });

        markers.push(marker);
    }

    var zoom = null;
    var size = null;
    var style = 0;

    markerClusterer = new MarkerClusterer(map, markers, {
        maxZoom: zoom,
        gridSize: size,
        styles: styles[style]
    });
}

function clearClusters() {
    markerClusterer.clearMarkers();
}

当您使用语法 infowindow.open(map, marker); 打开 InfoWindow 时,它似乎使用与 marker 关联的 map 到 hide/show infowindow。将该代码更改为:

infowindow.setContent(content);
infowindow.setOptions({
  pixelOffset: new google.maps.Size(0, -42)
})
infowindow.setPosition(marker.getPosition())
infowindow.open(map);

删除该依赖项。

proof of concept fiddle

代码片段:

var map;

function loadMap() {

  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: -41.75,
      lng: 172.75
    },
    zoom: 4
  });

  addMarkers();
}
var WeatherStations = [{
    "stn": 719460,
    "wban": 99999,
    "StationName": "FORT SIMPSON",
    "FIPS": "CA",
    "Latitude": 61.759998322,
    "Longitude": -121.2369995,
    "Elevation_m": 169,
    "NOAAReadings": 14952
  }, {
    "stn": 935970,
    "wban": 99999,
    "StationName": "CAPE CAMPBELL AWS",
    "FIPS": "NZ",
    "Latitude": -41.71699905,
    "Longitude": 174.26699829,
    "Elevation_m": 32,
    "NOAAReadings": 12174
  },
  {
    "stn": 934360,
    "wban": 99999,
    "StationName": "WELLINGTON INTL",
    "FIPS": "NZ",
    "Latitude": -41.32699966,
    "Longitude": 174.80499268,
    "Elevation_m": 12,
    "NOAAReadings": 9914
  }, {
    "stn": 937090,
    "wban": 99999,
    "StationName": "HAAST AWS",
    "FIPS": "NZ",
    "Latitude": -43.86700058,
    "Longitude": 169,
    "Elevation_m": 5,
    "NOAAReadings": 14371
  },
  {
    "stn": 935270,
    "wban": 99999,
    "StationName": "FAREWELL SPIT AWS",
    "FIPS": "NZ",
    "Latitude": -40.54999924,
    "Longitude": 173,
    "Elevation_m": 3,
    "NOAAReadings": 11575
  }, {
    "stn": 935460,
    "wban": 99999,
    "StationName": "NELSON AERODROME AWS",
    "FIPS": "NZ",
    "Latitude": -41.29999924,
    "Longitude": 173.19999695,
    "Elevation_m": 6,
    "NOAAReadings": 10557
  },
  {
    "stn": 937800,
    "wban": 99999,
    "StationName": "CHRISTCHURCH INTL",
    "FIPS": "NZ",
    "Latitude": -43.48899841,
    "Longitude": 172.53199768,
    "Elevation_m": 38,
    "NOAAReadings": 14933
  }, {
    "stn": 938050,
    "wban": 99999,
    "StationName": "PUYSEGUR POINT AWS",
    "FIPS": "NZ",
    "Latitude": -46.15000153,
    "Longitude": 166.6000061,
    "Elevation_m": 44,
    "NOAAReadings": 10493
  },
  {
    "stn": 939940,
    "wban": 99999,
    "StationName": "RAOUL ISLAND AWS",
    "FIPS": "NZ",
    "Latitude": -29.25,
    "Longitude": -177.9329987,
    "Elevation_m": 50,
    "NOAAReadings": 11001
  }
];

var styles = [
  [{
    url: "https://i.imgur.com/4dzjY47.png",
    height: 47,
    width: 48,
    anchorText: [14, 0],
    textColor: '#fff',
    textSize: 11
  }, {
    url: 'https://i.imgur.com/My5Cgpd.png',
    height: 47,
    width: 48,
    anchorText: [14, 0],
    textColor: '#fff',
    textSize: 11
  }, {
    url: 'https://i.imgur.com/t7SvOax.png',
    height: 47,
    width: 48,
    anchorText: [14, 0],
    textColor: '#fff',
    textSize: 11
  }]
];

var prev_infowindow = false; // to close previously-opened infowindows
var dataSourceType = 0; // 0 = grid; 1 = weatherstation
var gStn;
var gWban;
var gMarkerLat;
var gMarkerLng;
var gMarkerName;
var iw;
var iwClosed = false;
var curMark;
var infowindow;

function addMarkers() {
  infowindow = new google.maps.InfoWindow();

  var markers = [];

  for (var i = 0; i < WeatherStations.length; i++) {
    var latLng = new google.maps.LatLng(WeatherStations[i].Latitude, WeatherStations[i].Longitude)

    var marker = new google.maps.Marker({
      position: latLng,
      map: map,
      visible: true,
      zIndex: 10,

    });

    var content = "<div id='" + WeatherStations[i].stn + " '> <div class='scrollfix'><b>" + WeatherStations[i].StationName + "</b>";

    google.maps.event.addListener(marker, 'click', (function(marker, content, infowindow) {
      return function() {
        curMark = this;
        // Close already-opened InfoWindow
        if (prev_infowindow) {
          prev_infowindow.close();
        }

        prev_infowindow = infowindow;

        infowindow.setContent(content);
        infowindow.setOptions({
          pixelOffset: new google.maps.Size(0, -42)
        })
        infowindow.setPosition(marker.getPosition())
        infowindow.open(map, /* marker */ );
      };
    })(marker, content, infowindow));


    google.maps.event.addListener(marker, 'map_changed', function() {

      var clusters = markerClusterer.getClusters(); // use the get clusters method which returns an array of objects

      for (let i = 0, l = clusters.length; i < l; i++) {
        const markers = clusters[i].getMarkers();
        for (const m of markers) {
          if (m === curMark && markers.length > 1) {


            try {
              if (infowindow !== null) {

                infowindow.close();
                infowindow = null;
              }
              if (prev_infowindow) {
                prev_infowindow.close();
              }

            } catch (ee) {}
          }
        }
      }
    });

    markers.push(marker);
  }

  var zoom = null;
  var size = null;
  var style = 0;

  markerClusterer = new MarkerClusterer(map, markers, {
    maxZoom: zoom,
    gridSize: size,
    styles: styles[style]
  });
}

function clearClusters() {
  markerClusterer.clearMarkers();
}
<!DOCTYPE html>
<html>
<head>
  <title>Google Maps Marker Example</title>

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk" async defer></script>
        <script src="https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js"></script>
   <script type="text/javascript" src="mark.js"></script>
  <script>
  
    
  </script>
  <style>
    #map {
      width: 500px;
      height: 500px;
      border: thin solid black;
    }
  </style>
</head>
<body onload="loadMap();">
  <h1>Google Maps Marker Example</h1>
  <div id="map"></div>
</body>
</html>