使用 fitbounds 时,在地图范围内包括打开的信息窗口

Posted

技术标签:

【中文标题】使用 fitbounds 时,在地图范围内包括打开的信息窗口【英文标题】:Include open infowindows within bounds of map, when using fitbounds 【发布时间】:2014-01-26 22:16:53 【问题描述】:

我有一张地图,其中包含多个带有信息窗口的标记。信息窗口需要在页面加载时打开。使用 setbounds 将地图居中以合并所有标记,这是可行的,但它还需要在边界内包含信息窗口。目前信息窗口在一些地方被裁剪。

JS:

function initialize() 
    var map = new google.maps.Map(document.getElementById('map-canvas'));
    var bounds = new google.maps.LatLngBounds();
    var myLatlng1 = new google.maps.LatLng(51.525209,-0.09402479999994284)
    var contentString1 = '<div class="map-content"><p>Test1<br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf</p></div>'
    var infowindow1 = new google.maps.InfoWindow(content: contentString1);
    var marker1 = new google.maps.Marker(position: myLatlng1,map: map,title: 'Test1');

    google.maps.event.addListener(marker1, 'click', function() infowindow1.open(map,marker1););
    infowindow1.open(map,marker1);
    bounds.extend(myLatlng1);

    var myLatlng2 = new google.maps.LatLng(51.52106840183588,-0.10866641049801729)
    var contentString2 = '<div class="map-content"><p><br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf<br/ >dsfasdf</p></div>'
    var infowindow2 = new google.maps.InfoWindow(content: contentString2);
    var marker2 = new google.maps.Marker(position: myLatlng2,map: map,title: 'Test2');
    google.maps.event.addListener(marker2, 'click', function() infowindow2.open(map,marker2););
    infowindow2.open(map,marker2);
    bounds.extend(myLatlng2)

    //  Fit these bounds to the map
    map.fitBounds(bounds);

google.maps.event.addDomListener(window, 'load', initialize);

CSS:

#map-canvas  width: 100%; height: 520px; 

你可以在这里看到一个小提琴:http://jsfiddle.net/mKKVM/

任何人都可以建议如何在边界内获取信息窗口吗?

【问题讨论】:

你的jsfiddle中的代码真的很丑,不好看。你听说过缩进吗? :) 顺便说一句,javascript 代码应该放在 javascript 部分(左下角),你有它在 html 部分。 感谢托马斯的反馈。目标是让所有内容都出现在地图的范围内。单击标记会平移地图,并且可能会(部分)将其他标记移出视野,这并不令人满意。 【参考方案1】:

概念证明jsfiddle

    正常显示地图 计算从标记锚点到信息窗口上边缘的像素距离 计算从标记锚点到信息窗口左边缘的像素距离 计算从标记锚点到信息窗口右边缘的像素距离 用边界右上角加上信息窗口宽度的一半和边界顶部加上信息窗口高度的两个点来扩展原始边界。 用边界左角减去信息窗口宽度的一半和边界顶部加上信息窗口高度的两个点来扩展原始边界。 使地图适应新的边界。

大概可以细化为使用顶部中心、左侧中心和右侧中心 3 点,这是第一次切割,概念验证,可能可以清理和细化。

function initialize() 
  var map = new google.maps.Map(document.getElementById('map-canvas'));
  var projection = null; 
  google.maps.event.addListener(map,'projection_changed', function() 
    projection = map.getProjection();
  ); 

  var bounds = new google.maps.LatLngBounds();
  if (!projection) 
    google.maps.event.addListener(map, 'idle', computeBounds);
  else 
    computeBounds();

  var myLatlng1 = new google.maps.LatLng(51.525209,-0.09402479999994284);
  bounds.extend(myLatlng1);
  var myLatlng2 = new google.maps.LatLng(51.52106840183588,-0.10866641049801729);
  bounds.extend(myLatlng2);
  //  Fit these bounds to the map
  map.fitBounds(bounds);

  function computeBounds()     

    var contentString1 = '<div class="map-content"><p>Test1<br />dsfasdf<br />dsfasdf<br />dsfasdf<br />dsfasdf<br />dsfasdf<br />dsfasdf</p></div>'
    var infowindow1 = new google.maps.InfoWindow(content: contentString1);
    var marker1 = new google.maps.Marker(position: myLatlng1,map: map,title: 'Test1');

    google.maps.event.addListener(marker1, 'click', function() 
      infowindow1.open(map,marker1);
    );
    infowindow1.open(map,marker1);
    google.maps.event.addListenerOnce(infowindow1,'domready',calcInfoWindowBounds); 

    var contentString2 = '<div class="map-content"><p><br />dsfasdf<br />dsfasdf<br />dsfasdf<br />dsfasdf<br />dsfasdf</p></div>'
    var infowindow2 = new google.maps.InfoWindow(content: contentString2);
    var marker2 = new google.maps.Marker(position: myLatlng2,map: map,title: 'Test2');
    google.maps.event.addListener(marker2, 'click', function() 
      infowindow2.open(map,marker2);
    );
    infowindow2.open(map,marker2);

    google.maps.event.addListenerOnce(infowindow2,'domready',calcInfoWindowBounds); 

    function calcInfoWindowBounds()
      domEls = document.getElementsByClassName('map-content');
      var markerSpace = 32+8;
      var maxTop = 0;
      var maxLeft = 0;
      var maxRight = 0;
      for (var i=0; i<domEls.length; i++) 
        var topOfWindow = domEls[i].offsetHeight + markerSpace;
        var leftOfWindow = domEls[i].offsetWidth/2;
        var rightOfWindow = domEls[i].offsetWidth/2;

        if (topOfWindow > maxTop) maxTop = topOfWindow;
        if (leftOfWindow > maxLeft) maxLeft = leftOfWindow;
        if (rightOfWindow > maxRight) maxRight = rightOfWindow;
      

      var leftBounds = projection.fromLatLngToPoint(new google.maps.LatLng(bounds.getNorthEast().lat(),bounds.getSouththWest().lng()));
      var rightBounds = projection.fromLatLngToPoint(new google.maps.LatLng(bounds.getNorthEast()));
      var topBounds0 = rightBounds.y + maxTop;
      var rightBounds0 = rightBounds.x + maxRight;
      var leftBounds0 = leftBounds.x - maxLeft;
      bounds.extend(projection.fromPointToLatLng(leftBounds0,topBounds0));
      bounds.extend(projection.fromPointToLatLng(rightBounds0,topBounds0));
      map.fitBounds(bounds);
       

  


google.maps.event.addDomListener(window, 'load', initialize);

【讨论】:

getSouththWest() 应该是getSouthWest(),我猜。然后 - InvalidValueError: in property lat: not a number 在一行 var rightBounds = 上。这条线似乎以某种方式将bounds 对象的一个​​子属性转换为NaN:imgur.com/RMZOlPi.png 那里有无限循环。有什么问题?我有长这样的信息框,它不能正常工作。 jsfiddle.net/tayfunyasar/H7bPE/27 有一个错误。不像@Andrey 所说的那样工作。 var leftBounds = projection.fromLatLngToPoint(new google.maps.LatLng(bounds.getNorthEast().lat(),bounds.getSouthWest().lng())); var rightBounds = projection.fromLatLngToPoint(new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getNorthEast().lng()));

以上是关于使用 fitbounds 时,在地图范围内包括打开的信息窗口的主要内容,如果未能解决你的问题,请参考以下文章

Google 地图 api V3 中的 fitbounds() 不适合边界

调用 map.fitBounds 后立即谷歌地图 map.getBounds()

谷歌地图 API 3 缩小 fitBounds

使用 Leaflet-react 时如何调用 fitBounds()?

计算 fitBounds() 针对给定边界和地图大小返回的视口

谷歌地图 API V3 fitBounds() 不工作