diff --git a/CHANGELOG.md b/CHANGELOG.md index e807d417..c873beff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Adheres to [Semantic Versioning](http://semver.org/). * Ignored internal databases support for non GeoPackages (preconfigured to ignore ue3.db for Google Maps) * Get abstract User DAO by table name * Set User Custom DAO contents +* Feature Tiles geodesic draw support +* Feature Index Manager, RTree Index, Feature Table Index, Feature Indexer, and Manual query geodesic support ## [6.7.3](https://github.com/ngageoint/geopackage-android/releases/tag/6.7.3) (11-30-2023) diff --git a/geopackage-sdk/build.gradle b/geopackage-sdk/build.gradle index 7d10a42a..d98d157f 100644 --- a/geopackage-sdk/build.gradle +++ b/geopackage-sdk/build.gradle @@ -175,6 +175,7 @@ dependencies { api 'ar.com.hjg:pngj:2.1.0' api 'mil.nga:tiff:3.0.0' api 'mil.nga:sqlite-android:3440200' + //noinspection GradleDependency javadocDeps 'com.j256.ormlite:ormlite-android:6.1', 'mil.nga.geopackage:geopackage-core:6.6.7', 'ar.com.hjg:pngj:2.1.0', diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/db/FeatureIndexerTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/db/FeatureIndexerTest.java index f5e4452d..e74e832c 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/db/FeatureIndexerTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/db/FeatureIndexerTest.java @@ -48,12 +48,32 @@ public FeatureIndexerTest() { */ @Test public void testIndexer() throws SQLException { + testIndexer(false); + } + + /** + * Test indexer + * + * @throws java.sql.SQLException + */ + @Test + public void testIndexerGeodesic() throws SQLException { + testIndexer(true); + } + + /** + * Test indexer + * + * @param geodesic index using geodesic bounds + * @throws java.sql.SQLException + */ + private void testIndexer(boolean geodesic) throws SQLException { FeatureDao featureDao = FeatureTileUtils.createFeatureDao(geoPackage); int initialFeatures = FeatureTileUtils.insertFeatures(geoPackage, featureDao); - FeatureIndexer indexer = new FeatureIndexer(activity, featureDao); + FeatureIndexer indexer = new FeatureIndexer(activity, featureDao, geodesic); GeoPackageMetadataDb db = new GeoPackageMetadataDb(activity); db.open(); diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexCreateTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexCreateTest.java index d819b1ca..940dfc91 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexCreateTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexCreateTest.java @@ -28,7 +28,20 @@ public FeatureTableIndexCreateTest() { @Test public void testIndex() throws Exception { - FeatureTableIndexUtils.testIndex(geoPackage); + FeatureTableIndexUtils.testIndex(geoPackage, false); + + } + + /** + * Test index + * + * @throws Exception + * upon error + */ + @Test + public void testIndexGeodesic() throws Exception { + + FeatureTableIndexUtils.testIndex(geoPackage, true); } diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexExternalTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexExternalTest.java index 5110ad3c..3f9275ab 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexExternalTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexExternalTest.java @@ -28,7 +28,20 @@ public FeatureTableIndexExternalTest() { @Test public void testIndex() throws Exception { - FeatureTableIndexUtils.testIndex(geoPackage); + FeatureTableIndexUtils.testIndex(geoPackage, false); + + } + + /** + * Test index + * + * @throws Exception + * upon error + */ + @Test + public void testIndexGeodesic() throws Exception { + + FeatureTableIndexUtils.testIndex(geoPackage, true); } diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexImportTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexImportTest.java index 716446fd..f08d16e4 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexImportTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexImportTest.java @@ -28,7 +28,20 @@ public FeatureTableIndexImportTest() { @Test public void testIndex() throws Exception { - FeatureTableIndexUtils.testIndex(geoPackage); + FeatureTableIndexUtils.testIndex(geoPackage, false); + + } + + /** + * Test index + * + * @throws Exception + * upon error + */ + @Test + public void testIndexGeodesic() throws Exception { + + FeatureTableIndexUtils.testIndex(geoPackage, true); } diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexUtils.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexUtils.java index 1522cd6b..30d1858f 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexUtils.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndexUtils.java @@ -25,6 +25,7 @@ import mil.nga.proj.ProjectionTransform; import mil.nga.sf.GeometryEnvelope; import mil.nga.sf.Point; +import mil.nga.sf.proj.ProjectionGeometryUtils; import mil.nga.sf.util.GeometryEnvelopeBuilder; /** @@ -37,10 +38,11 @@ public class FeatureTableIndexUtils { /** * Test read * - * @param geoPackage + * @param geoPackage GeoPackage + * @param geodesic index using geodesic bounds * @throws Exception */ - public static void testIndex(GeoPackage geoPackage) throws Exception { + public static void testIndex(GeoPackage geoPackage, boolean geodesic) throws Exception { // Test indexing each feature table List featureTables = geoPackage.getFeatureTables(); @@ -48,7 +50,7 @@ public static void testIndex(GeoPackage geoPackage) throws Exception { FeatureDao featureDao = geoPackage.getFeatureDao(featureTable); FeatureTableIndex featureTableIndex = new FeatureTableIndex( - geoPackage, featureDao); + geoPackage, featureDao, geodesic); // Determine how many features have geometry envelopes or geometries int expectedCount = 0; @@ -107,7 +109,8 @@ public static void testIndex(GeoPackage geoPackage) throws Exception { .query(); while (featureTableResults.hasNext()) { GeometryIndex geometryIndex = featureTableResults.next(); - validateGeometryIndex(featureTableIndex, geometryIndex); + validateGeometryIndex(featureTableIndex, geometryIndex, + geodesic); resultCount++; } featureTableResults.close(); @@ -133,7 +136,8 @@ public static void testIndex(GeoPackage geoPackage) throws Exception { featureTableResults = featureTableIndex.query(envelope); while (featureTableResults.hasNext()) { GeometryIndex geometryIndex = featureTableResults.next(); - validateGeometryIndex(featureTableIndex, geometryIndex); + validateGeometryIndex(featureTableIndex, geometryIndex, + geodesic); if (geometryIndex.getGeomId() == testFeatureRow.getId()) { featureFound = true; } @@ -170,7 +174,8 @@ public static void testIndex(GeoPackage geoPackage) throws Exception { transformedBoundingBox, projection); while (featureTableResults.hasNext()) { GeometryIndex geometryIndex = featureTableResults.next(); - validateGeometryIndex(featureTableIndex, geometryIndex); + validateGeometryIndex(featureTableIndex, geometryIndex, + geodesic); if (geometryIndex.getGeomId() == testFeatureRow.getId()) { featureFound = true; } @@ -199,7 +204,8 @@ public static void testIndex(GeoPackage geoPackage) throws Exception { featureTableResults = featureTableIndex.query(envelope); while (featureTableResults.hasNext()) { GeometryIndex geometryIndex = featureTableResults.next(); - validateGeometryIndex(featureTableIndex, geometryIndex); + validateGeometryIndex(featureTableIndex, geometryIndex, + geodesic); if (geometryIndex.getGeomId() == testFeatureRow.getId()) { featureFound = true; } @@ -353,13 +359,18 @@ public static void testDeleteAll(GeoPackage geoPackage) throws SQLException { * @param geometryIndex */ private static void validateGeometryIndex( - FeatureTableIndex featureTableIndex, GeometryIndex geometryIndex) { + FeatureTableIndex featureTableIndex, GeometryIndex geometryIndex, + boolean geodesic) { FeatureRow featureRow = featureTableIndex.getFeatureRow(geometryIndex); TestCase.assertNotNull(featureRow); TestCase.assertEquals(featureTableIndex.getTableName(), geometryIndex.getTableName()); TestCase.assertEquals(geometryIndex.getGeomId(), featureRow.getId()); GeometryEnvelope envelope = featureRow.getGeometryEnvelope(); + if (geodesic) { + envelope = ProjectionGeometryUtils.geodesicEnvelope(envelope, + featureTableIndex.getProjection()); + } TestCase.assertNotNull(envelope); diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionCreateTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionCreateTest.java index 40069694..576616e7 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionCreateTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionCreateTest.java @@ -28,7 +28,20 @@ public RTreeIndexExtensionCreateTest() { @Test public void testRTree() throws SQLException { - RTreeIndexExtensionUtils.testRTree(geoPackage); + RTreeIndexExtensionUtils.testRTree(geoPackage, false); + + } + + /** + * Test RTree with geodesic + * + * @throws SQLException + * upon error + */ + @Test + public void testRTreeGeodesic() throws SQLException { + + RTreeIndexExtensionUtils.testRTree(geoPackage, true); } diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionExternalTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionExternalTest.java index 3e9bb3c8..9d75fc40 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionExternalTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionExternalTest.java @@ -28,7 +28,20 @@ public RTreeIndexExtensionExternalTest() { @Test public void testRTree() throws SQLException { - RTreeIndexExtensionUtils.testRTree(geoPackage); + RTreeIndexExtensionUtils.testRTree(geoPackage, false); + + } + + /** + * Test RTree with geodesic + * + * @throws SQLException + * upon error + */ + @Test + public void testRTreeGeodesic() throws SQLException { + + RTreeIndexExtensionUtils.testRTree(geoPackage, true); } diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionImportTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionImportTest.java index 07cf83ad..95c51a76 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionImportTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionImportTest.java @@ -28,7 +28,20 @@ public RTreeIndexExtensionImportTest() { @Test public void testRTree() throws SQLException { - RTreeIndexExtensionUtils.testRTree(geoPackage); + RTreeIndexExtensionUtils.testRTree(geoPackage, false); + + } + + /** + * Test RTree with geodesic + * + * @throws SQLException + * upon error + */ + @Test + public void testRTreeGeodesic() throws SQLException { + + RTreeIndexExtensionUtils.testRTree(geoPackage, true); } diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionUtils.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionUtils.java index 4514878a..59558d99 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionUtils.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtensionUtils.java @@ -29,11 +29,13 @@ public class RTreeIndexExtensionUtils { * Test RTree * * @param geoPackage GeoPackage + * @param geodesic index using geodesic bounds * @throws SQLException upon error */ - public static void testRTree(GeoPackage geoPackage) throws SQLException { + public static void testRTree(GeoPackage geoPackage, boolean geodesic) throws SQLException { - RTreeIndexExtension extension = new RTreeIndexExtension(geoPackage); + RTreeIndexExtension extension = new RTreeIndexExtension(geoPackage, + geodesic); List featureTables = geoPackage.getFeatureTables(); for (String featureTable : featureTables) { diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/features/OAPIFeatureGeneratorTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/features/OAPIFeatureGeneratorTest.java index bf72fb2f..2e3df8d8 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/features/OAPIFeatureGeneratorTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/features/OAPIFeatureGeneratorTest.java @@ -40,7 +40,7 @@ public void testOpenData1h() throws SQLException { } /** - * Test flurstueck + * Test lakes * * @throws SQLException upon failure */ @@ -82,7 +82,7 @@ public void testRakennus() throws SQLException { } /** - * Test mage + * Test MAGE * * @throws SQLException upon failure */ diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileGeneratorTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileGeneratorTest.java index 2b8a12ae..7643b0fe 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileGeneratorTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileGeneratorTest.java @@ -44,7 +44,7 @@ public FeatureTileGeneratorTest() { */ @Test public void testTileGenerator() throws IOException, SQLException { - testTileGenerator(false, false, false); + testTileGenerator(false, false, false, false); } /** @@ -55,7 +55,7 @@ public void testTileGenerator() throws IOException, SQLException { */ @Test public void testTileGeneratorWithIndex() throws IOException, SQLException { - testTileGenerator(true, false, false); + testTileGenerator(true, false, false, false); } /** @@ -66,7 +66,7 @@ public void testTileGeneratorWithIndex() throws IOException, SQLException { */ @Test public void testTileGeneratorWithIcon() throws IOException, SQLException { - testTileGenerator(false, true, false); + testTileGenerator(false, true, false, false); } /** @@ -78,7 +78,19 @@ public void testTileGeneratorWithIcon() throws IOException, SQLException { @Test public void testTileGeneratorWithMaxFeatures() throws IOException, SQLException { - testTileGenerator(false, false, true); + testTileGenerator(false, false, true, false); + } + + /** + * Test tile generator + * + * @throws java.io.IOException + * @throws java.sql.SQLException + */ + @Test + public void testTileGeneratorWithGeodesic() + throws IOException, SQLException { + testTileGenerator(false, false, false, true); } /** @@ -90,7 +102,19 @@ public void testTileGeneratorWithMaxFeatures() throws IOException, @Test public void testTileGeneratorWithIndexAndIcon() throws IOException, SQLException { - testTileGenerator(true, true, false); + testTileGenerator(true, true, false, false); + } + + /** + * Test tile generator + * + * @throws java.io.IOException + * @throws java.sql.SQLException + */ + @Test + public void testTileGeneratorWithIndexAndIconAndGeodesic() + throws IOException, SQLException { + testTileGenerator(true, true, false, true); } /** @@ -102,20 +126,34 @@ public void testTileGeneratorWithIndexAndIcon() throws IOException, @Test public void testTileGeneratorWithIndexAndIconAndMaxFeatures() throws IOException, SQLException { - testTileGenerator(true, true, true); + testTileGenerator(true, true, true, false); } /** * Test tile generator * - * @param index - * @param useIcon - * @param maxFeatures * @throws java.io.IOException * @throws java.sql.SQLException */ + @Test + public void testTileGeneratorWithIndexAndIconAndMaxFeaturesAndGeodesic() + throws IOException, SQLException { + testTileGenerator(true, true, true, true); + } + + /** + * Test tile generator + * + * @param index index features + * @param useIcon true to use an icon instead of the default point + * @param maxFeatures set max features + * @param geodesic draw geometries using geodesic lines + * @throws java.io.IOException upon error + * @throws java.sql.SQLException upon error + */ public void testTileGenerator(boolean index, boolean useIcon, - boolean maxFeatures) throws IOException, SQLException { + boolean maxFeatures, boolean geodesic) + throws IOException, SQLException { int minZoom = 0; int maxZoom = 4; @@ -125,11 +163,12 @@ public void testTileGenerator(boolean index, boolean useIcon, int num = FeatureTileUtils.insertFeatures(geoPackage, featureDao); FeatureTiles featureTiles = FeatureTileUtils.createFeatureTiles( - activity, geoPackage, featureDao, useIcon); + activity, geoPackage, featureDao, useIcon, geodesic); try { if (index) { - FeatureIndexManager indexManager = new FeatureIndexManager(activity, geoPackage, featureDao); + FeatureIndexManager indexManager = new FeatureIndexManager( + activity, geoPackage, featureDao, geodesic); featureTiles.setIndexManager(indexManager); indexManager.setIndexLocation(FeatureIndexType.GEOPACKAGE); int indexed = indexManager.index(); diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileUtils.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileUtils.java index 92df5bf8..8f2e0c6d 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileUtils.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTileUtils.java @@ -94,9 +94,12 @@ public static int insertFeatures(GeoPackage geoPackage, FeatureDao featureDao) t * * @return */ - public static FeatureTiles createFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, boolean useIcon) { + public static FeatureTiles createFeatureTiles(Context context, GeoPackage geoPackage, + FeatureDao featureDao, boolean useIcon, + boolean geodesic) { - FeatureTiles featureTiles = new DefaultFeatureTiles(context, featureDao, context.getResources().getDisplayMetrics().density); + FeatureTiles featureTiles = new DefaultFeatureTiles(context, featureDao, + context.getResources().getDisplayMetrics().density, geodesic); Paint pointPaint = featureTiles.getPointPaint(); if (useIcon) { diff --git a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTilesTest.java b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTilesTest.java index 7d3af659..3b16bac2 100644 --- a/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTilesTest.java +++ b/geopackage-sdk/src/androidTest/java/mil/nga/geopackage/tiles/features/FeatureTilesTest.java @@ -37,7 +37,17 @@ public FeatureTilesTest() { */ @Test public void testFeatureTiles() throws SQLException { - testFeatureTiles(false); + testFeatureTiles(false, false); + } + + /** + * Test feature tiles + * + * @throws java.sql.SQLException + */ + @Test + public void testFeatureTilesWithGeodesic() throws SQLException { + testFeatureTiles(false, true); } /** @@ -47,31 +57,45 @@ public void testFeatureTiles() throws SQLException { */ @Test public void testFeatureTilesWithIcon() throws SQLException { - testFeatureTiles(true); + testFeatureTiles(true, false); + } + + /** + * Test feature tiles + * + * @throws java.sql.SQLException + */ + @Test + public void testFeatureTilesWithIconGeodesic() throws SQLException { + testFeatureTiles(true, true); } /** * Test feature tiles * + * @param useIcon true to use an icon instead of the default point + * @param geodesic draw geometries using geodesic lines * @throws java.sql.SQLException */ - public void testFeatureTiles(boolean useIcon) throws SQLException { + public void testFeatureTiles(boolean useIcon, boolean geodesic) throws SQLException { FeatureDao featureDao = FeatureTileUtils.createFeatureDao(geoPackage); int num = FeatureTileUtils.insertFeatures(geoPackage, featureDao); - FeatureTiles featureTiles = FeatureTileUtils.createFeatureTiles(activity, geoPackage, featureDao, useIcon); + FeatureTiles featureTiles = FeatureTileUtils + .createFeatureTiles(activity, geoPackage, featureDao, useIcon, geodesic); try { - FeatureIndexer indexer = new FeatureIndexer(activity, featureDao); + FeatureIndexer indexer = new FeatureIndexer(activity, featureDao, geodesic); try { indexer.index(); } finally { indexer.close(); } - FeatureIndexManager indexManager = new FeatureIndexManager(activity, geoPackage, featureDao); + FeatureIndexManager indexManager = new FeatureIndexManager(activity, + geoPackage, featureDao, geodesic); featureTiles.setIndexManager(indexManager); indexManager.setIndexLocation(FeatureIndexType.GEOPACKAGE); diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/db/FeatureIndexer.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/db/FeatureIndexer.java index 5304bb66..c8a0b3dd 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/db/FeatureIndexer.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/db/FeatureIndexer.java @@ -74,11 +74,23 @@ public class FeatureIndexer { * @param featureDao feature dao */ public FeatureIndexer(Context context, FeatureDao featureDao) { + this(context, featureDao, false); + } + + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param geodesic index using geodesic bounds + * @since 6.7.4 + */ + public FeatureIndexer(Context context, FeatureDao featureDao, boolean geodesic) { this.context = context; this.featureDao = featureDao; db = new GeoPackageMetadataDb(context); db.open(); - geometryMetadataDataSource = new GeometryMetadataDataSource(db); + geometryMetadataDataSource = new GeometryMetadataDataSource(db, geodesic, featureDao.getProjection()); } /** @@ -129,6 +141,27 @@ public void setChunkLimit(int chunkLimit) { this.chunkLimit = chunkLimit; } + /** + * Geometries indexed using geodesic lines + * + * @return geodesic flag + * @since 6.7.4 + */ + public boolean isGeodesic() { + return geometryMetadataDataSource.isGeodesic(); + } + + /** + * Set the geodestic flag, true to index geodesic geometries + * + * @param geodesic + * index geodesic geometries flag + * @since 6.7.4 + */ + public void setGeodesic(boolean geodesic) { + geometryMetadataDataSource.setGeodesic(geodesic); + } + /** * Index the feature table if needed * diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/db/metadata/GeometryMetadataDataSource.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/db/metadata/GeometryMetadataDataSource.java index ae0eb4c8..3dd3ad7d 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/db/metadata/GeometryMetadataDataSource.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/db/metadata/GeometryMetadataDataSource.java @@ -7,7 +7,9 @@ import mil.nga.geopackage.BoundingBox; import mil.nga.geopackage.GeoPackageException; import mil.nga.geopackage.db.GeoPackageDatabase; +import mil.nga.proj.Projection; import mil.nga.sf.GeometryEnvelope; +import mil.nga.sf.proj.ProjectionGeometryUtils; /** * Table metadata Data Source @@ -25,6 +27,15 @@ public class GeometryMetadataDataSource { * Query range tolerance */ protected double tolerance = .00000000000001; + /** + * Index geometries using geodesic lines + */ + private boolean geodesic = false; + + /** + * Features projection + */ + private Projection projection; /** * Constructor @@ -35,6 +46,20 @@ public GeometryMetadataDataSource(GeoPackageMetadataDb db) { this.db = db.getDb(); } + /** + * Constructor + * + * @param db metadata db + * @param geodesic index geodesic geometries flag + * @param projection feature projection + * @since 6.7.4 + */ + public GeometryMetadataDataSource(GeoPackageMetadataDb db, boolean geodesic, Projection projection) { + this(db); + this.geodesic = geodesic; + this.projection = projection; + } + /** * Constructor * @@ -62,6 +87,45 @@ public void setTolerance(double tolerance) { this.tolerance = tolerance; } + /** + * Geometries indexed using geodesic lines + * + * @return geodesic flag + * @since 6.7.4 + */ + public boolean isGeodesic() { + return geodesic; + } + + /** + * Set the geodestic flag, true to index geodesic geometries + * + * @param geodesic + * index geodesic geometries flag + * @since 6.7.4 + */ + public void setGeodesic(boolean geodesic) { + this.geodesic = geodesic; + } + + /** + * Get the feature projection + * @return projection + * @since 6.7.4 + */ + public Projection getProjection(){ + return projection; + } + + /** + * Set the feature projection + * @param projection projection + * @since 6.7.4 + */ + public void setProjection(Projection projection){ + this.projection = projection; + } + /** * Create a new geometry metadata * @@ -816,6 +880,11 @@ public String[] querySQLArgs(GeometryEnvelope envelope, long geoPackageId, Strin args += 2; } + if (geodesic) { + envelope = ProjectionGeometryUtils.geodesicEnvelope( + envelope, projection); + } + double minX = envelope.getMinX() - tolerance; double maxX = envelope.getMaxX() + tolerance; double minY = envelope.getMinY() - tolerance; diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndex.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndex.java index 55bc3e11..1d5eb3c1 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndex.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/nga/index/FeatureTableIndex.java @@ -50,8 +50,21 @@ public class FeatureTableIndex extends FeatureTableCoreIndex { * @param featureDao feature dao */ public FeatureTableIndex(GeoPackage geoPackage, FeatureDao featureDao) { + this(geoPackage, featureDao, false); + } + + /** + * Constructor + * + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param geodesic index using geodesic bounds + * @since 6.7.4 + */ + public FeatureTableIndex(GeoPackage geoPackage, FeatureDao featureDao, + boolean geodesic) { super(geoPackage, featureDao.getTableName(), featureDao - .getGeometryColumnName()); + .getGeometryColumnName(), geodesic); this.featureDao = featureDao; } diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtension.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtension.java index f90e92bd..25183b07 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtension.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/extension/rtree/RTreeIndexExtension.java @@ -36,7 +36,18 @@ public class RTreeIndexExtension extends RTreeIndexCoreExtension { * @param geoPackage GeoPackage */ public RTreeIndexExtension(GeoPackage geoPackage) { - super(geoPackage); + this(geoPackage, false); + } + + /** + * Constructor + * + * @param geoPackage GeoPackage + * @param geodesic index using geodesic bounds + * @since 6.7.4 + */ + public RTreeIndexExtension(GeoPackage geoPackage, boolean geodesic) { + super(geoPackage, geodesic); connection = geoPackage.getConnection(); database = connection.getDb().copy(); } @@ -122,6 +133,10 @@ public Object execute(GeoPackageGeometryData data) { Object value = null; GeometryEnvelope envelope = getEnvelope(data); if (envelope != null) { + int srsId = data.getSrsId(); + if (srsId > 0) { + envelope = geodesicEnvelope(envelope, srsId); + } value = envelope.getMinY(); } return value; @@ -140,6 +155,10 @@ public Object execute(GeoPackageGeometryData data) { Object value = null; GeometryEnvelope envelope = getEnvelope(data); if (envelope != null) { + int srsId = data.getSrsId(); + if (srsId > 0) { + envelope = geodesicEnvelope(envelope, srsId); + } value = envelope.getMaxY(); } return value; diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/features/index/FeatureIndexManager.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/features/index/FeatureIndexManager.java index 85938835..8c4633e3 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/features/index/FeatureIndexManager.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/features/index/FeatureIndexManager.java @@ -82,6 +82,11 @@ public class FeatureIndexManager { */ private boolean continueOnError = true; + /** + * Index geometries using geodesic lines + */ + private boolean geodesic = false; + /** * Constructor * @@ -102,16 +107,48 @@ public FeatureIndexManager(Context context, GeoPackage geoPackage, String featur * @param featureDao feature DAO */ public FeatureIndexManager(Context context, GeoPackage geoPackage, FeatureDao featureDao) { + this(context, geoPackage, featureDao, false); + } + + /** + * Constructor + * + * @param context context + * @param geoPackage GeoPackage + * @param featureTable feature table + * @param geodesic index using geodesic bounds + * @since 6.7.4 + */ + public FeatureIndexManager(Context context, GeoPackage geoPackage, String featureTable, + boolean geodesic) { + this(context, geoPackage, geoPackage.getFeatureDao(featureTable), geodesic); + } + + /** + * Constructor + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature DAO + * @param geodesic index using geodesic bounds + * @since 6.7.4 + */ + public FeatureIndexManager(Context context, GeoPackage geoPackage, FeatureDao featureDao, + boolean geodesic) { this.featureDao = featureDao; - featureTableIndex = new FeatureTableIndex(geoPackage, featureDao.copy()); + this.geodesic = geodesic; + featureTableIndex = new FeatureTableIndex(geoPackage, featureDao.copy(), + geodesic); if (context != null) { - featureIndexer = new FeatureIndexer(context, featureDao.copy()); + featureIndexer = new FeatureIndexer(context, featureDao.copy(), + geodesic); } else { featureIndexer = null; } - RTreeIndexExtension rTreeExtension = new RTreeIndexExtension(geoPackage); + RTreeIndexExtension rTreeExtension = new RTreeIndexExtension(geoPackage, + geodesic); rTreeIndexTableDao = rTreeExtension.getTableDao(featureDao.copy()); - manualFeatureQuery = new ManualFeatureQuery(featureDao.copy()); + manualFeatureQuery = new ManualFeatureQuery(featureDao.copy(), geodesic); // Set the default indexed check and query order indexLocationQueryOrder.add(FeatureIndexType.RTREE); @@ -209,6 +246,33 @@ public void setContinueOnError(boolean continueOnError) { this.continueOnError = continueOnError; } + /** + * Geometries indexed using geodesic lines + * + * @return geodesic flag + * @since 6.7.4 + */ + public boolean isGeodesic() { + return geodesic; + } + + /** + * Set the geodestic flag, true to index geodesic geometries + * + * @param geodesic + * index geodesic geometries flag + * @since 6.7.4 + */ + public void setGeodesic(boolean geodesic) { + this.geodesic = geodesic; + featureTableIndex.setGeodesic(geodesic); + if (featureIndexer != null) { + featureIndexer.setGeodesic(geodesic); + } + rTreeIndexTableDao.getRTreeIndexExtension().setGeodesic(geodesic); + manualFeatureQuery.setGeodesic(geodesic); + } + /** * Prioritize the query location order. All types are placed at the front of the query order * in the order they are given. Omitting a location leaves it at it's current priority location. diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/features/user/ManualFeatureQuery.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/features/user/ManualFeatureQuery.java index 4c36f8e5..ddbff5c9 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/features/user/ManualFeatureQuery.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/features/user/ManualFeatureQuery.java @@ -10,6 +10,7 @@ import mil.nga.proj.Projection; import mil.nga.proj.ProjectionTransform; import mil.nga.sf.GeometryEnvelope; +import mil.nga.sf.proj.ProjectionGeometryUtils; /** * Performs manual brute force queries against feature rows. See @@ -35,13 +36,30 @@ public class ManualFeatureQuery { */ protected double tolerance = .00000000000001; + /** + * Index geometries using geodesic lines + */ + private boolean geodesic = false; + /** * Constructor * * @param featureDao feature DAO */ public ManualFeatureQuery(FeatureDao featureDao) { + this(featureDao, false); + } + + /** + * Constructor + * + * @param featureDao feature DAO + * @param geodesic index using geodesic bounds + * @since 6.7.4 + */ + public ManualFeatureQuery(FeatureDao featureDao, boolean geodesic) { this.featureDao = featureDao; + this.geodesic = geodesic; } /** @@ -89,6 +107,27 @@ public void setTolerance(double tolerance) { this.tolerance = tolerance; } + /** + * Geometries indexed using geodesic lines + * + * @return geodesic flag + * @since 6.7.4 + */ + public boolean isGeodesic() { + return geodesic; + } + + /** + * Set the geodestic flag, true to index geodesic geometries + * + * @param geodesic + * index geodesic geometries flag + * @since 6.7.4 + */ + public void setGeodesic(boolean geodesic) { + this.geodesic = geodesic; + } + /** * Query for features * @@ -479,6 +518,12 @@ public BoundingBox getBoundingBox() { .getGeometryEnvelope(); if (featureEnvelope != null) { + if (geodesic) { + featureEnvelope = ProjectionGeometryUtils + .geodesicEnvelope(featureEnvelope, + featureDao.getProjection()); + } + if (envelope == null) { envelope = featureEnvelope; } else { @@ -1763,6 +1808,11 @@ public ManualFeatureQueryResults query(boolean distinct, String[] columns, .getGeometryEnvelope(); if (envelope != null) { + if (geodesic) { + envelope = ProjectionGeometryUtils.geodesicEnvelope( + envelope, featureDao.getProjection()); + } + double minXMax = Math.max(minX, envelope.getMinX()); double maxXMin = Math.min(maxX, envelope.getMaxX()); double minYMax = Math.max(minY, envelope.getMinY()); @@ -2898,6 +2948,11 @@ public ManualFeatureQueryResults queryForChunk(boolean distinct, .getGeometryEnvelope(); if (envelope != null) { + if (geodesic) { + envelope = ProjectionGeometryUtils.geodesicEnvelope( + envelope, featureDao.getProjection()); + } + double minXMax = Math.max(minX, envelope.getMinX()); double maxXMin = Math.min(maxX, envelope.getMaxX()); double minYMax = Math.max(minY, envelope.getMinY()); diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/DefaultFeatureTiles.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/DefaultFeatureTiles.java index a6feb170..9d93bfac 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/DefaultFeatureTiles.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/DefaultFeatureTiles.java @@ -73,6 +73,18 @@ public DefaultFeatureTiles(Context context, FeatureDao featureDao) { super(context, featureDao); } + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, FeatureDao featureDao, boolean geodesic) { + super(context, featureDao, geodesic); + } + /** * Constructor * @@ -85,6 +97,20 @@ public DefaultFeatureTiles(Context context, FeatureDao featureDao, float density super(context, featureDao, density); } + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param density display density: {@link android.util.DisplayMetrics#density} + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, FeatureDao featureDao, float density, + boolean geodesic) { + super(context, featureDao, density, geodesic); + } + /** * Constructor * @@ -98,6 +124,21 @@ public DefaultFeatureTiles(Context context, FeatureDao featureDao, int width, in super(context, featureDao, width, height); } + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param width drawn tile width + * @param height drawn tile height + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, FeatureDao featureDao, int width, int height, + boolean geodesic) { + super(context, featureDao, width, height, geodesic); + } + /** * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables * @@ -110,6 +151,20 @@ public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao fe super(context, geoPackage, featureDao); } + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + boolean geodesic) { + super(context, geoPackage, featureDao, geodesic); + } + /** * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables * @@ -119,10 +174,26 @@ public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao fe * @param density display density: {@link android.util.DisplayMetrics#density} * @since 3.2.0 */ - public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, float density) { + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + float density) { super(context, geoPackage, featureDao, density); } + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param density display density: {@link android.util.DisplayMetrics#density} + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + float density, boolean geodesic) { + super(context, geoPackage, featureDao, density, geodesic); + } + /** * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables * @@ -133,10 +204,27 @@ public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao fe * @param height drawn tile height * @since 3.2.0 */ - public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, int width, int height) { + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + int width, int height) { super(context, geoPackage, featureDao, width, height); } + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param width drawn tile width + * @param height drawn tile height + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + int width, int height, boolean geodesic) { + super(context, geoPackage, featureDao, width, height, geodesic); + } + /** * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables * @@ -148,10 +236,28 @@ public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao fe * @param height drawn tile height * @since 3.2.0 */ - public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, float density, int width, int height) { + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + float density, int width, int height) { super(context, geoPackage, featureDao, density, width, height); } + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param density display density: {@link android.util.DisplayMetrics#density} + * @param width drawn tile width + * @param height drawn tile height + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public DefaultFeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + float density, int width, int height, boolean geodesic) { + super(context, geoPackage, featureDao, density, width, height, geodesic); + } + /** * Constructor, only for retrieving default feature attributes * @@ -522,6 +628,9 @@ private void addLineString(double simplifyTolerance, BoundingBox boundingBox, Ge // Try to simplify the number of points in the LineString points = simplifyPoints(simplifyTolerance, points); + // Create a geodesic path of points if needed + points = geodesicPath(simplifyTolerance, points); + for (int i = 0; i < points.size(); i++) { Point point = points.get(i); Point webMercatorPoint = transform.transform(point); @@ -583,6 +692,9 @@ private void addRing(double simplifyTolerance, BoundingBox boundingBox, Geometry // Try to simplify the number of points in the LineString points = simplifyPoints(simplifyTolerance, points); + // Create a geodesic path of points if needed + points = geodesicPath(simplifyTolerance, points); + for (int i = 0; i < points.size(); i++) { Point point = points.get(i); Point webMercatorPoint = transform.transform(point); diff --git a/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/FeatureTiles.java b/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/FeatureTiles.java index 37e04f71..b1dd99af 100644 --- a/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/FeatureTiles.java +++ b/geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/features/FeatureTiles.java @@ -44,6 +44,7 @@ import mil.nga.sf.GeometryType; import mil.nga.sf.Point; import mil.nga.sf.proj.GeometryTransform; +import mil.nga.sf.proj.ProjectionGeometryUtils; import mil.nga.sf.util.GeometryUtils; /** @@ -196,6 +197,11 @@ public abstract class FeatureTiles { */ protected boolean simplifyGeometries = true; + /** + * Draw geometries using geodesic lines + */ + protected boolean geodesic = false; + /** * Tile density based upon the device-independent pixels {@link TileUtils#TILE_DP} */ @@ -208,7 +214,19 @@ public abstract class FeatureTiles { * @param featureDao feature dao */ public FeatureTiles(Context context, FeatureDao featureDao) { - this(context, null, featureDao); + this(context, featureDao, false); + } + + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, FeatureDao featureDao, boolean geodesic) { + this(context, null, featureDao, geodesic); } /** @@ -220,7 +238,20 @@ public FeatureTiles(Context context, FeatureDao featureDao) { * @since 3.2.0 */ public FeatureTiles(Context context, FeatureDao featureDao, float density) { - this(context, null, featureDao, density); + this(context, featureDao, density, false); + } + + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param density display density: {@link android.util.DisplayMetrics#density} + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, FeatureDao featureDao, float density, boolean geodesic) { + this(context, null, featureDao, density, geodesic); } /** @@ -233,7 +264,22 @@ public FeatureTiles(Context context, FeatureDao featureDao, float density) { * @since 3.2.0 */ public FeatureTiles(Context context, FeatureDao featureDao, int width, int height) { - this(context, null, featureDao, width, height); + this(context, featureDao, width, height, false); + } + + /** + * Constructor + * + * @param context context + * @param featureDao feature dao + * @param width drawn tile width + * @param height drawn tile height + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, FeatureDao featureDao, int width, int height, + boolean geodesic) { + this(context, null, featureDao, width, height, geodesic); } /** @@ -245,7 +291,21 @@ public FeatureTiles(Context context, FeatureDao featureDao, int width, int heigh * @since 3.2.0 */ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao) { - this(context, geoPackage, featureDao, TileUtils.TILE_PIXELS_HIGH, TileUtils.TILE_PIXELS_HIGH); + this(context, geoPackage, featureDao, false); + } + + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + boolean geodesic) { + this(context, geoPackage, featureDao, TileUtils.TILE_PIXELS_HIGH, TileUtils.TILE_PIXELS_HIGH, geodesic); } /** @@ -258,7 +318,23 @@ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDa * @since 3.2.0 */ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, float density) { - this(context, geoPackage, featureDao, density, TileUtils.tileLength(density), TileUtils.tileLength(density)); + this(context, geoPackage, featureDao, density, false); + } + + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param density display density: {@link android.util.DisplayMetrics#density} + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + float density, boolean geodesic) { + this(context, geoPackage, featureDao, density, TileUtils.tileLength(density), + TileUtils.tileLength(density), geodesic); } /** @@ -272,7 +348,23 @@ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDa * @since 3.2.0 */ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, int width, int height) { - this(context, geoPackage, featureDao, TileUtils.density(width, height), width, height); + this(context, geoPackage, featureDao, width, height, false); + } + + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param width drawn tile width + * @param height drawn tile height + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, int width, + int height, boolean geodesic) { + this(context, geoPackage, featureDao, TileUtils.density(width, height), width, height, geodesic); } /** @@ -287,6 +379,23 @@ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDa * @since 3.2.0 */ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, float density, int width, int height) { + this(context, geoPackage, featureDao, density, width, height, false); + } + + /** + * Constructor, auto creates the index manager for indexed tables and feature styles for styled tables + * + * @param context context + * @param geoPackage GeoPackage + * @param featureDao feature dao + * @param density display density: {@link android.util.DisplayMetrics#density} + * @param width drawn tile width + * @param height drawn tile height + * @param geodesic draw geometries using geodesic lines + * @since 6.7.4 + */ + public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDao, + float density, int width, int height, boolean geodesic) { this.context = context; this.featureDao = featureDao; @@ -299,6 +408,8 @@ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDa tileWidth = width; tileHeight = height; + this.geodesic = geodesic; + createEmptyImage(); compressFormat = CompressFormat.valueOf(context.getString(R.string.feature_tiles_compress_format)); @@ -324,7 +435,7 @@ public FeatureTiles(Context context, GeoPackage geoPackage, FeatureDao featureDa if (geoPackage != null) { - indexManager = new FeatureIndexManager(context, geoPackage, featureDao); + indexManager = new FeatureIndexManager(context, geoPackage, featureDao, geodesic); if (!indexManager.isIndexed()) { indexManager.close(); indexManager = null; @@ -1035,6 +1146,27 @@ public void setSimplifyGeometries(boolean simplifyGeometries) { this.simplifyGeometries = simplifyGeometries; } + /** + * Are geometries drawn using geodesic lines? Default is false + * + * @return geodesic flag + * @since 6.7.4 + */ + public boolean isGeodesic() { + return geodesic; + } + + /** + * Set the geodestic flag, true to draw geodesic geometries + * + * @param geodesic + * draw geodesic geometries flag + * @since 6.7.4 + */ + public void setGeodesic(boolean geodesic) { + this.geodesic = geodesic; + } + /** * Draw the tile and get the bytes from the x, y, and zoom level * @@ -1405,6 +1537,27 @@ protected List simplifyPoints(double simplifyTolerance, return simplifiedPoints; } + /** + * When geodesic is enabled, create a geodesic path of points + * + * @param maxDistance + * max distance allowed between path points + * @param points + * ordered points + * @return geodesic path points + * @since 6.7.4 + */ + protected List geodesicPath(double maxDistance, List points) { + + List geodesicPath = points; + if (geodesic) { + geodesicPath = ProjectionGeometryUtils.geodesicPath(points, + maxDistance, projection); + } + + return geodesicPath; + } + /** * Get the feature style for the feature row and geometry type *