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

时间:2014-02-20 16:02:31

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

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

所有这一切都运行正常,但是地图实例当然仍然认为地图的重叠部分是地图的有效可用部分。这意味着,尤其是当叠加层处于最大高度时,setCenter不会关注可见中心,而使用DirectionsRenderer绘制的路线部分位于叠加层下方。< / p>

看到这张图片: enter image description here

有没有办法将实际视口限制在蓝色区域,以便setCenter以箭头为中心,setBounds适合蓝色部分?

3 个答案:

答案 0 :(得分:9)

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

一些有用的一般性说明:

  • 每个Map对象都有Projection,可以在LatLng点之间转换为地图点。
  • Projection用于计算的地图点位于&#39; world&#39;坐标,表示它们是缩放级别为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)));
}

这里的关键部分是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)));
}

我们首先在这里做的是获取边界的实际点,并且由于cb未设置,我们在bounds_changed上安装一次只有事件,然后在fitBounds之后触发cb=1已完成。这意味着在更正缩放后,第二次自动调用该功能。第二次调用{{1}},然后偏移该框以校正300像素宽的侧边栏。

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

希望这有助于某人:)

答案 1 :(得分:0)

您可以使用地图panBy() method,它允许您以给定的距离(以像素为单位)更改地图的中心。

希望这有帮助!

答案 2 :(得分:0)

我有类似的需求,结果只是在LatLngBounds对象的东边强制一些“填充”。

在好的方面,它很简单,而且很有效。在不利方面,它并不是真正的多功能。只是一个快速的小黑客。

// start with a standard LatLngBounds object, extending as you usually would...
bounds = new google.maps.LatLngBounds();

// ...

ne = bounds.getNorthEast();
sw = bounds.getSouthWest();

// the multiplier used to add space; positive for east, negative for west
lngPadding = 1.5

extendedLng = ne.lng() + (ne.lng() - sw.lng()) * lngPadding;

// copy original and extend with the new Lng
extendedBounds = bounds;
extendedBounds.extend(new google.maps.LatLng(ne.lat(), extendedLng));

map.fitBounds(extendedBounds);