OSMdroid загружает несколько автономных MBTIles через ListView

Я использую OSMdroid с Offline 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?


person user914425    schedule 10.07.2015    source источник


Ответы (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();

Это должно создать экземпляр и обновить представление карты.

Дополнительные примечания: исключения ввода-вывода более чем возможны

person spy    schedule 11.07.2015
comment
Вы можете поделиться своим кодом, который вы используете для поддержки нескольких MBTiles? Очень признателен. - person user914425; 14.07.2015
comment
обновлен кодом. Этот код не требует модификаций osm, кроме двух связанных проблем. - person spy; 15.07.2015
comment
спасибо за ваше обновление. Мне было интересно, как мне определить ограничивающую рамку (широта, долгота) карты MBTILES во время выполнения? - person user914425; 22.07.2015
comment
Похоже, что mbtiles — это база данных sqlite, github.com/mapbox/mbtiles-spec как таковая. , возможно, вы сможете вычислить границы. Он использует тот же формат x/y/z, что и все остальное. Вероятно, вы хотите найти максимальные значения x и y, а затем преобразовать их в широту/долготу. - person spy; 22.07.2015