2

我正在使用带有离线 MBTiles 的 OSMdroid。我需要能够添加用户以从ListView. ListView窗户很容易。但是,我需要帮助根据从中选择的 MBtiles 加载不同的 MBtiles 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);

    }
}

我创建了一个全局字符串变量来保存类可以通过公共方法设置的MapName位置。ListviewsetMapName()

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

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

每次用户切换到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;
    }

} 

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

4

1 回答 1

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

然后你会用

ITileSource src=FileBasedTileSource.getSource("MyTileSource.gemf");

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

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

    }
}

然后创建一个实例如下:

OfflineTileProvider provider = new OfflineTileProvider(new SimpleRegisterReceiver(mContext), myUserSelectedFiles[]));
mMapView.setTileProvider(provider);
mMapView.setUseDataConnection(false);
mMapView.invalidate();

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

附加说明:IO 异常是不可能的

于 2015-07-11T22:13:22.317 回答