gpt4 book ai didi

android - OSMdroid 通过 ListView 加载多个离线 MBTIles

转载 作者:搜寻专家 更新时间:2023-11-01 07:53:35 43 4
gpt4 key购买 nike

我将 OSMdroid 与 Offline MBTiles 一起使用。我需要能够添加用户以从 ListView 中选择多个 MBtiles。 ListView 窗口很简单。但是,我需要帮助根据从 ListView 中选择的 MBtiles 加载不同的 MBtiles。我的 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,其中 Listview 类可以通过公共(public)方法 setMapName() 进行设置。

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

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

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

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

}

如何集成 MyTwoListItemsActivityOfflineMapDemoActivity 之间的切换?

最佳答案

小世界,我只是做了你想要的。它需要 patch对于 osmdroid。

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

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

我最终会为我制作的一些适配器提交拉取请求,以简化此过程。

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

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

警告 1) 您需要提前知道每个存档的 Tile Source 名称。 Zip 文件通常是 map 源名称,例如 OpenStreetMaps。 Sqlite 有一个专栏,等等。如果您的磁贴没有显示,这是最可能的原因。

创建一个图 block 源。为简单起见,我选择命名文件以准确映射文件源名称。进行调整以满足您的需求。

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

这应该创建一个实例并更新 map View 。

补充说明:IO 异常比可能的多

关于android - OSMdroid 通过 ListView 加载多个离线 MBTIles,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31347019/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com