F.1. GeoPackage Non-Linear Geometry Types
Introduction
Clause 2.1.4 of the GeoPackage Version 1 Encoding Standard specifies support for the Geometry, Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection geometry types in the GeoPackageBinary geometry encoding format specified in clause 2.1.3. This extension specifies support for the additional CircularString, CompoundCurve, CurvePolygon, MultiCurve, MultiSurface, Curve, and Surface geometry types in the GeoPackage Binary geometry encoding format using the codes from Table 22.
Extension Author
GeoPackage SWG, author_name gpkg
Extension Name or Template
Extension names are constructed from the gpkg_geom_<gname> template where <gname> is the uppercase name of the extension geometry type from Table 22.
Extension Type
Applicability
This extension applies to any column specified in the gpkg_geometry_columns table.
Scope
Requirements
GeoPackage
Requirement 67
An extension name to specify a feature geometry extension type SHALL be defined for the "gpkg" author name using the "gpkg_geom_<gname>" template where <gname> is the uppercase name of the extension geometry type from Geometry Types (Normative) used in a GeoPackage.
Requirement 68
A GeoPackage that contains a gpkg_geometry_columns table or view with row records that specify extension geometry_type_name column values SHALL contain a gpkg_extensions table that contains row records with table_name and column_name values from the gpkg_geometry_columns row records that identify extension type uses, and extension_name column values for each of those geometry types constructed per the previous requirement [extension_geometry_types_extensions_name].
GeoPackage SQLite Configuration
GeoPackage SQLite Extension
Requirement 69
SQL functions that operate on GeoPackageBinary geometries as specified in other extensions SHALL operate correctly on the non-linear geometries specified in this extension.
Abstract Test Suite
GeoPackage Extension Types
Test Case ID |
/extensions/geometry_types/data_values_geometry_type_name |
Test Purpose |
Verify that only allowed geometry types (including extended non-linear geometry types) are in use. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/geometry_types/all_types_test_data |
Test Purpose |
Verify that geometries non-linear geometry types are stored in valid GeoPackageBinary format encodings. |
Test Method |
|
Reference |
|
Test Type |
Extensions Name
Test Case ID |
/extensions/geometry_types/extension_name |
Test Purpose |
Verify that an extension name in the form gpkg_geom_<gname> is defined for each <gname> extension geometry type from Annex G used in a GeoPackage. |
Test Method |
|
Reference |
|
Test Type |
Extensions Row
Test Case ID |
/extensions/geometry_types/extension_row |
Test Purpose |
Verify that the gpkg_extensions table contains a row with an extension_name in the form gpkg_geom_<gname> for each table_name and column_name in the gpkg_geometry_columns table with a <gname> geometry_type_name. |
Test Method |
|
Reference |
|
Test Type |
F.3. R-tree Spatial Indexes
Introduction
The R-tree Spatial Indexes extension provides a means to encode an R-tree index for geometry values in a GeoPackage. An R-tree index [B28] provides a significant performance advantage for searches with basic envelope spatial criteria that return subsets of the rows in a feature table with a non-trivial number (thousands or more) of rows.[K26]
Extension Author
GeoPackage SWG, author_name gpkg.
Extension Name or Template
Extension Type
Applicability
This extension applies to any column specified in the gpkg_geometry_columns table.
Scope
Write-only, because it does not change the result of reads, although it may improve their performance.
Requirements
GeoPackage
Requirement 75
The "gpkg_rtree_index" extension name SHALL be used as a gpkg_extensions table extension_name column value to specify implementation of spatial indexes on a geometry column.
Requirement 76
A GeoPackage that implements spatial indexes SHALL have a gpkg_extensions table that contains a row for each spatially indexed column with extension_name "gpkg_rtree_index", the table_name of the table with a spatially indexed column, the column_name of the spatially indexed column, and a scope of "write-only".
Requirement 77
A GeoPackage SHALL implement spatial indexes on feature table geometry columns using the SQLite Virtual Table R-trees and triggers specified below.
The tables below contain SQL templates with variables.
Replace the following template variables with the specified values to create the required SQL statements:
<t>: The name of the feature table containing the geometry column
<c>: The name of the geometry column in <t> that is being indexed
<i>: The name of the integer primary key column in <t> as specified in Requirement 29
Create Virtual Table
R-tree spatial indexes on geometry columns SHALL be created using the SQLite Virtual Table R-tree extension. An application that creates a spatial index SHALL create it using the following SQL statement template:
CREATE VIRTUAL TABLE rtree_<t>_<c> USING rtree(id, minx, maxx, miny, maxy)
where <t> and <c> are replaced with the names of the feature table and geometry column being indexed. The R-tree function id parameter becomes the virtual table 64-bit signed integer primary key id column, and the min/max x/y parameters are min- and max-value pairs (stored as 32-bit floating point numbers) for each dimension that become the virtual table data columns that are populated to create the spatial R-tree index.
Load Spatial Index Values
The indexes provided by the SQLite Virtual Table R-tree extension are not automatic indexes. This means the index data structure needs to be manually populated, updated and queried. Each newly created spatial index SHALL be populated using the following SQL statement
INSERT OR REPLACE INTO rtree_<t>_<c>
SELECT <i>, ST_MinX(<c>), ST_MaxX(<c>), ST_MinY(<c>), ST_MaxY(<c>) FROM <t> WHERE <c> NOT NULL AND NOT ST_IsEmpty(<c>);
where <t> and <c> are replaced with the names of the feature table and geometry column being indexed and <i> is replaced with the name of the feature table integer primary key column.
Define Triggers to Maintain Spatial Index Values
For each spatial index in a GeoPackage, corresponding insert, update and delete triggers that update the spatial index SHALL be present on the indexed geometry column. These spatial index triggers SHALL be defined as follows:
/* Conditions: Insertion of non-empty geometry
Actions : Insert record into R-tree */
CREATE TRIGGER rtree_<t>_<c>_insert AFTER INSERT ON <t>
WHEN (new.<c> NOT NULL AND NOT ST_IsEmpty(NEW.<c>))
BEGIN
INSERT OR REPLACE INTO rtree_<t>_<c> VALUES (
NEW.<i>,
ST_MinX(NEW.<c>), ST_MaxX(NEW.<c>),
ST_MinY(NEW.<c>), ST_MaxY(NEW.<c>)
);
END;
/* rtree_<t>_<c>_update1 is deprecated and is replaced by
rtree_<t>_<c>_update6 and rtree_<t>_<c>_update7 */
/* Conditions: Update of geometry column to empty geometry
No row ID change
Actions : Remove record from R-tree */
CREATE TRIGGER rtree_<t>_<c>_update2 AFTER UPDATE OF <c> ON <t>
WHEN OLD.<i> = NEW.<i> AND
(NEW.<c> ISNULL OR ST_IsEmpty(NEW.<c>))
BEGIN
DELETE FROM rtree_<t>_<c> WHERE id = OLD.<i>;
END;
/* rtree_<t>_<c>_update3 is deprecated and is replaced by
rtree_<t>_<c>_update5 */
/* Conditions: Update of any column
Row ID change
Empty geometry
Actions : Remove record from R-tree for old and new <i> */
CREATE TRIGGER rtree_<t>_<c>_update4 AFTER UPDATE ON <t>
WHEN OLD.<i> != NEW.<i> AND
(NEW.<c> ISNULL OR ST_IsEmpty(NEW.<c>))
BEGIN
DELETE FROM rtree_<t>_<c> WHERE id IN (OLD.<i>, NEW.<i>);
END;
/* Conditions: Update of any column
Row ID change
Non-empty geometry
Actions : Remove record from R-tree for old <i>
Insert record into R-tree for new <i> */
CREATE TRIGGER rtree_<t>_<c>_update5 AFTER UPDATE ON <t>
WHEN OLD.<i> != NEW.<i> AND
(NEW.<c> NOTNULL AND NOT ST_IsEmpty(NEW.<c>))
BEGIN
DELETE FROM rtree_<t>_<c> WHERE id = OLD.<i>;
INSERT OR REPLACE INTO rtree_<t>_<c> VALUES (
NEW.<i>,
ST_MinX(NEW.<c>), ST_MaxX(NEW.<c>),
ST_MinY(NEW.<c>), ST_MaxY(NEW.<c>)
);
END;
/* Conditions: Update a non-empty geometry with another non-empty geometry
Actions : Replace record from R-tree for <i> */
CREATE TRIGGER rtree_<t>_<c>_update6 AFTER UPDATE OF <c> ON <t>
WHEN OLD.<i> = NEW.<i> AND
(NEW.<c> NOTNULL AND NOT ST_IsEmpty(NEW.<c>)) AND
(OLD.<c> NOTNULL AND NOT ST_IsEmpty(OLD.<c>))
BEGIN
UPDATE rtree_<t>_<c> SET
minx = ST_MinX(NEW.<c>),
maxx = ST_MaxX(NEW.<c>),
miny = ST_MinY(NEW.<c>),
maxy = ST_MaxY(NEW.<c>)
WHERE id = NEW.<i>;
END;
/* Conditions: Update a null/empty geometry with a non-empty geometry
Actions : Insert record into R-tree for new <i> */
CREATE TRIGGER rtree_<t>_<c>_update7 AFTER UPDATE OF <c> ON <t>
WHEN OLD.<i> = NEW.<i> AND
(NEW.<c> NOTNULL AND NOT ST_IsEmpty(NEW.<c>)) AND
(OLD.<c> ISNULL OR ST_IsEmpty(OLD.<c>))
BEGIN
INSERT INTO rtree_<t>_<c> VALUES (
NEW.<i>,
ST_MinX(NEW.<c>), ST_MaxX(NEW.<c>),
ST_MinY(NEW.<c>), ST_MaxY(NEW.<c>)
);
END;
/* Conditions: Row deleted
Actions : Remove record from R-tree for old <i> */
CREATE TRIGGER rtree_<t>_<c>_delete AFTER DELETE ON <t>
WHEN old.<c> NOT NULL
BEGIN
DELETE FROM rtree_<t>_<c> WHERE id = OLD.<i>;
END;
where <t> and <c> are replaced with the names of the feature table and geometry column being indexed and <i> is replaced with the name of the feature table integer primary key column.
|
GeoPackage Versions 1.2.0 and prior have an incorrect update3 trigger that will fail in certain circumstances. GeoPackage Version 1.2.1 fixes this issue by replacing the update3 trigger. In GeoPackage 1.4.0, the decision was made to deprecate the update3 trigger and replace it with the new update5 trigger. This will allow clients to easily detect whether the correct trigger is in place. It is strongly recommended to update older GeoPackages by dropping the update3 trigger and adding the update5 trigger. The GeoPackage Executable Test Suite has been updated to accept either version of the trigger in older versions and to mandate the corrected version in versions after 1.2.0. In addition, GeoPackage Versions 1.3.1 and prior have a single update1 trigger that is incompatible with upsert statements. GeoPackage Version 1.4.0 fixes this issue by replacing the update1 trigger with the new update6 and update7 triggers. It is strongly recommended to update older GeoPackages by dropping the update1 trigger and adding the update6 and update7 triggers. The GeoPackage Executable Test Suite will be updated to accept either version of the trigger in older versions and to mandate the corrected version in versions after 1.3.1. If present, the deprecated triggers can be dropped with a
|
GeoPackage SQLite Configuration
Definition of SQLite configuration settings
| Setting compile or runtime | Option | Shall / Not (Value) | Discussion |
|---|---|---|---|
compile |
SQLITE_ENABLE_RTREE |
Shall |
R-trees are used for GeoPackage Spatial Indexes |
compile |
SQLITE_RTREE_INT_ONLY |
Not |
R-trees with floating point values are used for GeoPackage spatial indexes |
GeoPackage SQLite Extension
Definition of SQL functions
| SQL Function | Description | Use |
|---|---|---|
ST_IsEmpty(geom Geometry): integer |
Returns 1 if geometry value is empty, 0 if not empty, NULL if geometry value is NULL |
Test if a geometry value corresponds to the empty set |
ST_MinX(geom Geometry): real |
Returns the minimum X value of the bounding envelope of a geometry |
Update the spatial index on a geometry column in a feature table |
ST_MaxX(geom Geometry): real |
Returns the maximum Y value of the bounding envelope of a geometry |
Update the spatial index on a geometry column in a feature table |
ST_MinY(geom Geometry): real |
Returns the minimum X value of the bounding envelope of a geometry |
Update the spatial index on a geometry column in a feature table |
ST_MaxY(geom Geometry): real |
Returns the maximum Y value of the bounding envelope of a geometry |
Update the spatial index on a geometry column in a feature table |
|
The minimum bounding indexes created within the R-tree Extension for GeoPackage should reflect the appropriate bounding area for the indexed feature. However, due to varying precision implementations, it is not practical to assert this practice through a requirement or test. Clients should exercise care when using these indexes during queries because the SQLite R-tree module might round bounding boxes slightly outward (up to 0.000012%). Queries using spatial indexes should contain slightly expanded bounding boxes to guard against this. |
Abstract Test Suite
Extension Name
Test Case ID |
/extensions/rtree/extension_name |
Test Purpose |
Verify that spatial index extensions are registered using the "gpkg_rtree_index" name in the gpkg_extensions table. |
Test Method |
|
Reference |
|
Test Type |
Extensions Row
Test Case ID |
/extensions/rtree/extension_row |
Test Purpose |
Verify that the "gpkg_rtree_index" extension name is used to register spatial index extensions. |
Test Method |
|
Reference |
|
Test Type |
Implementation
Test Case ID |
/reg_ext/features/spatial_indexes/implementation |
Test Purpose |
Verify the correct implementation of spatial indexes on feature table geometry columns. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/reg_ext/features/spatial_indexes/implementation/sql_functions |
Test Purpose |
Verify the correct implementation of sql functions used in spatial indexes on feature table geometry columns. |
Test Method |
|
Reference |
|
Test Type |
F.6. Zoom Other Intervals
Introduction
This extension of clause Zoom Levels allows zoom level intervals other than a factor of two.
In a GeoPackage, zoom levels are integers in sequence from 0 to n that identify tile matrix layers in a tile matrix set that contain tiles of decreasing spatial extent and finer spatial resolution. Adjacent zoom levels immediately precede or follow each other and differ by a value of 1. Pixel sizes are real numbers in the terrain units of the spatial reference system of a tile image specifying the dimensions of the real world area represented by one pixel. Pixel sizes MAY vary by a constant factor or by different factors or intervals between some or all adjacent zoom levels in a tile matrix set. In the commonly used "zoom times two" convention, pixel sizes vary by a factor of 2 between all adjacent zoom levels, as shown in the example in [tiles_factor2_example_appendix].
This extension enables use of "zoom other intervals" conventions with different factors or irregular intervals with pixel sizes chosen for intuitive cartographic representation of raster data, or to coincide with the original pixel size of commonly used global image products. See WMTS [I16] Annex E for additional examples of both conventions.
Extension Author
GeoPackage SWG, author_name gpkg
Extension Name or Template
Extension Type
Extension of Existing Requirement in clause 2.2.3.
Applicability
This extension applies to any table listed in the gpkg_contents table with a data_type of tiles.
Scope
Requirements
GeoPackage
Requirement 87
The "gpkg_zoom_other" extension name SHALL be used as a gpkg_extensions table extension name column value to specify implementation of other zoom intervals on a tile pyramid user data table as specified in Zoom Other Intervals.
Requirement 88
A GeoPackage that implements other zoom intervals SHALL have a gpkg_extensions table that contains a row for each tile pyramid user data table with other zoom intervals with extension_name "gpkg_zoom_other", the table_name of the table with other zoom intervals, and the "tile_data" column_name.
Requirement 89
Tile pyramid user data tables MAY have pixel sizes that vary by irregular intervals or by regular intervals other than a factor of two (the default) between adjacent zoom levels. Extends Requirement 35.
The pixel_x_size and / or pixel_y_size column values in the gpkg_tile_matrix table vary by irregular intervals or by regular intervals other than a factor of two (the default) between adjacent zoom levels for a particular tile matrix set pyramid table.
GeoPackage SQLite Configuration
GeoPackage SQLite Extension
Abstract Test Suite
Extensions Name
Test Case ID |
/reg_ext/tiles/zoom_levels/data/zoom_other_ext_name |
Test Purpose |
Verify that the "gpkg_zoom_other" extension name is used to register tiles tables with other than factors of two zoom intervals. |
Test Method |
|
Reference |
|
Test Type |
Extensions Row
Test Case ID |
/reg_ext/tiles/zoom_levels/data/zoom_other_ext_row |
Test Purpose |
Verify that tiles tables with other than factors of two zoom intervals are registered using the "gpkg_zoom_other" extension name. |
Test Method |
/reg_ext/tiles/zoom_levels/data/zoom_other_ext_name |
Reference |
|
Test Type: |
Zoom Interval
Test Case ID |
/reg_ext/tiles/zoom_levels/data/zoom_intervals |
Test Purpose |
Verify that zoom level pixel sizes for tile matrix user data tables vary by factors of 2 between adjacent zoom levels in the tile matrix metadata table only for tile matrix sets that this extension does not apply to. |
Test Method |
|
Reference |
|
Test Type |
Introduction
Two tables in a GeoPackage provide a means of storing metadata in MIME [I21] encodings that are defined in accordance with any authoritative metadata specifications, and relating it to the entity stores (i.e., features, rasters, and tiles data) in a GeoPackage. These tables are intended to provide the support necessary to implement the hierarchical metadata models as defined in ISO 19115 [I28] and illustrated in Hierarchical Metadata Example One - ISO19115. and Raster or Tile Metadata Example. As GeoPackage data is captured and updated, the most local and specific detailed metadata changes associated with the new or modified data MAY be captured separately, and referenced to existing global and general metadata.
The gpkg_metadata table that contains metadata is described in clause Metadata Table, and the gpkg_metadata_reference table that relates gpkg_metadata to GeoPackage data is described in clause Metadata Reference Table.
There is no GeoPackage requirement that such metadata be provided or that defined metadata be structured in a hierarchical fashion [K27]. This extension simply provides a mechanism for storing this information. If this extension is used, such metadata [K28] and data that relates it to GeoPackage contents should not be stored in other tables.
Extension Author
GeoPackage SWG, author_name gpkg
Extension Name or Template
Extension Type
Applicability
This extension applies to any content in the GeoPackage.
Scope
Requirements
Table Definitions
The first component of GeoPackage metadata is the gpkg_metadata table that MAY contain metadata in MIME [I21] encodings structured in accordance with any authoritative metadata specification, such as ISO 19115 [I28], ISO 19115-2 [B6], ISO 19139 [B7], Dublin Core [B8], CSDGM [B10], DDMS [B12], NMF/NMIS [B13], etc.
The GeoPackage interpretation of what constitutes "metadata" is a broad one that includes UML models [B14] encoded in XMI [B15], GML Application Schemas [I30], ISO 19110 feature catalogues [B18], OWL [B20] and SKOS [B21] taxonomies, etc.
The md_standard_uri data value provides an identifier for the metadata structure (schema) specified by its definition authority. The structure (schema) information could be in whatever encoding is used by the definition authority, e.g. UML [B14], or IDEF1x [B16], or XML/Schema [I25][I26][I27], or RDF/S [B19].
The second component of GeoPackage metadata is the gpkg_metadata_reference table that links metadata in the gpkg_metadata table to data in the feature, and tiles tables defined in clauses 2.1.6 and 2.2.7.
The gpkg_metadata_reference table is not required to contain any rows.
Every row in gpkg_metadata_reference that has a NULL value as md_parent_id forms the root of a metadata hierarchy.[K31]
Table Data Values
gpkg_extensions
Requirement 140
GeoPackages with rows in the gpkg_extensions table with an extension_name of "gpkg_metadata" SHALL comply with this extension.
GeoPackages complying with this extension SHALL have rows in the gpkg_extensions table as described in Table 14 (below).
|
Requirement 140 was updated as part of GeoPackage 1.2.1.
In 1.1.0 and 1.2.0, the details of required |
The md_scope column in the gpkg_metadata table is the name of the applicable scope for the contents of the metadata column for a given row.
The list of valid scope names and their definitions is provided in Table 15 below.
The initial contents of this table were obtained from the ISO 19115 [I28], Annex B B.5.25 MD_ScopeCode code list, which was extended [K32] for use in the GeoPackage specification by addition of entries with "NA" as the scope code column in Table 12.
Requirement 94
Each md_scope column value in a gpkg_metadata table SHALL be one of the name column values from Table 15.
|
Each |
Requirement 96
Every gpkg_metadata_reference table reference scope column value SHALL be one of 'geopackage', 'table', 'column', 'row', 'row/col' in lowercase.
Requirement 97
Every gpkg_metadata_reference table row with a reference_scope column value of 'geopackage' SHALL have a table_name column value that is NULL.
Every other gpkg_metadata_reference table row SHALL have a table_name column value that references a value in the gpkg_contents table_name column.
Requirement 98
Every gpkg_metadata_reference table row with a reference_scope column value of 'geopackage','table' or 'row' SHALL have a column_name column value that is NULL.
Every other gpkg_metadata_reference table row SHALL have a column_name column value that contains the name of a column in the SQLite table or view identified by the table_name column value.
Requirement 99
Every gpkg_metadata_reference table row with a reference_scope column value of 'geopackage', 'table' or 'column' SHALL have a row_id_value column value that is NULL.
Every other gpkg_metadata_reference table row SHALL have a row_id_value column value that contains the ROWID of a row in the SQLite table or view identified by the table_name column value.
Requirement 100
Every gpkg_metadata_reference table row timestamp column value SHALL be in a DATETIME format as per Requirement 5.[K37]
Requirement 101
Every gpkg_metadata_reference table row md_file_id column value SHALL be an id column value from the gpkg_metadata table.
Requirement 102
Every gpkg_metadata_reference table row md_parent_id column value that is NOT NULL SHALL be an id column value from the gpkg_metadata table that is not equal to the md_file_id column value for that row.
Abstract Test Suite
Table Definition
Test Case ID |
/extensions/metadata/metadata/table_def |
Test Purpose |
Verify that the gpkg_metadata table exists and has the correct definition. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/table_def |
Test Purpose |
Verify that the gpkg_metadata_reference table exists and has the correct definition. |
Test Method |
|
Reference |
|
Test Type |
Table Data Values
gpkg_extensions
Test Case ID |
/extensions/metadata/extensions/data_values |
Test Purpose |
Verify that the gpkg_extensions table has the required rows. |
Test Method |
|
Reference |
|
Test Type: |
Test Case ID |
/extensions/metadata/metadata/data_values_md_scope |
Test Purpose |
Verify that each of the md_scope column values in a gpkg_metadata table is one of the name column values from Table 15. |
Test Method |
. SELECT md_scope FROM gpkg_metadata . Not testable if returns an empty result set . For each row returned from step 1 .. Fail if md_scope value not one of the name column values from Table 15. . Pass if no fails |
Reference |
|
Test Type: |
Test Case ID |
/extensions/metadata/metadata_reference/reference_scope |
Test Purpose |
Verify that gpkg_metadata_reference table reference_scope column values are valid. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/table_name |
Test Purpose |
Verify that gpkg_metadata_reference table_name column values are NULL for rows with reference_scope values of 'geopackage', and reference gpkg_contents table_name values for all other reference_scope values. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/column_name |
Test Purpose |
Verify that gpkg_metadata_reference column_name column values are NULL for rows with reference scope values of 'geopackage', 'table', or 'row', and contain the name of a column in table_name table for other reference scope values. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/row_id_value |
Test Purpose |
Verify that gpkg_metadata_reference row_id_value column values are NULL for rows with reference scope values of 'geopackage', 'table', or 'row', and contain the ROWID of a row in the table_name for other reference scope values. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/timestamp |
Test Purpose |
Verify that every gpkg_metadata_reference table row timestamp column value is in ISO 8601 UTC format. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/md_file_id |
Test Purpose |
Verify that every gpkg_metadata_reference table row md_file_id column value references a gpkg_metadata id column value. |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/metadata/metadata_reference/md_parent_id |
Test Purpose |
Verify that every gpkg_metadata_reference table row md_parent_id column value that is not null is an id column value from the gpkg_metadata_table that is not equal to the md_file_id column value for that row. |
Test Method |
|
Reference |
|
Test Type |
Table Definition SQL
|
GeoPackage versions 1.2.1 and prior had an optional validation triggers |
Example: gpkg_metadata_reference SQL insert statement (Informative)
INSERT INTO gpkg_metadata_reference VALUES (
'table',
'sample_rasters',
NULL,
NULL,
'2012-08-17T14:49:32.932Z',
98,
99
)
Examples (Informative)
Suppose we have this metadata:
and this reference table definition:
1) Consider a geographic data provider generating vector mapping data for three Administrative areas(A, B and C). … The metadata could be carried exclusively at Dataset Series level.
Then we need a record for each layer table for the three admin areas, like this:
INSERT INTO gpkg_metadata_reference VALUES (
'table', /* reference type */
'roads', /* table name */
'undefined', /* column_name */
-1, /* row_id_value */
(datetime('now')),
3, /* md_file_id */
0 /* md_parent_id */
)
2) After some time alternate vector mapping of Administrative area A becomes available. The metadata would then be extended for Administrative area A, to describe the new quality date values. These values would supersede those given for the Dataset series, but only for Administrative area A. The metadata for B and C would remain unchanged. This new metadata would be recorded at Dataset level.
Then we need a record for each layer table in "A" like this:
INSERT INTO gpkg_metadata_reference VALUES (
'table', /* reference type */
'roads', /* table name */
'undefined', /* column_name */
-1, /* row_id_value */
(datetime('now')),
4, /* md_file_id */
3 /* md_parent_id */
)
3) Eventually further data becomes available for Administrative area A, with a complete re-survey of the road network. Again this implies new metadata for the affected feature types. This metadata would be carried at Feature type level for Administrative area A. All other metadata relating to other feature types remains unaffected. Only the metadata for roads in Administrative area A is modified. This road metadata is recorded at Feature type level.
Then we need a record for each layer table for the roads network, like this:
INSERT INTO gpkg_metadata_reference VALUES (
'table', /* reference type */
'roads', /* table name */
'undefined', /* column_name */
-1, /* row_id_value */
(datetime('now')),
5, /* md_file_id */
4 /* md_parent_id */
)
4) An anomaly in the road survey is identified, in that all Overhead clearances for the Administrative area A have been surveyed to the nearest metre. These are re-surveyed to the nearest decimetre. This re-survey implies new metadata for the affected attribute type 'Overhead Clearance'. All other metadata for Administrative area A remains unaffected. This 'Overhead Clearance' metadata is recorded at Attribute Type level.
Then we need a record for each layer table in the roads network with attribute type 'Overhead Clearance', like this;
INSERT INTO gpkg_metadata_reference VALUES (
'column', /* reference type */
'roads', /* table name */
'overhead_clearance', /* column_name */
-1, /* row_id_value */
(datetime('now')),
7, /* md_file_id */
4 /* md_parent_id */
)
5) A new bridge is constructed in Administrative area A. This new data is reflected in the geographic data for Administrative area A, and new metadata is required to record this new feature. All other metadata for Administrative area A remains unaffected. This new feature metadata is recorded at Feature instance level.
Then we need a record for the bridge layer table row for the new bridge, like this:
INSERT INTO gpkg_metadata_reference VALUES (
'row', /* reference type */
'bridge', /* table name */
'undefined', /* column_name */
987, /* row_id_value */
(datetime('now')),
6, /* md_file_id */
4 /* md_parent_id */
)
6) The overhead clearance attribute of the new bridge was wrongly recorded, and is modified. Again this new attribute requires new metadata to describe the modification. All other metadata for Administrative area A remains unaffected. This new attribute metadata is recorded at Attribute instance level.
Then we need a record for the clearance attribute value, like this:
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'bridge', /* table name */
'overhead_clearance', /* column_name */
987, /* row_id_value */
(datetime('now')),
8, /* md_file_id */
4 /* md_parent_id */
)
This use case demonstrates a mechanism to indicate which data in a GeoPackage that was originally loaded with data from one or more services has been collected or updated since the initial load, and therefore MAY need to be uploaded to update the original services (e.g., WFS, WCS, WMTS).
Suppose a user with a mobile handheld device goes out in the field and collects observations of a new "Point of Interest" (POI) feature type, and associated metadata about the field session, the new feature type, some POI instances and some of their attributes (e.g., spatial accuracy, attribute accuracy) that results in the following additional metadata:
(This example assumes that the field session data is still considered "raw" and won’t be considered a data set or part of a data series until it has been verified and cleaned, but if that is wrong then additional series and data set metadata could be added.)
Then we need a gpkg_metadata_reference record for the field session for the new POI table, whose md_parent_id is undefined:
INSERT INTO gpkg_metadata_reference VALUES (
'table', /* reference type */
'poi', /* table name */
'undefined', /* column_name */
-1, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
1, /* md_file_id */
0 /* md_parent_id */
)
Then we need a gpkg_metadata_reference record for the feature type for the new POI table, whose md_parent_id is that of the field session:
INSERT INTO gpkg_metadata_reference VALUES (
'table', /* reference type */
'poi', /* table name */
'undefined', /* column_name */
-1, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
10, /* md_file_id */
1 /* md_parent_id */
)
Then we need gpkg_metadata_reference records for the poi feature instance rows, whose md_parent_id is that of the field session:
INSERT INTO gpkg_metadata_reference VALUES (
'row', /* reference type */
'poi', /* table name */
'undefined', /* column_name */
1, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
11, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row', /* reference type */
'poi', /* table name */
'undefined', /* column_name */
2, /* row_id_value */
14, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row', /* reference type */
'poi', /* table name */
'undefined', /* column_name */
3, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
17, /* md_file_id */
1 /* md_parent_id */
)
And finally we need gpkg_metadata_reference records for the poi attribute instance metadata , whose md_parent_id is that of the field session:
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'poi', /* table name */
'point', /* column_name */
1, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
12, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'poi', /* table name */
'point', /* column_name */
2, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
15, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'poi', /* table name */
'point', /* column_name */
3, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
18, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'poi', /* table name */
'category', /* column_name */
1, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
13, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'poi', /* table name */
'category', /* column_name */
2, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
16, /* md_file_id */
1 /* md_parent_id */
)
INSERT INTO gpkg_metadata_reference VALUES (
'row/col', /* reference type */
'poi', /* table name */
'category', /* column_name */
3, /* row_id_value */
(strftime('%Y-%m-%dT%H:%M:%fZ','now')),
19, /* md_file_id */
1 /* md_parent_id */
)
As long as all metadata collected in the field session either directly (as above) or indirectly (suppose there were a data set level metadata_reference record intermediary) refers to the field session metadata via md_parent_id values, then this chain of metadata references identifies the newly collected information, as Joan requested, in addition to the metadata.
So here is the data after both examples:
| reference_type | table_name | column_name | row_id_value | timestamp | md_file_id | md_parent_id |
|---|---|---|---|---|---|---|
table |
roads |
undefined |
0 |
ts |
3 |
0 |
table |
roads |
undefined |
0 |
ts |
4 |
3 |
table |
roads |
undefined |
0 |
ts |
5 |
4 |
column |
roads |
overhead_clearance |
0 |
ts |
7 |
4 |
row |
bridge |
undefined |
987 |
ts |
6 |
4 |
row/col |
bridge |
overhead_clearance |
987 |
ts |
8 |
4 |
table |
poi |
undefined |
0 |
ts |
1 |
0 |
row |
poi |
undefined |
0 |
ts |
10 |
1 |
row |
poi |
undefined |
1 |
ts |
11 |
1 |
row |
poi |
undefined |
2 |
ts |
14 |
1 |
row/col |
poi |
undefined |
3 |
ts |
17 |
1 |
row/col |
poi |
point |
1 |
ts |
12 |
1 |
row/col |
poi |
point |
2 |
ts |
15 |
1 |
row/col |
poi |
point |
3 |
ts |
18 |
1 |
row/col |
poi |
category |
1 |
ts |
13 |
1 |
row/col |
poi |
category |
2 |
ts |
16 |
1 |
row/col |
poi |
category |
3 |
ts |
19 |
1 |
A number of raster image processing problems MAY require the support of more metadata that is contained in the image itself.
Applications MAY use the gpkg_metadata and gpkg_metadata_reference tables defined in clause [_metadata] to store raster image metadata defined according to standard authoritative or application or vendor specific metadata models.
An example of the data items in such a model is shown in the following table.
-
Rational Polynomial Coefficient
-
Photometric Interpretation
-
No Data Value
-
Compression Quality Factor
-
Georectification
-
NIIRS
-
Min X
-
Min Y
-
Max X
-
Max Y
F.9. Schema
Introduction
The schema extension provides a means to describe the columns of tables in a GeoPackage with more detail than can be captured by the SQL table definition directly. The information provided by this extension can be used by applications to, for instance, present data contained in a GeoPackage in a more user-friendly fashion or implement data validation logic.
Extension Author
GeoPackage SWG, author_name gpkg
Extension Name
Extension Type
Applicability
Scope
Requirements
Table Definitions
Data Columns
| Column Name | Column Type | Column Description | Null | Key |
|---|---|---|---|---|
|
TEXT |
Name of a table specified in |
no |
PK, UK |
|
TEXT |
Name of the table column |
no |
PK |
|
TEXT |
A human-readable identifier (e.g. short name) for the column_name content |
yes |
UK |
|
TEXT |
A human-readable formal title for the column_name content |
yes |
|
|
TEXT |
A human-readable description for the column_name content |
yes |
|
|
TEXT |
MIME [I21] type of column_name if BLOB type, or NULL for other types |
yes |
|
|
TEXT |
Column value constraint name (lowercase) specified by reference to |
yes |
GeoPackage applications MAY [K38] use the gpkg_data_columns table to store minimal application schema identifying, descriptive and MIME [I21] type [K39] information about columns in user vector feature and tile matrix data tables that supplements the data available from the SQLite sqlite_master table and pragma table_info(table_name) SQL function.
The gpkg_data_columns data CAN be used to provide more specific column data types and value ranges and application specific structural and semantic information to enable more informative user menu displays and more effective user decisions on the suitability of GeoPackage contents for specific purposes.
|
In versions 1.2.1 and earlier, the |
Data Column Constraints
The gpkg_data_column_constraints table contains data to specify restrictions on basic data type column values.
The constraint_name column is referenced by the constraint_name column in the gpkg_data_columns table defined in Table 16.
| Column Name | Column Type | Column Description | Null | Key |
|---|---|---|---|---|
|
TEXT |
Name of constraint (lowercase) |
no |
Jointly Unique |
|
TEXT |
Type name of constraint: 'range' | 'enum' | 'glob' |
no |
Jointly Unique |
|
TEXT |
Specified case sensitive value for 'enum' or 'glob' or NULL for 'range' constraint_type |
yes |
Jointly Unique |
|
NUMERIC |
Minimum value for 'range' or NULL for 'enum' or 'glob' constraint_type |
yes |
|
|
BOOLEAN |
0 (false) if min value is exclusive, or 1 (true) if min value is inclusive |
yes |
|
|
NUMERIC |
Maximum value for 'range' or NULL for 'enum' or 'glob' constraint_type |
yes |
|
|
BOOLEAN |
0 (false) if max value is exclusive, or 1 (true) if max value is inclusive |
yes |
|
|
TEXT |
For ranges and globs, describes the constraint; for enums, describes the enum value. |
yes |
The min and max columns are defined as NUMERIC to be able to contain range values for any numeric data column defined with a data type from Table 1. These are the only exceptions to the data type rule stated in Req 5.
|
In GeoPackage 1.0, this table had column names |
Table Data Values
gpkg_extensions
Requirement 141
GeoPackages with rows in the gpkg_extensions table with an extension_name of "gpkg_schema" SHALL comply with this extension.
GeoPackages complying with this extension SHALL have rows in the gpkg_extensions table as described in Table 18 (below).
|
Requirement 141 was updated as part of GeoPackage 1.2.1.
In 1.1.0 and 1.2.0, the details of required |
| table_name | column_name | extension_name | definition | scope |
|---|---|---|---|---|
|
null |
|
see note below |
|
|
null |
|
see note below |
|
Data Columns
Requirement 104
Values of the gpkg_data_columns table table_name column value SHALL reference values in the table_name column from either gpkg_contents or gpkg_extensions.
Requirement 105
The column_name column value in a gpkg_data_columns table row SHALL contain the name of a column in the SQLite table or view identified by the table_name column value.
Requirement 106
The constraint_name column value in a gpkg_data_columns table MAY be NULL.
If it is not NULL, it SHALL contain a constraint_name column value (which SHALL be lowercase) from the gpkg_data_column_constraints table.
Data Column Constraints
The lowercase gpkg_data_column_constraints constraint_type column value specifies the type of constraint: "range", "enum", or "glob" (GLOB is a text pattern match - see [I33]).
The case sensitive value column contains an enumerated legal value for constraint_type "enum", a pattern match string for constraint_type "glob", or NULL for constraint_type "range". The set of value column values in rows of constraint_type "enum" with the same constraint_name contains all possible enumerated values for the constraint name. The min and max column values specify the minimum and maximum valid values for constraint_type "range", or are NULL for constraint_type "enum" or "glob". The min_is_inclusive and max_is_inclusive column values contain 1 if the min and max values (respectively) are inclusive, 0 if they are exclusive, or are NULL for constraint_type "enum" or "glob".
These restrictions MAY be enforced by SQL triggers or by code in applications that update GeoPackage data values.
| constraint_name | constraint_type | value | min | min_is_inclusive | max | max_is_inclusive |
|---|---|---|---|---|---|---|
sampleRange |
range |
NULL |
1 |
true |
10 |
true |
sampleEnum |
enum |
1 |
NULL |
NULL |
NULL |
NULL |
sampleEnum |
enum |
3 |
NULL |
NULL |
NULL |
NULL |
sampleEnum |
enum |
5 |
NULL |
NULL |
NULL |
NULL |
sampleEnum |
enum |
7 |
NULL |
NULL |
NULL |
NULL |
sampleEnum |
enum |
9 |
NULL |
NULL |
NULL |
NULL |
sampleGlob |
glob |
[1-2][0-9][0-9][0-9] |
NULL |
NULL |
NULL |
NULL |
Requirement 108
The gpkg_data_column_constraints table MAY be empty.
If it contains data, the lowercase constraint_type column values SHALL be one of "range", "enum", or "glob".
Requirement 109
The gpkg_data_column_constraint constraint_name values for rows with constraint_type values of "range" and "glob" SHALL be unique.
Requirement 110
The gpkg_data_column_constraints table MAY be empty.
If it contains rows with constraint_type column values of "range", the value column values for those rows SHALL be NULL.
Requirement 111
If the gpkg_data_column_constraints table contains rows with constraint_type column values of "range", the min column values for those rows SHALL be NOT NULL and less than the max column value which shall be NOT NULL.
Requirement 112
If the gpkg_data_column_constraints table contains rows with constraint_type column values of "range", the min_is_inclusive and max_is_inclusive column values for those rows SHALL be 0 or 1.
Requirement 113
If the gpkg_data_column_constraints table contains rows with constraint_type column values of "enum" or "glob", the min, max, min_is_inclusive and max_is_inclusive column values for those rows SHALL be NULL.
Requirement 114
If the gpkg_data_column_constraints table contains rows with constraint_type column values of "enum" or "glob", the value column SHALL NOT be NULL.
Abstract Test Suite
Table Definition
Data Columns
Test Case ID |
/extensions/schema/data_columns/table_def |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Data Column Constraints
Test Case ID |
/extensions/schema/data_column_constraints/table_def |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Data Values
gpkg_extensions
Test Case ID |
/extensions/schema/extensions/data_values |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type: |
Test Case ID |
/extensions/schema/data_columns/table_name |
Test Purpose |
Verify that for each |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/schema/data_columns/column_name |
Test Purpose |
Verify that for each |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/schema/data_columns/constraint_name |
Test Purpose |
Verify that for each |
Test Method |
|
Reference |
|
Test Type |
Data Column Constraints
Test Case ID |
/extensions/schema/data_column_constraints/constraint_type |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/schema/data_column_constraints/constraint_names_unique |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/schema/data_column_constraints/value_for_range |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/schema/data_column_constraints/min_max_for_range |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Test Case ID |
/extensions/schema/data_column_constraints/inclusive_for_range |
Test Purpose |
Verify that the |
Test Method |
|
Reference |
|
Test Type |
Test Case ID: |
/extensions/schema/data_column_constraints/min_max_inclusive_for_enum_glob |
Test Purpose: |
Verify that the |
Test Method: |
|
Reference |
|
Test Type |
Test Case ID: |
/extensions/schema/data_column_constraints/value_for_enum_glob |
Test Purpose: |
Verify that the |
Test Method: |
|
Reference |
|
Test Type |
Table Definition SQL
gpkg_data_columns
gpkg_data_columns Table Definition SQL
CREATE TABLE gpkg_data_columns (
table_name TEXT NOT NULL,
column_name TEXT NOT NULL,
name TEXT,
title TEXT,
description TEXT,
mime_type TEXT,
constraint_name TEXT,
CONSTRAINT pk_gdc PRIMARY KEY (table_name, column_name),
CONSTRAINT gdc_tn UNIQUE (table_name, name)
);
gpkg_data_column_constraints
gpkg_data_columns Table Definition SQL
CREATE TABLE gpkg_data_column_constraints (
constraint_name TEXT NOT NULL,
constraint_type TEXT NOT NULL, // 'range' | 'enum' | 'glob'
value TEXT,
min NUMERIC,
min_is_inclusive BOOLEAN, // 0 = false, 1 = true
max NUMERIC,
max_is_inclusive BOOLEAN, // 0 = false, 1 = true
description TEXT,
CONSTRAINT gdcc_ntv UNIQUE (constraint_name, constraint_type, value)
)