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

I'm trying to get all markers within a given radius (google.maps.Circle) by using google.maps.geometry.poly.containsLocation as recommended here, but I get an error: TypeError: e is undefined.

Snippet:

// ...
if (google.maps.geometry.poly.containsLocation(randomMarkers[i].marker.getPosition(), searchArea)) {
    console.log('=> is in searchArea');
} else {
    console.log('=> is NOT in searchArea');
}
// ...

Full code:

<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
  html, body, #map-canvas {
    height: 100%;
    margin: 0px;
    padding: 0px
  }
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
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());

        // find markers in area
        for (var i = 0; i < randomMarkers.length; i++) {
            console.log('Marker: ' + randomMarkers[i].marker.title + ', position: ' + randomMarkers[i].marker.getPosition()); 

            // ---------- Here comes the error: 
            // TypeError: e is undefined
            if (google.maps.geometry.poly.containsLocation(randomMarkers[i].marker.getPosition(), searchArea)) {
                console.log('=> is in searchArea');
            } else {
                console.log('=> is NOT in searchArea');
            }
        }
    });
}

google.maps.event.addDomListener(window, 'load', init);
</script>

Answers


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());

    // find markers in area
    for (var i = 0; i < randomMarkers.length; i++) {
      console.log('Marker: ' + randomMarkers[i].marker.title + ', position: ' + randomMarkers[i].marker.getPosition());

      // ---------- Here comes the error: 
      // TypeError: e is undefined
      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');
      }
    }
  });
}

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"></script>
<div id="map-canvas" style="border: 2px solid #3872ac;"></div>

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>

Use the native getBounds(); method. Most people believe that this method can be used for rectangles only, but they are wrong. It belongs to the LatLngBounds Constructor and delivers the most painless possibility to check if a marker is inside a (for e.g.) circle (or polylines, rectangulars) or not.

enter link description here

enter image description here


Need Your Help

How can I print to the console in color in a cross-platform manner?

linux macos console colors

How can I output colored text using "printf" on both Mac OS X and Linux?

How to solve "Batch update returned unexpected row count from update; actual row count: 0; expected: 1" problem?

nhibernate fluent-nhibernate automapping

Getting this everytime I attempt to CREATE a particular entity ... just want to know how I should go about figuring out the cause.