Si una carencia hay que destacar de la API de Google Maps es el poder incluir mapas offline en nuestras apps, de hecho hasta hace poco ni siquiera en la app oficial se podía y ahora que si se puede espero que sea un indicativo de que en un futuro disfrutaremos de esta funcionalidad en la API. Pero como no nos gusta esperar y como no hay que limitarse a una única opción hoy os venimos a contar la características mas interesante de OpenStreetMap y de la librería que nos atañe, los mapas offline en OSMDROID.
NOTA: Para el aprovechamiento de este tutorial se dan por asimiladas unas nociones básicas sobre el uso de la librería OSMDROID, si no tenéis esas nociones os recomendamos pasar por el tutorial de introducción publicado en AndroCode.
¿COMO FUNCIONA?
La arquitectura de OSMDROID está basada en una serie de Providers para la obtención de “Tiles” (las tiles son las secciones que conformaran nuestro mapa). Esta arquitectura está diseñada de forma modular y extensible proporcionando acceso a las diversas fuentes que se nos proporcionan, entre las que se incluyen recursos online, cache, archivos…
El sistema comprobará si disponemos de los recursos necesarios en cache y si no es así buscara los mismos a través de las siguientes opciones disponibles, entre las que estarán los mapas que hayamos incluidos dentro de nuestra app. Por tanto, asi así lo desearamos podríamos elimiar de nuestra app los permisos de acceso a internet ya que nuestra aplicacion no haría uso de ellos.
OBTENCIÓN DE TILES A TRAVES DE MOBAC
Para tener acceso a los mapas offline deberemos descargarlos nosotros mismos e incluirlos dentro de de nuestras apps. Para esto disponemos de varias opciones, una de estas, y la más sencilla, es usar Mobile Atlas Creator (MOBAC), una aplicación creada precisamente para la obtención de estos mapas. Una vez nos hemos descargado la aplicación y la hemos ejecutado nos encontraremos ante la siguiente pantalla:

Aquí deberemos indicar el nombre de nuestro Atlas así como el formato en el que lo guardaremos, en nuestro caso "osmdroid ZIP" o "osmdroid SQLITE" (aunque este último aún no he conseguido que funcione así que nos quedaremos con el primero).
Ya en la pantalla principal de la aplicación deberemos configurar varias cosas:
- Origen de los mapas: Seleccionaremos OpenStreetMap Mapnik.
- Coordenadas de la zona: Deberemos selecciona la zona que queremos descargar a partir de sus coordenadas. Podemos introducirlas manualmente o realizando una selección con el raton sobre el mapa que se muestra.
- Niveles de zoom: Prodremos elegir tambien los niveles de zoom que deseamos descargarnos, dato importante a tener en cuenta y que deberemos madurar en función de las necesidades de nuestra app. ¿Y esto porque? Pues por que resulta que conforme aumentamos el nivel del zoom se incrementan el número de tiles necesarios para mapear una zona y por tanto el tamañó de los datos pudiendo alcanzar estos un tamaño considerable.

Una vez seleccionados estos datos, en la zona “Atlas Content” deberemos añadir la selección deseada. En la sección “Saved profile” tenemos la opción de almacenar estas configuraciones para futuras descargas. Con todo ya configurado solo tenemos que hacer click en “Create atlas” y nuestros mapas serán descargados, mostrandonos una ventana desde la que podremos acceder a los ficheros generados.
Con nuestro ficheros ya generados y descargados tan solo tendremos que copiarlos a nuestra tarjeta SD en la carpeta /sdcart/osmdroid y la librería se encargará sola de acceder a ellos.
LIMITANDO EL DESPLAZAMIENTO
Cuando creamos apps que hacen uso de mapas online normalmente desearemos limitar la zona de mapa a visualizar para que esta no exceda la zona de mapa almacena en nuestras aplicaciones, puesto que si no recorreríamos zonas de mapas que no podriamos cargar ni visualizar. Realizar esta acción no es trivial ya que esta funcionalidad aun no viene incluida en la librería (esperamos que pronto si), así que deberemos descargarnos el código fuente y realizar unos cambios nosotros mismos.
Deberemos descargarnos el código fuente y crear un proyecto en eclipse para nosotros mismos compilar la librería que posteriormente usaremos como os hemos explicado. Importaremos el proyecto osmdroid-android a nuestro entorno de trabajao en eclipse vía SVN desde la siguiente dirección http://osmdroid.googlecode.com/svn/branches/release_3_0_5. Si os aparecen errores en el proeycto no os preocupéis mas adelante os explicaremos como configurarlo bien antes de compilar.
Una vez creado deberemos realizar una serie de cambios en el fichero MapView.java. Estos cambios vienen recogidos en el siguiente patch. En la líneas que empiezan por @@ veremos a que líneas corresponden estos cambios y deberemos incluir las líneas que empiezan por + y eliminar las que empiezan por -. No obstante os facilito la clase ya modificada para que tan solo tengáis que sustituirla:
MapView.java (46,38 kb)
Con esto ya tendríamo listo los cambios, pero como os indicabamos antes de compilar deberemos realizar unos cambios en el proyecto:
- Ir a la configuración del Java Build Path (hacer click con el boton derecho en el proyecto -> properties -> Java Build Path -> Libraries).
- Editar la entrada “ANDROID_SDK_PLATFORM/android.jar”.
- Hacer click en el boton “Variable” y añadir una nueva llamada “ANDROID_SDK_PLATFORM” con la ruta necesaria. Por ejemplo C:/Program Files (x86)/Android/android-sdk/platforms/android-3.
- Volver a la pestaña Libraries del Build Path y mirar dentro de la entrada ”JUnit 4″ el nombre de fichero de hamrest.core y la ruta de junit.jar. Apuntalas, las necesitaras más adelante.
- Abandonamos Build Path y cambiamos a las opciones de Builders.
- Creamos un nuevo Ant Builder añadiendo build.xml al “Buildfile” y añadiendo el proyecto como Base Directory.
- Cambiamos a la pestaña "Targets" y hacemos click en "Set Targets…" para Manual Build.
- Comprobamos que “jar” esta seleccionado y aceptamos. Ahora en Manual Build deberían estar seleccionados: “build, jar”.
- Volvemos a aceptar y nos aseguramo de que el nuevo Ant builder esta activo y el java Builder inactivo.
- Abrir “build-jar.xml y borrar “depends=”version” en la linea 32
- Borrar en la línea 37 ".r${version}
- Cambiar en la línea 43 “destfile” por la ruta donde queremos crear el fichero jar.
- Guardamos y abrimos "build.xml" y modificamos las siguientes líneas.
- Línea 9 – en el campo value introducimos la ruta del SDK, la misma que introdujimos anteriormente en la configuración del Build Path.
- Línea 10 – ruta donde tenemos instalado eclipse.
- Líneas 16 y 17 – Comprabar que los valores son los correctos, deben corresponderse con los que apuntamos anteriormente en el cuarto paso.
- Ejecutamos "build.xml" como "Ant Build" y nuestro jar estará listo para incluir en el proyecto de nuestra app.
Si aparece algún error relacionado con javac puede ser debido a que tenemos congurado el JRE en vez del JDK dentro del proyecto.
Con nuestro jar ya listo y compilado e incluido en nuestro proyecto tan solo deberemos usar el siguiente tip con la zona que queremos limitar y todo ira como la seda:
BoundingBoxE6 bbox = new BoundingBoxE6(limit north, limit east, limit south, limit west);
mapView.setScrollableAreaLimit(bbox);
Para saber las coordenadas que queremos limitar podemos averiguarlo a traves de la aplicación de MOBAC en de la propia web de OpenStreetMap en la sección de Exportar.
No obstante otra limitación que quizas queramos imponer es la de los niveles de zoom, puesto que puede que no hallamos descargado tiles para todos estos. En este caso deberíamos crearnos, en nuestro proyecto, nuestro propio MapView que extendiera al de la librería y del que sobreescribiriamos los métodos getMaxZoomLevel() y getMinZoomLevel().
public class ZoomLimitMapView extends MapView
{
/* snip the constructors */
@Override
public int getMaxZoomLevel()
{
return 15;
}
@Override
public int getMinZoomLevel()
{
return 4;
}
}
Y con esto habríamos acabado, espero que os sea de utilidad.
OSMDROID | http://code.google.com/p/osmdroid/
Mobile Atlas Creator | http://mobac.sourceforge.net/