Skip to content

GeoPackage Support ​

Introduction ​

This document explains GeoTools' implementation of the GeoPackage standard, an open, standards-based, platform-independent, portable, self-contained data format for geospatial information. GeoPackage is an SQLite container that allows you to store both vector features and raster data tiles, making it a versatile format for geospatial applications.

GeoTools provides comprehensive support for reading from and writing to GeoPackage files, including handling of features (vector data), tiles (raster data), metadata, and various GeoPackage extensions.

GeoPackage Architecture in GeoTools ​

GeoPackage support in GeoTools is implemented primarily through the geopkg module, which extends the JDBC framework with GeoPackage-specific handling.

Architecture Overview ​

Key Components ​

  1. GeoPkgDataStoreFactory: Creates instances of GeoPackage data stores
  2. GeoPackage: Main class for interacting directly with GeoPackage files
  3. GeoPkgDialect: Handles SQL translation, geometry encoding/decoding, and other SQLite-specific operations
  4. FeatureEntry/TileEntry: Metadata for feature and tile datasets
  5. Extensions: Support for standard GeoPackage extensions

GeoPackage Data Model ​

SVG
100%

Standard Tables ​

The GeoPackage format defines several standard tables:

TablePurpose
gpkg_contentsLists all feature and tile datasets in the GeoPackage
gpkg_spatial_ref_sysDefines spatial reference systems
gpkg_geometry_columnsDescribes geometry columns in feature tables
gpkg_tile_matrix_setDefines the tile matrix set extent
gpkg_tile_matrixDefines parameters for each zoom level
gpkg_extensionsRegisters extensions used in the GeoPackage

User Data Tables ​

Feature Support ​

Feature Reading and Writing ​

SVG
100%

Feature Data Types ​

GeoTools provides specific handling for various data types in GeoPackage:

  1. Geometries: Full support for all OGC geometry types including 3D geometries
  2. Basic Types: Integer, Double, String, Boolean, etc.
  3. Date/Time: Support for Date, Time, and Timestamp data types
  4. Enumerations: Support for storing and retrieving enumerated values
  5. Arrays: Support for array types stored as JSON strings

Spatial Indexing ​

GeoTools implements the GeoPackage R-Tree spatial indexing extension for improved spatial query performance:

Tile Support ​

GeoTools supports reading and writing tiled raster data in GeoPackage through the GeoPackageReader and associated classes.

Tile Reading Pipeline ​

SVG
100%

Zoom Levels and Resolution ​

GeoPackage organizes tiles in zoom levels with different resolutions. GeoTools provides methods to:

Extensions Support ​

GeoTools supports several GeoPackage extensions:

Spatial Index Extension ​

Implements the R-Tree spatial index extension for faster spatial queries on feature data. Spatial indexes are created using:

geoPackage.createSpatialIndex(featureEntry);

Schema Extension ​

The schema extension provides additional metadata about columns and constraints, implemented through the GeoPkgSchemaExtension class:

  1. Column Descriptions: Add titles, descriptions, and MIME types to columns
  2. Constraints: Define enum values, ranges, or patterns for columns
  3. Enumeration Support: Map between stored codes and human-readable values
DataColumn dc = new DataColumn();
dc.setColumnName("enumProperty");
dc.setConstraint(new DataColumnConstraint.Enum("constraint_name", enumValues));
geopkg.getExtension(GeoPkgSchemaExtension.class).addDataColumn(tableName, dc, connection);

Special Data Type Handling ​

Date and Time ​

GeoPackage stores date and time values as text strings in ISO-8601 format. GeoTools provides special handling for:

  • java.sql.Date for DATE columns
  • java.sql.Timestamp for DATETIME columns
  • java.sql.Time for TIME columns

The GeoPkgDialect ensures proper timezone handling when converting between SQLite strings and Java date objects.

Enumerations ​

GeoTools supports enumerated values through:

  1. Feature type options: builder.options("one", "two", "three")
  2. Explicit enumeration constraint via the schema extension
  3. Automatic conversion between stored codes and human-readable values

Arrays ​

GeoPackage doesn't natively support array types, but GeoTools implements array support by:

  1. Storing arrays as JSON strings in the database
  2. Setting MIME type to "application/json" in the schema extension
  3. Automatically converting between JSON and Java arrays

Filtering and Querying ​

GeoPackage supports standard GeoTools filtering capabilities through the GeoPkgFilterToSQL class, which translates Filter objects to SQL:

Spatial Filters ​

Spatial filters like BBOX and Intersects are optimized to use:

  • Spatial indices when available
  • Spatial functions (ST_MinX, ST_MaxX, etc.) as fallbacks

Attribute Filters ​

Full support for:

  • Comparison filters (=, <, >, BETWEEN, LIKE)
  • Logical filters (AND, OR, NOT)
  • Special handling for date/time comparisons

Query Performance ​

GeoTools implements several optimizations for GeoPackage queries:

Usage Examples ​

Reading Features from a GeoPackage ​

// Open a GeoPackage file
File file = new File("example.gpkg");
Map<String, Object> params = new HashMap<>();
params.put(GeoPkgDataStoreFactory.DBTYPE.key, "geopkg");
params.put(GeoPkgDataStoreFactory.DATABASE.key, file);

// Create the data store
DataStore dataStore = DataStoreFinder.getDataStore(params);

// Get feature source
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);

// Read features
SimpleFeatureCollection features = featureSource.getFeatures();

Writing Features to a GeoPackage ​

// Create a new GeoPackage file
File file = new File("new.gpkg");
GeoPackage geopkg = new GeoPackage(file);
geopkg.init();

// Create a feature entry
FeatureEntry entry = new FeatureEntry();
entry.setTableName("features");
entry.setSrid(4326);
entry.setBounds(new ReferencedEnvelope(-180, 180, -90, 90, CRS.decode("EPSG:4326")));

// Add features to the GeoPackage
geopkg.add(entry, featureCollection);

// Create a spatial index
geopkg.createSpatialIndex(entry);

geopkg.close();

Reading Tiles ​

// Open a GeoPackage with tiles
GeoPackageReader reader = new GeoPackageReader(file, null);

// Set up parameters for reading
GridGeometry2D gg = new GridGeometry2D(
    new GridEnvelope2D(new Rectangle(1000, 500)),
    new ReferencedEnvelope(-180, 180, -90, 90, CRS.decode("EPSG:4326"))
);
ParameterValue<GridGeometry2D> param = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
param.setValue(gg);

// Read the tiles as a GridCoverage2D
GridCoverage2D coverage = reader.read("tile_layer", new GeneralParameterValue[] { param });

Limitations and Considerations ​

  1. Version Compatibility: GeoTools implements the GeoPackage 1.2 specification
  2. Performance: For very large datasets, consider using spatial indexes
  3. Memory Usage: Tile reading can be memory-intensive for large areas
  4. SQLite Limitations: Remember SQLite's concurrent access limitations