Reputation: 63619
I want to use Google Maps API to draw an area around a particular point on the map where a person can walk to within X minutes. In other words, how can you find all the places one can travel from a given point within a user defined period of time?
Upvotes: 14
Views: 683
Reputation: 12592
Here is ready-to-copy solution: http://maps.forum.nu/gm_driving_radius.html#. An alternative near perfect solution is to use a space-filling-curve or a spatial-index. A sfc reduce the 2d complexity to a 1d complexity and it's an approximation algorithm not a heuristic. With a sfc it should be a guarantee of 1/4 to find all the points in the euklidian space.
Upvotes: 4
Reputation: 1925
Update: Have a play with this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps Geometry</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 1000px; height: 800px"></div>
<script type="text/javascript">
function CalculateDistanceBetweenTwoPoint(lat1, lon1, lat2, lon2) {
var R = 6371; // km
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var lat1 = lat1.toRad();
var lat2 = lat2.toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d * 1000;
}
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}
google.maps.LatLng.prototype.destinationPoint = function(brng, dist) {
dist = dist / 6371;
brng = brng.toRad();
var lat1 = this.lat().toRad(), lon1 = this.lng().toRad();
var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) +
Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) *
Math.cos(lat1),
Math.cos(dist) - Math.sin(lat1) *
Math.sin(lat2));
if (isNaN(lat2) || isNaN(lon2)) return null;
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
var pointA = new google.maps.LatLng(40.80, -74.00); // Circle center
var radius = 1; // 10km
var mapOpt = {
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: pointA,
zoom: 17
};
var map = new google.maps.Map(document.getElementById("map"), mapOpt);
// Draw the circle
new google.maps.Circle({
center: pointA,
radius: radius * 1000, // Convert to meters
fillColor: '#FF0000',
fillOpacity: 0.2,
map: map
});
// Show marker at circle center
new google.maps.Marker({
position: pointA,
map: map
});
var i = 0;
setTimeout(LoopThroughPoints, 1000);
var triangleCoords = [];
function LoopThroughPoints() {
var directionsService = new google.maps.DirectionsService();
var destination = pointA.destinationPoint(i, radius);
var request = {
origin: pointA,
destination: destination,
travelMode: google.maps.TravelMode["WALKING"]
};
console.log(request);
directionsService.route(request, function(response, status) {
console.log(response);
if (status == google.maps.DirectionsStatus.OK) {
var cumulativeDistance = 0;
new google.maps.Marker({
position: destination,
map: map
});
loopy: for(var i = 0; i < response.routes[0].overview_path.length; i++)
{
var path = response.routes[0].overview_path[i];
var pathNext = response.routes[0].overview_path[i+1];
cumulativeDistance += CalculateDistanceBetweenTwoPoint(path.Oa, path.Pa, pathNext.Oa, pathNext.Pa);
if(cumulativeDistance >= 500) {
triangleCoords.push(new google.maps.LatLng(path.Oa, path.Pa));
break loopy;
}
}
}
});
i = i + 10;
if(i!=360) {
setTimeout(LoopThroughPoints, 10);
} else {
bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
}
}
</script>
</body>
</html>
Just a quick look and some starters, though someone may be able to provide some better solutions.
There doesn't seem to be a way to get all the roads coming off a certain point with the Maps API.
Distance: Time taken is a hard one, I would try and calculate it in meters. So according to http://answers.yahoo.com/question/index?qid=1006021202308 (scientific i know…) 5km/h or 500m in 6 minutes.
My method would be:
This could also be helpful:
How to move a marker 100 meters with coordinates
Some more! Google Maps: Given a point, how to find all points at a given road distance?
This shows how to find all the points and then snap to the nearest street
Upvotes: 1