Blog dedicado a la programación y a la informática en general

Ir al contenido | Ir al menú | Ir a las búsquedas

OpenStreetMap en Android Studio

osmstudio.png

EDITADO 23/05/2017: actualizado a la última versión de Osmdroid.

EDITADO 03/08/2017: añadida comprobación de permisos en el proyecto de ejemplo para Android 6>.

EDITADO 07/08/2017: Actualizaciones de ubicaciones (proyecto de ejemplo).

Tener mapas en nuestra aplicación android es muy fácil con Android Studio ya que no hacen falta registros, cuentas, tokens o API Keys. Veremos que es muy sencillo con Android Studio.

Vamos a crear un proyecto de ejemplo para que de más claro. Por lo tanto el primer paso es crear el proyecto.

nuevo_proyecto.png

Android Studio proporciona un asistente muy fácil de seguir, le ponemos un nombre al proyecto, seleccionamos los dispositivos destinatarios de la aplicación, en este caso sólo marcaremos "Phone and Tablet" y por ejemplo la API 17 (versión 4.2), aunque podéis seleccionar otra. Después seleccionamos una actividad en blanco y finalizamos el asistente.

fin_asistente.png

Una vez con el proyecto base creado tenemos que añadir a las dependencias del proyecto la librería osmdroid, esto lo hacemos editando el fichero build.gradle (app) y dentro de dependencies {} añadimos la siguiente línea:

compile 'org.osmdroid:osmdroid-android:5.6.4'

Una vez hecho esto, sincronizamos el proyecto y esperamos a que termine.

Ahora tenemos que añadirle permisos para poder obtener los mapas de Internet, por lo tanto añadiremos en nuestro fichero manifest.xml (por encima del tag application) las siguientes líneas:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Ahora añadiremos en la vista de nuestra actividad la View donde se mostrará el mapa, abrimos el correspondiente layout y añadimos dentro de un LinearLayout:

<org.osmdroid.views.MapView
        android:id="@+id/openmapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>

Y por último modificamos nuestro código Java para que quede como en la siguiente captura:

activity.png

Ya estamos listos para ejecutar la aplicación y probarla, si todo va bien veremos el siguiente resultado:

app.png

Podemos marcar nuestra posición actual y centrar el mapa en ella, para ello tenemos disponible una capa llamada MyLocationNewOverlay que añadiremos (o no) al mapa y moveremos el mapa a nuestra posición actual mediante el método runOnFirstFix, ya que si lo hacemos directamente causaremos un NullPointerException:

final MyLocationNewOverlay myLocationoverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(getApplicationContext()), myOpenMapView);
myOpenMapView.getOverlays().add(myLocationoverlay); //No añadir si no quieres una marca
myLocationoverlay.enableMyLocation();
myLocationoverlay.runOnFirstFix(new Runnable() {
    public void run() {
        myMapController.animateTo(myLocationoverlay.getMyLocation());
    }
});

Podemos añadir marcas en puntos específicos creando una lista de puntos con una serie de atributos y creando una capa nueva que contenga esa información. Además, si añadimos un OnItemGestureListener podremos interactuar con los puntos añadidos y crear globos mediante la función setFocusItemsOnTap:

ArrayList<OverlayItem> puntos = new ArrayList<OverlayItem>();
puntos.add(new OverlayItem("Madrid", "Ciudad de Madrid", madrid));

ItemizedIconOverlay.OnItemGestureListener<OverlayItem> tap = new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
    @Override
    public boolean onItemLongPress(int arg0, OverlayItem arg1) {
        return false;
    }
    @Override
    public boolean onItemSingleTapUp(int index, OverlayItem item) {
        return true;
    }
};

ItemizedOverlayWithFocus<OverlayItem> capa = new ItemizedOverlayWithFocus<OverlayItem>(this, puntos, tap);
capa.setFocusItemsOnTap(true);
myOpenMapView.getOverlays().add(capa);

Y tendremos como resultado nuestra marca y globo informativo: final.png

Adjunto el proyecto de ejemplo.

Saludos!

Attachments

Comentarios

1. El Jueves, 5 de Enero de 2017, 12:49 por José

Excelente ayuda. Solo me resta preguntarte como hago si quiero usar un mapa offline con OSM. Muchas gracias desde ya.

2. El Viernes, 28 de Abril de 2017, 02:10 por Michael

Dos preguntas......

1 Por alguna razón no me carga el mapa (esta igual a tu ejemplo ).
2.Donde agrego lo de "MyLocationNewOverlay "

3. El Viernes, 28 de Abril de 2017, 02:23 por Michael

Otra ves..... punto 2 solucionado

pero sigue sin mostrarme l mapa

4. El Martes, 23 de Mayo de 2017, 16:20 por amunoz

Hola Michael,

He actualizado la entrada y adjunto un proyecto de ejemplo.

Creo que tu problema era el contenedor de la view del mapa, por defecto Android añade un layout de tipo ConstraintLayout y no basta con añadir la view del mapa. Cambiando ConstraintLayout por LinearLayout debe mostrarse.

Saludos!

5. El Martes, 23 de Mayo de 2017, 16:24 por amunoz

Hola José,

Puede que haga una entrada con ese tema, pero mientras podrías echarle un vistazo a la documentación oficial: 

https://github.com/osmdroid/osmdroid/wiki/Offline-Map-Tiles

Saludos

6. El Miércoles, 2 de Agosto de 2017, 17:01 por Lucia

Buenas tardes,
He realizado los mismos pasos y me sale el mapa vacío...
He descargado tu proyecto de ejemplo y me sale igual, ¿que puede ser?
Gracias.
Saludos!

7. El Jueves, 3 de Agosto de 2017, 07:26 por amunoz

Hola Lucía,

OpenStreepMap guarda las imágenes de los mapas en el almacenamiento externo y a partir de la versión 6 de Android hay que preguntar por los permisos de escritura antes de cargar el mapa.

He actualizado el proyecto de ejemplo con este cambio, podrás ver que he puesto todo lo referente al mapa en un procedimiento en lugar de en el onCreate.

Un saludo!

8. El Jueves, 3 de Agosto de 2017, 18:47 por Lucia

Gracias amunoz!

Me funciona correctamente. Solo me queda, en este código me muestra el muñeco en la ubicación actual, pero estoy intentando guardar los puntos geográficos(geopoint con latitud y longitud) de ese mismo punto y estoy teniendo problemas, ¿alguna idea?

Saludos!

9. El Lunes, 7 de Agosto de 2017, 08:15 por amunoz

Hola,

Lo que te aparece en el mapa es la última posición conocida que proporciona el sistema. Para obtener los cambios de ubicación hace falta crear un listener que le pasaremos al LocationManager del sistema. Este listener irá actualizando el mapa con la nueva ubicación.

Actualizo el proyecto de ejemplo por si te sirve. También te recomiendo la lectura de este tutorial (tiene dos partes): http://www.sgoliver.net/blog/locali...

Saludos

10. El Domingo, 3 de Junio de 2018, 17:23 por Paul

encontré un error por si acaso les sucede en la siguiente linea:

final MyLocationNewOverlay myLocationoverlay = new MyLocationNewOverlay (getApplicationContext(), new GpsMyLocationProvider(getApplicationContext()), myOpenMapView);

11. El Lunes, 29 de Octubre de 2018, 01:14 por 10DIEZ

Disculpa ya realice todos los pasos y creo estan correctos y tambien me sale la etiqueta con el nombre de la ubicación pero no se cual sea el problema que solo me sale una una cuadricula en lugar del mapa en mi telefono.¿alguna idea de cual pueda ser el problema?

12. El Martes, 13 de Noviembre de 2018, 08:08 por amunoz

Hola 10DIEZ,

Habilita los permisos de almacenamiento y ubicación para la aplicación. Seguramente sea eso.

OpenStreepMap cachea las imágenes del mapa en una carpeta llamada "osmdroid", si no puede escribir no muestra nada.

Saludos!

13. El Jueves, 17 de Enero de 2019, 02:19 por 10DIEZ

Excelente ya quedo, muchas gracias. Oye una pregunta de casualidad sabes si existe la posibilidad de cambiar el mapa a otro que sea de satélite igual en Open Street Maps?

14. El Lunes, 1 de Abril de 2019, 17:11 por josileudo

Hola, gran tutorial, sé pedir una ayuda. ¿Cómo puedo insertar una nueva marca sin necesidad de implementar dentro del sistema? Utilizando el mismo recurso de notas del mapa de calles abierto?

15. El Jueves, 10 de Octubre de 2019, 22:53 por Martin

Hola !
Implemente la guia pero sigue sin aparecer el mapa.
Le doy los permisos de escritura de forma manual y sigue sin funcionar.
No se si a alguien mas le paso?

Saludos

16. El Lunes, 22 de Febrero de 2021, 13:27 por Martin

Hola, que pasa si no se cuenta con almacenamiento externo. La app funcionará?
Hay alguna alternativa para que se guarde en almacenamiento interno?
Gracias.
Saludos.

17. El Miércoles, 14 de Abril de 2021, 19:26 por oso

para los que "NO LES APARECE EL MAPA" es la version #implementation 'org.osmdroid:osmdroid-android:6.1.0'#

Añadir un comentario

El código HTML se muestra como texto y las direcciones web se transforman automáticamente.

Discusiones sobre el mismo tema

URL de retroenlace : https://www.dosmweb.com/blog/index.php?trackback/15

Fuente de los comentarios de esta entrada