Sí, puede usar mosaicos personalizados con Android Maps API v2 ; puede ver un ejemplo completamente funcional en nuestra aplicación OpenTripPlanner para Android en Github . (También puede descargar la aplicación directamente desde Google Play )
Apoyamos a los siguientes proveedores de mosaicos:
- LyrkOpenStreetMap
- MapQuestOpenStreetMap
- Mapnik
- CycleMap
- Google (normal, satélite, híbrido, terreno)
Nuestra clase CustomUrlTileProvider se puede ver aquí en Github , y también la he pegado a continuación:
public class CustomUrlTileProvider extends UrlTileProvider {
private String baseUrl;
public CustomUrlTileProvider(int width, int height, String url) {
super(width, height);
this.baseUrl = url;
}
@Override
public URL getTileUrl(int x, int y, int zoom) {
try {
return new URL(baseUrl.replace("{z}", "" + zoom).replace("{x}", "" + x)
.replace("{y}", "" + y));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
Y aquí está el código que cambia entre proveedores de mosaicos de mapas, según la preferencia del usuario:
/**
* Changes the tiles used to display the map and sets max zoom level.
*
* @param overlayString tiles URL for custom tiles or description for
* Google ones
*/
public void updateOverlay(String overlayString) {
int tile_width = OTPApp.CUSTOM_MAP_TILE_SMALL_WIDTH;
int tile_height = OTPApp.CUSTOM_MAP_TILE_SMALL_HEIGHT;
if (overlayString == null) {
overlayString = mPrefs.getString(OTPApp.PREFERENCE_KEY_MAP_TILE_SOURCE,
mApplicationContext.getResources()
.getString(R.string.map_tiles_default_server));
}
if (mSelectedTileOverlay != null) {
mSelectedTileOverlay.remove();
}
if (overlayString.startsWith(OTPApp.MAP_TILE_GOOGLE)) {
int mapType = GoogleMap.MAP_TYPE_NORMAL;
if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_HYBRID)) {
mapType = GoogleMap.MAP_TYPE_HYBRID;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_NORMAL)) {
mapType = GoogleMap.MAP_TYPE_NORMAL;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_TERRAIN)) {
mapType = GoogleMap.MAP_TYPE_TERRAIN;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_SATELLITE)) {
mapType = GoogleMap.MAP_TYPE_SATELLITE;
}
mMap.setMapType(mapType);
mMaxZoomLevel = mMap.getMaxZoomLevel();
} else {
if (overlayString.equals(getResources().getString(R.string.tiles_mapnik))) {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_mapnik_max_zoom);
} else if (overlayString.equals(getResources().getString(R.string.tiles_lyrk))) {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_lyrk_max_zoom);
tile_width = OTPApp.CUSTOM_MAP_TILE_BIG_WIDTH;
tile_height = OTPApp.CUSTOM_MAP_TILE_BIG_HEIGHT;
} else {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_maquest_max_zoom);
}
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
CustomUrlTileProvider mTileProvider = new CustomUrlTileProvider(
tile_width,
tile_height, overlayString);
mSelectedTileOverlay = mMap.addTileOverlay(
new TileOverlayOptions().tileProvider(mTileProvider)
.zIndex(OTPApp.CUSTOM_MAP_TILE_Z_INDEX));
if (mMap.getCameraPosition().zoom > mMaxZoomLevel) {
mMap.moveCamera(CameraUpdateFactory.zoomTo(mMaxZoomLevel));
}
}
}
Aquí hay una captura de pantalla de los mosaicos de MapQuest OpenStreetMap:
Para obtener más información sobre cómo crear sus propios mosaicos, consulte la documentación de Google para TileOverlay , así como la wiki de OpenStreetMap para "Crear sus propios mosaicos" .
Específicamente, la documentación de Google dice:
Tenga en cuenta que el mundo se proyecta utilizando la proyección de Mercator (ver Wikipedia) con el lado izquierdo (oeste) del mapa correspondiente a -180 grados de longitud y el lado derecho (este) del mapa correspondiente a 180 grados de longitud. Para hacer que el mapa sea cuadrado, el lado superior (norte) del mapa corresponde a 85.0511 grados de latitud y el lado inferior (sur) del mapa corresponde a -85.0511 grados de latitud. Las áreas fuera de este rango de latitud no se representan.
En cada nivel de zoom, el mapa se divide en mosaicos y solo se descargan y representan los mosaicos que se superponen a la pantalla. Cada mosaico es cuadrado y el mapa se divide en mosaicos de la siguiente manera:
En el nivel de zoom 0, un mosaico representa el mundo entero. Las coordenadas de ese mosaico son (x, y) = (0, 0).
En el nivel de zoom 1, el mundo se divide en 4 mosaicos dispuestos en una cuadrícula de 2 x 2. ...
- En el nivel de zoom N, el mundo se divide en fichas 4N dispuestas en una cuadrícula de 2N x 2N.
Tenga en cuenta que el nivel de zoom mínimo que admite la cámara (que puede depender de varios factores) es GoogleMap.getMinZoomLevel y el nivel de zoom máximo es GoogleMap.getMaxZoomLevel.
Las coordenadas de los mosaicos se miden desde la esquina superior izquierda (noroeste) del mapa. En el nivel de zoom N, los valores de x de las coordenadas de mosaico varían de 0 a 2N - 1 y aumentan de oeste a este y los valores de y varían de 0 a 2N - 1 y aumentan de norte a sur.
Las URL formateadas que se utilizan en OTP Android para hacer referencia a cada proveedor de mosaico se ven así:
Entonces, para los proveedores anteriores, las imágenes en mosaico son archivos PNG dispuestos en la estructura de directorios indicada por la documentación de Google. Seguiría un formato similar para crear sus propios mosaicos de mapas alojados en su propio servidor. Tenga en cuenta que estas URL / imágenes deben ser de acceso público para el dispositivo móvil (es decir, no pueden protegerse con contraseña).
La solución más extensa que he encontrado está en esta respuesta de StackOverflow :
Básicamente, necesita implementar su propio TileProvider y usarlo como TileOverlay
En un par de aplicaciones, hemos utilizado este tipo de capa para mostrar mosaicos en el mapa, pero descubrimos que los mosaicos ocupaban mucho espacio. Por lo tanto, pasamos a usar mbtiles y esta biblioteca para mostrar los datos de mbtiles en el mapa.
fuente