¿Solución para la aplicación de mapas de Android con uso sin conexión?

14

Estoy buscando una manera de desarrollar una aplicación para Android con mapas integrados que pueda funcionar sin conexión a Internet (es decir, ¿puedo obtener los mosaicos del mapa abierto para usar sin conexión?).

He desarrollado aplicaciones web antes usando la API de Google Maps v3. Necesito una respuesta general como específica. Estoy tratando de encontrar los conceptos y tecnologías que necesito aprender :)

(Mientras tanto, encontré osmdroid. ¿Funciona sin conexión?)

Argiropoulos Stavros
fuente
Esto realmente no responde la pregunta. Si tiene una pregunta diferente, puede hacerla haciendo clic en Hacer pregunta . También puede agregar una recompensa para llamar más la atención sobre esta pregunta una vez que tenga suficiente reputación .
Jason Scheirer
Osmand no permite importar mapas personalizados a voluntad del usuario, pero solo permite descargar mapas directamente desde la aplicación para su uso sin conexión. Como en mi caso, necesito superponer hojas de cálculo (mapas ráster) que se convirtieron en * .kmz. Mi requisito es para uso sin conexión. Estoy buscando una guía adecuada para desarrollar dicha aplicación de Android compatible con mapas sin conexión.
surap
Esto realmente no responde a la pregunta original de dónde y cómo obtener mapas para su uso sin conexión.
MaryBeth
Esto realmente no responde la pregunta. Si tiene una pregunta diferente, puede hacerla haciendo clic en Hacer pregunta . También puede agregar una recompensa para llamar más la atención sobre esta pregunta una vez que tenga suficiente reputación . - De la opinión
John Powell

Respuestas:

13

Hice un mapa sin conexión con el SDK de Android de ESRI y una capa de mosaico personalizada. Utilicé un servidor ArcGIS para generar un caché de mapa basado en mosaicos, luego inserté esos mosaicos en una base de datos SQLite y los consulté en base a filas y columnas desde allí. Funciona muy bien y si necesita mapas personalizados de extremo a extremo, es un método muy útil.

package com.main.utilinspect;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;

import android.content.Context;
import android.util.Log;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.esri.core.internal.c.d;
import com.esri.core.internal.c.h;
import com.esri.core.internal.c.l;

import com.esri.android.map.TiledServiceLayer;

public class OfflineDbTiledLayer extends TiledServiceLayer {

File workingDirectory;
String mapDefinition;
String databaseName;
private SQLiteDatabase database;
File blankImage;

byte[] blankImageBytes;

private final Object lock = new Object();


private static final String TAG = "OfflineTiledLayer";  


public OfflineDbTiledLayer(Context paramContext, File workingDirectory, String mapDefinition, String databaseName)  {
    super("required");
    this.workingDirectory = workingDirectory;
    this.mapDefinition = mapDefinition;
    this.databaseName = databaseName;

    String databasePath = workingDirectory.getAbsolutePath() + File.separator + databaseName;

    this.database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 

    this.blankImage = new File(workingDirectory.getAbsolutePath() + File.separator + "blank.png");

    RandomAccessFile raFile = null;

    try {
        raFile = new RandomAccessFile(this.blankImage, "r");

        blankImageBytes = new byte[(int) raFile.length()];
        raFile.readFully(blankImageBytes);

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
    finally {
        if(raFile != null) {
            try {
                raFile.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }   

    h h1 = null;

    try
    {

    JsonParser paramJsonParser = new JsonFactory()
    .createJsonParser(new File(workingDirectory.getAbsolutePath() + File.separator + mapDefinition));
    paramJsonParser.nextToken();    

    h1 = h.a(paramJsonParser, "test");
    }
    catch(Exception ex){

    }       


    setFullExtent(h1.f());      
    setDefaultSpatialReference(h1.c());
    setInitialExtent(h1.e());

    l l1;
    List list;
    int i;
    double ad[] = new double[i = (list = (l1 = h1.d()).h).size()];
    double ad1[] = new double[i];
    for(int j = 0; j < list.size(); j++)
    {
        ad[j] = ((d)list.get(j)).b();
        ad1[j] = ((d)list.get(j)).a();
    }

    setTileInfo(new com.esri.android.map.TiledServiceLayer.TileInfo(l1.f, ad, ad1, i, l1.c, l1.b, l1.a));

    super.initLayer();
    return;     
}   

private void openDatabase(){
    if(!database.isOpen()){
        String databasePath = workingDirectory.getAbsolutePath() + File.separator + databaseName;
        this.database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
    }
}

private void closeDatabase(){
    if(database.isOpen()){
        this.database.close();
    }
}

@Override
protected byte[] getTile(int level, int column, int row) throws Exception {
    byte[] tileImage;       

    Log.i(TAG, "getTile");

    Log.i(TAG, "getTile - retrieving tile");            

    synchronized(lock) {

        Log.i(TAG, "getTile - entered synchronized block");

        openDatabase();     

        // First check to see if the tile exists in the database
        Cursor tileCursor = database.rawQuery("SELECT image FROM tiles WHERE level = " + Integer.toString(level) + " AND row = " + Integer.toString(row) + " AND column = " + Integer.toString(column), null);

        if(tileCursor != null && tileCursor.getCount() > 0) {
            tileCursor.moveToFirst();
            tileImage = tileCursor.getBlob(0);
            Log.i(TAG, "getTile - tile found, returning image");                        
        }
        else {
            // The tile does not exist in the database, read the blank placeholder tile and serve it
            tileImage = blankImageBytes;
            Log.i(TAG, "getTile - tile not found returning blank");
        }   

        tileCursor.close();     
        this.database.close();
    }

    Log.i(TAG, "getTile - exited synchronized block");

    return tileImage;   
}

}

eptiliom
fuente
¿Puedes por favor compartir un código?
gregm
Agregué mi clase de capa personalizada que hace el trabajo.
eptiliom
7

He desarrollado una aplicación con mapas sin conexión para Android. La única herramienta gratuita que desearía utilizar es OSMDroid, de lo contrario, ESRI. La API de OSMDroid es idéntica a la de Google, por lo que en caso de que desee cambiar de una a otra, es muy fácil.

Echa un vistazo a esta publicación , con una muestra de cómo integrar Google Maps en OSMDroid (también te da una idea de cómo usarlo en general).

Elijah Saounkine
fuente
2

Hay una gran aplicación llamada xGPS para iPhone y otros dispositivos. Es posible que desee ver eso para obtener ideas porque permite a los usuarios almacenar previamente en caché los mapas que necesitarán. Lo uso cuando estoy en lo más profundo de África, Florida Everglades, paseos en bote o en cualquier lugar donde no tenga cobertura de teléfono celular. Guardaré en caché los mapas antes de mi viaje y luego podré usar el GPS en mi iphone normalmente SIN INTERNET.

Básicamente, lo que hacen xGPS y lo que desea hacer es almacenar en caché los mosaicos del mapa localmente en su teléfono. El espacio en estos teléfonos móviles es limitado. Sí, incluso si tiene 32 gb en su teléfono, podría ser suficiente para almacenar en caché un país pequeño en todos los niveles de zoom (escalas). Ninguno de estos teléfonos (a menos que de alguna manera esté conectado al almacenamiento externo) tendrá suficiente espacio para almacenar en caché el mundo en todos los niveles de zoom. Me imagino que esto requeriría petabytes de almacenamiento.

Por lo tanto, debe poder pedirle a su usuario que guarde en caché las "regiones" o los mapas cuando esté en línea para que pueda usarlos sin conexión. Con xGPS, puedo dibujar un polígono sobre mi región de interés y especificar qué niveles de zoom quiero almacenar en caché. Luego comenzará a descargarlo todo para mí en mi teléfono, ya sea desde el teléfono mismo o desde un programa en mi computadora. Luego hay un botón en la aplicación que me permite cambiar al modo "fuera de línea" cuando pierdo la conectividad a Internet.

CaptDragon
fuente
2

Intente usar NextGIS Mobile SDK. El modo en línea / fuera de línea incluye edición y sincronización automática con el servidor (NextGIS Web). Capas ráster y vectoriales, formularios de entrada personalizados, todo tipo de soporte de geometría.

Puede encontrar una aplicación de ejemplo NextGIS Mobile en la tienda de Google Play: https://play.google.com/store/apps/details?id=com.nextgis.mobile

Las fuentes están aquí: https://github.com/nextgis/android_gisapp

Documentación: http://docs.nextgis.com/docs_ngmobile/source/toc.html

Otra aplicación simple está aquí: https://github.com/nextgis/android_muni_gisconf

Documentación del SDK: http://docs.nextgis.com/ngmobile_dev/toc.html

Dmitry Baryshnikov
fuente
1

Existe un soporte completo para mapas fuera de línea con la versión actual de ArcGIS Android SDK. Este ejemplo le mostrará cómo trabajar con un paquete de mosaico local como un mapa base y persistirá las características en línea en características fuera de línea desde las cuales puede editar. Tengo una esencia disponible en github también para una referencia simplificada.

jdONeill
fuente
1

Sugiero echar un vistazo al SDK de mapas 3D de Nutiteq que tiene capacidades fuera de línea y extras interesantes como soporte 3D. Está hecho por una compañía de desarrolladores especializados que lo respalda, por lo que tiene un soporte comercial dedicado y más flexibilidad que la que ofrecen los grandes proveedores. Descargo de responsabilidad: soy desarrollador de él.

JaakL
fuente