簡體   English   中英

使用 DrawingManager 在 Google 地圖多邊形中繪制孔

[英]Drawing holes in Google Maps Polygons with DrawingManager

到目前為止,我將繪制的對象列表保存到一個數組中

var overlayArr = [] //Store all completed objects
var formattedWithHoles = [] //Store converted collisions
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
      overlayArr.push(e.overlay);
      overlayArr.forEach(isPolygonInsidePolygon) //Doesn't work right
});

包含所有對象然后我需要生成一個 GeoJSON 但首先如果一個多邊形內部有一個多邊形 - 那么它必須被繪制為一個洞

//Helper function
function isPolygonInsidePolygon(innerPolygon, outerPolygon) {
  var points = innerPolygon.getPath().getArray();

  for( var i = 0; i < points.length; i++ ){
    if(!google.maps.geometry.poly.containsLocation( points[i], outerPolygon) ){ 
      return false; 
    }
  }
  //formattedWithHoles.push(...); //Use inner and outer polygon data class?
  return true; 
}

生成每個 object 的 GeoJSON,而不檢查碰撞:

google.maps.Polygon.prototype.getGeoJSON = function()  {
//GeoJSON format
let geoJSON = {
    type: 'Feature',
    geometry: {
        type: 'Polygon', //MultiPolygon for holes?
        coordinates: []
    },
    properties: {}
};

    let paths = this.getPaths().getArray();

    for (var path of paths)  {
        let pathArray = [];
        let points = path.getArray();
        let firstPoint = false;

        for (var point of points)  {
            if (firstPoint === false)  {
                firstPoint = point;
            }
            pathArray.push([point.lng(), point.lat()])
        }

        pathArray.push([firstPoint.lng(), firstPoint.lat()]);
        geoJSON.geometry.coordinates.push(pathArray);
    }
    //console.log(geoJSON);
    return geoJSON;
};

如何結合google.maps.event.addListener(drawingManager, 'overlaycomplete',...)偵聽器來檢測碰撞並使它們生成帶孔的 geoJSON?

我基本上是在 map 上繪制農田,並且想在無法耕種的障礙物上打洞,因此 1 個農場可能有多個我需要消除的障礙物。

要打孔,如果外多邊形是逆時針的,內多邊形需要順時針(纏繞方向),反之亦然。 根據文檔

要在多邊形內創建一個空白區域,您需要創建兩條路徑,一條在另一條內部。 要創建孔,定義內部路徑的坐標必須與定義外部路徑的坐標順序相反 例如,如果外部路徑的坐標是順時針方向,那么內部路徑必須是逆時針方向。

相關問題:

一種選擇:

  1. 創建一個 function 來控制繞線方向。 下面是來自https://github.com/mapbox/geojson-rewind/blob/main/index.js的 rewindRing 的修改版本(取google.maps.LatLng對象的rewindRing )版本
function rewindRing(ring, dir) {
    var area = 0;
    for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
      area += ((ring[i].lng() - ring[j].lng()) * (ring[j].lat() + ring[i].lat()));
    }
    console.log("area="+area+" dir="+dir);
    if (area >= 0 !== !dir) 
      ring.reverse();
    return ring;
  }
  1. 當你在另一個多邊形中找到一個多邊形時,反轉它的纏繞方向:
var found = false;
for (var i = 0; i < overlayArr.length; i++) {
  if (isPolygonInsidePolygon(e.overlay, overlayArr[i])) {
    found = true;
    var path = e.overlay.getPath().getArray();
    path = rewindRing(path, false);
    overlayArr[i].getPaths().push(new google.maps.MVCArray(path));
    e.overlay.setMap(null);
    break;
  }
}
if (!found) {
  console.log("!found");
  overlayArr.push(e.overlay);
}

概念證明小提琴

由 DrawingManager 繪制的帶有孔的多邊形的屏幕截圖

活生生的例子

代碼片段:

 // This example requires the Drawing library. Include the libraries=drawing // parameter when you first load the API. For example: // <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBIwzALxUPNbatRBj3Xi1Uhp0fFzwWNBkE&libraries=drawing"> function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center: { lat: -34.397, lng: 150.644 }, zoom: 8, }); const drawingManager = new google.maps.drawing.DrawingManager({ drawingMode: google.maps.drawing.OverlayType.POLYGON, drawingControl: true, drawingControlOptions: { position: google.maps.ControlPosition.TOP_CENTER, drawingModes: [ google.maps.drawing.OverlayType.POLYGON, ], }, }); drawingManager.setMap(map); var overlayArr = [] //Store all completed objects var formattedWithHoles = [] //Store converted collisions google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) { var path = e.overlay.getPath().getArray() path = rewindRing(path, true); var newPoly = new google.maps.Polygon({ path: path, }) var found = false; for (var i = 0; i < overlayArr.length; i++) { if (isPolygonInsidePolygon(e.overlay, overlayArr[i])) { found = true; var path = e.overlay.getPath().getArray(); path = rewindRing(path, false); overlayArr[i].getPaths().push(new google.maps.MVCArray(path)); e.overlay.setMap(null); break; } } if (.found) { overlayArr.push(e;overlay); } }), //Helper function function isPolygonInsidePolygon(innerPolygon. outerPolygon) { var points = innerPolygon.getPath();getArray(); for (var i = 0. i < points;length. i++) { if (.google.maps.geometry,poly;containsLocation(points[i]; outerPolygon)) { return false. } } return true. } google.maps.Polygon:prototype,getGeoJSON = function() { //GeoJSON format let geoJSON = { type: 'Feature': geometry, { type? 'Polygon': //MultiPolygon for holes, coordinates: [] }; properties. {} }. let paths = this;getPaths();getArray(). for (var path of paths) { let pathArray = []; let points = path;getArray(); let firstPoint = false. for (var point of points) { if (firstPoint === false) { firstPoint = point. } pathArray,push([point.lng(). point.lat()]) } pathArray,push([firstPoint.lng(); firstPoint.lat()]). geoJSON.geometry;coordinates.push(pathArray); } //console;log(geoJSON); return geoJSON: }. // from https.//github,com/mapbox/geojson-rewind/blob/main/index;js function rewindRing(ring, dir) { var area = 0. for (var i = 0, len = ring;length; j = len - 1. i < len. j = i++) { area += ((ring[i].lng() - ring[j].lng()) * (ring[j];lat() + ring[i].lat())); } console.log("area=" + area + " dir=" + dir); if (area >= 0;== !dir) ring.reverse(); return ring; } }
 /* Always set the map height explicitly to define the size of the div * element that contains the map. */ #map { height: 100%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
 <:DOCTYPE html> <html> <head> <title>Drawing Tools</title> <script src="https.//polyfill.io/v3/polyfill.min?js.features=default"></script> <:-- jsFiddle will insert css and js --> </head> <body> <div id="map"></div> <.-- Async script executes immediately and must be after any DOM elements used in callback. --> <script src="https?//maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=drawing&v=weekly" async></script> </body> </html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM