diff --git a/CHANGELOG.md b/CHANGELOG.md
index abe27892..30729cbd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,9 +4,14 @@ Adheres to [Semantic Versioning](http://semver.org/).
---
-## 1.16 (TBD)
-
-* TBD
+## [1.16](https://github.com/ngageoint/geopackage-mapcache-android/releases/tag/1.16) (07-13-2017)
+
+* geopackage-android-map version updated to 1.4.1
+* Manifest MultiDex fix for pre Lollipop Android versions
+* Improved handling of unknown Contents bounding boxes
+* Open GeoPackage from URI creates missing names from last path section
+* Prevent app crash from invalid or unsupported geometries
+* Bounding of degree projected boxes before Web Mercator transformations
## [1.15](https://github.com/ngageoint/geopackage-mapcache-android/releases/tag/1.15) (06-27-2017)
diff --git a/docs/index.html b/docs/index.html
index 6b014e8e..6f78a317 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -15,7 +15,7 @@
GeoPackage MapCache Android
by the National Geospatial-Intelligence Agency
GitHub
- APK
+ APK
.zip
.tar.gz
diff --git a/mapcache/build.gradle b/mapcache/build.gradle
index e44d4bcd..d2f70830 100644
--- a/mapcache/build.gradle
+++ b/mapcache/build.gradle
@@ -50,7 +50,7 @@ task androidAppVersion {
}
dependencies {
- compile "mil.nga.geopackage.map:geopackage-android-map:1.4.0" // comment out to build locally
+ compile "mil.nga.geopackage.map:geopackage-android-map:1.4.1" // comment out to build locally
compile 'com.android.support:multidex:1.0.1'
//compile project(':geopackage-map') // uncomment me to build locally
}
diff --git a/mapcache/src/main/AndroidManifest.xml b/mapcache/src/main/AndroidManifest.xml
index 74a1bb17..a6031123 100644
--- a/mapcache/src/main/AndroidManifest.xml
+++ b/mapcache/src/main/AndroidManifest.xml
@@ -14,6 +14,7 @@
diff --git a/mapcache/src/main/java/mil/nga/mapcache/GeoPackageManagerFragment.java b/mapcache/src/main/java/mil/nga/mapcache/GeoPackageManagerFragment.java
index 64317a25..99702d7b 100644
--- a/mapcache/src/main/java/mil/nga/mapcache/GeoPackageManagerFragment.java
+++ b/mapcache/src/main/java/mil/nga/mapcache/GeoPackageManagerFragment.java
@@ -49,6 +49,8 @@
import com.ipaulpro.afilechooser.utils.FileUtils;
+import org.osgeo.proj4j.units.DegreeUnit;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -2323,8 +2325,17 @@ private void createFeatureTilesTableOption(final GeoPackageTable table) {
Contents contents = contentsDao.queryForId(table.getName());
if (contents != null) {
BoundingBox boundingBox = contents.getBoundingBox();
- Projection projection = ProjectionFactory.getProjection(
- contents.getSrs().getOrganizationCoordsysId());
+ Projection projection = null;
+ if (boundingBox == null) {
+ boundingBox = new BoundingBox(-ProjectionConstants.WGS84_HALF_WORLD_LON_WIDTH,
+ ProjectionConstants.WGS84_HALF_WORLD_LON_WIDTH,
+ ProjectionConstants.WEB_MERCATOR_MIN_LAT_RANGE,
+ ProjectionConstants.WEB_MERCATOR_MAX_LAT_RANGE);
+ projection = ProjectionFactory.getProjection(ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
+ } else {
+ projection = ProjectionFactory.getProjection(
+ contents.getSrs());
+ }
// Try to find a good zoom starting point
ProjectionTransform webMercatorTransform = projection.getTransformation(
@@ -2598,16 +2609,28 @@ private void addFeatureOverlayTableOption(final GeoPackageTable table) {
maxZoomInput.setText(String.valueOf(maxZoomLevel));
BoundingBox boundingBox = contents.getBoundingBox();
- Projection projection = ProjectionFactory.getProjection(
- contents.getSrs().getOrganizationCoordsysId());
+ BoundingBox worldGeodeticBoundingBox = null;
+ if (boundingBox != null) {
+ Projection projection = ProjectionFactory.getProjection(
+ contents.getSrs());
+
+ ProjectionTransform webMercatorTransform = projection.getTransformation(
+ ProjectionConstants.EPSG_WEB_MERCATOR);
+ if (projection.getUnit() instanceof DegreeUnit) {
+ boundingBox = TileBoundingBoxUtils.boundDegreesBoundingBoxWithWebMercatorLimits(boundingBox);
+ }
+ BoundingBox webMercatorBoundingBox = webMercatorTransform.transform(boundingBox);
- ProjectionTransform webMercatorTransform = projection.getTransformation(
- ProjectionConstants.EPSG_WEB_MERCATOR);
- BoundingBox webMercatorBoundingBox = webMercatorTransform.transform(boundingBox);
+ ProjectionTransform worldGeodeticTransform = ProjectionFactory.getProjection(ProjectionConstants.EPSG_WEB_MERCATOR).getTransformation(
+ ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
+ worldGeodeticBoundingBox = worldGeodeticTransform.transform(webMercatorBoundingBox);
+ } else {
+ worldGeodeticBoundingBox = new BoundingBox(-ProjectionConstants.WGS84_HALF_WORLD_LON_WIDTH,
+ ProjectionConstants.WGS84_HALF_WORLD_LON_WIDTH,
+ ProjectionConstants.WEB_MERCATOR_MIN_LAT_RANGE,
+ ProjectionConstants.WEB_MERCATOR_MAX_LAT_RANGE);
+ }
- ProjectionTransform worldGeodeticTransform = ProjectionFactory.getProjection(ProjectionConstants.EPSG_WEB_MERCATOR).getTransformation(
- ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
- BoundingBox worldGeodeticBoundingBox = worldGeodeticTransform.transform(webMercatorBoundingBox);
minLonInput.setText(String.valueOf(worldGeodeticBoundingBox.getMinLongitude()));
minLatInput.setText(String.valueOf(worldGeodeticBoundingBox.getMinLatitude()));
maxLonInput.setText(String.valueOf(worldGeodeticBoundingBox.getMaxLongitude()));
diff --git a/mapcache/src/main/java/mil/nga/mapcache/GeoPackageMapFragment.java b/mapcache/src/main/java/mil/nga/mapcache/GeoPackageMapFragment.java
index 75982b63..ab78a19d 100755
--- a/mapcache/src/main/java/mil/nga/mapcache/GeoPackageMapFragment.java
+++ b/mapcache/src/main/java/mil/nga/mapcache/GeoPackageMapFragment.java
@@ -63,6 +63,8 @@
import com.google.android.gms.maps.model.TileOverlayOptions;
import com.google.android.gms.maps.model.TileProvider;
+import org.osgeo.proj4j.units.DegreeUnit;
+
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -1708,9 +1710,9 @@ private void zoomToActive() {
LatLng topLeft = new LatLng(maxLatitude, bbox.getMinLongitude());
LatLng topRight = new LatLng(maxLatitude, bbox.getMaxLongitude());
- if(lowerLeft.longitude == lowerRight.longitude){
+ if (lowerLeft.longitude == lowerRight.longitude) {
double adjustLongitude = lowerRight.longitude - .0000000000001;
- lowerRight= new LatLng(minLatitude, adjustLongitude);
+ lowerRight = new LatLng(minLatitude, adjustLongitude);
topRight = new LatLng(maxLatitude, adjustLongitude);
}
@@ -1759,16 +1761,23 @@ private void displayFeatures(MapUpdateTask task,
try {
while (!task.isCancelled() && count.get() < maxFeatures
&& cursor.moveToNext()) {
- FeatureRow row = cursor.getRow();
+ try {
+ FeatureRow row = cursor.getRow();
- if (threadPool != null) {
- // Process the feature row in the thread pool
- FeatureRowProcessor processor = new FeatureRowProcessor(
- task, database, featureDao, row, count, maxFeatures, editable);
- threadPool.execute(processor);
- } else {
- processFeatureRow(task, database, featureDao, row, count,
- maxFeatures, editable);
+ if (threadPool != null) {
+ // Process the feature row in the thread pool
+ FeatureRowProcessor processor = new FeatureRowProcessor(
+ task, database, featureDao, row, count, maxFeatures, editable);
+ threadPool.execute(processor);
+ } else {
+ processFeatureRow(task, database, featureDao, row, count,
+ maxFeatures, editable);
+ }
+ } catch (Exception e) {
+ Log.e(GeoPackageMapFragment.class.getSimpleName(),
+ "Failed to display feature. database: " + database
+ + ", feature table: " + features
+ + ", row: " + cursor.getPosition(), e);
}
}
@@ -2303,17 +2312,29 @@ private void displayTiles(TileProvider overlay, Contents contents, int zIndex, B
overlayOptions.tileProvider(overlay);
overlayOptions.zIndex(zIndex);
- ProjectionTransform transformToWebMercator = ProjectionFactory.getProjection(
- contents.getSrs().getOrganizationCoordsysId())
- .getTransformation(
- ProjectionConstants.EPSG_WEB_MERCATOR);
- BoundingBox webMercatorBoundingBox = transformToWebMercator.transform(contents.getBoundingBox());
- ProjectionTransform transform = ProjectionFactory.getProjection(
- ProjectionConstants.EPSG_WEB_MERCATOR)
- .getTransformation(
- ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
- BoundingBox boundingBox = transform
- .transform(webMercatorBoundingBox);
+ BoundingBox boundingBox = contents.getBoundingBox();
+ if (boundingBox != null) {
+ mil.nga.geopackage.projection.Projection projection = ProjectionFactory.getProjection(
+ contents.getSrs());
+ if (projection.getUnit() instanceof DegreeUnit) {
+ boundingBox = TileBoundingBoxUtils.boundDegreesBoundingBoxWithWebMercatorLimits(boundingBox);
+ }
+ ProjectionTransform transformToWebMercator = projection
+ .getTransformation(
+ ProjectionConstants.EPSG_WEB_MERCATOR);
+ BoundingBox webMercatorBoundingBox = transformToWebMercator.transform(boundingBox);
+ ProjectionTransform transform = ProjectionFactory.getProjection(
+ ProjectionConstants.EPSG_WEB_MERCATOR)
+ .getTransformation(
+ ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
+ boundingBox = transform
+ .transform(webMercatorBoundingBox);
+ } else {
+ boundingBox = new BoundingBox(-ProjectionConstants.WGS84_HALF_WORLD_LON_WIDTH,
+ ProjectionConstants.WGS84_HALF_WORLD_LON_WIDTH,
+ ProjectionConstants.WEB_MERCATOR_MIN_LAT_RANGE,
+ ProjectionConstants.WEB_MERCATOR_MAX_LAT_RANGE);
+ }
if (specifiedBoundingBox != null) {
boundingBox = TileBoundingBoxUtils.overlap(boundingBox, specifiedBoundingBox);
diff --git a/mapcache/src/main/java/mil/nga/mapcache/io/MapCacheFileUtils.java b/mapcache/src/main/java/mil/nga/mapcache/io/MapCacheFileUtils.java
index 3990723b..96ce399f 100644
--- a/mapcache/src/main/java/mil/nga/mapcache/io/MapCacheFileUtils.java
+++ b/mapcache/src/main/java/mil/nga/mapcache/io/MapCacheFileUtils.java
@@ -72,6 +72,14 @@ private static String getDisplayName(Context context, Uri uri) {
}
}
+ if (name == null) {
+ name = uri.getPath();
+ int index = name.lastIndexOf('/');
+ if (index != -1) {
+ name = name.substring(index + 1);
+ }
+ }
+
return name;
}