检查地址是否在多个多边形之一中

时间:2018-03-07 06:08:54

标签: google-maps google-maps-api-3 geolocation

对于许多卫星来说,Stack Overflow是狂热的消费者,但这是我的第一个问题,请耐心等待我!

我知道HTML& CSS,但我不是很有文化知识,也不是我在Google Maps API中的经验。

我希望我的用户使用Google地图输入地址'地点'库并返回关于该地点的纬度/经度坐标是否落在地图上三个预定多边形之一内的结果。

根据提供的位置,API将生成3条消息之一:

  • 如果坐标位于所有多边形之外,则显示msg 1
  • 如果坐标位于多边形1 内,则显示msg 2
  • 如果坐标位于 多边形2或3内,显示消息3。

我找到了this near-perfect-match我的需求案例,MKiss得到了很好的回答。 JS代码是:

var map;
var geocoder; //Added on 27/09/2016
var marker;
var polygon;
var bounds;
window.onload = initMap;
function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: center,
        zoom: 14,
        scaleControl: true
    });
  geocoder = new google.maps.Geocoder(); //Added on 27/09/2016
    bounds = new google.maps.LatLngBounds();
    google.maps.event.addListenerOnce(map, 'tilesloaded', function(evt) { 
        bounds = map.getBounds();
    });
        marker = new google.maps.Marker({
            position: center
        });
        polygon = new google.maps.Polygon({
        path: area,
        geodesic: true,
        strokeColor: '#FFd000',
        strokeOpacity: 1.0,
        strokeWeight: 4,
        fillColor: '#FFd000',
        fillOpacity: 0.35
    });

    polygon.setMap(map);    

    var input = /** @type {!HTMLInputElement} */(
        document.getElementById('pac-input'));
        var types = document.getElementById('type-selector');
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);

        var autocomplete = new google.maps.places.Autocomplete(input);
        autocomplete.addListener('place_changed', function() {
        marker.setMap(null);
        var place = autocomplete.getPlace();
        var newBounds = new google.maps.LatLngBounds(bounds.getSouthWest(), bounds.getNorthEast()); //Changed
        // removed newBounds = bounds;
          if (!place.geometry) {
                        geocodeAddress(input.value);//Added on 27/09/2016          
            //window.alert("Autocomplete's returned place contains no geometry");
            return;
          };
          marker.setPosition(place.geometry.location);
          marker.setMap(map);
          newBounds.extend(place.geometry.location);
          map.fitBounds(newBounds);
          if (google.maps.geometry.poly.containsLocation(place.geometry.location, polygon)){
            alert('The area contains the address');  
          } else {
            alert('The address is outside of the area.');  
          };
       });
}

//Added on 27/09/2016
//*************************
function geocodeAddress(addr) {
    geocoder.geocode({'address': addr}, function(results, status) {
      if (status === 'OK') {
        var newBounds = new google.maps.LatLngBounds(bounds.getSouthWest(), bounds.getNorthEast());
          marker.setPosition(results[0].geometry.location);
          marker.setMap(map);
          newBounds.extend(results[0].geometry.location);
          map.fitBounds(newBounds);
          if (google.maps.geometry.poly.containsLocation(results[0].geometry.location, polygon)){
            alert('The area contains the address');  
          } else {
            alert('The address is outside of the area.');  
          };
      } else {
        alert('Geocode was not successful for the following reason: ' + status);
      }
    });
}; 
//*************************

var center = new google.maps.LatLng(41.3899621, 2.1469796);
var area= [
{lat: 41.3749971 , lng: 2.1669979},
{lat: 41.3749569 , lng: 2.1683179},
{lat: 41.3759391 , lng: 2.1690059},
{lat: 41.3780967 , lng: 2.1652293},
{lat: 41.3777424 , lng: 2.1645641},
{lat: 41.380383 , lng: 2.1611738},
{lat: 41.3820333 , lng: 2.1634162},
{lat: 41.3837962 , lng: 2.1614313},
{lat: 41.3956283 , lng: 2.1772671},
{lat: 41.4000548 , lng: 2.1715379},
{lat: 41.3973829 , lng: 2.16156},
{lat: 41.3970609 , lng: 2.1603155},
{lat: 41.3981555 , lng: 2.158041},
{lat: 41.3990569 , lng: 2.1534061},
{lat: 41.400924 , lng: 2.1511316},
{lat: 41.4019541 , lng: 2.1492863},
{lat: 41.4015678 , lng: 2.1472263},
{lat: 41.400087 , lng: 2.1439648},
{lat: 41.4014068 , lng: 2.1419048},
{lat: 41.3997651 , lng: 2.1375704},
{lat: 41.3980911 , lng: 2.1330643},
{lat: 41.3957088 , lng: 2.1283007},
{lat: 41.3930689 , lng: 2.1241379},
{lat: 41.3883039 , lng: 2.1270561},
{lat: 41.3882556 , lng: 2.128129},
{lat: 41.3857442 , lng: 2.1296847},
{lat: 41.3831039 , lng: 2.130897},
{lat: 41.3805882 , lng: 2.1322328},
{lat: 41.3769615 , lng: 2.1339547},
{lat: 41.3761192 , lng: 2.1343651},
{lat: 41.3753413 , lng: 2.1350651},
{lat: 41.3751301 , lng: 2.1405369},
{lat: 41.3750193 , lng: 2.1458101},
{lat: 41.3747598 , lng: 2.1521402},
{lat: 41.374651 , lng: 2.1585345},
{lat: 41.3746349 , lng: 2.1606589},
{lat: 41.3747476 , lng: 2.1653795},
{lat: 41.3749971, lng: 2.1669979}
];

但我不知道如何编写处理所有三个多边形的逻辑。

我构建了三个多边形here

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

下面的代码将警告该地址是否在任何给定的多边形内。

(用您的Google Key替换YOUR_GOOGLE_KEY在index.html上)

index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <link href="index.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <input id="js-input" class="map__input" type="text" placeholder="Enter a location">
    <div id="js-map" class="map"></div>

    <script src="index.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?libraries=places&&key=YOUR_GOOGLE_KEY&callback=initMap" async defer></script>
  </body>
</html>

index.css

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map {
  height: 100%;
  z-index: 1;
}


.map__input {
  background-color: #fff;
  font-family: Roboto;
  font-size: 15px;
  font-weight: 300;
  margin-left: 12px;
  padding: 0 11px 0 13px;
  text-overflow: ellipsis;
  width: 280px;
  margin-top: 10px;
  border: 1px solid transparent;
  border-radius: 2px 0 0 2px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  height: 32px;
  outline: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  position: absolute;
  top: 50px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
}

index.js

const myPolygons = [
  {
    name: 'Yellow Area',
    path: [ // You have to changes those values with lats and lngs of your polygon
      { lat: 11.0104601, lng: -74.8078690 },
      { lat: 11.0034337, lng: -74.7891669 },
      { lat: 11.022699, lng: -74.80161799 },
    ],
    geodesic: true,
    strokeColor: '#FFd000',
    strokeOpacity: 1.0,
    strokeWeight: 4,
    fillColor: '#FFd000',
    fillOpacity: 0.35
  },
  {
    name: 'Blue Area',
    path: [ // You have to changes those values with lats and lngs of your polygon
      { lat: 11.0194794, lng: -74.8504209 },
      { lat: 11.0131404, lng: -74.8276712 },
      { lat: 10.9946794, lng: -74.8395515 },
    ],
    geodesic: true,
    strokeColor: 'blue',
    strokeOpacity: 1.0,
    strokeWeight: 4,
    fillColor: 'blue',
    fillOpacity: 0.35
  },
  {
    name: 'Green Area',
    path: [ // You have to changes those values with lats and lngs of your polygon
      { lat: 10.9772761, lng: -74.8134354 },
      { lat: 10.9933967, lng: -74.8183852 },
      { lat: 10.987963, lng: -74.78883119 },
    ],
    geodesic: true,
    strokeColor: 'green',
    strokeOpacity: 1.0,
    strokeWeight: 4,
    fillColor: 'green',
    fillOpacity: 0.35
  },
];

function initMap() {
  let map;
  let marker;

  const createMap = ({ latitude, longitude, polygons, mapId, inputId }) => {
    const center = new google.maps.LatLng(latitude, longitude);

    map = new google.maps.Map(document.getElementById(mapId), { center, zoom: 14, scaleControl: true });

    marker = new google.maps.Marker({ position: center });

    const createGooglePolygons = ({ name, ...polygon }) => {
      const newPolygon = new google.maps.Polygon(polygon);
      newPolygon.setMap(map);

      return { name, polygon: newPolygon };
    }

    const googlePolygons = polygons.map(createGooglePolygons);

    const input = document.getElementById(inputId);

    const autocomplete = new google.maps.places.Autocomplete(input);

    const onAutocompleteChange = () => {
      const place = autocomplete.getPlace();
      const location = place.geometry.location;
      const poly = google.maps.geometry.poly;

      if (!place.geometry) return alert("Autocomplete's returned place contains no geometry");

      marker.setPosition(location);
      marker.setMap(map);

      const isLocationInsidePolygon = ({ polygon }) => poly.containsLocation(location, polygon);

      const matchedPolygon = googlePolygons.find(isLocationInsidePolygon);

      if (!matchedPolygon) return alert('The address does not match any valid area');

      alert(`The ${matchedPolygon.name} contains the address`);
    };

    autocomplete.addListener('place_changed', onAutocompleteChange);
  }

  createMap({
    latitude: 10.9939751, //Put your origin latitude here
    longitude: -74.8069332, //Put your origin longitude here
    polygons: myPolygons,
    mapId: 'js-map',
    inputId: 'js-input'
  })
};

window.onload = initMap;


答案 1 :(得分:0)

您只需要单独定义多边形并更改逻辑以测试位置是在每个多边形内还是两者中。我不熟悉javascript,但这里有一个使用你应该让你开始的代码的例子(也许更熟悉的人会整理它):

var map;
var marker;
var polygon;
var bounds;
window.onload = initMap;
function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: center,
        zoom: 14,
        scaleControl: true
    });
    bounds = new google.maps.LatLngBounds();
    google.maps.event.addListenerOnce(map, 'tilesloaded', function(evt) { 
        bounds = map.getBounds();
    });
        marker = new google.maps.Marker({
            position: center
        });
        polygon1 = new google.maps.Polygon({
        path: area1,
        geodesic: true,
        strokeColor: '#FFd000',
        strokeOpacity: 1.0,
        strokeWeight: 4,
        fillColor: '#FFd000',
        fillOpacity: 0.35
    });
        polygon2 = new google.maps.Polygon({
        path: area2,
        geodesic: true,
        strokeColor: '#00ffe1',
        strokeOpacity: 1.0,
        strokeWeight: 4,
        fillColor: '#00ffe1',
        fillOpacity: 0.35
    });

    polygon1.setMap(map);   
  polygon2.setMap(map);

    var input = /** @type {!HTMLInputElement} */(
        document.getElementById('pac-input'));
        var types = document.getElementById('type-selector');
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);

        var autocomplete = new google.maps.places.Autocomplete(input);
        autocomplete.addListener('place_changed', function() {
        marker.setMap(null);
        var place = autocomplete.getPlace();
        var newBounds = new google.maps.LatLngBounds();
        newBounds = bounds;
          if (!place.geometry) {
            window.alert("Autocomplete's returned place contains no geometry");
            return;
          };
          marker.setPosition(place.geometry.location);
          marker.setMap(map);
          newBounds.extend(place.geometry.location);
          map.fitBounds(newBounds);
          if (google.maps.geometry.poly.containsLocation(place.geometry.location, polygon1)){
            if (google.maps.geometry.poly.containsLocation(place.geometry.location, polygon2)){
            alert('The address is inside polygon1 and 2');  
          } else {
            alert('The address is inside polygon1');  
          }  
          } else {
          if (google.maps.geometry.poly.containsLocation(place.geometry.location, polygon2)){
            alert('The address is inside polygon2');  
          } else {
            alert('The address is outside of the area.');  
          };
          }
       });
}

var center = new google.maps.LatLng(41.3899621, 2.1469796);
var area1= [
{lat: 41.3749971 , lng: 2.1669979},
{lat: 41.3749569 , lng: 2.1683179},
{lat: 41.3759391 , lng: 2.1690059},
{lat: 41.3780967 , lng: 2.1652293},
{lat: 41.3777424 , lng: 2.1645641},
{lat: 41.380383 , lng: 2.1611738},
{lat: 41.3820333 , lng: 2.1634162},
{lat: 41.3837962 , lng: 2.1614313},
{lat: 41.3956283 , lng: 2.1772671},
{lat: 41.4000548 , lng: 2.1715379},
{lat: 41.3973829 , lng: 2.16156},
{lat: 41.3970609 , lng: 2.1603155},
{lat: 41.3981555 , lng: 2.158041},
{lat: 41.3990569 , lng: 2.1534061},
{lat: 41.400924 , lng: 2.1511316},
{lat: 41.4019541 , lng: 2.1492863},
{lat: 41.4015678 , lng: 2.1472263}];
var area2= [
{lat: 41.3973829 , lng: 2.16156},
{lat: 41.3970609 , lng: 2.1603155},
{lat: 41.3981555 , lng: 2.158041},
{lat: 41.3990569 , lng: 2.1534061},
{lat: 41.400924 , lng: 2.1511316},
{lat: 41.4019541 , lng: 2.1492863},
{lat: 41.4015678 , lng: 2.1472263},
{lat: 41.400087 , lng: 2.1439648},
{lat: 41.4014068 , lng: 2.1419048},
{lat: 41.3997651 , lng: 2.1375704},
{lat: 41.3980911 , lng: 2.1330643},
{lat: 41.3957088 , lng: 2.1283007},
{lat: 41.3930689 , lng: 2.1241379},
{lat: 41.3883039 , lng: 2.1270561},
{lat: 41.3882556 , lng: 2.128129},
{lat: 41.3857442 , lng: 2.1296847},
{lat: 41.3831039 , lng: 2.130897},
{lat: 41.3805882 , lng: 2.1322328},
{lat: 41.3769615 , lng: 2.1339547},
{lat: 41.3761192 , lng: 2.1343651},
{lat: 41.3753413 , lng: 2.1350651},
{lat: 41.3751301 , lng: 2.1405369},
{lat: 41.3750193 , lng: 2.1458101},
{lat: 41.3747598 , lng: 2.1521402},
{lat: 41.374651 , lng: 2.1585345},
{lat: 41.3746349 , lng: 2.1606589},
{lat: 41.3747476 , lng: 2.1653795},
{lat: 41.3749971, lng: 2.1669979}
];