Skip to content

Commit

Permalink
osmdroid#180 auto zoom to bounds of the selected tile source for both…
Browse files Browse the repository at this point in the history
… geopackage and mapsforge.

osmdroid#527 found a simplier solution
  • Loading branch information
spyhunter99 committed Jan 14, 2017
1 parent 2cddf86 commit 92e6fcb
Show file tree
Hide file tree
Showing 39 changed files with 549 additions and 2,569 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ before_script:
- adb shell mount -o rw,remount rootfs /
- adb shell chmod 777 /mnt/sdcard
- adb shell mkdir /sdcard/osmdroid/
- adb push osmdroid-forge-app/world.map /sdcard/osmdroid/world.map
- adb push world.map /sdcard/osmdroid/world.map
- adb push ERDC_Whitehorse_GeoPackage.gpkg /sdcard/osmdroid/ERDC_Whitehorse_GeoPackage.gpkg
#- adb push resources/usgsbase.gemf /sdcard/osmdroid/usgsbase.gemf
#- adb push resources/usgstopo.sqlite /sdcard/osmdroid/usgstopo.sqlite
#- adb push resources/usgssat.zip /sdcard/osmdroid/usgssat.zip
Expand Down
2 changes: 2 additions & 0 deletions OpenStreetMapViewer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ android {
dependencies {
compile 'com.android.support:support-v4:23+'
compile project(':osmdroid-android')
compile project(':osmdroid-geopackage')
compile project(':osmdroid-mapsforge')

compile 'com.android.support:design:23.+'

Expand Down
7 changes: 4 additions & 3 deletions OpenStreetMapViewer/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.osmdroid"
android:versionCode="20"
android:versionName="5.3-SNAPSHOT">

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="23" />
<uses-sdk tools:overrideLibrary="org.osmdroid.gpkg,mil.nga.geopackage,org.osmdroid.mapsforge,android.support.v13"
android:minSdkVersion="8"
android:targetSdkVersion="23"/>

<supports-screens
android:anyDensity="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.osmdroid.samplefragments;


import android.os.Build;

import org.osmdroid.ISampleFactory;
import org.osmdroid.samplefragments.cache.CacheImport;
import org.osmdroid.samplefragments.cache.CachePurge;
Expand Down Expand Up @@ -40,7 +42,9 @@
import org.osmdroid.samplefragments.location.SampleFollowMe;
import org.osmdroid.samplefragments.location.SampleHeadingCompassUp;
import org.osmdroid.samplefragments.location.SampleRotation;
import org.osmdroid.samplefragments.tilesources.SampleAssetsOnly;
import org.osmdroid.samplefragments.tileproviders.GeopackageSample;
import org.osmdroid.samplefragments.tileproviders.MapsforgeTileProviderSample;
import org.osmdroid.samplefragments.tileproviders.SampleAssetsOnly;
import org.osmdroid.samplefragments.tilesources.SampleBingHybrid;
import org.osmdroid.samplefragments.tilesources.SampleBingRoad;
import org.osmdroid.samplefragments.tilesources.SampleCopyrightOverlay;
Expand All @@ -50,7 +54,7 @@
import org.osmdroid.samplefragments.tilesources.SampleInvertedTiles_NightMode;
import org.osmdroid.samplefragments.tilesources.SampleMapBox;
import org.osmdroid.samplefragments.tilesources.SampleMapQuest;
import org.osmdroid.samplefragments.tilesources.SampleOfflineOnly;
import org.osmdroid.samplefragments.tileproviders.SampleOfflineOnly;
import org.osmdroid.samplefragments.tilesources.SampleOpenSeaMap;
import org.osmdroid.samplefragments.tilesources.SampleWhackyColorFilter;
import org.osmdroid.samplefragments.tilesources.SepiaToneTiles;
Expand Down Expand Up @@ -133,6 +137,11 @@ private SampleFactory() {
mSamples.add(SampleBingRoad.class);
mSamples.add(Gridlines2.class);
mSamples.add(SepiaToneTiles.class);

if (Build.VERSION.SDK_INT >= 10)
mSamples.add(MapsforgeTileProviderSample.class);
if (Build.VERSION.SDK_INT >= 14)
mSamples.add(GeopackageSample.class);
}

public void addSample(Class<? extends BaseSampleFragment> clz) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package org.osmdroid.samplefragments.tileproviders;

import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import org.osmdroid.R;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.api.IMapView;
import org.osmdroid.config.Configuration;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.gpkg.GeoPackageMapTileModuleProvider;
import org.osmdroid.gpkg.GeoPackageProvider;
import org.osmdroid.samplefragments.BaseSampleFragment;
import org.osmdroid.tileprovider.tilesource.XYTileSource;
import org.osmdroid.tileprovider.util.StorageUtils;
import org.osmdroid.views.MapView;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.osmdroid.samplefragments.events.SampleMapEventListener.df;

/**
* One way for viewing geopackage tiles to the osmdroid view
* <p>
* created on 1/12/2017.
*
* @author Alex O'Ree
* @since 5.6.3
*/

public class GeopackageSample extends BaseSampleFragment {
TextView textViewCurrentLocation;
GeoPackageProvider.TileSourceBounds tileSourceBounds;
XYTileSource currentSource = null;

@Override
public String getSampleTitle() {
return "Geopackage tiles";
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
Log.d(TAG, "onCreate");
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View root = inflater.inflate(R.layout.map_with_locationbox, container, false);
mMapView = (MapView) root.findViewById(R.id.mapview);

if (Build.VERSION.SDK_INT >= 12) {
mMapView.setOnGenericMotionListener(new View.OnGenericMotionListener() {
/**
* mouse wheel zooming ftw
* http://stackoverflow.com/questions/11024809/how-can-my-view-respond-to-a-mousewheel
* @param v
* @param event
* @return
*/
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
if (0 != (event.getSource() & InputDevice.SOURCE_CLASS_POINTER)) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f)
mMapView.getController().zoomOut();
else {
mMapView.getController().zoomIn();
}
return true;
}
}
return false;
}
});
}

textViewCurrentLocation = (TextView) root.findViewById(R.id.textViewCurrentLocation);
return root;
}


@Override
public void addOverlays() {
super.addOverlays();
//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<File> mapfiles = findMapFiles();
//do a simple scan of local storage for .gpkg files.
File[] maps = new File[mapfiles.size()];
maps = mapfiles.toArray(maps);
if (maps.length == 0) {
//show a warning that no map files were found
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(
getContext());

// set title
alertDialogBuilder.setTitle("No Geopackage files found");

// set dialog message
alertDialogBuilder
.setMessage("In order to render map tiles, you'll need to either create or obtain .gpkg files. See http://www.geopackage.org/ for more info. Place them in "
+ Configuration.getInstance().getOsmdroidBasePath().getAbsolutePath())
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {

}
});


// create alert dialog
android.app.AlertDialog alertDialog = alertDialogBuilder.create();

// show it
alertDialog.show();

} else {
Toast.makeText(getContext(), "Loaded " + maps.length + " map files", Toast.LENGTH_LONG).show();
GeoPackageProvider geoPackageProvider = new GeoPackageProvider(maps, this.getContext());
mMapView.setTileProvider(geoPackageProvider);
List<GeoPackageMapTileModuleProvider.Container> tileSources = geoPackageProvider.geoPackageMapTileModuleProvider().getTileSources();

//here we're keeping track of the current tile source so we can reference it later, primarly for
//displaying the bounds of the tile set
boolean sourceSet = false;
for (int i = 0; i < tileSources.size(); i++) {
//this is a list of geopackages, since we only support tile tables, pick the first one of those
//ideally this should populate a spinner so that the user can select whatever tile source they want
if (tileSources.get(i) != null && !tileSources.get(i).tiles.isEmpty()) {
currentSource = (XYTileSource) geoPackageProvider.getTileSource(tileSources.get(i).database,
tileSources.get(0).tiles.get(i)
);
mMapView.setTileSource(currentSource);
sourceSet = true;
break;
}
}


if (!sourceSet) {
Toast.makeText(getContext(), "No tile source is available, get your geopackages for 'tiles' tables", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), "Tile source set to " + mMapView.getTileProvider().getTileSource().name(), Toast.LENGTH_LONG).show();
//this part will attempt to zoom to bounds of the selected tile source
tileSourceBounds = geoPackageProvider.getTileSourceBounds();
if (tileSourceBounds != null) {
mMapView.zoomToBoundingBox(tileSourceBounds.bounds, true);
mMapView.getController().setZoom(tileSourceBounds.minzoom);
}
}
}

mMapView.setMapListener(new MapListener() {
@Override
public boolean onScroll(ScrollEvent event) {
Log.i(IMapView.LOGTAG, System.currentTimeMillis() + " onScroll " + event.getX() + "," + event.getY());
updateInfo();
return true;
}

@Override
public boolean onZoom(ZoomEvent event) {
Log.i(IMapView.LOGTAG, System.currentTimeMillis() + " onZoom " + event.getZoomLevel());
updateInfo();
return true;
}
});
updateInfo();
}

private void updateInfo() {
StringBuilder sb = new StringBuilder();
IGeoPoint mapCenter = mMapView.getMapCenter();
sb.append(df.format(mapCenter.getLatitude()) + "," +
df.format(mapCenter.getLongitude())
+ ",zoom=" + mMapView.getZoomLevel());

if (currentSource != null) {
sb.append("\n");
sb.append(currentSource.name() + "," + currentSource.getBaseUrl());
}

if (tileSourceBounds != null) {
sb.append("\n");
sb.append(" minzoom=" + tileSourceBounds.minzoom);
sb.append(" maxzoom=" + tileSourceBounds.maxzoom);
sb.append(" bounds=" + df.format(tileSourceBounds.bounds.getLatNorth())
+ "," + df.format(tileSourceBounds.bounds.getLonEast()) + "," +
df.format(tileSourceBounds.bounds.getLatSouth()) + "," +
df.format(tileSourceBounds.bounds.getLonWest()));

}

textViewCurrentLocation.setText(sb.toString());
}

/**
* simple function to scan for paths that match /something/osmdroid/*.map to find database files
*
* @return
*/
protected static Set<File> findMapFiles() {
Set<File> maps = new HashSet<>();
List<StorageUtils.StorageInfo> 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<File> ret = new ArrayList<>();
File[] files = f.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().toLowerCase().endsWith(".gpkg"))
return true;
return false;
}
});
if (files != null) {
for (int i = 0; i < files.length; i++) {
ret.add(files[i]);
}
}
return ret;
}
}
Loading

0 comments on commit 92e6fcb

Please sign in to comment.