Guia Mapas

123
Google Maps API V3 introducción y primeros pasos Google Maps fue desarrollado originalmente por dos hermanos Daneses, Lars y Jens Rasmussen, co-fundadores de Where 2 Technologies una empresa dedicada a la creación de soluciones de mapeo. La empresa fue adquirida por Google en octubre de 2004, y los dos hermanos luego crearon Google Maps (también son los que están detrás de Google Wave ). Antes de que hubiera una API pública, algunos desarrolladores descubrieron la manera de hackear Google Maps para incorporar los mapas en sus propios sitios web. Esto llevó a Google a la conclusión de que había una necesidad de una API pública, y en junio de 2005 fue lanzado públicamente. El mashup por primera vez en Internet es a menudo considerado que lo ejerció Housingmaps.com, una combinación de Google Maps con los listados de bienes raíces de Craiglist.org. Fue creado de hecho antes de la API pública fuera puesto en libertad y fue hackeado por el desarrollador Paul Rademacher . En mayo de 2010, se anunció la versión 3 del API. Ahora es la opción recomendada para las nuevas aplicaciones de Google Maps y el siguiente paso en la historia de Google Maps. ¿Cómo funciona Google Maps? Es sólo HTML, CSS y JavaScript trabajando junto. Los mapas son solo imágenes que se cargan en el fondo a través de peticiones ejecutadas por la tecnología de AJAX, y se insertan en un <div> en la página HTML. Mientras navegas en el mapa, el API envía información acerca de las nuevas coordenadas y los niveles de “zoom” de el mapa a través de AJAX y esto retorna las imágenes. El API consiste de archivos JavaScript que contienen las clases, métodos y propiedades que se usan para el comportamiento de los mapas. ¿Cómo se usan?, de eso se trata esta guía. Esta guía tratará acerca de la última versión creada al momento, la versión 3.

Transcript of Guia Mapas

Page 1: Guia Mapas

Google Maps API V3 introducción y primeros pasosGoogle Maps fue desarrollado originalmente por dos hermanos Daneses, Lars y Jens Rasmussen, co-fundadores de Where 2 Technologies una empresa dedicada a la creación de soluciones de mapeo. La empresa fue adquirida por Google en octubre de 2004, y los dos hermanos luego crearon Google Maps (también son los que están detrás de Google Wave).

Antes de que hubiera una API pública, algunos desarrolladores descubrieron la manera de hackear Google Maps para incorporar los mapas en sus propios sitios web. Esto llevó a Google a la conclusión de que había una necesidad de una API pública, y en junio de 2005 fue lanzado públicamente.

El mashup por primera vez en Internet es a menudo considerado que lo ejerció Housingmaps.com, una combinación de Google Maps con los listados de bienes raíces de Craiglist.org. Fue creado de hecho antes de la API pública fuera puesto en libertad y fue hackeado por el desarrollador Paul Rademacher. En mayo de 2010, se anunció la versión 3 del API. Ahora es la opción recomendada para las nuevas aplicaciones de Google Maps y el siguiente paso en la historia de Google Maps.

¿Cómo funciona Google Maps?

Es sólo HTML, CSS y JavaScript trabajando junto. Los mapas son solo imágenes que se cargan en el fondo a través de peticiones ejecutadas por la tecnología de AJAX, y se insertan en un <div> en la página HTML. Mientras navegas en el mapa, el API envía información acerca de las nuevas coordenadas y los niveles de “zoom” de el mapa a través de AJAX y esto retorna las imágenes.

El API consiste de archivos JavaScript que contienen las clases, métodos y propiedades que se usan para el comportamiento de los mapas. ¿Cómo se usan?, de eso se trata esta guía. Esta guía tratará acerca de la última versión creada al momento, la versión 3.

Page 2: Guia Mapas

Las coordenadas están expresadas usando números decimales separados por coma. La latitud siempre precede la longitud. La latitud es positiva si va después del punto mostrado en el mapa y negativo si va antes. La longitud es positiva si va arriba del punto y negativa si va debajo.

En los mapas físicos, las coordenadas están expresadas en grados, así que la posición de Puerto Rico sería:18°14’70″ N 66°29’68″ W

La forma de convertir estos datos a decimales sería:(18°14’70″ N) = (18 + (14 / 60) + (70 / 3600)) = 18.252(66°29’68″ W) = -(66 + (29 / 60) + (68 / 3600)) = -66.8627La longitud se multiplica por negativo, porque está a la izquierda (oeste) del punto 0,0. Para esta guía solo vamos a estar trabajando con decimales.

¿Cuánto es el máximo de decimales?

Google maps no se limita a cierta cantidad de decimales. Sin embargo, según unas pruebas hechas, se notó que números mayores a 6 decimales es una perdida de tiempo. Así también google estableció en varios métodos que la mayor cantidad a trabajar es 6 decimales, como por ejemplo el método toUrlValue(). Es decir, cuando vayamos a establecer los decimales se puede hacer así:

5 a 6 decimales: es el máximo que debemos usar para ser específicos 4 decimales: para algún detalle en el mapa 3 decimales: es bueno para centrar ciudades 2 decimales: es apropiado para centrar paises o estados, tal vez 3 por monaco

Page 3: Guia Mapas

Preparando el área de trabajo

Para propósito de enseñanza tomaremos el 100% de ancho y el 100% de alto del navegador. También nos limitaremos a explicar solo la parte del API. Para referencia sobre el último API que contiene las clases, métodos y propiedades pueden ir a la dirección http://code.google.com/intl/es/apis/maps/documentation/javascript/reference.html

?

01020304050607080910111213141516171819

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

En el siguiente código:

?

1<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&;amp;language=es"></script>La dirección apunta al API, pero también se requiere pasar una cadena de consulta con la llave sensor. Esto le indica a Google si el dispositivo que usa el mapa, tiene un dispositivo que determina la geolocalización, como por ejemplo un GPS. Es forzoso mencionarlo y como valor indicar si es falso o cierto. Falso para los que no lo usan y cierto para los que sí lo usan. Esto lo usa Google para proveer estadísticas a sus proveedores. No tiene que ver con habilitarlo para la geolocalización.

También se añadió el lenguaje, aunque el API trata de determinar cual es el lenguaje a mostrar, pero puedes especificarlo usando la llave language. En este ejemplo no hemos mencionado la llave api ya que para la versión 3 no se usa.

?1<script type="text/javascript" src="map.js"></script>Es importante que el código mencionado anteriormente, se encuentre debajo del elemento <script> que incluye el API, para que así se

Page 4: Guia Mapas

pueda cargar todas las clases, métodos y propiedades a usar. Las clases, métodos y propiedades comienzan con google.maps. A eso se le conoce como namespace.

Dentro del archivo map.js escribimos:

?

12345678

window.onload = function(){var options = {zoom: 8, center: new google.maps.LatLng(18.2, -66.4), mapTypeId: google.maps.MapTypeId.SATELLITE};var map = new google.maps.Map(document.getElementById('map'), options);};

Esto nos trae el mapa de Puerto Rico. ¿Qué es lo que hace? Primero indicamos que queremos que el mapa se muestre una vez se haya cargado toda la información con el evento window.onload. Para iniciar el mapa hacemos uso de la clase google.maps.Map(). A este se le indica dos argumentos:

La referencia hacia el elemento que mostrará el mapa, en este caso el elemento <div> con el atributo id que tiene como valor map.

Una notación literal llamada MapOptions que contiene la configuración inicial para mostrar el mapa como por ejemplo, el “zoom”, donde está el centro y que tipo de mapa deseamos mostrar.

MapOptions

MapOptions contiene la información de cómo queremos ver el mapa y cómo queremos que se comporte. Se requiere tres propiedades:

zoom: Define el “zoom” inicial. Debe ser un número entre el 1 y el 23. El 1 es el mapa completamente afuera y 23 es completamente adentro.

center: Define el centro del mapa con las coordenadas. Las coordenadas debe indicarse usando el método google.maps.LatLng(latitud, longitud).

Page 5: Guia Mapas

mapTypeId : Define que tipo de mapa se desea mostrar al inicio.

Los opcionales son:

keyboardShortcuts: Habilita o inhabilita el uso del teclado. Las teclas a usar son las flechas para mover el mapa y +/- para el “zoom”.Valores: true|false, por defecto true.

disableDoubleClickZoom: Habilita o inhabilita el doble click del ratón para hacer “zoom”.Valores: true|false por defecto false.

draggable: Habilita o inhabilita el poder arrastrar el mapa.Valores: true|false, por defecto true.

scrollwheel: Habilita o inhabilita el poder hacer “zoom” con la rueda del ratón.Valores: true|false, por defecto true.

draggableCursor: Indica que tipo de cursor deseas mostrar cuando el ratón está encima del mapa. El valor es del tipo cadena y pueden ser los que una computadora tiene por defecto y la mayoría de los que están mencionado en el siguiente listado o puede ser uno personalizado y la ruta puede ser local (en el servidor de la aplicación) o una dirección web externa.

draggingCursor: Indica que tipo de cursor deseas mostrar cuando el ratón está presionado en el mapa. El valor es del tipo cadena y pueden ser los que una computadora tiene por defecto y la mayoría de los que están mencionado en el siguiente listado o puede ser uno personalizado y la ruta puede ser local (en el servidor de la aplicación) o una dirección web externa.

backgroundColor: Esta propiedad afecta el color del fondo del contenedor. Típicamente se ve cuando se arrastra el mapa o cuando carga al inicio. Puedes usar un valor hexadecimal o la forma estándar (red, yellow, green, blue, etc). Por defecto el color es con el valor hexádecimal #E5E3DF

noClear: Habilita o inhabilita que se sobre-escriba lo que haya en el contenedor. Por lo regular la forma como se trabaja para colocar contenido encima del contenedor es usando un elemento fuera del contenedor que muestra el mapa y con CSS se coloca en el lugar deseado en el mapa.Valores: true|false, por defecto false.

disableDefaultUI: Habilita o inhabilita mostrar el UI que viene predefinido.Valores: true|false, por defecto false.

mapTypeControl: Habilita o inhabilita el control de tipo de mapa. mapTypeControlOptions : Son las opciones de visualización iniciales del control de tipo de

mapa. navigationControl: Habilita o inhabilita el control de navegación.

Valores: true|false, por defecto true. navigationControlOptions : Son las opciones de visualización iniciales del control de

navegación. scaleControl: Habilita o inhabilita el control de escala.

Valores: true|false, por defecto true. scaleControlOptions : Son las opciones de visualización iniciales del control de escala. streetViewControl: Habilita o inhabilita el hombrecito de “Street View”. Está disponible

en ciertas áreas.Valores: true|false, por defecto false.

Modificamos y añadimos el siguiente código al archivo map.js

Page 6: Guia Mapas

?0102030405060708091011121314151617181920212223242526272829303132333435363738

window.onload = function(){var options = {zoom: 8, center: new google.maps.LatLng(18.2, -66.4), mapTypeId: google.maps.MapTypeId.SATELLITE, backgroundColor: '#ffffff', noClear: true, disableDefaultUI: true, keyboardShortcuts: false, disableDoubleClickZoom: true, draggable: false, scrollwheel: false, draggableCursor: 'move', draggingCursor: 'move', mapTypeControl: true, mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.HORIZONTAL_MENU, position: google.maps.ControlPosition.TOP_LEFT, mapTypeIds: [google.maps.MapTypeId.SATELLITE]}, navigationControl: true, streetViewControl: true, navigationControlOptions: {position: google.maps.ControlPosition.TOP_RIGHT, style: google.maps.NavigationControlStyle.ANDROID}, scaleControl: true, scaleControlOptions: {position: google.maps.ControlPosition.TOP_LEFT, style: google.maps.ScaleControlStyle.DEFAULT}};var map = new google.maps.Map(document.getElementById('map'), options);};

Page 7: Guia Mapas

Modificar los valores ya asignados

Hasta ahora, hemos iniciado los valores directamente en el MapOptions para iniciar el mapa. Luego de que se hayan cargado, podemos modificarlos con el método setOptions. Podemos modificar la mayoría de las propiedades. Solo tres no son modificables: noClear, backgroundColor y disableDefaultUI, por lo que debemos estar seguros qué debemos hacer con ellos al inicio. El setOptions es de gran utilidad para interactuar con el usuario. Veamos un ejemplo

?010203040506070809101112131415161718192021222324

window.onload = function(){var options = {zoom: 8, center: new google.maps.LatLng(18.2, -66.4), mapTypeId: google.maps.MapTypeId.SATELLITE, backgroundColor: '#ffffff', noClear: true, disableDefaultUI: true, keyboardShortcuts: false, disableDoubleClickZoom: true, draggable: false, scrollwheel: false, draggableCursor: 'move', draggingCursor: 'move', mapTypeControl: true, mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.HORIZONTAL_MENU, position: google.maps.ControlPosition.TOP_LEFT, mapTypeIds: [google.maps.MapTypeId.SATELLITE]}, navigationControl: true, streetViewControl: true

Page 8: Guia Mapas

2526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071

, navigationControlOptions: {position: google.maps.ControlPosition.TOP_RIGHT, style: google.maps.NavigationControlStyle.ANDROID}, scaleControl: true, scaleControlOptions: {position: google.maps.ControlPosition.TOP_LEFT, style: google.maps.ScaleControlStyle.DEFAULT}};var map = new google.maps.Map(document.getElementById('map'), options);map.setOptions({zoom: 10, center: new google.maps.LatLng(18.17, -66.42), mapTypeId: google.maps.MapTypeId.TERRAIN, keyboardShortcuts: true, disableDoubleClickZoom: false, draggable: true, scrollwheel: true, draggableCursor: 'hand', draggingCursor: 'hand', mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, position: google.maps.ControlPosition.TOP_RIGHT, mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE]}, navigationControlOptions: {position: google.maps.ControlPosition.TOP_LEFT, style: google.maps.NavigationControlStyle.ZOOM_PAN}, scaleControlOptions: {position: google.maps.ControlPosition.BOTTOM_LEFT, style: google.maps.ScaleControlStyle.DEFAULT}});};

Page 9: Guia Mapas

Getters y Setters

Existen unos métodos que nos permiten solo modificar y/o obtener los resultados de las propiedades que son requisitos.

getZoom() setZoom(1-23) getCenter() setCenter(google.maps.LatLng(latitud, longitud)) getMapTypeId() setMaptTypeId(google.maps.MapTypeId.*)

Uniendo todo

?010203040506070809101112131415161718

window.onload = function(){var options = {zoom: 8, center: new google.maps.LatLng(18.2, -66.4), mapTypeId: google.maps.MapTypeId.SATELLITE, backgroundColor: '#ffffff', noClear: true, disableDefaultUI: true, keyboardShortcuts: false, disableDoubleClickZoom: true, draggable: false, scrollwheel: false, draggableCursor: 'move', draggingCursor: 'move', mapTypeControl: true, mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.HORIZONTAL_MENU, position: google.maps.ControlPosition.TOP_LEFT

Page 10: Guia Mapas

19202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

, mapTypeIds: [google.maps.MapTypeId.SATELLITE]}, navigationControl: true, streetViewControl: true, navigationControlOptions: {position: google.maps.ControlPosition.TOP_RIGHT, style: google.maps.NavigationControlStyle.ANDROID}, scaleControl: true, scaleControlOptions: {position: google.maps.ControlPosition.TOP_LEFT, style: google.maps.ScaleControlStyle.DEFAULT}};var map = new google.maps.Map(document.getElementById('map'), options);map.setOptions({zoom: 10, center: new google.maps.LatLng(18.17, -66.42), mapTypeId: google.maps.MapTypeId.TERRAIN, keyboardShortcuts: true, disableDoubleClickZoom: false, draggable: true, scrollwheel: true, draggableCursor: 'hand', draggingCursor: 'hand', mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU, position: google.maps.ControlPosition.TOP_RIGHT, mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE]}, navigationControlOptions: {position: google.maps.ControlPosition.TOP_LEFT, style: google.maps.NavigationControlStyle.ZOOM_PAN}, scaleControlOptions: {position: google.maps.ControlPosition.BOTTOM_LEFT, style: google.maps.ScaleControlStyle.DEFAULT}});map.setZoom(9);var zoomLevel = map.getZoom();map.setCenter(new google.maps.LatLng(18.17, -66.3));var centerOfMap = map.getCenter();

Page 11: Guia Mapas

686970717273747576777879808182

map.setMapTypeId(google.maps.MapTypeId.ROADMAP);var mapTypeIdOfMap = map.getMapTypeId();alert(zoomLevel + ' -- ' + centerOfMap + ' -- ' + mapTypeIdOfMap);};

Marcadores, posicionar una imagen en el mapaEl uso más común del mapa es visualizar la posición geográfica de algo, los marcadores son los ideales para lograrlo. Un marcador es básicamente una pequeña imagen posicionada en un lugar específico del mapa.

Page 12: Guia Mapas

Área de trabajo

Usaremos el mismo área de trabajo del primer capítulo (Google Maps API V3 introducción y primeros pasos):

?

01020304050607080910111213141516171819

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

Dentro del archivo map.js, es donde estaremos trabajando el resto de los ejemplos.

Crear marcador

Para crear un marcador, necesitas usar el objeto google.maps.Marker. Este toma un sólo argumento y es google.maps.MarkerOptions. MarkerOptions tiene varias propiedades que puedes usar para hacer que el marcador se vea y comporte de diversas formas. Solo dos propiedades son requisitos:

position: Define las coordenadas donde el marcador va a estar posicionado. Toma las coordenadas usando el método google.maps.LatLng.

map: Es una referencia al mapa donde quieres añadir el marcador.

Estos son algunas de las opciones que se pueden usar en el marcador:

?01020304050607

window.onload = function(){var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'),

Page 13: Guia Mapas

0809101112131415161718

options);new google.maps.Marker({position: map.getCenter(), map: map, title: 'Pulsa aquí', icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/green/blank.png', cursor: 'default', draggable: true});};

Notas:

Si deseamos que el marcador no se pueda seleccionar podemos inhabilitarlo usando clickable y como valor false. No podemos habilitar draggable porque eso sobre-escribiría el valor establecido en el clickable, ya que para poder mover el marcador se requiere que se pueda seleccionar.

En la dirección

http://gmaps-samples.googlecode.com/svn/trunk/markers/{color}/marker{n}.png

puedes obtener diferentes tipos de marcadores, donde {color} puede ser: blue, green, orange, pink y red. {n} puede ser un número entre el 1 y el 99 y para los que no se requiere número se puede usar blank.png, así como en el ejemplo. Más marcadores en http://code.google.com/p/google-maps-icons/wiki/AllUpdates.

Page 14: Guia Mapas

InfoWindow

Para añadir la burbuja que contiene información acerca del marcador solo tienes que hacer referencia a la clase google.maps.InfoWindow y esta toma un solo argumento que es google.maps.InfoWindowOptions. InfoWindowOptions tiene varias propiedades, pero la más importante es content. En esa propiedad podemos añadir cualquier tipo de datos que queramos, como por ejemplo: texto plano, HTML, video y puedes modificar el contenido usando CSS.

Para poder visualizar la burbuja se requiere usar el método open que está disponible en la clase google.maps.InfoWindow. Este método tiene dos argumento y el primero es requisito:

map: Es una referencia al objeto que contiene el mapa que se va a usar (la razón es que puede que tengamos varios mapas en la misma página) o StreetViewPanorama

El objeto en donde se quiere añadir la burbuja. Esta es opcional si se menciona la propiedad position en el InfoWindowOptions.

?0102030405060708091011121314151617181920212223

window.onload = function(){var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var marker = new google.maps.Marker({position: map.getCenter(), map: map, title: 'Pulsa aquí', icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png'});var popup = new google.maps.InfoWindow({content: 'Wohoooo, salió el InfoWindow, pero ¿por qué sale exactamente en el punto del marcador?', position: map.getCenter()});popup.open(map);};

Page 15: Guia Mapas

Si prestamos atención, vemos que la posición de la burbuja es exactamente donde está ubicado el marcador, pero la realidad es que deseamos que la burbuja aparezca encima del marcador. Una forma de lograrlo es creando una nueva instancia de google.maps.LatLng y asignando valores que logre colocar la burbuja encima del marcador. Otra forma y la más sencilla es asignando el segundo argumento del método de open e indicar que tome como base el marcador.

?010203040506070809101112131415161718192021

window.onload = function(){var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var marker = new google.maps.Marker({position: map.getCenter(), map: map, title: 'Pulsa aquí', icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/pink/blank.png'});var popup = new google.maps.InfoWindow({content: 'Wohoooo, salió el InfoWindow y encima del marcador, ahora ¿qué más puedo hacer con esto?'});popup.open(map, marker);};

Page 16: Guia Mapas

22

Si queremos visualizar la ventana usando algún evento (cuando se pulse el ratón, o cuando presionemos alguna tecla) se puede usar el método google.maps.event.addListener(). Requiere de tres argumentos:

El objeto a añadir El evento que debe escuchar Una función que se ejecutará cuando ocurra el evento. Esta función se le conoce como gestión

de eventos (event handler en ingles)

?010203040506070809101112131415161718

window.onload = function(){var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var marker = new google.maps.Marker({position: map.getCenter(), map: map, title: 'Pulsa aquí', icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/orange/blank.png'});var popup = new google.maps.InfoWindow({content: 'Wohoooo, salió el InfoWindow cuando pulsé el marcador, pero ¿hay más?'});

Page 17: Guia Mapas

192021222324

google.maps.event.addListener(marker, 'click', function(){popup.open(map, marker);});};

Para una lista de los eventos, pueden verlo en la clase google.maps.Map en la categoría que dice Events.

Añadir varios marcadores

Podemos añadir varios marcadores de la misma forma como hemos añadido uno. Se puede hacer ingresándolo uno a uno o en forma más dinámica usando arrays.

?01020304050607080910111213

window.onload = function(){var n=1;var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);for(var i in place){

Page 18: Guia Mapas

141516171819202122232425262728293031

var marker = new google.maps.Marker({position: place[i], map: map, title: i, icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/red/marker' + n++ + '.png'});google.maps.event.addListener(marker, 'click', function(){var popup = new google.maps.InfoWindow();var note = 'Wohoooo, salió el InfoWindow cuando pulsé el marcador y en el lugar: ' + i+ ', pero ¿por qué todos se muestran en ' + i + '?';popup.setContent(note);popup.open(map, marker);})}};

Siempre que seleccionamos cualquier marcador nos dará el último creado en el array. La razón es que estamos usando como referencia la variable y no el valor, y esto siempre nos dará el último valor indicado en el array. Hay varias formas de corregirlo. Una de las formas más sencilla es hacer referencia al objeto corriente usando la palabra clave this:

?01020304

window.onload = function(){var n=1;var options = {zoom: 9

Page 19: Guia Mapas

050607080910111213141516171819202122232425262728293031

, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);for(var i in place){var marker = new google.maps.Marker({position: place[i], map: map, title: i, icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/red/marker' + n++ + '.png'});google.maps.event.addListener(marker, 'click', function(){var popup = new google.maps.InfoWindow();var note = 'Wohoooo, salió el InfoWindow cuando pulsé el marcador y en el lugar: ' + this.title+ ', por fin se arreglo, pero ¿por qué salen varias burbujas?';popup.setContent(note);popup.open(map, this);});}};

Page 20: Guia Mapas

Otra situación que se presenta es que si seleccionas una burbuja y luego otra, tanto la primera como la segunda se quedan abiertas. Para la versión 2 automáticamente se cerraban. En la versión 3 ya no hay esa limitación. Esto puede representar una ventaja y desventaja. Entre las ventajas es posible ahora comparar datos en ambas burbujas y verlo a la misma vez.

Entre las desventajas es que tenemos más clicks y puede que se vuelva problemático. Una forma de evitar que salgan varias burbujas es, declarar la variable que guarda la instancia de InfoWindow fuera del bucle y luego en la función del evento verificar si existe ya una instancia, si no es así entonces crearla, si es así usar la que ya existe.

?01020304050607080910111213141516171819202122232425262728293031323334

window.onload = function(){var popup;var n=1;var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);for(var i in place){var marker = new google.maps.Marker({position: place[i], map: map, title: i, icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/orange/marker' + n++ + '.png'});google.maps.event.addListener(marker, 'click', function(){if(!popup){popup = new google.maps.InfoWindow();}var note = 'Wohoooo, salió el InfoWindow cuando pulsé el marcador, en el lugar: ' + this.title+ ' y no se repiten las burbujas, ufff, ya estoy fatigado de emocionarme...';popup.setContent(note);popup.open(map, this);})}};

Page 21: Guia Mapas

Ajustar automáticamente la ventana para adaptarse a todos los marcadores

A veces sabemos cuantos marcadores va haber en el mapa, pero cuando empezamos a crear aplicaciones que toman valores automáticos, es bueno dejar que la aplicación se encargue de establecer los límites. Con la clase google.maps.LatLngBounds es posible lograrlo.

LatLngBounds establece los límites en forma rectangular y se puede pasar dos argumentos (opcionales) que son las coordenadas suroccidental y nororiental expresadas con la clase google.maps.LatLng(). El primer argumento debe ser el marcador que se encuentre más a la izquierda y el segundo el que esté más a la derecha. Luego con el método fitBounds de la clase map reajustamos el mapa.

?010203040506070809101112131415

window.onload = function(){var popup;var n=1;var options = {zoom: 3, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);marker = new google.maps.Marker({position: place['San Juan']

Page 22: Guia Mapas

1617181920212223242526272829303132333435

, map: map, title: 'San Juan', icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/red/blank.png'});var marker = new google.maps.Marker({position: place['Fajardo'], map: map, title: 'Fajardo', icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png'});var limits = new google.maps.LatLngBounds(place['San Juan'], place['Fajardo']);map.fitBounds(limits);};

Pero ¿cómo podemos hacer que lo haga automático? La clase LatLngBounds tiene un método llamado extend que nos ayudará en lo que queremos hacer. Este toma un solo argumento y es google.maps.LatLng() del marcador en curso. Primero instanciamos la clase LatLngBounds fuera del bucle y dentro del bucle usamos el método extend, al final, fuera del bucle, llamamos el método fitBounds.

?01window.onload = function(){

Page 23: Guia Mapas

02030405060708091011121314151617181920212223242526272829

var popup;var n=1;var options = {zoom: 3, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var limits = new google.maps.LatLngBounds();var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);place['Culebras'] = new google.maps.LatLng(18.315, -65.3);for(var i in place){var marker = new google.maps.Marker({position: place[i], map: map, title: i, icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/red/marker' + n++ + '.png'});limits.extend(place[i]);}map.fitBounds(limits);};

Page 24: Guia Mapas

Personalizar el marcador con MarkerImage

google.maps.MarkerImage es una clase que contiene información acerca de la imagen y/o sombra a usar en el marcador. Tiene cinco argumentos, pero solo el primero es requisito.

url: La dirección apuntando a la imagen size: El tamaño de la imagen origin: La parte de la imagen a usar. Debe usarse con la clase google.maps.Point. Esto

se usa mucho con la técnica llamada sprites anchor: Establece la parte de la imagen que va a usar para apuntar la localización en el mapa.

Si no se establece, toma como base la parte del medio-abajo scaledSize: Permite mostrar la imagen más pequeña o más grande al tamaño original. Si se

usa esta propiedad se debe ajustar el anchor al tamaño establecida de la imagen

Se puede definir qué áreas del marcador son clickeables usando shape en el objeto MarkerOptions. Si no se usa esta propiedad toda la imagen es clickeable. Esta propiedad tiene como valor un objeto literal con dos propiedades: type que define cual es la figura (rect, circ, poly) a usar y coord que establece las coordenadas a usar pero dependiendo el tipo de figura que se haya seleccionado.

rect: requiere dos valores que son las esquinas de: arriba-izquierda, abajo-derecha circ: requiere de tres valores que son: x,y y el radio poly: consiste de varios puntos x,y en forma lineal y como los poligonos son figuras cerradas,

el último punto automaticamente se conecta con el primero

Notas:

Cuando no se requiera usar algún argumento opcional, solo debes añadir null hasta llegar al argumento deseado

Es buena programación indicar en los argumentos opcionales los valores, para que así el navegador no necesite hacer cálculos innecesarios, como por ejemplo indicar el size

¿Por qué no usar una imagen que contenga la sombra directamente? Para tener más flexibilidad. Podriamos usar una imagen y darle brillo conforme al evento que esté ocurriendo al momento, como por ejemplo hover. Veremos luego, como podemos cambiar la imagen conforme al evento que ocurra. También podríamos inhablitar la sombra para mostrar mejor algún detalle en el mapa

Para inhabilitar la sombra del marcador, solo se tiene que declarar como valor true la propiedad flat en el objeto MarkerOptions de la clase google.maps.Marker. Por defecto tiene como valor false

Hemos tomado el logo de este sitio web, lo cambiamos a forma vertical y lo convertimos a una imagen png con transparencia, luego visitamos http://www.powerhut.co.uk/googlemaps/custom_markers.php para obtener la sombra y el shape con sus coordenadas a usar en el marcador de una forma sencilla. También crea la imagen usando la técnica de sprites. En este ejemplo usaremos la técnica de sprites:

?010203040506

window.onload = function(){var popup;var n=1;var options = {zoom: 3, center: new google.maps.LatLng(18.2, -66.5)

Page 25: Guia Mapas

07080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

, mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var limits = new google.maps.LatLngBounds();var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);place['Culebras'] = new google.maps.LatLng(18.315, -65.3);place['Vieques'] = new google.maps.LatLng(18.125, -65.44);place['Humacao'] = new google.maps.LatLng(18.14, -65.88);var image = new google.maps.MarkerImage('http://www.maestrosdelweb.com/images/2011/04/sprite.png', new google.maps.Size(30,43), new google.maps.Point(0,0), new google.maps.Point(15,43));var shadow = new google.maps.MarkerImage('http://www.maestrosdelweb.com/images/2011/04/sprite.png', new google.maps.Size(56,43), new google.maps.Point(30,0), new google.maps.Point(15,43));var shape = {coord: [2,0,3,1,5,2,7,3,8,4,10,5,11,6,29,7,29,8,29,9,29,10,29,11,29,12,29,13,29,14,28,15,27,16,26,17,25,18,23,19,21,20,20,21,26,22,26,23,26,24,26,25,26,26,26,27,25,28,24,29,23,30,21,31,20,32,18,33,17,34,15,35,15,36,15,37,15,38,15,39,15,40,15,41,15,42,14,42,14,41,13,40,12,39,10,38,8,37,7,36,6,35,5,34,4,33,4,32,4,31,4,30,4,29,5,28,10,27,8,26,7,25,5,24,4,23,3,22,3,21,3,20,3,19,3,18,3,17,3,16,11,15,9,14,8,13,6,12,4,11,3,10,2,9,1,8,0,7,0,6,0,5,0,4,0,3,0,2,0,1,0,0,2,0], type: 'poly'};for(var i in place){var marker = new google.maps.Marker({position: place[i], map: map, title: i, icon: image, shadow: shadow, shape: shape});limits.extend(place[i]);}map.fitBounds(limits);};

Page 26: Guia Mapas

565758596061

Cambiar imagen conforme a un evento

La clase google.maps.Marker tiene unos getters/setters que nos ayudará para poder modificar la imagen conforme al evento que ocurre. Solo necesitamos indicar el evento usando google.maps.event.addListener y en el tercer argumento indicamos que queremos modificar la imagen del objeto en uso, con el método setIcon de la clase google.maps.Marker.

?01020304050607080910111213

window.onload = function(){var popup;var n=1;var options = {zoom: 3, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var limits = new google.maps.LatLngBounds();var place = new Array();place['San Juan'] = new google.maps.LatLng(18.465, -66.105);place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);

Page 27: Guia Mapas

141516171819202122232425262728293031323334353637383940414243444546474849

place['Culebras'] = new google.maps.LatLng(18.315, -65.3);place['Vieques'] = new google.maps.LatLng(18.125, -65.44);place['Humacao'] = new google.maps.LatLng(18.14, -65.88);place['Ponce'] = new google.maps.LatLng(18.025, -66.615);place['Mayagüez'] = new google.maps.LatLng(18.215, -67.14);for(var i in place){var marker = new google.maps.Marker({position: place[i], map: map, title: i, icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png'});google.maps.event.addListener(marker, 'mouseover', function(){this.setIcon('http://gmaps-samples.googlecode.com/svn/trunk/markers/green/blank.png');});google.maps.event.addListener(marker, 'mouseout', function(){this.setIcon('http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png');});google.maps.event.addListener(marker, 'mousedown', function(){this.setIcon('http://gmaps-samples.googlecode.com/svn/trunk/markers/red/blank.png');});google.maps.event.addListener(marker, 'mouseup', function(){this.setIcon('http://gmaps-samples.googlecode.com/svn/trunk/markers/green/blank.png');});limits.extend(place[i]);}map.fitBounds(limits);};

Page 28: Guia Mapas
Page 29: Guia Mapas

Consejos prácticos para el InfoWindow en Google MapsEn la versión 2 de Google Maps, existen muchos métodos para trabajar con el InfoWindow. Sin embargo, en la versión 3, han colocado solo lo esencial. Vamos a mostrar varios ejemplos y consejos para trabajar con el InfoWindow, algunos similares a los que se podían hacer con la versión 2.

Área de trabajo

Para empezar usaremos el mismo área de trabajo que el capítulo 1 (Google Maps API V3 introducción y primeros pasos) y capítulo 2 (Marcadores, posicionar una imagen en el mapa). Luego iremos modificándolo conforme a lo que vayamos trabajando.

?01020304050607080910

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;

Page 30: Guia Mapas

111213141516171819

height: 100%;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

Dentro del archivo map.js, es donde estaremos trabajando los ejemplos de javascript.

zIndex

Cuando se van creando los InfoWindow, el último creado se muestra sobre el anterior. Por lo regular una forma de evitarlo, es usando la misma instancia del objeto creado y así solo se puede visualizar uno. Pero si deseamos mostrar varios a la misma vez, entonces ¿cómo podemos hacer para seleccionar un InfoWindow y este se coloque encima de los anteriores?

Conforme a la clase de InfoWindow podemos ver en el área de eventos que solo están disponibles: closeclick, content_changed, domready, position_changed y zindex_changed. En ningún momento se mencionó el evento click y es el que necesitamos. Una solución es que cuando se seleccione algún elemento dentro del InfoWindow, este se pueda colocar encima de todos los demas (luego ampliaremos como trabajar HTML y CSS en el InfoWindow):

?01020304050607080910111213141516171819202122

window.onload = function(){var options = {zoom: 14, center: new google.maps.LatLng(18.470338, -66.123503), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var n=1;var markers = [{'position':new google.maps.LatLng(18.470338, -66.123503), 'info':'<div id="contentInfoWindow' + n++ + '" style="width: 300px; height: 300px; border: 1px solid #000;"></div>'},{'position':new google.maps.LatLng(18.464008, -66.117776), 'info':'<div id="contentInfoWindow' + n++ + '" style="width: 300px; height: 300px; border: 1px solid #000;"></div>'},{'position':new google.maps.LatLng(18.470826, -66.136205)

Page 31: Guia Mapas

2324252627282930313233343536373839404142434445

, 'info':'<div id="contentInfoWindow' + n++ + '" style="width: 300px; height: 300px; border: 1px solid #000;"></div>'}];n=1;for(var i in markers){marker = new google.maps.Marker({position: markers[i]['position'], map: map});popup = new google.maps.InfoWindow({content: markers[i]['info'], zIndex: n});popup.open(map, marker);(function(id, popup){google.maps.event.addListener(popup, 'domready', function(){google.maps.event.addDomListener(document.getElementById('contentInfoWindow' + id), 'click', function(){popup.setZIndex(n++);});})})(n++, popup);}};

Si seleccionamos cualquier área dentro del elemento <div> que está en el contenido del InfoWindow, podemos ver que la burbuja que seleccionemos se coloca encima de todos los mencionados. Esto lo logramos:

Colocando primero en qué zIndex debe estar cuando se creen. Este paso es necesario para evitar sorpresas en el momento de seleccionar los elementos. Si no se coloca, el zIndex está indefinido y al seleccionar un elemento este se coloca por debajo de todos los elementos hasta que todos tengan definidos el zIndex

Una forma de hacer referencia a un valor en específico y no a la variable es encapsulando el valor. Esto lo hicimos creando una función anónima (con dos argumentos) entre paréntesis, luego colocamos otros parétesis y dentro de estos, los valores a usar (conforme a los argumento declarados en la función)

Como las peticiones son asincrónicas, debemos esperar que los elementos declarados en el InfoWindow se carguen por lo que debemos hacer uso del evento domready de la clase InfoWindow. Una vez cargados los elementos le indicamos que queremos usar el método addDomListener y usar el evento click, de esta forma podemos seleccionar el elemento que deseamos

Page 32: Guia Mapas

Por último modificamos el valor del zIndex del InfoWindow que seleccionamos, con el método setZIndex indicando el último valor numérico que se encuentra en la variable n

HTML y CSS

Dentro del InfoWindow podemos colocar diferentes tipos de datos, por ejemplo HTML y modificarlo con CSS. Modificamos el archivo que contiene el área de trabajo a que quede:

?01020304050607080910111213141516171819202122232425262728293031323334353637383940

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}img{ border: 0; }.contentMap{width: 630px;border: 1px solid #336699;max-height:415px;overflow:auto;}.contentImg{float: left;width: 300px;margin-right: 10px;text-align: center;}.contentImg a{color: #369;font-size: 12px;}.contentTxt{float: left;width: 300px;}.clear{ clear: both; }</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head><body>

Page 33: Guia Mapas

4142

<div id="map"></div></body></html>

En el archivo map.js colocamos:

?01020304050607080910111213141516171819202122232425262728293031323334353637383940414243

window.onload = function(){var options = {zoom: 14, center: new google.maps.LatLng(18.470338, -66.123503), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var n=1;var markers = [{'position':new google.maps.LatLng(18.470338, -66.123503), 'info':'<div id="contentInfoWindow' + n++ + '" class="contentMap">\<div class="contentImg">\<img src="http://www.maestrosdelweb.com/images/2011/04/SanJuan.jpg" title="San Juan Morro" />\Autor desconocido\<img src="http://www.maestrosdelweb.com/images/2011/04/SanJuan2.jpg" title="San Juan Morro" />\<a href="http://www.flickr.com/photos/19114667@N00/2134221308/">Tomada por blucolt</a>\</div>\<div class="contentTxt">\<h2>San Juan Morro</h2>\<p>\En la cima del Antiguo San Juan, encontrarás al Fuerte San Felipe del Morro,\más conocido como El Morro. Esta construcción perteneciente al siglo XVI, fue\hecha para proteger a la ciudad de los ataques por mar, siendo uno de los elementos\más representativos de la antigua ciudad. Probablemente haya sido el monumento más\famoso en los tiempos de las colonias españolas y ahora la fortaleza sobresale en una\isleta rocosa.\</p>\</div>\<div class="clear"></div>\</div>'},{'position':new google.maps.LatLng(18.464008, -66.117776)

Page 34: Guia Mapas

44454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192

, 'info':'<div id="contentInfoWindow' + n++ + '" class="contentMap">\<div class="contentImg">\<img src="http://www.maestrosdelweb.com/images/2011/04/SanJuan3.jpg" title="San Juan Parque de las Palomas" />\<a href="http://www.flickr.com/photos/coltharp/2133445467/in/photostream/">Tomada por blucolt</a>\<img src="http://www.maestrosdelweb.com/images/2011/04/Sanjuan4.jpg" title="San Juan Parque de las Palomas" />\autor desconocido\</div>\<div class="contentTxt">\<h2>San Juan Parque de las Palomas</h2>\<p>\Sobre una de las murallas antiguas de la ciudad, con vista desde lo alto hacia el\Paseo de la Princesa, es el lugar perfecto para disfrutar de una vista espectacular\de la Bahía de San Juan, de la ciudad y de las montañas.\</p>\</div>\<div class="clear"></div>\</div>'},{'position':new google.maps.LatLng(18.470826, -66.136205), 'info':'<div id="contentInfoWindow' + n++ + '" class="contentMap">\<div class="contentImg">\<img src="http://www.maestrosdelweb.com/images/2011/04/ToaBaja.jpg" title="Toa Baja Isla de Cabras" />\autor desconocido\<img src="http://www.maestrosdelweb.com/images/2011/04/ToaBaja2.jpg" title="Toa Baja Isla de Cabras" />\<a href="http://www.flickr.com/photos/arturodonate/2825560234/">Tomada por arturodonate</a>\</div>\<div class="contentTxt">\<h2>Toa Baja Isla de Cabras</h2>\<p>\Debido a su localización estratégica en la entrada de la bahía de San Juan, Isla de Cabras\proveía un punto estratégico para un fuego cruzado en conjunto con el Fuerte San Felipe del Morro\en el otro lado de la bahía, para así prevenir que navíos invasores entraran.\</p>\</div>\<div class="clear"></div>\

Page 35: Guia Mapas

9394959697

</div>'}];n=1;for(var i in markers){marker = new google.maps.Marker({position: markers[i]['position'], map: map, zIndex: n});popup = new google.maps.InfoWindow({content: markers[i]['info'], zIndex: n});popup.open(map, marker);(function(id, popup){google.maps.event.addListener(popup, 'domready', function(){google.maps.event.addDomListener(document.getElementById('contentInfoWindow' + id), 'click', function(){popup.setZIndex(n++);});})})(n++, popup);}};

Notas:

Es buena programación el separar los archivos, como por ejemplo el de CSS. Para este material estaremos trabajando el CSS y HTML junto, para facilitar la enseñanza

El tamaño del InfoWindow es una combinación del contenido, el estilo que le hayas dado y del tamaño del mapa. Si el tamaño del InfoWindow no cabe en el tamaño establecido para el mapa, el API va a reducirlo para que se acomode

Añadir video de Youtube

Las etiquetas object tienden a sobre-ponerse a las demás. Una forma de evitarlo es llamar la etiqueta object una vez el InfoWindow esté al frente de todos los demás. Modificamos primero el área de trabajo para trabajar las etiquetas con CSS y añadimos el API de youtube:

?01020304

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>

Page 36: Guia Mapas

05060708091011121314151617181920212223242526272829303132333435363738394041424344

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}img{ border: 0; }.contentMap{width: 630px;border: 1px solid #336699;max-height:415px;overflow:auto;}.contentImg{float: left;width: 300px;margin-right: 10px;text-align: center;}.contentImg a{color: #369;font-size: 12px;}.contentTxt{float: left;width: 300px;}.clear{ clear: both; }.youtube{ cursor: pointer; }</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

Luego modificamos el archivo map.js:

?001002003004005

window.onload = function(){var options = {zoom: 14, center: new google.maps.LatLng(18.470338, -66.123503), mapTypeId: google.maps.MapTypeId.ROADMAP

Page 37: Guia Mapas

006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054

};var map = new google.maps.Map(document.getElementById('map'), options);var n=1;var markers = [{'position':new google.maps.LatLng(18.470338, -66.123503), 'info':'<div id="contentInfoWindow' + n + '" class="contentMap">\<div class="contentImg">\<a id="zoom' + n + '" href="#">Zoom</a>\<img src="http://www.maestrosdelweb.com/images/2011/04/SanJuan.jpg" title="San Juan Morro" />\Autor desconocido\<img src="http://www.maestrosdelweb.com/images/2011/04/SanJuan2.jpg" title="San Juan Morro" />\<a href="http://www.flickr.com/photos/19114667@N00/2134221308/">Tomada por blucolt</a>\</div>\<div class="contentTxt">\<h2>San Juan Morro</h2>\<p>\En la cima del Antiguo San Juan, encontrarás al Fuerte San Felipe del Morro,\más conocido como El Morro. Esta construcción perteneciente al siglo XVI, fue\hecha para proteger a la ciudad de los ataques por mar, siendo uno de los elementos\más representativos de la antigua ciudad. Probablemente haya sido el monumento más\famoso en los tiempos de las colonias españolas y ahora la fortaleza sobresale en una\isleta rocosa.\</p>\<div id="youtube' + n++ + '" class="youtube"></div>\</div>\<div class="clear"></div>\</div>', 'youtube':'xKiaeLhBhvk'}, {'position':new google.maps.LatLng(18.464008, -66.117776), 'info':'<div id="contentInfoWindow' + n + '" class="contentMap">\<div class="contentImg">\<a id="zoom' + n + '" href="#">Zoom</a>\<img src="http://www.maestrosdelweb.com/images/2011/04/SanJuan3.jpg" title="San Juan Parque de las Palomas" />\<a href="http://www.flickr.com/photos/coltharp/2133445467/in/photostream/">Tomada por blucolt</a>\<img src="http://www.maestrosdelweb.com/images/2011/04/Sanjuan4.jpg" title="San

Page 38: Guia Mapas

055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103

Juan Parque de las Palomas" />\autor desconocido\</div>\<div class="contentTxt">\<h2>San Juan Parque de las Palomas</h2>\<p>\Sobre una de las murallas antiguas de la ciudad, con vista desde lo alto hacia el\Paseo de la Princesa, es el lugar perfecto para disfrutar de una vista espectacular\de la Bahía de San Juan, de la ciudad y de las montañas.\</p>\<div id="youtube' + n++ + '" class="youtube"></div>\</div>\<div class="clear"></div>\</div>', 'youtube':'7NvCsS1Kt_s'}, {'position':new google.maps.LatLng(18.470826, -66.136205), 'info':'<div id="contentInfoWindow' + n + '" class="contentMap">\<div class="contentImg">\<a id="zoom' + n + '" href="#">Zoom</a>\<img src="http://www.maestrosdelweb.com/images/2011/04/ToaBaja.jpg" title="Toa Baja Isla de Cabras" />\autor desconocido\<img src="http://www.maestrosdelweb.com/images/2011/04/ToaBaja2.jpg" title="Toa Baja Isla de Cabras" />\<a href="http://www.flickr.com/photos/arturodonate/2825560234/">Tomada por arturodonate</a>\</div>\<div class="contentTxt">\<h2>Toa Baja Isla de Cabras</h2>\<p>\Debido a su localización estratégica en la entrada de la bahía de San Juan, Isla de Cabras\proveía un punto estratégico para un fuego cruzado en conjunto con el Fuerte San Felipe del Morro\en el otro lado de la bahía, para así prevenir que navíos invasores entraran.\</p>\<div id="youtube' + n++ + '" class="youtube"></div>\</div>\<div class="clear"></div>\</div>', 'youtube':'PZpF3FShJyc'}];n=1;

Page 39: Guia Mapas

104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152

var currentId;for(var i in markers){marker = new google.maps.Marker({position: markers[i]['position'], map: map, zIndex: n});popup = new google.maps.InfoWindow({content: markers[i]['info'], zIndex: n});popup.open(map, marker);(function(id, marker, popup, video){google.maps.event.addListener(popup, 'domready', function(){var a = document.getElementById('zoom' + id);a.onclick = function(){map.setMapTypeId(google.maps.MapTypeId.SATELLITE);map.setCenter(marker.getPosition());map.setZoom(16);return false;}var youtube = getImage(video, id);google.maps.event.addDomListener(youtube, 'click', function(){var object = document.createElement('object');object.id = 'player' + id;this.innerHTML = '';this.appendChild(object);// método de youtubeswfobject.embedSWF('http://www.youtube.com/v/' + video + '?f=user_uploads&app=youtube_gdata&rel=1&border=0&fs=1&autoplay=1',('player' + id), '300', '255', '9.0.0', false,false, {allowfullscreen: 'true'});});google.maps.event.addDomListener(document.getElementById('contentInfoWindow' + id), 'click', function(){if(id != currentId){popup.setZIndex(n++);currentId = id;}});google.maps.event.addListener(popup, 'zindex_changed', function(){for(var ii in markers){if(currentId == (parseInt(ii) + 1)){getImage(markers[ii]['youtube'], (parseInt(ii) + 1));}}});currentId = id;

Page 40: Guia Mapas

153154155156157

});})(n++, marker, popup, markers[i]['youtube']);}};function getImage(video, id){var img = document.createElement('img');img.src = 'http://img.youtube.com/vi/' + video + '/0.jpg';img.width = '300';img.height = '255';var youtube = document.getElementById('youtube' + id);youtube.innerHTML = '';youtube.appendChild(img);return youtube;}

¿Qué es lo que hace? Si pulsamos en la imagen de la derecha de cada InfoWindow se ejecuta el evento click del addDomListener que mira la etiqueta <div> que contiene el id youtube{n}, donde {n} puede ser uno de los tres elementos creados que tiene el contenido de youtube. Se crea la etiqueta object, se añade el video correspondiente y luego se añade la etiqueta object a la etiqueta que tiene el id youtube{n}.

Si queremos ver otra burbuja, seleccionamos la que deseamos y se ejecutan dos eventos, el que contiene el id contentInfoWindow{n}, este tiene todo el contenido del InfoWindow y el evento

Page 41: Guia Mapas

zindex_changed que verifica si hubo algún cambio en el zIndex del InfoWindow. Este último vuelve a colocar las imagenes en el elemento <div> con el id youtube{n} en aquel InfoWindow que no se encuentre alfrente.

También se añadió un enlace llamado Zoom. Lo que hace es cambiar el tipo de mapa, acercarlo más y centrar el mapa al marcador.

Añadir mapa

Podemos crear un mapa, en el InfoWindow, mostrándolo con más detalle. Modificamos el área de trabajo:

?

01020304050607080910111213141516171819202122232425

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}.contentMap{width: 400px;height: 400px;border: 1px solid #336699;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

El map.js lo modificamos así:

?0102030405060708

window.onload = function(){var options = {zoom: 14, center: new google.maps.LatLng(18.470338, -66.123503), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);

Page 42: Guia Mapas

09101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657

var n=1;var markers = [{'position':new google.maps.LatLng(18.470338, -66.123503), 'info':'<div id="contentInfoWindow' + n++ + '" class="contentMap"></div>'},{'position':new google.maps.LatLng(18.464008, -66.117776), 'info':'<div id="contentInfoWindow' + n++ + '" class="contentMap"></div>'},{'position':new google.maps.LatLng(18.470826, -66.136205), 'info':'<div id="contentInfoWindow' + n++ + '" class="contentMap"></div>'}];n=1;for(var i in markers){marker = new google.maps.Marker({position: markers[i]['position'], map: map});popup = new google.maps.InfoWindow({content: markers[i]['info'], zIndex: n});popup.open(map, marker);(function(id, popup, marker){google.maps.event.addListener(popup, 'domready', function(){var div = document.createElement('div');div.style.width = '100%';div.style.height = '100%';var root = document.getElementById('contentInfoWindow' + id);root.appendChild(div);var divOptions = {zoom: 17, center: marker.getPosition(), mapTypeId: google.maps.MapTypeId.HYBRID, disableDefaultUI: true, draggable: false};var divMap = new google.maps.Map(div, divOptions);var divMarker = new google.maps.Marker({position: marker.getPosition(), map: divMap, clickable: false});

Page 43: Guia Mapas

585960616263646566

google.maps.event.addDomListener(root, 'click', function(){popup.setZIndex(n++);});})})(n++, popup, marker);}};

Polilíneas y Polígonos en Google MapLas Polilíneas y los Polígonos son unas herramientas muy útiles para mostrar carreteras, bordes y otro tipo de información.

Área de trabajo

Continuaremos con el área de trabajo que hemos usado a través de los capítulos:

Capítulo uno: Google Maps API V3 introducción y primeros pasos Capítulo dos: Marcadores, posicionar una imagen en el mapa Capítulo tres: Consejos prácticos para el InfoWindow en Google Maps

?0102030405060708091011121314151617

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head>

Page 44: Guia Mapas

1819

<body><div id="map"></div></body></html>

Polilíneas

Consiste de una serie de segmentos conectados por vértices (línea recta creada por dos puntos) que forman un único objeto. Para poder crear una polilínea se requiere usar la clase google.maps.Polyline. Requiere de dos argumentos dentro del objeto google.maps.PolylineOptions, path y map.

path: requiere de varios puntos que indican la latitud y longitud usando la clase google.maps.LatLng

map: el mapa donde se va a mostrar la polilínea, usando la clase google.maps.Map

?01020304050607080910111213141516171819202122232425

window.onload = function(){var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP, draggableCursor: 'default', draggingCursor: 'default'};var map = new google.maps.Map(document.getElementById('map'), options);var routes = [new google.maps.LatLng(17.997671, -66.615356), new google.maps.LatLng(18.459418, -66.060646)];var polyline = new google.maps.Polyline({path: routes, map: map, strokeColor: '#ff0000', strokeWeight: 5, strokeOpacity: 0.3, clickable: false});};

Nota: Para poder quitar las líneas del mapa, se puede lograr usando el método de setMap y como valor null.

Page 45: Guia Mapas

El array que se usó para mostrar la ruta, google maps lo convierte a un MVCArray cuando lo indico en el path del PolylineOptions. MVCArray es un objeto que tiene otros objetos. La diferencia entre un MVCArray a un array regular es que si creas los puntos usando MVCArray, luego puedes añadir otro punto, insertándolo en el MVCArray y el mapa lo reconoce automáticamente, mientras que un array regular tienes que indicarle al mapa el nuevo punto e insertarlo en el path del PolylineOptions.

?010203040506070809101112131415161718192021222324252627

window.onload = function(){var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP, draggableCursor: 'default', draggingCursor: 'default'};var map = new google.maps.Map(document.getElementById('map'), options);var routes = new google.maps.MVCArray();var polyline = new google.maps.Polyline({path: routes, map: map, strokeColor: '#ff0000', strokeWeight: 3, strokeOpacity: 0.4, clickable: false});google.maps.event.addListener(map, 'click', function(e){var path = polyline.getPath();path.push(e.latLng);});};

Nota: Como indicamos en la definición, una polilínea consiste de una serie de segmentos conectados por vertices que esto representa dos puntos que hacen una línea, por lo que la línea aparecerá luego que marquemos el segundo punto.

Para poder crear múltiples polilíneas, se necesita crear diferentes clases de google.maps.Polyline.

?010203040506

/*** Sugerencias y correcciones por Jonathan (zerokilled)* http://www.forosdelweb.com/miembros/zerokilled/*/window.onload = function(){var hexVal = "0123456789ABCDEF".split("");

Page 46: Guia Mapas

07080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

var defaultColor = '#f00';var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP, draggableCursor: 'default', draggingCursor: 'default'};var map = new google.maps.Map(document.getElementById('map'), options);var polyline = new google.maps.Polyline({path: new google.maps.MVCArray(), map: map, strokeColor: defaultColor, strokeWeight: 3, strokeOpacity: 0.5});function makeColor(){/*** Otra forma de crear un color aleatoriamente:** for(var color = Math.floor(Math.random()*0xffffff).toString(16); color.length < 6; color = '0'+color);* return '#' + color;*/return '#' + hexVal.sort(function(){return (Math.round(Math.random())-0.5);}).slice(0,6).join('');}polyline.currentColor = makeColor();google.maps.event.addListener(polyline, 'click', function(e){polyline.setOptions({strokeColor: polyline.currentColor});polyline = this, this.setOptions({strokeColor: defaultColor});});google.maps.event.addListener(map, 'rightclick', function(){polyline.setOptions({strokeColor: polyline.currentColor});polyline = new google.maps.Polyline({path: new google.maps.MVCArray(), map: map, strokeColor: defaultColor, strokeWeight: 3, strokeOpacity: 0.5});polyline.currentColor = makeColor();google.maps.event.addListener(polyline, 'click', function(){polyline.setOptions({strokeColor: polyline.currentColor});polyline = this, this.setOptions({strokeColor: defaultColor});});});

Page 47: Guia Mapas

565758596061626364

google.maps.event.addListener(map, 'click', function(e){polyline.getPath().push(e.latLng);});};

Empezamos pulsando en el mapa para crear una polilínea, luego del segundo punto es que se muestra en el mapa la línea. Para crear una nueva polilínea pulsamos el botón de la derecha del ratón en cualquier parte del mapa, el evento rightclick del addListener se ejecuta y añade una nueva clase google.maps.Polyline. Ahora podemos trazar una nueva polilinea, con diferente color. Si queremos volver a añadir más puntos a alguna polilínea ya mencionada, la podemos seleccionar y seguir trabajando donde se quedó el último punto que hayamos indicado.

Polígonos

Los polígonos son objetos cerrados. Con la clase google.maps.Polygon se crean los polígonos. Requiere de dos argumentos dentro del objeto google.maps.PolygonOptions, path y map.

path: requiere de varios puntos que indican la latitud y longitud usando la clase google.maps.LatLng

map: el mapa donde se va a mostrar el polígono, usando la clase google.maps.Map

Modificamos un poco el código de polilíneas y podemos crear múltiples polígonos de la misma forma como lo hicimos con las polilíneas

?010203040506070809101112131415161718

/*** Sugerencias y correcciones por Jonathan (zerokilled)* http://www.forosdelweb.com/miembros/zerokilled/*/window.onload = function(){var hexVal = "0123456789ABCDEF".split("");var defaultColor = '#ff0000';var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.5), mapTypeId: google.maps.MapTypeId.ROADMAP, draggableCursor: 'default', draggingCursor: 'default'};var map = new google.maps.Map(document.getElementById('map'), options);var polygon = new google.maps.Polygon({path: new google.maps.MVCArray(), map: map

Page 48: Guia Mapas

19202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

, strokeColor: defaultColor, strokeWeight: 3, strokeOpacity: 0.5, fillColor: defaultColor, fillOpacity: 0.3, clickable: false});function makeColor(){/*** Otra forma de crear un color aleatoriamente:** for(var color = Math.floor(Math.random()*0xffffff).toString(16); color.length < 6; color = '0'+color);* return '#' + color;*/return '#' + hexVal.sort(function(){return (Math.round(Math.random())-0.5);}).slice(0,6).join('');}polygon.currentColor = makeColor();google.maps.event.addListener(polygon, 'click', function(e){polygon.setOptions({strokeColor: polygon.currentColor, fillColor: polygon.currentColor, clickable: true});polygon = this, this.setOptions({strokeColor: defaultColor, fillColor: defaultColor, clickable: false});});google.maps.event.addListener(map, 'rightclick', function(){polygon.setOptions({strokeColor: polygon.currentColor, fillColor: polygon.currentColor, clickable: true});polygon = new google.maps.Polygon({path: new google.maps.MVCArray(), map: map, strokeColor: defaultColor, strokeWeight: 3, strokeOpacity: 0.5, fillColor: defaultColor, fillOpacity: 0.3, clickable: false});polygon.currentColor = makeColor();

Page 49: Guia Mapas

6869707172737475767778798081828384858687888990

google.maps.event.addListener(polygon, 'click', function(){polygon.setOptions({strokeColor: polygon.currentColor, fillColor: polygon.currentColor, clickable: true});polygon = this, this.setOptions({strokeColor: defaultColor, fillColor: defaultColor, clickable: false});});});google.maps.event.addListener(map, 'click', function(e){polygon.getPath().push(e.latLng);});};

A diferencia de polilíneas, necesitamos indicar que cuando esté seleccionado el polígono no sea “clickeable” y así poder marcar la línea dentro del polígono si fuera necesario.

Librerías y manejo masivos de marcadoresUn problema común para los desarrolladores es la necesidad de trabajar con grandes números de marcadores, se puede dificultar el navegar con muchos marcadores porque se vuelve lento el navegador y también visualizar los datos del mapa.

Lo primero que debemos preguntarnos es ¿cuántos marcadores se consideran muchos? Eso dependerá de varios factores, entre ellos:

Rendimiento: mientras más marcadores añadas más lento se vuelve el mapa. Indicar a cual número de marcador se vuelve lento el mapa es difícil de decir. Todo va a depender de qué navegador se use

Usabilidad: mientras más marcadores añadas más difícil puede ser para el usuario encontrar el punto que desea

Por lo general con menos de 100 marcadores no debe haber problemas (siempre y cuando los marcadores estén distribuidos a través del mapa y se pueda visualizar corréctamente), cuando hay más de 100 se debe cuestionar:

¿Es el mapa lento?

Page 50: Guia Mapas

¿Es difícil de visualizar? ¿Es difícil de verificar la data en el mapa?

Si respondes que sí a una de esas preguntas, entonces piensa como mejorar el rendimiento o la forma de como se debe visualizar la data.

Manejando los marcadores

Una forma de trabajar los marcadores es filtrándolos, crear un menú y que tenga solo seleccionado algunos por defecto y que el usuario luego escoja aquellos que desee visualizar.

index.html

?010203040506070809101112131415161718192021222324252627282930313233343536

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}#menu{width: 200px;margin: 0 auto;background-color: #fff;border: 1px solid #333;position: relative;top: -50px;text-align: center;padding: 5px;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div><div id="menu"><form action="index.html" method="get"><input type="checkbox" id="foo" name="fooBarBaz" /> <label for="foo">Foo</label><input type="checkbox" id="bar" name="fooBarBaz" /> <label for="bar">Bar</label><input type="checkbox" id="baz" name="fooBarBaz" /> <label for="baz">Baz</label>

Page 51: Guia Mapas

</form></div></body></html>

map.js

?010203040506070809101112131415161718192021222324252627282930313233343536373839404142

/*** Listener para el formulario*/function addListener(element, type, expression, bubbling){bubbling = bubbling || false;if(element.addEventListener) { // Standardelement.addEventListener(type, expression, bubbling);return true;}else if(element.attachEvent) { // IEelement.attachEvent('on' + type, expression);return true;}else return false;}window.onload = function(){var fooArr = [], barArr = [], bazArr = [];var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.3), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var southWest = new google.maps.LatLng(17.85, -67.35);var northEast = new google.maps.LatLng(18.55, -65.2);var lngSpan = northEast.lng() - southWest.lng();var latSpan = northEast.lat() - southWest.lat();for(var i=1; i<=1000; i++){var lat = southWest.lat() + latSpan * Math.random();var lng = southWest.lng() + lngSpan * Math.random();var latlng = new google.maps.LatLng(lat, lng);var marker = new google.maps.Marker({position: latlng});if((i%3) == 0){ bazArr.push(marker); }else if((i%2) == 0){ barArr.push(marker); }else{ fooArr.push(marker); }}document.getElementById('foo').checked = true;for(var i in fooArr){fooArr[i].setMap(map);}addListener(document.getElementById('foo'), 'click', function(){

Page 52: Guia Mapas

4344454647484950515253545556575859606162636465666768697071727374757677787980818283

if(this.checked){for(var i in fooArr){fooArr[i].setMap(map);}}else{for(var i in fooArr){fooArr[i].setMap(null);}}});addListener(document.getElementById('bar'), 'click', function(){if(this.checked){for(var i in barArr){barArr[i].setMap(map);}}else{for(var i in barArr){barArr[i].setMap(null);}}});addListener(document.getElementById('baz'), 'click', function(){if(this.checked){for(var i in bazArr){bazArr[i].setMap(map);}}else{for(var i in bazArr){bazArr[i].setMap(null);}}});};

Librerías

Google maps tiene librerías adicionales para trabajar con el mapa. Todas las librerías adicionales las podemos ver en Libraries y las mencionadas en este capítulo son MarkerClusterer y MarkerManager.

Nota: Podemos usar las librerías desde la dirección web, pero lo aconsajable es que descarguen el archivo (o copien y peguen el código en un archivo js), para evitar que si hacen una actualización al código, no se afecte lo que han trabajado. También es aconsejable trabajar con la compilación. Para

Page 53: Guia Mapas

propósitos de enseñanza lo trabajaremos indicando la dirección web oficial directamente.

MarkerClusterer

MarkerCulterer agrupa los marcadores y muestra la cantidad de marcadores que hay en cierto segmento. En la documentación en el directorio llamado examples, muestra varios ejemplos de como utilizar esta librería. Para usarla se puede bajar el archivo markerclusterer.js, markerclusterer_compiled.js o colocar en el src de script directamente la dirección de la librería.

index.html

?

0102030405060708091011121314151617181920

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer_compiled.js"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

map.js

?010203040506070809101112

window.onload = function(){var markers = [];var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.3), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var southWest = new google.maps.LatLng(17.85, -67.35);var northEast = new google.maps.LatLng(18.55, -65.2);var lngSpan = northEast.lng() - southWest.lng();

Page 54: Guia Mapas

131415161718192021222324252627

var latSpan = northEast.lat() - southWest.lat();for(var i=1; i<=5000; i++){var lat = southWest.lat() + latSpan * Math.random();var lng = southWest.lng() + lngSpan * Math.random();var latlng = new google.maps.LatLng(lat, lng);var marker = new google.maps.Marker({position: latlng});markers.push(marker);}var markerclusterer = new MarkerClusterer(map, markers);};

Estos son los posibles colores que se pueden mostrar en el mapa que viene por defecto:

Azul 2-9 Amarillo 10-99 Rojo 100-999 Violeta 1,000-9,999 Violeta oscuro 10,000+

El comportamiento que trae por defecto la clase MarkerClusterer se puede modificar en el tercer parametro. Las posibles opciones son:

gridSize: Número entero. Valor por defecto 60 maxZoom: Número entero entre el 1 al 23. Indica hasta donde debe hacer el agrupamiento zoomOnClick: Valor booleano para hacer “zoom” al pulsar en el marcador. true o false.

Valor por defecto true averageCenter: Centrar aproximádamente el marcador. true o false. Valor por defecto true

minimumClusterSize: Número mínimo para agrupar los marcadores. Por defecto 2

styles: Es un array que contiene uno o varios objetos de MarkerStyleOptions.Posibles valores son:

url: La dirección de la imagen a mostrar height: El alto de la imagen width: El ancho de la imagen anchor: Array con la posición x y y de los números en la imagen. Por defecto centrado textColor: Color de los números. Por defecto black textSize: Tamaño de los números. Por defecto 11 backgroundPosition: Posición del fondo

Es importante el orden en que se indican los objetos en el tercer parametro de la clase MarkerClusterer, las imágenes se van a mostrar conforme al orden de los valores numéricos indicados en los colores por defecto.

También los números de imágenes a colocar son importante, ya que si se coloca uno, esa es la imagen a mostrar en cada uno de los niveles indicados en los colores, si son dos la primera representa el primer

Page 55: Guia Mapas

valor numérico y la segunda del segundo al quinto, si se colocan tres, la primera representa el primer valor numérico, la segunda el segundo y la tercera del tercero al quinto y así sucesivamente.

map.js

?0102030405060708091011121314151617181920212223242526272829303132333435363738394041424344

window.onload = function(){var markers = [];var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.3), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var southWest = new google.maps.LatLng(17.85, -67.35);var northEast = new google.maps.LatLng(18.55, -65.2);var lngSpan = northEast.lng() - southWest.lng();var latSpan = northEast.lat() - southWest.lat();for(var i=1; i<=1000; i++){var lat = southWest.lat() + latSpan * Math.random();var lng = southWest.lng() + lngSpan * Math.random();var latlng = new google.maps.LatLng(lat, lng);var marker = new google.maps.Marker({position: latlng});markers.push(marker);}var markerclusterer = new MarkerClusterer(map, markers, {gridSize: 60, maxZoom: 11, zoomOnClick: false, minimumClusterSize: 4, averageCenter: true, styles: [{url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people35.png", height: 35, width: 35, textColor: 'white', textSize: 12, anchor: [1,1]},{url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people45.png", height: 45, width: 45, textColor: 'white', textSize: 14, anchor: [1,30]

Page 56: Guia Mapas

4546474849505152535455

},{url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people55.png", height: 55, width: 55, textColor: 'white', textSize: 16, anchor: [40,40]}]});};

MarkerManager

MarkerManager es bien similar a MarkerClusterer en que puede agrupar varios marcadores, pero su trabajo principal es mostrar solo aquellos marcadores en el “viewport” corriente. Al mover el mapa se van mostrando los puntos de acuerdo al “viewport” que se encuentra el usuario. También se puede indicar desde cuál nivel de “zoom” deseamos mostrar los marcadores. Cuando el usuario acerque o aleje el mapa, MarkerManager mostrará aquel o aquellos marcadores indicados en ese “zoom”.

index.html

?

0102030405060708091011121314151617181920

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>test</title><style>*{ margin: 0; padding: 0; }html, body, #map{width: 100%;height: 100%;}</style><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script><script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/tags/markermanager/1.0/src/markermanager_packed.js"></script><script type="text/javascript" src="js/map.js"></script></head><body><div id="map"></div></body></html>

map.js

?0102window.onload = function(){var markers = [];

Page 57: Guia Mapas

0304050607080910111213141516171819202122232425262728293031

var options = {zoom: 9, center: new google.maps.LatLng(18.2, -66.3), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var markerManager = new MarkerManager(map);var southWest = new google.maps.LatLng(17.85, -67.35);var northEast = new google.maps.LatLng(18.55, -65.2);var lngSpan = northEast.lng() - southWest.lng();var latSpan = northEast.lat() - southWest.lat();for(var i=1; i<=1000; i++){var lat = southWest.lat() + latSpan * Math.random();var lng = southWest.lng() + lngSpan * Math.random();var latlng = new google.maps.LatLng(lat, lng);var marker = new google.maps.Marker({position: latlng});markers.push(marker);}google.maps.event.addListener(markerManager, 'loaded', function() {markerManager.addMarkers(markers, 8, 10);markerManager.refresh();});};

En la clase MarkerManager también se puede modificar algunos de sus comportamientos, en el segundo parametro. Las posibles opciones son:

maxZoom: Número entero entre el 1 al 23. Indica hasta donde debe trabajar MarkerManager borderPadding: MarkerManager muestra solo aquellos que están en el “viewport”, pero

tiene una zona adicional al “viewport” para mostrar marcadores adicionales. La razón es que cuando se mueva el mapa a cortas distancias ya tenga recargado también algunos marcadores. Por defecto esta zona de buffer es de 100

trackMarkers: true o false. Si cambiamos la posición de un marcador después que lo hayas añadido al MarkerManager se van a reflejar dos simultaneamente. Al colocar esta opción como valor true le indicamos al MarkerManager que recargue de nuevo los marcadores y así se ve reflejado una sola vez el marcador que se haya modificado. Esto representa que el código corra más lento, así que si no se modificara la posición de los marcadores se aconseja dejarlo como viene por defecto con valor false

map.js

?010203

window.onload = function(){var markers = [];var options = {

Page 58: Guia Mapas

0405060708091011121314151617181920212223242526272829303132333435

zoom: 9, center: new google.maps.LatLng(18.2, -66.3), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var markerManager = new MarkerManager(map, {maxZoom: 10, borderPadding: 60, trackMarkers: true});var southWest = new google.maps.LatLng(17.85, -67.35);var northEast = new google.maps.LatLng(18.55, -65.2);var lngSpan = northEast.lng() - southWest.lng();var latSpan = northEast.lat() - southWest.lat();for(var i=1; i<=1000; i++){var lat = southWest.lat() + latSpan * Math.random();var lng = southWest.lng() + lngSpan * Math.random();var latlng = new google.maps.LatLng(lat, lng);var marker = new google.maps.Marker({position: latlng});markers.push(marker);}google.maps.event.addListener(markerManager, 'loaded', function() {markerManager.addMarkers(markers, 8, 10);markerManager.refresh();});};

Trabajando con los niveles

Se trabaja similar al MarkerClusterer pero se puede indicar en cada uno de los niveles de “zoom”, qué tipo de imagen queremos mostrar.

map.js

?010203040506070809

window.onload = function(){var options = {zoom: 13, center: new google.maps.LatLng(18.372201, -66.139797), mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('map'), options);var mnr = new MarkerManager(map);

Page 59: Guia Mapas

101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657

google.maps.event.addListenerOnce(map, 'bounds_changed', function(){var markers = [];var bounds = map.getBounds();var southWest = bounds.getSouthWest();var northEast = bounds.getNorthEast();var lngSpan = northEast.lng() - southWest.lng();var latSpan = northEast.lat() - southWest.lat();for (var i = 0; i < 1000; i++) {var lat = southWest.lat() + latSpan * Math.random();var lng = southWest.lng() + lngSpan * Math.random();var latlng = new google.maps.LatLng(lat, lng);var marker = new google.maps.Marker({position: latlng});markers.push(marker);}var bayamon = new google.maps.Marker({position: new google.maps.LatLng(18.383563, -66.162713), icon: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people35.png'});google.maps.event.addListener(bayamon, 'click', function() {map.setZoom(14);map.setCenter(this.getPosition());});var guaynabo = new google.maps.Marker({position: new google.maps.LatLng(18.3580678, -66.112674), icon: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/people35.png'});google.maps.event.addListener(guaynabo, 'click', function() {map.setZoom(14);map.setCenter(this.getPosition());});var towns = [bayamon, guaynabo];google.maps.event.addListener(mnr, 'loaded', function() {this.addMarkers(towns, 10, 13);this.addMarkers(markers, 14);this.refresh();});});};

Si alejamos el mapa continuará con la misma imagen hasta el “zoom”

Page 60: Guia Mapas

10, pero si lo acercamos veremos todos los marcadores. Es una buena forma de agrupar y mostrar de acuerdo al nivel de “zoom” que deseamos, esto nos da un mejor control.

El próximo capítulo estará dedicado a Geocoder.

Geolocalización, móviles y mapasLa Geolocalización es la determinación de tu ubicación geográfica por medio de tu dispositivo móvil o tu computadora, por cualquiera de los medios disponibles para lograrlo. Para determinar tu ubicación, existen varias maneras de hacerlo, entre ellas están la identificación del router al que te estás conectado, la red de tu proveedor, tu celular o directamente por el receptor interno de GPS de tu dispositivo.

Para aprovechar la geolocalización de los visitantes de tu sitio o a tu aplicación web ten en cuenta que no todos los navegadores lo soportan, es importante también mencionar que el usuario debe autorizar a tu sitio o aplicación web para que ésta obtenga tu posición, no asumir en tu desarrollo que siempre vas a tener la ubicación y saber manejar éstas excepciones.

No está de mas recalcar que ninguno de estos métodos son parte de la API de Google Maps, en cambio, son las normas comunes de la industria. Cada día los navegadores más recientes están empezando a soportar el estándar del W3C de geolocalización.

Introducción a la especificación de la API de Geolocalización

La API de Geolocalización es un esfuerzo de la World Wide Web Consortium(W3C) para estandarizar una interfaz para recuperar la información de la localización geográfica de un dispositivo cliente. La API define un conjunto de objetos, que se ejecutan en la aplicación cliente para dar la ubicación del dispositivo cliente a través de la consulta de los servidores de información de la localización.

Esto se realiza por medio de una interfaz de alto nivel de información de localización asociada sólo con el dispositivo que aloja la aplicación, la información que proporciona es la siguiente: latitud, longitud, altura, rumbo, velocidad y valores de precisión de los reportes.

La API es independiente de las fuentes de información y debe ser transparente en su uso de como se obtuvo la localización. Algunas fuentes comunes de información sobre la ubicación incluyen los Sistema de Posicionamiento Global (GPS) y la ubicación originada de las señales de red como la dirección IP, RFID, WiFi y Bluetooth , redes GSM / CDMA de celulares, así como se puede hacer una entrada directa del usuario. Por lo anterior la API no puede garantizar devolver la ubicación real del dispositivo.

Aplicaciones web en dispositivos móviles

La API de geolocalización es ideal para aplicaciones web en dispositivos móviles, que es el tema de esté capítulo. Sin embargo, hay que tener presente que aún no existe un apoyo generalizado en plataformas móviles debido a la gran variedad de dispositivos y navegadores.

En equipos Desktop, la API de geolocalización del W3C trabaja en Firefox desde la versión 3.5, Google Chrome, Opera 10.6 y en Internet Explorer desde la versión 9.0. En los dispositivos móviles,

Page 61: Guia Mapas

funciona en iPhone, Google Android (Desde Ver. 2.0 +), y Maemo. El API de Geolocalización W3C también está soportado desde la versión 10.1 de Opera Mobile disponible para Android y Symbian (S60 3 ª y 5 ª generación).

La API se ha diseñado para permitir peticiones de posición instantánea y peticiones continuas de actualización de posición, así como la posibilidad de consultar explícitamente las posiciones en caché. La información de ubicación está representada por coordenadas de latitud y longitud. Técnicamente esta norma no es parte de HTML5 pero ya está siendo implementada como tal y probablemente se convertirá en el estándar default en el futuro, recientemente sistemas móviles como los Blackberry de RIM que tenían otro estándar lo han adoptado a partir de la versión OS 6, los dispositivos Android y con iOs (iPod, iPad, IPhone) ya lo soportan.

Algunos navegadores utilizan direcciones IP para detectar la ubicación de un usuario, aunque esto sólo proporciona una estimación muy aproximada.

Solicitud de posición instantánea:

?010203040506070809101112131415161718192021222324252627282930313233

function MostrarMapa(pos) {// Código para mostrar mapa centrado en// pos.coords.latitude, pos.coords.longitude.}// Llamada de petición de posición instantaneanavigator.geolocation.getCurrentPosition(MostrarMapa);Solicitud continuada de posición:function CentrarMapa(pos) {// Código para centrar el mapa en// pos.coords.latitude, pos.coords.longitude, esta función se ejecuta// constantemente mientras el dispositivo detecte cambio de posición}// Solicitud de Monitoreo de Posiciónvar MonitorearPosicion = navigator.geolocation.watchPosition(CentrarMapa);function buttonClickHandler() {// Cancela las actualizaciones y llamadas a CentrarMapa, por ejemplo// al hacer Click en un botón navigator.geolocation.clearWatch(MonitorearPosicion);}

Page 62: Guia Mapas

34353637

Ejemplo de localización básica:

?010203040506070809101112131415161718192021

<!DOCTYPE html><meta charset="utf-8"><html><script type="text/javascript">function pedirPosicion(pos) {document.write("¡Hola! Estas en : "+pos.coords.latitude+ ","+pos.coords.longitude);document.write(" Rango de localización de +/- "+pos.coords.accuracy+" metros");}navigator.geolocation.getCurrentPosition(pedirPosicion);</script></html>

Te pedirá que autorices a tu sitio que permita conocer tu ubicación lo cual tienes que aceptar.

Si todo te ha funcionado te debería salir algo así:

¡Hola! Estas en : 14.5949159,-90.5117639 Rango de localización de +/- 80 metros

Ver ejemplo: te proporcionará tu ubicación si lo autorizas.

Como pudiste ver esto no es parte de ninguna API de Google maps o algún otro servicio, es un estándar implementado en casi todos los navegadores modernos.

Hagamos un mapa centrado en nuestra ubicación

Haremos un mapa muy simple, el cual inicia en una posición y al presionar un link intenta geolocalizarte y centra el mapa en tu posición, lo único que hice es tomar el código ya explicado y combinarlo con un mapa simple, para mas opciones sobre el mapa puedes consultar el capítulo 1 de la Guía Mapas.

?0102<!DOCTYPE html><html>

Page 63: Guia Mapas

0304050607080910111213141516171819202122232425262728293031323334353637383940

<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /><meta http-equiv="content-type" content="text/html; charset=UTF-8"/><title>Ejemplo de un mapa muy simple y geolocalización - Google API v3</title><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script><script type="text/javascript">var map; //importante definirla fuera de la funcion initialize() para poderla usar desde otras funciones.function initialize() {var punto = new google.maps.LatLng(17.22207, -89.6235); //ubicación del Plaza Central de Tikal, Guatemalavar myOptions = {zoom: 18, //nivel de zoom para poder ver de cerca.center: punto,mapTypeId: google.maps.MapTypeId.SATELLITE //Tipo de mapa inicial, satélite para ver las pirámides}map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);}//copiamos la función de geolocalización del ejemplo anterior.function pedirPosicion(pos) {var centro = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude);map.setCenter(centro); //pedimos que centre el mapa..map.setMapTypeId(google.maps.MapTypeId.ROADMAP); //y lo volvemos un mapa callejeroalert("¡Hola! Estas en : "+pos.coords.latitude+ ","+pos.coords.longitude+" Rango de localización de +/- "+pos.coords.accuracy+" metros");}function geolocalizame(){navigator.geolocation.getCurrentPosition(pedirPosicion);}</script></head><body onload="initialize()"><div id="map_canvas" style="width:640px ;height:480px"></div><a href="#" onclick="geolocalizame()">Ahora llevame a mi ubicación</a></body></html>

Como ves, tomé el código que habíamos hecho antes y lo modifiqué para ponerlo en un mapa.

Page 64: Guia Mapas

Ver ejemplo: revisa cómo funciona el mapa.

Conclusiones

La API de Google Maps V3 ha sido diseñada para cargar rápidamente y funcionar bien en dispositivos móviles. Esta se ha centrado principalmente en teléfonos Android y iPhone, lo cual es una ventaja pues no tenemos que hacerle nada a nuestro mapa para que éste puedar ser visto en un teléfono celular de los mencionados, incluso cambiando los controles automáticamente de acuerdo al dispositivo.

La especificación de Geolocalización de W3C es mucho mas extensa, puedes agregar controles para mejorar la precisión, forzar actualizaciones constantes entre otras cosas, ésto dependerá de la necesidad que tengas de tener el GPS prendido todo el tiempo toda vez que es un elemento a considerar por el consumo de tu batería.

Open Street Maps: buscando alternativas a Google Maps¿Quieres saber como llegar a X lugar? ¿Ubicar en donde estás? ¿Estás desarrollando un proyecto que requiere utilizar mapas? Seguramente recurres a la herramienta salvadora: Google Maps. Este servicio fue creado por Lars y Jens Rasmussen y es ofrecido por Google desde el año 2006. En la guia mapas te ayudamos a dar los primeros pasos con la API, crear marcadores y trabajar con geolocalización.

La API de Google Maps ha sufrido cambios en lo que se refiere a la utilización libre y gratuita de la plataforma: a partir de 20.000 teselas los desarrolladores tienen que comenzar a pagar pero hay alternativas viables para utilizar y desarrollar mapas, hoy queremos hablar de OpenStreetMap.

Page 65: Guia Mapas

Contactamos a referentes del proyecto en diferentes países de latinoamérica, ellos nos comentaron sobre OSM como alternativa, las características de la comunidad y nos hablaron de los cambios en la API de Google Maps.

OpenStreetMap: Mapas por y para todos

Julio Costa, es chileno, trabaja como asesor de eLearning en el ministerio de defensa de su país, es fundador de ZambelliKnowledge y miembro fundador de OpenStreetMap Chile. En un artículo que escribió sobre OpenStreetMap en Latinoamérica nos comentaba en qué consiste el proyecto:

OpenStreetMap (OSM) es un proyecto global destinado a generar y proveer datos geográficos libres a todos quienes lo requieran. Una de las razones para iniciar el proyecto fue que los datos geográficos que normalmente consideramos libres, no lo son realmente. En muchos casos se trata de la dicotomía Gratis/Libre.

Para ser parte del proyecto uno tiene que querer “mapear” y tener conocimientos informáticos mínimos ya que según Julio “incluso el editor más fácil tiene una curva de aprendizaje bastante empinada”. Nos comenta también que “debe tener cierta ética para no romper los mapas de otros usuarios, nos hemos topado con usuarios que crean ciudades fantasmas”.

El verdadero desafío es que se difunda el proyecto, para que a la gente le interese mapear.

El objetivo de OSM es claro, Julio nos dice que es:

Generar cartografía y ponerla a disposición de todo el mundo.

Ventajas de OSM frente a Google Maps

En lo que coinciden todos es que la gran ventaja de OSM se resume en una palabra: Libertad. Como dice Hernán Ramirez (Venezuela): “En OSM los mapas son libres de verdad”. Es libre para uso comercial o personal y los datos geográficos se pueden descargar en formato digital (a diferencia de Google Maps) y pueden ser utilizados en cualquier formato SIG, receptor GPS, o servidor de geodatos. Además el mapa es “fácilmente editable y personalizable” nos cuenta Gustavo Jarrín (Ecuador).

Ante los cambios de Google Maps, es un buen momento para conocer OSM

Sebastián Dulmont (@sd), utiliza muchos mapas para su sitio Streeteasy.com, un buscador web de bienes raíces. En una entrevista nos comentó que utilizaban Google Maps y que estaban muy contentos con el servicio pero al modificarse los precios y ser más estrictos con el pago, tuvieron que pensar en otra alternativa.

Ante la perspectiva de tener que pagar 100.000$ si seguían con el servicio de Google Maps, Sebastián y su equipo buscaron otras alternativas “cartográficas” opensource, entre las cuales encontraron a OSM. Una de las ventajas principales fue la posibilidad de modificar algo si estaba mal y mayor control de la información.

Page 66: Guia Mapas

“Lo importante no es que una plataforma sea gratis, lo importante es que sea libre.”

Las comunidades de OSM en latinoamérica, ven una alternativa viable no solo por ser gratis sino porque la información “te pertenece”. Nos dice Julio Costa que la api de Google Maps tiene muchas opciones y a nivel de grandes empresas y multinacionales quizás sea bueno pero la api de OSM “lo que hace es intermediar entre los seguidores y la base de datos”.

Dar herramientas para crear los datos, almacenarlos y ponerlos a disposición de todo el mundo.

Norman Avila, autor de capítulos para la guía Mapas, nos dice que “OSM nació como plataforma abierta y permanece abierta, es la alternativa más consistente y más confiable”. Según los datos actualizados que nos brindó Julio en la entrevista, OSM ya llegó a los 500.00 usuarios registrados que es la gente que efectivamente puede editar los mapas, ya que “no hay ediciones anónimas como en Wikipedia”.

Para todos los que alguna vez hemos utilizado o hemos desarrollado mapas para nuestros sitios, sin duda que Google Maps nos ha sido de gran ayuda. Sin embargo el ecosistema ha cambiado y hay que pensar en alternativas para hacer más rentables nuestros sitios y apoyar en cierta manera el movimiento opensource que cada vez está tomando más fuerza.