Skip to main content
The GeoPackage standard is designed to be extended. Any tool can register a custom extension by inserting a row into the gpkg_extensions table. That row records the extension name, the table and column it applies to, and a definition URI. Extensions fall into two categories:
  • OGC standard extensions — authored by gpkg and ratified as part of the GeoPackage specification.
  • NGA extensions — community extensions authored by the National Geospatial-Intelligence Agency (nga) and maintained at ngageoint.github.io/GeoPackage.
The library’s ExtensionManager coordinates both sets. OGC extensions are handled directly; NGA extensions are delegated to NGAExtensions, which in turn manages the lifecycle (create, copy, delete) of each NGA extension.

Available extensions

RTree Index

OGC standard. Adds an R*Tree spatial index on feature geometry columns for fast bounding-box queries. Used internally by FeatureIndexManager when indexing is requested.

Related Tables

OGC standard. Defines many-to-many relationships between tables using mapping tables registered in gpkgext_relations. Enables linking features to media, simple attributes, or other features.

Schema (Data Columns)

OGC standard. Stores display names, descriptions, and constraint metadata for individual columns in gpkg_data_columns and gpkg_data_column_constraints.

Metadata

OGC standard. Attaches ISO 19115 / Dublin Core metadata documents to GeoPackage contents via gpkg_metadata and gpkg_metadata_reference.

CRS WKT

OGC standard. Extends gpkg_spatial_ref_sys with a definition_12_063 column that stores the full OGC WKT 2 representation of the SRS.

WebP

OGC standard. Declares that a tile table stores tiles in WebP format rather than PNG or JPEG.

Zoom Other

OGC standard. Signals that a tile table uses zoom levels with intervals other than a factor of 2.

Tile Scaling

NGA extension. Configures how GeoPackageTileRetriever fills missing tiles by scaling up or down from adjacent zoom levels. Scaling type and buffer are stored in nga_tile_scaling.

Feature Style

NGA extension. Associates style and icon records with individual features or entire feature tables using the Related Tables Extension. Styles are stored in nga_style and nga_icon tables.

Contents ID

NGA extension. Assigns a stable numeric identifier to each entry in gpkg_contents. Used internally by the Feature Style Extension to reference tables without relying on table name strings.

Feature Tile Link

NGA extension. Records explicit links between feature tables and tile tables in nga_feature_tile_link, allowing renderers to know which tile layers correspond to which feature layers.

Properties

NGA extension. Stores arbitrary key-value properties in a nga_properties attributes table, providing a simple mechanism for GeoPackage-level metadata.

How extensions are registered

Every extension inserts one or more rows into gpkg_extensions. Each row has the following columns:
ColumnDescription
table_nameThe user table the extension applies to, or NULL for GeoPackage-wide extensions
column_nameThe specific column, or NULL if not column-specific
extension_nameNamespaced name such as gpkg_rtree_index or nga_feature_style
definitionURI or document reference describing the extension
scoperead-write or write-only
ExtensionsDao provides typed access to this table.

Checking for an extension

import { GeoPackageAPI, RTreeIndexExtension } from '@ngageoint/geopackage';

const geoPackage = await GeoPackageAPI.open('/path/to/file.gpkg');

// Check whether the RTree Index extension is present on a feature table
const rtree = new RTreeIndexExtension(geoPackage);
const hasIndex = rtree.has('my_layer');
console.log('RTree index present:', hasIndex);

// Inspect all registered extensions
const extensionsDao = geoPackage.getExtensionsDao();
if (extensionsDao.isTableExists()) {
  const extensions = extensionsDao.queryForAll();
  while (extensions.moveToNext()) {
    const ext = extensions.getRow();
    console.log(ext.getExtensionName(), ext.getTableName());
  }
  extensions.close();
}

geoPackage.close();
When copying or deleting a table, call ExtensionManager.copyTableExtensions() or ExtensionManager.deleteTableExtensions() so that all extension-owned metadata and mapping tables are updated consistently.

Build docs developers (and LLMs) love