Oct 022013
 
Artículo Javascript

El API de Google Maps permite superponer a un mapa una serie de figuras geométricas para resaltar regiones. Las más complejas son los polígonos, que constan de un número variable áreas cerradas, cada una de ella definida por una serie de puntos.

Para casos más sencillos, se pueden utilizar rectángulos, o incluso círculos.

En este artículo vamos a examinar las posibilidades que ofrece el API de Google Maps para trabajar con rectángulos.

Mapa de partida

Para ilustrar este artículo, vamos a utilizar como punto de partida una sencilla página HTML que simplemente contiene un mapa.

El código HTML de la página es el siguiente:

<!DOCTYPE html>
<html lang="es-ES">
<head>
    <meta charset="UTF-8" />
    <title>Ejemplo de uso de rectángulos en el API de Google Maps</title>
<script type="text/javascript"
        src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
    var centerx = 7.5;
    var centery = 5;
    var minlong = -40;
    var minlat = 0;
    var maxlong = 55;
    var maxlat = 10;
</script>
<script type='text/javascript'>

  var map;

  function initialize() {
    var myOptions = {
        center: new google.maps.LatLng( centerx, centery ),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        zoomControl: true,
        scrollwheel: false
    };
    // Crear el mapa en el div contenedor "map_canvas"
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    map.fitBounds(new google.maps.LatLngBounds(
          new google.maps.LatLng(minlong, minlat),
          new google.maps.LatLng(maxlong, maxlat)
          )
    );
}
</script>
</head>

<body onload="initialize()">
        <div id="map_canvas" style="width:690px; height:300px"></div>
</body>
</html>

Y el resultado que obtenemos es el siguiente:

mapamundi

 

Superponer rectángulos sobre el mapa

Ahora vamos a añadir a la inicialización el código que superpone unos rectángulos sobre el mapa.

Comenzamos por definir un array que contiene cuatro rectángulos, cada uno de ellos identificado con un nombre y definido con las coordenadas (latitud, longitud) de sus extremos suroeste y noreste:

    var areas = [
        [ "rectángulo uno"    ,-20.7575, -43.5951, -25.52, -50.2614],
        [ "rectángulo dos"    ,20.7575, -43.5951, 25.52, -50.2614],
        [ "rectángulo tres"    ,-18.7575, -44.5951, -23.52, -48.2614],
        [ "cuarto rectángulo"    ,30.7575, -43.5951, -25.52, -50.2614],
    ];

A continuación, ejecutamos un bucle que añade al mapa los cuatro rectángulos.

    var rectangulos = [];

    for (i = 0; i < 4; i++) {
        var suroeste = new google.maps.LatLng(areas[i][1],areas[i][2]);
        var noreste = new google.maps.LatLng(areas[i][3],areas[i][4]);
        rectangulos[i] =  
        new google.maps.Rectangle({
            bounds: new google.maps.LatLngBounds(suroeste, noreste),
            strokeColor: "#0000FF",
            strokeOpacity: 1,
            strokeWeight: 1,
            fillColor: "#FF0000",
            fillOpacity: 0.5
        }); 

        rectangulos[i].setMap(map);

        rectangulos[i].name = areas[i][0];
        rectangulos[i].id = i;

Como podemos ver, cada rectángulo se crea como un objeto “google.maps.Rectangle”.

En el constructor del rectángulo, especificamos una serie de parámetros:

  • bounds – especifica las coordenadas inferior izquierda (suroeste) y superior derecha (noreste) del rectángulo
  • strokeColor – color del borde
  • StrokeOpacity – opacidad del borde
  • strokeWeight – grosor del borde
  • fillColor – color de relleno
  • fillOpacity – opacidad del relleno

En nuestro ejemplo, hemos especificado una opacidad del relleno de 0.5, de manera que el relleno es parcialmente transparente y deja ver el mapa que hay debajo.

Una vez creado, el objeto se presenta en el mapa con una llamada a setMap.

Por último, asignamos al objeto los atributos “name” e “id”. Esto no es obligatorio en este punto, pero es importante para poder identificarlo más adelante, cuando utilicemos eventos (mouseover, mouseout, click).

Con ello, obtenemos el siguiente resultado:

rectangulos-1

Asociar manejadores de eventos mouseover y mouseout al rectángulo

A continuación vamos hacer que cuando se coloca el cursor sobre un rectángulo, cambie de color. Para ello, asignamos al rectángulo unos manejadores de eventos asociados a los eventos mouseover y mouseout.

En el interior del bucle de creación de los rectángulos, añadimos el siguiente código:

        google.maps.event.addListener(rectangulos[i],"mouseover",function(){
                 this.setOptions({fillColor: "#00FF00"});
                 });

        google.maps.event.addListener(rectangulos[i],"mouseout",function(){
                 this.setOptions({fillColor: "#FF0000"});
                 });

Editar un rectángulo

También es posible poner un rectángulo en modo edición, de manera que podamos cambiar sus dimensiones utilizando el ratón.

Para ello, utilizamos el siguiente código para asociar al rectángulo un manejador del evento “click”:

google.maps.event.addListener(rectangulos[i],"click",function(){
        this.setOptions({ editable: true});
    });

Con este código, al hacer click sobre un rectángulo obtenemos el siguiente resultado:

rectangulo-editable

Como podemos ver, al colocar el cursor sobre el rectángulo su color de relleno ha cambiado a verde, como consecuencia del manejador del evento “mouseover” que incorporamos en el apartado anterior.

Además, al hacer click sobre el rectángulo, ha pasado a ser editable. En sus vértices y lados aparecen unos puntos de anclaje señalados con pequeños círculos blancos. Ahora, podemos cambiar las dimensiones del rectángulo colocando el cursor sobre uno de los puntos de anclaje, haciendo click y moviendo el ratón sin soltar.

Para poder volver a poner el rectángulo en estado no editable, vamos a modificar el manejador del evento “click” de modo que cada vez que se hace click sobre el rectángulo pase de estado editable a no editable, y viceversa.

Para ello, utilizamos el método “getEditable()” que devuelve “true” si el rectángulo está en estado editable, o “false” en caso contrario:

google.maps.event.addListener(rectangulos[i],"click",function(){
        this.setOptions({ editable: ! this.getEditable()});
    });

Cambiar el orden de los rectángulos en el eje Z

Tras editar los rectángulos de nuestro ejemplo, nos podemos encontrar en una situación como la que se presenta en la siguiente imagen:

rectangulos-superpuestos

En ella, podemos ver que hay varios rectangulos superpuestos.

En particular, el rectángulo pequeño que hay sobre la zona de Mexico se encuentra completamente dentro de otro rectángulo. Además, no es posible editarlo haciendo click sobre el mismo, porque al hacerlo se selecciona el rectángulo grande.

Esto se puede resolver cambiando el “indice Z” de los rectángulos, que indica el orden en el que se superponen unos sobre otros. Cuando mayor es el índice Z de un rectángulo, mas “arriba” se encuentra en la pila de rectángulos.

Para conseguir esta funcionalidad, vamos a cambiar nuestro manejador del evento “click” de modo que envíe el rectángulo a la parte superior de la pila cuando se pone en modo edición, y lo envíe al fondo de la pila cuando se abandona el modo edición.

El código completo del manejador del evento “click” queda como sigue:

    google.maps.event.addListener(rectangulos[i],"click",function(){
        for (i = 0; i < 4; i++) {
            this.setOptions({ editable: ! this.getEditable()});
            if (this.getEditable()) {
                // Enviar el rectángulo a la parte superior de la pila
                // Primero, asegurar que el zIndex de todos los rectángulos es 0
                for (i = 0; i < 4; i++) {
                    rectangulos[i].setOptions({ zIndex: 0});
                }
                // Despues, establecer en diez el zIndex del rectángulo seleccionado
                this.setOptions({ zIndex: 10});
            } else {
                // Enviar el rectángulo al fondo de la pila
                // Primero, asegurar que el zIndex de todos los rectángulos es 10
                for (i = 0; i < 4; i++) {
                    rectangulos[i].setOptions({ zIndex: 10});
                }
                // Despues, establecer en cero el zIndex del rectángulo seleccionado
                this.setOptions({ zIndex: 0});
            }
    });

 

Referencias:

Documentación de referencia de la clase Rectangle

 

 Publicado por en 2:33 pm

 Deja un comentario

(requerido)

(requerido)