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

发布于 2024-09-06 19:03:03 字数 211 浏览 2 评论 0原文

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

实现此类功能的有效方法是什么(即,充分优化,以免毁掉一台四年前的笔记本电脑)?

谢谢你!

The Google Maps API for a Polygon does not offer a drag method.

What would be an efficient way of implementing such a feature (i.e., sufficiently optimised so that it would not kill a four year old laptop)?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

顾北清歌寒 2024-09-13 19:03:04

好吧 - 所以在看到你试图实现的网站之后,我开始觉得 Raphael 可能没有必要,因为它是一个相当重的 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. 实现绘制函数以在缩放和平移期间重绘矩形

目前我只存储矩形的一个 LatLng 值(是左上角) - 您可以轻松扩展此示例以存储矩形的所有 4 个点,并让形状在缩放时动态调整自身大小。您可能想要这样做,否则当用户缩小时,他们将获得越来越大区域的气候报告。

Okay - so after seeing the website you are trying to implement I started to feel like Raphael may not be necessary because it is a pretty heavy JS Library - and if you are only trying to draw a rectangle polygon I thought, why not just do it with a single lightweight DIV instead?

However I think the Raphael solution would still hold water for many other cases - so I think I'll just post another possible answer.

Here is a working example I threw together:

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

Feel free to take a look at the source:

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

Essentially we do the following

  1. Create the Custom Overlay
  2. Create the draggable div polygon and, using jQuery UI, make it draggable
  3. Tie an event that listens to when the dragging has stopped that updates the LatLng position of the rectangle
  4. Add the object to the Custom Overlay
  5. Implement the draw function to redraw the rectangle during zooms and pans

Currently I am only storing one LatLng value for the Rectangle (being the top left corner) - you could easily extend this example to store all 4 points of the rectangle and have the shape dynamically resize itself on zooms. You may want to do that, otherwise as users zoom out they will get a climate report for a larger and larger area.

喜爱皱眉﹌ 2024-09-13 19:03:03

我发现 Google 地图 V2 多边形实现对于我的需求来说非常有限,并通过创建自定义叠加层解决了这个问题。我的小组目前停留在 IE6 上,所以我还没有迁移到 Google 地图 V3 - 但快速浏览一下 API 表明,您可能可以使用 V3 做与我在 V2 中所做的类似的事情。

本质上,其想法是:

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

自定义叠加层:

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

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


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

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

http://raphaeljs.com/

使用 Raphaël 将为您节省大量时间来尝试弄清楚如何发怒-浏览器矢量图形(多边形)功能 - 最重要的是它已经支持拖动事件,这是他们库中的一个示例:

http://raphaeljs.com/graffle.html

一旦您有了自定义叠加层并且您能够将一些 Raphaël 对象扔到其上,最后一步是将您想要的坐标从 Lat/Lng 值转换为像素值。这在 V3 的 MapCanvasProjection 中可用:

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

您可以使用 fromLatLngToDivPixel 找出拉斐尔多边形上的点的实际像素值,绘制它,然后将其添加到覆盖拖动事件。

I found the Google Maps V2 Polygon Implementation to be very limiting for the needs I have had and solved it by creating a custom overlay. My group is currently stuck on IE6 so I have yet to migrate over to Google Maps V3 - but taking a quick look at the API shows that you could probably do a similar thing that I did in V2 with V3.

Essentially the idea is:

  1. Create a Custom Overlay
  2. Populate it with your own SVG/VML Polygons and attach a drag event to this custom polygon object

Custom Overlays:

Here is some information to get you started on making your own custom overlay:

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


Creating your own "Dragable" Polygon Object:

Once you get that down you'll want to add your own polygons to the custom overlay instead of using GPolygons. I went through the painful process of learning SVG/VML and writing a library to bridge SVG/VML together - you could do that, but I would recommend starting by trying to use another library such as Raphaël.

http://raphaeljs.com/

Using Raphaël will save you a whole lot of time trying to figure out how to get cross-browser Vector Graphic (Polygon) functionality - and best of all it supports drag events already, here is an example from their library:

http://raphaeljs.com/graffle.html

Once you have a custom overlay and you are able to throw some Raphaël objects onto it the last step is to translate the coordinates you want from a Lat/Lng value to a Pixel value. This is available in the MapCanvasProjection of V3:

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

You can use fromLatLngToDivPixel to figure out what the actual pixel values are for the points on your Raphael polygon, draw it, then add it to the overlay with a drag event.

陌伤浅笑 2024-09-13 19:03:03

从版本 3.11(日期为 2013 年 1 月 22 日)开始,可以将 draggable 属性设置到 google.maps.Polygon 实例上;请参阅此示例

如果您想以编程方式移动多边形,则需要 我编写的自定义 Google 地图扩展,因为 API 不提供这样的方法。

Since version 3.11 (dated Jan 22, 2013) it's possible to just set the draggable property onto the google.maps.Polygon instance; see this example.

If you want to programmatically move a polygon, you'll need a custom Google Maps Extension which I wrote, as the API does not provide such a method.

趁年轻赶紧闹 2024-09-13 19:03:03

我是这样做的。找到多边形的大致中心,并添加一个标记,然后向该标记添加一个拖动侦听器。在纬度/经度更改时,减去原始标记纬度/经度的差值,减去每个路径的差值,然后将原始位置设置为新位置。确保在您的 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;
}

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

Here's how I do it. Find the approximate center of the polygon, and add a marker, then add a drag listener to the marker. On lat/lng change, subtract the difference from the original marker lat/lng, subtract the difference to each of the paths, then, set the original position to the new position. Make sure that in your javascript api call that you have 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;
}

If you have any questions, feel free to contact me.

简美 2024-09-13 19:03:03

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

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

You could have markers for each point on the polygon, these markers could have drag and at the end of each drag, the polygon could be redrawn.

You could also have a marker in the center of the polygon representing the polygon as a whole, when you move that marker, every marker could be moved by the same amount to maintain the shape.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文