OSMdroid 通过 ListView 加载多个离线 MBTIles

use*_*425 2 android google-maps osmdroid mbtiles

我正在将 OSMdroid 与离线 MBTiles 一起使用。我需要能够添加用户从ListView. ListView窗户很容易。但是,我需要帮助根据从ListView. 我的 MBTiles 从 SDCard 加载。

import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;

import android.app.Activity;
import android.os.Bundle;
import android.widget.RelativeLayout;

public class OfflineMapDemoActivity extends Activity {

    private String MapName;

    public String getMapName(){
        return MapName;
    }
    public void setMapName(String s){
        MapName = s;
    }

    // layout
    private RelativeLayout mapLayout;

    // MapView
    private MapView mapView;
    private MapController mapController;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        // init Layout
        setContentView(R.layout.main);
        this.mapLayout = (RelativeLayout) findViewById(R.id.mapLayout);

        // init Offline Map
        MapName="World.sqlitedb";
        this.mapView = new OfflineMapView(this, MapName);
        this.mapController = mapView.getController();

        // set Zoom Countrol
        this.mapView.setBuiltInZoomControls(true);
        // set Touch Control
        this.mapView.setMultiTouchControls(true);
        // zoom to 15
        this.mapController.setZoom(15);
        //add mapview
        this.mapLayout.addView(this.mapView, new RelativeLayout.LayoutParams(
                    android.view.ViewGroup.LayoutParams.FILL_PARENT,
                    android.view.ViewGroup.LayoutParams.FILL_PARENT));

        // scroll to 24082456, 120558472
        GeoPoint geoPoint = new GeoPoint(24082456, 120558472);
        this.mapController.setCenter(geoPoint);

    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个全局字符串变量来保存MapName在那里的Listview类可以通过公共的方法设置setMapName()

顺便问一下,有没有一种方法可以自动读取 MBTiles 中心,而不是像这样进行硬编码?

    // scroll to 24082456, 120558472
    GeoPoint geoPoint = new GeoPoint(24082456, 120558472);
    this.mapController.setCenter(geoPoint);
Run Code Online (Sandbox Code Playgroud)

每次用户切换到OSMdroid映射ListView以从列表视图加载选定的离线 MBtiles 映射时,我应该使用哪种方法?上面关于 Create 方法只在第一次加载时加载一次 MBTiles 地图?这是列表视图代码。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.SimpleAdapter;

public class MyTwoListItemsActivity extends ListActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ArrayList<Map<String, String>> list = buildData();
        String[] from = { "mapname", "selected" };
        int[] to = { android.R.id.text1, android.R.id.text2 };

        SimpleAdapter adapter = new SimpleAdapter(this, list,
            android.R.layout.simple_list_item_2, from, to);
        setListAdapter(adapter);
    }

    private ArrayList<Map<String, String>> buildData() {
        ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
        list.add(putData("Map1", "Map1"));
        list.add(putData("Map2", "Map2"));
        list.add(putData("Map3", "Map3"));
        return list;
    } 

    private HashMap<String, String> putData(String name, String purpose) {
        HashMap<String, String> item = new HashMap<String, String>();
        item.put("mapname", mapname);
        item.put("selected", selected);
        return item;
    }

} 
Run Code Online (Sandbox Code Playgroud)

如何集成MyTwoListItemsActivity和之间的切换OfflineMapDemoActivity

spy*_*spy 5

小世界,我只是做了你正在寻找的。它需要osmdroid的补丁

假设打了补丁,就需要自己做MapTileProviderBase的扩展(参考MapTileProviderBasic)。您需要创建一个接受文件数组的构造函数,然后将其传递给 FileArchiveProvider。从这里开始,一旦用户选择了他们想要用于离线地图的文件,然后将该列表传递给您的自定义图块提供程序的实例,然后调用 MapView.setTileProvider。

另请注意, /sdcard/osmdroid 可以很好地用于此目的,但是如果您的设备在 kitkat 上并且文件在 /storage/extSdCard(例如三星设备)中,您还需要这个

我最终会为我制作的一些适配器提交一个拉取请求,以使这个过程更简单。

编辑:您的直接问题,“我如何集成 MyTwoListItemsActivity 和 OfflineMapDemoActivity 之间的切换?”,更多的是关于如何将数据从一个活动传输到另一个活动的 android 特定问题。意图和共享首选项是此应用程序最有可能的候选对象。您可能需要考虑使用某种弹出窗口、菜单、操作栏、对话框等来翻转地图源。MapView 的构建成本很高,防止重新初始化是一个好主意。

编辑:这是我使用的代码。

警告 1) 您需要提前知道每个存档的 Tile Source 名称。Zip 文件通常是地图源名称,如 OpenStreetMaps。Sqlite 有一个列,等等。如果你的瓷砖没有出现,这是最可能的原因。

创建平铺源。为简单起见,我选择命名文件以精确映射文件源名称。调整以满足您的需求。

public class FileBasedTileSource extends XYTileSource {

    public FileBasedTileSource(String aName, ResourceProxy.string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding, String[] aBaseUrl) {
        super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding, aBaseUrl);
    }

    public static ITileSource getSource(String name) {
        if (name.contains(".")) {
            name = name.substring(0, name.indexOf("."));
        }
        return new FileBasedTileSource(name,
            ResourceProxy.string.mapbox, 0, 18, 256, ".png", new String[]{
            "http://localhost"});
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你会用

ITileSource src=FileBasedTileSource.getSource("MyTileSource.gemf");
Run Code Online (Sandbox Code Playgroud)

接下来,您将需要以下类,我将为其创建拉取请求。这是瓷砖供应商。

public class OfflineTileProvider extends MapTileProviderArray implements IMapTileProviderCallback {

    /**
     * Creates a {@link MapTileProviderBasic}.
     * throws with the source[] is null or empty
     */
    public OfflineTileProvider(final IRegisterReceiver pRegisterReceiver, File[] source
    )
        throws Exception {
        super(FileBasedTileSource.getSource(source[0].getName()), pRegisterReceiver);
        IArchiveFile[] f = new IArchiveFile[source.length];
        for (int i=0; i < source.length; i++)
            f[i]=ArchiveFileFactory.getArchiveFile(source[i]);

        mTileProviderList.add(new MapTileFileArchiveProvider(pRegisterReceiver, getTileSource(), f));

    }
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个实例如下:

OfflineTileProvider provider = new OfflineTileProvider(new SimpleRegisterReceiver(mContext), myUserSelectedFiles[]));
mMapView.setTileProvider(provider);
mMapView.setUseDataConnection(false);
mMapView.invalidate();
Run Code Online (Sandbox Code Playgroud)

这应该创建一个实例并更新地图视图。

附加说明:IO 异常多于可能