Google Maps (II)
Crear ruta
Para crear la ruta codificada utilizaremos una herramienta de Google llamada "Interactive Polyline Encoder Utility" en la que podemos dibujar la ruta directamente sobre el mapa.
Esta utilidad nos proporciona dos cadenas de texto que deberemos incluir en nuestro código. En el mapa que tenemos debajo, se ha creado la siguiente ruta (ver points y levels):
function barranc(){
limpiaMapa();
var infoInicio = [ new GInfoWindowTab("Tab #1", "Inicio del recorrido") ];
var infoFin = [ new GInfoWindowTab("Tab #1", "Fin del recorrido") ];
var ePoly = new GPolyline.fromEncoded({
color: "#FF0000",
weight: 10,
points: "ggekFnm{AIbAmDfDuMjM|CjDcKpPyPaTwH~@g@bU~@~IrBjFJpAy@hGwApAyCE?xB",
levels: "BBBBBBBBBBBBBBBB",
zoomFactor: 32,
numLevels: 4
});
map.addOverlay(ePoly);
// Inicio
var inicio = new GMarker(new GLatLng(38.69828857, -0.4733562469));
GEvent.addListener(inicio, "click", function()
{ inicio.openInfoWindowTabsHtml(infoInicio); });
map.addOverlay(inicio);
// Fin
var fin= new GMarker(new GLatLng(38.707850253909, -0.4866600036621094));
GEvent.addListener(fin, "click", function()
{ fin.openInfoWindowTabsHtml(infoFin); });
map.addOverlay(fin);
}
También hemos marcado en la ruta el punto de partida y el punto de llegada. Para ello, hemos utilizado el objeto GMarker, al que le pasaremos las coordenadas del punto. Posteriormente, añadimos un listener, para que al pinchar sobre el marcador, nos muestre un diálogo con la información del punto. Este diálogo lo hemos creado con GInfoWindowTab.
Marcar la dirección de la ruta
Por desgracia, la API de Google no permite crear las flechas de dirección para que quede más clara la ruta. Buscando por internet, encontré algunas funciones que me han ayudado para esta tarea.
Para marcar la ruta vamos a necesitar un conjunto de imágenes que marquen cierto grado respecto al norte, una función que nos calcule el grado adecuado entre dos puntos y otra que ponga la imagen sobre el mapa.
Empecemos con la función que nos calcula el grado de rotación que debemos aplicar entre dos puntos del mapa:
// === Returns the bearing in degrees between two points. ===
// North = 0, East = 90, South = 180, West = 270.
var degreesPerRadian = 180.0 / Math.PI;
function bearing( from, to ) {
// See T. Vincenty, Survey Review, 23, No 176, p 88-93,1975.
// Convert to radians.
var lat1 = from.latRadians();
var lon1 = from.lngRadians();
var lat2 = to.latRadians();
var lon2 = to.lngRadians();
// Compute the angle.
var angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) );
if ( angle < 0.0 )
angle += Math.PI * 2.0;
// And convert result to degrees.
angle = angle * degreesPerRadian;
angle = angle.toFixed(1);
return angle;
}
Encontré esta función en un foro, por lo que no puedo poner ninguna referencia a su autor. Se puede observar la siguiente referencia en los comentarios: See T. Vincenty, Survey Review, 23, No 176, p 88-93,1975.
También necesitamos una función que seleccione la imagen a utilizar dependiendo del grado que nos devuelva la función anterior:
var arrowIcon = new GIcon();
arrowIcon.iconSize = new GSize(21,21);
arrowIcon.shadowSize = new GSize(1,1);
arrowIcon.iconAnchor = new GPoint(12,12);
arrowIcon.infoWindowAnchor = new GPoint(0,0);
function direccion(points) {
var p1=points[0];
var p2=points[1];
// Obtiene la direccion de la flecha (bearing) entre los dos puntos
var dir = bearing(p1,p2);
// lo redondea para que sea multiplo de 3 ya que las imagenes se han creado en diferenciales de 3 grados
var dir = Math.round(dir/3) * 3;
if (dir==360) { dir = 0; }
// Busca el punto medio entre los dos puntos
var p1x, p1y, p2x, p2y, pmidxy, pmid;
p1x=map.fromLatLngToDivPixel(p1).x;
p1y=map.fromLatLngToDivPixel(p1).y;
p2x=map.fromLatLngToDivPixel(p2).x;
p2y=map.fromLatLngToDivPixel(p2).y;
// busca el punto medio
pmidxy=new GPoint((p1x+p2x)/2,(p1y+p2y)/2);
// convierte la posición en pixel a geo-coordenadas
pmid=map.fromDivPixelToLatLng(pmidxy);
// selecciona la imagen correspondiente
arrowIcon.image = "img/gmaps/dir_"+dir+".png";
map.addOverlay(new GMarker(pmid, arrowIcon));
}
Para ello se busca el punto medio de los puntos pasados como parámetros y obtiene el grado de rotación de la flecha a mostrar en el mapa. Por último crea un GMarker (un marcador) con la imagen y el punto medio obtenidos.
En el ejemplo, se puede observar que las imágenes se encuentran en /img/gmaps/ y se han nombrado siguiendo el patrón dir_XXX.png, dónde XXX es el grado de rotación. Para crear estas imágenes, podéis consultar el siguiente artículo del blog 'Google Maps(III)'.
1 comentarios:
Muchas gracias por tu artículo, me ha sido de gran ayuda.
Quisiera añadir que para mejorarlo hay que tener en cuenta que al menos actualmente, porque no se si cuando escribiste el articulo era así, Google tiene en su dirección http://maps.google.com/mapfiles/ los gráficos dir_*.png con cada rotación de la fecha de 3 en 3 grados pero no con los 360 grados sino del 0 al 117.
Si el grado es mayor que ese número ya no encontraría el gráfico.
Esto debe ser así porque a partir de los 120 y 240 grados, los gráficos del triangulo vuelven a ser iguales que los de los primeros 120 grados.
Para solventar ese problema bastaría con añadir las líneas:
while (dir > 117)
dir -= 117;
justo antes de la penúltima línea de la función direccion donde se llama al gráfico. y de esta forma se encuentra el gráfico que correspondería al giro del triangulo.
Muchas gracias.
Publicar un comentario