从Google地图视口边界中排除重叠元素

Nie*_*jes 9 javascript google-maps google-maps-api-3

我使用Google Maps API v3在网站上创建内联地图.在它的容器元素中,我还有一个绝对定位的叠加层,它显示了一些细节信息,在视觉上悬停在地图上.确定上下文时,此元素可能会增长到整个地图元素的大小.

所有这一切都运行正常,但是地图实例当然仍然认为地图的重叠部分是地图的有效可用部分.这意味着,特别是如果叠加层处于最大高度,setCenter则不会聚焦在可见中心上,并且绘制的路线DirectionsRenderer部分位于叠加层下方.

看这个图片: 在此输入图像描述

有没有办法将实际视口限制在蓝色区域,因此setCenter箭头尖端的中心setBounds适合蓝色部分?

Nie*_*jes 9

我已经设法暂时实现了可接受的功能性解决方法.

一些常见的注意事项很有用:

  • 每个Map对象都有一个Projection,可以在LatLng点之间转换为地图点.
  • 地图指向Projection用于计算的用于"世界"坐标,这意味着它们是缩放级别0的世界地图上的像素.
  • 每个缩放级别都会使显示的像素数精确加倍.这意味着给定地图点中的像素数等于2 ^ zoom.

下面的示例假设右侧有300px宽的侧边栏 - 适应其他边框应该很容易.

定心

使用这些知识,为偏心定心编写自定义函数变得微不足道:

function setCenter(latlng)
{
    var z = Math.pow(2, map.getZoom());
    var pnt = map.getProjection().fromLatLngToPoint(latlng);
    map.setCenter(map.getProjection().fromPointToLatLng(
                    new google.maps.Point(pnt.x + 150/z, pnt.y)));
}
Run Code Online (Sandbox Code Playgroud)

这里的关键部分是z变量,pnt.x + 150/z最后一行的计算.由于上述假设,对于当前缩放级别,这会将点移动到左侧150个像素的中心,并因此补偿右侧边栏上缺少的300个像素.

边界

边界问题远没那么简单.这样做的原因是要正确地偏移点,您需要知道缩放级别.对于重新定位,这不会改变,但是为了适应以前未知的界限,它几乎总是如此.由于Google Maps在适应边界时会在内部使用未知边距,因此没有可靠的方法来预测所需的缩放级别.

因此,一种可能的解决方案是调用两步火箭.首先,调用fitBounds整个地图.这应该使边界和缩放级别至少接近正确.然后就在那之后,再做第二次调用以fitBounds纠正侧边栏.

应使用LatLngBounds对象作为参数调用以下示例实现,或者不调用默认为当前边界的参数.

function setBounds(bnd, cb)
{
    var prj = map.getProjection();
    if(!bnd) bnd = map.getBounds();
    var ne = prj.fromLatLngToPoint(bnd.getNorthEast()),
        sw = prj.fromLatLngToPoint(bnd.getSouthWest());
    if(cb) ne.x += (300 / Math.pow(2, map.getZoom()));
    else google.maps.event.addListenerOnce(map,'bounds_changed',
        function(){setBounds(bnd,1)});
    map.fitBounds(new google.maps.LatLngBounds(
        prj.fromPointToLatLng(sw), prj.fromPointToLatLng(ne)));
}
Run Code Online (Sandbox Code Playgroud)

我们首先在这里做的是得到边界的实际点,并且因为cb没有设置,我们安装一个只有一次的事件bounds_changed,然后在fitBounds完成后触发.这意味着在更正缩放后,第二次自动调用该功能.第二次调用,cb=1然后偏移该框以校正300像素宽的侧边栏.

在某些情况下,这可能导致轻微的动画外观,但实际上我只看到这种情况发生在真正垃圾点击按钮导致适合操作时.否则它运行得非常好.

希望这有助于某人:)