Skip to main content
The Metadata Extension (gpkg_metadata) provides a standard mechanism for embedding metadata documents inside a GeoPackage. Metadata is stored in the gpkg_metadata table and linked to GeoPackage objects (the file, specific tables, columns, or rows) through the gpkg_metadata_reference table.
This is an OGC-registered extension defined at http://www.geopackage.org/spec/#extension_metadata.

Core Tables

TablePurpose
gpkg_metadataStores the raw metadata documents (XML, JSON, text, etc.)
gpkg_metadata_referenceLinks metadata documents to GeoPackage objects

Key Classes

MetadataExtension

Manages the lifecycle of the extension itself (registration, table creation, removal).
import { MetadataExtension } from '@ngageoint/geopackage';

const metaExt = new MetadataExtension(geoPackage);

// Register the extension and create tables
metaExt.getOrCreateExtension();

// Check presence
const hasMetadata = metaExt.has();

// Remove all metadata tables and extension registrations
metaExt.removeExtension();

Metadata

A row in gpkg_metadata. Stores the document content and describes its encoding.
id
number
Auto-assigned primary key.
md_scope
string
Scope string from MetadataScopeType (e.g. 'dataset', 'table'). Describes what the metadata applies to.
md_standard_uri
string
URI identifying the metadata standard (e.g. http://www.isotc211.org/2005/gmd for ISO 19139).
mime_type
string
MIME type of the encoded metadata (e.g. text/xml, application/json).
metadata
string
The raw metadata document content.

MetadataReference

A row in gpkg_metadata_reference. Links a Metadata document to a specific target object.
reference_scope
string
One of the ReferenceScopeType values: geopackage, table, column, row, row/col.
table_name
string
Target table name. NULL when reference_scope is geopackage.
column_name
string
Target column name. Set only for column or row/col scopes.
row_id_value
number
Target row ID. Set only for row or row/col scopes.
md_file_id
number
Foreign key to gpkg_metadata.id.
md_parent_id
number | null
Optional foreign key to a parent gpkg_metadata.id for hierarchical metadata.

MetadataScopeType Values

The scope describes what entity the metadata document is about:
ValueStringDescription
UNDEFINEDundefinedScope is undefined
FIELD_SESSIONfieldSessionApplies to a field data collection session
COLLECTION_SESSIONcollectionSessionApplies to a collection session
SERIESseriesApplies to a dataset series
DATASETdatasetApplies to a geographic feature dataset
FEATURE_TYPEfeatureTypeApplies to a feature type (class)
FEATUREfeatureApplies to a single feature instance
ATTRIBUTE_TYPEattributeTypeApplies to an attribute class
ATTRIBUTEattributeApplies to a feature attribute
TILEtileApplies to a tile
MODELmodelApplies to a model
CATALOGcatalogApplies to a feature catalog
SCHEMAschemaApplies to an application schema
TAXONOMYtaxonomyApplies to a taxonomy or knowledge system
SOFTWAREsoftwareApplies to software
SERVICEserviceApplies to a service
COLLECTION_HARDWAREcollectionHardwareApplies to collection hardware
NON_GEOGRAPHIC_DATASETnonGeographicDatasetApplies to non-geographic data
DIMENSION_GROUPdimensionGroupApplies to a dimension group
STYLEstyleApplies to a specific style

ReferenceScopeType Values

Controls what GeoPackage object a MetadataReference row points to:
ValueStringPoints to
GEOPACKAGEgeopackageThe entire GeoPackage file
TABLEtableA specific table
COLUMNcolumnA specific column in a table
ROWrowA specific row in a table
ROW_COLrow/colA specific cell (row + column)

Creating and Attaching Metadata

1

Initialize the extension

import {
  GeoPackageAPI,
  MetadataExtension,
  Metadata,
  MetadataReference,
  MetadataScopeType,
  ReferenceScopeType,
} from '@ngageoint/geopackage';

const geoPackage = await GeoPackageAPI.open('my.gpkg');
const metaExt = new MetadataExtension(geoPackage);
metaExt.getOrCreateExtension();
2

Create a Metadata document

const metadataDao = geoPackage.getMetadataDao();

const meta = new Metadata();
meta.md_scope    = MetadataScopeType.DATASET;
meta.md_standard_uri = 'http://www.isotc211.org/2005/gmd';
meta.mime_type   = 'text/xml';
meta.metadata    = `<gmd:MD_Metadata>...</gmd:MD_Metadata>`;

const metaId = metadataDao.create(meta);
3

Create a MetadataReference linking the document to a table

const refDao = geoPackage.getMetadataReferenceDao();

const ref = new MetadataReference();
ref.reference_scope = ReferenceScopeType.TABLE;
ref.table_name      = 'my_features';
ref.md_file_id      = metaId;
ref.md_parent_id    = null;
ref.timestamp       = new Date().toISOString();

refDao.create(ref);

Attaching Metadata to a Specific Row

const rowRef = new MetadataReference();
rowRef.reference_scope = ReferenceScopeType.ROW;
rowRef.table_name      = 'my_features';
rowRef.row_id_value    = 42;          // the feature's row ID
rowRef.md_file_id      = metaId;
rowRef.timestamp       = new Date().toISOString();

refDao.create(rowRef);

Querying Metadata for a Table

const refDao = geoPackage.getMetadataReferenceDao();
const metadataDao = geoPackage.getMetadataDao();

// Get all references pointing to 'my_features'
const refs = refDao.queryByTableName('my_features');

for (const ref of refs) {
  const doc = metadataDao.queryForId(ref.md_file_id);
  console.log('Scope:', doc.md_scope);
  console.log('Standard:', doc.md_standard_uri);
  console.log('Content:', doc.metadata);
}

GeoPackage-Level Metadata

// Attach metadata to the GeoPackage file itself
const gpkgRef = new MetadataReference();
gpkgRef.reference_scope = ReferenceScopeType.GEOPACKAGE;
gpkgRef.table_name      = null;
gpkgRef.md_file_id      = metaId;
gpkgRef.timestamp       = new Date().toISOString();

refDao.create(gpkgRef);
Use MetadataScopeType.DATASET for dataset-level ISO 19115 records and MetadataScopeType.FEATURE for per-row provenance or quality metadata. Keep MIME types accurate (text/xml, application/json, text/plain) so consumers can decode the content correctly.

Build docs developers (and LLMs) love