OSMdroid Загрузка нескольких автономных MBTIles через ListView
Я использую OSMdroid с автономными MBTiles. Мне нужно иметь возможность добавлять пользователей, чтобы выбрать несколько MBtiles из 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
где 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
?
1 ответ
Маленький мир, я просто сделал именно то, что вы ищете. Требуется патч для osmdroid.
Предполагая, что исправление применено, вам нужно создать собственное расширение MapTileProviderBase (см. MapTileProviderBasic в качестве ссылки). Вы захотите создать конструктор, который будет принимать массив файлов, а затем передавать его в FileArchiveProvider. Отсюда, как только пользователь выбрал файлы, которые он хочет использовать для автономных карт, затем передайте этот список экземпляру своего пользовательского провайдера плиток, а затем вызовите MapView.setTileProvider.
Также обратите внимание, что /sdcard/osmdroid отлично подходит для этой цели, однако, если ваше устройство находится на kitkat, а файлы находятся в /storage/extSdCard (например, на устройствах Samsung), вам также понадобится это
В конце концов я отправлю запрос на извлечение некоторых адаптеров, которые я сделал, чтобы упростить этот процесс.
Изменить: Ваш прямой вопрос, "Как мне интегрировать переключение между 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();
Это должно создать экземпляр и обновить вид карты.
Дополнительные примечания: исключений ввода-вывода более чем возможно