오프라인에서 사용할 수있는 안드로이드 맵 앱 솔루션?


14

인터넷 연결없이 작동 할 수있는 내장 된지 도로 안드로이드 용 앱을 개발하는 방법을 찾고 있습니다 (즉, 오프라인 사용을 위해 열린 거리지도 타일을 얻을 수 있습니까?).

Google지도 API v3을 사용하여 웹 앱을 개발했습니다. 특정 답변으로 일반적인 답변이 필요합니다. 배워야 할 개념과 기술을 찾으려고합니다. :)

(내가 osmdroid를 찾았습니다. 오프라인으로 작동합니까?)


이것은 실제로 질문에 대답하지 않습니다. 다른 질문이 있으면 질문하기를 클릭하여 질문 할 수 있습니다 . 당신은 또한 충분한 명성을 얻은 후에이 질문에 더 많은 관심을 끌기 위해 현상금추가 할 수 있습니다 .
Jason Scheirer

Osmand는 사용자가 원하는대로 맞춤지도를 가져올 수 없지만 오프라인 사용을 위해 앱에서 바로지도를 다운로드 할 수만 있습니다. 필자의 경우와 같이 * .kmz로 변환 된 지형지 물 (래스터 맵)을 오버레이해야합니다. 내 요구 사항은 오프라인 사용입니다. 이러한 오프라인지도 지원 안드로이드 응용 프로그램을 개발하기위한 적절한 지침을 찾고 있습니다.
sup

이것은 오프라인 사용을 위해지도를 어디서 어떻게 얻는 지에 대한 원래의 질문에 실제로 대답하지는 않습니다.
MaryBeth

이것은 실제로 질문에 대답하지 않습니다. 다른 질문이 있으면 질문하기를 클릭하여 질문 할 수 있습니다 . 당신은 또한 충분한 명성을 얻은 후에이 질문에 더 많은 관심을 끌기 위해 현상금추가 할 수 있습니다 . - 리뷰에서
John Powell

답변:



13

ESRI Android SDK와 맞춤형 타일 레이어를 사용하여 오프라인 맵을 만들었습니다. ArcGIS 서버를 사용하여 타일 기반 맵 캐시를 생성 한 다음 해당 타일을 SQLite 데이터베이스에 삽입하고 거기에서 행과 열을 기준으로 쿼리합니다. 훌륭하게 작동하며 맞춤지도가 필요하다면 매우 유용한 방법입니다.

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;   
}

}


코드를 공유해 주시겠습니까?
gregm

작업을 수행하는 사용자 정의 레이어 클래스를 추가했습니다.
eptiliom

7

Android 용 오프라인지도가있는 애플리케이션을 개발했습니다. 사용하려는 유일한 무료 도구는 OSMDroid, 그렇지 않으면 ESRI입니다. OSMDroid API는 Google의 API와 동일하므로 서로 전환하려면 바람이 불다.

Google지도를 OSMDroid에 통합하는 방법에 대한 샘플과 함께이 게시물을 확인하십시오 (일반적으로 사용 방법에 대한 아이디어도 제공함).


2

iPhone 및 기타 장치 용 xGPS라는 훌륭한 앱이 있습니다. 사용자가 필요한 맵을 사전 캐시 할 수 있기 때문에 아이디어를 얻기 위해이를보고 싶을 것입니다. 아프리카, 플로리다 에버글레이즈, 보트, 또는 휴대 전화가없는 곳의 덤불에있을 때 사용합니다. 여행하기 전에지도를 캐시 한 다음 인터넷없이 인터넷에서 GPS를 정상적으로 사용할 수 있습니다.

기본적으로 xGPS의 기능과 수행하려는 작업은지도 타일을 휴대폰에 로컬로 캐시하는 것입니다. 이 휴대 전화의 공간은 제한되어 있습니다. 예, 휴대 전화에 32GB가 있어도 모든 확대 / 축소 수준에서 소규모 국가를 캐시하기에 충분할 수 있습니다. 외부 저장 장치에 연결된 경우를 제외하고 이러한 전화 중 어느 것도 모든 확대 / 축소 수준에서 세계를 캐시하기에 충분한 공간을 확보하지 못합니다. 나는 이것이 페타 바이트의 저장 공간을 필요로한다고 생각합니다.

따라서 사용자가 온라인 상태 일 때 "지역"또는지도를 캐시하여 오프라인으로 사용할 수 있도록 요청할 수 있어야합니다. xGPS를 사용하면 관심 영역에 다각형을 그리고 캐시 할 확대 / 축소 수준을 지정할 수 있습니다. 그런 다음 전화 자체 또는 컴퓨터의 프로그램에서 전화로 다운로드를 시작합니다. 그런 다음 인터넷 연결이 끊겼을 때 앱에 "오프라인"모드로 전환 할 수있는 버튼이 있습니다.


2

NextGIS Mobile SDK를 사용해보십시오. 온라인 / 오프라인 모드에는 편집 및 서버와의 자동 동기화 (NextGIS Web)가 포함됩니다. 래스터 및 벡터 레이어, 사용자 정의 입력 양식, 모든 유형의 지오메트리 지원.

NextGIS Mobile 예제 애플리케이션은 Google Play 스토어 ( https://play.google.com/store/apps/details?id=com.nextgis.mobile) 에서 찾을 수 있습니다.

출처는 다음과 같습니다. https://github.com/nextgis/android_gisapp

설명서 : http://docs.nextgis.com/docs_ngmobile/source/toc.html

또 다른 간단한 응용 프로그램은 다음과 같습니다. https://github.com/nextgis/android_muni_gisconf

SDK 설명서 : http://docs.nextgis.com/ngmobile_dev/toc.html


1

ArcGIS Android SDK의 현재 릴리스에서는 오프라인 맵을 완벽하게 지원합니다. 이 샘플 에서는 로컬 타일 패키지를베이스 맵으로 사용하는 방법을 보여주고 온라인 기능을 편집 할 수있는 오프라인 기능에 유지합니다. 단순화 된 참조를 위해 github 에서 요점을 사용할 수 있습니다.


1

오프라인 기능과 3D 지원과 같은 흥미로운 추가 기능이있는 Nutiteq 3D 맵 SDK 를 살펴 보는 것이 좋습니다 . 그것은 전문 개발자 회사가 그 뒤에 만들었으므로 큰 상용 공급 업체가 제공하는 것보다 전용 상업용 지원과 더 많은 유연성을 가지고 있습니다. 면책 조항 : 나는 그것을 개발자입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.