Solution pour l'application de carte Android avec utilisation hors ligne?

14

Je suis à la recherche d'un moyen de développer une application pour Android avec des cartes intégrées pouvant fonctionner sans connexion Internet (c'est-à-dire puis-je obtenir les tuiles du plan de ville ouvert pour une utilisation hors ligne?).

J'ai déjà développé des applications Web en utilisant l'API Google Maps v3. J'ai besoin d'une réponse générale en tant que réponse spécifique. J'essaie de trouver les concepts et les technologies dont j'ai besoin pour apprendre :)

(Pendant ce temps, j'ai trouvé osmdroid. Est-ce que cela fonctionne hors ligne?)

Argiropoulos Stavros
la source
Cela ne répond pas vraiment à la question. Si vous avez une autre question, vous pouvez la poser en cliquant sur Poser une question . Vous pouvez également ajouter une prime pour attirer davantage l'attention sur cette question une fois que vous avez suffisamment de réputation .
Jason Scheirer
Osmand ne permet pas d'importer des cartes personnalisées à la demande de l'utilisateur, mais il permet uniquement de télécharger des cartes directement depuis l'application pour une utilisation hors ligne. Comme dans mon cas, j'ai besoin de superposer des feuilles de calcul (cartes raster) qui ont été converties en * .kmz. Mon exigence est pour une utilisation hors ligne. Je recherche des conseils appropriés pour développer une telle application Android de support de carte hors ligne.
surap le
Cela ne répond pas vraiment à la question initiale de savoir où et comment obtenir des cartes pour une utilisation hors ligne.
MaryBeth
Cela ne répond pas vraiment à la question. Si vous avez une autre question, vous pouvez la poser en cliquant sur Poser une question . Vous pouvez également ajouter une prime pour attirer davantage l'attention sur cette question une fois que vous avez suffisamment de réputation . - De l'avis
John Powell

Réponses:

13

J'ai créé une carte hors ligne à l'aide du SDK Android ESRI et d'une couche de tuiles personnalisée. J'ai utilisé un serveur ArcGIS pour générer un cache de carte basé sur des tuiles, puis j'ai inséré ces tuiles dans une base de données SQLite et les ai interrogées en fonction de la ligne et de la colonne à partir de là. Cela fonctionne très bien et si vous avez besoin de cartes personnalisées de bout en bout, c'est une méthode très utilisable.

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
la source
Pouvez-vous s'il vous plaît partager du code?
gregm
J'ai ajouté ma classe de calques personnalisée qui fait le travail.
eptiliom
7

J'ai développé une application avec des cartes hors ligne pour Android. Le seul outil gratuit que vous voudriez utiliser est OSMDroid, sinon ESRI. L'API OSMDroid est identique à celle de Google, donc si vous voulez passer de l'un à l'autre, c'est un jeu d'enfant.

Consultez cet article , avec un exemple de la façon d'intégrer Google Maps dans OSMDroid (il vous donne également une idée de la façon de l'utiliser en général).

Elijah Saounkine
la source
2

Il existe une excellente application appelée xGPS pour iPhone et autres appareils. Vous voudrez peut-être examiner cela pour obtenir des idées, car cela permet aux utilisateurs de mettre en cache les cartes dont ils auront besoin. Je l'utilise quand je suis au fond de la brousse en Afrique, dans les Everglades en Floride, en bateau ou partout où je n'ai pas de couverture de téléphone portable. Je mettrai en cache les cartes avant mon voyage et puis pourra utiliser le GPS sur mon iphone normalement sans Internet.

Fondamentalement, ce qu'ils font xGPS et ce que vous voudriez faire, c'est mettre en cache les tuiles de carte localement sur votre téléphone. L'espace sur ces téléphones mobiles est limité. Oui, même si vous avez 32 Go sur votre téléphone, cela pourrait suffire pour mettre en cache un petit pays à tous les niveaux de zoom (échelles). Aucun de ces téléphones (sauf s'ils sont attachés d'une manière ou d'une autre à un stockage externe) n'aura suffisamment d'espace pour mettre le monde en cache à tous les niveaux de zoom. J'imagine que cela nécessiterait des pétaoctets de stockage.

Vous devez donc pouvoir demander à votre utilisateur de mettre en cache les "régions" ou les cartes lorsqu'il est en ligne afin qu'il puisse les utiliser hors ligne. Avec xGPS, je peux dessiner un polygone sur ma région d'intérêt et spécifier les niveaux de zoom que je veux mettre en cache. Ensuite, il commencera à tout télécharger pour moi sur mon téléphone, à partir du téléphone lui-même ou d'un programme sur mon ordinateur. Ensuite, il y a un bouton sur l'application qui me permet de passer en mode "hors ligne" lorsque je perds la connectivité Internet.

CaptDragon
la source
2

Essayez d'utiliser NextGIS Mobile SDK. Le mode en ligne / hors ligne inclut l'édition et la synchronisation automatique avec le serveur (NextGIS Web). Couches raster et vectorielles, formulaires d'entrée personnalisés, prise en charge de tous les types de géométrie.

Un exemple d'application NextGIS Mobile peut être trouvé dans Google Play Store - https://play.google.com/store/apps/details?id=com.nextgis.mobile

Les sources sont ici: https://github.com/nextgis/android_gisapp

Documentation: http://docs.nextgis.com/docs_ngmobile/source/toc.html

Une autre application simple est ici: https://github.com/nextgis/android_muni_gisconf

Documentation du SDK: http://docs.nextgis.com/ngmobile_dev/toc.html

Dmitry Baryshnikov
la source
1

Les cartes hors ligne sont entièrement prises en charge avec la version actuelle du SDK ArcGIS Android. Cet exemple vous montrera comment travailler avec un paquetage de tuiles local en tant que fond de carte et conserver les fonctionnalités en ligne sur les fonctionnalités hors ligne à partir desquelles vous pouvez modifier. J'ai également un aperçu disponible sur github pour une référence simplifiée.

jdONeill
la source
1

Je suggère de jeter un œil au SDK de cartes 3D Nutiteq qui a des capacités hors ligne et des extras intéressants comme le support 3D. Il est fabriqué par une société de développement spécialisée derrière lui, il dispose donc d'un support commercial dédié et d'une plus grande flexibilité que les grands fournisseurs. Avertissement: j'en suis le développeur.

JaakL
la source