Skip to content

Commit

Permalink
MapFragment with SAF-based map and theme selection (#1091)
Browse files Browse the repository at this point in the history
  • Loading branch information
moving-bits authored and devemux86 committed Jan 7, 2024
1 parent 9df4efa commit 737143b
Showing 1 changed file with 96 additions and 30 deletions.
126 changes: 96 additions & 30 deletions vtm-android-example/src/org/oscim/android/test/MapFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,47 @@
*/
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;
import android.view.ViewGroup;
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;
import org.oscim.renderer.GLViewport;
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();
Expand All @@ -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<String> 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<String> getCategories(final XmlRenderThemeStyleMenu menu) {
// ignore theme settings for now
return new HashSet<>();
}

@Override
Expand Down

0 comments on commit 737143b

Please sign in to comment.