Superposiciones de mosaicos

Una superposición de mosaicos, a veces denominada "capa de mosaicos", es una colección de imágenes que se muestran sobre los mosaicos de mapas base.

Muestras de código

El repositorio ApiDemos de GitHub incluye una muestra de código que ilustra el elemento de superposición de mosaicos:

Introducción

Un TileOverlay define un conjunto de imágenes que se agregan sobre los mosaicos de mapas base.

Debes proporcionar los mosaicos para cada nivel de zoom que desees admitir. Si tienes suficientes mosaicos en varios niveles de zoom, puedes complementar los datos de mapas de Google para todo el mapa.

Las superposiciones de mosaicos son útiles cuando deseas agregar muchas imágenes al mapa que, por lo general, cubren áreas geográficas extensas. Por el contrario, las superposiciones de suelo resultan útiles cuando deseas fijar una sola imagen en un área del mapa.

También puedes usar superposiciones de mosaicos transparentes para agregar elementos adicionales al mapa. Para ello, establece un factor de transparencia en la superposición de mosaicos de forma programática o proporciona imágenes de mosaicos transparentes.

Coordenadas de mosaicos y niveles de zoom

La API de Google Maps desglosa las imágenes de cada nivel de zoom y forma un conjunto de mosaicos de mapa cuadrados dispuestos en una cuadrícula. Cuando en un mapa se realiza un desplazamiento hacia una nueva ubicación, o un cambio en el nivel de zoom, la API de Google Maps determina cuáles son los mosaicos necesarios para completar esta acción y convierte esa información en un conjunto de mosaicos que se deben recuperar.

El mosaico con coordenadas (0,0) siempre se encuentra en la esquina noroeste del mapa. Los valores de x aumentan de oeste a este, y los de y lo hacen de norte a sur. Los mosaicos se indexan a partir de coordenadas x,y desde el origen mencionado.

En el nivel de zoom 0, se renderiza el mundo entero en un solo mosaico. Cada nivel de zoom duplica la ampliación. Por lo tanto, en el nivel de zoom 1 el mapa se renderizará como una cuadrícula de mosaicos de 2 x 2. En el nivel de zoom 2, la cuadrícula es de 4 x 4. En el nivel de zoom 3, la cuadrícula es de 8 x 8.

Por ejemplo, en el nivel de zoom 2, la Tierra se divide en 16 mosaicos. Se puede hacer referencia a cada mosaico a través de una combinación única de x, y y zoom:

Al crear imágenes para una capa de mosaicos, deberás crear una imagen por cada mosaico de cada nivel de zoom que desees admitir. Google Maps aplica 256 dp (píxeles independientes del dispositivo) al mostrar mosaicos. Para dispositivos de alta resolución, te recomendamos mostrar mosaicos con un alto valor de dpi (512 x 512 px). Consulta la documentación para desarrolladores de Android a fin de obtener información sobre cómo admitir diferentes tamaños y densidades de pantallas.

Nota: Los niveles de zoom que admite la cámara dependen de varios factores y no están relacionados con los que admitirán tus mosaicos.

  1. GoogleMap.getMaxZoomLevel() muestra el nivel de zoom máximo disponible en la posición actual de la cámara. Se tiene en cuenta el tipo de mapa que se encuentra en uso. Por ejemplo, un mapa satelital o terrestre puede tener un nivel de zoom máximo inferior al de los mosaicos del mapa base.
  2. GoogleMap.getMinZoomLevel() muestra el nivel de zoom mínimo, que es el mismo para cada ubicación (a diferencia del nivel de zoom máximo), pero puede variar según el dispositivo y el tamaño de mapa.

Cómo agregar una superposición de mosaicos

La manera más simple y común de crear una superposición de mosaicos consiste en proporcionar una URL que apunte a la imagen de mosaicos correspondiente. UrlTileProvider es una implementación parcial de TileProvider que proporciona mosaicos de imágenes según una URL. Para esta clase es necesario que todas las imágenes tengan las mismas dimensiones.

Deberás implementar UrlTileProvider.getTileUrl(). Este método acepta las coordenadas de mosaicos (x, y, zoom) y muestra una URL que apunta a la imagen que se usará para el mosaico. El método debe mostrar "null" si no hay mosaicos para los valores de x, y y zoom. Una URL puede apuntar a un recurso web, un elemento de Android o un archivo en el disco local.

Configura tus imágenes de mosaico disponibles en un servidor, definidas para las coordenadas x,y y los niveles de zoom que quieras admitir. Luego, agrega la superposición de mosaicos:

  1. Define un objeto UrlTileProvider para proporcionar las imágenes de mosaicos.
  2. Anula getTileUrl() a fin de construir la URL para cada imagen de mosaico.
  3. Proporciona un objeto TileOverlayOptions con las opciones relevantes:
    • fadeIn: Booleano. Especifica si se debe aplicar fundido de entrada a los mosaicos. El valor predeterminado es true. Probablemente te resulte útil desactivar el fundido de entrada al pasar rápidamente de una superposición de mosaicos a otra. Para obtener más información sobre la relación entre la transparencia y el fundido de entrada, consulta la sección sobre transparencia a continuación.
    • tileProvider: El TileProvider que se usará para esta superposición.
    • transparency: Número de punto flotante. Establece un factor de transparencia para imágenes de mosaicos. El valor debe estar dentro del rango [0.0f, 1.0f], en el que 0.0f significa totalmente opaco (predeterminado) y 1.0f significa completamente transparente. Consulta la sección sobre transparencia que aparece a continuación para ver una muestra de código y conocer la relación entre la transparencia y el fundido de entrada.
    • visible: Booleano. Especifica la visibilidad de la superposición de mosaicos. Las superposiciones de mosaicos invisibles (valor false) no se dibujan en el mapa, pero conservan todas las demás propiedades. El valor predeterminado es true.
    • zIndex: Determina el orden en el que se dibujará la superposición de mosaicos respecto de otras superposiciones, como las superposiciones de suelo, los círculos, las polilíneas y los polígonos. Las superposiciones con índice z más alto se dibujan sobre aquellas con índice z más bajo. Para las superposiciones con el mismo índice z, el orden es arbitrario. El valor predeterminado del índice z es 0. Ten en cuenta que los marcadores siempre se dibujan encima de otras superposiciones, independientemente del índice z de estas.
  4. Llama a GoogleMap.addTileOverlay() para agregar la superposición al mapa.

Java


private GoogleMap map;

TileProvider tileProvider = new UrlTileProvider(256, 256) {

    @Override
    public URL getTileUrl(int x, int y, int zoom) {

        /* Define the URL pattern for the tile images */
        String s = String.format("http://my.image.server/images/%d/%d/%d.png", zoom, x, y);

        if (!checkTileExists(x, y, zoom)) {
            return null;
        }

        try {
            return new URL(s);
        } catch (MalformedURLException e) {
            throw new AssertionError(e);
        }
    }

    /*
     * Check that the tile server supports the requested x, y and zoom.
     * Complete this stub according to the tile range you support.
     * If you support a limited range of tiles at different zoom levels, then you
     * need to define the supported x, y range at each zoom level.
     */
    private boolean checkTileExists(int x, int y, int zoom) {
        int minZoom = 12;
        int maxZoom = 16;

        return (zoom >= minZoom && zoom <= maxZoom);
    }
};

TileOverlay tileOverlay = map.addTileOverlay(new TileOverlayOptions()
    .tileProvider(tileProvider));

      

Kotlin


private lateinit var map: GoogleMap

var tileProvider: TileProvider = object : UrlTileProvider(256, 256) {
    override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? {

        /* Define the URL pattern for the tile images */
        val url = "http://my.image.server/images/$zoom/$x/$y.png"
        return if (!checkTileExists(x, y, zoom)) {
            null
        } else try {
            URL(url)
        } catch (e: MalformedURLException) {
            throw AssertionError(e)
        }
    }

    /*
     * Check that the tile server supports the requested x, y and zoom.
     * Complete this stub according to the tile range you support.
     * If you support a limited range of tiles at different zoom levels, then you
     * need to define the supported x, y range at each zoom level.
     */
    private fun checkTileExists(x: Int, y: Int, zoom: Int): Boolean {
        val minZoom = 12
        val maxZoom = 16
        return zoom in minZoom..maxZoom
    }
}

val tileOverlay = map.addTileOverlay(
    TileOverlayOptions()
        .tileProvider(tileProvider)
)

      

Para ver un ejemplo de un objeto UrlTileProvider en funcionamiento, consulta la sección sobre TileOverlayDemoActivity en el código de muestra que se incluye en el paquete del SDK de Servicios de Google Play.

Cómo establecer la transparencia para las superposiciones de mosaicos

Puede resultar útil superponer mosaicos transparentes en el mapa, para que los usuarios puedan ver el mapa base debajo de los mosaicos superpuestos. Para ello, proporciona tus propios mosaicos transparentes o establece un factor de transparencia en la superposición de mosaicos de manera programática.

En la siguiente muestra de código, se alterna la transparencia de la superposición de mosaicos entre 0.5f y 0.0f:

Java


private TileOverlay tileOverlayTransparent;

@Override
public void onMapReady(GoogleMap map) {
    tileOverlayTransparent = map.addTileOverlay(new TileOverlayOptions()
        .tileProvider(new UrlTileProvider(256, 256) {
            // ...
        })
        .transparency(0.5f));
}

// Switch between 0.0f and 0.5f transparency.
public void toggleTileOverlayTransparency() {
    if (tileOverlayTransparent != null) {
        tileOverlayTransparent.setTransparency(0.5f - tileOverlayTransparent.getTransparency());
    }
}

      

Kotlin


private var tileOverlayTransparent: TileOverlay? = null

override fun onMapReady(map: GoogleMap) {
    tileOverlayTransparent = map.addTileOverlay(
        TileOverlayOptions()
            .tileProvider(object : UrlTileProvider(256, 256) {
                // ...
            })
            .transparency(0.5f)
    )
}

// Switch between 0.0f and 0.5f transparency.
fun toggleTileOverlayTransparency() {
    tileOverlayTransparent?.let {
        it.transparency = 0.5f - it.transparency
    }
}

      

La transparencia se implementa como un multiplicador de canal alfa para imágenes de mosaicos. Para establecer la transparencia de una superposición de mosaicos, proporciona un objeto TileOverlayOptions con el valor de transparency en el rango [0.0f, 1.0f], como se muestra más arriba. Un valor de 0.0f significa que la superposición de mosaicos es totalmente opaca, y uno de 1.0f significa que es totalmente transparente. El valor predeterminado es 0.0f (opaco).

Si deseas acceder a la transparencia de la superposición de mosaicos, llama a TileOverlay.getTransparency(). Si deseas cambiarla, llama a TileOverlay.setTransparency().

Transparencia, animación y fundido de entrada

No existe animación cuando se modifica la transparencia. La opción de transparencia funciona junto con la opción de fundido de entrada.

El fundido de entrada proporciona animación a la transparencia durante la carga de mosaicos. Si fijas un valor de transparencia, se aplicará a los mosaicos un fundido de entrada que irá de una transparencia total al valor de transparencia definido. Si cambias el valor de transparencia durante el fundido de entrada, la animación continuará desarrollándose hasta alcanzar el nuevo valor.

Cómo quitar una superposición de mosaicos

Puedes quitar una superposición de mosaicos a través del método TileOverlay.remove().

Java


tileOverlay.remove();

      

Kotlin


tileOverlay?.remove()

      

Cómo borrar mosaicos inactivos

Si los mosaicos proporcionados por la superposición se vuelven "inactivos", puedes llamar a clearTileCache() para forzar una actualización. Esto hará que vuelvan a cargarse todos los mosaicos de esta superposición. Por ejemplo, si se modifican los mosaicos proporcionados por TileProvider, debes llamar a clearTileCache() posteriormente para asegurarte de que dejen de renderizarse los mosaicos anteriores.

Java


tileOverlay.clearTileCache();

      

Kotlin


tileOverlay?.clearTileCache()