Android: scoped storage example
This commit is contained in:
parent
e3b4ff502e
commit
e103c38e3e
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## New since 0.14.0
|
## New since 0.14.0
|
||||||
|
|
||||||
|
- Android: scoped storage example [#785](https://github.com/mapsforge/vtm/pull/785)
|
||||||
- Mapsforge: map stream support [#784](https://github.com/mapsforge/vtm/pull/784)
|
- Mapsforge: map stream support [#784](https://github.com/mapsforge/vtm/pull/784)
|
||||||
- Render theme from Android content providers [#783](https://github.com/mapsforge/vtm/pull/783)
|
- Render theme from Android content providers [#783](https://github.com/mapsforge/vtm/pull/783)
|
||||||
- Many other minor improvements and bug fixes
|
- Many other minor improvements and bug fixes
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018-2019 devemux86
|
* Copyright 2018-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@ -15,6 +15,9 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import org.oscim.android.MapView;
|
import org.oscim.android.MapView;
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
@ -29,6 +32,7 @@ import org.oscim.theme.VtmThemes;
|
|||||||
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A very basic Android app example.
|
* A very basic Android app example.
|
||||||
@ -41,6 +45,9 @@ public class GettingStarted extends Activity {
|
|||||||
// Name of the map file in device storage
|
// Name of the map file in device storage
|
||||||
private static final String MAP_FILE = "berlin.map";
|
private static final String MAP_FILE = "berlin.map";
|
||||||
|
|
||||||
|
// Request code for selecting a map file
|
||||||
|
private static final int PICK_MAP_FILE = 0;
|
||||||
|
|
||||||
private MapView mapView;
|
private MapView mapView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -51,10 +58,39 @@ public class GettingStarted extends Activity {
|
|||||||
mapView = new MapView(this);
|
mapView = new MapView(this);
|
||||||
setContentView(mapView);
|
setContentView(mapView);
|
||||||
|
|
||||||
// Tile source
|
// Open map
|
||||||
MapFileTileSource tileSource = new MapFileTileSource();
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
String mapPath = new File(getExternalFilesDir(null), MAP_FILE).getAbsolutePath();
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
if (tileSource.setMapFile(mapPath)) {
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, PICK_MAP_FILE);
|
||||||
|
} else
|
||||||
|
openMap(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (requestCode == PICK_MAP_FILE && resultCode == Activity.RESULT_OK) {
|
||||||
|
if (data != null) {
|
||||||
|
Uri uri = data.getData();
|
||||||
|
openMap(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openMap(Uri uri) {
|
||||||
|
try {
|
||||||
|
// Tile source
|
||||||
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
|
if (uri != null) {
|
||||||
|
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
|
||||||
|
tileSource.setMapFileInputStream(fis);
|
||||||
|
} else {
|
||||||
|
String mapPath = new File(getExternalFilesDir(null), MAP_FILE).getAbsolutePath();
|
||||||
|
if (!tileSource.setMapFile(mapPath))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Vector layer
|
// Vector layer
|
||||||
VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource);
|
VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource);
|
||||||
|
|
||||||
@ -76,6 +112,11 @@ public class GettingStarted extends Activity {
|
|||||||
|
|
||||||
// Note: this map position is specific to Berlin area
|
// Note: this map position is specific to Berlin area
|
||||||
mapView.map().setMapPosition(52.517037, 13.38886, 1 << 12);
|
mapView.map().setMapPosition(52.517037, 13.38886, 1 << 12);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
* In case of map file errors avoid crash, but developers should handle these cases!
|
||||||
|
*/
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Hannes Janetzek
|
* Copyright 2014 Hannes Janetzek
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
* Copyright 2018 Gustl22
|
* Copyright 2018 Gustl22
|
||||||
*
|
*
|
||||||
@ -19,15 +19,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import org.oscim.android.filepicker.FilePicker;
|
import org.oscim.android.filepicker.FilePicker;
|
||||||
import org.oscim.android.filepicker.FilterByFileExtension;
|
import org.oscim.android.filepicker.FilterByFileExtension;
|
||||||
import org.oscim.android.filepicker.ValidMapFile;
|
import org.oscim.android.filepicker.ValidMapFile;
|
||||||
import org.oscim.android.filepicker.ValidRenderTheme;
|
import org.oscim.android.filepicker.ValidRenderTheme;
|
||||||
|
import org.oscim.android.theme.ContentRenderTheme;
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
@ -42,23 +45,29 @@ import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
|||||||
import org.oscim.renderer.BitmapRenderer;
|
import org.oscim.renderer.BitmapRenderer;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.bucket.RenderBuckets;
|
import org.oscim.renderer.bucket.RenderBuckets;
|
||||||
import org.oscim.scalebar.DefaultMapScaleBar;
|
import org.oscim.scalebar.*;
|
||||||
import org.oscim.scalebar.ImperialUnitAdapter;
|
|
||||||
import org.oscim.scalebar.MapScaleBar;
|
|
||||||
import org.oscim.scalebar.MapScaleBarLayer;
|
|
||||||
import org.oscim.scalebar.MetricUnitAdapter;
|
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
import org.oscim.theme.ExternalRenderTheme;
|
||||||
import org.oscim.theme.ThemeUtils;
|
import org.oscim.theme.ThemeFile;
|
||||||
import org.oscim.theme.VtmThemes;
|
import org.oscim.theme.VtmThemes;
|
||||||
import org.oscim.theme.styles.AreaStyle;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||||
import org.oscim.tiling.source.mapfile.MapInfo;
|
import org.oscim.tiling.source.mapfile.MapInfo;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class MapsforgeActivity extends MapActivity {
|
public class MapsforgeActivity extends MapActivity {
|
||||||
|
|
||||||
static final int SELECT_MAP_FILE = 0;
|
private static final Logger log = LoggerFactory.getLogger(MapsforgeActivity.class);
|
||||||
static final int SELECT_THEME_FILE = SELECT_MAP_FILE + 1;
|
|
||||||
|
static final int PICK_MAP_FILE = 0;
|
||||||
|
static final int PICK_THEME_FILE = 1;
|
||||||
|
|
||||||
|
static final int SELECT_MAP_FILE = 2;
|
||||||
|
static final int SELECT_THEME_FILE = 3;
|
||||||
|
|
||||||
private static final Tag ISSEA_TAG = new Tag("natural", "issea");
|
private static final Tag ISSEA_TAG = new Tag("natural", "issea");
|
||||||
private static final Tag NOSEA_TAG = new Tag("natural", "nosea");
|
private static final Tag NOSEA_TAG = new Tag("natural", "nosea");
|
||||||
@ -66,7 +75,7 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
|
|
||||||
private TileGridLayer mGridLayer;
|
private TileGridLayer mGridLayer;
|
||||||
private Menu mMenu;
|
private Menu mMenu;
|
||||||
private boolean mS3db;
|
private final boolean mS3db;
|
||||||
VectorTileLayer mTileLayer;
|
VectorTileLayer mTileLayer;
|
||||||
|
|
||||||
public MapsforgeActivity() {
|
public MapsforgeActivity() {
|
||||||
@ -87,8 +96,14 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
startActivityForResult(new Intent(this, MapFilePicker.class),
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
SELECT_MAP_FILE);
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, PICK_MAP_FILE);
|
||||||
|
} else
|
||||||
|
startActivityForResult(new Intent(this, MapFilePicker.class),
|
||||||
|
SELECT_MAP_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MapFilePicker extends FilePicker {
|
public static class MapFilePicker extends FilePicker {
|
||||||
@ -142,8 +157,14 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_external:
|
case R.id.theme_external:
|
||||||
startActivityForResult(new Intent(this, ThemeFilePicker.class),
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
SELECT_THEME_FILE);
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, PICK_THEME_FILE);
|
||||||
|
} else
|
||||||
|
startActivityForResult(new Intent(this, ThemeFilePicker.class),
|
||||||
|
SELECT_THEME_FILE);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.gridlayer:
|
case R.id.gridlayer:
|
||||||
@ -165,58 +186,86 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
|
||||||
if (requestCode == SELECT_MAP_FILE) {
|
if (requestCode == PICK_MAP_FILE || requestCode == SELECT_MAP_FILE) {
|
||||||
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
if (resultCode != Activity.RESULT_OK || data == null) {
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapFileTileSource mTileSource = new MapFileTileSource();
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
//mTileSource.setPreferredLanguage("en");
|
//tileSource.setPreferredLanguage("en");
|
||||||
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
|
||||||
if (mTileSource.setMapFile(file)) {
|
|
||||||
|
|
||||||
mTileLayer = mMap.setBaseMap(mTileSource);
|
if (requestCode == PICK_MAP_FILE) {
|
||||||
loadTheme(null);
|
try {
|
||||||
|
Uri uri = data.getData();
|
||||||
|
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
|
||||||
|
tileSource.setMapFileInputStream(fis);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (data.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mS3db)
|
String file = data.getStringExtra(FilePicker.SELECTED_FILE);
|
||||||
mMap.layers().add(new S3DBLayer(mMap, mTileLayer));
|
if (!tileSource.setMapFile(file)) {
|
||||||
else
|
finish();
|
||||||
mMap.layers().add(new BuildingLayer(mMap, mTileLayer));
|
return;
|
||||||
mMap.layers().add(new LabelLayer(mMap, mTileLayer));
|
|
||||||
|
|
||||||
DefaultMapScaleBar mMapScaleBar = new DefaultMapScaleBar(mMap);
|
|
||||||
mMapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
|
|
||||||
mMapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE);
|
|
||||||
mMapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE);
|
|
||||||
mMapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT);
|
|
||||||
|
|
||||||
MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mMapScaleBar);
|
|
||||||
BitmapRenderer renderer = mapScaleBarLayer.getRenderer();
|
|
||||||
renderer.setPosition(GLViewport.Position.BOTTOM_LEFT);
|
|
||||||
renderer.setOffset(5 * CanvasAdapter.getScale(), 0);
|
|
||||||
mMap.layers().add(mapScaleBarLayer);
|
|
||||||
|
|
||||||
MapInfo info = mTileSource.getMapInfo();
|
|
||||||
if (!info.boundingBox.contains(mMap.getMapPosition().getGeoPoint())) {
|
|
||||||
MapPosition pos = new MapPosition();
|
|
||||||
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
|
|
||||||
mMap.setMapPosition(pos);
|
|
||||||
mPrefs.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (requestCode == SELECT_THEME_FILE) {
|
|
||||||
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
mTileLayer = mMap.setBaseMap(tileSource);
|
||||||
|
loadTheme(null);
|
||||||
|
|
||||||
|
if (mS3db)
|
||||||
|
mMap.layers().add(new S3DBLayer(mMap, mTileLayer));
|
||||||
|
else
|
||||||
|
mMap.layers().add(new BuildingLayer(mMap, mTileLayer));
|
||||||
|
mMap.layers().add(new LabelLayer(mMap, mTileLayer));
|
||||||
|
|
||||||
|
DefaultMapScaleBar mapScaleBar = new DefaultMapScaleBar(mMap);
|
||||||
|
mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
|
||||||
|
mapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE);
|
||||||
|
mapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE);
|
||||||
|
mapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT);
|
||||||
|
|
||||||
|
MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mapScaleBar);
|
||||||
|
BitmapRenderer renderer = mapScaleBarLayer.getRenderer();
|
||||||
|
renderer.setPosition(GLViewport.Position.BOTTOM_LEFT);
|
||||||
|
renderer.setOffset(5 * CanvasAdapter.getScale(), 0);
|
||||||
|
mMap.layers().add(mapScaleBarLayer);
|
||||||
|
|
||||||
|
MapInfo info = tileSource.getMapInfo();
|
||||||
|
if (!info.boundingBox.contains(mMap.getMapPosition().getGeoPoint())) {
|
||||||
|
MapPosition pos = new MapPosition();
|
||||||
|
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
|
||||||
|
mMap.setMapPosition(pos);
|
||||||
|
mPrefs.clear();
|
||||||
|
}
|
||||||
|
} else if (requestCode == PICK_THEME_FILE || requestCode == SELECT_THEME_FILE) {
|
||||||
|
if (resultCode != Activity.RESULT_OK || data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ThemeFile theme;
|
||||||
|
if (requestCode == PICK_THEME_FILE) {
|
||||||
|
Uri uri = data.getData();
|
||||||
|
theme = new ContentRenderTheme(getContentResolver(), "", uri);
|
||||||
|
} else {
|
||||||
|
if (data.getStringExtra(FilePicker.SELECTED_FILE) == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
String file = data.getStringExtra(FilePicker.SELECTED_FILE);
|
||||||
|
theme = new ExternalRenderTheme(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
|
||||||
ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(file);
|
|
||||||
|
|
||||||
// Use tessellation with sea and land for Mapsforge themes
|
// Use tessellation with sea and land for Mapsforge themes
|
||||||
if (ThemeUtils.isMapsforgeTheme(externalRenderTheme)) {
|
if (theme.isMapsforgeTheme()) {
|
||||||
mTileLayer.addHook(new VectorTileLayer.TileLoaderThemeHook() {
|
mTileLayer.addHook(new VectorTileLayer.TileLoaderThemeHook() {
|
||||||
@Override
|
@Override
|
||||||
public boolean process(MapTile tile, RenderBuckets buckets, MapElement element, RenderStyle style, int level) {
|
public boolean process(MapTile tile, RenderBuckets buckets, MapElement element, RenderStyle style, int level) {
|
||||||
@ -233,7 +282,7 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mMap.setTheme(externalRenderTheme);
|
mMap.setTheme(theme);
|
||||||
mMenu.findItem(R.id.theme_external).setChecked(true);
|
mMenu.findItem(R.id.theme_external).setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user