在谷歌地图上使用鼠标绘制多边形

35

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

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

10个回答

32

以下是一些代码(适用于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);
    });
});

21

是的,这些是要检查的第一个链接。您还可以浏览快速示例的路径;其中有一些不错的小贴士,例如http://gmaps-samples-v3.googlecode.com/svn/trunk/poly/poly_edit.html - Jerome
@mimic 谷歌确实有清理程序,会删除他们认为不再符合其目的的内容。但如果您访问根页面,则它们将重定向您到 GitHub https://github.com/googlemaps/js-samples 。有趣的是,对吧? - Jerome

18

你可以在应用程序中使用 Google MyMaps 的多边形编辑工具,也许这对你来说是可以的?

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

但是如果你想自己实现这个功能,基本上就是这样:

向地图添加点击监听器。

重复:

  • 将用户点击的点存储到数组中,并在此点添加一个标记。
  • 如果这是第一个标记,添加单击监听器。

当用户单击第一个标记时,使用点数组解析并构建多边形。

我没有代码可以展示给你,但我在以前的公司已经实现过这个功能,所以它是可行的 :)


感谢Richard的想法。你说得对,我确实使用了地图的多边形和添加覆盖物功能。不过还有一些棘手的事件处理。保重 :) - Kunal
3
我的地图代码有v3版本吗?由于2013年开始,地图v2将退出使用。 - mooreds

9

谢谢Daniel。几何控件看起来更加详细。然而,对于我的项目,我已经使用了Google地图的多边形叠加功能。非常感谢您提供这个好例子。 - Kunal

7
我为自己做了一个示例。以下是代码,也可以在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>

如果您想显示绘图管理器,可以将drawingcontrol设置为true。

https://jsfiddle.net/zgmdvsrz/


4

2
我已经使用以下代码在地图上绘制多边形:
<!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>

输出:在这里输入图片描述


1
自此问题首次提出以来,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);
        })
    });
});

在这种情况下,如果其他人到达此处,请使用新代码回答旧问题!

1

这个工具可以免费使用吗? - kaoscify

0

谷歌我的地图创建新地图,然后创建新图层,然后导入新的Excel文件,在Excel文件中可以编写你的WKT

[
{
    "WKT": "POLYGON ((100.01397525354281 50, 100.0137067229647 49.99727356328608, 100.01291145070986 49.99465190200606, 100.01161999864507 49.99223576513271, 100.00988199654893 49.99011800345108, 100.00776423486728 49.988380001354926, 100.00534809799393 49.98708854929014, 100.00272643671393 49.98629327703531, 100 49.98602474645719, 99.99727356328607 49.98629327703531, 99.99465190200607 49.98708854929014, 99.99223576513272 49.988380001354926, 99.99011800345107 49.99011800345108, 99.98838000135493 49.99223576513271, 99.98708854929014 49.99465190200606, 99.9862932770353 49.99727356328608, 99.98602474645719 50, 99.9862932770353 50.00272643671392, 99.98708854929014 50.00534809799394, 99.98838000135493 50.00776423486729, 99.99011800345107 50.00988199654892, 99.99223576513272 50.011619998645074, 99.99465190200607 50.01291145070986, 99.99727356328607 50.01370672296469, 100 50.01397525354281, 100.00272643671393 50.01370672296469, 100.00534809799393 50.01291145070986, 100.00776423486728 50.011619998645074, 100.00988199654893 50.00988199654892, 100.01161999864507 50.00776423486729, 100.01291145070986 50.00534809799394, 100.0137067229647 50.00272643671392, 100.01397525354281 50))",
    "name": "Circle",
    "description": "radius 1000 meters"
},
{
    "WKT": "POLYGON ((100.01397525354281 50.01397525354281, 100.01397525354281 49.98602474645719, 99.98602474645719 49.98602474645719, 99.98602474645719 50.01397525354281, 100.01397525354281 50.01397525354281))",
    "name": "Rectangle",
    "description": ""
},
{
    "WKT": "POLYGON ((100.01976399309784 50, 100.01938423351235 49.996144236222214, 100.0182595487038 49.99243664728408, 100.01643315967861 49.98901971374923, 100.01397525354281 49.98602474645719, 100.01098028625077 49.98356684032139, 100.00756335271592 49.981740451296204, 100.00385576377778 49.980615766487645, 100 49.98023600690215, 99.99614423622222 49.980615766487645, 99.99243664728408 49.981740451296204, 99.98901971374923 49.98356684032139, 99.98602474645719 49.98602474645719, 99.98356684032139 49.98901971374923, 99.9817404512962 49.99243664728408, 99.98061576648765 49.996144236222214, 99.98023600690216 50, 99.98061576648765 50.003855763777786, 99.9817404512962 50.00756335271592, 99.98356684032139 50.01098028625077, 99.98602474645719 50.01397525354281, 99.98901971374923 50.01643315967861, 99.99243664728408 50.018259548703796, 99.99614423622222 50.019384233512355, 100 50.01976399309785, 100.00385576377778 50.019384233512355, 100.00756335271592 50.018259548703796, 100.01098028625077 50.01643315967861, 100.01397525354281 50.01397525354281, 100.01643315967861 50.01098028625077, 100.0182595487038 50.00756335271592, 100.01938423351235 50.003855763777786, 100.01976399309784 50))",
    "name": "Circle"
}

]

enter image description here enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接