Google maps JS API v3: get markers in circle with containsLocation() doesn't work - why?

前端 未结 2 1427
北海茫月
北海茫月 2020-12-09 19:45

I\'m trying to get all markers within a given radius (google.maps.Circle) by using google.maps.geometry.poly.containsLocation as recommended here,

相关标签:
2条回答
  • 2020-12-09 20:17

    The solution suggested by @Sumuray will create points also outside of the circle, but still in the bounds (square/rectangle) of the circle.

    using the method he suggested:

    // if HTML DOM Element that contains the map is found...
    if (document.getElementById('map-canvas')) {
    
      // Coordinates to center the map
      var myLatlng = new google.maps.LatLng(52.525595, 13.393085);
    
      // Other options for the map, pretty much selfexplanatory
      var mapOptions = {
        zoom: 14,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };
    
      // Attach a map to the DOM Element, with the defined settings
      var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
      var marker = new google.maps.Marker({
        map: map,
        position: myLatlng
      });
      var circle = new google.maps.Circle({
        map: map,
        radius: 1000,
        fillColor: '#AA0000',
        fillOpacity: 0.15,
        strokeWeight: 0.9,
        position: myLatlng
      });
      circle.bindTo('center', marker, 'position');
    
      var circleBounds = circle.getBounds();
      for (var i = 0; i < 50; i++) {
        var marker = generateMarkerInBoundries(circleBounds);
        marker.setMap(map);
      }
    
      function generateMarkerInBoundries(boundries) {
        var marker = new google.maps.Marker();
        marker.setPosition(new google.maps.LatLng(0, 0));
        while (!boundries.contains(marker.position)) {
          var
            ne = boundries.getNorthEast(),
            sw = boundries.getSouthWest(),
            lat = randomFloat(ne.lat(), sw.lat()),
            lng = randomFloat(ne.lng(), sw.lng());
          marker.setPosition(new google.maps.LatLng(lat, lng))
        }
        return marker;
      }
    
      function randomFloat(min, max) {
        return Math.random() * (max - min) + min;
      }
    
    }
    #map-canvas {
      height: 500px;
      width: 500px;
      border: 3px solid black;
    }
    <div id="map-canvas"></div>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false" type="text/javascript"></script>

    You can clearly see that some of the markers are outside of the circle, but within the bounding box of the circle.

    To fix the issue, you could use the geometry library and add a method to check if the point is within the circle's radius

    // if HTML DOM Element that contains the map is found...
    if (document.getElementById('map-canvas')) {
    
      // Coordinates to center the map
      var myLatlng = new google.maps.LatLng(52.525595, 13.393085);
    
      // Other options for the map, pretty much selfexplanatory
      var mapOptions = {
        zoom: 14,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };
    
      // Attach a map to the DOM Element, with the defined settings
      var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
      var marker = new google.maps.Marker({
        map: map,
        position: myLatlng
      });
      var circle = new google.maps.Circle({
        map: map,
        radius: 1000,
        fillColor: '#AA0000',
        fillOpacity: 0.15,
        strokeWeight: 0.9,
        position: myLatlng
      });
      circle.bindTo('center', marker, 'position');
    
      var circleBounds = circle.getBounds();
      for (var i = 0; i < 50; i++) {
        var marker = generateMarkerInCircleRadius(circleBounds);
        marker.setMap(map);
      }
    
      function generateMarkerInCircleRadius(boundries) {
        var marker = new google.maps.Marker();
        marker.setPosition(new google.maps.LatLng(0, 0));
        while (!isMarkerInRadius(marker, circle)) {
          var
            ne = boundries.getNorthEast(),
            sw = boundries.getSouthWest(),
            lat = randomFloat(ne.lat(), sw.lat()),
            lng = randomFloat(ne.lng(), sw.lng());
          marker.setPosition(new google.maps.LatLng(lat, lng))
        }
        return marker;
      }
    
      function randomFloat(min, max) {
        return Math.random() * (max - min) + min;
      }
    
      function isMarkerInRadius(marker, circle) {
        return google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), circle.getCenter()) <= circle.getRadius();
      }
    }
    #map-canvas {
      height: 500px;
      width: 500px;
      border: 3px solid black;
    }
    <div id="map-canvas"></div>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry&sensor=false" type="text/javascript"></script>

    0 讨论(0)
  • 2020-12-09 20:24

    containsLocation is a method on google.maps.Polygon objects not google.maps.Circle objects

    To determine if a marker is within a circle use google.maps.geometry.spherical.computeDistanceBetween

    if (google.maps.geometry.spherical.computeDistanceBetween(randomMarkers[i].marker.getPosition(), searchArea.getCenter()) <= searchArea.getRadius()) {
        console.log('=> is in searchArea');
    } else {
        console.log('=> is NOT in searchArea');
    }
    

    working fiddle

    working code snippet:

    var map,
      searchArea,
      searchAreaMarker,
      searchAreaRadius = 1000, // metres
      startLat = 40.782827,
      startLng = -73.966167;
    
    function init() {
      var startLatLng = new google.maps.LatLng(startLat, startLng);
    
      map = new google.maps.Map(document.getElementById('map-canvas'), {
        center: startLatLng,
        zoom: 12
      });
    
      searchArea = new google.maps.Circle({
        strokeColor: '#FF0000',
        strokeOpacity: 0.5,
        strokeWeight: 2,
        fillColor: '#FF0000',
        fillOpacity: 0.2,
        map: map,
        center: startLatLng,
        radius: searchAreaRadius
      });
    
      searchAreaMarker = new google.maps.Marker({
        position: startLatLng,
        map: map,
        draggable: true,
        animation: google.maps.Animation.DROP,
        title: 'searchAreaMarker'
      });
    
      var randomMarkers = [{
        title: 'Marker 1',
        latLng: new google.maps.LatLng(40.770088, -73.971146)
      }, {
        title: 'Marker 2',
        latLng: new google.maps.LatLng(40.782048, -73.972691)
      }, {
        title: 'Marker 3',
        latLng: new google.maps.LatLng(40.769048, -73.987797)
      }, {
        title: 'Marker 4',
        latLng: new google.maps.LatLng(40.773858, -73.956211)
      }, {
        title: 'Marker 5',
        latLng: new google.maps.LatLng(40.800372, -73.952091)
      }, {
        title: 'Marker 6',
        latLng: new google.maps.LatLng(40.804661, -73.939388)
      }];
    
      for (var i = 0; i < randomMarkers.length; i++) {
        randomMarkers[i].marker = new google.maps.Marker({
          position: randomMarkers[i].latLng,
          map: map,
          title: randomMarkers[i].title
        });
      }
    
      google.maps.event.addListener(searchAreaMarker, 'dragend', function(e) {
        startLatLng = e.latLng;
    
        searchArea.setOptions({
          center: startLatLng
        });
    
        map.panTo(searchAreaMarker.getPosition());
        findMarkersInArea();
      });
      var iwArray = [];
      function findMarkersInArea() {
        // close open infowindows
        for (var i=0; i<iwArray.length; i++) {
          iwArray[i].close();
        }
        iwArray = [];
        // find markers in area
        for (var i = 0; i < randomMarkers.length; i++) {
          console.log('Marker: ' + randomMarkers[i].marker.title + ', position: ' + randomMarkers[i].marker.getPosition());
          console.log("marker["+i+"] posn="+randomMarkers[i].marker.getPosition().toUrlValue(6));
          if (google.maps.geometry.spherical.computeDistanceBetween(randomMarkers[i].marker.getPosition(), searchArea.getCenter()) <= searchArea.getRadius()) {
            console.log('=> is in searchArea');
            var iw = new google.maps.InfoWindow();
            iw.setContent("is in searchArea");
            iw.open(map, randomMarkers[i].marker);
            iwArray.push(iw);
          } else {
            console.log('=> is NOT in searchArea');
            var iw = new google.maps.InfoWindow();
            iw.setContent("outside searchArea");
            iw.open(map, randomMarkers[i].marker);
            iwArray.push(iw);
          }
        }
      }
      // initial config
      findMarkersInArea();
    }
    
    google.maps.event.addDomListener(window, 'load', init);
    html,
    body,
    #map-canvas {
      height: 100%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map-canvas" style="border: 2px solid #3872ac;"></div>

    0 讨论(0)
提交回复
热议问题