使用Google Maps v3拖动(移动)多边形

时间:2010-06-24 22:50:59

标签: javascript google-maps user-interface drag-and-drop polygon

多边形的Google Maps API不提供拖动方法。

实现这样一个功能的有效方法是什么(即,充分优化以便不会杀死一台四年前的笔记本电脑)?

谢谢!

5 个答案:

答案 0 :(得分:6)

我发现Google Maps V2 Polygon Implementation对我的需求非常有限,并通过创建自定义叠加层来解决它。我的小组目前仍然停留在IE6上,所以我还没有迁移到谷歌地图V3 - 但是快速浏览一下这个API就可以看出你可能做的和我在V2中用V3做的类似。

基本上这个想法是:

  1. 创建自定义叠加层
  2. 使用您自己的SVG / VML多边形填充它并将拖动事件附加到此自定义多边形对象

  3. 自定义叠加层:

    以下是一些信息,可帮助您开始制作自己的自定义叠加层:

    http://code.google.com/apis/maps/documentation/javascript/overlays.html#CustomOverlays


    创建自己的“可拖动”多边形对象:

    一旦你失败了,你就会想要将自己的多边形添加到自定义叠加层而不是使用GPolygons。我经历了学习SVG / VML和编写库以将SVG / VML连接在一起的痛苦过程 - 你可以这样做,但我建议首先尝试使用另一个库,如Raphaël。

    http://raphaeljs.com/

    使用Raphaël将为您节省大量时间,试图找出如何获得跨浏览器矢量图形(多边形)功能 - 最重要的是它已经支持拖动事件,这里是他们的库中的示例:

    http://raphaeljs.com/graffle.html

    一旦你有一个自定义叠加层并且你能够将一些Raphaël对象扔到它上面,最后一步就是将你想要的坐标从Lat / Lng值转换为Pixel值。这可以在V3的MapCanvasProjection中找到:

    http://code.google.com/apis/maps/documentation/javascript/reference.html#MapCanvasProjection

    您可以使用fromLatLngToDivPixel来确定Raphael多边形上的点的实际像素值,绘制它,然后使用拖动事件将其添加到叠加层。

答案 1 :(得分:4)

从3.11版(2013年1月22日)开始,可以将draggable属性设置为google.maps.Polygon实例;见this example

如果要以编程方式移动多边形,则需要a custom Google Maps Extension which I wrote,因为API不提供此类方法。

答案 2 :(得分:3)

我是这样做的。找到多边形的近似中心,然后添加标记,然后向标记添加拖动侦听器。在lat / lng更改时,减去与原始标记lat / lng的差值,减去每条路径的差值,然后将原始位置设置为新位置。确保在你的javascript api调用中你有library = geometry,drawing

google.maps.event.addListener(draw, 'overlaycomplete', function(shape) {
// POLYGON
      if (shape.type == 'polygon') {
        var bounds = new google.maps.LatLngBounds(); var i;  
        var path = shape.overlay.getPath();
        for (i = 0; i < path.length; i++) { bounds.extend(path.getAt(i)); }
        shape.latLng = bounds.getCenter();
        marker = getMarker(map,shape);
        shape.overlay.marker = marker;
        markers.push(marker); 
      }
      google.maps.event.addListener(marker, 'drag', function(event) {
         shape.overlay.move(event.latLng, shape, path);
      });

          google.maps.event.addListener(shape.overlay, 'rightclick', function() {
            this.setMap(null);
            this.marker.setMap(null);
            draw.setDrawingMode('polygon');
          });

  });
}
google.maps.Polygon.prototype.move = function(latLng, shape, p) {
    var lat = latLng.lat();
    var lng = latLng.lng();

    latDiff = shape.latLng.lat()-lat;
    lngDiff = shape.latLng.lng()-lng;

   for (i = 0; i < p.length; i++) {
    pLat = p.getAt(i).lat();
    pLng = p.getAt(i).lng();
    p.setAt(i,new google.maps.LatLng(pLat-latDiff,pLng-lngDiff));
   }
   shape.latLng = latLng; 
}
function getMarker(map,shape){
  var infowindow = new google.maps.InfoWindow();
  if(shape.type=='polygon'){ latLng = shape.latLng; }
  marker = new google.maps.Marker({
              position: latLng,
              map:map,
              draggable:true,
              clickable: true,
              animation: google.maps.Animation.DROP
            });
           shape.overlay.marker = marker;
           shape.overlay.bindTo('center',marker,'position');
           google.maps.event.addListener(marker, 'click', (function(marker) {
            return function() {
              infowindow.setContent('polygon');
              infowindow.open(map, marker);
              toggleBounce(marker);
            }
          })(marker));
          google.maps.event.addListener(infowindow,'closeclick', (function(marker) {      
            return function() {
            marker.setAnimation(null);
            }
          })(marker));
 return marker;
}

如果您有任何疑问,请随时与我联系。

答案 3 :(得分:1)

您可以为多边形上的每个点设置标记,这些标记可以拖动,并且在每次拖动结束时,可以重绘多边形。

您还可以在多边形的中心有一个标记,表示多边形作为一个整体,当您移动该标记时,每个标记可以移动相同的量以保持形状。

答案 4 :(得分:1)

好的 - 所以在看到你想要实现的网站后,我开始觉得拉斐尔可能没有必要,因为它是一个非常沉重的JS库 - 如果你只想绘制一个矩形多边形我想,为什么不只用一个轻量级DIV来做它?

然而,我认为拉斐尔解决方案仍会为许多其他情况保留水 - 所以我想我会发布另一个可能的答案。

以下是我聚集在一起的一个工作示例:

http://www.johnmick.net/drag-div-v3/

随意查看来源:

http://www.johnmick.net/drag-div-v3/js/main.js

基本上我们做以下

  1. 创建自定义叠加层
  2. 创建可拖动的div多边形,并使用jQuery UI使其可拖动
  3. 绑定一个事件,该事件监听拖动何时停止更新矩形的LatLng位置
  4. 将对象添加到自定义叠加层
  5. 实现绘图功能以在缩放和平移期间重绘矩形
  6. 目前我只为Rectangle存储一个LatLng值(左上角) - 您可以轻松扩展此示例以存储矩形的所有4个点,并使形状在缩放上动态调整大小。您可能希望这样做,否则当用户缩小时,他们将获得越来越大的区域的气候报告。