Vamos a necesitar un método que devuelve el punto de destino cuando se le da un rumbo y la distancia recorrida desde un punto de origen. Afortunadamente, hay una muy buena implementación de JavaScript por parte de Chris Veness al Calculate distance, bearing and more between Latitude/Longitude points.
Lo siguiente ha sido adaptado para trabajar con la clase google.maps.LatLng
:
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());
}
sólo tendría que utilizar del modo siguiente:
var pointA = new google.maps.LatLng(25.48, -71.26);
var radiusInKm = 10;
var pointB = pointA.destinationPoint(90, radiusInKm);
Aquí es un ejemplo completo utilizando Google Maps API v3:
<!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: 400px; height: 300px"></div>
<script type="text/javascript">
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.70, -74.00); // Circle center
var radius = 10; // 10km
var mapOpt = {
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: pointA,
zoom: 10
};
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
});
// Show marker at destination point
new google.maps.Marker({
position: pointA.destinationPoint(90, radius),
map: map
});
</script>
</body>
</html>
Captura de pantalla:
![Google Maps Geometry](https://i.imgur.com/IgXd59o.png)
ACTUALIZACIÓN:
En respuesta a Paul's comentario más abajo, esto es lo que sucede cuando el círculo se envuelve alrededor de uno de los polos.
Trazado pointA
cerca del polo norte, con un radio de 1,000 kilometros:
var pointA = new google.maps.LatLng(85, 0); // Close to north pole
var radius = 1000; // 1000km
Captura de pointA.destinationPoint(90, radius)
:
![Close to north pole](https://i.imgur.com/EorwQPJ.png)
@Rene : Adaptar mi respuesta a GMaps API v2 debería ser sencillo. Creo que solo se trata de reemplazar 'google.maps.LatLng' con' GLatLng'. Avísame si encuentras alguna dificultad. –
Gracias, no hay dificultades aquí :) –