【问题标题】:Draw polygon using mouse on google maps在谷歌地图上使用鼠标绘制多边形
【发布时间】:2011-01-20 12:08:45
【问题描述】:

我需要使用鼠标绘制多边形并在 Google 地图上标记特定区域。目的是在谷歌地图上标记一个区域,然后显示该区域的酒店和景点。用户将在创建酒店时在 Google 地图上标记酒店,以便数据库具有它们的纬度和经度。

如何绘制多边形并将其填充为背景颜色以在 Google 地图中标记该区域?我已阅读 API 手册“如何绘制多边形?”基本上你需要标记多个点,然后将它们组合成一个多边形。但我需要使用鼠标拖动来完成此操作,就像绘制形状一样。请帮助我如何实现这一目标。

【问题讨论】:

    标签: javascript google-maps


    【解决方案1】:

    这里有一些代码(适用于 Google Maps JavaScript API 版本 3),可以实现您想要的。它支持:

    • 单击以追加顶点。
    • 再次单击第一个顶点以关闭路径。
    • 拖动顶点。

    它没有记录,但希望你能很容易地看到它在做什么。

    $(document).ready(function () {
        var map = new google.maps.Map(document.getElementById('map'), { center: new google.maps.LatLng(21.17, -86.66), zoom: 9, mapTypeId: google.maps.MapTypeId.HYBRID, scaleControl: true });
        var isClosed = false;
        var poly = new google.maps.Polyline({ map: map, path: [], strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 2 });
        google.maps.event.addListener(map, 'click', function (clickEvent) {
            if (isClosed)
                return;
            var markerIndex = poly.getPath().length;
            var isFirstMarker = markerIndex === 0;
            var marker = new google.maps.Marker({ map: map, position: clickEvent.latLng, draggable: true });
            if (isFirstMarker) {
                google.maps.event.addListener(marker, 'click', function () {
                    if (isClosed)
                        return;
                    var path = poly.getPath();
                    poly.setMap(null);
                    poly = new google.maps.Polygon({ map: map, path: path, strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35 });
                    isClosed = true;
                });
            }
            google.maps.event.addListener(marker, 'drag', function (dragEvent) {
                poly.getPath().setAt(markerIndex, dragEvent.latLng);
            });
            poly.getPath().push(clickEvent.latLng);
        });
    });
    

    【讨论】:

      【解决方案2】:

      Google Maps JavaScript API v3 提供了一个绘图库,http://code.google.com/apis/maps/documentation/javascript/overlays.html#drawing_tools

      您只需要启用绘图工具(如文档中的示例所示)并添加事件侦听器以创建叠加类型(如“绘图事件”部分所示)。

      使用它的一个简单示例是:http://gmaps-samples-v3.googlecode.com/svn/trunk/drawing/drawing-tools.html

      【讨论】:

      • 是的,这些是首先要检查的链接。您还可以浏览快速示例的路径;里面有一些不错的花絮,即http://gmaps-samples-v3.googlecode.com/svn/trunk/poly/poly_edit.html
      • @mimic Google 确实有清扫员,他们会寻找他们认为不再适用于他们的目的的东西。但是,如果您转到根页面,他们会将您重定向到 github github.com/googlemaps/js-samples。有趣的是,它是如何工作的,嗯?
      【解决方案3】:

      您可以在您的应用程序中使用 Google MyMaps 多边形编辑工具,也许这适合您?

      http://googlemapsapi.blogspot.com/2008/05/love-my-maps-use-its-line-and-shape.html

      但是,如果您想自己实现它,基本上是这样的:

      将点击监听器添加到地图。

      重复: 将用户单击的点存储在数组中,并在此时添加标记。 如果它是第一个标记,则向其添加点击侦听器

      当用户点击第一个标记时,解析使用点数组来构建你的多边形

      我没有任何代码给你看,但是我自己在以前的公司实现过,所以可以做到:)

      【讨论】:

      • 感谢理查德的想法。你是正确的,我确实使用了地图的多边形和叠加功能。然而,也有一些棘手的事件处理。保重:)
      • 我的地图代码有 v3 端口吗? Maps v2 将于 2013 年停用。
      【解决方案4】:

      您可能想查看GMaps Utility LibraryGeometry Controls

      如需进一步参考,您可能需要通过GeometryControls Reference

      【讨论】:

      • 谢谢丹尼尔。几何控制看起来更详细。但是对于我的项目,我使用了谷歌地图的多边形叠加功能。非常感谢这个很好的例子。
      【解决方案5】:

      我为自己做了一个例子。代码如下,jsfiddle也可用

      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=drawing&callback=initMap" async defer></script>
      
      <script>
      
      function initMap() {
      var map = new google.maps.Map(document.getElementById('map'), {
      center: {
        lat: -34.397,
        lng: 150.644
      },
      zoom: 8
      });
      
      var drawingManager = new google.maps.drawing.DrawingManager({
      drawingMode: google.maps.drawing.OverlayType.POLYGON,
      drawingControl: false,
      drawingControlOptions: {
        position: google.maps.ControlPosition.TOP_CENTER,
        drawingModes: ['polygon', 'circle']
      },
      polygonOptions: {
        editable: true
      }
      
      });
      drawingManager.setMap(map);
      
      google.maps.event.addListener(drawingManager, 'overlaycomplete', 
      function(event) {
      event.overlay.set('editable', false);
      drawingManager.setMap(null);
      console.log(event.overlay);
      });
      
      }
      </script>
      

      https://jsfiddle.net/zgmdvsrz/

      如果要显示绘图管理器,可以将绘图控件设置为 true

      【讨论】:

        【解决方案6】:

        我认为新的 Map Engines Lite 正是您正在寻找的工具:https://mapsengine.google.com/map/

        【讨论】:

          【解决方案7】:

          我使用以下代码在地图上绘制多边形

          <!DOCTYPE html>
          <html>
          <head>
          <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
          <meta charset="UTF-8">
          <title>Drawing Tools</title>
          
          <script type="text/javascript"  src="http://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script>
          <style type="text/css">
            #map, html, body {
              padding: 0;
              margin: 0;
              height: 100%;
            }
            #panel {
              width: 200px;
              font-family: Arial, sans-serif;
              font-size: 13px;
              float: right;
              margin: 10px;
            }
            #color-palette {
              clear: both;
            }
            .color-button {
              width: 14px;
              height: 14px;
              font-size: 0;
              margin: 2px;
              float: left;
              cursor: pointer;
            }
            #delete-button {
              margin-top: 5px;
            }
            #map_canvas {
             height: 100%;
             width: 100%;
             margin: 0px;
             padding: 0px
           }
          
          </style>
          <script type="text/javascript">
           var geocoder;
           var map;
           var all_overlays = [];
          
           function initialize() {
               var map = new google.maps.Map(
               document.getElementById("map_canvas"), {
               center: new google.maps.LatLng(37.4419, -122.1419),
               zoom: 13,
               mapTypeId: google.maps.MapTypeId.ROADMAP
               });
          
          var polyOptions = {
               strokeWeight: 0,
               fillOpacity: 0.45,
               editable: true,
               fillColor: '#FF1493'
             };
          var selectedShape;
          
           var drawingManager = new google.maps.drawing.DrawingManager({
                     drawingMode: google.maps.drawing.OverlayType.POLYGON,
                     drawingControl: false,
                     markerOptions: {
                     draggable: true
                 },
              polygonOptions: polyOptions
               });
          
            $('#enablePolygon').click(function() {
                   drawingManager.setMap(map);
                  drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
            });
          
             $('#resetPolygon').click(function() {
                  if (selectedShape) {
                       selectedShape.setMap(null);
                     }
                  drawingManager.setMap(null);
                  $('#showonPolygon').hide();
                  $('#resetPolygon').hide();
              });
          
              google.maps.event.addListener(drawingManager, 'polygoncomplete', 
          
             function(polygon) {
                   //  var area = google.maps.geometry.spherical.computeArea(selectedShape.getPath());
                  //  $('#areaPolygon').html(area.toFixed(2)+' Sq meters');
                $('#resetPolygon').show();
              });
          
            function clearSelection() {
                if (selectedShape) {
                      selectedShape.setEditable(false);
                      selectedShape = null;
                   }
              }
          
          
             function setSelection(shape) {
                    clearSelection();
                    selectedShape = shape;
                    shape.setEditable(true);
              }
          
          google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
          all_overlays.push(e);
          if (e.type != google.maps.drawing.OverlayType.MARKER) {
            // Switch back to non-drawing mode after drawing a shape.
            drawingManager.setDrawingMode(null);
          
            // Add an event listener that selects the newly-drawn shape when the user
            // mouses down on it.
            var newShape = e.overlay;
            newShape.type = e.type;
            google.maps.event.addListener(newShape, 'click', function() {
              setSelection(newShape);
            });
            setSelection(newShape);
             }
           });
          
           google.maps.event.addListener(drawingManager, 'polygoncomplete', function (polygon) {
          var coordinates = (polygon.getPath().getArray());
          console.log(coordinates);
          alert(coordinates);
           });
          }
           google.maps.event.addDomListener(window, "load", initialize);
          </script>
          </head>
             <body>
              <input type="button" id="enablePolygon" value="Calculate Area" />
              <input type="button" id="resetPolygon" value="Reset" style="display: none;" />
             <div id="showonPolygon" style="display:none;"><b>Area:</b> <span 
               id="areaPolygon">&nbsp;</span></div>
               <div id="map_canvas"></div>
               </html>
          

          输出:

          【讨论】:

            【解决方案8】:

            API v2 绘图工具移植到 API v3 @http://nettique.free.fr/gmap/toolbar.html

            【讨论】:

            • 这个工具可以免费使用吗?
            【解决方案9】:

            自从第一次提出这个问题以来,google.maps.polygon 已经有了一些显着的改进。这是一个简单的实现,使用所有原生 google.maps v3 工具。 (注意:这里有一个不稳定的 JavaScript 范围工作......但它确实工作......)

            var listener1 = google.maps.event.addListener(map, "click", function(e) {
                var latLng = e.latLng;
                var myMvcArray = new google.maps.MVCArray();
                myMvcArray.push(latLng); // First Point
                var myPolygon = new google.maps.Polygon({
                    map: map,
                    paths: myMvcArray, // one time registration reqd only
                    strokeColor: "#FF0000",
                    strokeOpacity: 1.0,
                    strokeWeight: 2,
                    fillColor: "#FF0000",
                    fillOpacity: 0.10,
                    editable: true,
                    draggable: false,
                    clickable: true
                });
                google.maps.event.removeListener(listener1);
            
                var listener2 = google.maps.event.addListener(map, 'click', function(e) {
                    latLng = e.latLng;
                    myMvcArray.push(latLng);
                    myMvcArray.getArray().forEach(function(value, index) {
                        console.log(" index: " + index + "    value: " + value);
                    })
                });
            });
            

            用旧问题提交的新代码回答,以防其他人来这里!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-05-31
              • 2020-06-28
              • 2014-04-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多