diff --git a/vtm-android-example/src/org/oscim/android/test/MapFragment.java b/vtm-android-example/src/org/oscim/android/test/MapFragment.java index 5cbb219aa..70c74d57a 100644 --- a/vtm-android-example/src/org/oscim/android/test/MapFragment.java +++ b/vtm-android-example/src/org/oscim/android/test/MapFragment.java @@ -15,6 +15,10 @@ */ package org.oscim.android.test; +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -22,6 +26,8 @@ import android.widget.RelativeLayout; import org.oscim.android.MapView; import org.oscim.backend.CanvasAdapter; +import org.oscim.core.MapPosition; +import org.oscim.core.Tile; import org.oscim.layers.tile.buildings.BuildingLayer; import org.oscim.layers.tile.vector.VectorTileLayer; import org.oscim.layers.tile.vector.labeling.LabelLayer; @@ -29,20 +35,27 @@ import org.oscim.scalebar.DefaultMapScaleBar; import org.oscim.scalebar.MapScaleBar; import org.oscim.scalebar.MapScaleBarLayer; -import org.oscim.theme.IRenderTheme; -import org.oscim.theme.VtmThemes; +import org.oscim.theme.*; import org.oscim.tiling.source.mapfile.MapFileTileSource; +import org.oscim.tiling.source.mapfile.MapInfo; -import java.io.File; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipInputStream; -/** - * You'll need a map with filename berlin.map from download.mapsforge.org in device storage. - */ @SuppressWarnings("deprecation") -public class MapFragment extends android.app.Fragment { +public class MapFragment extends android.app.Fragment implements XmlRenderThemeMenuCallback { + + // Request code for selecting a map file / theme file + private static final int SELECT_MAP_FILE = 0; + private static final int SELECT_THEME_FILE = 1; private MapView mapView; private IRenderTheme theme; + private Uri tempMapUri; public static MapFragment newInstance() { MapFragment instance = new MapFragment(); @@ -65,32 +78,85 @@ public void onViewCreated(View view, Bundle savedInstanceState) { RelativeLayout relativeLayout = view.findViewById(R.id.mapView); relativeLayout.addView(mapView); - // Tile source - MapFileTileSource tileSource = new MapFileTileSource(); - File file = new File(getActivity().getExternalMediaDirs()[0], "berlin.map"); - tileSource.setMapFile(file.getAbsolutePath()); - - // Vector layer - VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource); - - // Building layer - mapView.map().layers().add(new BuildingLayer(mapView.map(), tileLayer)); - - // Label layer - mapView.map().layers().add(new LabelLayer(mapView.map(), tileLayer)); + // Open map + Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("*/*"); + startActivityForResult(intent, SELECT_MAP_FILE); + } - // Render theme - theme = mapView.map().setTheme(VtmThemes.DEFAULT); + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == SELECT_MAP_FILE && resultCode == Activity.RESULT_OK) { + if (data != null) { + tempMapUri = data.getData(); + + // Open map + Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("*/*"); + startActivityForResult(intent, SELECT_THEME_FILE); + } + } else if (requestCode == SELECT_THEME_FILE && resultCode == Activity.RESULT_OK) { + Uri uri = data.getData(); + openMap(tempMapUri, uri); + } + } - // Scale bar - MapScaleBar mapScaleBar = new DefaultMapScaleBar(mapView.map()); - MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mapView.map(), mapScaleBar); - mapScaleBarLayer.getRenderer().setPosition(GLViewport.Position.BOTTOM_LEFT); - mapScaleBarLayer.getRenderer().setOffset(5 * CanvasAdapter.getScale(), 0); - mapView.map().layers().add(mapScaleBarLayer); + // themeUri may be null, using default theme then + private void openMap(Uri mapUri, Uri themeUri) { + try { + // Tile source + MapFileTileSource tileSource = new MapFileTileSource(); + FileInputStream fis = (FileInputStream) getActivity().getContentResolver().openInputStream(mapUri); + tileSource.setMapFileInputStream(fis); + + // Vector layer + VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource); + + // Building layer + mapView.map().layers().add(new BuildingLayer(mapView.map(), tileLayer)); + + // Label layer + mapView.map().layers().add(new LabelLayer(mapView.map(), tileLayer)); + + // Render theme + if (themeUri != null) { + final List xmlThemes = ZipXmlThemeResourceProvider.scanXmlThemes(new ZipInputStream(new BufferedInputStream(getActivity().getContentResolver().openInputStream(themeUri)))); + if (xmlThemes.isEmpty()) { + return; + } + ThemeFile theme = new ZipRenderTheme(xmlThemes.get(0), new ZipXmlThemeResourceProvider(new ZipInputStream(new BufferedInputStream(getActivity().getContentResolver().openInputStream(themeUri))))); + mapView.map().setTheme(theme); + } else { + theme = mapView.map().setTheme(VtmThemes.DEFAULT); + } + + // Scale bar + MapScaleBar mapScaleBar = new DefaultMapScaleBar(mapView.map()); + MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mapView.map(), mapScaleBar); + mapScaleBarLayer.getRenderer().setPosition(GLViewport.Position.BOTTOM_LEFT); + mapScaleBarLayer.getRenderer().setOffset(5 * CanvasAdapter.getScale(), 0); + mapView.map().layers().add(mapScaleBarLayer); + + MapInfo info = tileSource.getMapInfo(); + if (!info.boundingBox.contains(mapView.map().getMapPosition().getGeoPoint())) { + MapPosition pos = new MapPosition(); + pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4); + mapView.map().setMapPosition(pos); + } + } catch (Exception e) { + /* + * In case of map file errors avoid crash, but developers should handle these cases! + */ + e.printStackTrace(); + } + } - // Note: this map position is specific to Berlin area - mapView.map().setMapPosition(52.517037, 13.38886, 1 << 12); + @Override + public Set getCategories(final XmlRenderThemeStyleMenu menu) { + // ignore theme settings for now + return new HashSet<>(); } @Override