【问题标题】:Reposition GoogleMap's center view to infoWindow's pixel position after it has loaded加载后将 GoogleMap 的中心视图重新定位到 infoWindow 的像素位置
【发布时间】:2018-02-26 12:06:06
【问题描述】:

我在一个页面上有一个谷歌地图,上面有几个标记(ajax'ed)。当我单击标记时,会打开一个信息窗口,其中包含详细信息(也是 ajax 处理的)。

我不知道如何使地图居中以使此信息窗口位于地图中间。

GoogleMap 是这样加载的:

var map = new google.maps.Map(document.getElementById('map'), {
    zoom: zoomSteps[0],
    center: new google.maps.LatLng(46.227638, 2.213749000000007),
    mapTypeId: google.maps.MapTypeId.TERRAIN,
    mapTypeControl: false,
    streetViewControl: false,
    styles: [{
        featureType: "poi",
        stylers: [{
            visibility: "off"
        }]
    }]
});

另外,InfoWindow GoogleMap 对象的生成方式如下:

var infowindow = new google.maps.InfoWindow({
    maxWidth: 400,
});

然后我执行一个 ajax 请求来获取数据以在 success: function(data) {} 中的地图上定位标记:

for (i = 0; i < data.length; i++) {
    marker = new google.maps.Marker({
        position: new google.maps.LatLng(data[i].latitude, data[i].longitude),
        map: map
    });

    // ...
}

在这个for() {} 循环中,我在每个生成的marker 上添加一个EventListener

google.maps.event.addListener(marker, 'click', (function (marker, i) {
    return function () {
        // open the info window
        infowindow.open(map, marker); 

        // get css load spinner HTML from ajax and populate a div
        var $loader = $('<div/>').addClass('loader').css('overflow', 'hidden').html(data[i].htmlLoader); 

        // inject this div html code into the infowindow
        infowindow.setContent($loader.prop('outerHTML')); 

        // (1)

        // Main function to retrieve data from the SOAP WebService :
        // it takes infoWindow html template from data[i].htmlTemplate,
        // populates it with data fetched from SOAP WebService and sends it back to here        
        MainSearchTool.prototype.loadEntityResults(data[i].ws.data, data[i].htmlTemplate, function (htmlTemplate) {

            // inject newly fetched results into the infowindow
            infowindow.setContent(htmlTemplate);

            /**
             * Here is where I would like to reposition the center
             * of the map to fit the infoWindow 
             * (2)
             */
        });

    }
})(marker, i));

(2) 我尝试(无济于事):

  1. 调用map.setCenter(LatLng)LatLngmarker.getPosition() - 在(1) 中调用时有效,但infoWindow 填充了加载微调器,而不是此时的最终模板;
  2. 将 infoWindow offset() left 和 top 转换为 new google.maps.Point() 并按照 this question 将其转换回 LatLng 对象;
  3. 使用多种技术根据特定值重新定位map

我似乎找不到任何特定的方法来根据 LatLng 对象来使地图居中,该对象将与 infoWindow 的中心相匹配。

如果您觉得有用,请随时询问任何其他信息。

谢谢。

【问题讨论】:

    标签: javascript jquery google-maps google-maps-api-3 position


    【解决方案1】:

    没关系。

    (2) 中再次调用infowindow.open(map, marker); 就可以了。

    供进一步参考。

    【讨论】:

      【解决方案2】:

      无论如何,让我本着问题的精神来回答:已知尺寸信息窗口,已知尺寸图。我在css中设置了这些值,见代码

      点击地图后,我们读取了标记的位置;将该位置转换为相应的像素;我们将像素距离标记添加到中间信息窗口;我们将该点转换为坐标,然后将地图以该点为中心。

      对于我的代码,这意味着我们必须将地图居中在标记上方(y 方向)100 像素处。您可能需要为您的值计算 tat 距离的函数(如果您不固定大小,则可能是动态的)

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
      <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
      <script>
          // @see https://stackoverflow.com/questions/25219346/how-to-convert-from-x-y-screen-coordinates-to-latlng-google-maps
          function latLng2Point(latLng, map) {
              var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
              var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
              var scale = Math.pow(2, map.getZoom());
              var worldPoint = map.getProjection().fromLatLngToPoint(latLng);
              return new google.maps.Point((worldPoint.x - bottomLeft.x) * scale, (worldPoint.y - topRight.y) * scale);
          }
      
          function point2LatLng(point, map) {
              var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
              var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
              var scale = Math.pow(2, map.getZoom());
              var worldPoint = new google.maps.Point(point.x / scale + bottomLeft.x, point.y / scale + topRight.y);
              return map.getProjection().fromPointToLatLng(worldPoint);
          }
      
          var map;
          var markers = [];
          var infowindow;
      
          function senterOnInfowindow(infowindow, marker) {
              var markerposition = marker.getPosition();
              // let's add pixels to that to the north: Y-offset + half the height of the infowindow
              var xy = latLng2Point(markerposition, map);
              xy.x += 0; // if needed, ajust x
              xy.y -= 100;
              var newCenter = point2LatLng(xy, map);
              map.setCenter(newCenter);
          }
      
          function initMap() {
              map = new google.maps.Map(document.getElementById('map'), {
                  zoom: 19,
                  center: new google.maps.LatLng(46.227638, 2.213749000000007),
                  mapTypeId: google.maps.MapTypeId.TERRAIN,
                  mapTypeControl: false,
                  streetViewControl: false
              });
              // place a few markers
              var markerlocations = [
                  [46.2276, 2.2137, 'location 1'],
                  [46.2277, 2.2136, 'location 2'],
                  [46.2278, 2.2135, 'location 3'],
                  [46.2279, 2.2134, 'location 4']
              ];
              for (var i in markerlocations) {
                  var marker = new google.maps.Marker({
                      position: new google.maps.LatLng(markerlocations[i][0], markerlocations[i][1]),
                      title: markerlocations[i][2],
                      map: map
                  });
      
                  markers.push(marker);
                  google.maps.event.addListener(marker, 'click', (function(marker, i) {
                      return function() {
                          infowindow = new google.maps.InfoWindow({
                              width: 400,
                              height: 300,
                              content: '<div id="mydiv">' + markerlocations[i][2] + '</div>'
                          });
                          infowindow.open(map, marker);
                          //senterOnInfowindow(infowindow, marker)
                      }
                  })(marker, i));
      
              }
          }
          window.onload = initMap;
      </script>
      <style>
          #mydiv {
              height: 100px;
              width: 200px;
          }
      
          #map {
              height: 500px;
              width: 700px;
          }
      </style>
      <div id="map"></div>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 1970-01-01
        • 2016-03-07
        • 2019-02-14
        • 2016-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多