Reputation: 6200
I have a Google Map that has multiple circles around multiple points which I've drawn the following way:
for (i = 0; i < markers.length; i++) {
var circle = new google.maps.Circle({
map: map,
radius: parseInt(radius_entry[markers[i][0]]),
fillColor: '#2c3e50',
strokeColor: '#2c3e50',
strokeOpacity: 0
});
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
pinIcon = new google.maps.MarkerImage(
"assets/images/station_maker.png",
null, /* size is determined at runtime */
null, /* origin is 0,0 */
null, /* anchor is bottom center of the scaled image */
new google.maps.Size(21, 34)
);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0],
});
marker.setIcon(pinIcon)
circle.bindTo('center', marker, 'position');
google.maps.event.addListener(circle, 'click', function(ev) { //Placing marker only on clicks inside a circle
placeMarker(ev.latLng);
});
bounds.extend(position);
map.fitBounds(bounds);
}
I have also provided a method for users to search for a location using the places library on the same map which is a very straightforward implementation.
var input = document.getElementById('search-places');
var searchBox = new google.maps.places.SearchBox(input);
google.maps.event.addListener(searchBox, 'places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
However, I want to add a mechanism that checks if the searched place falls within any of the circles drawn earlier. I found this method:
polygon.containsLocation()
https://developers.google.com/maps/documentation/javascript/examples/poly-containsLocation
But this didn't work for circles.
I also found this SO question How to detect if a point is in a Circle? but it deals with only one circle drawn on a map. How do I achieve this scenario?
Upvotes: 0
Views: 2058
Reputation: 59378
You could utilize the following function to determine whether point is located inside a circle:
function circleContainsLocation(point, circle)
{
var radius = circle.getRadius();
var center = circle.getCenter();
return (google.maps.geometry.spherical.computeDistanceBetween(point, center) <= radius)
}
Then to introduce circles
array to store all rendered circles.
And then add the following code to determine whether place is located in circles or not:
for (var i = 0, place; place = places[i]; i++) {
var result = circles.filter(function(c){
if(circleContainsLocation(place.geometry.location,c))
return c;
});
var placeFound = (result.length > 0);
if(placeFound){
console.log('Place is found');
}
}
Complete example
var circles = [];
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: -33.8688, lng: 151.2195 },
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var markers = [
['Sydney',-33.867080, 151.209450,50000],
['Newcastle NSW',-32.927896, 151.768989,10000]
];
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
var circle = new google.maps.Circle({
map: map,
radius: markers[i][3],
fillColor: '#2c3e50',
strokeColor: '#2c3e50',
strokeOpacity: 0
});
circles.push(circle);
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
var marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0],
});
circle.bindTo('center', marker, 'position');
bounds.extend(position);
}
map.fitBounds(bounds);
google.maps.event.addListener(searchBox, 'places_changed', function () {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
var result = circles.filter(function(c){
if(circleContainsLocation(place.geometry.location,c))
return c;
})
var placeFound = (result.length > 0);
if(placeFound){
document.getElementById('output').innerHTML = 'Place is found';
}
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
}
function circleContainsLocation(point, circle)
{
var radius = circle.getRadius();
var center = circle.getCenter();
return (google.maps.geometry.spherical.computeDistanceBetween(point, center) <= radius)
}
html, body {
height: 200px;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
.controls {
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);
}
#pac-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: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div id="map"></div>
<div id="output"/>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initMap"
async defer></script>
Upvotes: 3