Toni Michel Caubet
Toni Michel Caubet

Reputation: 20163

computeDistanceBetween seems not to calculate right

After user draws a circle on the gmaps, I do being lastShape the object:

var drawingManager;
		var lastShape;
		var map;
		var markers = [];
		var timeout;
		var timeoutwait = 500;
		function initialize() {
		    map = new google.maps.Map(document.getElementById('gmap'), {
		        zoom: 3,
		        center: new google.maps.LatLng(40.463667, -3.749220),
		        mapTypeId: google.maps.MapTypeId.ROADMAP,
		        disableDefaultUI: true,
		        zoomControl: true
		    });
		    var shapeOptions = {
		        strokeWeight: 1,
		        strokeOpacity: 1,
		        fillOpacity: 0.2,
		        editable: true,
		        draggable: true,
		        clickable: true,
		        strokeColor: '#D60056',
		        fillColor: '#D60056'
		    };
		    var shapeOptionsCircle = {
		        strokeWeight: 1,
		        strokeOpacity: 1,
		        fillOpacity: 0.2,
		        editable: true,
		        draggable: true,
		        clickable: false,
		        strokeColor: '#D60056',
		        fillColor: '#D60056'
		    };
		    drawingManager = new google.maps.drawing.DrawingManager({
		        drawingMode: null,
		        drawingControlOptions: {
		            drawingModes: [google.maps.drawing.OverlayType.CIRCLE, 			google.maps.drawing.OverlayType.RECTANGLE]
		        },
		        rectangleOptions: shapeOptions,
		        circleOptions: shapeOptionsCircle,
		        Options: shapeOptions,
		        map: map
		    });
		    google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
		        if (lastShape != undefined) {
		            lastShape.setMap(null);
		        }
		        if (shift_draw == false) {
		            drawingManager.setDrawingMode(null);
		        }
		        lastShape = e.overlay;
		        lastShape.type = e.type;			
		        lastBounds = lastShape.getBounds();
		        clearTimeout(timeout);
		        drawHotels();
		        
		        lastShape.addListener('bounds_changed', function () {
		        	lastBounds = lastShape.getBounds();
		            clearTimeout(timeout);
		            timeout = setTimeout(drawHotels, timeoutwait);
		        });
		        lastShape.addListener('radius_changed', function() {
		          lastBounds = lastShape.getBounds();
		          clearTimeout(timeout);
		          timeout = setTimeout(drawHotels, timeoutwait);
		        });
		    });
		    var shift_draw = false;			    
		}
		google.maps.event.addDomListener(window, 'load', initialize);
		
		
		function drawHotels() {
			if ( markers != undefined) {
				for (var i = 0; i < markers.length; i++ ) {
				    markers[i].setMap(null);
				}
				markers.length = 0;
			}
			var json = [
			   		    {"id":8585885,"hotel":"Hotel name", "lat" : "1.3", "long" : "1.33"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "-1.3", "long" : "1.33"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "42.5000", "long" : "1.5000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "24.0000", "long" : "54.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "17.0500", "long" : "-61.8000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "18.2500", "long" : "-63.1667"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "24.0000", "long" : "54.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "41.0000", "long" : "20.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "40.0000", "long" : "45.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "12.2500", "long" : "-68.7500"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "-12.5000", "long" : "18.5000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "35.0000", "long" : "105.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "-90.0000", "long" : "0.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "34.0000", "long" : "-64.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "-14.3333", "long" : "-170.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "47.3333", "long" : "13.3333"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "-27.0000", "long" : "133.0000"},
						{"id":8585886,"hotel":"Hotel name 1", "lat" : "12.5000", "long" : "-69.9667"}
					   ];
			
			var hotels = eval(json);
			lastBounds = lastShape.getBounds();
			for ( var i = 0; i<hotels.length; i++ ) {
				var hotel = hotels[i];
				if ( lastBounds.contains(  new google.maps.LatLng(hotel.lat, hotel.long) ) ) {
					 
					var m1 = new google.maps.Marker({
					    position: new google.maps.LatLng(hotel.lat, hotel.long),
					    map: map,
					    title: hotel.name
					});
					markers.push(m1);
				} else if ( lastShape.type == 'circle') {
					google.maps.Circle.prototype.contains = function(latLng) {
					  var condition = this.getBounds().contains(latLng) && google.maps.geometry.spherical.computeDistanceBetween(this.getCenter(), latLng) <= this.getRadius();
					  if ( condition ) {
					  	var m1 = new google.maps.Marker({
					  	    position: new google.maps.LatLng(hotel.lat, hotel.long),
					  	    map: map,
					  	    title: hotel.name
					  	});
					  	markers.push(m1);
					  }
					}
				}
			}
		}
.google-maps {
  height:0;
  position:relative;
  padding-bottom: 50%;
}
#gmap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height:100%
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
	<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script>

<div class="">
					<div class="google-maps"><div id="gmap"></div></div>
				</div>

The thing it seems to add the marker even if it's not in the circle (It is tough in the square that contains it)

Any idea what am I missing?

Upvotes: 0

Views: 167

Answers (1)

geocodezip
geocodezip

Reputation: 161334

Your code is always executing the first path of the if statement:

if ( lastBounds.contains(  new google.maps.LatLng(hotel.lat, hotel.long) ) ) {

  var m1 = new google.maps.Marker({
    position: new google.maps.LatLng(hotel.lat, hotel.long),
    map: map,
    title: hotel.name
  });
  markers.push(m1);
}
  1. Change your code to evaluate whether or not the hotel is in a circle first (if it is inside the circle it will be inside the bounds, but not necessarily the opposite).
  2. add the .contains function to the google.maps.Circle outside of the if statement and use it in the test.

add the function:

google.maps.Circle.prototype.contains = function (latLng) {
    var condition = this.getBounds().contains(latLng) && google.maps.geometry.spherical.computeDistanceBetween(this.getCenter(), latLng) <= this.getRadius();
    return condition;
}

Then use it in the test:

lastBounds = lastShape.getBounds();
for (var i = 0; i < hotels.length; i++) {
    var hotel = hotels[i];
    if (lastShape.type == 'circle') {
        if (lastShape.contains(new google.maps.LatLng(hotel.lat, hotel.long))) {
            var m1 = new google.maps.Marker({
                position: new google.maps.LatLng(hotel.lat, hotel.long),
                map: map,
                title: hotel.name
            });
            markers.push(m1);
        }
    } else if (lastBounds.contains(new google.maps.LatLng(hotel.lat, hotel.long))) {

        var m1 = new google.maps.Marker({
            position: new google.maps.LatLng(hotel.lat, hotel.long),
            map: map,
            title: hotel.name
        });
        markers.push(m1);
    }
}

proof of concept fiddle

code snippet:

var drawingManager;
var lastShape;
var map;
var markers = [];
var timeout;
var timeoutwait = 500;

function initialize() {
  map = new google.maps.Map(document.getElementById('gmap'), {
    zoom: 3,
    center: new google.maps.LatLng(40.463667, -3.749220),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    disableDefaultUI: true,
    zoomControl: true
  });
  var shapeOptions = {
    strokeWeight: 1,
    strokeOpacity: 1,
    fillOpacity: 0.2,
    editable: true,
    draggable: true,
    clickable: true,
    strokeColor: '#D60056',
    fillColor: '#D60056'
  };
  var shapeOptionsCircle = {
    strokeWeight: 1,
    strokeOpacity: 1,
    fillOpacity: 0.2,
    editable: true,
    draggable: true,
    clickable: false,
    strokeColor: '#D60056',
    fillColor: '#D60056'
  };
  drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: null,
    drawingControlOptions: {
      drawingModes: [google.maps.drawing.OverlayType.CIRCLE, google.maps.drawing.OverlayType.RECTANGLE]
    },
    rectangleOptions: shapeOptions,
    circleOptions: shapeOptionsCircle,
    Options: shapeOptions,
    map: map
  });
  google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    if (lastShape != undefined) {
      lastShape.setMap(null);
    }
    if (shift_draw == false) {
      drawingManager.setDrawingMode(null);
    }
    lastShape = e.overlay;
    lastShape.type = e.type;
    lastBounds = lastShape.getBounds();
    clearTimeout(timeout);
    drawHotels();

    lastShape.addListener('bounds_changed', function() {
      lastBounds = lastShape.getBounds();
      clearTimeout(timeout);
      timeout = setTimeout(drawHotels, timeoutwait);
    });
    lastShape.addListener('radius_changed', function() {
      lastBounds = lastShape.getBounds();
      clearTimeout(timeout);
      timeout = setTimeout(drawHotels, timeoutwait);
    });
  });
  var shift_draw = false;
}
google.maps.event.addDomListener(window, 'load', initialize);


function drawHotels() {
  if (markers != undefined) {
    for (var i = 0; i < markers.length; i++) {
      markers[i].setMap(null);
    }
    markers.length = 0;
  }
  var json = [{
    "id": 8585885,
    "hotel": "Hotel name",
    "lat": "1.3",
    "long": "1.33"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "-1.3",
    "long": "1.33"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "42.5000",
    "long": "1.5000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "24.0000",
    "long": "54.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "17.0500",
    "long": "-61.8000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "18.2500",
    "long": "-63.1667"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "24.0000",
    "long": "54.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "41.0000",
    "long": "20.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "40.0000",
    "long": "45.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "12.2500",
    "long": "-68.7500"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "-12.5000",
    "long": "18.5000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "35.0000",
    "long": "105.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "-90.0000",
    "long": "0.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "34.0000",
    "long": "-64.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "-14.3333",
    "long": "-170.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "47.3333",
    "long": "13.3333"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "-27.0000",
    "long": "133.0000"
  }, {
    "id": 8585886,
    "hotel": "Hotel name 1",
    "lat": "12.5000",
    "long": "-69.9667"
  }];

  var hotels = eval(json);
  lastBounds = lastShape.getBounds();
  for (var i = 0; i < hotels.length; i++) {
    var hotel = hotels[i];
    if (lastShape.type == 'circle') {
      if (lastShape.contains(new google.maps.LatLng(hotel.lat, hotel.long))) {
        var m1 = new google.maps.Marker({
          position: new google.maps.LatLng(hotel.lat, hotel.long),
          map: map,
          title: hotel.name
        });
        markers.push(m1);
      }
    } else if (lastBounds.contains(new google.maps.LatLng(hotel.lat, hotel.long))) {

      var m1 = new google.maps.Marker({
        position: new google.maps.LatLng(hotel.lat, hotel.long),
        map: map,
        title: hotel.name
      });
      markers.push(m1);
    }
  }
}
google.maps.Circle.prototype.contains = function(latLng) {
  var condition = this.getBounds().contains(latLng) && google.maps.geometry.spherical.computeDistanceBetween(this.getCenter(), latLng) <= this.getRadius();
  return condition;
}
.google-maps {
  height: 0;
  position: relative;
  padding-bottom: 50%;
}
#gmap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%
}
<script src="https://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script>
<div class="">
  <div class="google-maps">
    <div id="gmap"></div>
  </div>
</div>

Upvotes: 1

Related Questions