Reputation: 27
I am using Google Maps to develop a app using Code Igniter, and I have a big issue with feature of checking if the coordonates of a marker are within the radius of a circle which is stored in my database.
I will try to describe in pseudocode, and sorry I'm a rookie.
Right click-> a circle appears on the google map with a InfoBubble where you complete name, color and circle radius in meters;
Click save-> Using ajax I send the circle center, name, color, etc.
In the AJAX I am storing in the database the information about the circle, but before registering I need to set the number of markers that are found within the radius of the created circle.
I have searched and found this link http://www.movable-type.co.uk/scripts/latlong.html , but my math is not that great.
I need a function that takes the circle, marker coords and radius and that returns true or false if the marker is within the circle or not.
I made something that I found over the net but it does not work
public function arePointsNear($checkPoint, $centerPoint, $km) {
$km = $km * 1000;
$ky = 40000 / 360;
$kx = cos(pi() * $centerPoint->lat / 180.0) * $ky;
$dx = abs($centerPoint->lng - $checkPoint->lng) * $kx;
$dy = abs($centerPoint->lat - $checkPoint->lat) * $ky;
return sqrt($dx * $dx + $dy * $dy) <= $km;
}
Thanks!
Upvotes: 0
Views: 3520
Reputation: 3679
Let me give you code that calculates that in Javascript; all within the Google Maps code, but the function that calculates the distance is just a function, not a service. (I don't know who wrote the function)
Your question is to have a PHP function, right? No doubt you can translate the javascript function to PHP; or you just trust the calculation in javascript and send that result with Ajax.
The code draws a Circle (center = Brussels; radius = 30km) and 4 markers. You can drag them all. Clicking on the button triggers the calculation. I show the result by turning the markers green or red.
(Do you know how to take over from here?)
<style>
#map-canvas {
height: 400px;
margin: 0px;
padding: 0px;
}
</style>
<div id="map-canvas"></div>
<input type="button" id="start" value="Click">
<p>Drag the circle, drag the markers; when you click the button it will calculate if the markers are in the circle</p>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?"></script>
<script>
function initialize() {
// settings
var center = new google.maps.LatLng(50.84546, 4.357112);
var radius_circle = 30000; // 30km
var markerPositions = [
{lat: 50.940749, lng: 4.2033035},
{lat: 50.791671, lng: 4.587825},
{lat: 50.66649, lng: 3.945124},
{lat: 50.429139, lng: 4.813044}
];
var markers=[];
// draw map
var mapOptions = {
center: center,
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var circle = drawCircle(mapOptions.center, radius_circle);
// markers
for (var i=0; i<markerPositions.length; i++) {
markers.push(
new google.maps.Marker({
position: new google.maps.LatLng(markerPositions[i].lat, markerPositions[i].lng),
map: map,
draggable: true
})
);
}
// client clicks on button, we will check for the markers within the circle
google.maps.event.addDomListener(document.getElementById('start'), 'click', function() {
for (var i=0; i<markerPositions.length; i++) {
var distance = calculateDistance(
markers[i].getPosition().lat(),
markers[i].getPosition().lng(),
circle.getCenter().lat(),
circle.getCenter().lng(),
"K"
);
if (distance * 1000 < radius_circle) { // radius is in meter; distance in km
markers[i].setIcon('http://maps.gstatic.com/mapfiles/icon_green.png'); // make or find a better icon
}
else {
markers[i].setIcon('http://maps.gstatic.com/mapfiles/icon.png'); // make or find a better icon
}
}
});
function drawCircle(center, radius) {
return new google.maps.Circle({
strokeColor: '#0000FF',
strokeOpacity: 0.7,
strokeWeight: 1,
fillColor: '#0000FF',
fillOpacity: 0.15,
draggable: true,
map: map,
center: center,
radius: radius
});
}
function calculateDistance(lat1, lon1, lat2, lon2, unit) {
var radlat1 = Math.PI * lat1/180;
var radlat2 = Math.PI * lat2/180;
var radlon1 = Math.PI * lon1/180;
var radlon2 = Math.PI * lon2/180;
var theta = lon1-lon2;
var radtheta = Math.PI * theta/180;
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist);
dist = dist * 180/Math.PI;
dist = dist * 60 * 1.1515;
if (unit=="K") { dist = dist * 1.609344; }
if (unit=="N") { dist = dist * 0.8684; }
return dist;
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Upvotes: 4