Mapas offline en Android con OpenStreetMap y la librería MapsForge

Mapas offline en Android con OpenStreetMap y la librería MapsForge

En este artículo vamos a ver cómo integrar mapas offline en nuestra aplicación gracias a OpenStreetMap y la librería MapsForge.

Los mapas offline nos permiten mostrar al usuario de nuestra aplicación un mapa con toda la información necesaria pero sin requerir conexión a internet, los mapas se almacenan en el teléfono.

La librería MapsForge es una librería libre y gratuita que integra los mapas de OpenStreetMap en Android, sus características principales son:

  • Formato de archivo ligero para renderizado rápido de datos OpenStreetMap en el dispositivo
  • De fácil uso, similar a la librería de Google Maps (v1)
  • API de capas potente y flexible
  • Estilos de mapas personalizables mediante ficheros de configuración XML
  • Librería de sólo 400KB de tamaño
  • 100% libre y gratuita

 

Eso es lo que nos ofrece MapsForge, además hace nada han publicado una actualización que facilita mucho las cosas, el problema es que cambia mucho respecto a la versión anterior, y, a día de hoy la documentación está sin actualizar, por lo que hay que mirar los ejemplos que publicaron para poder entender algo, sobre todo si es la primera vez que la utilizas. Ese es uno de los principales motivos que me han llevado a escribir este artículo, ya que me ha costado un mundo implementar la librería en mi aplicación.

Dicho esto, vamos a  ello.

Los pasos necesarios, en resumen, son:

  • Generar un fichero con el mapa de nuestra zona y convertirlo al formato utilizado por MapsForge
  • Integrar la librería en nuestro proyecto
  • Copiar los datos a la tarjeta SD del dispositivo, ya sea a mano o mediante código, aquí para reducir el tamaño del artículo lo haremos a mano
  • Implementar la lógica de la aplicación

De extra veremos cómo ejecutar una tarea al hacer click en un Marker

1.- Generar fichero con el mapa de nuestra zona

Lo primero que hay que hacer es generar el fichero ".map" con el mapa de la zona que incluiremos en nuestra aplicación, para ello vamos a esta página web: OpenStreetMap Data Extracts y seleccionamos el continente y país de la zona que incluiremos en nuestra aplicación. Para este ejemplo yo he entrado en "Europe->Spain" y he descargado el fichero con nombre "spain-latest.osm.pbf".

Una vez tenemos el fichero con extensión "pbf" necesitamos otra herramienta más llamada Osmosis que podemos descargar pinchando aquí.

Una vez descargado lo descomprimimos y accedemos a la carpeta desde una terminal en Linux o desde la consola de comandos en Windows. Para generar nuestro mapa tendríamos que ejecutar el siguiente comando:

osmosis --read-pbf file=spain-latest.osm.pbf --bounding-box left=COORDENADA_OESTE bottom=COORDENADA_SUR right=COORDENADA_ESTE top=COORDENADA_NORTE --write-xml coruna.osm

–read-pbf file: Requiere la ruta a nuestro fichero "pbf" descargado antes.

–write-xml: Nombre del fichero generado (respetar la extensión ".osm")

Dónde se nos piden 4 valores que no conocemos, que son las coordenadas que limitan nuestra zona, por tanto tendremos que conseguirlas. Para ello entramos aquí, navegamos por el mapa hasta la zona que incluiremos en nuestra aplicación y pinchamos en la opción de la izquierda que dice "Seleccionar manualmente un área diferente" lo que nos permitirá seleccionar la zona mostrando las coordenadas. Así que la seleccionamos y lo dejamos como está.

SeleccionZona

Ahora tenemos que pasar esas coordenadas a Osmosis. Según podemos ver en la imagen anterior las coordenadas están situadas por punto cardinal, por tanto la COORDENADA_OESTE está en la izquierda, la COORDENADA_NORTE está arriba y así. Por lo que el comando quedaría así:

osmosis --read-pbf file=spain-latest.osm.pbf --bounding-box left=-8.4481 bottom=43.3252 right=-8.3747 top=43.3911 --write-xml coruna.osm

El nombre del fichero resultante es "coruna.osm", podemos llamarlo como queramos pero respetando la extensión ".osm" para no tener problemas a posteriori.

Ya tenemos el mapa de nuestra zona generado en formato OpenStreetMap, pero como vimos en las características principales MapsForge usa un formato de archivo diferente que reduce el tamaño considerablemente, por lo que nos falta convertir el fichero ".osm" generado al formato ".map" de MapsForge para ello necesitamos un plugin que pondremos a Osmosis.

El plugin en cuestión se llama "Map Writer" y lo podéis descargar desde la página de MapsForge concretamente desde su sección de Descargas dónde dice "Writer Plugin" dentro de "Release 0.4.0 Downloads" (última versión).
 El fichero descargado lo tenemos que copiar en la carpeta "lib/default" de nuestro Osmosis (la ruta en la que lo hayamos descomprimido). Después tendremos que crear un fichero dentro de la carpeta "config" de Osmosis con nombre "osmosis-plugins.conf" que contenga la línea:

org.mapsforge.map.writer.osmosis.MapFileWriterPluginLoader

Con esto ya estamos preparados para convertir el mapa, así que ejecutamos:

osmosis --read-xml coruna.osm --mapfile-writer file=coruna.map

–read-xml: Solicita el nombre del fichero a convertir (generado antes)

–mapfile-writer file: Nombre del fichero destino (respetar extensión ".map")

Tras esto, ya tendremos preparado el fichero que contiene los mapas de la zona que mostraremos en el mapa de nuestra aplicación.

2.- Integrar la librería en nuestro proyecto (Eclipse)

Tras crear nuestro proyecto procederemos primero de todo a integrar la librería en él para poder utilizarla en nuestra aplicación. Para ello creamos un carpeta llamada "libs" en el proyecto si es que aun no existe y en él copiamos/importamos los siguientes ficheros que descargamos de aquí (versión 0.4.3):

  • mapsforge-core-0.4.3.jar
  • mapsforge-map-0.4.3.jar
  • mapsforge-map-android-0.4.3.jar
  • mapsforge-map-reader-0.4.3.jar
  • svg-android-0.4.3.jar

Después los seleccionamos todos y pulsando con el botón derecho abrimos el sub menú "Build Path" y presionamos "Add to Build Path". Ahora ya podemos empezar a desarrollar nuestra app, pero antes de ello vamos a copiar el mapa a su lugar correspondiente para tenerlo disponible en la aplicación.

Librerias Mapsforge

3.- Copiar los datos a la SD del dispositivo

Como dijimos al principio, copiaremos el mapa a mano al dispositivo, para reducir el tamaño del artículo pero lo ideal sería que la aplicación se encargase de copiarlo si no existe para no tener problemas si el usuario lo elimina o algo así.

Así que en la SD del dispositivo que vayas a utilizar la aplicación hay que crear una carpeta llamada "maps" y dentro copiamos el fichero "coruna.map" generado en el primer punto.

Vayamos con el código de nuestra aplicación

4.- Implementar la lógica de la aplicación

Lo primero que necesitamos es un contenedor para nuestro mapa, así que en nuestro "xml" escribimos lo siguiente:

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.offlinemapsforgesample.MainActivity" >
 
    <org.mapsforge.map.android.view.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
</RelativeLayout>

 

Algo tan sencillo como añadir un "MapView" que es la vista que mostrará el mapa.

La actividad resultante es la siguiente:

 

package com.example.offlinemapsforgesample;
 
import java.io.File;
 
import org.mapsforge.core.model.LatLong;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.android.util.AndroidUtil;
import org.mapsforge.map.android.view.MapView;
import org.mapsforge.map.layer.cache.TileCache;
import org.mapsforge.map.layer.renderer.TileRendererLayer;
import org.mapsforge.map.rendertheme.InternalRenderTheme;
 
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
 
public class MainActivity extends ActionBarActivity {
 
	private MapView mapView;
	private TileCache tileCache;
	private TileRendererLayer tileRendererLayer;
 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		AndroidGraphicFactory.createInstance(getApplication());
		setContentView(R.layout.activity_main);
 
		mapView = (MapView)findViewById(R.id.mapView);
		mapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
 
		mapView.setClickable(true);
 
		// create a tile cache of suitable size
		tileCache = AndroidUtil.createTileCache(this, "mapcache",
				mapView.getModel().displayModel.getTileSize(), 1f, 
				mapView.getModel().frameBufferModel.getOverdrawFactor());
 
		mapView.getModel().mapViewPosition.setZoomLevel((byte) 15);
		mapView.getMapZoomControls().setZoomLevelMin((byte)14);
		mapView.getMapZoomControls().setZoomLevelMax((byte)20);
 
		String filepath = Environment.getExternalStorageDirectory().getPath() + "/maps/coruna.map";
		// tile renderer layer using internal render theme
		tileRendererLayer = new TileRendererLayer(tileCache,
				mapView.getModel().mapViewPosition, false, AndroidGraphicFactory.INSTANCE);
		tileRendererLayer.setMapFile(new File(filepath));
		tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.OSMARENDER);
 
		// only once a layer is associated with a mapView the rendering starts
		mapView.getLayerManager().getLayers().add(tileRendererLayer);
 
		//mapView.setClickable(true);
		mapView.setBuiltInZoomControls(true);
		mapView.getMapScaleBar().setVisible(false);
 
		mapView.getModel().mapViewPosition.setCenter(new LatLong(43.385833, -8.406389));
 
		MyMarker marker = new MyMarker(this, new LatLong(43.385833, -8.406389), AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.ic_launcher)), 0, 0);
		mapView.getLayerManager().getLayers().add(marker);	
	}
 
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
 
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

En ella podemos contemplar varias cosas importantes:

  • AndroidGraphicFactory.createInstance(getApplication());

Se encarga de recopilar información de nuestro dispositivo necesaria para mostrar el mapa, tiene que estar antes del "setContentView" y tiene que estar siempre presente, en caso contrario la aplicación se cierra con un error.

Después se inicializa la vista del mapa para poder usarla, como es habitual en Android y se le asigna el tipo de layer.

Le decimos que el mapa es "pulsable" para poder movernos por él y hacer zoom, sino sería un mapa estático.

  • mapView.setClickable(true);

Después de esto se crea un "Tile caché" que se encarga de cachear los "tiles" (porciones de mapa) que se van mostrando para no tener que andar cargándolas siempre desde cero y se indica el zoom por defecto y los niveles mínimo y máximo de oom. Luego se crea un "Tile renderer layer" encargado de dibujar los "tiles" al que se le indica el "Tile Caché" que utilizará y la ruta al mapa además del tipo de "renderer".

  • mapView.getLayerManager().getLayers().add(tileRendererLayer);

Esto añade la "capa" creada al mapa y por último se le indica que muestre los controles de zoom predefinidos y que oculte la barra de escala que mostraría la distancia de una proporción de mapa de forma visual, para al final centrar el mapa en una posición concreta.

Para que esto funcione tenemos que añadir a nuestro fichero Manifest el permiso:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

AndroidManifest.xml

Ya que en la tarjeta SD se almacena el caché del mapa, y es necesario poder escribir en ella.

Con esto ya tenemos nuestra aplicación funcionando y el mapa perfectamente usable.

Por último veremos como implementar el click en un "Marker" para que se puedan abrir nuevas ventanas o mostrar información relativa a un punto concreto tras pulsar en él.

EXTRA.- Ejecutar tarea al hacer click en un Marker

Algo que no sabía como hacer con esta librería y que me parece vital es cómo ejecutar algo al hacer click en un Marker para mostrar la información de ese punto o abrir una ventana nueva, por lo que vamos a ver cómo hacerlo.

Para implementar el click, tenemos que heredar el objeto "Marker" de MapsForge y realizar nuestra tarea dentro del método "onTap", así que para ello creamos una nueva clase dentro del proyecto (llamada "MyMarker" en el ejemplo) que contenga lo siguiente:

 

package com.example.offlinemapsforgesample;
 
import org.mapsforge.core.graphics.Bitmap;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.Point;
import org.mapsforge.map.layer.overlay.Marker;
 
import android.content.Context;
import android.widget.Toast;
 
public class MyMarker extends Marker{
	private Context ctx;
 
	public MyMarker(Context ctx, LatLong latLong, Bitmap bitmap, int horizontalOffset,
			int verticalOffset) {
		super(latLong, bitmap, horizontalOffset, verticalOffset);
		this.ctx = ctx;
	}
 
	@Override
	public boolean onTap(LatLong tapLatLong, Point layerXY, Point tapXY) {
		if (this.contains(layerXY, tapXY)) {
			Toast.makeText(ctx, "Marker con latitud: " + tapLatLong.latitude + " y longitud: " + tapLatLong.longitude + " pulsado", Toast.LENGTH_SHORT).show();
		return true;
	}
		return super.onTap(tapLatLong, layerXY, tapXY);
	}
 
}

 

Y en la actividad principal añadimos estas dos líneas:

 

MyMarker marker = new MyMarker(this, new LatLong(43.385833, -8.406389), AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.ic_launcher)), 0, 0);
mapView.getLayerManager().getLayers().add(marker);

 

Que se encargan de crear el Marker personalizado y añadirlo al mapa.

Y eso es todo por hoy, espero que con esta mini guía os sea más fácil integrar las funcionalidades de MapsForge en vuestra aplicación para poder mostrar mapas sin necesidad de conexión a internet.

Recursos:

Este es el resultado final:

Resultado final

Relacionado:

By | 2016-09-10T17:11:10+00:00 agosto 11th, 2014|Android, Desarrollo, Informática, Móvil|31 Comments

About the Author:

Desarrollador de software de profesión, apasionado de la informática y todo lo relacionado con la tecnología

31 Comments

  1. Amaia septiembre 15, 2014 at 9:05 am - Reply

    Hola! muy buen tutorial. Gracias por hacerlo, no se encuentra nada tan detallado por ahí.

    Una pregunta. Es necesario que el mapa este en la SD del dispositivo? o se puede guardar en la memoria interna, lo digo por ejemplo con telefonos móviles que no tengan tarjeta SD.

    Gracias!

    • dolphin septiembre 15, 2014 at 1:37 pm - Reply

      Hola Amaia, me alegro que te haya sido de utilidad. Se puede guardar en la memoria interna, el problema es que hay dispositivos que tienen una memoria interna muy limitada, sobre todo los antiguos, y como el mapa ocupe mucho puede que luego el usuario no pueda instalar más aplicaciones, recibir mensajes y esas cosas.

      Saludos.

  2. Amaia septiembre 15, 2014 at 9:36 am - Reply

    Hola de nuevo. Cuando ejecuto la aplicación me sale un mensaje de error que dice que tengo que guardar el coruna.map en la ruta /storage/sdcard0/maps/coruna.map

    El archivo coruna.map lo he guardado en la tarjeta sd, en una carpeta llamada maps. No es el sitio correcto?

    Un saludo!

  3. Amaia septiembre 15, 2014 at 9:49 am - Reply

    Ah vale! error mio! jaja he puesto la carpeta en la memoria interna del telefono, en la raiz y ha funcionado perfecto. 

    Gracias por el tutorial, muy bueno, me ha servido de gran ayuda

    • dolphin septiembre 15, 2014 at 1:38 pm - Reply

      Hola de nuevo, me alegro de que lo hayas arreglado, cualquier cosa por aquí estamos.

      Saludos

  4. Gabriel Alberione septiembre 18, 2014 at 6:01 pm - Reply

    Buenas Tardes, 

    Primero que nada muchas gracias por el tutorial, tal como comentan arriba, hay poca info dando vuelta tan detallada.

    Te consulto algo a ver si me podes dar una mano:

    Necesito que el .map sea inaccesible para el usuario final, es decir, ni siquiera el root pueda abrirlo. te comento la situacion. Voy a generar un .map a partir de unos mapas bases que no son libres, entonces la idea es que no se robe la informacion. Tenes alguna idea como lo puedo hacer?

    Muchas Gracias.

    Saludos

    • dolphin septiembre 18, 2014 at 7:46 pm - Reply

      Pues la verdad que no se me ocurre ninguna forma, me imagino que la habrá quizá cifrando los ficheros del mapa o algo así, pero la verdad que no sabría decirte cómo hacerlo. Espero encuentres la forma y si te apetece nos comentes a todos cómo has hecho.

      Gracias por comentar.

      Saludos

      • Gabriel Alberione septiembre 19, 2014 at 11:23 am - Reply

        gracias dophin por la respuesta, lo de ocultar el archivo segun estuve investigando es imposible, por que la aplicacion no puede ser mas root que el root, je. En cuanto al cifrado, tambien lo pense, poner las coordenadas en cualquier lado y despues mediante un proceso interno acomodarlas. 

        Otra alternativa que pense es encriptar el archivo, pero creo que cuando este en uso en algun lado va  a existir temporalmente.

        Cuando encuentre la solucion la comento, je!. 

        Muchas Gracias por el Aporte!

  5. Edwin Cepeda octubre 14, 2014 at 12:41 am - Reply

    Hola… excelente tutorial pero me queda la duda de como puedo agregar un Circle y Polyline en el mapa?

    • dolphin octubre 18, 2014 at 8:57 pm - Reply

      Hola Edwin, ¿a qué te refieres con un Circle y un Polyline? Ambos son clases de Android por tanto no deberías poder crearlos, además si no me equivoco también la librería Mapsforge tiene ambas clases.

      Si a lo que te refieres con Polyline es a añadir rutas en el mapa para eso necesitas otra librería diferente, yo para un proyecto he utilizado la librería GraphHopper que permite rutas offline, ya que MapsForge no tiene creación de rutas por sí misma.

      Cualquier cosa me cuentas.

      Saludos

      • Edwin Cepeda noviembre 20, 2014 at 12:46 pm - Reply

        Gracias por la respuesta me sirvio muchismo, pero tengo otra duda alguna vez han logrado rotar el mapa? Gracias de nuevo!

        • dolphin noviembre 20, 2014 at 12:50 pm - Reply

          Hola de nuevo Edwin, me alegro de que te haya servido. La verdad es que no he probado a implementar rotación en el mapa, creo que la librería por ahora no lo permite pero sí que tienen pensado añadirlo.

          En este enlace hablan de ello, e incluso algunos comentan que lo han logrado imitando cómo lo hace Google con sus mapas, puedes mirar ahí que igual te sirve.

          Cualquier cosa por aquí estamos.

          Saludos

  6. WIlfredo noviembre 10, 2014 at 8:45 pm - Reply

    Amigo he intentado correr la aplicaciòn en el emulador y me bota la pantalla negra en vez de salir el mapa. Y la otra es que cuando lo exporto para obtener el apk y lo instalo(justo aquí) me aparece un mensaje diciendo que ha habido un problema al iniciar el apk.

    Lo corro con sdk 4.0 y las librerias mapsforge 4.03 y las otras que son adiicionales.

    Ayuda por favor.

    • dolphin noviembre 19, 2014 at 11:51 pm - Reply

      Hola Wilfredo, para que funcione tienes que incluir el mapa adjunto en la ruta indicada. Si te da un error de “Forzar cierre” al correr la app, envíame el log generado para poder ayudarte.

  7. Jorge Riffarachy diciembre 3, 2014 at 10:05 pm - Reply

    Hola amigo, disculpa en una anterior ocasion he usado la libreria misma pero una version anterior, la mapsforge-map-0.3.0-jar-with-depencies.jar   y en esta nueva version  mapsforge-map-0.4.3.jar ya no puedo dibujar lineas desde un punto a otro porque ya no me reconoce algunas clases de la anterior version como ser:  ArrayWayOverlay , OverlayWay.

    O de que manera ahora se dibuja lineas y circulos en esta version.

    Espero tu ayuda. gracias

    • Acc krt enero 17, 2015 at 6:30 pm - Reply

      Hola Jorge, no se si has solucionado el tema de dibujar lineas en el mapa, si lo has hecho te agradeceria que me indicases como ya que no consigo hacerlo.

       

      gracias por todo.

  8. Pablo diciembre 10, 2014 at 4:58 am - Reply

    Hola, tengo un par de preguntas.

    1. ¿que formatos soporta para los mapas?¿solo .map (ojala no) ?

    2. ¿se pueden cargar mapas de forma online?

    quiero cargar unas capas que tengo y poder mostrarlas en el map (obvio), pero no quiero que se almacenen en el telefono,  y en caso del formato…  como puedo transformar mis capas a formato .map.

    Por ultimo abra otra libreria o api con la que pueda mostrar mis capas…

    PDA: toda info y tuto se agradece

  9. yordan mayo 27, 2015 at 6:58 pm - Reply

    Hola, excelente artículo, sin embargo he estado tratando de generar mi propio mapa desde la consola de windows , con el osmosis- 0.40 y cuando hago el primer paso para generar el .osm me dice:  Exception in thread  "main"  java.lang.NoClassDefFoundError: org/codehaus/classworlds/Launcher

    estoy tratando de recortar el mapa cuba-latest.osm.pbf

  10. Gabriel junio 10, 2015 at 8:34 pm - Reply

    Mi problema es que cuando istalo Osmosis me dice que:

    No se puede encontrar la clase principal org.codehaus.classworlds.launcher

    He intentado especificando el Path de Java pero ni asi funciona.
     

  11. miguel octubre 8, 2015 at 3:15 pm - Reply

    a mi me funciona de maravilla , pero cuando creo mi propio mapa con la guia y remplazo en la aplicacion no me funciona solo se ve blanco todo jeje gracias por su respuesta.

    • dolphin noviembre 8, 2015 at 5:54 pm - Reply

      Hola Miguel, ¿has verificado que las coordenadas iintroducidas son las correctas? A mi me pasó eso también al principio y era que las coordenadas GPS apuntaban a un sitio dónde no había mapa generado. Espero puedas resolverlo.

      Saludos

  12. Fred noviembre 29, 2016 at 4:57 am - Reply

    Hola, muchas gracias por tu excelente tutorial, solo que tengo un pequeño problema al final, me aparece un error que dice:
    “cannot read file: ” (y la ubicación del archivo).

    No consigo ver el mapa, ya lo probé cambiando la dirección y aun asi no puedo verlo.

    Además en el activity.xml me aparecen varios errores:

    The following classes could not be instantiated:
    – org.mapsforge.map.android.view.MapView (Open Class, Show Error Log)
    See the Error Log (Window > Show View) for more details.
    Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse

    java.lang.NullPointerException
    at org.mapsforge.map.view.FpsCounter.createPaint(FpsCounter.java:33)
    at org.mapsforge.map.view.FpsCounter.(FpsCounter.java:47)
    at org.mapsforge.map.android.view.MapView.(MapView.java:70)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0( at sun.reflect.NativeConstructorAccessorImpl.newInstance( at sun.reflect.DelegatingConstructorAccessorImpl.newInstance( at java.lang.reflect.Constructor.newInstance( at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:444)
    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:196)
    at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:206)
    at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:131)
    at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:756)
    at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:728)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:373)

    espero aún sigas al pendiente del tema y puedas ayudarme, muchas gracias.

    Saludos!

    • Alberto Méndez noviembre 29, 2016 at 9:59 pm - Reply

      Hola Fred, necesitaría saber qué versión de la librería estás utilizando ya que me imagino que desde que escribí el artículo hasta ahora habrán cambiado muchas cosas. Primero y antes de nada déjame recomendarte echarle un vistazo la aplicación de ejemplo que tienen en GitHub los creadores de la librería: https://github.com/mapsforge/mapsforge/tree/master/mapsforge-samples-android

      Yo trataría de entender cómo lo hacen para poder implementar en la aplicación, incluso puedes descargarla y compilarla por ti mismo si quieres.

      Hace mucho que no toco el tema ya que no lo he necesitado más pero viendo tus errores suena a que no es capaz de reconocer la librería, supongo que la habrás añadido al build.gradle de tu aplicación con las sentencias:

      • compile ‘org.mapsforge:mapsforge-map-android:[CURRENT-VERSION]’
      • compile ‘com.caverock:androidsvg:1.2.2-beta-1’

      Una vez hecho eso debería desaparecer por lo menos el error del xml. El NullPointerException creo que es por el mismo problema, verifica que la has añadido correctamente y échale un vistazo al ejemplo que te enlazo. Espero haberte ayudado, cualquier cosa me cuentas.

      Saludos

      • Fred noviembre 30, 2016 at 5:14 am - Reply

        Muchas gracias por tu respuesta, le dedicaré un par de semanas para tratar de entender la aplicación de ejemplo.

        Saludos!

  13. Royer abril 18, 2017 at 7:52 pm - Reply

    Muy buena tu ayuda me lo puedes pasar el codigo a mi correo XXXXXX@gmail.com

    • Alberto Méndez abril 18, 2017 at 7:55 pm - Reply

      Hola Royer, pues sinceramente hace tanto tiempo que lo hice que no sé si lo tendré por algún sitio, trataré de buscarlo en estos días y si lo tengo te lo envío.
      Saludos

  14. Royer abril 25, 2017 at 4:46 am - Reply

    hola no podias hacerlo de lo nuevo en android y si puedes tambien para generar camino en los mapas por no piyo en ningun eso

    • Alberto Méndez mayo 2, 2017 at 10:15 pm - Reply

      Hola de nuevo Royer, me temo que no voy a tener tiempo para hacerlo de nuevo y tengo muchos artículos pendientes de publicar así que lo veo muy complicado, lo siento!! Saludos

  15. Mario Córdova mayo 6, 2017 at 5:07 am - Reply

    Genial, gracias por el tutorial, lo probaré en mi proyecto de la universidad. Saludos.

  16. Mario Córdova mayo 6, 2017 at 6:42 pm - Reply

    Disculpá ¿cómo hago para este paso?:
    “El plugin en cuestión se llama “Map Writer” y lo podéis descargar desde la página de MapsForge concretamente desde su sección de Descargas dónde dice “Writer Plugin” dentro de “Release 0.4.0 Downloads” (última versión).”

  17. Mario Córdova mayo 6, 2017 at 7:28 pm - Reply

    Como lo soluciono. Me sale este error:

    mariocordova@marioPC:~/Descargas/osmosis-latest$ osmosis –read-xml santacruz.osm –mapfile-writer file=santacruz.map
    may 06, 2017 1:21:41 PM org.openstreetmap.osmosis.core.Osmosis run
    INFORMACIÓN: Osmosis Version 0.44.1
    may 06, 2017 1:21:41 PM org.openstreetmap.osmosis.core.Osmosis run
    INFORMACIÓN: Preparing pipeline.
    may 06, 2017 1:21:41 PM org.openstreetmap.osmosis.core.Osmosis main
    GRAVE: Execution aborted.
    org.openstreetmap.osmosis.core.OsmosisRuntimeException: Task type mapfile-writer doesn’t exist.
    at org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactoryRegister.getInstance(TaskManagerFactoryRegister.java:60)
    at org.openstreetmap.osmosis.core.pipeline.common.Pipeline.buildTasks(Pipeline.java:50)
    at org.openstreetmap.osmosis.core.pipeline.common.Pipeline.prepare(Pipeline.java:112)
    at org.openstreetmap.osmosis.core.Osmosis.run(Osmosis.java:86)
    at org.openstreetmap.osmosis.core.Osmosis.main(Osmosis.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchStandard(Launcher.java:328)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:238)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:408)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:351)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:31)

    Copié
    mapsforge-map-writer-0.4.0.jar
    en
    /home/mariocordova/Descargas/osmosis-latest/lib/default

Leave A Comment