我正在使用OSMdroid和离线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
可以通过公共方法setMapName()
设置的位置。
顺便问一下,有没有一种方法可以自动读取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
之间的切换?
答案 0 :(得分:4)
小世界,我只是做了你正在寻找的东西。 osmdroid需要patch。
假设应用了补丁,您需要自己扩展MapTileProviderBase(请参阅MapTileProviderBasic作为参考)。您将需要创建一个构造函数,该构造函数接收文件数组,然后将其传递给FileArchiveProvider。从这里开始,一旦用户选择了他们想要用于离线地图的文件,然后将该列表传递给自定义磁贴提供者的实例,然后调用MapView.setTileProvider。
另请注意,/ sdcard / osmdroid可以正常工作,但是如果你的设备在kitkat上并且文件在/ storage / extSdCard中(例如三星设备),你还需要{{3} }
我最终会提交一些拉动请求,以便我为使这个过程更简单而制作一些适配器。
编辑:您的直接问题“我如何在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异常超出可能性