Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Maps API containsLocation not working as expected

I am trying to create a property search for a website where users can draw a polygon on a google map, and the relevant properties within the boundaries will be shown.

I have a group of markers created from lat/lng definitions in a database. When the polygon is complete, I loop through the markers and compare to the polygon using containsLocation. If containsLocation returns false, I remove the marker from the map.

Unfortunately, this isn't working - many properties that are a long way outside the polygon are left intact, and I have no idea why. I've included my JS below, and a link to a JSFiddle where you can see this in action:

jQuery(function() {
  map = new google.maps.Map(document.getElementById('search_map'), {
    zoom: 10,
    center: {lat: 53.1877837, lng: -2.890695400000027}
  });

  var markers = [];
  var properties = [
    {"lat":"53.19744","lng":"-2.90324"},{"lat":"53.20113","lng":"-2.88327"},{"lat":"53.19467","lng":"-2.89708"},{"lat":"53.19408","lng":"-2.90420"},{"lat":"53.19122","lng":"-2.86685"},{"lat":"53.19157","lng":"-2.87039"},{"lat":"53.19495","lng":"-2.90185"},{"lat":"53.19912","lng":"-2.90328"},{"lat":"53.19744","lng":"-2.89996"},{"lat":"53.19939","lng":"-2.90310"},{"lat":"53.19955","lng":"-2.90304"},{"lat":"53.18981","lng":"-2.89322"},{"lat":"53.19707","lng":"-2.89818"},{"lat":"53.19246","lng":"-2.86232"},{"lat":"53.19694","lng":"-2.89845"},{"lat":"53.19248","lng":"-2.87886"},{"lat":"53.19393","lng":"-2.90255"},{"lat":"53.19675","lng":"-2.89979"},{"lat":"53.19426","lng":"-2.90188"},{"lat":"53.28044","lng":"-2.89737"},{"lat":"53.27536","lng":"-2.93683"},{"lat":"53.16830","lng":"-3.08807"},{"lat":"53.17966","lng":"-2.90035"},{"lat":"53.27380","lng":"-2.89055"},{"lat":"53.20563","lng":"-2.92282"},{"lat":"53.20092","lng":"-2.89327"},{"lat":"53.19120","lng":"-2.86799"},{"lat":"53.18154","lng":"-2.88894"},{"lat":"53.19474","lng":"-2.88410"},{"lat":"53.19995","lng":"-2.89468"},{"lat":"53.19354","lng":"-2.88157"},{"lat":"53.21982","lng":"-2.88244"},{"lat":"53.20004","lng":"-2.89296"},{"lat":"53.19487","lng":"-2.87742"},{"lat":"53.19640","lng":"-2.88485"},{"lat":"53.22933","lng":"-2.95355"},{"lat":"53.21318","lng":"-2.87070"},{"lat":"53.20609","lng":"-2.92817"},{"lat":"53.19710","lng":"-2.87817"},{"lat":"53.18776","lng":"-2.89100"},{"lat":"53.19487","lng":"-2.87742"},{"lat":"53.17526","lng":"-2.91006"},{"lat":"53.19338","lng":"-2.88320"},{"lat":"53.18978","lng":"-2.86599"},{"lat":"53.19143","lng":"-2.88282"},{"lat":"53.19479","lng":"-2.88436"}
  ];

  for (var i = 0; i < properties.length; i++) {
    var markerPosition = new google.maps.LatLng(parseFloat(properties[i].lat), parseFloat(properties[i].lng));
    var marker = new google.maps.Marker({
      position: markerPosition,
      map: map
    });

    // Add it to the array
    markers.push(marker);
  }

  var drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: google.maps.drawing.OverlayType.POLYGON,
    drawingControl: false,
    drawingControlOptions: {
      drawingModes: ['polygon']
    }
  });
  drawingManager.setMap(map);

  google.maps.event.addListener(drawingManager, 'overlaycomplete', function(polygon) {
    for (var i = 0; i < markers.length; i++) {
      if (!google.maps.geometry.poly.containsLocation(markers[i].position, polygon.overlay)) {
        markers[i].setMap(null);
        markers.splice(i, 1);
      }
    }
    jQuery('#result').text(markers.length + ' properties found');
  });
 });

https://jsfiddle.net/mwttowd8/21/

I have stripped my code right back to this and it still isn't returning the correct markers. I've also tried using lat/lng objects instead of google maps LatLng objects and still no luck - I'm not sure what else to try!

like image 955
jtrich Avatar asked Sep 11 '25 18:09

jtrich


1 Answers

I edited your listener to the following:

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(polygon) {
var locationsFound = 0;
for (var i = 0; i < markers.length; i++) {
  if (!google.maps.geometry.poly.containsLocation(markers[i].position, polygon.overlay)) {
    markers[i].setMap(null);
    markers.splice(i, 0);
  } else if (google.maps.geometry.poly.containsLocation(markers[i].position, polygon.overlay)){
        locationsFound ++;
  }
}
$('#result').text(locationsFound + ' properties found');
});

It is a bit of a hack to get the number of properties unfortunately. If you need to do anything with the markers (i.e. get location) I'm not sure how you would proceed.

The array splice for some reason does not work:

markers.splice(i, 1); and when I changed it to: markers.splice(i, 0); or removed it completely the markers all disappeared correctly

Edit: A slightly better solution that stores the markers that are present in the polygon as locArray

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(polygon) {
var locArray=[];
for (var i = 0; i < markers.length; i++) {
  if (!google.maps.geometry.poly.containsLocation(markers[i].position, polygon.overlay)) {
        markers[i].setMap(null);

  } else if (google.maps.geometry.poly.containsLocation(markers[i].position, polygon.overlay)){
        locArray.push(markers[i]);
  }
}
$('#result').text(locArray.length + ' properties found');
});
like image 76
fez Avatar answered Sep 14 '25 09:09

fez