Coder Social home page Coder Social logo

ngageoint / geopackage-android Goto Github PK

View Code? Open in Web Editor NEW
92.0 26.0 31.0 37.08 MB

GeoPackage Android Library

Home Page: http://ngageoint.github.io/geopackage-android

License: MIT License

Java 100.00%
geopackage-android geopackage-libraries geopackage-mapcache geopackage-functionality nga android android-sdk android-library geopackage geopackage-tiles

geopackage-android's Introduction

GeoPackage Android

GeoPackage Android Lib

The GeoPackage Libraries were developed at the National Geospatial-Intelligence Agency (NGA) in collaboration with BIT Systems. The government has "unlimited rights" and is releasing this software to increase the impact of government investments by providing developers with the opportunity to take things in new directions. The software use, modification, and distribution rights are stipulated within the MIT license.

Pull Requests

If you'd like to contribute to this project, please make a pull request. We'll review the pull request and discuss the changes. All pull request contributions to this project will be released under the MIT license.

Software source code previously released under an open source license and then modified by NGA staff is considered a "joint work" (see 17 USC § 101); it is partially copyrighted, partially public domain, and as a whole is protected by the copyrights of the non-government authors and must be released according to the terms of the original open source license.

About

GeoPackage Android is a GeoPackage Library SDK implementation of the Open Geospatial Consortium GeoPackage spec. It is listed as an OGC GeoPackage Implementation by the National Geospatial-Intelligence Agency.

The GeoPackage SDK provides the ability to manage GeoPackage files providing read, write, import, export, share, and open support. Open GeoPackage files provide read and write access to features and tiles. Feature support includes Well-Known Binary translations. Tile generation supports creation by URL or features.

Usage

View the latest Javadoc

Implementations

GeoPackage Android Map

The GeoPackage Android Map SDK adds Android Map implementations to this base library.

GeoPackage MapCache

The GeoPackage MapCache app provides an extensive standalone example on how to use both this and the GeoPackage Android Map SDKs.

MAGE

The Mobile Awareness GEOINT Environment (MAGE) app provides mobile situational awareness capabilities. It uses the SDK to provide GeoPackage functionality.

Example

// Context context = ...;
// File geoPackageFile = ...;

// Get a manager
GeoPackageManager manager = GeoPackageFactory.getManager(context);

// Import database
boolean imported = manager.importGeoPackage(geoPackageFile);

// Available databases
List<String> databases = manager.databases();

// Open database
GeoPackage geoPackage = manager.open(name);

// GeoPackage Table DAOs
SpatialReferenceSystemDao srsDao = geoPackage.getSpatialReferenceSystemDao();
ContentsDao contentsDao = geoPackage.getContentsDao();
GeometryColumnsDao geomColumnsDao = geoPackage.getGeometryColumnsDao();
TileMatrixSetDao tileMatrixSetDao = geoPackage.getTileMatrixSetDao();
TileMatrixDao tileMatrixDao = geoPackage.getTileMatrixDao();
SchemaExtension schemaExtension = new SchemaExtension(geoPackage);
DataColumnsDao dataColumnsDao = schemaExtension.getDataColumnsDao();
DataColumnConstraintsDao dataColumnConstraintsDao = schemaExtension
        .getDataColumnConstraintsDao();
MetadataExtension metadataExtension = new MetadataExtension(geoPackage);
MetadataDao metadataDao = metadataExtension.getMetadataDao();
MetadataReferenceDao metadataReferenceDao = metadataExtension
        .getMetadataReferenceDao();
ExtensionsDao extensionsDao = geoPackage.getExtensionsDao();

// Feature and tile tables
List<String> features = geoPackage.getFeatureTables();
List<String> tiles = geoPackage.getTileTables();

// Query Features
String featureTable = features.get(0);
FeatureDao featureDao = geoPackage.getFeatureDao(featureTable);
FeatureCursor featureCursor = featureDao.queryForAll();
try {
    for (FeatureRow featureRow : featureCursor) {
        GeoPackageGeometryData geometryData = featureRow.getGeometry();
        if (geometryData != null && !geometryData.isEmpty()) {
            Geometry geometry = geometryData.getGeometry();
            // ...
        }
    }
} finally {
    featureCursor.close();
}

// Query Tiles
String tileTable = tiles.get(0);
TileDao tileDao = geoPackage.getTileDao(tileTable);
TileCursor tileCursor = tileDao.queryForAll();
try {
    for (TileRow tileRow : tileCursor) {
        byte[] tileBytes = tileRow.getTileData();
        Bitmap tileBitmap = tileRow.getTileDataBitmap();
        // ...
    }
} finally {
    tileCursor.close();
}

// Retrieve Tiles by XYZ
GeoPackageTileRetriever retriever = new GeoPackageTileRetriever(tileDao);
GeoPackageTile geoPackageTile = retriever.getTile(2, 2, 2);
if (geoPackageTile != null) {
    byte[] tileBytes = geoPackageTile.getData();
    Bitmap tileBitmap = geoPackageTile.getBitmap();
    // ...
}

// Retrieve Tiles by Bounding Box
TileCreator tileCreator = new TileCreator(
        tileDao, ProjectionFactory.getProjection(ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM));
GeoPackageTile geoPackageTile2 = tileCreator.getTile(
        new BoundingBox(-90.0, 0.0, 0.0, 66.513260));
if (geoPackageTile2 != null) {
    byte[] tileBytes = geoPackageTile2.getData();
    Bitmap tileBitmap = geoPackageTile2.getBitmap();
    // ...
}

BoundingBox boundingBox = BoundingBox.worldWebMercator();
Projection projection = ProjectionFactory
        .getProjection(ProjectionConstants.EPSG_WEB_MERCATOR);

// Index Features
FeatureIndexManager indexer = new FeatureIndexManager(context, geoPackage, featureDao, false);
indexer.setIndexLocation(FeatureIndexType.GEOPACKAGE);
int indexedCount = indexer.index();

// Query Indexed Features in paginated chunks
FeatureIndexResults indexResults = indexer.queryForChunk(boundingBox,
        projection, 50);
FeaturePaginatedCursor paginatedCursor = indexer
        .paginate(indexResults);
for (FeatureRow featureRow : paginatedCursor) {
    GeoPackageGeometryData geometryData = featureRow.getGeometry();
    if (geometryData != null && !geometryData.isEmpty()) {
        Geometry geometry = geometryData.getGeometry();
        // ...
    }
}

// Draw tiles from features
FeatureTiles featureTiles = new DefaultFeatureTiles(context, featureDao, context.getResources().getDisplayMetrics().density, false);
featureTiles.setMaxFeaturesPerTile(1000); // Set max features to draw per tile
NumberFeaturesTile numberFeaturesTile = new NumberFeaturesTile(context); // Custom feature tile implementation
featureTiles.setMaxFeaturesTileDraw(numberFeaturesTile); // Draw feature count tiles when max features passed
featureTiles.setIndexManager(indexer); // Set index manager to query feature indices
Bitmap tile = featureTiles.drawTile(2, 2, 2);

// URL Tile Generator (generate tiles from a URL)
TileGenerator urlTileGenerator = new UrlTileGenerator(context, geoPackage,
        "url_tile_table", "http://url/{z}/{x}/{y}.png", 0, 0, boundingBox, projection);
int urlTileCount = urlTileGenerator.generateTiles();

// Feature Tile Generator (generate tiles from features)
TileGenerator featureTileGenerator = new FeatureTileGenerator(context, geoPackage,
        "tiles_" + featureTable, featureTiles, 1, 2, boundingBox, projection);
int featureTileCount = featureTileGenerator.generateTiles();

// Close feature tiles (and indexer)
featureTiles.close();

// Close database when done
geoPackage.close();

Installation

Pull from the Maven Central Repository (AAR, POM, Source, Javadoc)

api 'mil.nga.geopackage:geopackage-android:6.7.4'

Build

Build Artifacts Test

Build this repository using Android Studio and/or Gradle.

Project Setup

Include as repositories in your project build.gradle:

repositories {
    google()
    mavenCentral()
    mavenLocal()
}
Normal Build

Include the dependency in your module build.gradle with desired version number:

api 'mil.nga.geopackage:geopackage-android:6.7.4'

As part of the build process, run the "publishToMavenLocal" task on the geopackage-android Gradle script to update the Maven local repository.

Local Build

Replace the normal build dependency in your module build.gradle with:

api project(':geopackage-sdk')

Include in your settings.gradle:

include ':geopackage-sdk'

From your project directory, link the cloned SDK directory:

ln -s ../geopackage-android/geopackage-sdk geopackage-sdk

Remote Dependencies

  • GeoPackage Core Java (The MIT License (MIT)) - GeoPackage Library
  • TIFF (The MIT License (MIT)) - Tagged Image File Format Lib
  • OrmLite (Open Source License) - Object Relational Mapping (ORM) Library
  • PNGJ (Apache License, Version 2.0) - PNGJ: Java library for PNG encoding

geopackage-android's People

Contributors

bosborn avatar restjohn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geopackage-android's Issues

geopackage cannot open attribute table by ArcMap

Please fill out as much known and relevant information as possible.

Version Information:

Why did I make an error in ArcGIS through the gpkg created by Geopackage-Android and written to the data?

  • GeoPackage Android Version: 2.0.0

  • GeoPackage Android Source:

  • Device or Emulator:

  • Android Studio Version:

  • Android Version Number:

  • Android SDK Version: 26

  • Platform & OS: Android ArcGIS [10.3.1]

  • Other Relevant Libraries:

Expected Results:

  • What did you expect to happen?

Observed Results:

  • What happened instead?
  • How often does this occur?

Output:

  • Any logs, errors, or output messages?

Steps to Reproduce:

  1. Step One
  2. Step Two
  3. ...

Relevant Code:

// Code to reproduce the problem?

Test Files:

  • Links to any files needed for testing?

Additional Information:

  • Any additional configuration, data, or information that might help with the issue?

SQLUtils.quoteWrap is broken on Android Q beta

Version Information:

  • GeoPackage Android Version: 3.2.0
  • GeoPackage Android Source: Central Repository
  • Device or Emulator: Both
  • Android Studio Version: 3.5.0-beta01
  • Android Version Number: Q beta 3
  • Android SDK Version: Q beta 3
  • Platform & OS: Q beta 3
  • Other Relevant Libraries:

Expected Results:

  • What did you expect to happen?
    The returned ContentValues to be populated with the same items as the passed in ContentValues with the keys quoted

Observed Results:

  • What happened instead? The returned ContentValues are empty
  • How often does this occur? Every time

Steps to Reproduce:

  1. This is happening when trying to import a geoPackage on Android Q beta 3 using geoPackageManager.importGeoPackage(destinationFile, true)

suport cache result

When large data is frequently queried, the speed of building data is too slow. For data over 1W, index queries take only a few milliseconds, and building FeatureRow takes more than 3-5 seconds.
In most cases, only a small part of the data will be updated during map movement. Supporting caching when querying can greatly improve the speed of map loading.

public class FeatureIndexRTreeResults implements FeatureIndexResults {
  public FeatureIndexRTreeResults(RTreeIndexTableDao dao,
                                    UserCustomCursor cursor) {
        this.dao = dao;
        this.cursor = cursor;
        String tableName=dao.getFeatureDao().getTableName();
        this.lruCache= CacheManager.getCache(tableName);
    }
@Override
            public FeatureRow next() {
                Long id=dao.getRow(cursor).getId();
                Object obj=lruCache.get(id);
                if(obj!=null){
                    Log.d("lruCache", "cacheID:"+id );
                    return (FeatureRow) obj;
                }
                FeatureRow row=dao.getFeatureRow(cursor);
                lruCache.put(id,row);
                Log.d("next", "nextID: "+id );
                return row;
            }
}
public class CacheManager {
    static Map<String,LruCache> cacheMap=new HashMap<>();
    public static int MaxSize=1000;
    public static LruCache getCache(String tableName) {
        if(cacheMap.containsKey(tableName)){
            return cacheMap.get(tableName);
        }else {
            LruCache cache= new LruCache(MaxSize);
            cacheMap.put(tableName,cache);
            return cache;
        }
    }
}

When a raster Geopackage file is copied locally from a file import, it seems corrupt when it is not

Please fill out as much known and relevant information as possible.

Version Information:

  • GeoPackage Android Version: 6.1.2
  • GeoPackage Android Source: Android app build.gradle api 'mil.nga.geopackage:geopackage-android:6.1.2'
  • Device or Emulator: Samsung Note 5 (SM-N9208)
  • Android Studio Version:
Android Studio Arctic Fox | 2020.3.1 Patch 3
Build #AI-203.7717.56.2031.7784292, built on October 1, 2021
Runtime version: 11.0.10+0-b96-7249189 amd64
VM: OpenJDK 64-Bit Server VM by Oracle Corporation
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 2560M
Cores: 4
Registry: analyze.exceptions.on.the.fly=true, external.system.auto.import.disabled=true
Non-Bundled Plugins: com.alayouni.ansiHighlight, com.intellij.ideolog, JFormDesigner, idea.plugin.protoeditor, io.protostuff.protostuff-jetbrains-plugin, Dart, org.jetbrains.kotlin, io.flutter, org.intellij.plugins.markdown
  • Android Version Number: 7.0
  • Android SDK Version: 31
  • Platform & OS: Android Studio on Windows 10 21H1
  • Other Relevant Libraries: N/A

Expected Results:

  • What did you expect to happen?
    Taking a design influence from the Geopackage MapCache Android ImportTask method with its options to copy locally or to modify the original, I expect a raster Geopackage file to be imported with "copy locally" option without any trouble in my app that leverages the OSMDroid map engine with Geopackage support. The tables of the Geopackage will be stored in the OsmDroid SQLite cache database.

However, following import, it appears "corrupt." However, after restarting the app, the "failed" map renders correctly.

Import feature

import from file 1

Importing with copy locally option selected

import from file 2

Observed Results:

  • What happened instead?
    When I try to import from a Geopackage file and select the "copy locally" option, an exception popup shows up after the failed loading attempt.
Failed to import popup message

import from file 3

But it loads fine after app restart

import from file 4

  • How often does this occur?
    It happens when importing a new map with the "copy locally" option. The assumed "failed to copy locally" map is loaded without issue after the app restarts to indicate that the required tables (gpkg_spatial_ref_sys & gpkg_contents) in Geopackage are still intact and are not corrupted. However, the name stored in the OSMDroid cache database now becomes "5312.corrupt".
2022-04-11 11:34:33.529 1920-1920/? I/OsmDroid: Geopackage database list: [5312.corrupt]
2022-04-11 11:34:33.533 1920-1920/? I/OsmDroid: Geopackage database size: 1
2022-04-11 11:34:33.564 1920-1920/? I/OsmDroid: Geopackage database open: 5312.corrupt (true)

Output:

  • Any logs, errors, or output messages?
    Either the logcat shows this error or the one after importing a Geopackage file:
Error 1
2022-04-11 10:46:28.214 16539-16539/? I/OsmDroid: Geopackage database list: [5312]
2022-04-11 10:46:28.217 16539-16539/? I/OsmDroid: Geopackage database size: 1
2022-04-11 10:46:28.704 16539-16539/? E/com.my.app.android.component.OsmMapFragment: GPKG file setupMap() load error: mil.nga.geopackage.validate.GeoPackageValidate.validateMinimumTables(GeoPackageValidate.java:155)
    mil.nga.geopackage.GeoPackageException: Invalid GeoPackage. Does not contain required tables: gpkg_spatial_ref_sys & gpkg_contents, GeoPackage Name: 5312
        at mil.nga.geopackage.validate.GeoPackageValidate.validateMinimumTables(GeoPackageValidate.java:155)
        at mil.nga.geopackage.GeoPackageCreator.createGeoPackage(GeoPackageCreator.java:228)
        at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:1101)
        at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:1070)
        at com.my.app.android.gpkg.tiles.raster.SafGeoPackageMapTileModuleProvider.<init>(SafGeoPackageMapTileModuleProvider.java:90)
Error 2
2022-04-11 11:16:15.032 1920-1920/? I/OsmDroid: Geopackage database list: [5312]
2022-04-11 11:16:15.037 1920-1920/? I/OsmDroid: Geopackage database size: 1
2022-04-11 11:16:15.118 1920-1920/? E/com.my.app.android.component.OsmMapFragment: GPKG file setupMap() load error: android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
    android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed (code 11)
    #################################################################
    Error Code : 11 (SQLITE_CORRUPT)
    Caused By : The database disk image is malformed.
    	(database disk image is malformed (code 11))
    #################################################################
        at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:930)
        at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
        at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:219)
        at android.database.AbstractCursor.moveToNext(AbstractCursor.java:268)
        at android.database.CursorWrapper.moveToNext(CursorWrapper.java:202)
        at mil.nga.geopackage.db.ResultUtils.buildResults(ResultUtils.java:395)
        at mil.nga.geopackage.db.GeoPackageConnection.queryResults(GeoPackageConnection.java:192)
        at mil.nga.geopackage.db.GeoPackageCoreConnection.queryResults(GeoPackageCoreConnection.java:998)
        at mil.nga.geopackage.db.CoreSQLUtils.foreignKeyCheck(CoreSQLUtils.java:363)
        at mil.nga.geopackage.db.GeoPackageCoreConnection.foreignKeyCheck(GeoPackageCoreConnection.java:194)
        at mil.nga.geopackage.db.GeoPackageCoreConnection.enableForeignKeys(GeoPackageCoreConnection.java:147)
        at mil.nga.geopackage.GeoPackageCreator.createGeoPackage(GeoPackageCreator.java:222)
        at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:1101)
        at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:1070)
        at com.my.app.android.gpkg.tiles.raster.SafGeoPackageMapTileModuleProvider.<init>(SafGeoPackageMapTileModuleProvider.java:90)
        at com.my.app.android.gpkg.tiles.raster.SafGeoPackageProvider.<init>(SafGeoPackageProvider.java:67)
        at com.my.app.android.gpkg.tiles.raster.SafGeoPackageProvider.<init>(SafGeoPackageProvider.java:44)
        at com.my.app.android.component.OsmMapFragment$LoadGeoPackageTask.onPreExecute(OsmMapFragment.java:1860)
        at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:613)
        at com.my.app.android.component.OsmMapFragment.loadMap(OsmMapFragment.java:1634)
        at com.my.app.android.component.gpkg.load.ImportTask$2.onClick(ImportTask.java:232)
        at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6682)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

Steps to Reproduce:

It is not relevant since it is my custom codes

Relevant Code:

The code snippet where the exception occurs at (SafGeoPackageMapTileModuleProvider.java:90):
GeoPackage open = manager.open(databases.get(i));

I'm not sure if removing the extension ".gpkg" (GEO_PACKAGE_EXTENSION) from the file name before adding the file into the GeoPackageManager.importGeoPackage() call is a problem or not.

    public SafGeoPackageMapTileModuleProvider(DocumentFile[] pFile,
                                              final Context context, IFilesystemCache cache) {
        //int pThreadPoolSize, final int pPendingQueueSize
        super(Configuration.getInstance().getTileFileSystemThreads(), Configuration.getInstance().getTileFileSystemMaxQueueSize());
        Log.i(IMapView.LOGTAG, "Geopackage support is BETA. Please report any issues");
        tileWriter = cache;
        // Get a manager
        manager = GeoPackageFactory.getManager(context);
        // Available databases

        String[] list = manager.databases().stream().toArray(String[]::new);
        Log.i(IMapView.LOGTAG, "Geopackage database list: " + Arrays.toString(list));

        // Import database but strip the .gpkg extension from the file name
        for (int i = 0; i < pFile.length; i++) {
            String name = pFile[i].getName();
            name = name.replace(GEO_PACKAGE_EXTENSION, "");
            //Log.i(IMapView.LOGTAG, "Geopackage database new entry: " + name);
            if (StringUtils.indexOfAny(name, list) == -1) {
                Log.i(IMapView.LOGTAG, "Geopackage database new entry: " + pFile[i].getName());
                manager.importGeoPackage((pFile[i]));
            }
        }

        // Available databases
        List<String> databases = manager.databases();
        Log.i(IMapView.LOGTAG, String.format(Locale.getDefault(), "Geopackage database size: %d", databases.size()));
        // Open database
        for (int i = 0; i < databases.size(); i++) {
            GeoPackage open = manager.open(databases.get(i));
            boolean newTile = tileSources.add(open);
            Log.i(IMapView.LOGTAG, String.format(Locale.getDefault(), "Geopackage database open: %s (%s)", databases.get(i), newTile ? "true":"false"));
            open.close();
        }

    }

Test Files:

  • Links to any files needed for testing? None

Additional Information:

  • Any additional configuration, data, or information that might help with the issue? None

Rebuild the index by creating a trigger

The index must be updated manually.Is there a plan to provide automatic updating index?

        // Update a Geometry 
        TestCase.assertEquals(1, featureDao.update(testFeatureRow));
        //update the index of a single feature row
        TestCase.assertTrue(featureIndexManager.index(testFeatureRow));

When I build a new Geopacakge database in QGIS, QGIS will help me create related indexes and triggers automatically.I didn't care about index maintenance when I was working, and simplified my work.

CREATE TABLE "taiwan-EPSG_3857" ( "fid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "geom" LINESTRING, "ID" MEDIUMINT, "ELEV" REAL);

CREATE TRIGGER "trigger_insert_feature_count_taiwan-EPSG_3857" AFTER INSERT ON "taiwan-EPSG_3857" BEGIN UPDATE gpkg_ogr_contents SET feature_count = feature_count + 1 WHERE lower(table_name) = lower('taiwan-EPSG_3857'); END;

CREATE TRIGGER "rtree_taiwan-EPSG_3857_geom_update3" AFTER UPDATE ON "taiwan-EPSG_3857" WHEN OLD."fid" != NEW."fid" AND (NEW."geom" NOTNULL AND NOT ST_IsEmpty(NEW."geom")) BEGIN DELETE FROM "rtree_taiwan-EPSG_3857_geom" WHERE id = OLD."fid"; INSERT OR REPLACE INTO "rtree_taiwan-EPSG_3857_geom" VALUES (NEW."fid",ST_MinX(NEW."geom"), ST_MaxX(NEW."geom"),ST_MinY(NEW."geom"), ST_MaxY(NEW."geom")); END;

CREATE TRIGGER "rtree_taiwan-EPSG_3857_geom_update4" AFTER UPDATE ON "taiwan-EPSG_3857" WHEN OLD."fid" != NEW."fid" AND (NEW."geom" ISNULL OR ST_IsEmpty(NEW."geom")) BEGIN DELETE FROM "rtree_taiwan-EPSG_3857_geom" WHERE id IN (OLD."fid", NEW."fid"); END;

CREATE TRIGGER "trigger_delete_feature_count_taiwan-EPSG_3857" AFTER DELETE ON "taiwan-EPSG_3857" BEGIN UPDATE gpkg_ogr_contents SET feature_count = feature_count - 1 WHERE lower(table_name) = lower('taiwan-EPSG_3857'); END;

CREATE TRIGGER "rtree_taiwan-EPSG_3857_geom_update2" AFTER UPDATE OF "geom" ON "taiwan-EPSG_3857" WHEN OLD."fid" = NEW."fid" AND (NEW."geom" ISNULL OR ST_IsEmpty(NEW."geom")) BEGIN DELETE FROM "rtree_taiwan-EPSG_3857_geom" WHERE id = OLD."fid"; END;

CREATE TRIGGER "rtree_taiwan-EPSG_3857_geom_delete" AFTER DELETE ON "taiwan-EPSG_3857" WHEN old."geom" NOT NULL BEGIN DELETE FROM "rtree_taiwan-EPSG_3857_geom" WHERE id = OLD."fid"; END;

CREATE TRIGGER "rtree_taiwan-EPSG_3857_geom_insert" AFTER INSERT ON "taiwan-EPSG_3857" WHEN (new."geom" NOT NULL AND NOT ST_IsEmpty(NEW."geom")) BEGIN INSERT OR REPLACE INTO "rtree_taiwan-EPSG_3857_geom" VALUES (NEW."fid",ST_MinX(NEW."geom"), ST_MaxX(NEW."geom"),ST_MinY(NEW."geom"), ST_MaxY(NEW."geom")); END;

CREATE TRIGGER "rtree_taiwan-EPSG_3857_geom_update1" AFTER UPDATE OF "geom" ON "taiwan-EPSG_3857" WHEN OLD."fid" = NEW."fid" AND (NEW."geom" NOTNULL AND NOT ST_IsEmpty(NEW."geom")) BEGIN INSERT OR REPLACE INTO "rtree_taiwan-EPSG_3857_geom" VALUES (NEW."fid",ST_MinX(NEW."geom"), ST_MaxX(NEW."geom"),ST_MinY(NEW."geom"), ST_MaxY(NEW."geom")); END;

Importing GeoPackage as external link additional validation

When importing a GeoPackage database as an external link, some corrupt or non database files make it past early validation. This cause crashes attempting to operate on the file.

We need to validate that the external database files are valid. Integrity checks can sometimes take a long time or loop till out of memory on corrupt / non db files. We should first check the header to see if it is a valid sqlite database file in addition to allowing integrity checks.

Header and integrity checks will be supported on imports and opens. Due to the extra time constraint these can cause, the only check on by default will be import header checks. The remaining can be enabled on the GeoPackage manager.

We should also allow validation, both header and integrity on an existing database file. In case something has corrupted the file after it was added.

Table not created

I'm trying to create a database and table from tab fragment. My problem is the table is not created. Should database creation run on MainActivity or there is something i forgot in my code? Thank you

Version Information:

  • GeoPackage Android Version: mil.nga.geopackage.map:geopackage-android-map:3.0.2
  • GeoPackage Android Source: Central Repository
  • Device or Emulator: AVD

Expected Results:

  • The table TESTFEATURE created

Observed Results:

  • the database created but the table does not

Output:

  • No error

Steps to Reproduce:

  1. Create a small app with two tab. Tab 1 contain map and the second contains button
  2. Click the button
  3. Cek the database created in /databases folder

Relevant Code:

btnCreateDB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                GeoPackageManager manager = GeoPackageFactory.getManager(getActivity());

                manager.delete("test_gpkg.gpkg");
                try {
                    manager.create("test_gpkg.gpkg");

                    GeoPackage geoPackage = manager.open("test_gpkg.gpkg");
                    if (geoPackage == null) {
                        Log.d("Error null", "Error geopackage null");
                    }
                    geoPackage.createGeometryColumnsTable();

                    SpatialReferenceSystemDao srsDao = geoPackage.getSpatialReferenceSystemDao();
                    SpatialReferenceSystem epsgSrs = srsDao.queryForId(4326l);
                    srsDao.createWebMercator();

                    GeometryColumnsDao geometryColumnsDao = geoPackage.getGeometryColumnsDao();

                    List<FeatureColumn> columns = new ArrayList<FeatureColumn>();
                    columns.add(FeatureColumn.createPrimaryKeyColumn(0, "ID"));
                    columns.add(FeatureColumn.createGeometryColumn(1, "GEOM",
                            GeometryType.MULTIPOLYGON, false, null));
                    columns.add(FeatureColumn.createColumn(2, "DESC",
                            GeoPackageDataType.TEXT, false, null));

                    FeatureTable table = new FeatureTable("TESTFEATURE", columns);
                    geoPackage.createFeatureTable(table);

                    ContentsDao contentsDao = geoPackage.getContentsDao();
                    Contents contents = new Contents();
                    contents.setTableName("TESTFEATURE");
                    contents.setDataType(ContentsDataType.FEATURES);
                    contents.setIdentifier("TESTFEATURE");
                    contents.setDescription("TEST FEATURE");
                    contents.setMinX(94d);
                    contents.setMinY(-12d);
                    contents.setMaxX(142d);
                    contents.setMaxY(7d);
                    contents.setSrs(epsgSrs);

                    contentsDao.create(contents);

                    GeometryColumns geometryColumns = new GeometryColumns();
                    geometryColumns.setContents(contents);
                    geometryColumns.setColumnName("GEOM");
                    geometryColumns.setGeometryType(GeometryType.MULTIPOLYGON);
                    geometryColumns.setSrs(contents.getSrs());
                    geometryColumns.setZ((byte) 0);
                    geometryColumns.setM((byte) 0);
                    geometryColumnsDao.create(geometryColumns);

                    Toast toast = Toast.makeText(getContext(), "Table created successfully", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();

                }
                catch (Exception ex)
                {
                    Log.d("Error",  ex.getMessage());
                    Toast toast = Toast.makeText(getContext(), ex.getMessage(), Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                }
            }
        });

How to create a custom SpatialReference?

How to create a custom SpatialReference?
When I try to create a custom SpatialReference. Throw the wrong :
mil.nga.sf.util.SFException: Failed to create projection for authority
thanks

Referring to issue no #57 and #16, This crash comes with importAsExternalLink as well. Please guide

Please fill out as much known and relevant information as possible.

Version Information:

  • GeoPackage Android Version: 4.0.0
  • GeoPackage Android Source: (e.g. Central Repository / Bintray, Release, Source Code Build) central repo
  • Device or Emulator: device
  • Android Studio Version: 4.1.3
  • Android Version Number: 9
  • Android SDK Version: 29
  • Platform & OS: Android
  • Other Relevant Libraries:

Expected Results:

  • What did you expect to happen? - import geopackage file with given path

Observed Results:

  • What happened instead?
    I get java.lang.ExceptionInInitializerError, saying it could not open some file in app/data/.../base.apk

  • How often does this occur? Frequent, every time app starts from fresh.

Output:

  • Any logs, errors, or output messages?

2021-05-01 17:38:26.577 28181-28181/com.sixsimplex.revelo E/System: Unable to open zip file: /data/app/com.sixsimplex.revelo-qcn96uwbyhmtAMG8qGYDDg==/base.apk
2021-05-01 17:38:26.583 28181-28181/com.sixsimplex.revelo E/System: java.io.FileNotFoundException: File doesn't exist: /data/app/com.sixsimplex.revelo-qcn96uwbyhmtAMG8qGYDDg==/base.apk
at java.util.zip.ZipFile.(ZipFile.java:215)
at java.util.zip.ZipFile.(ZipFile.java:152)
at java.util.jar.JarFile.(JarFile.java:160)
at java.util.jar.JarFile.(JarFile.java:97)
at libcore.io.ClassPathURLStreamHandler.(ClassPathURLStreamHandler.java:47)
at dalvik.system.DexPathList$Element.maybeInit(DexPathList.java:702)
at dalvik.system.DexPathList$Element.findResource(DexPathList.java:729)
at dalvik.system.DexPathList.findResource(DexPathList.java:508)
at dalvik.system.BaseDexClassLoader.findResource(BaseDexClassLoader.java:169)
at java.lang.ClassLoader.getResource(ClassLoader.java:793)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:987)
at java.lang.Class.getResourceAsStream(Class.java:2211)
at mil.nga.geopackage.property.GeoPackageProperties.initializeConfigurationProperties(GeoPackageProperties.java:262)
at mil.nga.geopackage.property.GeoPackageProperties.getProperty(GeoPackageProperties.java:50)
at mil.nga.geopackage.property.GeoPackageProperties.getProperty(GeoPackageProperties.java:82)
at mil.nga.geopackage.property.GeoPackageProperties.getProperty(GeoPackageProperties.java:68)
at mil.nga.geopackage.extension.CrsWktExtension.(CrsWktExtension.java:39)
at mil.nga.geopackage.GeoPackageCoreImpl.getSpatialReferenceSystemDao(GeoPackageCoreImpl.java:788)
at mil.nga.geopackage.validate.GeoPackageValidate.hasMinimumTables(GeoPackageValidate.java:132)
at mil.nga.geopackage.validate.GeoPackageValidate.validateMinimumTables(GeoPackageValidate.java:150)
at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:894)
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1167)
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1115)
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1107)
at com.sixsimplex.revelo.geopackage.geopackage.GeoPackageManagerAgent.getMetaGeoPackage(GeoPackageManagerAgent.java:78)
at com.sixsimplex.revelo.geopackage.tableUtil.EntitiesTable.getDao(EntitiesTable.java:55)
at com.sixsimplex.revelo.geopackage.tableUtil.EntitiesTable.getFeatureLayers(EntitiesTable.java:72)
at com.sixsimplex.revelo.home.presenter.HomePresenter.createEntityListData(HomePresenter.java:710)
at com.sixsimplex.revelo.home.HomeActivity.callHomeUi(HomeActivity.java:245)
at com.sixsimplex.revelo.home.HomeActivity.successMessage(HomeActivity.java:464)
at com.sixsimplex.revelo.home.presenter.HomePresenter.checkDataDownloadScenario(HomePresenter.java:263)
at com.sixsimplex.revelo.home.presenter.HomePresenter.onPresenterHome(HomePresenter.java:137)
at com.sixsimplex.revelo.home.HomeActivity.initComponent(HomeActivity.java:216)
at com.sixsimplex.revelo.home.HomeActivity.onCreate(HomeActivity.java:144)
at android.app.Activity.performCreate(Activity.java:7272)
at android.app.Activity.performCreate(Activity.java:7263)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3163)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3318)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2022)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7147)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:511)
at com.android.internal.os.ZygoteInit.main(ZygoteI
2021-05-01 17:38:26.583 28181-28181/com.sixsimplex.revelo E/GeoPackageProperties: Failed to load properties, file not found: geopackage.properties
2021-05-01 17:38:26.590 28181-28181/com.sixsimplex.revelo D/AndroidRuntime: Shutting down VM
2021-05-01 17:38:26.596 28181-28181/com.sixsimplex.revelo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sixsimplex.revelo, PID: 28181
java.lang.ExceptionInInitializerError
at mil.nga.geopackage.GeoPackageCoreImpl.getSpatialReferenceSystemDao(GeoPackageCoreImpl.java:788)
at mil.nga.geopackage.validate.GeoPackageValidate.hasMinimumTables(GeoPackageValidate.java:132)
at mil.nga.geopackage.validate.GeoPackageValidate.validateMinimumTables(GeoPackageValidate.java:150)
at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:894)
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1167)
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1115)
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1107)
at com.sixsimplex.revelo.geopackage.geopackage.GeoPackageManagerAgent.getMetaGeoPackage(GeoPackageManagerAgent.java:78)
at com.sixsimplex.revelo.geopackage.tableUtil.EntitiesTable.getDao(EntitiesTable.java:55)
at com.sixsimplex.revelo.geopackage.tableUtil.EntitiesTable.getFeatureLayers(EntitiesTable.java:72)
at com.sixsimplex.revelo.home.presenter.HomePresenter.createEntityListData(HomePresenter.java:710)
at com.sixsimplex.revelo.home.HomeActivity.callHomeUi(HomeActivity.java:245)
at com.sixsimplex.revelo.home.HomeActivity.successMessage(HomeActivity.java:464)
at com.sixsimplex.revelo.home.presenter.HomePresenter.checkDataDownloadScenario(HomePresenter.java:263)
at com.sixsimplex.revelo.home.presenter.HomePresenter.onPresenterHome(HomePresenter.java:137)
at com.sixsimplex.revelo.home.HomeActivity.initComponent(HomeActivity.java:216)
at com.sixsimplex.revelo.home.HomeActivity.onCreate(HomeActivity.java:144)
at android.app.Activity.performCreate(Activity.java:7272)
at android.app.Activity.performCreate(Activity.java:7263)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3163)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3318)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2022)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7147)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:511)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
Caused by: java.lang.RuntimeException: Property not found: geopackage.extensions.crs_wkt
at mil.nga.geopackage.property.GeoPackageProperties.getProperty(GeoPackageProperties.java:54)
at mil.nga.geopackage.property.GeoPackageProperties.getProperty(GeoPackageProperties.java:82)
at mil.nga.geopackage.property.GeoPackageProperties.getProperty(GeoPackageProperties.java:68)
at mil.nga.geopackage.extension.CrsWktExtension.(CrsWktExtension.java:39)
at mil.nga.geopackage.GeoPackageCoreImpl.getSpatialReferenceSystemDao(GeoPackageCoreImpl.java:788) 
at mil.nga.geopackage.validate.GeoPackageValidate.hasMinimumTables(GeoPackageValidate.java:132) 
at mil.nga.geopackage.validate.GeoPackageValidate.validateMinimumTables(GeoPackageValidate.java:150) 
at mil.nga.geopackage.GeoPackageManagerImpl.open(GeoPackageManagerImpl.java:894) 
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1167) 
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1115) 
at mil.nga.geopackage.GeoPackageManagerImpl.importGeoPackageAsExternalLink(GeoPackageManagerImpl.java:1107) 
at com.sixsimplex.revelo.geopackage.geopackage.GeoPackageManagerAgent.getMetaGeoPackage(GeoPackageManagerAgent.java:78) 
at com.sixsimplex.revelo.geopackage.tableUtil.EntitiesTable.getDao(EntitiesTable.java:55) 
at com.sixsimplex.revelo.geopackage.tableUtil.EntitiesTable.getFeatureLayers(EntitiesTable.java:72) 
at com.sixsimplex.revelo.home.presenter.HomePresenter.createEntityListData(HomePresenter.java:710) 
at com.sixsimplex.revelo.home.HomeActivity.callHomeUi(HomeActivity.java:245) 
at com.sixsimplex.revelo.home.HomeActivity.successMessage(HomeActivity.java:464) 
at com.sixsimplex.revelo.home.presenter.HomePresenter.checkDataDownloadScenario(HomePresenter.java:263) 
at com.sixsimplex.revelo.home.presenter.HomePresenter.onPresenterHome(HomePresenter.java:137) 
at com.sixsimplex.revelo.home.HomeActivity.initComponent(HomeActivity.java:216) 
at com.sixsimplex.revelo.home.HomeActivity.onCreate(HomeActivity.java:144) 
at android.app.Activity.performCreate(Activity.java:7272) 
at android.app.Activity.performCreate(Activity.java:7263) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3163) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3318) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2022) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:224) 
at android.app.ActivityThread.main(ActivityThread.java:7147) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:511) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876) 

Steps to Reproduce:

  1. Step One
  2. Step Two
  3. ...

Relevant Code:

// Code to reproduce the problem?

Test Files:

  • Links to any files needed for testing?

Additional Information:

  • Any additional configuration, data, or information that might help with the issue?
    This happens everytime I start the app from rest. When I run app for second time, it goes fine

Android Manifest conflict

Please fill out as much known and relevant information as possible.

Version Information:

  • GeoPackage Android Version: 4.0.0
  • GeoPackage Android Source: Central Repository
  • Device or Emulator: S20
  • Android Studio Version: 4.1.2
  • Android Version Number: 10
  • Android SDK Version: 29
  • Platform & OS: Linux 20.04
  • Other Relevant Libraries:

Expected Results:

Add geopackage-android dependency to gradle, have it compile correctly for an ATAK plugin app.
implementation 'mil.nga.geopackage:geopackage-android:4.0.0'

Observed Results:

  • What happened instead? During build, manifest conflict between libraries within repository and ATAK plugin app. Specifically geopackage-android-4.0.0.aar & sqlite-android-3320300.aar have manifest application callouts that need to be deleted to de-conflict with app the repository is intended to support.

  • How often does this occur? Every compilation attempt.

Output:

  • Any logs, errors, or output messages?

Task :processDebugManifest FAILED
/home/jason/AndroidStudioProjects/vracamera/AndroidManifest.xml:22:18-91 Error:
Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.1.0] AndroidManifest.xml:24:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:20:5-50:19 to override.

See http://g.co/androidstudio/manifest-merger for more information about the manifest merger.

Execution failed for task ':processDebugManifest'.

Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.1.0] AndroidManifest.xml:24:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:20:5-50:19 to override.

Steps to Reproduce:

  1. Step One
  2. Step Two
  3. ...

Relevant Code:

// Code to reproduce the problem?

Test Files:

  • Links to any files needed for testing?

Additional Information:

  • Any additional configuration, data, or information that might help with the issue?

Open GeoPackage file by absolute path

Hi there,

is it possible to open GeoPackage file providing an absolute path? I have some GeoPackages stored on a SD card, so I can create a simple SQLite connection to read them, but in GeoPackage Library I found only a way to provide App Context, which always takes a context.databasePath.
Is there a way to write something like this

File dbFile = new File(storageDir, "myDatabase.gpkg");
GeoPackage mySdCardGeoPackage = new GeoPackage(dbFile.getAbsolutPath());

or any way to provide own database connection?

Version Information:

  • GeoPackage Android Version: 3.2.0
  • GeoPackage Android Source: Central Repository
  • Device or Emulator: Device Nokia 6.1
  • Android Studio Version: 3.3.1
  • Android Version Number: 8.1.0

Thank you for any help.

Tile DAO get Bounding Box and Tile Grid at a zoom level

Add methods to query for the Tile Grid and Bounding Box of the existing tiles at a Tile Matrix zoom level. This could be the entire Tile Matrix Set bounding box or grid, or a subset if tiles are missing around the edges.

FeatureDao query

The current query method is divided into two parts. First, the index is queried, and then the data is retrieved according to ID. If there are additional supplementary queries, each data need to be judged.

public FeatureCursor query(BoundingBox boundingBox, Projection projection, String where, String[] whereArgs) {
    String box_query =buildWhere(boundingBox, projection);
    where =box_query+"and"+where;
    return super.query(where, whereArgs);
}

SQlite Transactioin

The SQLite database supports transactional operations, but the current version of Geopackage is too cumbersome to use.

SQLiteDatabase db=featureDao.getDb().getDb().getDb();

SQLiteDatabase db1= featureDao.getDatabaseConnection().getDb();

db.beginTransaction();  //Manual Setup to Start Transaction
    try{
        //Batch processing operation
        for(Collection c:colls){
            insert(db, c);
        }
        //Setting the transaction to be processed successfully will automatically roll back uncommitted if not set.
        db.setTransactionSuccessful();      
    }catch(Exception e){

    }finally{
        db.endTransaction(); //处理完成
    }

Compatible: Manifest merge conflict and androidx support

Version Information:

  • GeoPackage Android Version: mil.nga.geopackage:geopackage-android:3.1.0
  • GeoPackage Android Source: Source Code Build
  • Device or Emulator: Oneplus 3T
  • Android Studio Version: 3.5 C7
  • Android Version Number: 8.0
  • Android SDK Version: 28
  • Platform & OS: Ubuntu
  • Other Relevant Libraries: https://sqlite.org/2019/sqlite-android-3270200.aar

Problem

  1. Manifest merge conflict. Add 'tools:replace' not work. Can not build.
  2. com.android.support and androidx.appcompat conflict. Can not build.

Output:

ERROR: Manifest merger failed : Attribute application@appComponentFactory value=(androidx.core.app.CoreComponentFactory) from [androidx.core:core:1.0.1] AndroidManifest.xml:22:18-86
	is also present at [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91 value=(android.support.v4.app.CoreComponentFactory).
	Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:11:3-23:17 to override.

ERROR: Manifest merger failed with multiple errors, see logs
org.gradle.execution.MultipleBuildFailures: Build completed with 1 failures.
...

Steps to Reproduce:

build.gradle
  implementation 'androidx.appcompat:appcompat:1.0.2'
  implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

  implementation 'mil.nga.geopackage:geopackage-android:3.1.0'
sync gradle

Relevant Code:

apply plugin: 'com.android.application'

android {
  compileSdkVersion 28
  defaultConfig {
    applicationId "red.lilu.app.maptest"
    minSdkVersion 21
    targetSdkVersion 21
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  }
  buildTypes {
    release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
  }
  // Add below lines to set compatibility with Java 8 language features for an Android app module.
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])
  implementation 'androidx.appcompat:appcompat:1.0.2'
  implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

  implementation 'mil.nga.geopackage:geopackage-android:3.1.0'
//  implementation project(":geopackage")
  implementation 'org.osmdroid:osmdroid-android:6.1.0-SNAPSHOT:debug@aar'
  
  testImplementation 'junit:junit:4.12'
  androidTestImplementation 'androidx.test.ext:junit:1.1.0'
  androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

Suggest

Clean up sqlite aar

Manifest merge conflict cause by sqlite aar, remove all tags.

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true" >
    </application>

to:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.sqlite.database" />
Empty geopackage-android's AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="mil.nga.geopackage" />

Module library without ui not need tags any more. I remove them, works fine.

androidx support

Add tools:replace="android:appComponentFactory" to main Manifests not work, can not build.

Change com.android.support:support-v13:28.0.0 to androidx.appcompat:appcompat:1.0.2 will work, but will affect old users...

Last

  1. Manifest merge conflict need to solve as soon as possible. Can not build!
  2. Anyone use androidx need to build from source now. Blow is my geopackage-android build.gradle:
apply plugin: 'com.android.library'

android {
  compileSdkVersion 28

  defaultConfig {
    minSdkVersion 21
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  }

  buildTypes {
    release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
  }

}

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])

  implementation 'androidx.appcompat:appcompat:1.0.2'
  //drop mil.nga:sqlite-android:3240000
  implementation project(':sqlite-android')
  implementation'com.j256.ormlite:ormlite-android:5.1'
  implementation 'ar.com.hjg:pngj:2.1.0'
  implementation 'mil.nga:tiff:2.0.0'
  implementation 'mil.nga.sf:sf-geojson:2.0.0'
  api 'mil.nga.geopackage:geopackage-core:3.1.0'

  testImplementation 'junit:junit:4.12'
  androidTestImplementation 'com.android.support.test:runner:1.0.2'
  androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

You can build a library module first, then copy src in.

I changed the sqlite library. I download https://sqlite.org/2019/sqlite-android-3270200.aar. So i can change AndroidManifest.xml easily(drag out, modify, drop in).

FeatureIndexManager FeatureIndexType.RTREE index error

Hi
trying to create a table.
I want to use rtree. I get an error in ST_Min function

My Code Is;

FeatureIndexManager indexer = new FeatureIndexManager(_context, _geoPackage, name);
indexer.setIndexLocation(FeatureIndexType.RTREE);
indexer.index();

java.lang.UnsupportedOperationException: User defined SQL functions are not supported. name: ST_MinX
mil.nga.geopackage.extension.RTreeIndexExtension.createFunction(RTreeIndexExtension.java:120)

thanks

Delete External Database do not delete physical file

If i create external database with command manager.createAtPath(dbName, myPath) and then delete it with manager.delete(dbName) i found that the physical file is not deleted. But if i create with manager.create(dbName) and then manager.delete(dbName) then the physical file is gone. Did i miss some setup? I'm still using geopackage android 3.2.0. Thank you

How to create table with no geometry Column

Hi guy
I am a new for geopackage,I wanna create a new table with no geometry Column,but I am failed finally. so please give me some ideas to deal with it . I have done something in activity as bellow

I got the object by "GeoPackager geopackager=GeoPackageFactory.getManager(this);" and create table by
createFeatureTable() or createFeatureTableWithMetadata(), but is invalid with exception that "no GEOEMTRY column was found for table 'my_table'"

Failed to use Custom coordinate system

Version Information:

  • GeoPackage Android Version: mil.nga.geopackage:geopackage-android:1.3.2

Expected Results:

I want to use my own coordinatesystem,for example:
+proj=tmerc +lat_0=0 +lon_0=121 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m +no_defs

srs_id,srs_name,srs_id,organization,organization_coordsys_id,definition,description
100001,unnamed,100001,NONE,100001,"PROJCS[""unnamed"",GEOGCS[""Krassovsky, 1942"",DATUM[""unknown"",SPHEROID[""krass"",6378245,298.3]],PRIMEM[""Greenwich"",0],UNIT[""degree"",0.0174532925199433]],PROJECTION[""Transverse_Mercator""],PARAMETER[""latitude_of_origin"",0],PARAMETER[""central_meridian"",121],PARAMETER[""scale_factor"",1],PARAMETER[""false_easting"",500000],PARAMETER[""false_northing"",0],UNIT[""Meter"",1]]",

Observed Results:

package mil.nga.geopackage.features.user;
class FeatureDao

projection = ProjectionFactory.getProjection(geometryColumns.getSrs());

Output:

Failed to create project for EPSG 100001 Parrameters:null.

Additional Information:

Resolvent:

try {
        projection = ProjectionFactory.getProjection(geometryColumns.getSrs());
    }catch (Exception e){
        //Use custom SpatialReferenceSystem
        SpatialReferenceSystem srs=geometryColumns.getSrs();
        String wktDefine=srs.getDefinition();
        long epsg = srs.getOrganizationCoordsysId();        
       CoordinateReferenceSystem crs= praseWKT(wktDefine);
        projection=new Projection(epsg,crs);// Projection Constructor is pravate ,I don't want to change geopackage-core source code.
    }

QGSIS can automatic recognition table [gpkg_spatial_ref_sys ] ,the field of definition
my data come from QGIS Export to Geopackage when i select a custom CRS

Prj4j - problem with some unsupported projection parameters

Hi Brian, the project is using prj4j (java version) of the library to do coordinates transformations.
In most cases this is fine, however some operations are not supported on Java version e.g.

If you would like to apply EPSG: 3375 which has got the definition:

+proj=omerc +lat_0=4 +lonc=102.25 +alpha=323.0257964666666 +k=0.99984 +x_0=804671 +y_0=0 +no_uoff +gamma=323.1301023611111 +ellps=GRS80 +units=m +no_defs

no_uoff and gamma parameters are not supported by prj4j

Would you consider using Native C++ compilation of Prj4 in the future?

Currently it fails at:

Proj4Parser.java

public CoordinateReferenceSystem parse(String name, String[] args)
  {
    if (args == null)
      return null;
    
    Map params = createParameterMap(args);
    Proj4Keyword.checkUnsupported(params.keySet());
    DatumParameters datumParam = new DatumParameters();
    parseDatum(params, datumParam);
    parseEllipsoid(params, datumParam);
    Datum datum = datumParam.getDatum();
    Ellipsoid ellipsoid = datum.getEllipsoid(); 
    // TODO: this makes a difference - why?
    // which is better?
//    Ellipsoid ellipsoid = datumParam.getEllipsoid(); 
    Projection proj = parseProjection(params, ellipsoid);
    return new CoordinateReferenceSystem(name, args, datum, proj);
  }

Proj4Keyword.checkUnsupported(params.keySet());

Supported parameters are:

public static synchronized Set supportedParameters()
  {
    if (supportedParams == null) {
      supportedParams = new TreeSet<String>();
      
      supportedParams.add(a);
      supportedParams.add(rf);
      supportedParams.add(f);
      supportedParams.add(alpha);
      supportedParams.add(es);
      supportedParams.add(b);
      supportedParams.add(datum);
      supportedParams.add(ellps);
      
      supportedParams.add(R_A);
   
      supportedParams.add(k);
      supportedParams.add(k_0);
      supportedParams.add(lat_ts);
      supportedParams.add(lat_0);
      supportedParams.add(lat_1);
      supportedParams.add(lat_2);
      supportedParams.add(lon_0);
      supportedParams.add(lonc);
      
      supportedParams.add(x_0);
      supportedParams.add(y_0);

      supportedParams.add(proj);
      supportedParams.add(south);
      supportedParams.add(towgs84);
      supportedParams.add(to_meter);
      supportedParams.add(units);
      supportedParams.add(zone);
      
      supportedParams.add(title);       // no-op
      supportedParams.add(no_defs);     // no-op
      supportedParams.add(wktext);      // no-op
      supportedParams.add(nadgrids);    // no-op for now

    }
    return supportedParams;
  }


Kind Regards,
Andrzej Bieniek

X/Y Offset in TileRetriever.getTile()

Hi,
I‘m using this library (v3.4.0) to display a fairly large GeoPackage file on Android (Samsung Galaxy A50 with OSMDroid, but not with osmdroid-geopackage, as that was not flexible enough for me).
The GeoPackage File is in EPSG:3857 and was generated with GDAL. The Tilematrix overviews were built with gdaladdo.

When viewing the file with a gdal-based application (e.g. Qgis), everything is fine.
However, on Android with this library, the file is slightly shifted in X direction.
E.g. when using TileRetriever.getTile(551010, 365532, 20) with a tile size of 627x627.
This translates to this bounding box (taken from the Android Debugger inside getTile()):

minLongitude=1021275.134918239
minLatitude=6067380.212706579
maxLongitude=1021313.3534323834
maxLatitude=6067418.431220721

The resulting Tile from android is this:
android_result

Trying the same with gdal:
gdal_translate -projwin 1021275.134918239 6067418.431220721 1021313.3534323834 6067380.212706579 -outsize 672 672 -of PNG in.gpkg out.png
gdal_result

The code is not much more than the a standard OSMDroid tile provider. Basically:

        int zoom = MapTileIndex.getZoom(pMapTileIndex);
        int x = MapTileIndex.getX(pMapTileIndex);
        int y = MapTileIndex.getY(pMapTileIndex);
        GeoPackageTile geoPackageTile = tileRetriever.getTile(x, y, zoom);

Is there anything I‘m doing wrong?
I‘m fairly certain, that the issue is in geopackage-android, not in GDAL.
Reason: When I‘m going outside with a centimeter-precise RTK GPS, I‘m seeing the same offset when the underlying map is drawn with geopackage-android.

Tile matrix of the input image:

sqlite> select * from gpkg_tile_matrix; 
table_name|zoom_level|matrix_width|matrix_height|tile_width|tile_height|pixel_x_size|pixel_y_size 
tiles|0|1|1|256|256|152.455059500864|152.455059500864 
tiles|1|2|2|256|256|76.2275297504321|76.2275297504321 
tiles|2|3|3|256|256|38.1137648752161|38.1137648752161 
tiles|3|5|5|256|256|19.056882437608|19.056882437608 
tiles|4|10|10|256|256|9.52844121880402|9.52844121880402 
tiles|5|20|20|256|256|4.76422060940201|4.76422060940201 
tiles|6|40|40|256|256|2.382110304701|2.382110304701 
tiles|7|79|79|256|256|1.1910551523505|1.1910551523505 
tiles|8|157|157|256|256|0.595527576175251|0.595527576175251 
tiles|9|313|314|256|256|0.297763788087625|0.297763788087625 
tiles|10|626|628|256|256|0.148881894043813|0.148881894043813

EDIT:
Note that the offset seems to be absolute in terms of world coordinates.
I.e. when zooming out, everything is still shifted in the same way (the same "amount of meters").
Only when zooming out even further into the next overview in the tile matrix, there is a sudden jump (and it then again stays the same offset for the complete zoom-range for that overview).

EDIT2:
Just noticed the same with other geo package files, too. However, it's not always in x-direction. For some files, there is an y-shift. All files were created with gdal.

Error using TileDao queryForTile(long column, long row, long zoomLevel) method

I'm trying to use queryForTile(long column, long row, long zoomLevel) to retrive an specific map tile but it gives me an error. I'm only using the method, in fact the exception shows that the error it's not in my code, it's internal.

GeoPackage geoPackage = geoPackageTileWriter.getGeopackage();
TileDao tileDao = geoPackage.getTileDao(tileSource.name());

if(tileDao != null) {
            .....
            TileRow tileRow = tileDao.queryForTile(col,row,zoom);
 }

Version Information:

  • GeoPackage Android Version: 2.0.0
  • GeoPackage Android Source: (e.g. Central Repository / Bintray, Release, Source Code Build)
  • Device or Emulator: Pixel XL
  • Android Studio Version: 3.0
  • Android Version Number: 7
  • Android SDK Version: 24
  • Platform & OS: Windows
  • Other Relevant Libraries: osmdroid

Expected Results:

TileRow tileRow = tileDao.queryForTile(col,row,(long)zoom);
I want to receive the specific tile row

Observed Results:

It throws an exception

Output:

java.lang.ClassCastException: android.database.sqlite.SQLiteCursor cannot be cast to mil.nga.geopackage.user.UserCursor
at mil.nga.geopackage.user.UserConnection.convertCursor(UserConnection.java:171)
at mil.nga.geopackage.user.UserConnection.handleCursor(UserConnection.java:158)
at mil.nga.geopackage.user.UserConnection.query(UserConnection.java:145)
at mil.nga.geopackage.user.UserConnection.query(UserConnection.java:53)
at mil.nga.geopackage.user.UserConnection.query(UserConnection.java:18)
at mil.nga.geopackage.user.UserCoreDao.queryForFieldValues(UserCoreDao.java:245)
at mil.nga.geopackage.tiles.user.TileDao.queryForTile(TileDao.java:258)
at cu.citi.idesoi.pcidroid.tilesprovider.modules.GeoPackageMapTileModuleProvider$TileLoader.loadTile(GeoPackageMapTileModuleProvider.java:179)
at org.osmdroid.tileprovider.modules.MapTileModuleProviderBase$TileLoader.run(MapTileModuleProviderBase.java:297)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

OsmDroid variant

It'd be awesome to have an osmdroid variant of this package. I've already done some of the work as a proof of concept (live queries, instead of an import process to a native format, but it's way too slow). I'd be willing to assist and open a PR if you all are willing to accept it.

NGA NSG PROFILE

Has the Android SDK been updated to support NGA NSG TILING SCHEMA/profile?

Remove table column

Dear Brian (@bosborn), I know there is no direct method to ALTER the table and remove the field in SQLite, but just as a curiosity - do you think of supporting this kind of operation as part of API?

At the moment I have kind of the workaround (copy table, delete, create, insert from copy) semi working in test but If you could say what you think about this that would be great.

Kind Regards,
Andrzej

Android 10+ scoped storage support

Please fill out as much known and relevant information as possible.

Version Information:

  • GeoPackage Android Version: 2.0.1+ (as long as it uses java.io.File to read database or GPKG files in shared storage of Android10+ scoped storage such as public Documents folder)
  • GeoPackage Android Source: (e.g. Central Repository / Bintray, Release, Source Code Build)
  • Device or Emulator: Samsung SM-A515F
  • Android Studio Version:
Android Studio Arctic Fox | 2020.3.1
Build #AI-203.7717.56.2031.7583922, built on July 27, 2021
Runtime version: 11.0.10+0-b96-7249189 amd64
VM: OpenJDK 64-Bit Server VM by Oracle Corporation
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 4
Registry: analyze.exceptions.on.the.fly=true, external.system.auto.import.disabled=true, ide.images.show.chessboard=true
Non-Bundled Plugins: com.alayouni.ansiHighlight, com.intellij.ideolog, JFormDesigner, idea.plugin.protoeditor, io.protostuff.protostuff-jetbrains-plugin, Dart, org.jetbrains.kotlin, io.flutter, org.intellij.plugins.markdown
  • Android Version Number: 11
  • Android SDK Version: 30
  • Platform & OS: Android Studio on Windows 10 21H1
  • Other Relevant Libraries: N/A

Expected Results:

  • What did you expect to happen?
    GeoPackage is able to read/write folders or files in the Android10+ storage model (such as shared storage such as public Documents folder or MediaStore like Downloads, Music, etc.)

Observed Results:

  • What happened instead?
    The use of java.io.File to read/write folders or files in a scoped storage environment especially shared storage such as public Documents folder or MediaStore like Downloads, Music, etc. will be a major problem. Refer osmdroid/osmdroid#1743
  • How often does this occur?
    Always!

Output:

  • Any logs, errors, or output messages?
2021-09-25 12:26:30.220 17694-17694/? E/SQLiteDatabase: Error inserting 
    android.database.sqlite.SQLiteException: near "null": syntax error (code 1 SQLITE_ERROR[1]): , while compiling: INSERT INTO "geopackage"(null) VALUES (NULL)
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1463)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:901)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:62)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:33)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:2217)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:2088)
        at mil.nga.geopackage.db.GeoPackageDatabase.insert(GeoPackageDatabase.java:127)
        at mil.nga.geopackage.db.metadata.GeoPackageMetadataDataSource.create(GeoPackageMetadataDataSource.java:51)
        at mil.nga.geopackage.factory.GeoPackageManagerImpl.importGeoPackage(GeoPackageManagerImpl.java:1319)
        at mil.nga.geopackage.factory.GeoPackageManagerImpl.importGeoPackage(GeoPackageManagerImpl.java:658)
        at mil.nga.geopackage.factory.GeoPackageManagerImpl.importGeoPackage(GeoPackageManagerImpl.java:572)

Steps to Reproduce:

Just use any code sample that has GeoPackageFactory.importGeoPackage() calls or has made java.io.File calls to read/write database or files.

Relevant Code:

Just use any code sample that has GeoPackageFactory.importGeoPackage() calls or has made java.io.File calls to read/write database or files.

Test Files:

  • Links to any files needed for testing? N/A

Additional Information:

  • Any additional configuration, data, or information that might help with the issue? N/A

RTree Index 3.4.0

State your question
Hi Brian, would you kindly provide more clarification around Line 433 (comment) in https://github.com/ngageoint/geopackage-android/blob/3.4.0/geopackage-sdk/src/main/java/mil/nga/geopackage/features/index/FeatureIndexManager.java:

            case RTREE:
            // Updated by triggers, ignore for RTree
            indexed = true;

Is the rtree index updated when new feature is being added to the table?

Additional context
Is now rtree index supported for writing?

Thanks you,
Kind Regards,
Andrzej

GeoPackage with Vector Tiles inside (based on new Extensions)

Describe the documentation issue
https://github.com/opengeospatial/OGC-OS-Sprint-04-2020/tree/master/Shared_Datasets
https://github.com/jerstlouis/developer-events/blob/patch-1/2023/Tiling-Interfaces-Code-Sprint/README.md

https://github.com/jerstlouis/developer-events/blob/patch-1/2023/Tiling-Interfaces-Code-Sprint/GeoPackage%20Vector%20Tiles%20Extensions.pdf

Additional context
Army Geospatial Center and NGA want to distribute data in GPKG format with vector tiles inside using new extension to gpkg sqlite
Protocol buffer format
Tiles can be 3395 or 3857 or other SRS/CRS

Getting NPE in UserCursor's constructor for table.getUserColumns()

Calling rawQuery(String sql, String[] selectionArgs) on a FeatureWrapperConnection item throws NPE. As I investigated, I encountered a little bug in the geopackage library.
This is my stacktrace:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'mil.nga.geopackage.user.UserColumns mil.nga.geopackage.user.UserTable.getUserColumns()' on a null object reference
        at mil.nga.geopackage.user.UserCursor.<init>(UserCursor.java:86)
        at mil.nga.geopackage.features.user.FeatureCursor.<init>(FeatureCursor.java:27)
        at mil.nga.geopackage.features.user.FeatureWrapperConnection.wrapCursor(FeatureWrapperConnection.java:31)
        at mil.nga.geopackage.features.user.FeatureWrapperConnection.wrapCursor(FeatureWrapperConnection.java:13)
        at mil.nga.geopackage.user.UserWrapperConnection.convertCursor(UserWrapperConnection.java:42)
        at mil.nga.geopackage.user.UserConnection.handleCursor(UserConnection.java:317)
        at mil.nga.geopackage.user.UserConnection.query(UserConnection.java:304)
        at mil.nga.geopackage.user.UserConnection.rawQuery(UserConnection.java:76)

As you can see, the NPE is thrown here:

     /**
     * Constructor
     *
     * @param table  table
     * @param cursor cursor
     */
    protected UserCursor(TTable table, Cursor cursor) {
        this(table, table.getUserColumns(), cursor);
    }

But if you got back until the FeatureWrapperConnection class, you can observe, that the wrapCursor method calls the FeatureCursor constructor with table parameter set to null:

    /**
     * {@inheritDoc}
     */
    @Override
    protected FeatureCursor wrapCursor(Cursor cursor) {
        return new FeatureCursor(null, cursor);
    }

Can you please put a null check in the UserCursor constructor, so that it won't throw any NPE in the future?

Version Information:

  • GeoPackage Java Version: 6.2.0, 6.2.1
  • IDE Name & Version: Android Studio Bumblebee, 2021.1.1
  • Gradle Version: 6.7.1 (android gradle plugin version: 4.2.2)
  • Java Version: 1.8
  • Platform & OS: Android

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.