2015-07-10 4 views
2

Я использую OSMdroid с автономными MBTiles. Мне нужно, чтобы пользователи могли выбирать несколько MBtiles из ListView. ListView Окна легко. Тем не менее, мне нужна помощь в загрузке различных загрузок MBtiles на основе MBtiles, выбранных из ListView. Мои MBTiles загружаются из SDCard.OSMdroid Загрузка нескольких автономных MBTIles через ListView

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?

ответ

4

Маленький мир, я просто сделал именно то, что вы ищете. Для osmdroid потребовалось patch.

Предполагая, что исправление применяется, вам необходимо создать собственное расширение MapTileProviderBase (см. MapTileProviderBasic в качестве ссылки). Вы захотите создать конструктор, который принимает массив файлов, а затем передать его в FileArchiveProvider. Отсюда, как только пользователь выбрал файлы, которые они хотят использовать для автономных карт, передайте этот список экземпляру своего пользовательского поставщика плитки, а затем вызовите MapView.setTileProvider.

Также отметим, что/SDCard/osmdroid работает очень хорошо для этой цели, однако, если устройство находится на KitKat и файлы находятся в/хранение/extSdCard (например, устройства Samsung), вам нужно также нужно this

В конечном итоге я отправлю запрос на перенос некоторых адаптеров, которые я сделал, чтобы упростить этот процесс.

Редактировать: Ваш прямой вопрос: «Как интегрировать переключение между MyTwoListItemsActivity и OfflineMapDemoActivity?», Является более специфичным для Android вопросом о том, как передавать данные из одной активности в другую. Намерения и общие предпочтения являются наиболее вероятными кандидатами для этого приложения. Вы можете захотеть использовать какие-то всплывающие окна, меню, панель действий, диалог и т. Д., Чтобы перевернуть источники карт. Построение MapView дорого и предотвращение повторной инициализации было бы хорошей идеей.

Редактировать: вот код, который я использовал.

Предостережение 1) вам нужно знать имя источника плитки раньше времени для каждого архива. Обычно 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 более чем возможны

+0

Вы можете поделиться своим кодом, который используется для поддержки нескольких MBTiles? Очень признателен. – user914425

+0

обновлен с кодом. Этот код не требует модификаций osm помимо двух связанных проблем. – spy

+0

ссылка на проблему osmdroid https://github.com/osmdroid/osmdroid/issues/140 – spy

Смежные вопросы