Lösung für Android Map App mit Offline-Nutzung?

14

Ich bin auf der Suche nach einer Möglichkeit, eine App für Android mit eingebetteten Karten zu entwickeln, die ohne Internetverbindung funktioniert (dh kann ich die Kacheln der offenen Straßenkarte für die Offline-Verwendung erhalten?).

Ich habe zuvor Web-Apps mit der Google Maps API v3 entwickelt. Ich brauche eine allgemeine Antwort als eine spezifische. Ich versuche, die Konzepte und Technologien zu finden, die ich lernen muss :)

(Inzwischen habe ich osmdroid gefunden . Funktioniert es offline?)

Argiropoulos Stavros
quelle
Dies beantwortet die Frage nicht wirklich. Wenn Sie eine andere Frage haben, können Sie sie stellen, indem Sie auf Frage stellen klicken . Sie können auch ein Kopfgeld hinzufügen, um mehr Aufmerksamkeit auf diese Frage zu lenken, sobald Sie über einen ausreichenden Ruf verfügen .
Jason Scheirer
Osmand erlaubt es nicht, benutzerdefinierte Karten auf Benutzerwunsch zu importieren, aber es erlaubt nur, Karten direkt von der App für die Offline-Verwendung herunterzuladen. Wie in meinem Fall muss ich Toposheets (Rasterkarten) überlagern, die in * .kmz konvertiert wurden. Meine Anforderung ist für die Offline-Nutzung. Ich bin auf der Suche nach einer geeigneten Anleitung, um eine solche Offline-Kartenunterstützung für Android-Anwendungen zu entwickeln.
4.
Dies beantwortet nicht wirklich die ursprüngliche Frage, wo und wie Karten für die Offline-Verwendung erhältlich sind.
MaryBeth
Dies beantwortet die Frage nicht wirklich. Wenn Sie eine andere Frage haben, können Sie sie stellen, indem Sie auf Frage stellen klicken . Sie können auch ein Kopfgeld hinzufügen, um mehr Aufmerksamkeit auf diese Frage zu lenken, sobald Sie über einen ausreichenden Ruf verfügen . - Aus der Bewertung
John Powell

Antworten:

13

Ich habe eine Offline-Karte mit dem ESRI Android SDK und einer benutzerdefinierten Kachelebene erstellt. Ich habe einen ArcGIS-Server verwendet, um einen kachelbasierten Karten-Cache zu generieren. Anschließend habe ich diese Kacheln in eine SQLite-Datenbank eingefügt und sie basierend auf Zeile und Spalte von dort abgefragt. Es funktioniert sehr gut und wenn Sie benutzerdefinierte Karten von Ende zu Ende benötigen, ist es eine sehr benutzerfreundliche Methode.

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
quelle
Können Sie bitte einen Code teilen?
Gregm
Ich habe meine benutzerdefinierte Layerklasse hinzugefügt, die die Arbeit erledigt.
5.
7

Ich habe eine Anwendung mit Offline-Karten für Android entwickelt. Das einzige kostenlose Tool, das Sie verwenden möchten, ist OSMDroid, ansonsten ESRI. Die OSMDroid-API ist mit der von Google identisch. Wenn Sie also von einer zur anderen wechseln möchten, ist dies ein Kinderspiel.

Schauen Sie sich diesen Beitrag mit einem Beispiel für die Integration von Google Maps in OSMDroid an.

Elijah Saounkine
quelle
2

Es gibt eine großartige App namens xGPS für iPhone und andere Geräte. Vielleicht möchten Sie sich das ansehen, um Ideen zu erhalten, da Benutzer die Karten, die sie benötigen, vorab zwischenspeichern können. Ich benutze es, wenn ich tief im Busch in Afrika, in den Florida Everglades, beim Bootfahren oder überall dort bin, wo ich keine Handy-Abdeckung habe. Ich werde die Karten vor meiner Reise zwischenspeichern und kann dann das GPS auf meinem iPhone normalerweise ohne Internet verwenden.

Grundsätzlich funktioniert xGPS und Sie möchten die Kartenkacheln lokal auf Ihrem Telefon zwischenspeichern. Der Platz auf diesen Handys ist begrenzt. Ja, auch wenn Sie 32 GB auf Ihrem Telefon haben, reicht es möglicherweise aus, ein kleines Land in allen Zoomstufen (Skalen) zwischenzuspeichern. Keines dieser Telefone (es sei denn, es ist irgendwie an einen externen Speicher angeschlossen) verfügt über genügend Speicherplatz, um die Welt in allen Zoomstufen zwischenzuspeichern. Ich stelle mir vor, das würde Petabyte Speicherplatz erfordern.

Sie müssen also in der Lage sein, Ihren Benutzer aufzufordern, die "Regionen" oder Karten zwischenzuspeichern, wenn er online ist, damit er sie offline verwenden kann. Mit xGPS kann ich ein Polygon über meiner Region von Interesse zeichnen und angeben, welche Zoomstufen ich zwischenspeichern möchte. Dann wird alles für mich auf mein Telefon heruntergeladen, entweder vom Telefon selbst oder von einem Programm auf meinem Computer. Dann gibt es eine Schaltfläche in der App, mit der ich in den "Offline" -Modus wechseln kann, wenn ich die Internetverbindung verliere.

CaptDragon
quelle
2

Versuchen Sie, NextGIS Mobile SDK zu verwenden. Der Online- / Offline-Modus umfasst die Bearbeitung und die automatische Synchronisierung mit dem Server (NextGIS Web). Raster- und Vektorebenen, benutzerdefinierte Eingabeformulare, Unterstützung für alle Arten von Geometrien.

Eine Beispielanwendung für NextGIS Mobile finden Sie im Google Play Store unter https://play.google.com/store/apps/details?id=com.nextgis.mobile

Quellen sind hier: https://github.com/nextgis/android_gisapp

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

Eine andere einfache Anwendung finden Sie hier: https://github.com/nextgis/android_muni_gisconf

SDK-Dokumentation: http://docs.nextgis.com/ngmobile_dev/toc.html

Dmitry Baryshnikov
quelle
1

Die aktuelle Version von ArcGIS Android SDK bietet vollständige Unterstützung für Offline-Karten. In diesem Beispiel wird gezeigt, wie Sie mit einem lokalen Kachelpaket als Grundkarte arbeiten und Online-Features bis hin zu Offline-Features beibehalten, von denen aus Sie verschiedene Bearbeitungsmöglichkeiten haben. Ich habe auch eine Übersicht über Github als vereinfachte Referenz.

jdONeill
quelle
1

Ich schlage vor, sich Nutiteq 3D Maps SDK anzusehen, das über Offline-Funktionen und interessante Extras wie 3D-Unterstützung verfügt. Es wird von einer spezialisierten Entwicklerfirma entwickelt, die dahinter steckt. Daher bietet es engagierten kommerziellen Support und mehr Flexibilität als große Anbieter. Haftungsausschluss: Ich bin Entwickler.

JaakL
quelle