Google Maps JS API v3-如何检查和显示多边形点之间的距离

时间:2019-04-29 14:17:33

标签: javascript google-maps-api-3

我正在使用Google Maps API,以允许用户在地图上绘制自定义多边形。我需要检查并显示每个边框的长度。

我已经使用了“几何库”和“地图标签库”来获取和显示多边形的计算区域(也在'insert_at'和'set_at'事件上更改),但是不幸的是,我不知道如何获取边框长度。任何帮助将不胜感激。

使用的代码示例:


var labels = [];
var allOverlays = [];

function setSelection(shape) {
  selectedShape = shape;
  shape.setEditable(true);
}

function initMap() {

 var options = {
    zoom: 14,
    center: {lat: 52.250618, lng: 20.9774}
}

var map = new google.maps.Map(document.getElementById('map'), options);

var drawingManager = new google.maps.drawing.DrawingManager({
 markerOption: {
 draggable: false
 },
 polygonOptions: {
 draggable: false,
 fillColor: '#5C6BC0',
 fillOpacity: 0.45,
 strokeWeight: 0,
 editable: true,
 zIndex: 1
 },
 drawingControl: true,
 drawingControlOptions: {
 position: google.maps.ControlPosition.TOP_CENTER,
 drawingModes: ['circle', 'polygon']
 },
 circleOptions: {
 fillColor: '#5C6BC0',
 fillOpacity: 0.45,
 strokeWeight: 0,
 editable: true,
 zIndex: 1
 },
 map: map
});

function attachPolygonInfoWindow(polygon) {
   var path = polygon.getPath();
   var points = path.getArray();
   var area = (google.maps.geometry.spherical.computeArea(path.getArray())).toFixed(0);
   var bounds = new google.maps.LatLngBounds();
   var i;

   for (i = 0; i < points.length; i++) {
      bounds.extend(points[i]);
   }

   var boundsCenter = bounds.getCenter();
   var mapLabel = new MapLabel({
      map: map,
      fontSize: 20,
      align: 'left'
   });

   if (!labels.length) {
      labels.push(mapLabel)
   }

   showPolygonInfoWindow(labels, boundsCenter, area);
}

function showPolygonInfoWindow(arr, position, text) {
   arr.forEach((el) => {
     el.set('position', position);
     el.set('text', text + 'm2')
   })
}

function removePolygonInfoWindow() {

   for (var i = 0; i < labels.length; i++) {
     labels[i].setMap(null);
   }

   labels = [];
}

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
   allOverlays.push(e);

   if (e.type != google.maps.drawing.OverlayType.MARKER) {

   drawingManager.setDrawingMode(null);

   var newShape = e.overlay;
   newShape.type = e.type;

   google.maps.event.addListener(newShape, 'click', function() {
       setSelection(newShape);
   });


   if (newShape.type == "polygon") {
     var path = newShape.getPath();

     google.maps.event.addListener(path, 'insert_at', function() {
        attachPolygonInfoWindow(newShape);
     });

     google.maps.event.addListener(path, 'set_at', function() {
        attachPolygonInfoWindow(newShape);
     });

     attachPolygonInfoWindow(newShape);
   }

   setSelection(newShape);
  }
});
}

initMap();

<script src="https://maps.google.com/maps/api/js?sensor=false&libraries=drawing,geometry">
</script>
<script type="text/javascript" src="https://cdn.rawgit.com/googlemaps/js-map-label/gh-pages/src/maplabel.js"></script>

Working example Codepen

我想在每个边框的侧面显示每个边框的长度。

1 个答案:

答案 0 :(得分:0)

我的建议是创建中心标签时,还处理多边形的路径,计算其长度和中心;然后为每个对象创建MapLabel对象,并将其放置在边的中心。像这样:

for (var i=0; i<polygon.getPath().getLength(); i++) {
  // for each side in path, compute center and length
  var start = polygon.getPath().getAt(i);
  var end = polygon.getPath().getAt(i<polygon.getPath().getLength()-1 ? i+1 : 0);
  var sideLength = google.maps.geometry.spherical.computeDistanceBetween(start,end);
  var sideCenter = google.maps.geometry.spherical.interpolate(start, end, 0.5);
  var sideLabel = new MapLabel({
    map: map,
    fontSize: 20,
    align: "center"
  });
  sideLabel.set("position", sideCenter);
  sideLabel.set("text", sideLength.toFixed(2)+"m");
  polygon.labels.push(sideLabel);
}

proof of concept fiddle

screenshot of resulting map

代码段:

var labels = [];
var allOverlays = [];

function setSelection(shape) {
  selectedShape = shape;
  shape.setEditable(true);
}

function initMap() {
  var options = {
    zoom: 14,
    center: {
      lat: 52.250618,
      lng: 20.9774
    }
  };

  var map = new google.maps.Map(document.getElementById("map"), options);

  var drawingManager = new google.maps.drawing.DrawingManager({
    polygonOptions: {
      draggable: false,
      fillColor: "#5C6BC0",
      fillOpacity: 0.45,
      strokeWeight: 0,
      editable: true,
      zIndex: 1
    },
    drawingControl: true,
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_CENTER,
      drawingModes: ["polygon"]
    },
    map: map,
    drawingMode: 'polygon'
  });

  function attachPolygonInfoWindow(polygon) {
    if (!polygon.labels) polygon.labels = [];
    for (var i = 0; i < polygon.labels.length; i++) {
      polygon.labels[i].setMap(null);
    }
    polygon.labels = [];
    var path = polygon.getPath();
    var points = path.getArray();
    var area = google.maps.geometry.spherical
      .computeArea(path.getArray())
      .toFixed(0);
    var bounds = new google.maps.LatLngBounds();
    var i;

    for (i = 0; i < points.length; i++) {
      bounds.extend(points[i]);
    }

    var boundsCenter = bounds.getCenter();
    var centerLabel = new MapLabel({
      map: map,
      fontSize: 20,
      align: "left"
    });

    polygon.labels.push(centerLabel);

    centerLabel.set("position", bounds.getCenter());
    centerLabel.set("text", area + "m2");
    if (path.getLength() < 2) return;
    for (var i = 0; i < polygon.getPath().getLength(); i++) {
      // for each side in path, compute center and length
      var start = polygon.getPath().getAt(i);
      var end = polygon.getPath().getAt(i < polygon.getPath().getLength() - 1 ? i + 1 : 0);
      var sideLength = google.maps.geometry.spherical.computeDistanceBetween(start, end);
      var sideCenter = google.maps.geometry.spherical.interpolate(start, end, 0.5);
      var sideLabel = new MapLabel({
        map: map,
        fontSize: 20,
        align: "center"
      });
      sideLabel.set("position", sideCenter);
      sideLabel.set("text", sideLength.toFixed(2) + "m");
      polygon.labels.push(sideLabel);
    }
  }

  function removePolygonInfoWindow() {
    for (var i = 0; i < labels.length; i++) {
      labels[i].setMap(null);
    }
    labels = [];
  }

  google.maps.event.addListener(drawingManager, "overlaycomplete", function(e) {
    allOverlays.push(e);

    if (e.type != google.maps.drawing.OverlayType.MARKER) {
      drawingManager.setDrawingMode(null);

      var newShape = e.overlay;
      newShape.type = e.type;

      google.maps.event.addListener(newShape, "click", function() {
        setSelection(newShape);
      });

      if (newShape.type == "polygon") {
        var path = newShape.getPath();

        google.maps.event.addListener(path, "insert_at", function() {
          attachPolygonInfoWindow(newShape);
        });

        google.maps.event.addListener(path, "set_at", function() {
          attachPolygonInfoWindow(newShape);
        });

        attachPolygonInfoWindow(newShape);
      }

      setSelection(newShape);
    }
  });
}

initMap();
html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=drawing"></script>
<script src="https://cdn.jsdelivr.net/npm/js-map-label@1.0.1/src/maplabel.js"></script>