谷歌地图V3自定义标记图像和fitBounds()

时间:2012-05-20 18:44:29

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

我尝试使用fitBounds()方法将地图的边界与标记本身相匹配后,让我的自定义标记显示在地图上。

我通过循环标记数组然后扩展地图边界以合并标记坐标来完成此操作。

这适用于股票谷歌地图标记。但是,我的客户希望为他们的网站使用相当大的(36px×57px)标记图像。在拟合地图边界时如何补偿?

在使用自定义标记图像时,它们并不都适合设置的边界。

2 个答案:

答案 0 :(得分:3)

由于您已经计算了边界,因此您可能只需要扩展边界以添加足够的缓冲区以包含大图像。可用于以这种方式计算或扩展边界的公式称为凸包; Computational Geometry Algorithms Library2D Convex Hull Algorithms上有一个部分,或者有一个JavaScript Quickhull Article,其中还包含一个靠近页面底部的漂亮的在线示例。希望这有用 -

答案 1 :(得分:1)

便宜的答案是在fitBounds()之后总是缩小一个级别。但我们可以做得更好。

我喜欢写黑客。在这里,我假设您的标记的大小永远不会大于36x57。我测试了一会儿发现fitBounds()在边缘和最近的标记之间留下了大约42 px的边距(可能不在手机上),我还假设你没有重新定位标记,也就是说,它将始终显示在给定的坐标位置上方。如果图标跑到另一边,则需要进行调整。

我的hack利用了一个测量LatLng像素位置的函数(使用容器版本,我在这里读到div版本在边界更改时不可靠)。

由于我们知道图标的高度以及最顶部标记的位置,如果确定要在屏幕外,我们可以将地图向南平移一点。如果下面没有足够的边距,唯一的选择是缩小。我唯一担心的是它会生涩,因为它需要两个事件:fitBounds和自定义平移/缩放。那么唯一的答案就是重写自定义的fitBounds。当我手动测试时,事件顺利进行。

http://jsfiddle.net/sZJjY/

单击以添加猫图标,右键单击以触发调整大小/平移。

示例:放置3-4个小猫,右键单击,然后故意将另一个放在顶部,再次右键单击。

  function fitIcons() {
    var left = 180.0;
    var right = -180.0;
    var top = -90.0;
    var bottom = 90.0;

    for (var i = 0; i < markers.length; i++) {
      curlat = markers[i].getPosition().lat();
      curlng = markers[i].getPosition().lng();
      if(curlat > top)    { top = curlat; }
      if(curlat < bottom) { bottom = curlat; }
      if(curlng > right)  { right = curlng; }
      if(curlng < left)   { left = curlng; }
    }

    var overlay = new google.maps.OverlayView();
    overlay.draw = function() {};
    overlay.setMap(map);

    map.fitBounds(new google.maps.LatLngBounds(
      new google.maps.LatLng(bottom, left),
      new google.maps.LatLng(top, right)));

    topPixels = overlay.getProjection().fromLatLngToContainerPixel(
                  new google.maps.LatLng(top, right));

    bottomPixels = overlay.getProjection().fromLatLngToContainerPixel(
                  new google.maps.LatLng(bottom, left));

    topGap = topPixels.y;
    bottomGap = $("#map_canvas").height() - bottomPixels.y;

    if(topGap < iconHeight) {
      if(bottomGap > iconHeight) {
        map.panBy(0, topGap);
      }
      else {
        map.setZoom(map.getZoom() - 1);
      }
    }
  }