Mapas en Android – Google Maps Android API (3)

Curso Programación Android

Este artículo forma parte del Curso de Programación Android que tienes disponible de forma completamente gratuita en sgoliver.net

En los dos artículos anteriores (I y II) del curso hemos visto cómo crear aplicaciones utilizando la API de Google Maps para Android y hemos descrito las acciones y eventos principales de los mapas.

En este último artículo de la serie nos vamos a centrar en la creación y gestión de marcadores, y en el dibujo de elementos gráficos, como líneas y polígonos, sobre el mapa.

De forma similar al artículo anterior, para esta ocasión vamos a partir de nuevo de la aplicación de ejemplo creada en el primer artículo de la serie sobre mapas, a la que añadiremos tres botones superiores para demostrar las nuevas funcionalidades que presentaremos en esta entrega.

Sin más preámbulos, empecemos por la creación de marcadores. Rara es la aplicación Android que hace uso de mapas sin utilizar también este tipo de elementos para resaltar determinados puntos de interés sobre el mapa. Agregar un marcador básico a un mapa resulta tan sencillo como llamar al método addMarker() pasándole la posición, en forma de objeto LatLng, y el texto a mostrar en la ventana de información del marcador. En nuestra aplicación de ejemplo añadiremos al primer botón una acción de este tipo, de forma que cuando lo pulsemos se añada automáticamente un marcador sobre España con el texto “Pais: España“.

btnMarcador = (Button)findViewById(R.id.btnMarcador);
btnMarcador.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
         insertarMarcador();
    }
});

//...

private void insertarMarcador() {
    mapa.addMarker(new MarkerOptions()
        .position(new LatLng(40.3936945, -3.701519))
        .title("Pais: España"));
}

Así de sencillo, basta con llamar al método addMarker() pasando como parámetro un nuevo objeto MarkerOptions sobre el que establecemos la posición del marcador (método position()) y el texto a incluir en la ventana de información del marcador (métodos title() para el título y snippet() para el resto del texto). Si ejecutamos la aplicación de ejemplo y pulsamos el botón “MARCADORES” aparecerá el siguiente marcador sobre el mapa:

marcador

Si pulsamos sobre el marcador, la vista se centrará en la posición del marcador y se mostrará la ventana de información con el texto indicado.

marcador-pulsado

Pero vemos que además aparecen por defecto en la esquina inferior derecha dos botones para mostrar dicha ubicación en la aplicación de Google Maps y para calcular la ruta al lugar marcado. Si no queremos que aparezcan estos botones, debemos llamar previamente al método setMapToolbarEnabled(false) sobre nuestro objeto GoogleMap. Podríamos hacer esto por ejemplo dentro del método onMapReady() tras obtener la referencia al mapa:

@Override
public void onMapReady(GoogleMap map) {
    mapa = map;

    mapa.getUiSettings().setMapToolbarEnabled(false);
}

Si no nos gusta el comportamiento por defecto al pulsar sobre un marcador, también tenemos la posibilidad de definirlo de forma personalizada asignando al mapa dicho evento como cualquiera de los comentados anteriormente. En este caso el listener se asignará al mapa mediante el método setOnMarkerClickListener() y sobrescribiremos el método onMarkerClick(). Dicho método recibe como parámetro el objeto Marker pulsado, de forma que podamos identificarlo accediendo a su información (posición, título, texto, …). Veamos un ejemplo donde mostramos un toast con el título del marcador pulsado:

mapa.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
    public boolean onMarkerClick(Marker marker) {
        Toast.makeText(
            MainActivity.this,
            "Marcador pulsado:n" +
            marker.getTitle(),
            Toast.LENGTH_SHORT).show();

         return true;
    }
});

Con el código anterior, si pulsamos sobre el marcador de España aparecerá el siguiente mensaje informativo:

marcador-pulsado-2

Salvo este último punto, todo lo explicado sobre marcadores corresponde al comportamiento por defecto de la API, sin embargo también es posible por supuesto personalizar determinadas cosas, como por ejemplo el aspecto de los marcadores. Esto se sale un poco del alcance de este artículo, donde pretendía describir los temas más básicos, pero para quien esté interesado tan sólo decir que mediante los métodos icon() y anchor() del objeto MakerOptions que hemos visto antes es posible utilizar una imagen personalizada para mostrar como marcador en el mapa. En la documentación oficial (en inglés) podéis encontrar un ejemplo de cómo hacer esto.

Como último tema, vamos a ver cómo dibujar líneas y polígonos sobre el mapa, elementos muy comúnmente utilizados para trazar rutas o delimitar zonas del mapa. Para realizar esto vamos a actuar una vez más directamente sobre la vista de mapa, sin necesidad de añadir overlays o similares (para quienes recuerden versiones anteriores de la API), y ayudándonos de los objetos PolylineOptions y PolygonOptions respectivamente.

Para dibujar una linea lo primero que tendremos que hacer será crear un nuevo objeto PolylineOptions sobre el que añadiremos, utilizando su método add(), las coordenadas (latitud-longitud) de todos los puntos que conformen la linea. Tras esto estableceremos el grosor y color de la linea llamando a los métodos width() y color() respectivamente, y por último añadiremos la linea al mapa mediante su método addPolyline() pasándole el objeto PolylineOptions recién creado.

En nuestra aplicación de ejemplo haremos esto en el segundo botón de demostración para dibujar un rectángulo sobre España. Veamos cómo queda el código:

btnLineas = (Button)findViewById(R.id.btnLineas);
btnLineas.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mostrarLineas();
    }
});

//...

private void mostrarLineas()
{
    //Dibujo con Lineas

    PolylineOptions lineas = new PolylineOptions()
        .add(new LatLng(45.0, -12.0))
        .add(new LatLng(45.0, 5.0))
        .add(new LatLng(34.5, 5.0))
        .add(new LatLng(34.5, -12.0))
        .add(new LatLng(45.0, -12.0));

    lineas.width(8);
    lineas.color(Color.RED);

    mapa.addPolyline(lineas);
}

Ejecutando esta acción en el emulador veríamos lo siguiente:

lineas-poligonos

Pues bien, esto mismo podríamos haberlo logrado mediante el dibujo de polígonos, cuyo funcionamiento es muy similar. Para ello crearíamos un nuevo objeto PolygonOptions y añadiremos las coordenadas de sus puntos en el sentido de las agujas del reloj. En este caso no es necesario cerrar el circuito (es decir, que la primera coordenada y la última fueran iguales) ya que se hace de forma automática. Otra diferencia es que para polígonos el ancho y color de la linea los estableceríamos mediante los métodos strokeWidth() y strokeColor(). Además, el dibujo final del polígono sobre el mapa lo haríamos mediante addPolygon(). En nuestro caso de ejemplo, implementado en el tercer botón de demostración, quedaría como sigue:

btnPoligono = (Button)findViewById(R.id.btnPoligono);
btnPoligono.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mostrarPoligono();
    }
});

//...
    
private void mostrarPoligono()
{
    //Dibujo con Poligonos

    PolygonOptions rectangulo = new PolygonOptions()
        .add(new LatLng(45.0, -12.0),
             new LatLng(45.0, 5.0),
             new LatLng(34.5, 5.0),
             new LatLng(34.5, -12.0),
             new LatLng(45.0, -12.0));

    rectangulo.strokeWidth(8);
    rectangulo.strokeColor(Color.RED);

    mapa.addPolygon(rectangulo);
}

El resultado al ejecutar la acción en el emulador debería ser exactamente igual que el anterior.

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la pagina del curso en GitHub.

Y con esto habríamos concluido la serie de tres artículos destinados a describir el funcionamiento básico de API de Google Maps para Android. Espero haber aclarado las dudas principales a la hora de comenzar a utilizar esta funcionalidad. Tampoco descarto algún artículo adicional para comentar temas algo más avanzados sobre esta API, pero eso será más adelante.

Curso Programación Android

Este artículo forma parte del Curso de Programación Android que tienes disponible de forma completamente gratuita en sgoliver.net