google-maps - 如何访问重叠的 geojson/多边形以显示在信息框中

标签 google-maps google-maps-api-3

我使用 Google Maps API 通过 geoJSON 数据层将多个多边形加载到 map 中。其中一些多边形在某些区域重叠。当用户单击位于多个多边形内部的点时,我想通过单击事件在信息框中显示属性(名称、标签等)。

我想显示给定点的所有多边形的属性。目前,当我点击一个点时,我只能看到一个多边形,尽管该点位于多个多边形内。

如何使用 Google Maps API v3 访问所有多边形的所有属性?

const map = useGoogleMap(); // google map instance
const polygons; // an array of polygons, example snippet below. 

map.data.addGeoJson(polygons);

map.data.addListener('click', function(event) {
   // how can i access other features underneath this clicked point
   console.log(event.feature); // only returns "Geofence 1"
})

示例 GeoJson:

polygons = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
      "name": "Geofence 1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -8.96484375,
              -9.96885060854611
            ],
            [
              3.955078125,
              -9.96885060854611
            ],
            [
              3.955078125,
              -0.17578097424708533
            ],
            [
              -8.96484375,
              -0.17578097424708533
            ],
            [
              -8.96484375,
              -9.96885060854611
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
      "name": "Geofence 2"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -6.591796875,
              -8.320212289522944
            ],
            [
              2.197265625,
              -8.320212289522944
            ],
            [
              2.197265625,
              -1.9332268264771106
            ],
            [
              -6.591796875,
              -1.9332268264771106
            ],
            [
              -6.591796875,
              -8.320212289522944
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
      "name": "Geofence 3"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -4.39453125,
              -6.926426847059551
            ],
            [
              0.263671875,
              -6.926426847059551
            ],
            [
              0.263671875,
              -3.337953961416472
            ],
            [
              -4.39453125,
              -3.337953961416472
            ],
            [
              -4.39453125,
              -6.926426847059551
            ]
          ]
        ]
      }
    }
  ]
}

最佳答案

一个选择是使用 containsLocation几何库中的方法。

containsLocation(point, polygon) Parameters:
point: LatLng
polygon: Polygon
Return Value: boolean
Computes whether the given point lies inside the specified polygon.

不幸的是,它只适用于原生 google.maps.Polygon 对象,不适用于 Data.Polygon 对象。将要素中的数据转换为原生 google.maps.Polygon 对象,将它们推送到一个数组中,然后处理该数组以查看点击位于哪个多边形中。

  1. 为输入中的每个多边形创建 google.maps.Polygon(假设只有多边形)
  var polygonArray = [];
  map.data.addListener('addfeature', function(e) {
    e.feature.getGeometry().getArray().forEach(function(latLngArry){
      const polygon = new google.maps.Polygon({
        map: map,
        paths: latLngArry.getArray(),
        clickable: false,
        name: e.feature.getProperty("name") // save the data we want to output as an attribute
      })
      polygonArray.push(polygon);
    })
  1. 点击检查点击所在的多边形:
  map.addListener('click', function(event) {
    var content = "";
    for (var i=0;i<polygonArray.length;i++) {
       if (google.maps.geometry.poly.containsLocation(event.latLng, polygonArray[i])) {
          if (content.length!=0) 
            content+=" : "
          content += polygonArray[i].name;
       }
    }
    console.log(content);
  })

proof of concept fiddle

screenshot of resulting map

// This example uses the Google Maps JavaScript API's Data layer
// to create a rectangular polygon with 2 holes in it.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"));
  const infowindow = new google.maps.InfoWindow();
  var bounds = new google.maps.LatLngBounds();
  var polygonArray = [];
  map.data.addListener('addfeature', function(e) {
    console.log(e.feature.getGeometry().getArray().length);
    e.feature.getGeometry().getArray().forEach(function(latLngArry) {
      console.log(latLngArry.getArray())
      const polygon = new google.maps.Polygon({
        map: map,
        paths: latLngArry.getArray(),
        clickable: false,
        name: e.feature.getProperty("name")
      })
      polygonArray.push(polygon);
    })
    processPoints(e.feature.getGeometry(), bounds.extend, bounds);
    map.fitBounds(bounds);
  });
  const features = map.data.addGeoJson(polygons);
  map.data.setMap(null);
  map.addListener('click', function(event) {
    var content = "";
    for (var i = 0; i < polygonArray.length; i++) {
      if (google.maps.geometry.poly.containsLocation(event.latLng, polygonArray[i])) {
        if (content.length != 0)
          content += " : "
        content += polygonArray[i].name;
      }
    }
    console.log(content);
    document.getElementById('info').innerHTML = content;
    infowindow.setPosition(event.latLng);
    if (content.length == 0) content = "no GeoFence";
    infowindow.setContent(content);
    infowindow.open(map);
  })

  function processPoints(geometry, callback, thisArg) {
    if (geometry instanceof google.maps.LatLng) {
      callback.call(thisArg, geometry);
    } else if (geometry instanceof google.maps.Data.Point) {
      callback.call(thisArg, geometry.get());
    } else {
      geometry.getArray().forEach(function(g) {
        processPoints(g, callback, thisArg);
      });
    }
  }
}
const polygons = {
  "type": "FeatureCollection",
  "features": [{
      "type": "Feature",
      "properties": {
        "name": "Geofence 1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-8.96484375, -9.96885060854611],
            [
              3.955078125, -9.96885060854611
            ],
            [
              3.955078125, -0.17578097424708533
            ],
            [-8.96484375, -0.17578097424708533],
            [-8.96484375, -9.96885060854611]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "name": "Geofence 2"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-6.591796875, -8.320212289522944],
            [
              2.197265625, -8.320212289522944
            ],
            [
              2.197265625, -1.9332268264771106
            ],
            [-6.591796875, -1.9332268264771106],
            [-6.591796875, -8.320212289522944]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "name": "Geofence 3"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-4.39453125, -6.926426847059551],
            [
              0.263671875, -6.926426847059551
            ],
            [
              0.263671875, -3.337953961416472
            ],
            [-4.39453125, -3.337953961416472],
            [-4.39453125, -6.926426847059551]
          ]
        ]
      }
    }
  ]
}
/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */

#map {
  height: 90%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>

<head>
  <title>Data Layer: Polygon</title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly" defer></script>
  <!-- jsFiddle will insert css and js -->
</head>

<body>
  <div id="info"></div>
  <div id="map"></div>
</body>

</html>

关于google-maps - 如何访问重叠的 geojson/多边形以显示在信息框中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64778263/

相关文章:

javascript - 通过 JavaScript 中的异步调用返回对象

google-maps - 无法嵌入谷歌地图

javascript - 无法读取未定义的属性 '__e3_'

javascript - Google Maps API v3 - 带有可拖动备用路线的路线

javascript - 谷歌地图js api在浏览器上工作但在cordova应用程序上不起作用

java - Android - 无法初始化 Google 地方信息

javascript - 即时创建 Google map 标记

javascript - 如何在 Google Maps API 上绘制圆圈并在圆圈内搜索?

javascript - 捕获所有 Google API Javascript 异常

google-chrome - Google Maps API v3,自定义点未绘制 - 仅在 Chrome 中