org.osmdroid.forge.app.MainActivity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of OpenStreetMapViewer-Forge Show documentation
Show all versions of OpenStreetMapViewer-Forge Show documentation
Uses MapsForge to render tiles
The newest version!
package org.osmdroid.forge.app;
import android.Manifest;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.android.rendertheme.AssetsRenderTheme;
import org.mapsforge.map.rendertheme.XmlRenderTheme;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.mapsforge.MapsForgeTileProvider;
import org.osmdroid.mapsforge.MapsForgeTileSource;
import org.osmdroid.tileprovider.util.SimpleRegisterReceiver;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A simple, sample application, to use MapsForge https://github.com/mapsforge/mapsforge
* with osmdroid https://github.com/osmdroid/osmdroid map engine.
* @author Alex O'Ree
*/
public class MainActivity extends AppCompatActivity {
TextView currentCenter;
MapView mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* super important to configure some of the mapsforge settings first
*/
AndroidGraphicFactory.createInstance(this.getApplication());
/*
not sure how important these are....
MapFile.wayFilterEnabled = true;
MapFile.wayFilterDistance = 20;
MapWorkerPool.DEBUG_TIMING = true;
MapWorkerPool.NUMBER_OF_THREADS = MapWorkerPool.DEFAULT_NUMBER_OF_THREADS;
*/
//enable these for additional log output
//OpenStreetMapTileProviderConstants.DEBUG_TILE_PROVIDERS = true;
//OpenStreetMapTileProviderConstants.DEBUGMODE = true;
// Request permissions to support Android Marshmallow and above devices
if (Build.VERSION.SDK_INT >= 23) {
checkPermissions();
}
setContentView(R.layout.activity_main);
mMap = (MapView) findViewById(R.id.mapview);
currentCenter=(TextView) findViewById(R.id.currentCenter);
//first let's up our map source, mapsforge needs you to explicitly specify which map files to load
//this bit does some basic file system scanning
Set mapfiles = findMapFiles();
//do a simple scan of local storage for .map files.
File[] maps = new File[mapfiles.size()];
maps = mapfiles.toArray(maps);
if (maps.length==0){
//show a warning that no map files were found
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this);
// set title
alertDialogBuilder.setTitle("No Mapsforge files found");
// set dialog message
alertDialogBuilder
.setMessage("In order to render map tiles, you'll need to either create or obtain mapsforge .map files. See https://github.com/mapsforge/mapsforge for more info.")
.setCancelable(false)
.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
else
Toast.makeText(this, "Loaded " + maps.length + " map files", Toast.LENGTH_LONG).show();
//this creates the forge provider and tile sources
//that's it!
//note this example does not using caching yet, so each tile is rendered on the fly, every time
//the user browses to an area. This needs to be updated to support sqlite raster image caches
//protip: when changing themes, you should also change the tile source name to prevent cached tiles
//null is ok here, uses the default rendering theme if it's not set
XmlRenderTheme theme = null;
try {
theme = new AssetsRenderTheme(getApplicationContext(), "renderthemes/","rendertheme-v4.xml");
}catch (Exception ex){
ex.printStackTrace();
}
MapsForgeTileProvider forge = new MapsForgeTileProvider(
new SimpleRegisterReceiver(this),
MapsForgeTileSource.createFromFiles(maps,theme, "rendertheme-v4"));
mMap.setTileProvider(forge);
mMap.setUseDataConnection(false);
mMap.setMultiTouchControls(true);
mMap.setBuiltInZoomControls(true);
}
@Override
public void onStart() {
super.onStart();
mMap.getController().setCenter(new GeoPoint(0d, 0d));
mMap.getController().setZoom(5);
mMap.getController().zoomTo(5);
mMap.setMapListener(new MapListener() {
@Override
public boolean onScroll(ScrollEvent event) {
IGeoPoint mapCenter = mMap.getMapCenter();
currentCenter.setText(mapCenter.getLatitude() + "," + mapCenter.getLongitude() + " " + mMap.getZoomLevel());
return false;
}
@Override
public boolean onZoom(ZoomEvent event) {
return false;
}
});
}
/**
* simple function to scan for paths that match /something/osmdroid/*.map to find mapforge database files
* @return
*/
protected static Set findMapFiles() {
Set maps = new HashSet<>();
List storageList = StorageUtils.getStorageList();
for (int i = 0; i < storageList.size(); i++) {
File f = new File(storageList.get(i).path + File.separator + "osmdroid" + File.separator);
if (f.exists()) {
maps.addAll(scan(f));
}
}
return maps;
}
static private Collection extends File> scan(File f) {
List ret = new ArrayList<>();
File[] files = f.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().toLowerCase().endsWith(".map"))
return true;
return false;
}
});
if (files != null) {
for (int i = 0; i < files.length; i++) {
ret.add(files[i]);
}
}
return ret;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// START PERMISSION CHECK
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
private void checkPermissions() {
List permissions = new ArrayList<>();
String message = "OSMDroid permissions:";
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
message += "\nStorage access to store map tiles.";
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
message += "\nLocation to show user location.";
}
if (!permissions.isEmpty()) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
String[] params = permissions.toArray(new String[permissions.size()]);
requestPermissions(params, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
} // else: We already have permissions, so handle as normal
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map perms = new HashMap<>();
// Initial
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION and WRITE_EXTERNAL_STORAGE
Boolean location = perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
Boolean storage = perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
if (location && storage) {
// All Permissions Granted
Toast.makeText(MainActivity.this, "All permissions granted", Toast.LENGTH_SHORT).show();
} else if (location) {
Toast.makeText(this, "Storage permission is required to store map tiles to reduce data usage and for offline usage.", Toast.LENGTH_LONG).show();
} else if (storage) {
Toast.makeText(this, "Location permission is required to show the user's location on map.", Toast.LENGTH_LONG).show();
} else { // !location && !storage case
// Permission Denied
Toast.makeText(MainActivity.this, "Storage permission is required to store map tiles to reduce data usage and for offline usage." +
"\nLocation permission is required to show the user's location on map.", Toast.LENGTH_SHORT).show();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
// END PERMISSION CHECK
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy