代码之家  ›  专栏  ›  技术社区  ›  Dave Jarvis James Eichele

使用谷歌地图v3拖动(移动)多边形

  •  7
  • Dave Jarvis James Eichele  · 技术社区  · 14 年前

    这个 Google Maps API 因为多边形不提供拖动方法。

    实现这种功能的有效方法是什么(即充分优化,使其不会杀死一台四岁的笔记本电脑)?

    谢谢您!

    5 回复  |  直到 12 年前
        1
  •  6
  •   John    14 年前

    我发现google maps v2多边形的实现对于我的需求非常有限,并且通过创建一个自定义覆盖来解决它。我的团队目前一直在使用IE6,所以我还没有迁移到GoogleMapsv3——但是快速查看一下API就可以发现,你可能会做一件和我在v2和v3中做的类似的事情。

    其基本思想是:

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

    自定义套印格式:

    以下是一些信息,可以帮助您开始创建自己的自定义覆盖:

    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值转换成像素值。这在v3的mapcanvas投影中可用:

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

    可以使用fromlatlngtodivPixel来计算拉斐尔多边形上点的实际像素值,绘制它,然后将其添加到具有拖动事件的覆盖层中。

        2
  •  4
  •   Bramus    12 年前

    从3.11版(2013年1月22日)开始,只需设置 draggable 属性到 google.maps.Polygon 实例;参见 this example .

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

        3
  •  3
  •   Eric Leroy    12 年前

    我就是这样做的。找到多边形的大致中心,并添加一个标记,然后向该标记添加一个拖动侦听器。在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;
    }
    

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

        4
  •  1
  •   Dave Jarvis James Eichele    14 年前

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

    也可以在多边形的中心有一个标记,表示整个多边形,移动该标记时,每个标记都可以移动相同的数量以保持形状。

        5
  •  1
  •   John    14 年前

    好吧-所以在看到你试图实现的网站后,我开始觉得拉斐尔可能不是必要的,因为它是一个相当重的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. 当拖动停止时,绑定一个侦听的事件,该事件将更新矩形的锁定位置。
    4. 将对象添加到自定义覆盖
    5. 实现draw函数,以便在缩放和平移期间重新绘制矩形。

    目前,我只为矩形存储一个latlng值(左上角)-您可以轻松扩展此示例以存储矩形的所有4个点,并使形状在缩放时自动调整大小。你可能想这样做,否则当用户缩小时,他们会得到一份更大范围的气候报告。