Cargar un KML con la API de Google Maps
Insertar contacto en Agenda con Google Maps
En este caso queremos hacer un formulario que permita la alta de mis contactos en BD añadiendo un mapa en el que podamos localizar al contacto.
Capturará el evento de clic sobre el mapa para generar el marcador.
Capturará la posición del clic para mostrarlo en los input type=text X e Y.
Haremos «draggable» el marcador para poder moverlo de un sitio a otro. La posición en X e Y se irá modificando.
Imagen del Formulario:
Fichero HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="agenda.css"> <title>Insertar nuevo contacto</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> function inicializar(){ var mapa; var marcador; var myLatlng = new google.maps.LatLng(37.192869,-3.613186); var mapOptions = { zoom: 10, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } mapa = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); google.maps.event.addListener(mapa, 'click', function(event) { // Crear marcador if (marcador) marcador.setMap(null); marcador = new google.maps.Marker({ position: event.latLng, draggable: true, map: mapa }); mapa.setCenter(event.latLng); // Rellenar X e Y document.formulario.latitud.value=event.latLng.lat(); document.formulario.longitud.value=event.latLng.lng(); // Modificar X e Y al mover google.maps.event.addListener(marcador,'drag',function(event){ document.formulario.latitud.value=event.latLng.lat(); document.formulario.longitud.value=event.latLng.lng(); mapa.setCenter(event.latLng); }); }); } </script> </head> <body onload="inicializar()"> <h1>Alta de Contacto:</h1> <form action="insertaragendamapa.php" method="post" name="formulario"> <div style="float:right">X: <input type="text" name="latitud"/> Y: <input type="text" name="longitud"/><br/><br/> <div id="map_canvas" style="width:500px;height:500px"> </div> </div>Nombre: <input type="text" name="nombre"/><br/><br/> Apellidos: <input type="text" name="ap1"/> <input type="text" name="ap2"/><br/><br/> Teléfono: <input type="text" name="telefono"/><br/><br/> e-mail: <input type="text" name="email"/><br/><br/> Dirección: <input type="text" name="direccion"/><br/><br/> Provincia: <input type="text" name="provincia"/><br/><br/> Fecha de Nacimiento: <input type="text" name="fecha"/><br/><br/> <br/><br/> <input type="submit" value="Guardar"/> <input type="reset" value="Limpiar"/> </form> </body> </html>
Fichero PHP
<html> <body> <?php $nombre=$_POST['nombre']; $ap1=$_POST['ap1']; $ap2=$_POST['ap2']; $direccion = $_POST['direccion']; $email=$_POST['email']; $fecha=$_POST['fecha']; $telefono=$_POST['telefono']; $provincia=$_POST['provincia']; $latitud=$_POST['latitud']; $longitud=$_POST['longitud']; //Transformo fecha de DD-MM-YYYY a YYYY-MM-DD $fecha = date_create_from_format('d-m-Y', $fecha); $fechanueva = date_format($fecha, 'Y-m-d'); $link = mysql_connect("localhost", "root", "acrear2012"); mysql_select_db("agenda",$link); $sql = "INSERT INTO agenda (nombre, apellido1, apellido2, direccion, telefono, email, fechanacimiento, provincia, X, Y) ". "VALUES ('$nombre', '$ap1', '$ap2', '$direccion', '$telefono', '$email', '$fechanueva','$provincia',$latitud,$longitud)"; $result = mysql_query($sql,$link) or die("No he podido insertar el contacto"); echo "<p>El contacto $nombre $ap1 $ap2 ha sido insertado.</p>\n"; ?> </body> </html>
Mejora en el formulario mediante GeoCoder
Para conseguir que sitúe un marcador a partir de la dirección escrita, programamos el evento onchange del campo Dirección.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="agenda.css"> <title>Insertar nuevo contacto</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> var mapa; var marcador; var geocoder; function inicializar(){ geocoder = new google.maps.Geocoder(); var myLatlng = new google.maps.LatLng(37.192869,-3.613186); var mapOptions = { zoom: 10, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } mapa = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); google.maps.event.addListener(mapa, 'click', function (event){ creaMarcador(event.latLng) }); } function creaMarcador(localizacion){ // Crear marcador if (marcador) marcador.setMap(null); marcador = new google.maps.Marker({ position: localizacion, draggable: true, map: mapa }); mapa.setCenter(localizacion); // Rellenar X e Y document.formulario.latitud.value=localizacion.lat(); document.formulario.longitud.value=localizacion.lng(); // Modificar X e Y al mover google.maps.event.addListener(marcador,'drag',function(event){ document.formulario.latitud.value=event.latLng.lat(); document.formulario.longitud.value=event.latLng.lng(); //mapa.setCenter(localizacion); }); } function direc(){ var dire = document.getElementById("direccion").value; geocoder.geocode( {'address': dire}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { mapa.setCenter(results[0].geometry.location); creaMarcador(results[0].geometry.location); } else { alert("Geocode was not successful for the following reason: " + status); } }); } </script> </head> <body onload="inicializar()"> <h1>Alta de Contacto:</h1> <form action="insertaragendamapa.php" method="post" name="formulario"> <div style="float:right">X: <input type="text" name="latitud"/> Y: <input type="text" name="longitud"/><br/><br/> <div id="map_canvas" style="width:500px;height:500px"> </div> </div>Nombre: <input type="text" name="nombre"/><br/><br/> Apellidos: <input type="text" name="ap1"/> <input type="text" name="ap2"/><br/><br/> Teléfono: <input type="text" name="telefono"/><br/><br/> e-mail: <input type="text" name="email"/><br/><br/> Dirección: <input type="text" id="direccion" name="direccion" onchange="direc()"/> <!--<input type="button" name="boton" value="Busca" onclick="direc()"/>--><br/><br/> Provincia: <input type="text" name="provincia"/><br/><br/> Fecha de Nacimiento: <input type="text" name="fecha"/><br/><br/> <br/><br/> <input type="submit" value="Guardar"/> <input type="reset" value="Limpiar"/> </form> </body> </html>
…
Nuestros contactos en Google Maps
<!DOCTYPE html> <html> <head> <style type="text/css"> body{ text-align:center; margin: 0 auto; padding: 0 auto; } #map_canvas{ margin: 0 auto; padding: 0 auto; width:700px; height:400px; /*background:blue;*/ text-align:left; } </style> <title>Mapa de mis contactos</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> function inicializar(){ var ventana; var latitudlongitud = new google.maps.LatLng(37.206167,-3.654254); var opciones = { zoom: 10, center: latitudlongitud, mapTypeId: google.maps.MapTypeId.ROADMAP }; var mapa = new google.maps.Map(document.getElementById("map_canvas"),opciones); var coordenadas = new google.maps.LatLng(37.195604,-3.609191); var marcador = new google.maps.Marker({ position: coordenadas, map: mapa, title: 'Jorgito Ruiz López', icon: 'imagenes/statue-2.png' }); var cadena='<div>' +'<h1>Jorgito Ruiz López</h1>' +'<p>Calle Almuñecar 4 (Granada)</p>' +'<p>Teléfono: 666000111</p>' +'<p>email: jorgito@gmail.com</p>' +'<p>Fecha de nacimiento: 1965-02-03</p>' +'</div>'; google.maps.event.addListener(marcador, 'click', function() { if (ventana) ventana.close(); ventana = new google.maps.InfoWindow({content: cadena}); ventana.open(mapa,marcador); }); } </script> </head> <body onload="inicializar()"> <h1>Mapa de mis contactos</h1> <div id="map_canvas"> </div> </body> </html>
…
El siguiente código consulta la BD y muestra un punto por cada contacto:
<!DOCTYPE html> <html> <head> <style type="text/css"> body{ text-align:center; margin: 0 auto; padding: 0 auto; } #map_canvas{ margin: 0 auto; padding: 0 auto; width:700px; height:400px; /*background:blue;*/ text-align:left; } </style> <title>Mapa de mis contactos</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> function inicializar(){ var ventana; var latitudlongitud = new google.maps.LatLng(37.206167,-3.644254); var opciones = { zoom: 12, center: latitudlongitud, mapTypeId: google.maps.MapTypeId.ROADMAP }; var mapa = new google.maps.Map(document.getElementById("map_canvas"),opciones); <?php // Conecta con BD y ejecutar consulta // Conectar con el Servidor $link = mysql_connect("localhost", "root", "acrear2012") or die ("No puedo conectarme con el servidor"); // Usar la BD mysql_select_db("agenda",$link) or die ("No puedo abrir la BD"); // Hacer la consulta $consulta= "SELECT * FROM agenda"; // Consulta por defecto $resultado = mysql_query($consulta, $link) or die ("No puedo ejecutar la consulta"); // Voy leyendo fila a fila while ($fila = mysql_fetch_array($resultado)){ $latitud=$fila['X']; $longitud=$fila['Y']; $id=$fila['id']; echo "var coordenadas = new google.maps.LatLng($latitud,$longitud); var marcador$id = new google.maps.Marker({ position: coordenadas, map: mapa, title: 'Jorgito Ruiz López', icon: 'imagenes/statue-2.png' }); var cadena='<div>' +'<h1>Jorgito Ruiz López</h1>' +'<p>Calle Almuñecar 4 (Granada)</p>' +'<p>Teléfono: 666000111</p>' +'<p>email: jorgito@gmail.com</p>' +'<p>Fecha de nacimiento: 1965-02-03</p>' +'</div>'; google.maps.event.addListener(marcador$id, 'click', function() { if (ventana) ventana.close(); ventana = new google.maps.InfoWindow({content: cadena}); ventana.open(mapa,marcador$id); }); "; } mysql_close($link); ?> } </script> </head> <body onload="inicializar()"> <h1>Mapa de mis contactos</h1> <div id="map_canvas"> </div> </body> </html>
Y el código definitivo es:
<!DOCTYPE html> <html> <head> <style type="text/css"> body{ text-align:center; margin: 0 auto; padding: 0 auto; } #map_canvas{ margin: 0 auto; padding: 0 auto; width:700px; height:400px; /*background:blue;*/ text-align:left; } </style> <title>Mapa de mis contactos</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> function inicializar(){ var ventana; var latitudlongitud = new google.maps.LatLng(37.206167,-3.644254); var opciones = { zoom: 12, center: latitudlongitud, mapTypeId: google.maps.MapTypeId.ROADMAP }; var mapa = new google.maps.Map(document.getElementById("map_canvas"),opciones); <?php // Conecta con BD y ejecutar consulta // Conectar con el Servidor $link = mysql_connect("localhost", "root", "acrear2012") or die ("No puedo conectarme con el servidor"); // Usar la BD mysql_select_db("agenda",$link) or die ("No puedo abrir la BD"); // Hacer la consulta $consulta= "SELECT * FROM agenda"; // Consulta por defecto $resultado = mysql_query($consulta, $link) or die ("No puedo ejecutar la consulta"); // Voy leyendo fila a fila while ($fila = mysql_fetch_array($resultado)){ $latitud=$fila['X']; $longitud=$fila['Y']; $id=$fila['id']; $nombrecompleto= $fila['nombre'].' '.$fila['apellido1'].' '.$fila['apellido2']; $direccion=$fila['direccion']; $provincia=$fila['provincia']; $telefono=$fila['telefono']; $correo=$fila['email']; $fecha=$fila['fechanacimiento']; echo "var coordenadas = new google.maps.LatLng($latitud,$longitud); var marcador$id = new google.maps.Marker({ position: coordenadas, map: mapa, title: '$nombrecompleto', icon: 'imagenes/statue-2.png' }); var cadena$id='<div>' +'<h1>$nombrecompleto</h1>' +'<p>$direccion ($provincia)</p>' +'<p>Teléfono: $telefono</p>' +'<p>email: $correo</p>' +'<p>Fecha de nacimiento: $fecha</p>' +'<p><img src=\"imagenes/pepito.jpg\" alt=\"foto de pepito\" width=50px/></p>' +'</div>'; google.maps.event.addListener(marcador$id, 'click', function() { if (ventana) ventana.close(); ventana = new google.maps.InfoWindow({content: cadena$id}); ventana.open(mapa,marcador$id); }); "; } mysql_close($link); ?> } </script> </head> <body onload="inicializar()"> <h1>Mapa de mis contactos</h1> <div id="map_canvas"> </div> </body> </html>
…
Ejemplo mapa con 3 marcadores
Código del segundo mapa que hacemos. Ejemplo básico. Tenemos 3 marcadores situados uno en Maracena, otro en Armilla y otro en Granada.
Código fuente:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <title>Mapa en Granada</title> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> <script> function initialize() { var myLatlng = new google.maps.LatLng(37.192869,-3.613186); var mapOptions = { zoom: 10, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); var contentString = '<div>' +'<h1>Maracena</h1>' +'<p>Localidad: Maracena. 20000 habitantes</p>' +'</div>'; var infowindow = new google.maps.InfoWindow({ content: contentString, maxWidth: 300 }); var myLatlng = new google.maps.LatLng(37.209277,-3.636875); var marker = new google.maps.Marker({ position: myLatlng, map: map, title: 'Maracena', icon: 'imagenes/arch.png' }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); // Segundo marcador var contentString2 = '<div>' +'<h1>Armilla</h1>' +'<p>Localidad: Armilla. 23000 habitantes</p>' +'</div>'; var infowindow2 = new google.maps.InfoWindow({ content: contentString2, maxWidth: 300 }); var myLatlng = new google.maps.LatLng(37.141435,-3.620739); var marker2 = new google.maps.Marker({ position: myLatlng, map: map, title: 'Armilla', icon: 'imagenes/statue-2.png' }); google.maps.event.addListener(marker2, 'click', function() { infowindow2.open(map,marker2); }); // Tercer marcador var contenidoGranada = '<div>' +'<h1>Granada</h1>' +'<p>Localidad: Granada. 250000 habitantes</p>' +'</div>'; var ventanaGranada = new google.maps.InfoWindow({ content: contenidoGranada, maxWidth: 300 }); var latitudGranada = new google.maps.LatLng(37.180561,-3.602886); var marcadorGranada = new google.maps.Marker({ position: latitudGranada, map: map, title: 'Granada', icon: 'imagenes/rockhouse.png' }); google.maps.event.addListener(marcadorGranada, 'click', function() { ventanaGranada.open(map,marcadorGranada); }); } </script> </head> <body onload="initialize()"> <h1>Mapa en Granada</h1> <div id="map_canvas" style="width:500px;height:500px"></div> <h2>Tres puntos distintos</h2> </body> </html>
Mostrar una única InfoWindow en Google Maps
Para no obtener varios InfoWindow en un mapa, como sucede en la siguiente imagen:
El secreto es utilizar una única variable InfoWindow.
Esta variable, en el Listener de cada Marker, la comprobaremos si existe. Si es así la cerramos, si no, creamos un nuevo objeto con el content correcto y lo asignamos al marcador actual.
El código fuente sería el siguiente:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <title>Mapa en Granada</title> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script> <script> function initialize() { var myLatlng = new google.maps.LatLng(37.192869,-3.613186); var infowindow; var mapOptions = { zoom: 10, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); var contentString = '<div>' +'<h1>Maracena</h1>' +'<p>Localidad: Maracena. 20000 habitantes</p>' +'</div>'; var myLatlng = new google.maps.LatLng(37.209277,-3.636875); var marker = new google.maps.Marker({ position: myLatlng, map: map, title: 'Maracena', icon: 'imagenes/arch.png' }); google.maps.event.addListener(marker, 'click', function() { if (infowindow) infowindow.close(); infowindow = new google.maps.InfoWindow({content: contentString}); infowindow.open(map,marker); }); // Segundo marcador var contentString2 = '<div>' +'<h1>Armilla</h1>' +'<p>Localidad: Armilla. 23000 habitantes</p>' +'</div>'; var myLatlng = new google.maps.LatLng(37.141435,-3.620739); var marker2 = new google.maps.Marker({ position: myLatlng, map: map, title: 'Armilla', icon: 'imagenes/statue-2.png' }); google.maps.event.addListener(marker2, 'click', function() { if (infowindow) infowindow.close(); infowindow = new google.maps.InfoWindow({content: contentString2}); infowindow.open(map,marker2); }); // Tercer marcador var contenidoGranada = '<div>' +'<h1>Granada</h1>' +'<p>Localidad: Granada. 250000 habitantes</p>' +'</div>'; var ventanaGranada = new google.maps.InfoWindow({ content: contenidoGranada, maxWidth: 300 }); var latitudGranada = new google.maps.LatLng(37.180561,-3.602886); var marcadorGranada = new google.maps.Marker({ position: latitudGranada, map: map, title: 'Granada', icon: 'imagenes/rockhouse.png' }); google.maps.event.addListener(marcadorGranada, 'click', function() { if (infowindow) infowindow.close(); infowindow = new google.maps.InfoWindow({content: contenidoGranada}); infowindow.open(map,marcadorGranada); }); } </script> </head> <body onload="initialize()"> <h1>Mapa en Granada</h1> <div id="map_canvas" style="width:500px;height:500px"></div> <h2>Tres puntos distintos</h2> </body> </html>
…
Capas KML y GeoRSS
Google Maps API admite los formatos de datos KML y GeoRSS para la visualización de información geográfica. Estos formatos de datos se muestran un mapa a través de un objeto KmlLayer
, cuyo constructor toma la URL de un archivo KML o GeoRSS de acceso público.
El API de Google Maps convierte los datos geográficos proporcionados en formato XML en una representación KML que se muestra en el mapa mediante una superposición de mosaico de la versión 3. El aspecto (y, en cierto modo, el comportamiento) de la representación KML se parece al de los elementos de superposición de la versión 3. Los elementos KML <Placemark>
y GeoRSS point
se representan como marcadores, por ejemplo, los elementos <LineString>
se representan como polilíneas y los elementos <Polygon>
se representan como polígonos. Asimismo, los elementos <GroundOverlay>
se representan como imágenes rectangulares en el mapa. Sin embargo, estos objetos en gran medida no son marcadores (Marker
), polilíneas (Polyline
), polígonos (Polygon
) o superposiciones de suelo (GroundOverlay
) del API de Google Maps; en su lugar, se representan en un único objeto en el mapa.
Los objetos KmlLayer
aparecen en un mapa después de definir la propiedad map
correspondiente. (Puedes eliminarlos del mapa ejecutando setMap()
y transmitiendo null
). El objeto KmlLayer
administra la representación de estos elementos secundarios mediante la recuperación automática de las características apropiadas correspondientes a los límites especificados para el mapa. A medida que cambian los límites, se representan automáticamente las características de la correspondiente ventana gráfica.
Dado que los componentes de una capa KmlLayer
se representan bajo demanda, la capa permite administrar fácilmente la representación de miles de marcadores, polilíneas y polígonos. Ten en cuenta que no puedes acceder a los objetos constituyentes directamente, aunque cada uno de ellos proporciona eventos de clic que devuelven datos sobre cada uno de dichos objetos.
Opciones de la capa KML
El constructor KmlLayer()
transmite opcionalmente diversos valores KmlLayerOptions
:
map
especifica el mapa (Map
) en el que se representará el valorKmlLayer
. Puedes ocultar una capaKmlLayer
estableciendo este valor comonull
en el métodosetMap()
.preserveViewport
especifica que el mapa no se debe ajustar a los límites del contenido deKmlLayer
al mostrar la capa. De forma predeterminada, al mostrar un valorKmlLayer
, el mapa se amplía o reduce y se posiciona para mostrar todo el contenido de la capa.suppressInfoWindows
indica que las funciones de clic deKmlLayer
no provocarán la visualización de objetosInfoWindow
.
Además, una vez representado el objeto KmlLayer
, incluye una propiedad metadata
inmutable que contiene el nombre, la descripción, el fragmento de código y el autor en un objeto literal KmlLayerMetadata
. El métodogetMetadata()
te permite inspeccionar esta información. Dado que la representación de objetos KmlLayer
requiere una comunicación asíncrona con un servidor externo, se recomienda detectar el evento metadata_changed
, que indicará que se ha completado la propiedad.
En el ejemplo siguiente se crea un objeto KmlLayer
a partir del feed de GeoRSS especificado:
var myLatlng = new google.maps.LatLng(49.496675,-102.65625); var myOptions = { zoom: 4, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var georssLayer = new google.maps.KmlLayer('http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss'); georssLayer.setMap(map);
Ver ejemplo de GeoRSS (layer-georss.html)
En el ejemplo siguiente se crea un objeto KmlLayer
a partir del feed de KML especificado:
var myLatlng = new google.maps.LatLng(41.875696,-87.624207); var myOptions = { zoom: 11, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var ctaLayer = new google.maps.KmlLayer('http://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml'); ctaLayer.setMap(map);
Ver ejemplo de KML (layer-kml.html)
Detalles de recursos KML
Dado que KML puede incluir un gran número de recursos, es posible que no puedas acceder a los datos de recursos directamente desde el objeto KmlLayer
. Por contra, a medida que se muestran los recursos, estos se representan de forma que parezcan superposiciones del API de Google Maps en las que se puede hacer clic. De forma predeterminada, al hacer clic en cada uno de los recursos, se muestra una ventana de información (InfoWindow
) que incluye el valor <title>
de KML e información del tipo <description>
sobre dicho recurso. Además, al hacer clic en un recurso KML, se genera un evento KmlMouseEvent
que transmite la información siguiente:
position
indica las coordenadas (latitud/longitud) en las que se anclará la ventana de información (InfoWindow
) de este recurso KML. Esta posición es normalmente la ubicación en la que se ha hecho clic para polígonos, polilíneas y las clases GroundOverlays, así como el origen verdadero de objetos.pixelOffset
indica la desviación desde la posición (position
) anterior en la que se anclará la «cola» deInfoWindow
. En el caso de los objetos poligonales, esta desviación es normalmente de0,0
, pero para los marcadores, incluye también la altura del marcador.featureData
incluye una estructura JSON deKmlFeatureData
.
A continuación, se muestra un objeto KmlFeatureData
de ejemplo:
{ author: { email: "nobody@google.com", name: "Mr Nobody", uri: "http://example.com" }, description: "description", id: "id", infoWindowHtml: "html", name: "name", snippet: "snippet" }
En el ejemplo siguiente, se muestra el texto <Description>
del recurso KML en el lado <div>
al hacer clic en el recurso:
var myLatlng = new google.maps.LatLng(40.65, -73.95); var myOptions = { zoom: 12, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var nyLayer = new google.maps.KmlLayer('http://www.searcharoo.net/SearchKml/newyork.kml', {suppressInfoWindows: true}); nyLayer.setMap(map); google.maps.event.addListener(nyLayer, 'click', function(kmlEvent) { var text = kmlEvent.featureData.description; showInDiv(text); }); function showInDiv(text) { var sidediv = document.getElementById('contentWindow'); sidediv.innerHTML = text; }
Aspectos generales de capas
Las capas son objetos que se muestran sobre el mapa, que constan de uno o más elementos independientes, que sin embargo se manipulan como una sola unidad. Las capas representan normalmente conjuntos de objetos que se añaden sobre el mapa para designar una asociación común. El API de Google Maps administra la presentación de objetos dentro de las capas mediante la presentación de los elementos que las constituyen en un único objeto (normalmente una superposición de mosaico) y la visualización de los mismos a medida que cambia la ventana gráfica del mapa. Las capas también pueden modificar la capa de presentación del propio mapa, alterando ligeramente los mosaicos base en consonancia con la capa. Ten en cuenta que, por diseño, no se puede acceder a la mayoría de las capas a través de sus objetos individuales y que solo se pueden manipular como una unidad.
Para añadir una capa a un mapa, solo es necesario ejecutar setMap()
, transmitiéndole el objeto del mapa en el que se mostrará la capa. De forma similar, para ocultar una capa, ejecuta setMap()
, transmitiendo null
.
Google Maps API incorpora varios tipos de capas:
- Los objetos
KmlLayer
representan elementos KML y GeoRSS en una superposición de mosaico de la versión 3 del API de Google Maps. - Los objetos
FusionTablesLayer
representan datos incluidos en GoogleFusion Tables. - El objeto
TrafficLayer
representa una capa que muestra las condiciones de tráfico y superposiciones que representan el tráfico. - El objeto
BicyclingLayer
representa una capa de rutas para bicicletas o superposiciones específicas de bicicletas en una capa común. Esta capa se devuelve de forma predeterminada enDirectionsRenderer
al solicitar indicaciones en el modo de viajeBICYCLING
.
Ventanas de información
Las ventanas de información (InfoWindow
) muestran contenido en una ventana flotante situada encima del mapa. La ventana de información tiene un aspecto ligeramente parecido al de los bocadillos de los cómics. Tiene un área de contenido y un pico afilado, cuyo extremo se encuentra en una ubicación especificada en el mapa. Puedes ver cómo funcionan las ventanas de información si haces clic en los marcadores de negocios de Google Maps.
El constructor InfoWindow
utiliza un objeto InfoWindow options
, que especifica un conjunto de parámetros iniciales para la visualización de la ventana de información. La ventana de información no se añade al mapa cuando la creas. Para mostrar la ventana de información, necesitas ejecutar el método open()
en el objeto InfoWindow
, incluir el mapa (Map
) en el que se va a abrir y, opcionalmente, el marcador (Marker
) en el que se va a anclar. (En caso de que no se especifique ningún marcador, la ventana de información se abrirá en su propiedad position
).
El objeto InfoWindow options
es un objeto literal que contiene los siguientes campos:
content
contiene una cadena de texto o un nodo DOM que se mostrará cuando se abra la ventana de información.pixelOffset
contiene una desviación de la punta de la ventana de información con relación a la ubicación en la que dicha ventana está anclada. En la práctica, no deberías tener que modificar este campo.position
contiene el objetoLatLng
en el que se ancla esta ventana de información. Ten en cuenta que al abrir la ventana de información en un marcador se actualizará de manera automática este valor para obtener la nueva posición.maxWidth
especifica la anchura máxima en píxeles de la ventana de información. De manera predeterminada, las ventanas de información se amplían para ajustarse a su contenido y ajustan el texto de manera automática si la ventana de información se amplía hasta cubrir el mapa. Si implementas un elementomaxWidth
, la ventana de información se ajustará de manera automática para respetar el ancho en píxeles. Cuando se alcanza el ancho máximo, la ventana de información se puede expandir verticalmente si la pantalla dispone de espacio real.
El contenido de InfoWindow
puede incluir una cadena de texto, un fragmento HTML o un elemento DOM. Para especificar este contenido, puedes trasmitirlo al constructor InfoWindow options
o ejecutar setContent()
explícitamente en el objeto InfoWindow. Si quieres especificar explícitamente el tamaño del contenido, puedes utilizar elementos <div>
y, si lo deseas, habilitar el desplazamiento. Ten en cuenta que si no habilitas el desplazamiento y el contenido excede el espacio disponible en una ventana de información, dicho contenido puede salirse de la ventana de información.
Las ventanas de información (InfoWindow
) pueden adjuntarse a objetos Marker
(en cuyo caso su posición se basa en la ubicación del marcador) o al propio mapa en un objeto LatLng
especificado. Si solo deseas mostrar una ventana de información a la vez (como suele ser el caso en Google Maps), solo tienes que crear una ventana de información que puedes reasignar a diferentes ubicaciones o marcadores en función de los eventos del mapa (tales como los clics del usuario). Sin embargo, a diferencia de lo que sucedía en la versión 2 del API de Google Maps, los mapas ahora pueden mostrar varios objetos InfoWindow
, si así lo indicas.
Para cambiar la ubicación de la ventana de información, puedes ejecutar setPosition()
explícitamente en la ventana de información o bien adjuntarla a un nuevo marcador mediante el método InfoWindow.open()
. Ten en cuenta que si ejecutas open()
sin incluir un marcador, la ventana de información (InfoWindow
) utilizará la posición especificada en la construcción mediante el objeto InfoWindow options
.
El siguiente fragmento de código muestra un marcador en el centro de Australia. Al hacer clic en el marcador, aparece la ventana de información.
var myLatlng = new google.maps.LatLng(-25.363882,131.044922); var myOptions = { zoom: 4, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var contentString = '<div id="content">'+ '<div id="siteNotice">'+ '</div>'+ '<h1 id="firstHeading">Uluru</h1>'+ '<div id="bodyContent">'+ '<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' + 'sandstone rock formation in the southern part of the '+ 'Northern Territory, central Australia. It lies 335 km (208 mi) '+ 'south west of the nearest large town, Alice Springs; 450 km '+ '(280 mi) by road. Kata Tjuta and Uluru are the two major '+ 'features of the Uluru - Kata Tjuta National Park. Uluru is '+ 'sacred to the Pitjantjatjara and Yankunytjatjara, the '+ 'Aboriginal people of the area. It has many springs, waterholes, '+ 'rock caves and ancient paintings. Uluru is listed as a World '+ 'Heritage Site.</p>'+ '<p>Attribution: Uluru, <a href="http://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">'+ 'http://en.wikipedia.org/w/index.php?title=Uluru</a> (last visited June 22, 2009).</p>'+ '</div>'+ '</div>'; var infowindow = new google.maps.InfoWindow({ content: contentString }); var marker = new google.maps.Marker({ position: myLatlng, map: map, title:"Uluru (Ayers Rock)" }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); });
Ver ejemplo (infowindow-simple.html)
A continuación aparece un ejemplo en el que el elemento maxWidth
de la ventana de información se ha establecido en 200 píxeles:
Superposiciones de suelo
Los polígonos son superposiciones que resultan útiles para representar zonas de tamaño irregular, pero no permiten mostrar imágenes. Si tienes una imagen que deseas colocar en un mapa, puedes utilizar un objeto GroundOverlay
. El constructor de un objeto GroundOverlay
permite especificar la URL de una imagen y el objeto LatLngBounds
de la imagen en forma de parámetros. La imagen se mostrará en el mapa, dentro de los límites establecidos y de acuerdo con la proyección del mapa.
En el ejemplo siguiente, se superpone un mapa antiguo de Newark (Nueva Jersey, EE.UU.) sobre uno reciente:
var newark = new google.maps.LatLng(40.740, -74.18); var imageBounds = new google.maps.LatLngBounds( new google.maps.LatLng(40.716216,-74.213393), new google.maps.LatLng(40.765641,-74.139235)); var myOptions = { zoom: 13, center: newark, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var oldmap = new google.maps.GroundOverlay( "http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg", imageBounds); oldmap.setMap(map);
Círculos y rectángulos
Además de una clase Polygon
genérica, el API de JavaScript de Google Maps incluye clases específicas para Circle
y Rectangle
a fin de simplificar su construcción.
Círculos
Un círculo (Circle
) es similar a un polígono (Polygon
) en que puedes definir colores, grosores y niveles de opacidad personalizados para el borde del círculo (el «trazo»), así como colores y opacidades personalizados para el área que engloba (el «relleno»). Los colores se deben representar en estilo HTML numérico hexadecimal.
A diferencia de un polígono (Polygon
), no se definen rutas (paths
) para un círculo (Circle
); en su lugar, un círculo tiene dos propiedades adicionales que definen su forma:
center
especificagoogle.maps.LatLng
del centro del círculo.radius
especifica el radio del círculo, en metros.
El siguiente fragmento de código crea un círculo que representa poblaciones de Estados Unidos:
// Create an object containing LatLng, population. var citymap = {}; citymap['chicago'] = { center: new google.maps.LatLng(41.878113, -87.629798), population: 2842518 }; citymap['newyork'] = { center: new google.maps.LatLng(40.714352, -74.005973), population: 8143197 }; citymap['losangeles'] = { center: new google.maps.LatLng(34.052234, -118.243684), population: 3844829 } var cityCircle; function initialize() { var mapOptions = { zoom: 4, center: new google.maps.LatLng(37.09024, -95.712891), mapTypeId: google.maps.MapTypeId.TERRAIN }; var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); for (var city in citymap) { // Construct the circle for each value in citymap. We scale population by 20. var populationOptions = { strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35, map: map, center: citymap[city].center, radius: citymap[city].population / 20 }; cityCircle = new google.maps.Circle(populationOptions); } }
Ver ejemplo (circle-simple.html)
Rectángulos
Un círculo (Rectangle
) es similar a un polígono (Polygon
) en que puedes definir colores, grosores y niveles de opacidad personalizados para el borde del rectángulo (el «trazo»), así como colores y opacidades personalizados para el área que engloba (el «relleno»). Los colores se deben representar en estilo HTML numérico hexadecimal.
A diferencia de un polígono (Polygon
), no se definen rutas (paths
) para un rectángulo (Rectangle
); en su lugar, un rectángulo tiene una propiedad adicional que define su forma:
bounds
especificagoogle.maps.LatLngBounds
del rectángulo.
El siguiente ejemplo crea un rectángulo a partir de la ventana gráfica previa de cualquier evento 'zoom_changed'
:
function initialize() { var coachella = new google.maps.LatLng(33.6803003, -116.173894); var rectangle; var myOptions = { zoom: 11, center: coachella, mapTypeId: google.maps.MapTypeId.TERRAIN }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); rectangle = new google.maps.Rectangle(); google.maps.event.addListener(map, 'zoom_changed', function() { // Get the current bounds, which reflect the bounds before the zoom. var rectOptions = { strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35, map: map, bounds: map.getBounds() }; rectangle.setOptions(rectOptions); }); }