Publication Date: 2021-01-13

Approval Date: 2020-12-14

Submission Date: 2020-11-16

Reference number of this document: OGC 20-019r1

Reference URL for this document: http://www.opengis.net/doc/PER/t16-D010

Category: OGC Public Engineering Report

Editor: Jeff Yutzler

Title: OGC Testbed-16: GeoPackage Engineering Report


OGC Public Engineering Report

COPYRIGHT

Copyright © 2021 Open Geospatial Consortium. To obtain additional rights of use, visit http://www.opengeospatial.org/

WARNING

This document is not an OGC Standard. This document is an OGC Public Engineering Report created as a deliverable in an OGC Interoperability Initiative and is not an official position of the OGC membership. It is distributed for review and comment. It is subject to change without notice and may not be referred to as an OGC Standard. Further, any OGC Public Engineering Report should not be referenced as required or mandatory technology in procurements. However, the discussions in this document could very well lead to the definition of an OGC Standard.

LICENSE AGREEMENT

Permission is hereby granted by the Open Geospatial Consortium, ("Licensor"), free of charge and subject to the terms set forth below, to any person obtaining a copy of this Intellectual Property and any associated documentation, to deal in the Intellectual Property without restriction (except as set forth below), including without limitation the rights to implement, use, copy, modify, merge, publish, distribute, and/or sublicense copies of the Intellectual Property, and to permit persons to whom the Intellectual Property is furnished to do so, provided that all copyright notices on the intellectual property are retained intact and that each person to whom the Intellectual Property is furnished agrees to the terms of this Agreement.

If you modify the Intellectual Property, all copies of the modified Intellectual Property must include, in addition to the above copyright notice, a notice that the Intellectual Property includes modifications that have not been approved or adopted by LICENSOR.

THIS LICENSE IS A COPYRIGHT LICENSE ONLY, AND DOES NOT CONVEY ANY RIGHTS UNDER ANY PATENTS THAT MAY BE IN FORCE ANYWHERE IN THE WORLD. THE INTELLECTUAL PROPERTY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE DO NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE INTELLECTUAL PROPERTY WILL MEET YOUR REQUIREMENTS OR THAT THE OPERATION OF THE INTELLECTUAL PROPERTY WILL BE UNINTERRUPTED OR ERROR FREE. ANY USE OF THE INTELLECTUAL PROPERTY SHALL BE MADE ENTIRELY AT THE USER’S OWN RISK. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY CONTRIBUTOR OF INTELLECTUAL PROPERTY RIGHTS TO THE INTELLECTUAL PROPERTY BE LIABLE FOR ANY CLAIM, OR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM ANY ALLEGED INFRINGEMENT OR ANY LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR UNDER ANY OTHER LEGAL THEORY, ARISING OUT OF OR IN CONNECTION WITH THE IMPLEMENTATION, USE, COMMERCIALIZATION OR PERFORMANCE OF THIS INTELLECTUAL PROPERTY.

This license is effective until terminated. You may terminate it at any time by destroying the Intellectual Property together with all copies in any form. The license will also terminate if you fail to comply with any term or condition of this Agreement. Except as provided in the following sentence, no such termination of this license shall require the termination of any third party end-user sublicense to the Intellectual Property which is in force as of the date of notice of such termination. In addition, should the Intellectual Property, or the operation of the Intellectual Property, infringe, or in LICENSOR’s sole opinion be likely to infringe, any patent, copyright, trademark or other right of a third party, you agree that LICENSOR, in its sole discretion, may terminate this license without any compensation or liability to you, your licensees or any other party. You agree upon termination of any kind to destroy or cause to be destroyed the Intellectual Property together with all copies in any form, whether held by you or by any third party.

Except as contained in this notice, the name of LICENSOR or of any other holder of a copyright in all or part of the Intellectual Property shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Intellectual Property without prior written authorization of LICENSOR or such copyright holder. LICENSOR is and shall at all times be the sole entity that may authorize you or any third party to use certification marks, trademarks or other special designations to indicate compliance with any LICENSOR standards or specifications.

This Agreement is governed by the laws of the Commonwealth of Massachusetts. The application to this Agreement of the United Nations Convention on Contracts for the International Sale of Goods is hereby expressly excluded. In the event any provision of this Agreement shall be deemed unenforceable, void or invalid, such provision shall be modified so as to make it valid and enforceable, and as so modified the entire Agreement shall remain in full force and effect. No decision, action or inaction by LICENSOR shall be construed to be a waiver of any rights or remedies available to it.

None of the Intellectual Property or underlying information or technology may be downloaded or otherwise exported or reexported in violation of U.S. export laws and regulations. In addition, you are responsible for complying with any local laws in your jurisdiction which may impact your right to import, export or use the Intellectual Property, and you represent that you have complied with any regulations or registration procedures required by applicable law to make this license enforceable.

Table of Contents

1. Introduction

1.1. Executive Summary

The OGC GeoPackage Standard has grown substantially in popularity in the Geospatial community. The GeoPackage Encoding Standard was originally developed to provide an open, standards-based platform for transferring and using geospatial information which is platform-independent, portable, self-describing, and compact. In the Testbed-16 GeoPackage activity, the participants developed ways to:

  • Improve the interoperability of GeoPackages through better metadata, and

  • Improve the performance of extremely large GeoPackages so that the format itself is no longer the limit on the size of datasets that can be distributed.

Previous work suggested three specific GeoPackage limitations:

  1. The ability to discover what geospatial content is in a GeoPackage so that a client can assess the type of data contained in a GeoPackage and to determine how it may be processed effectively,

  2. Lack of a standard ability to share portrayal information (styles and symbols) via GeoPackage, and

  3. Poor performance when loading and processing very large GeoPackage vector datasets in client software.

In Testbed-16, participants researched ways to mitigate these limitations, particularly in the context of the Ordnance Survey (OS) MasterMap Topography datasets. The Testbed activity also made use of OS Open Zoomstack, a smaller, freely available, multi-scale dataset. To address the first two limitations, Testbed participants developed GeoPackage metadata profiles designed to advance the discoverability of the contents of a GeoPackage and exchange the OS portrayal styles and symbols. The metadata proved to be interoperable between the server and client implementation.

To address the third limitation, Testbed participants developed a profile of GeoPackage suitable for OS MasterMap data and performed controlled experiments on GeoPackages that used different techniques designed to improve performance. The profile was designed to improve performance by reducing overall GeoPackage size, segment data into smaller GeoPackages, and optimize the ordering of the feature identifiers. OS MasterMap data proved to be an ideal test case due to its size and complexity. The participants demonstrated that large amounts of feature data could be distributed via the GeoPackage Encoding Standard in a manner that maximizes the efficiency of data access.

Based on the results of these tests, the participants recommend that these techniques be used by other GeoPackage-supporting software systems so that these techniques emerge as interoperable solutions. Standardization of these approaches may make it easier for other systems to be able to implement these new capabilities. As a result, the participants proposed a number of change requests and community extensions that are candidates for standardization as part of the GeoPackage ecosystem.

1.2. Document contributor contact points

All questions regarding this document should be directed to the editor or the contributors:

Table 1. Contacts
Name Organization Role

Jeff Yutzler

Image Matters

Editor

Andrea Aime

GeoSolutions

Contributor

Adam Parsons

Compusult

Contributor

1.3. Foreword

Attention is drawn to the possibility that some of the elements of this document may be the subject of patent rights. The Open Geospatial Consortium shall not be held responsible for identifying any or all such patent rights.

Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the standard set forth in this document, and to provide supporting documentation.

2. References

The following normative documents are referenced in this document.

Note

Only normative standards are referenced here, e.g. OGC, ISO or other SDO standards. All other references are listed in the bibliography.

3. Terms and definitions

For the purposes of this report, the definitions specified in Clause 4 of the OWS Common Implementation Standard OGC 06-121r9 shall apply. In addition, the following terms and definitions apply.

● controlled vocabulary

Controlled vocabularies provide a way to organize knowledge for subsequent retrieval and use. They are used in subject indexing schemes, subject headings, thesauri,[1][2] taxonomies and other forms of knowledge organization systems. Controlled vocabulary schemes mandate the use of predefined, authorized terms that have been preselected by the designers of the schemes, in contrast to natural language vocabularies, which have no such restriction. The use of controlled vocabularies in standards such as CDB can significantly increase interoperability and consistent understanding of the semantics. Controlled vocabularies typically are managed through formal processes and official governance.

● coordinate reference system

coordinate system that is related to the real world by a datum term name (source: ISO 19111)

● enumeration

In computer programming, an enumerated type (also called enumeration) is a data type consisting of a set of named values called elements, members, enumeral, or enumerators of the type. The enumerator names are usually identifiers that behave as constants in the language. Similarly, in a database enumerated (enum) types are data types that comprise a static, ordered set of values. They are equivalent to the enum types supported in a number of programming languages. An example of an enum type might be the days of the week, or a set of status values for a piece of data.

● GeoJSON

a geospatial data interchange format based on JSON (source: RFC 7946)

● glob

a pattern set for wildcard characters

● multiplicity

an indication of how many objects may participate in the given relationship, or the allowable number of instances of the element

● stylable layer set

a collection of styles designed to be used within the same domain

3.1. Abbreviated terms

  • COP Common Operational Picture

  • DDIL Denied Disconnected Intermittent Limited

  • GEMINI GEo-spatial Metadata INteroperability Initiative

  • GML Geography Markup Language

  • GPKG GeoPackage

  • JSON JavaScript Object Notation

  • OS Ordnance Survey

  • OWS OGC Web Services

  • PNG Portable Network Graphics

  • SLD Stylable Layer Descriptor

  • SVG Scalable Vector Graphics

  • UK United Kingdom

  • UML Unified Modeling Language

  • VTP2 OGC Vector Tiles Pilot, Phase 2

  • WFS Web Feature Service

  • WPS Web Processing Service

  • XML eXtensible Markup Language

3.2. Conventions

This Engineering Report uses a modified form of Unified Modeling Language (UML) to describe GeoPackage tables. Tables are represented as UML classes with the T label and columns are represented as UML attributes. The conventions used are as follows:

diag a14a91ca5f465f72f670a7ef05ecdd83
Figure 1. A green circle indicates a mandatory column.
diag bfd75325918a46dc9fe358fd66378e43
Figure 2. A solid arrow indicates a foreign key relationship, with the arrow label indicating the name of the referencing column in the dependent table.
diag c07587797956520c975516be131f8d17
Figure 3. A dashed arrow indicates a table_name relationship, with the arrow indicating the name of the referencing column in the referencing table.
diag e4d6bb3efcd6417911ee2a46d9b695c6
Figure 4. Non-explicit references between tables are indicated with a dashed arrow with a box at its base.

4. Overview

Section 5 describes the operational scenario used to test and demonstrate the work of this testbed activity.

Section 6 describes the efforts to encode metadata in a GeoPackage using draft GeoPackage metadata profiles.

Section 7 describes the efforts to improve GeoPackage performance when loading, accessing, and rendering very large vector datasets.

Section 8 describes the implementations produced by each of the participants.

Section 9 describes feedback, recommendations, and future work.

Annex A provides performance measurements and other statistics.

Annex B provides draft GeoPackage Extensions, including the metadata profiles.

Annex C provides example metadata documents.

Annex D provides schemas including database schemas and JSON schemas for metadata documents.

Annex E contains the revision history.

Annex F contains the bibliography.

5. Scenario

In Testbed 16, the data (see Datasets) was loaded into a GeoServer instance provided by GeoSolutions. GeoSolutions provided a WPS server that exported valid GeoPackages according to the various extensions evaluated in the GeoPackage Testbed 16 activity. Arrays present in the source data were converted to strings encoded as JSON arrays. The ensuing GeoPackages were opened by the Compusult GeoPackage client.

GeoPackages were created with several types of metadata:

This metadata increased the utility of the resulting GeoPackages, as demonstrated through the Compusult GeoPackage client.

In addition to metadata, the GeoPackages were created using a number of techniques to improve GeoPackage performance.

  1. Reduce overall dataset size by replacing text strings with more compact enumerations.

  2. Segment the data into smaller GeoPackages so that the file for each segment was not too big.

  3. Improve the ordering of the feature data so that it could be accessed more quickly.

Note

In addition, an approach for generalizing data was also researched. While generalization was not relevant for MasterMap data, the process led to significant performance gains for Zoomstack, in some cases as much as a 300X improvement in read throughput.

GeoSolutions captured metrics on how GeoPackage size was affected by the GeoPackage extensions that were used in creation. GeoSolutions also conducted performance measurement of client read speed when the ordering strategy was used. Compusult conducted performance measurement of client read speed when the segmentation, ordering, and generalization strategies were used. While benchmarking is difficult due to the inconsistency of disk speeds and access time, both GeoSolutions and Compusult were able to measure dramatic improvements in client read performance in their tests.

5.1. Datasets

The Testbed 16 activities used two separate data sets provided by Ordnance Survey.

5.1.1. OS MasterMap Topography

OS MasterMap topography is "the most detailed and accurate view of Great Britain’s landscape – from roads to fields, to buildings and trees, fences, paths and more." This dataset is delivered as a large set of GML files. The data can be used with a set of four freely available style sets also available as SLD. The MasterMap topography is to be displayed only at high scales (1:4000 and above). However, this dataset has a very significant size: 50GB as compressed GML files, 300GB as imported in PostgreSQL, and 200GB as an encoded GeoPackage (after optimizations). See MasterMap Data for more details. This dataset was ideal for tuning write and read performance, as well as experimenting with different content layouts.

5.1.2. OS Zoomstack

OS Zoomstack is a single GeoPackage providing "a single, customisable map of Great Britain to be used at national and local levels." Quoting from the documentation, "OS Open Zoomstack is a comprehensive vector basemap covering Great Britain at a national level, right down to street-level detail." This GeoPackage can be used with a set of six freely available style sets encoded, among other formats, as SLD.

The Zoomstack data set, around 11GB in size (see Space used by table, sorted from larger to smaller tables for details), provided a multi-scale map. Due to the small size of this dataset, the data was suitable for quick tests. As evident in Column level size details, geometries are the major component of space utilization in this dataset, while potentially enumerated fields (type when present) use an amount of space that is one or two orders of magnitude smaller.

In Testbed-16, participants used Zoomstack in scenarios where the huge size of the MasterMap data was cumbersome. Unlike the MasterMap dataset, ZoomStack is a true multi-zoom level dataset, visible from the country level and down to the road level, although not as detailed as the former. The data is also a natural fit for the generalized tables extension.

6. Metadata

Being able to discover what geospatial content is contained in a GeoPackage enables a developer to quickly assess the type of data contained in a GeoPackage and to determine how to best process the content. There is currently no agreement on the meaning and significance of metadata in GeoPackage or how that metadata should be used to serve any particular purpose. Without having to access the row entries in GeoPackage tables, manually opening a GeoPackage provides no way of recognizing if the file has any particular type of associated metadata.

6.1. The Metadata Extension

As described in the GeoPackage Getting Started Guide and illustrated in Figure 5, the Metadata Extension is enabled by adding two rows into gpkg_extensions:

c+m
Figure 5. The GeoPackage Metadata Extension

6.2. Semantic Annotations

Semantic annotations provide a way to represent the meaning of any business object (layer, feature, tile, style, etc.) through a resolvable URI. [1] In Testbed-16, semantic annotations were implemented in GeoPackage through the draft Semantic Annotations Extension. Semantic annotations may be placed on virtually any row in the GeoPackage.

6.3. Metadata Profiles

"Proposed GeoPackage Enhancements" cite:[Yutzler2019] proposed the concept of Metadata Profiles to meet this documented GeoPackage requirement. Profile creation consists of two parts:

  • Creating a new GeoPackage extension that defines a new “scope” (i.e., the gpkg_extensions.scope column) of "metadata".

  • Creating an extension for each metadata profile that describes the meaning and significance of a particular type of metadata.

Once the Metadata Extension is enabled, individual metadata profiles can be activated with additional rows in gpkg_extensions with a scope of "metadata". The Testbed-16 participants investigated implementing metadata profiles for OS MasterMap feature data. However, metadata profiles are also suitable for many other raster and imagery datasets. As described in the following subsections, participants tested a number of these profiles during Testbed-16 .

6.4. Common Operational Pictures

One of the use cases identified in the OGC OWS Context GeoJSON Encoding Standard is the exchange of a set of resources as a Common Operational Picture (COP). In Testbed-16, COPs were encoded as metadata in the GeoPackage as per GeoPackage Common Operational Picture Metadata Profile. The design for this capability is illustrated in Figure 6.

c+m owc1
Figure 6. The Common Operational Picture Metadata Profile

Since the OWS Context standard predates GeoPackage, OWS Context does not support referencing of GeoPackage layers. In Testbed-16, the participants extended OWS Context using the ideas first presented in "GeoPackage / OWS Context Harmonization Discussion Paper" cite:[Yutzler2018]. OWS Context GeoPackage Extension describes the extension used in Testbed-16 to extend OWS Context to represent GeoPackage contents.

In addition, semantic annotations were used to separate OWS Contexts representing COPs from OWS Contexts used for other purposes.

  • In gpkgext_semantic_annotations, a type of "im_metadata_cop_owc_geojson" was used and the title, description, and uri values were populated by the GeoPackage Producer.

  • In gpkgext_sa_reference, a row was added referencing the appropriate row in gpkg_metadata.

6.5. Dataset Details

UK GEMINI (GEo-spatial Metadata INteroperability Initiative) is a specification for a set of metadata elements that describe geospatial data resources. ISO 19115:2003 compliant UK GEMINI discovery level metadata is provided for the OS MasterMap data and can be found on the GIgateway®.

The following is a detailed description of the metadata elements that are provided on the GIgateway:

  • Title: The title of the product.

  • Abstract: The abstract gives a brief description of the product.

  • Currency: The currency takes the form of date of last update for the feature.

  • Lineage: The lineage metadata takes the form of product specification name and date of product specification.

  • Spatial extent: The spatial extent is supplied in the form of geographic identifiers (for example, England, Scotland, and Wales) and in the form of geographic coordinates.

  • Spatial reference system: The spatial reference system for all products takes the form of a British National Grid system, namely OSGB36®.

  • Data format: Data format takes the form of the name of the format or formats the product is supplied in.

  • Frequency of updates: Frequency of update takes the form of a stated period of time.

  • Distributor contact details: Distributor contact details include with postal address, phone number, fax number, email address and website.

  • Data originator: Given as the company having primary responsibility for the intellectual content of the data source; in all cases this will be Ordnance Survey.

  • Other metadata available includes keywords, start date of data capture, access constraints, use constraints, level of spatial data, supply media and presentation details.

Since GEMINI metadata is available for OS MasterMap, adding that metadata to the GeoPackage was a natural choice. GeoPackage Gemini Metadata Profile describes how GEMINI metadata documents may be added to a GeoPackage as metadata. As illustrated in Figure 7, one row is added to gpkg_metadata for each GEMINI document and one row is added to gpkg_metadata_reference for each GEMINI document – feature table combination.

c+m
Figure 7. The GeoPackage Metadata Extension for GEMINI Metadata

6.6. Dataset Provenance

In Testbed-16, GeoPackages were produced via a Web Processing Service (WPS) instance.

A WPS Execute request describes all of the relevant parameters, including which datasets are to be loaded into the GeoPackage. In core GeoPackage, there is no direct link between contents and their source. However the relationship may be described through metadata. This information may be useful when evaluating GeoPackage contents for fitness of purpose. This information could potentially enable in-field updates, such as when the source data is updated on a regular schedule.

There are a number of candidate encodings for the metadata including OWS Context. The OGC has adopted two encoding standards for OWS Context: Atom and GeoJSON. The Testbed-16 participants selected the GeoJSON encoding for this project because GeoJSON is easier for modern client applications to parse.

Note

"GeoPackage / OWS Context Harmonization Discussion Paper" cite:[Yutzler2018] proposed a relational encoding for OWS Context suitable for GeoPackage, but this approach stalled during Testbed-15.

The OWS Context GeoJSON Encoding specifies a number of offering types including WPS, WFS, and GML. In this metadata profile, an OWS Context document was populated with multiple resources:

  • A WPS resource indicating the WPS request that led to the creation of this GeoPackage

  • A WFS resource indicating the WFS instance that served the data after it was imported into GeoServer

6.6.1. Hierarchical Metadata

The GeoPackage Metadata Extension supports hierarchical metadata. Through hierarchical metadata, a GeoPackage client can identify metadata that pertains to the whole GeoPackage file and metadata that is relevant to a particular layer (e.g., feature table). In the Testbed-16 experiment, the metadata elements for the whole GeoPackage file included the WPS request that led to the creation of the GeoPackage. Further, the metadata elements for individual layers included descriptions of the WFS resources that served the data were included. Due to the hierarchical nature of the metadata, when needed a GeoPackage client can navigate from a the layer metadata to the metadata for the whole GeoPackage.

Note

Since a WFS (or other data resource) serving GeoPackage data might not be available online, the layer level dataset provenance metadata should be considered optional.

In the OWS Context GeoJSON encoding, the context is represented by a GeoJSON FeatureCollection and individual resources (layers) are represented by GeoJSON Feature instances. In this metadata profile, the FeatureCollection is inserted into gpkg_metadata as a metadata document, but the GeoJSON Feature instances referring to the feature data (not the WPS instance) are removed. The Feature instances are subsequently inserted into gpkg_metadata as their own entries.

As illustrated in Figure 8, gpkg_metadata_reference is populated as follows:

  • One row with an md_file_id of the parent metadata document reference_scope of "geopackage".

  • One row for each GeoPackage contents table and resource Feature instance, with an md_file_id of that Feature instance, a parent_id of the parent metadata document, and a reference_scope of "table".

c+m owc2
Figure 8. The Dataset Provenance Metadata Profile

6.6.2. Schema and Examples

6.6.3. Semantic Annotations

In addition, semantic annotations were used to separate OWS Contexts representing dataset provenance from OWS Contexts used for other purposes.

  • In gpkgext_semantic_annotations, a type of "im_metadata_dp_owc_geojson" was used and the title, description, and uri values were populated by the GeoPackage Producer.

  • In gpkgext_sa_reference, a row was added referencing the appropriate row in gpkg_metadata.

6.7. Portrayal

OS provides portrayal information for MasterMap in a GitHub repository. This repository contains styling rules using the OGC Styled Layer Descriptor (SLD) format and symbol information in both the Scalable Vector Graphics (SVG) and Portable Network Graphics (PNG) formats.

GeoPackage does not have core support for portrayal information, but recent efforts including the Vector Tiles Pilot, Phase 2 have led to a Portrayal Community Extension. Figure 9 illustrates how portrayal information can be added to GeoPackage through this extension.

diag 826ed2ab8a9f117e52acb84d04955157
Figure 9. The GeoPackage Portrayal Extension

6.7.1. Styles

The Portrayal Extension defines two tables for style information, gpkgext_styles and gpkgext_stylesheets. While this table structure allows a style to have multiple encodings, this feature was not used in Testbed-16.

These tables were populated as follows:

gpkgext_styles

  • id primary key

  • style a text name for the file

  • description null

  • uri the URL of the file landing page on GitHub

gpkgext_stylesheets

  • id primary key

  • style_id gpkgext_styles.id

  • format application/vnd.ogc.sld+xml;version=1.0

  • stylesheet the actual file

6.7.2. Symbols

The Portrayal Extension defines three tables for symbol information: gpkgext_symbols, gpkgext_symbol_images, and gpkgext_symbol_content. While this table structure supports multiple encodings for each style and encoding of multiple styles into a single file as sprites, neither of these approaches was used in Testbed-16.

These tables were populated as follows:

gpkgext_symbols

  • id primary key

  • symbol a text name for the file

  • description null

  • uri the URL of the file landing page on GitHub

gpkgext_symbol_images

  • id primary key

  • symbol_id gpkgext_symbols.id

  • content_id gpkgext_symbol_content.id

  • others null

gpkgext_symbol_content

  • id primary key

  • format "image/svg+xml"

  • content the actual file

  • uri the URL of the file on GitHub

The Portrayal Extension does not define an explicit coupling between layers and styles. (Coupling, in this context, refers to association of styles with layers.) Without any additional design elements, coupling is completely the responsibility of the user and/or client application as illustrated in Figure 10. In many scenarios, having the GeoPackage explicitly declare the coupling between layers and styles simplifies operations for the GeoPackage client operator. In Testbed-16, this coupling was done using semantic annotations.

f+p
Figure 10. GeoPackage Portrayal without Coupling to Layers

As illustrated in Figure 11, semantic annotations can be applied to features table and a style (a row in gpkgext_styles). This links the table and the style together.

c+sa
Figure 11. Semantic Annotations for OS MasterMap portrayal

In Testbed-16, semantic annotations were established for styles in a GeoPackage through the following:

  1. Ensure required tables are present as per the Semantic Annotations Extension:

    • gpkgext_sa_reference

    • gpkgext_semantic_annotations

  2. Populate gpkg_extensions with references to all tables mentioned above.

  3. Add a row to gpkgext_semantic_annotations for every style’s semantic annotation

    • type: Style

    • title: gpkgext_styles.style

    • description: gpkgext_styles.description

    • uri: gpkgext_styles.uri

  4. Add a row to gpkgext_sa_reference for every row that must be annotated.

    • The style in gpkgext_styles

    • Every table in gpkg_contents that is allowed to be used with that style (key_column_name and key_column_value are null).

6.7.4. Stylable Layer Sets

There are a number of scenarios where multiple styles or stylesheets are designed to be used together. In the Testbed-16 scenario, there are four stylesheets (standard, backdrop, light, outdoor) for each of the six feature types. Since a client user may wish to change the style for each layer at once, there needs to be a mechanism to aggregate these styles together. In Testbed-16, this was done through stylable layer sets. As developed in the OGC Vector Tiles Pilot, Phase 2 (VTP2), a stylable layer is created through a semantic annotation and both the styles and layers are tagged with that annotation.

In Testbed-16, semantic annotations were established for stylable layer sets in a GeoPackage through the following:

  1. Ensure required tables are present as per the Semantic Annotations Extension:

    • gpkgext_sa_reference

    • gpkgext_semantic_annotations

  2. Populate gpkg_extensions with references to all tables mentioned above

  3. Add a row to gpkgext_semantic_annotations for every style’s semantic annotation

    • type: StylableLayerSet

    • title: "backdrop", "light", "outdoor", or "standard"

    • description: null

    • uri: like a gpkgext_styles.uri, but with the filename replaced by /stylableLayerSet/[title]

  4. Add a row to gpkgext_sa_reference for every row that must be annotated

    • Every style in gpkgext_styles that is associated with that stylable layer set

    • Every table in gpkg_contents that is associated with that stylable layer set (key_column_name and key_column_value are null)

7. Large Vector Datasets

7.1. Baseline

During Testbed-16, the participants had access to the OS MasterMap Topography dataset. The dataset is licensed and may not be redistributed with permission. The download of the OS MasterMap Topography dataset is comprised of 50GB of gzipped GML files, allocated to 10 folders. The XML schemas for the GML files can be found here.

The data is meant to be rendered using the SLD version provided at the Topography Layer stylesheets. Each feature type is associated with 4 different variations of the styles, as illustrated by the following figures.

Table 2. Examples of Topography Layer Stylesheets. Contains OS data © Crown Copyright and database right 2020.

Backdrop 1 Backdrop

Light 1 Light

Outdoor 1 Outdoor

Standard 1 Standard

The styles are structurally similar. However, they each use different symbology for lines, points and polygon. In particular, the styles all have scale dependencies activating symbolization between presentation scales of 1:1 to 1:4000. No data are rendered at lower scales, making the portrayed map quite similar to a printed product. This is due to the very small range of visible scales.

7.2. Importing the Data

The GML content can be imported into GeoPackage using any of a variety of tools. In particular, there are tools specifically dedicated to the transformation of the GML datasets into a PostgreSQL database, with PostGIS extensions:

Both tools import directly into PostGIS and generate the same database structure, but the Lutra translator proved to be significantly faster. The database schemas are described in Database Schemas. Attributes with multiplicity higher than one have been translated into PostgreSQL array types.

7.3. Exporting the Data

For the most part, exporting the data was straightforward. However, a significant portion of the source data is in the form of arrays of either enumerations or date strings. In particular, the MasterMap arrays contain two types of data:

  • Dates, expressed as "YYYY-MM-DD".

  • Enumerated values, which can be expressed as compact enumerations (integers).

The GML loaders turn these two types into PostgreSQL arrays. Since SQLite databases do not support array column types, some translations were required to flatten arrays into JSON-encoded strings.

The Testbed participants chose to accomplish this translation by leveraging SQLite’s limited support for JSON through the JSON1 extension. These JSON arrays were used to hold either enumerations or date strings. The enumerations were as described above. The date strings were described by an appropriate glob [1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]. A SQLite GLOB operator is used to match only text values against a pattern using wildcards. The following two examples show a JSON representations of arrays:

  • "changedate" ["2000-11-10", "2002-08-09", "2003-05-20", "2003-05-20", "2017-03-01", "2018-09-14"]

  • "reasonsforchange" (enumerated) [2, 0, 3, 4, 2, 2]

Storing the arrays as JSON arrays comes with a few benefits:

  • The JSON format is well-known and widely supported.

  • If the extension is present in the SQLite build, the contents of the arrays can be queried via SQL.

  • The overhead of storing JSON as a string is limited to the additional element identifiers {}[] and delimiter ,.

Using the "application/json" content type plus an additional constraint representing either the enumeration (for the array contents) or a glob identifying the column as a date container, the JSON columns are exposed as such through a modified form of the schema extension. Through relaxing GeoPackage requirements 103 and 106 of the existing Schema Extension, participants were able express the fact that arrays were encoded in this manner. Requirement 103 describes the columns for gpkg_data_columns table. The revised schema allows for the use of the media type "application/json" to be used for JSON arrays. Requirement 106 describes how constraints are defined for columns. The revised requirement allows constraints to apply to each element of a JSON array when a JSON array is declared as described above. The modified Schema Extension is presented in an annex.

7.4. Reducing GeoPackage Size

GeoPackage read and write speed appears to decay with GeoPackage size. Since there are a number of factors that affect SQLite performance. including disk speed and record proximity, defining an exact formula for speed is difficult. Anecdotal information suggests something like O(logN) for reads and O(n log n) for building the spatial index. While SQLite is reasonably fast for datasets of moderate size, performance does begin to become a problem when datasets are in the tens of gigabytes or more. This issue is evident when working with MasterMap, which is over 200GB. The full MasterMap GeoPackage file, as generated by Lutra Translator II, from GML to PostGIS, and then down to GeoPackage via ogr2ogr, is 235GB in size. One way to improve GeoPackage performance is to reduce the size of the file.

Note

The GeoPackage, as generated by OGR, is already significantly smaller than the PostgreSQL tables. This is due to the SQLite database design. In PostgreSQL records contents are aligned for fast access to specific columns. For example, a 32 bit integer always uses 4 bytes, no matter what the actual number is. On the other hand, SQLite is designed to use the minimum possible space, so numbers are stored in the exact space they need. For example, 1 is stored as a single byte, while 1024 requires two bytes of storage.

7.4.1. Enumerations

Many attributes from the source OS data originally stored as strings can be expressed as enumerations (code lists). The GeoPackage schema extension allows encoding these enumerations as integers or single characters. Their descriptions are found in the gpkg_data_column_constraints table. Following are some examples of how GeoPackage data is encoded without and with enumerations.

Table 3. Feature properties without and with enumerations
Without Enumerations With Enumerations

["Administrative Boundaries"]

[1]

2.5m

1

["Modified", "Attributes", "New", "Position", "Modified", "Modified"]

[2, 0, 3, 4, 2, 2]

["Political Or Administrative"]

[17]

["Parish"]

[164]

Boundary

0

Parish Boundary

0

The complete set of enumerations used can be found in Enumerations. Using this approach reduced the MasterMap GeoPackage size from 245GB to 206GB, an improvement of roughly 20%.

7.4.2. Segmentation

MasterMap is meant to be displayed at scale down to 1:4000, but not lower. As a result, when displaying maps, most of the time is spent locating the tiny portion of data required. The grid split could then be leveraged as a way to reduce data access. This provides an index GeoPackage that simply spatially indexes the single GeoPackages in the grid, while also providing all the styling and metadata information required to present the full dataset. Under these conditions, rendering a map should require opening and processing the spatial indexes over a small number of files. In particular, the common case will be to read data from a single GeoPackage, while the worst case will be to open at most four, for any conceivable map display at 1:4000.

In response, the large MasterMap Topography dataset was split into smaller GeoPackages as described in Segmentation. These GeoPackages are available in the GeoServer osmm workspace, which is password protected (please ask for credentials). Each GeoPackage generates 6 layers in the GeoServer services. For example, in TQ.gpkg we have:

osmm:tq_boundaryline
osmm:tq_cartographicsymbol
osmm:tq_cartographictext
osmm:tq_topographicarea
osmm:tq_topographicline
osmm:tq_topographicpoint

This amounts to a grand total of 336 layers. There are also layer groups for the TQ zone, one for each possible styling of the six layers, for a grand total of 230 layer groups, for example:

tq_backdrop
tq_light
tq_outdoor
tq_standard

To take advantage of this segmentation, Testbed-16 participants produced the GeoPackage Index extension which supports an Index GeoPackage containing an index table. A client of the GeoPackage Index extension should be able to find all the metadata information about a feature entry in the main GeoPackage, including attribute information, geometry, schema, proper metadata, styles, and the overall bounding box of the layer. With that information, clients are able to locate which files contain records for a given feature entry and bounding box. If a particular geometry spans multiple GeoPackages, it is encoded in all of them. A key column named fid was used to identify the duplicates.

gpkg index shared feature
Figure 12. Encoding a feature across multiple segments

Each feature entry should have separate information for the following reasons:

  • Not all feature entries span the full set of sub-packages

  • Feature entries do not necessarily share the same coordinate reference system.

The idea is borrowed from [MapServer’s ogrtindex tool](https://mapserver.org/optimization/tileindex.html).

7.4.3. Dates

Dates in GeoPackage are expressed as ISO-8601 strings. The OS MasterMap database contains a number of dates, making them significant from the point of use of space usage. Participants considered two candidate approaches for reducing the storage space required for these data.

  1. Express dates as integer Unix epochs. Then a database view could be set up to expand the integer to the expected ISO-8601 string through the SRTFTIME function. However, the current 10-byte date representation is not significantly greater than 8-byte long integers. While a more compact representation optimized for dates is possible, this approach would require an extension to transform the compact representation back to the ISO-8601 string expected by clients. This would potentially limit, or make more complex, the ability to perform queries on those fields. The space considerations would have been different had the dates been timestamps.

  2. Expressing dates as enumerations. Since each date value is potentially used by many entries in the database, each date could be turned into an enumeration using the ISO-8601 form as the description of the value. However, this would have to be tested to determine whether the cost of the join negates the benefits of the enumeration.

Participants ultimately chose not to pursue either approach and to accept the status quo.

7.4.4. Geometry Encoding

As illustrated by the Zoomstack column sizes, geometries generated the largest columns. The following alternatives were considered and discarded:

  • FlatGeoBuf This approach is not better in terms of size and is probably slightly worse due to the alignment constraint)

  • TinyWKB This approach reduces the accuracy of the data.

  • TopoJSON This approach requires reorganizing not just the geometry, but entire feature records.

  • MVT This approach reduces the accuracy of the data.

7.5. Controlling records layout via sorting

When accessing a spatial subset of the full GeoPackage dataset, SQLite performs two operations as part of an SQL query:

  • Traverse the R-Tree to locate all geometries intersecting the target bounding box.

  • Fetch from disk the relevant records.

These operations are faster if the the number of disk read operations is reduced. The participants were able to accomplish this by sorting the data using a GeoHash and inserting the features in the sorted order. The following images borrowed from the postgis.net workshop illustrate the concept:

Table 4. Spatially uncorrelated vs correlated information.

clustering3

Un-balanced R-tree

clustering4

Balanced R-Tree

Table 5. Retrieving features from disk

clustering1

Correlated features scattered on the disk

clustering2

Correlated features stored close on disk

The images above might give the impression that proper correlation is important primarily for spinning disks. While that is certainly more important on spinning disk, proper co-location has benefits also for Solid State Disks (SSD). This is due to the minimum unit of access to the disk (page), typically 4 to 8 kilobytes worth of data. A single page can host a number of features, especially if the features are small. If features spatially correlated are also close on the disk, there is a higher chance that they fit into the same page, or a small number of pages, reducing the amount of physical IO required. This also plays a role in the Operating System (OS) file system caches, which can then host a larger number of relevant features given the same amount of physical RAM.

7.6. Generalization

GeoPackage performance degrades as the size of the relevant tables increases. To mitigate this decrease in performance, T-16 participants developed a mechanism for generalizing the largest tables for use at larger scales. (This approach would work for ZoomStack data but not for MasterMap because MasterMap data is only designed for use at 1:4000 scale.) The generalizes tables contain fewer features and simpler geometries than the base tables. While adding generalized tables does increase the overall GeoPackage size, the incremental size increase is minor, approximately a few percent. Through this technique, read performance was improved by a factor of 2-8X for data at a scale of 1:40,000 and as much as 300X for data at a scale of 1:200,000. See Generalization for how this was implemented.

8. Implementations

8.1. GeoSolutions

GeoSolutions used the GeoTools library and GeoServer software application. The GeoTools library gt-gpkg module provided the basic library to read and write GeoPackages as well as support for the official GeoPackage spatial indexing extension. The GeoServer GeoPackage WPS community module (gs-gpkg) provided the ability to generate GeoPackages from layers available in GeoServer, with detailed control on what to include in the resulting GeoPackage.

gs layer list
Figure 13. GeoServer layers. Each of them can be included in a GeoPackage via the WPS GeoPackage process.

Both the gt-gpkg and gs-gpkg modules were significantly improved during Testbed 16. GeoSolutions donated these improvements to the respective communities. The improvements started appearing in GeoTools 24 and GeoServer 2.18, released September 2020, and are fully included into GeoTools 25 and GeoServer 2.19, to be released March 2021.

8.1.1. Initial status

The GeoTools gt-gpkg module was able to read and write both vector and raster GeoPackages and had already received performance tuning for reading vector data. The only supported extension was the R-Tree spatial index.

The GeoServer gs-gpkg community module provided GeoPackage output formats for the WMS, WFS and WPS endpoints, in particular:

  • The WMS output format produced GeoPackages with tiled maps.

  • The WFS output format produced GeoPackages with the requested feature entries (one or more depending on the GetFeature request),

  • The WPS request allowed the generation of complete GeoPackages with both raster and vector contents. In particular, it supported the following:

    • Enumerating the GeoServer layers included in the output GeoPackage.

    • For each layer, control of:

      • The inclusion of raster map tiles versus raw vector data.

      • The bounding box spatially filtering the data.

      • Input query (filter and property names).

      • Reprojection of the output.

      • Optional generation of a R-Tree spatial index.

8.1.2. Importing MasterMap topography

For the Testbed 16 activity, OS MasterMap topography was delivered as a set of 1694 gzip-compressed GML files with a volume of over 50GB. The first challenge was to translate these files into a GeoPackage. There are two open source tools dedicated to the import of MasterMap GML files:

  • Astun’s Loader: A set of Python scripts orchestrating the GDAL/OGR libraries and converting them to a format of choice.

  • Lutra Consulting’s OS Translator II: A QGIS plugin optimized for speed.

The import was performed using OS Translator II to load the files into PostGIS. Then a dedicated tool was written to generate GeoPackages from the PostGIS content. Rationale:

  • OS Translator II focuses on speed thus allowing a full data transfer into PostGIS in a matter of hours. The Astun Loader tool would have taken days.

  • Various MapsterMap Topography attributes are multi-valued. PostgreSQL supports a native array type to host the attributes. GeoPackage does not have an equivalent support (an approach to represent arrays in GeoPackage has been developed during the Testbed).

  • The translation between PostGIS and GeoPackage provided a good test harness for experimenting with data transfer speed improvements at different scales, starting from a small portion of the data and up to the entire data sets.

8.1.3. Write performance enhancement

A major portion of the GeoSolutions activity involved writing large GeoPackages, ranging from a few GB for a ZoomStack subset to the 200GB required to store the entire MasterMap topography dataset in a single GeoPackage. A number of improvements to the GeoPackage writing code allowed for speeding up the WPS export of GeoPackages, making the export process up to 4 times faster compared to the original code. The improvements were:

  • Upgrade to the latest version of the SQLite JDBC driver.

  • Use of prepared statements and statement batching during records insertion. In particular, given the large size of the transfer, the batch size was set to ten thousands statements.[2].

  • Specifically setup the SQLite database for one-off generation, including enforcing exclusive access, turning off the transaction journal as well as synchronous writes. Further information can be found exploring the SQLite pragmas.

  • Some export operations involved reading from a GeoPackage data source as well. In these cases the data source was set to read-only and memory mapping enabled, to speed up the reading side.

8.1.4. GeoPackage extension framework and implementation

As part of the GeoTools core functionality, the GeoPackage module initially supported only the R-Tree spatial indexing extension. The Testbed required the implementation of a variety of extensions, some well known, as part of the core GeoPackage standard. In addition, new extensions were developed during the Testbed to experiment with new functionality. This work required a new extension point in the GeoTools library that would allow for a variety of extensions to be implemented while allowing them to be plugged in. This kept the core module small.

Thus, a new base class GeoPkgExtension was added to the GeoPackage module, providing the basic functionality shared by all extensions registered in the GeoPackage. These include:

  • Providing the extension identifier, definition, scope.

  • Checking if the extension is registered in the current GeoPackage.

  • Listing which tables/columns are associated with the extension.

The GeoPackage class can look up extensions using the extension identifier. The extensions can be registered as plugins using the Java Service Provider Interface. This allowed placing the extensions in different module based on their state of evolution:

  • The schema extension and the metadata extension, part of the core GeoPackage standard, were placed directly in the supported gt-gpkg module.

  • The portrayal, semantic annotation and generalized tables extensions were placed in the unsupported gs-gpkg module, placing no backward compability requirement on them, leaving the door open for future breaking changes.

Ultimately the gs-gpkg module is the sole user of all the above extensions, accessing and using them to generate the GeoPackages as required.

8.1.5. Metadata generation

The metadata and semantic annotation extension support was used to include the following information in the GeoPackages:

  • Any metadata linked from GeoServer layers.

  • A list of layers, with styles, as a OGC Web Services Context (OWC) document, allowing the client to re-construct a usable map.

  • The request that generated the GeoPackage, thus providing provenance and ancestry information.

GeoServer layers cannot contain metadata by themselves. However, they can link to existing online metadata.

gs layer metadata
Figure 14. GeoServer layer metadata links

When a layer links to metadata, the GeoPackage generator downloads the link contents, and places them in the metadata table, making it available for offline consumption. The entry is then associated with the pertinent layer using the metadata reference.

In a similar way, the WPS request gets recorded, stored in the metadata table, and associated to the entire GeoPackage as "Dataset provenance" via semantic annotation. In order to allow update of the GeoPackage contents, one metadata entry is also associated to each layer, providing back-links to a WFS service offering the layer.

The portrayal extension is used to store relevant styles and their resources (e.g. icons) in the GeoPackage. Each style associated to the layer in the GeoServer configuration is included in the GeoPackage:

gs layer styles
Figure 15. GeoServer layer style associations

Finally, a layer might be included in a "Layer group" which is the definition of a set of layers and their stacking order and style to be used. If the layers included in the GeoPackage are part of one or more layer groups, the definition of the group is translated into a OWC operational picture document. This provides the list of layers, their stacking order, and style to be used. In the case of MasterMap Topography, this results in 4 entries in the GeoPackage: One for each of the four style set shared by Ordnance Survey.

gs layer groups
Figure 16. GeoServer layer group definitions

8.1.6. Generalized Tables Extension

When datasets are large, it is common to serve them in a multi-scale fashion, where detailed information is only available at high scales and lower scales depict the most important features. Introduced as part of this Testbed, the generalized tables extension sets up parallel tables with generalized geometries and reduced record contents. These are meant to be displayed at lower scales, providing the client with faster access path to the information needed for map rendering. When properly set up, this leads to a significant difference in read speed.

Following is an excerpt of the WPS request creating two generalized tables for the woodland layer:

Creating two generalized tables for the woodland layer
<features name="woodland" identifier="woodland">
  <description>woodland</description>
  <srs>EPSG:27700</srs>
  <featuretype>oszoom:woodland</featuretype>
  <indexed>true</indexed>
  <styles>true</styles>
  <overviews>
    <overview>
      <name>woodland_g1</name>
      <scaleDenominator>80000</scaleDenominator>
      <filter xmlns:fes="http://www.opengis.net/fes/2.0">
        <fes:Or>
          <fes:PropertyIsEqualTo>
            <fes:ValueReference>type</fes:ValueReference>
            <fes:Literal>National</fes:Literal>
          </fes:PropertyIsEqualTo>
          <fes:PropertyIsEqualTo>
            <fes:ValueReference>type</fes:ValueReference>
            <fes:Literal>Regional</fes:Literal>
          </fes:PropertyIsEqualTo>
        </fes:Or>
      </filter>
    </overview>
    <overview>
      <name>woodland_g2</name>
      <scaleDenominator>320000</scaleDenominator>
      <filter xmlns:fes="http://www.opengis.net/fes/2.0">
        <fes:PropertyIsEqualTo>
          <fes:ValueReference>type</fes:ValueReference>
          <fes:Literal>National</fes:Literal>
        </fes:PropertyIsEqualTo>
      </filter>
    </overview>
  </overviews>
</features>

The woodland_g1 table is meant to be used in place of the base woodland table starting at a scale of 1:80.000. This table only contains National and Regional woodlands. The woodland_g2 table is meant to be used starting at a scale of 1:320.000 and only contains National woodlands.

For performance reasons, each generalized table is generated from the previous one. This leverages the progressive filtering work already done including the geometry generalization. For more information refer to the generalized tables extension. Full examples of generalized tables WPS requests can be found in the appendix.

8.1.7. Controlling records layout via sorting

To implement the strategy described in Controlling records layout via sorting, the GeoPackage process was extended to sort data before insertion into SQLite, according to one or more sort keys. This is important because SQLite generates the primary key of the table based on insertion order and preserves such order in the final file layout. In particular, GeoPackages with 3 layouts were generated:

  • Using the natural order of the data as as the data are being loaded. Evaluating the data, there is already some spatial correlation, but is incomplete.

  • Sorting by the geometry field, which causes the GeoPackage process to compute a GeoHash of the geometry and sort based on that sort key.

  • Sorting over a non spatially correlated field, like a road name, or internal identifier (MasterMap TID).

The following example shows a WPS request excerpt, sorting the "topographicline" layer by geometry, in other words, by GeoHash:

Sorting topographicline by GeoHash
   <features name="topographicline" identifier="topographicline">
     <description>boundaryline</description>
     <srs>EPSG:27700</srs>
     <featuretype>osmm:topographicline</featuretype>
     <sort xmlns:fes="http://www.opengis.net/fes/2.0">
       <fes:SortProperty>
         <fes:ValueReference>wkb_geometry</fes:ValueReference>
       </fes:SortProperty>
     </sort>
     <indexed>true</indexed>
     <styles>true</styles>
   </features>

The following instead sorts the topographicline layer by fid (also known as TID in MasterMap Topography):

Sorting topographicline by an alphanumeric, non spatially correlated identifier.
   <features name="topographicline" identifier="topographicline">
     <description>boundaryline</description>
     <srs>EPSG:27700</srs>
     <featuretype>osmm:topographicline</featuretype>
     <sort xmlns:fes="http://www.opengis.net/fes/2.0">
       <fes:SortProperty>
         <fes:ValueReference>fid</fes:ValueReference>
       </fes:SortProperty>
     </sort>
     <indexed>true</indexed>
     <styles>true</styles>
   </features>
8.1.7.1. Benchmarking the GeoHash sorting

In order to provide a server side comparison between the original data order, as imported from GML, and GeoHash sorted GeoPackages, a GeoServer WMS benchmark has been run, drawing the maps from MasterMap.

The benchmarking is defined as follows:

  • Over 4000 unique random WMS requests have been created, all over the UK land, to be issued during the benchmark.

  • JMeter is used to generate increasingly high number of parallel WMS requests picked from the above list, starting with a single request, and progressing through 2, 4, 8, 16 and 64 concurrent requests.

  • Each set of concurrent requests generates statistics, such as response time statistics and throughput, measured as requests per second.

Table 6. Request area samples, starting from distribution at the country level and going to higher detail
benchmark locations low
benchmark locations mid
benchmark locations high

The benchmarks were executed under two sets of conditions:

  • "Hot benchmark", with the whole suite repeated, in sequence, several times, until the performance value settle to stable results. The system has enough memory to allow the Operating System (OS) file system cache to fully contain all the data needed, thus, no input/output (I/O) is observed during the load test.

  • "Cold benchmark", in which all the OS caches have been forcefully dropped, making GeoServer read each data bit directly from the disk. Continuous data read from disk has been verified using system utilities (iotop).

The hardware used for the tests was a desktop machine (developer workstation) with the following specifications:

  • AMD Ryzen 1700x, 8 physical cores, with hyperthreading (the OS sees 16 virtual cores). The CPU frequency governor has been forced to "performance" mode, meaning CPU core are running at their highest frequency all the time (instead of scaling down to lower frequencies when there is less load).

  • 32GB memory.

  • Internal 512GB SSD, NVME connection, Samsung 960 PRO. This disk was not used in benchmarks due to lack of free space.

  • Internal 2TB spinning disk, Seagate Barracuda, with 64MB of internal cache (used in the second benchmark).

  • External SanDisk Extreme 500GB disk, connected via a USB3 port (used in the first benchmark).

8.1.7.1.1. SSD Drive

The following table and chart report the throughput (request per second) in the various cases, when using the external SanDisk Extreme SSD drive:

Table 7. GeoServer WMS benchmark results, SSD drive
Concurrent requests Original order, "cold" Original order, "hot" GeoHash sorted, "cold" GeoHash sorted, "hot"

1

7.36

13.29

14.38

16.91

2

10.38

19.94

23.67

25.99

4

23.34

35.09

44.79

46.55

8

37.55

51.46

56.62

58.24

16

43.36

61.14

61.11

61.59

32

41.75

45.99

58.82

60.24

64

41.67

49.75

59.35

61.33

gs benchmark ssd
Figure 17. GeoServer WMS benchmark results chart, SDD drive

Observations

  • The data with original sorting is consistently slower than the one with GeoHash sorting

  • The package in original order sees a significant performance difference between cold and hot, while the GeoHash sorted has virtually no difference between them

  • Even in hot mode, the package with the original order does not manage to reach the performance of the GeoHash sorted. We speculate this could be an indication that even when fully cached, the distribute of data in the cache is less efficient, and likely causing more OS calls than the GeoHash one.

8.1.7.1.2. Hard Disk

To evaluate the importance of an efficient disk storage, a second set of benchmarks has been run against the internal Seagate spinning disk. This disk has good sequential read performance, but as most spinning disk, suffers on random access.

Running the same benchmark required hours, making it impossible to run a "hot" version of it (the cache got invalidated, as with most modern machines, there is a number of other background activities happening over the span of several hours):

Table 8. GeoServer WMS benchmark results, requests per second, spinning disk drive
Concurrent requests Original order, "cold" GeoHash sorted, "cold"

1

0.48

2.44

2

0.26

1.75

4

0.48

2.46

8

0.59

3.30

16

0.75

4.11

32

0.76

4.34

64

0.85

2.20

gs benchmark spinning
Figure 18. GeoServer WMS benchmark results chart, requests per second, on spinning disk drive.

Observations

  • The performance hit compared to the SSD is severe, even the GeoHash sorted package is an order of magnitude slower (4.3 r/s tops vs 61.5r/s tops).

  • The performance ratio between the GeoHash and the original package has been magnified, ranging between 2.5 and 4 times.

8.1.7.1.3. Maximum Response Times

It is also interesting to see a comparison of the maximum response time recorded during this spinning disk benchmark, at various load levels:

Table 9. GeoServer WMS benchmark results, maximum response time in milliseconds, spinning disk drive
Concurrent requests Original order, "cold" GeoHash sorted, "cold"

1

27102

1104

2

84874

5086

4

141793

10381

8

347901

12273

16

394209

27039

32

561954

50626

64

744749

102795

Observations As expected, the performance of the original GeoPackage proved to insufficient to make map browsing practical. However, the introduction of GeoHash ordering improved performance to the point that it is bearable even for extremely large GeoPackages.

8.1.8. GeoPackage Index extension

GeoSolutions prepared an example of a GeoPackage index and the associated GeoPackage parts. The split of the main GeoPackage has been performed along the 100KM UK national grid, depicted in the following image.

uk national grid 100km
Figure 19. UK 100KM national grid

While the squares have the same area, their contents vary significantly, from the smallest, SC.gpkg, weighting only 272KB, to the largest, TQ.gpkg, using 12GB of disk space.

A index GeoPackage has then been created, with the following characteristics:

  • All feature tables are present, and fully described, with metadata and styles, but have no contents.

  • The gpkgext_index table contains one entry per feature table, referencing a index table following the gpkgext_<main_table_name>_index naming convention.

  • The per table index contains one entry for each sub-geopackage that contains any record for that table. This results in some tables referencing all 54 GeoPackages, while for example gpkext_boundarile_index contains only 46, as some squares are not intersecting any boundaryline.

Table 10. The gpkgext_index table contents
table_name index_table_name key_column

boundaryline

gpkgext_boundaryline_index

fid

cartographicsymbol

gpkgext_cartographicsymbol_index

fid

cartographictext

gpkgext_cartographictext_index

fid

topographicarea

gpkgext_topographicarea_index

fid

topographicline

gpkgext_topographicline_index

fid

topographicpoint

gpkgext_topographicpoint_index

fid

Table 11. An excerpt from the gpkgext_boundaryline_index table
file min_x min_y max_x max_y

ND.gpkg

292879.5

915090.38

347962.13

995248.76

NW.gpkg

199749.0

553919.7

199816.1

553994.6

TQ.gpkg

499050.869

99278.28

602344.9

203093.29

TF.gpkg

498060.214

297787.03

602679.63

400834.96

NC.gpkg

207468.92

888949.2

330676.781

974571.8

NK.gpkg

398797.73

823737.98

413618.1

866884.4

8.2. Compusult

Compusult provided a client implementation for testing and demonstration of developed concepts as well as performance metric collection for this testbed activity. The desktop and mobile GeoPackage client was updated to support the new/updated GeoPackage extensions to support semantic annotations, portrayal, metadata profiles, generalizations and storage optimizations for large vector data-sets. A profiling module was also implemented to generate performance metrics to provide feedback regarding performance improvements when using table generalizations and GeoPackages sorted using the Geohash algorithm.

8.2.1. Portrayal

Building from the work done for portrayal during the Vector Tiles Pilot, the client was updated to support the updated (draft) Portrayal Extension for GeoPackage. Using the proposed Semantic Annotation Extension style references are looked up for each layer using the gpkgext_sa_reference and gpkgext_semantic_annotations tables. The client retrieves the style metadata and content from the gpkgext_styles and gpkgext_stylesheets allowing the client to view and select a style of there choosing. The selection of OS MasterMap and OS Open Zoomstack styles is illustrated in Table 12.

Table 12. Dataset Layer Styles.

mastermap layer styles OS MasterMap

zoomstack layer styles OS Open Zoomstack

The client allows a user to specify the style to use for each layer and dynamically update the map on selection. SLD style documents were provided for both OS MasterMap and OS Open Zoomstack layers. SLD documents can provide symbol content as an online resource for online scenarios or use symbol references which the client uses to retrieve symbol information using the gpkgext_symbols, gpkext_symbol_content and gpkgext_symbol_content tables. Since most supplied symbols were of the format image/svg+xml and were to drawn based on scale of the map the client caches scaled versions of the image at distinct scale steps to ensure new images were not created for each scale change without significantly degrading size approximation. A demonstration of changing the style of topographicarea for the OS MasterMap dataset is illustrated in Table 13.

Table 13. OS MasterMap Topographic Area Style Modification. Contains OS data © Crown Copyright and database right 2020.

mastermap topographicarea standard Standard

mastermap topographicarea outdoor Outdoor

Using the semantic Semantic Annotation Extension Stylable Layer Sets were determined and displayed to the user giving them the ability to change the styles of all layers to a common style set or theme. The style sets for OS MasterMap are illustrated in Figure 20.

mastermap styleablelayerset
Figure 20. MasterMap Styleable Layer Sets

With the ability to update the map to a defined theme the client dynamically updates the map based on the user selection. Style documents are cached upon use and a cache of style to feature at a particular scale is constructed to improve performance when performing style based filtering in memory. An illustration of OS MasterMap rendering using the outdoor, indoor, light, and backdrop style sets can be seen in Table 14.

Table 14. MasterMap Rendered Style Sets. Contains OS data © Crown Copyright and database right 2020.

mastermap standard Standard

mastermap outdoor Outdoor

mastermap light Light

mastermap backdrop Backdrop

Performance and querying improvements for vector data sets were gained by leveraging the scale hints defined in the associated style documents ensuring that the client only requests data when it is appropriate for styling. Using the scale of the map and the MinScaleDenominator and MaxScaleDenomintor as filters a WHERE clause was constructed by converting and combining all the <ogc:Filter> for each applicable style to an appropriate SQL filter definition. Furthermore, layer data will not be queried at all if it does not fall inside of the MinScaleDenominator and MaxScaleDenomintor requirements of the applied stylesheet.

8.2.2. Metadata Profiles

Leveraging the ability to determine stored GeoPackage metadata contextual information the client provides the users the ability to browse and view metadata on the Dataset(GeoPackage) and Table(Layer) levels. Metadata Profiles available in the OS MasterMap and OS Open Zoomstack datasets illustrated in Table 15. All metadata regardless of profile is viewable in the client.

gpkg metadata option
Figure 21. GeoPackage option available when Metadata is available.
Table 15. Dataset metadata.

mastermap metadata OS MasterMap

zoomstack metadata OS Open Zoomstack

With the new ability to understand the context of the metadata provided using the semantic Semantic Annotation Extension and the Metadata Extension along with the proposed Metadata Profiles concept, new functionality was added depending on the types of profiles in use.

8.2.2.1. Common Operation Picture Profile

When the Common Operational Picture (COP) profile is encountered using the type im_metadata_cop_owc_geojson, users are given the ability to to view the resources and offerings relating to the layers in gpkg_contents.

mastermap load context
Figure 22. Loading the content for OS MasterMap Standard Context

The OWS Context can be used to quickly load a scenario without having to make modifications to each individual layer. Since the GeoPackage core does not define a layer order, the Common Operational Picture (COP) profile allows producers to supply a layer order critical for rendering maps in proper drawing order.

Table 16. Context Layer Order Display.

mastermap layer order OS MasterMap

zoomstack layer order OS Open Zoomstack

Each context resource has a defined style which references a style defined using the Portrayal Extension and gpkgext_styles table, allowing a user to quickly define a style set to be used for a particular scenario. The available Common Operation Pictures for OS Open Zoomstack can be seen below in Table 17.

Table 17. OS Open Zoomstack Rendered Context Documents. Contains OS data © Crown Copyright and database right 2020.

zoomstack outdoor Outdoor

zoomstack light Light

zoomstack night Night

zoomstack road Road

zoomstack tritanopia Tritanopia

zoomstack deuternopia Deuternopia

8.2.2.2. Dataset Provenance

Future client updates intend to use the Dataset Provenance profile with the type of im_metadata_dp_owc_geojson to allow the client to access the services that provide the raw data in online scenarios as well using supported services to provide or retrieve data updates.

mastermap wps operation
Figure 23. Dataset Provenance profile - WPS Operations
mastermap raw layer metadata
Figure 24. OS MasterMap - GEMINI Metadata

8.2.3. Large Vector Datasets

In this section performance metrics are gathered comparing the various techniques used to optimize Large Vector Datasets size and performance. Since we are dealing with large datasets, depending on the scenario, it will be quite common to use mechanical drives. To provide a range of metrics, solid state (SSD) and mechanical drives (HDD) were used. The full hardware details for the desktop machine that the metrics were gathered on include :

  • Hexa core Intel Core i7-8700 (3.20 GHz)

  • 32GB RAM

  • 12MB Cache

  • HDD - ST1000LX015-1U71 - 1TB 5400RPM

  • SSD - Samsung SSD 860 - 1TB

8.2.3.1. Enumerations

To provide optimal performance and storage of large vector data-sets, the client was updated to support array-based enumerations allowing for reduced size in offline content. Using the gpkg_data_column_constraints along with the mime_type column in gpkg_data_columns, the client can decode JSON array-based enumerations found in feature attributes as illustrated in Figure 25. Using the JSON1 extension, the client can also query for features when an enumeration is part of a filter avoiding the requirement to perform specialized string based queries.

Table 18. OS MasterMap Topographic Area Reason for Change Enumeration

mastermap enumeration constraints

mastermap enumeration db

mastermap enumeration
Figure 25. OS MasterMap Topographic Area Feature Metadata Display. Contains OS data © Crown Copyright and database right 2020.
8.2.3.2. Generalization

The client was updated to use the Generalization extension and the extension table gpkgext_generalized to optimize rendering performance using scale based style information and geometry simplification. The OS Open Zoomstack dataset contained both generalized and non-generalized tables the selected generalized tables can be seen below. Feature tables were selected for querying from gpkgext_generalized based on the current scale denominator of the map client and the distance value for the generalized table. A simple profiler was implemented to gather performance metrics comparing the generalized and non-generalized dataset. Comparison between the standard and generalized tables on the mechanical drive ST1000LX015-1U71 and the solid state drive Samsung SSD 860 can be seen below at Table 19.

Table 19. OS Open Zoomstack Generalization Performance (HDD and SSD)
table name feature count generalization scale denominator HDD SSD HDD/SSD

roads_local_g1

3,026,133

40,000

1.0-2.0X

1.0X

1.0X

waterlines_g3

2,429,712

600,000

40.2-70.1X

10.1-12.5X

3.9-5.6X

waterlines_g2

2,429,712

200,000

30.0-45.0X

5.5-6.5X

5.4-6.9X

waterlines_g1

2,429,712

40,000

2.0-7.0X

1.0-1.6X

2-4.4X

woodland_g2

1,263,681

320,000

25.0-30.0X

5.1-6.0X

4.9-5.0X

woodland_g1

1,263,681

80,000

5.0-10.0X

1.2-2.0X

4.2-5.0X

names_g4

660,488

200,000

50.0-300.0X

12.2-62X

4.1- 4.8X

names_g3

660,488

100,000

7.0-15.0X

2.0-3.5X

3.5-4.3X

names_g2

660,488

80,000

3.0-10.0X

1.4-2.6X

2.2-3.9X

names_g1

660,488

40,000

2.0-3.0X

1.0-2.0X

1.5-2.0X

contours_g1

599,165

120,000

4.0-8.0X

1.6-2.5X

2.5-3.2X

surfacewater_g2

510,989

100,000

20.0-60.0X

4.1-9.7X

4.8-6.2X

surfacewater_g1

510,989

40,000

3.0-5.0X

1.0-1.9X

2.6-3.0X

rail_g1

105,698

40,000

1.0X

1.0X

1.0X

land_g4

30,167

4,000,000

4.5-5.1X

3.3-3.7X

1.3X

land_g3

30,167

2,000,000

3.5-4.0X

1.9-2.5X

1.6-1.8X

land_g2

30,167

1,000,000

2.7-3.3X

1.3-2.0X

1.7-2.0X

land_g1

30,167

500,000

1.5-2.5X

1.1-1.3X

1.4-1.9X

urban_areas_g1

5,215

640,000

7.0-20.0X

2.1-4.0X

3.3-5.0X

As we can see from above, performance gains for each table vary. This variance is likely due to the appropriateness of generalization since some of the OS Open Zoomstack dataset already benefits from natural generalization. One example is roads_local which has already been generalized based on road types. It can also be noted that performance gain decreases as generalization levels decrease as expected, due to feature count increasing while geometries are becoming less simplified. The tables waterlines, woodland, names and surfacewater are the most interesting seeing 30-300X improvements at the highest levels of generalization on a mechanical drive. Performance gains in general increase when the generalized tables include a smaller percentage of the dataset due to styling rules. Mechanical drives see a 1-7X increase in performance gain compared to their solid state counterpart when both the standard and generalized GeoPackage are the same type of disk.

Note

Performance metrics gathered encapsulate a range of cached and non-cached row retrieval due to the caching nature of the SQLite database. The command echo 3 > /proc/sys/vm/drop_caches was used to clear the pagecache, dentries and inodes during each new map request.

8.2.3.3. Sorting

In an attempt to further optimize the query performance of large vector data-sets performance metrics were gathered comparing GeoPackages for the OS Open Zoomstack and OS MasterMap data-sets for the scenarios of regular, random and geohashed Rtree sorting. The gathered metrics are found below.

OS MasterMap was created from the original GML files and the data was imported using multiple threads. Because of the multi-threaded based data insertion, vector content was not organized geospatially. To produce a random sorting, the fid column for each table was used. Performance metrics were gathered using the worst-case scenario of querying content at scale denominator ~ 4000 in the city of London in a attempt to query the most dense feature locations.

In general, the performance gains obtained through Geohash sorting increased when queried feature count increased and scale denominator was reduced. With a combined size of 620GB a mechanical disk was used for comparison, in this case ST1000LX015-1U71. Because of this, client rendering of the standard OS Open Zoomstack resulted in an unusable map taking up to a 35 seconds, however the performance improvements gained through Geohash sorting allows the client to render this large vector dataset with loading times never exceeding 2 seconds. The comparison of query performance between these GeoPackages along with the GeoPackage sorted using Geohash can be seen in Table 20.

Table 20. OS MasterMap Sorting Performance
table name feature count queried feature count fid sorted geohash sorted

topographicline

338,790,112

4360-11852

9.0-22.4X

35.0-69.0X

topographicarea

121,382,384

1476-4461

6.0-17.5X

34.0-47.0X

cartographictext

21,865,014

25-46

1.8-4.0X

8.5-47.5X

topographicpoint

4,270,670

31-88

2.4-4.6X

1.4-9.0X

cartographicsymbol

3,705,680

7-15

0.7-2.2X

2.2-6.0X

boundaryline

516,863

2-26

0.8-2.0X

1.3-1.9X

Unlike OS MasterMap, OS Open Zoomstack returned different feature sets based on scale denominator hints found in the SLD stylesheet, resulting in varied performance improvements. The standard version of this GeoPackage already benefits from geospatially correlated records, so for testing purposes a randomly sorted GeoPackage was produced, using a random number assigned to each table row. Since OS Open Zoomstack is about 1/20th the size of OS MasterMap, the performance improvement is not as significant, with only the names layer seeing about a 2X improvement compared to the randomly sorted GeoPackage. The complete metrics for each layer are shown below in Table 21.

Table 21. OS Open Zoomstack Sorting Performance
table name feature count random sorted geohash sorted

local_buildings

11,176,402

1.0X

1.0X

roads_local

3,026,133

1.0X

1.0X

district_buildings

2,717,911

1.0X

1.0X

waterlines

2,429,712

1.0X

1.0X

woodland

1,263,681

1.0X

1.0X

names

660,488

0.6X

1.35X

contours

599,165

1.0X

1.0X

surfacewater

510,989

1.0X

1.0X

roads_regional

332,766

1.0X

1.0X

greenspace

160,034

1.0X

1.0X

rail

105,698

1.0X

1.0X

foreshore

37,156

1.0X

1.0X

sites

36,439

1.0X

1.0X

land

30,167

1.0X

1.0X

urban_areas

5,215

1.0X

1.0X

etl

3,522

1.0X

1.0X

railway_stations

3,452

1.0X

1.0X

airports

46

1.0X

1.0X

national_parks

39

1.0X

1.0X

boundaries

36

1.0X

1.0X

8.2.4. Segmentation

Since the OS MasterMap dataset had a defined grid split, it was a perfect candidate to produce a Indexed GeoPackage using the OS MasterMap Segmentation. With the entire dataset being over 200GB it can be beneficial to allow users to supply only the small indexed GeoPackage containing meta-data and styling information, accompanied by only the grids they are interested in. This is most important for mobile users who it many cases will not have this space available on their device or SD card. The client was updated to spatially query the index bounds to select only indexes that intersect the map and to query the appropriate GeoPackage if it exists on disk. Since each GeoPackage has far less features per layer then the full dataset performance gains were expected. 3 grids were chosen with high, medium and low feature density per grid. A comparison between query performance for the full, indexed and geohash sorted datasets can be seen below. During this comparison the solid state drive Samsung SSD 860 was used, allowing for a comparison between performance gains seen on mechanical and solid state drives.

uk segments
Table 22. OS MasterMap TQ Performance
table name feature count queried feature count indexed geohash sorted

topographicline

338,790,112

8891-12019

1.2-1.4X

9.1-15.9X

topographicarea

121,382,384

3323-4356

1.0-1.4X

8.3-9.2X

cartographictext

21,865,014

32-42

1.0-2.0X

3.1-7.5X

topographicpoint

4,270,670

62-84

1.0X

2.3-3.3X

cartographicsymbol

3,705,680

11-13

1.0X

1.0X

boundaryline

516,863

5-6

1.0-2.0X

3.0-5.0X

Table 23. OS MasterMap SP Performance
table name feature count queried feature count indexed geohash sorted

topographicline

338,790,112

789-5546

4.4-12.6X

2.0-12.6X

topographicarea

121,382,384

287-2057

2.0-5.5X

2.8-9.3X

cartographictext

21,865,014

31-81

1.8-3.8X

2.2-9.6X

topographicpoint

4,270,670

6-39

1.0-9.0X

1.0-9.0X

cartographicsymbol

3,705,680

30-81

1.0-3.0X

2.0-6.0X

boundaryline

516,863

5-38

3.0-7.0X

4.0-12.0X

Table 24. OS MasterMap NG Performance
table name feature count queried feature count indexed geohash sorted

topographicline

338,790,112

413-12924

1.4-2.4X

1.9-3.0X

topographicarea

121,382,384

168-4634

1.0-3.0X

1.0-3.0X

cartographictext

21,865,014

4-68

1.0-7.0X

1.0-7.0X

topographicpoint

4,270,670

1-100

1.0-4.0X

1.0-4.0X

cartographicsymbol

3,705,680

10-55

1.0-3.0X

1.0-3.0X

boundaryline

516,863

0

NA

NA

From the above metrics we can infer that the Geohash sorting provides significant perform improvements compared to the standard dataset. Performance improvements increase based on the feature density of the region along with the complexity of the features being queried. The most interesting performance improvements come from the topopgraphicline and topographicarea layers since they have significantly more queried features with varying complexities. The Geohash GeoPackage sees up to 15X improvements in the most dense grid (TQ) while still seeing up to 3X improvements in less the less dense grid (NG)

While the Geohash GeoPackage performance increases with feature density, we see the opposite improvements from the Indexed GeoPackage. In the most dense grid of TQ we see minimal improvements compared to the standard GeoPackage. However, in the medium density grid of SP we begin to see significant improvements of up to 15X. Interestingly, in the lower density grid of NG we see a drop in performance seeing only a 2-3X improvement. The drop in improvement might be attributed to the simplified lines and areas found in this region. It should be noted that as feature density decreased the Indexed GeoPackage begins to perform as well as the Geohash sorted GeoPackage with performance improvements being nearly identical in grid NG.

Comparing the performance gains for the Geohash sorted GeoPackage on the mechanical drive ST1000LX015-1U71 and the solid state drive Samsung SSD 860 for the grid TQ we can see that the user will generally see a further 4-5X increase in performance when all data is stored on a mechanical drive a common scenario when dealing with such large datasets. A full comparison between the Geohash GeoPackage and its original for the the two drives can be seen below in Table 25. The column HDD/SSD represents the added performance gain seen in mechanical drives.

Table 25. OS MasterMap Drive Performance
table name feature count SSD HDD HDD/SDD

topographicline

338,790,112

9.1-15.9X

35.0-69.0X

3.9-4.3X

topographicarea

121,382,384

8.3-9.2X

34.0-47.0X

4.1-5.1X

cartographictext

21,865,014

3.1-7.5X

8.5-47.5X

2.7- 6.3X

topographicpoint

4,270,670

2.3-3.3X

1.4-9.0X

1-2.7X

cartographicsymbol

3,705,680

1.0X

2.2-6.0X

2.2-6.0X

boundaryline

516,863

3.0-5.0X

1.3-1.9X

0.4X

Note

Due to the low number of queried features in cartographictext, topographicpoint, cartographicsymbol and boundaryline performance improvements can be ignored since most improvements result in less than 20ms speed up.

8.3. Image Matters

Image Matters played a minor role in implementations for this testbed activity. As part of the development process for both the Metadata and Large Data subtasks, Image Matters developed software to produce GeoPackages. These GeoPackages were used as the initial reference implementations to illustrate the new and revised extension specifications. These GeoPackages were shared with other testbed participants. The software itself is not a deliverable for the activity.

9. Feedback and Recommendations

9.1. GeoPackage Change Requests

9.1.1. JSON Arrays in GeoPackage

Testbed-16 participants proposed a change request to the GeoPackage Encoding Standard to allow JSON arrays to be encoded into string columns and to allow this to be reflected in the schema. In Testbed-16 this was done by specifying a constraint_type column value of application/json in addition to the previously allowed values of enum, glob, and range. Another recommendation is for more explicit media type that would both specifically identify the data as an array (not just a JSON object) and indicate the data type of the contents. This could be done using media type parameters, e.g., application/json;type=array;items=<itemType>. In this case, itemType would be one of the allowed GeoPackage data types as per GeoPackage Data Types. The proposed updated extension is presented in GeoPackage Schema Extension. This approach was not implemented in Testbed-16 due to lack of time.

9.1.2. Metadata Profiles

Testbed-16 participants proposed a change request to the GeoPackage Encoding Standard to allow Metadata Profiles to be encoded in the gpkg_extensions table as described in Metadata Profiles. This would make the metadata profiles in use discoverable by GeoPackage Clients. As part of this change, a recommendation is that the metadata_standard_uri in gpkg_metadata point to a metadata profile when possible. This change is not believed to pose any interoperability risks, but it would improve the utility of the metadata stored in a GeoPackage. As part of this change, the informative examples currently in Annex F.8 could be converted into profiles.

9.2. OWS Context Change Requests

9.2.1. OWS Context Style Operations Reference

Testbed-16 participants noted that the style information in an OWS Context follows a different pattern than other content types. There is no notion of "operations" in a style element, even though styles may be published through a service interface as was done in VTP2. The Testbed-16 participants request a change to OWS Context to treat styles like other content types.

9.3. Proposed GeoPackage Extensions

Testbed-16 participants developed a number of proposed GeoPackage extensions. The participants request that these extensions be published separately as community extensions and linked through geopackage.org. This will allow the extensions to be used, in an at-risk fashion, until such time that they can be approved as official OGC standards.

9.3.1. Semantic Annotations and the Portrayal GeoPackage Extension

Testbed-16 participants used the Semantic Annotations and Portrayal GeoPackage extensions that were developed during prior initiatives. One participant expressed reservations regarding the approach used in Testbed 16 for using semantic annotations to link layers and styles as described in Layer-to-Style Links. The participant noted the following concerns:

  • The proposed approach is somewhat complicated, more than needed to be to meet this particular use case.

  • The semantic annotation itself adds little additional information to what is already in the gpkgext_styles table.

  • Semantic annotations do not maintain referential integrity.

The participant provided a counter-proposal for a simple join table called gpkgext_style_link with the following schema:

  • style_id foreign key to gpkgext_styles.id.

  • table_name foreign key to gpkgext_contents.table_name.

This would be a very direct way to link the concepts while maintaining referential integrity. An ON DELETE CASCADE clause on the foreign key constraints would allow clients to remove tables or styles without hitting unexpected foreign key violations. However, how this approach would support tiled vector data (aka vector tiles) is not clear. As of the completion of Testbed-16, the proposed extension for tiled vector data calls for a gpkgext_vt_layers table that describes the layers within a tileset of vector data. There are a number of approaches that could work.

  1. If the stylesheets have multiple layers, then the mechanism described above would still work. Note that in the case of SLD, the recommendation is that the stylesheet populate both the NamedLayer and FeatureTypeStyle elements even though they are somewhat redundant.

  2. The referential integrity requirement could be removed, though it might be difficult for clients to detect that a lack of referential integrity indicates that the stylesheet corresponds to a vector tiles layer.

  3. An additional column could be added to the join table to indicate a the tiled vector data scenario. Note that this approach would not scale to support any other atypical scenario.

Should they decide to move forward in standardizing the Portrayal Extension, the GeoPackage SWG members will have to consider the benefits and drawbacks of the two approaches, .

9.3.2. Generalized Tables Extension

A generalized table is a feature table that is designed for faster display at lower scales than the base table. A generalized table contains a filtered set of features which can be used without potentially expensive join operations. This table also contains simplified geometries. This approach is designed to improve client performance at the expense of a small increase in GeoPackage size. This extension defines the relationship between base tables and generalized tables. See GeoPackage Generalized Tables Extension.

9.3.3. Index Extension

Since the performance of GeoPackage features data degrades with GeoPackage size, splitting GeoPackages into well-defined partitions is prudent. This approach is useful in scenarios that require opening and processing features data over a small geographic area. The purpose of this extension is to allow for the creation of an index GeoPackage that can point to a set of segment GeoPackages, each containing a partition. A client of the GeoPackage Index extension should be able to inspect the index GeoPackage to find all the metadata information about a feature entry in the main GeoPackage, including attribute information, geometry, schema, proper metadata, styles, and the overall bounding box of the layer. Then the client can determine which GeoPackages contain features of a particular feature type and bounding box. See GeoPackage Index extension.

9.4. Alternative area subdivision

When dividing the area of interest (Great Britain and surrounding islands) into smaller GeoPackages, an isomorphic tiling scheme (100km by 100km) was used. This is not optimal because there is a huge difference in data density between the denser areas (e.g., London and vicinity) and sparser areas (e.g., coastal areas). A scheme that sets a ceiling on GeoPackage size and aggregates sparser tiles together may be a better approach.

The participants had no occasion to investigate further, but two approaches were considered to even out the size of the various packages:

  • Keep using well-known grids, but split large packages on the next grid level when possible. For example, the TQ package in the 100km UK grid is 20GB, but can be split into 100 smaller packages using a well known, more detailed grid using 10km increments. This approach works well if the audience of the packages has a good understanding of the grids involved.

  • Move to a synthetic grid approach, based on quadtree splitting. Start with the full area of interest bounding box, split it into four regular parts, and keep on splitting each until each generated box contains fewer than a desired amount of features (or split until the size of the resulting package goes below a given target size). This approach ensures a more even data distribution across the grid elements.

quad split
Figure 26. The land polygon of ZoomStack, split along a QuadTree structure. Contains OS data © Crown Copyright and database right 2020.

This is an OGC-wide issue so the participants request that this be considered in a future initiative.

9.5. Better Indexing

One weakness of the current spatial indexing mechanism is that the indexing functions read the full Well Known Binary (WKB), or at least the WKB header. Each call is independent, so the header is literally parsed four times. This process is not as efficient as it could be. Create an SQLite virtual table containing just the envelope (minx, miny, maxx, maxy) of the original geometry table is possible. This should make generating the index significantly faster. The participants recommend experimenting with this approach in a future initiative.

Note

Some SQLite libraries do not support the creation of virtual tables.

9.6. Alternative GeoPackage Extensions

9.6.1. Alternative Vector Tiles Extension

In Vector Tiles Pilot (VTP) one and two, participants developed a GeoPackage extension to relationalize information that Mapbox stores in its MBTiles JSON format. Since developers already familiar with the Mapbox ecosystem are accustomed to working with these JSON files, treating these JSON files as another type of GeoPackage metadata (i.e. a new metadata profile) may be prudent. Staying with architectures that people already have code for may ease the path to adoption. This approach could work for both Mapbox and non-Mapbox (e.g., GeoJSON) vector tiles.

9.6.2. Alternative OWS Context Extension

The approach proposed in Common Operational Pictures for representing a Common Operational Picture (COP) is fairly complex. A client would have to be able to parse a full OWS Context JSON document and support for that format is not widespread at this time. If the COP is homogeneous, in other words all of the relevant content is stored in GeoPackage, then concepts like offerings and operations that are part of OWS Context are not necessary. Producing a simple GeoPackage extension specifically designed for homogeneous COPs may be prident.

This approach would require two tables:

  • COP

    • id primary key

    • min_x, max_x, min_y, max_y, and srs_id bounding box

    • title

  • COP Layer

    • id primary key

    • cop_id foreign key

    • table_name foreign key to gpkg_contents.table_name

    • style_name foreign key to gpkgext_styles.id

    • z_index, active, and possibly opacity to describe the layer on the map (opacity could potentially be controlled by the style itself)

The full OWS Context could still be used for heterogeneous architectures where some information is in the GeoPackage and some is not.

Appendix A: Metrics

MasterMap Data

Table Size

The following SQL script provides some statistics in terms of row counts and sizes for MasterMap:

> SELECT table_schema, table_name,
    to_char(row_estimate, '999,999,999') as row_estimate,
    pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
  SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes FROM (
      SELECT c.oid,nspname AS table_schema, relname AS TABLE_NAME
              , c.reltuples AS row_estimate
              , pg_total_relation_size(c.oid) AS total_bytes
              , pg_indexes_size(c.oid) AS index_bytes
              , pg_total_relation_size(reltoastrelid) AS toast_bytes
          FROM pg_class c
          LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
          WHERE relkind = 'r' and nspname = 'translator2'
  ) a
) a order by table_bytes desc;
 table_schema |     table_name     | row_estimate |  total  |  index  |   toast    |  table
--------------+--------------------+--------------+---------+---------+------------+---------
 translator2  | topographicline    |  338,790,112 | 183 GB  | 42 GB   | 227 MB     | 140 GB
 translator2  | topographicarea    |  121,382,384 | 101 GB  | 14 GB   | 2138 MB    | 85 GB
 translator2  | cartographictext   |   21,865,014 | 10 GB   | 2695 MB | 8192 bytes | 8022 MB
 translator2  | topographicpoint   |    4,270,670 | 2015 MB | 453 MB  | 8192 bytes | 1562 MB
 translator2  | cartographicsymbol |    3,705,680 | 1755 MB | 403 MB  | 8192 bytes | 1353 MB
 translator2  | boundaryline       |      516,863 | 563 MB  | 55 MB   | 24 MB      | 484 MB

> select pg_size_pretty(pg_database_size('mastermap2'));
 pg_size_pretty |
----------------+
 303 GB         |

Segmentation

The large MasterMap Topography dataset was split into smaller GeoPackages, one for each 100km UK zone, as depicted in the following map:

image
Figure 27. GeoPackage Segmentation. Contains OS data © Crown Copyright and database right 2020.

The resulting GeoPackages vary widely in size, as reported by the following list:

Size Filename

23G

TQ.gpkg

15G

SJ.gpkg

13G

SK.gpkg

13G

SP.gpkg

12G

SU.gpkg

11G

ST.gpkg

11G

SE.gpkg

9,5G

SD.gpkg

9,2G

TL.gpkg

9,0G

SO.gpkg

7,1G

NZ.gpkg

6,9G

NS.gpkg

4,6G

SX.gpkg

3,9G

NT.gpkg

3,9G

SS.gpkg

3,8G

SN.gpkg

3,5G

TF.gpkg

3,2G

NY.gpkg

3,1G

TM.gpkg

2,8G

SH.gpkg

2,7G

NO.gpkg

2,5G

NJ.gpkg

2,2G

TA.gpkg

2,0G

SZ.gpkg

1,9G

TG.gpkg

1,9G

SW.gpkg

1,8G

TR.gpkg

1,7G

NH.gpkg

1,6G

NX.gpkg

1,5G

SY.gpkg

1,3G

NN.gpkg

847M

NM.gpkg

807M

NG.gpkg

643M

NC.gpkg

583M

SM.gpkg

557M

NR.gpkg

461M

HU.gpkg

426M

ND.gpkg

401M

NU.gpkg

399M

NF.gpkg

375M

HY.gpkg

371M

NB.gpkg

191M

NK.gpkg

108M

TV.gpkg

51M

NL.gpkg

50M

HP.gpkg

34M

SV.gpkg

32M

SR.gpkg

29M

NW.gpkg

9,4M

NA.gpkg

6,2M

HZ.gpkg

3,0M

HT.gpkg

1,1M

HW.gpkg

604K

OV.gpkg

412K

HX.gpkg

272K

SC.gpkg

Zoomstack Data

Table Size

Looking at the documentation, chapter 7, "GeoPackage Schema", there are many tables, a number of which contain small enumerations (not significant enough to reduce the package size). SQLite does not seem to provide column oriented information of how much disk space is used. Therefore the data was imported into PostgreSQL via ogr2ogr and the same queries used for the topography dataset where run:

Table 26. Space used by table, sorted from larger to smaller tables
table_schema table_name row_estimate total index toast table

public

local_buildings

11,176,402

3676 MB

983 MB

96 kB

2693 MB

public

contours

599,165

1539 MB

67 MB

515 MB

957 MB

public

woodland

1,263,681

1073 MB

108 MB

49 MB

916 MB

public

district_buildings

2,717,911

1098 MB

187 MB

136 kB

911 MB

public

roads_local

3,026,133

619 MB

206 MB

8192 bytes

413 MB

public

waterlines

2,429,712

615 MB

218 MB

3528 kB

393 MB

public

surfacewater

510,989

412 MB

35 MB

38 MB

339 MB

public

names

660,488

106 MB

46 MB

8192 bytes

60 MB

public

greenspace

160,034

62 MB

12 MB

64 kB

50 MB

public

roads_regional

332,766

68 MB

22 MB

8192 bytes

46 MB

public

foreshore

37,156

47 MB

2576 kB

12 MB

33 MB

public

land

30,167

29 MB

2120 kB

8192 bytes

27 MB

public

roads_national

124,045

26 MB

8552 kB

8192 bytes

18 MB

public

sites

36,439

19 MB

2640 kB

64 kB

17 MB

public

urban_areas

5,215

29 MB

392 kB

16 MB

12 MB

public

rail

105,698

17 MB

7152 kB

8192 bytes

10 MB

public

spatial_ref_sys

5,009

4192 kB

184 kB

8192 bytes

4000 kB

public

etl

3,522

3696 kB

296 kB

64 kB

3336 kB

public

railway_stations

3,452

608 kB

272 kB

8192 bytes

328 kB

public

national_parks

0

232 kB

24 kB

144 kB

64 kB

public

boundaries

0

992 kB

24 kB

912 kB

56 kB

public

airports

0

40 kB

24 kB

8192 bytes

8192 bytes

Column Size

Table 27. Column level size details
table_name column_name data_type size pg_size_pretty

airports

geom

USER-DEFINED

1334

1334 bytes

airports

name

character varying

1044

1044 bytes

airports

id

integer

184

184 bytes

boundaries

geom

USER-DEFINED

909464

888 kB

boundaries

type

character varying

324

324 bytes

boundaries

id

integer

144

144 bytes

contours

geom

USER-DEFINED

1436827992

1370 MB

contours

height

double precision

7034816

6870 kB

contours

type

character varying

5993838

5853 kB

contours

id

integer

3517408

3435 kB

district_buildings

geom

USER-DEFINED

842998002

804 MB

district_buildings

id

integer

10891448

10 MB

etl

geom

USER-DEFINED

2973371

2904 kB

etl

id

integer

14088

14 kB

foreshore

geom

USER-DEFINED

43528053

42 MB

foreshore

id

integer

148624

145 kB

greenspace

geom

USER-DEFINED

43380184

41 MB

greenspace

type

character varying

2732278

2668 kB

greenspace

id

integer

640136

625 kB

land

geom

USER-DEFINED

26266169

25 MB

land

id

integer

120668

118 kB

local_buildings

geom

USER-DEFINED

1769136273

1687 MB

local_buildings

uuid

character varying

525477339

501 MB

local_buildings

id

integer

56808412

54 MB

names

geom

USER-DEFINED

19154152

18 MB

names

name1

character varying

10179817

9941 kB

names

type

character varying

7897538

7712 kB

names

id

integer

2641952

2580 kB

names

name2

character varying

628311

614 kB

names

name1language

character varying

622852

608 kB

names

name2language

character varying

622852

608 kB

national_parks

geom

USER-DEFINED

162454

159 kB

national_parks

id

integer

156

156 bytes

rail

geom

USER-DEFINED

5711034

5577 kB

rail

type

character varying

1301042

1271 kB

rail

id

integer

422792

413 kB

railway_stations

geom

USER-DEFINED

100108

98 kB

railway_stations

type

character varying

64624

63 kB

railway_stations

name

character varying

41347

40 kB

railway_stations

id

integer

13808

13 kB

roads_local

geom

USER-DEFINED

249990407

238 MB

roads_local

name

character varying

28639368

27 MB

roads_local

type

character varying

22012918

21 MB

roads_local

level

integer

12099912

12 MB

roads_local

id

integer

12099912

12 MB

roads_national

geom

USER-DEFINED

10390828

10147 kB

roads_national

type

character varying

1004517

981 kB

roads_national

name

character varying

988059

965 kB

roads_national

number

character varying

558967

546 kB

roads_national

level

integer

496180

485 kB

roads_national

id

integer

496180

485 kB

roads_regional

geom

USER-DEFINED

25847792

25 MB

roads_regional

name

character varying

3441420

3361 kB

roads_regional

type

character varying

2330312

2276 kB

roads_regional

number

character varying

1807598

1765 kB

roads_regional

id

integer

1331064

1300 kB

roads_regional

level

integer

1327264

1296 kB

sites

geom

USER-DEFINED

15365402

15 MB

sites

type

character varying

386739

378 kB

sites

id

integer

145756

142 kB

surfacewater

geom

USER-DEFINED

363532090

347 MB

surfacewater

type

character varying

3102864

3030 kB

surfacewater

id

integer

2040528

1993 kB

urban_areas

geom

USER-DEFINED

26818864

26 MB

urban_areas

type

character varying

46935

46 kB

urban_areas

id

integer

20860

20 kB

waterlines

geom

USER-DEFINED

314207033

300 MB

waterlines

type

character varying

14861390

14 MB

waterlines

id

integer

9727392

9499 kB

woodland

geom

USER-DEFINED

932843274

890 MB

woodland

type

character varying

7633146

7454 kB

woodland

id

integer

5050548

4932 kB

Styling and visualization

Ordnance Survey provides stylesheets as SLDs, along with point symbology. Here are a few maps rendered by GeoServer at various zoom levels, using the stylesheets linked above, in particular the "Outdoor" styles set:

Table 28. GeoPackage styling and visualization. Contains OS data © Crown Copyright and database right 2020.

image

image

image

image

image

image

image

image

image

image

The dataset already contains a zoom level oriented table split when it comes to road, separating national, regional and local roads.

The following tables stand out in terms of size or number of records:

Table 29. Schemas and rows
table_schema table_name row_estimate total index toast table

public

local_buildings

11,176,402

3676 MB

983 MB

96 kB

2693 MB

public

contours

599,165

1539 MB

67 MB

515 MB

957 MB

public

woodland

1,263,681

1073 MB

108 MB

49 MB

916 MB

public

district_buildings

2,717,911

1098 MB

187 MB

136 kB

911 MB

public

roads_local

3,026,133

619 MB

206 MB

8192 bytes

413 MB

public

waterlines

2,429,712

615 MB

218 MB

3528 kB

393 MB

Observations:

  • Local buildings show at scales higher than 1:17000. Thus, only a small portion of the many buildings if visible are shown. Potential candidate for the geohash rtree optimization, if any.

  • District buildings is similar to local buildings, represents an aggregation of sorts, and displays between 1:80000 and 1:17000 and disappearing when local buildings can show up.

  • Contours appears to be "heavy" for display. The style already contains scale dependencies, showing "index" contours at scales higher than 1:320000, while other contours are visible above 1:120000. Contour data could use some splitting, and given the large geometries, possibly also using reduced precision geometry tables/columns.

  • Woodland is similar to contours, split in three categories, national, regional and local showing at different zoom scales. Same possible as for Contour optimizations apply.

  • Local roads mostly show up above 1:40000, however there is a small subset, with type "minor", displaying between 1:40000 and 1:100000, which could be related to another table.

  • Waterlines contains different types of features (national, regional, district, and all the local types), displayed at different zoom levels. These could be split into 4 different tables for the different zoom levels.

Appendix B: GeoPackage Extensions

B.1. GeoPackage Metadata Profiles Extension

Warning

This subsection is under discussion and may change radically.

Extension Title

Metadata Profiles Extension

Introduction

A metadata profile establishes rules for using the Metadata Extension to meet a specific purpose. Use of this extension signifies that metadata profiles are in use in the current GeoPackage.

Extension Author

Image Matters LLC, in collaboration with the participants of OGC Testbed-15 and Testbed-16.

Extension Name or Template

im_metadata_profiles (will become gpkg_metadata_profiles if adopted by OGC)

Extension Type

New requirement dependent on GeoPackage Metadata Extension and extending Requirement 64.

Applicability

This extension allows for the definition of metadata profiles to describe a particular class of metadata use.

Scope

read-write

Specification

gpkg_extensions

To use this extension, add the following rows to this table in addition to the rows required for the Metadata Extension and any metadata profiles.

Table 30. gpkg_extensions table row
table_name column_name extension_name definition scope

gpkg_metadata

null

im_metadata_profiles

a reference to this file

read-write

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

Creating New Metadata Profiles

To create a new metadata profile, write a new extension specifying the following:

  1. A row in gpkg_extensions with the values as per gpkg_extensions table row for a metadata profile

  2. The values for the md_scope, md_standard_uri, and mime_type columns of gpkg_metadata that jointly identify this particular profile

  3. The allowed values for the reference_scope column of gpkg_metadata_reference

Table 31. gpkg_extensions table row for a metadata profile
table_name column_name extension_name definition scope

gpkg_metadata

metadata

an extension name

a reference to this file

metadata

Note

Before this extension, gpkg_extensions.scope values were limited to "read-write" and "write-only".

B.2. GeoPackage Portrayal Extension

Warning

This subsection is under discussion and may change radically.

Extension Title

Portrayal

Introduction

This extension provides a mechanism for styles and symbols needed to implement portrayal in a GeoPackage.

Extension Author

Image Matters LLC, in collaboration with the participants of OGC Testbed-15, Testbed-16, and the OGC Vector Tiles Pilot 2.

Extension Name or Template

im_portrayal (will become gpkg_portrayal if adopted by the OGC)

Extension Type

New requirement dependent on GeoPackage Core (Clause 1).

Applicability

This extension allows for styles and symbols to be stored in a GeoPackage. How those styles are used is outside of the scope of this specification.

Scope

read-write

Specification

gpkg_extensions

To use this extension, add the following rows to this table.

Table 32. gpkg_extensions Table Rows
table_name column_name extension_name definition scope

gpkgext_styles

null

im_portrayal

a reference to this file

read-write

gpkgext_symbols

null

im_portrayal

a reference to this file

read-write

gpkgext_stylesheets

null

im_portrayal

a reference to this file

read-write

gpkgext_symbol_content

null

im_portrayal

a reference to this file

read-write

gpkgext_symbol_images

null

im_portrayal

a reference to this file

read-write

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by the OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

New Table Definitions

Following are definitions of the tables for this extension. As with other GeoPackage tables, this extension takes no position on how either of these tables are to be used by a client.

gpkgext_styles

This table contains styles. The columns of this table are:

  • id is a primary key

  • style is text naming a specific style

  • description is an optional text description

  • uri is a resolvable URI

Note

Where possible, URIs should resolve to a network-accessible resource. When that is not possible, they should be unique. If no existing URI scheme is available, a URI can take the form of: gpkgstyle::[stylable layer set]::[org]::[style]

gpkgext_stylesheets

This table contains stylesheets. The columns of this table are:

  • id is a primary key

  • style_id is a foreign key to gpkgext_styles

  • format is the format of the stylesheet (e.g., mbstyle or sld)

  • stylesheet is the actual stylesheet BLOB (since some stylesheets are binary)

gpkgext_symbols

This table contains symbols. The columns of this table are:

  • id is a primary key

  • symbol is text naming a specific symbol

  • description is an optional text description

  • uri is a resolvable URI

Note

Where possible, URIs should resolve to a network-accessible resource. When that is not possible, they should be unique. If no existing URI scheme is available, a URI can take the form of: gpkgsym::[stylable layer set]::[org]::[style]::[symbol]

gpkgext_symbol_images

This table contains images representing symbols, with optional support for sprites. The columns of this table are:

  • id is a primary key

  • symbol_id is a foreign key to gpkgext_symbols

  • content_id is a foreign key to gpkgext_symbol_content

  • width, height are optional parameters that are required for sprites or for when there are multiple versions of the same image with different sizes

  • offset_x, offset_y, pixel_ratio are optional parameters for sprite information (NULL if the entire symbol is used)

gpkgext_symbol_content

This table contains the content (data) for symbols. The columns of this table are:

  • id is a primary key

  • format is the media type (formerly MIME type, e.g., image/svg+xml or image/png) of the symbol

  • content is the actual symbol BLOB

  • uri is a resolvable name to uniquely reference a specific content entry, e.g., for use in Mapbox GL styles "sprite" property to reference a particular sprite sheet

B.3. GeoPackage Semantic Annotations Extension

Warning

This subsection is under discussion and may change radically.

Extension Title

Semantic Annotations Extension

Introduction

A semantic annotation is a semantically grounded term that can be applied to another concept. Use of this extension enables semantic annotations to be applied to any business object in the current GeoPackage.

Extension Author

Image Matters LLC, in collaboration with the participants of OGC Testbed-15 and Testbed-16.

Extension Name or Template

im_semantic_annotations (will become gpkg_semantic_annotations if adopted by the OGC)

Extension Type

New requirement optionally dependent on the GeoPackage Schema Extension.

Applicability

This extension can be applied to any GeoPackage business object (layers, features, tiles, styles, etc.).

Scope

read-write

Specification

gpkg_extensions

To use this extension, add the following rows to this table in addition to the rows required for the Schema Extension (if used).

Table 33. gpkg_extensions table row
table_name column_name extension_name definition scope

gpkgext_semantic_annotations

null

im_semantic_annotations

a reference to this file

read-write

gpkgext_sa_reference

null

im_semantic_annotations

a reference to this file

read-write

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

New Table Definitions

Following are definitions of the tables for this extension. As with other GeoPackage tables, this extension takes no position on how either of these tables are to be used by a client.

gpkgext_semantic_annotations

When this extension is in use, add a table with this name and the following columns:

  • id is a primary key

  • type is a semantically grounded type (category) for the annotation[3]

  • title is a human-readable title for the annotation

  • description is an optional human-readable text description for the annotation

  • uri is the resolvable URI for the semantic concept

gpkgext_sa_reference

When this extension is in use, add a table with this name and the following columns:

  • table_name is the name of the table containing the business object

  • key_column_name is the name of the integer column in the specified table that acts as a key

    • null indicates that the semantic annotation refers to the entire table

    • if no such column exists, rowid can be used

  • key_value is the value of the key column that uniquely identifies the row

    • null indicates that the semantic annotation refers to the entire table

  • sa_id is a foreign key to gpkgext_semantic_annotations

Warning

Use of rowid should be avoided in references because rowids that are not backed by an integer primary key are not guaranteed to be maintained by SQLite after vacuum operations.

Using Semantic Annotations

To use semantic annotations, do the following:

  1. Add rows to gpkgext_semantic_annotations for every annotation you want to use.

    1. Optionally, use the Schema Extension to establish an enumeration for the types and further describe those types. See http://www.geopackage.org/guidance/extensions/schema.html for more details.

  2. Add a row to gpkgext_sa_reference for every row of every table requiring the annotation. There can be a many-to-many mapping between business object rows and semantic annotations.

B.4. GeoPackage Schema Extension

Warning

This extension is a proposed update to the Schema Extension published as part of GeoPackage 1.2.1.

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

gpkg_schema

Extension Type

New requirement dependent on clauses [features], [attributes], and [extension_mechanism].

Applicability

This extension may apply to any [feature_user_tables], [attributes_user_tables], or extension tables (see [attributes_user_tables]).

Scope

Read-write

Requirements

Table Definitions
Data Columns
Requirement 103

A GeoPackage MAY contain a table named gpkg_data_columns. If present it SHALL be defined per Table 27 and gpkg_data_columns Table Definition SQL. If the mime_type is "application/json" then the content in the corresponding table and column values SHALL be JSON arrays.

Table 34. Data Columns Table Definition
Column Name Column Type Column Description Null Key

table_name

TEXT

Name of a table specified in gpkg_contents.table_name or gpkg_extensions.table_name

no

PK

column_name

TEXT

Name of the table column

no

PK

name

TEXT

A human-readable identifier (e.g. short name) for the column_name content

yes

UNIQUE

title

TEXT

A human-readable formal title for the column_name content

yes

description

TEXT

A human-readable description for the column_name content

yes

mime_type

TEXT

MIME [21] type of column_name if BLOB type or JSON array, or NULL for other types

yes

constraint_name

TEXT

Column value constraint name (lowercase) specified by reference to gpkg_data_column_constraints.constraint_name

yes

GeoPackage applications MAY [K38] use the gpkg_data_columns table to store minimal application schema identifying, descriptive and MIME [21] 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.

Warning

In versions 1.2.1 and earlier, the table_name column had a foreign key to gpkg_contents.table_name. This constraint has been relaxed but software that edits GeoPackages should be aware that this constraint will exist in many existing files.

Data Column Constraints
Requirement 107

A GeoPackage MAY contain a table named gpkg_data_column_constraints. If present it SHALL be defined per Table 28 and gpkg_data_columns Table Definition SQL.

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 27.

Table 35. Data Column Constraints Table Definition
Column Name Column Type Column Description Null Key

constraint_name

TEXT

Name of constraint (lowercase)

no

Unique

constraint_type

TEXT

Type name of constraint: 'range' | 'enum' | 'glob'

no

Unique

value

TEXT

Specified case sensitive value for 'enum' or 'glob' or NULL for 'range' constraint_type

yes

Unique

min

NUMERIC

Minimum value for 'range' or NULL for 'enum' or 'glob' constraint_type

yes

min_is_inclusive

BOOLEAN

0 (false) if min value is exclusive, or 1 (true) if min value is inclusive

yes

max

NUMERIC

Maximum value for 'range' or NULL for 'enum' or 'glob' constraint_type

yes

max_is_inclusive

BOOLEAN

0 (false) if max value is exclusive, or 1 (true) if max value is inclusive

yes

description

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.

Warning

In GeoPackage 1.0, this table had column names minIsInclusive and maxIsInclusive instead of min_is_inclusive and max_is_inclusive. This was corrected in GeoPackage 1.1 but it is possible that some older GeoPackages may have rows in this table and use the incorrect 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 29 (below).

Warning

Requirement 141 was updated as part of GeoPackage 1.2.1. In 1.1.0 and 1.2.0, the details of required gpkg_extensions rows were inadvertently left unspecified. While the executable test suite running on an older GeoPackage version will not generate a failure due to missing gpkg_extensions rows, it is recommended to update these rows to comply with the updated requirement on older versions as well.

Table 36. Extension Table Records
table_name column_name extension_name definition scope

gpkg_data_columns

null

gpkg_schema

see note 1 below

read-write

gpkg_data_column_constraints

null

gpkg_schema

see note 1 below

read-write

any

any

gpkg_schema

see notes 1,2 below

read-write

Note
  1. For the definition column, use a hyperlink that describes the current implementation of this extension. While a URL like http://www.geopackage.org/spec/#extension_schema is acceptable, permalinks to specific versions are provided upon publication using the URL pattern http://www.geopackage.org/specMmP/#extension_schema where M is the major version, m is the minor version, and P is the patch. For example http://www.geopackage.org/spec121/#extension_schema is the permalink for this extension for GeoPackage 1.2.1.

  2. The gpkg_extensions table SHOULD have a row indicating every GeoPackage table and column combination that is defined by a constraint. These rows are designed to indicate to a client content that cannot be reasonably interpreted without resolving the constraint.

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 row MAY be NULL. If it is not NULL, then it SHALL contain a constraint_name column value (which SHALL be lowercase) from the gpkg_data_column_constraints table. If the corresponding mime_type column value is "application/json", then the constraints SHALL apply to each value in the JSON array.

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 [33]). 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". If the content is a JSON array as per Requirement 106 and the constraint_type is "enum", then the content may be encoded as numeric values to save space. In this case, it is the responsibility of the client to convert the numeric value to the corresponding string in accordance with the enumeration.

These restrictions MAY be enforced by SQL triggers or by code in applications that update GeoPackage data values.

Table 37. Sample Data Column Constraints
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", then 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", then 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", then 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", then 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", then the value column SHALL NOT be NULL.

New Requirement

If the gpkg_data_columns table contains rows with mim_type column values of "application/json", then the corresponding content SHALL be a JSON Array.

Abstract Test Suite

Table Definition
Data Columns

Test Case ID

/extensions/schema/data_columns/table_def

Test Purpose

Verify that the gpkg_data_columns table exists and has the correct definition.

Test Method

  1. PRAGMA table_info(gpkg_data_columns)

  2. Fail if returns an empty result set

  3. Fail if column names and column definitions in the returned table_info do not match those of Table 23, including data type, nullability, default values. Column order, check constraint and trigger definitions, and other column definitions in the returned sql are irrelevant.

  4. Pass if no failures.

Reference

Annex F.9 Req 103

Test Type

Basic

Data Column Constraints

Test Case ID

/extensions/schema/data_column_constraints/table_def

Test Purpose

Verify that the gpkg_data_column_constraints table exists and has the correct definition.

Test Method

  1. PRAGMA table_info(gpkg_data_column_constraints)

  2. Fail if returns an empty result set

  3. Fail if column names and column definitions in the returned table_info do not match those of Table 23, including data type, nullability, default values. Column order, check constraint and trigger definitions, and other column definitions in the returned sql are irrelevant.

  4. Pass if no failures.

Reference

Annex F.9 Req 107

Test Type

Basic

Data Values
gpkg_extensions

Test Case ID

/extensions/schema/extensions/data_values

Test Purpose

Verify that the gpkg_extensions table has the required rows.

Test Method

  1. SELECT table_name, column_name, scope FROM gpkg_extensions WHERE extension_name = 'gpkg_schema';

  2. Not testable if returns an empty result set

  3. Fail if there are not exactly two rows

  4. For each row returned from step 1

    1. Fail if scope is not "read-write"

    2. Fail if column_name is not NULL

  5. Fail if either table_name entry is not present

  6. Pass if no fails

Reference

Annex F.9 Req 141

Test Type:

Capabilities

Test Case ID

/extensions/schema/data_columns/table_name

Test Purpose

Verify that for each gpkg_data_columns row, the table_name value matches a row in gpkg_contents or gpkg_extensions.

Test Method

  1. SELECT DISTINCT gdc.table_name AS gdc_table, ge.table_name AS joined_table FROM gpkg_data_columns AS gdc LEFT OUTER JOIN gpkg_contents AS gc ON gdc.table_name = gc.table_name LEFT OUTER JOIN gpkg_extensions AS ge ON gdc.table_name = ge.table_name;

  2. Not testable if returns an empty result set

  3. For each row from step 1

    1. Fail if joined_table is NULL.

  4. Pass if no fails.

Reference

Annex F.9 Req 104

Test Type

Capability

Test Case ID

/extensions/schema/data_columns/column_name

Test Purpose

Verify that for each gpkg_data_columns row, the column_name value matches a column in the table or view identified by the table_name column value.

Test Method

  1. SELECT table_name, column_name FROM gpkg_data_columns

  2. Not testable if returns an empty result set

  3. For each row from step 1

    1. PRAGMA table_info(table_name)

    2. Fail if table_name does not contain a column matching column_name

  4. Pass if no fails

Reference

Annex F.9 Req 105

Test Type

Capability

Test Case ID

/extensions/schema/data_columns/constraint_name

Test Purpose

Verify that for each gpkg_data_columns row, if the constraint_name value is NOT NULL then the constraint_type column value contains a constraint_type column value from the gpkg_data_column_constraints table for a row with a matching constraint_name value.

Test Method

  1. SELECT constraint_name AS cn, constraint_type AS ct FROM gpkg_data_columns

  2. Not testable if returns an empty result set

  3. For each NOT NULL cn value from step 1

    1. Fail if ct is NULL

    2. If ct NOT NULL, SELECT constraint_type FROM gpkg_data_column_constraints WHERE constraint_name = cn AND constraint_type = ct

    3. Fail if returns an empty result set

  4. Pass if no fails

Reference

Annex F.9 Req 106

Test Type

Capability

Data Column Constraints

Test Case ID

/extensions/schema/data_column_constraints/constraint_type

Test Purpose

Verify that the gpkg_data_column_constraints constraint_type column values are one of "range", "enum", or "glob".

Test Method

  1. SELECT DISTINCT constraint_type FROM gpkg_data_column_constraints

  2. Not testable if returns an empty result set

  3. For each constraint_type value returned by step 1

    1. Fail if constraint_type NOT IN ("range", "enum", "glob").

  4. Pass if no fails.

Reference

Annex F.9 Req 108

Test Type

Capability

Test Case ID

/extensions/schema/data_column_constraints/constraint_names_unique

Test Purpose

Verify that the gpkg_data_column_constraints constraint_name column values for constraint_type values of "range", or "glob" are unique.

Test Method

  1. SELECT DISTINCT constraint_name FROM gpkg_data_column_constraints WHERE constraint_type IN ('range', 'glob')

    1. For each returned constraint_name cn

    2. SELECT count(*) FROM gpkg_data column_constraints WHERE constraint_name = cn

    3. Fail if count > 1

  2. Pass if no fails.

Reference

Annex F.9 Req 109

Test Type

Capability

Test Case ID

/extensions/schema/data_column_constraints/value_for_range

Test Purpose

Verify that the gpkg_data_column_constraints value column values are NULL for rows with a constraint_type value of "range".

Test Method

  1. SELECT constraint_name, value FROM gpkg_data_column_constraints WHERE constraint_type = 'range'

  2. Not testable if returns an empty result set

  3. For each value returned by step 1

    1. Fail if value IS NOT NULL

  4. Pass if no fails.

Reference

Annex F.9 Req 110

Test Type

Capability

Test Case ID

/extensions/schema/data_column_constraints/min_max_for_range

Test Purpose

Verify that the gpkg_data_column_constraints min column values are NOT NULL and less than the max column values for rows with a constraint_type value of "range".

Test Method

  1. SELECT constraint_name, min, max FROM gpkg_data_column_constraints WHERE constraint_type = 'range'

  2. Not testable if returns an empty result set

  3. For each set of min and max values returned by step 1

    1. Fail if min IS NULL

    2. Fail if max IS NULL

    3. Fail if min >= max

  4. Pass if no fails.

Reference

Annex F.9 Req 111

Test Type

Capability

Test Case ID

/extensions/schema/data_column_constraints/inclusive_for_range

Test Purpose

Verify that the gpkg_data_column_constraints min_is_inclusive and max_is_inclusive column values are NOT NULL and either 0 or 1 for rows with a constraint_type value of "range".

Test Method

  1. SELECT constraint_name, min_is_inclusive, max_is_inclusive FROM gpkg_data_column_constraints WHERE constraint_type = 'range'

  2. Not testable if returns an empty result set

  3. For each set of values returned by step 1

    1. Fail if min_is_inclusive IS NULL

    2. Fail if max_is_inclusive IS NULL

    3. Fail if min_is_inclusive is NOT IN (0,1)

    4. Fail if max_is_inclusive is NOT IN (0,1)

  4. Pass if no fails.

Reference

Annex F.9 Req 112

Test Type

Capability

Test Case ID:

/extensions/schema/data_column_constraints/min_max_inclusive_for_enum_glob

Test Purpose:

Verify that the gpkg_data_column_constraints min, max, min_is_inclusive and max_is_inclusive column values are NULL for rows with a constraint_type value of "enum" or "glob".

Test Method:

  1. SELECT constraint_name, min, max, min_is_inclusive, max_is_inclusive FROM gpkg_data_column_constraints WHERE constraint_type IN ('enum','glob')

  2. Not testable if returns an empty result set

  3. For each set of values returned by step 1

    1. Fail if min IS NOT NULL

    2. Fail if max IS NOT NULL

    3. Fail if min_is_inclusive IS NOT NULL

    4. Fail if max_is_inclusive IS NOT NULL

  4. Pass if no fails.

Reference

Annex F.9 Req 113

Test Type

Capability

Test Case ID:

/extensions/schema/data_column_constraints/value_for_enum_glob

Test Purpose:

Verify that the gpkg_data_column_constraints value column values are NOT NULL for rows with a constraint_type value of "enum" or "glob".

Test Method:

  1. SELECT value FROM gpkg_data_column_constraints WHERE constraint_type IN ('enum','glob')

  2. Not testable if returns an empty result set

  3. For each value returned by step 1

    1. Fail if value IS NULL

  4. Pass if no fails.

Reference

Annex F.9 Req 114

Test Type

Capability

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)
)

B.5. GeoPackage Dataset Provenance Metadata Profile

Warning

This subsection is under discussion and may change radically.

Extension Title

Dataset Provenance Encoding Metadata Profile

Introduction

A metadata profile establishes rules for using the Metadata Extension to meet a specific purpose. This profile indicates how to present the metadata describing the provenance of a GeoPackage and/or its datasets. The metadata document itself is a GeoJSON-encoded OWS Context as per the OWS Context GeoJSON Encoding Standard. The FeatureCollection in this document will have citation information in the properties object and a single Feature object that indicates where the dataset was derived from.

This profile supports hierarchical metadata. There may be additional metadata entries describing the datasets that were sources for the GeoPackage. These entries will be linked to the parent metadata object and all of the contents tables using that source.

Extension Author

Image Matters LLC, in collaboration with the participants of OGC Testbed-16.

Extension Name or Template

im_metadata_dp_owc_geojson (will become gpkg_metadata_dp_owc_geojson if adopted by OGC)

Extension Type

New requirement dependent on GeoPackage Metadata Extension and Metadata Profiles.

Applicability

This metadata profile allows for the storage of metadata pertaining to the provenance of a GeoPackage and/or its datasets.

Scope

metadata

Specification

gpkg_extensions

To use this extension, add the following row to this table.

Table 38. gpkg_extensions Table Rows
table_name column_name extension_name definition scope

gpkg_metadata

metadata

im_metadata_dp_owc_geojson

a reference to this file

metadata

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

gpkg_metadata

This profile requires two separate sets of entries in this table.

GeoPackage

For the GeoPackage, add a row to the gpkg_metadata table with the following values:

  • id is a primary key

  • md_scope "undefined"

  • md_standard_uri "https://portal.opengeospatial.org/files/?artifact_id=68826"

  • mime_type "application/geo+json"

  • metadata the actual OWS Context (FeatureCollection) document as described by the Dataset Provenance GeoJSON Schema, minus any Feature instances that directly describe datasets (see the next subsection for those)

The GeoJSON Encoding is described by the Dataset Provenance GeoJSON Schema. The geometries of the features in the FeatureCollection do not need to be populated.

In addition, some elements are required in a way that is not currently expressed in the schema:

  • In the FeatureCollection properties.links array, there must be an element with a rel of "profiles" and an href of "http://www.opengis.net/spec/owcgeojson/1.0/req/core"

  • If the GeoPackage was produced via a WPS, then in the FeatureCollection properties.links array, there should be an element with a rel of "via"

  • If the GeoPackage was produced via a WPS, then there must be a Feature element describing that WPS instance, including the WPS request and response objects in an Offering

Dataset

For every dataset, add a row to the gpkg_metadata table with the following values:

  • id is a primary key

  • md_scope "dataset"

  • md_standard_uri "https://portal.opengeospatial.org/files/?artifact_id=68826"

  • mime_type "application/geo+json"

  • metadata the actual OWS Context (Feature) document as described by the Dataset Provenance GeoJSON Schema that describes that dataset

The GeoJSON Encoding is described by the Dataset Provenance GeoJSON Schema. The geometries of the features in the FeatureCollection do not need to be populated.

In addition, some elements are required in a way that is not currently expressed in the schema:

  • In the FeatureCollection properties.links array, there must be an element with a rel of "profiles" and an href of "http://www.opengis.net/spec/owcgeojson/1.0/req/core"

  • If the Context file is derived from a known resource, then in the FeatureCollection properties.links array, there should be an element with a rel of "via"

  • If a feature resource data is derived from a known data repository with a known URL, then in the corresponding Feature properties.links array, there should be an element with a rel of "data"

gpkg_metadata_reference
GeoPackage

For the GeoPackage, add a row to the gpkg_metadata_reference table with the following values:

  • reference_scope "geopackage"

  • table_name null

  • column_name null

  • row_id_value null

  • timestamp strftime(\'%Y-%m-%dT%H:%M:%fZ', \'now')

  • md_file_id the gpkg_metadata.id for that metadata document

  • md_parent_id null

Dataset

For every dataset that was derived from the source identified in the metadata document, add a row to the gpkg_metadata_reference table with the following values:

  • reference_scope "table"

  • table_name the gpkg_contents.table_name for that dataset

  • column_name null

  • row_id_value null

  • timestamp strftime(\'%Y-%m-%dT%H:%M:%fZ', \'now')

  • md_file_id the gpkg_metadata.id for that metadata document

  • md_parent_id the gpkg_metadata.id for the parent document

B.6. GeoPackage Gemini Metadata Profile

Warning

This subsection is under discussion and may change radically.

Extension Title

GEMINI Metadata Profile

Introduction

UK GEMINI (GEo-spatial Metadata INteroperability Initiative) is a specification for a set of metadata elements for describing geospatial data resources. A metadata profile establishes rules for using the Metadata Extension to meet a specific purpose. This profile indicates how to use ISO 19139-compliant GEMINI metadata to describe datasets in a GeoPackage.

Extension Author

Image Matters LLC, in collaboration with the participants of OGC Testbed-16.

Extension Name or Template

im_metadata_gemini (will become gpkg_metadata_gemini if adopted by OGC)

Extension Type

New requirement dependent on GeoPackage Metadata Extension and Metadata Profiles.

Applicability

This metadata profile allows for the storage of metadata describing a specific dataset.

Scope

metadata

Specification

gpkg_extensions

To use this extension, add the following row to this table.

Table 39. gpkg_extensions Table Rows
table_name column_name extension_name definition scope

gpkg_metadata

metadata

im_metadata_gemini

a reference to this file

metadata

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

gpkg_metadata

For every dataset, add a row to the gpkg_metadata table with the following values:

  • id is a primary key

  • md_scope "dataset"

  • md_standard_uri "https://www.agi.org.uk/agi-groups/standards-committee/uk-gemini/40-gemini/1062-gemini-datasets-and-data-series"

  • mime_type "application/xml" IS THIS RIGHT?

  • metadata the actual metadata document

gpkg_metadata_reference

For every dataset, add a row to the gpkg_metadata_reference table with the following values:

  • reference_scope "table"

  • table_name the gpkg_contents.table_name for that dataset

  • column_name null

  • row_id_value null

  • timestamp strftime(\'%Y-%m-%dT%H:%M:%fZ', \'now')

  • md_file_id the gpkg_metadata.id for that metadata document

  • md_parent_id null

B.7. GeoPackage Common Operational Picture Metadata Profile

Warning

This subsection is under discussion and may change radically.

Extension Title

Common Operational Picture Encoding Metadata Profile

Introduction

A metadata profile establishes rules for using the Metadata Extension to meet a specific purpose. This profile indicates how to present the metadata describing a Common Operational Picture (COP). The metadata document itself is a GeoJSON-encoded OWS Context as per the OWS Context GeoJSON Encoding Standard. The FeatureCollection in this document will resources representing the individual layers for the COP along with all of the ancillary information required to render the layers.

Extension Author

Image Matters LLC, in collaboration with the participants of OGC Testbed-16.

Extension Name or Template

im_metadata_cop_owc_geojson (will become gpkg_metadata_cop_owc_geojson if adopted by OGC)

Extension Type

New requirement dependent on GeoPackage Metadata Extension and Metadata Profiles.

Applicability

This metadata profile allows for the storage of a COP.

Scope

metadata

Specification

gpkg_extensions

To use this extension, add the following row to this table.

Table 40. gpkg_extensions Table Rows
table_name column_name extension_name definition scope

gpkg_metadata

metadata

im_metadata_cop_owc_geojson

a reference to this file

metadata

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

gpkg_metadata

For the COP, add a row to the gpkg_metadata table with the following values:

  • id is a primary key

  • md_scope "undefined"

  • md_standard_uri "https://portal.opengeospatial.org/files/?artifact_id=68826"

  • mime_type "application/geo+json"

  • metadata the actual OWS Context (FeatureCollection) document as described by the Dataset Provenance GeoJSON Schema, minus any Feature instances that directly describe datasets (see the next subsection for those)

The GeoJSON Encoding is described by the Dataset Provenance GeoJSON Schema as modified by the OWS Context GeoPackage Extension. The geometries of the features in the FeatureCollection do not need to be populated. However, if the client is expected to start at a particular area of interest, then the bbox of the FeatureCollection should be populated accordingly.

gpkg_metadata_reference

For the COP, add a row to the gpkg_metadata_reference table with the following values:

  • reference_scope "geopackage"

  • table_name null

  • column_name null

  • row_id_value null

  • timestamp strftime(\'%Y-%m-%dT%H:%M:%fZ', \'now')

  • md_file_id the gpkg_metadata.id for that metadata document

  • md_parent_id null

B.8. OWS Context GeoPackage Extension

This extension to OWS Context defines the rules for encoding GeoPackage content in an OWS Context document.

OWC:Resource

Table 30 shows the properties that are constrained when GeoPackage content is used as an OWC Resource. Other elements are optional and have no further constraints other than what is presented in OWS Context. It is common to populate the “active”, “minscaledenominator”, and “maxscaledenominator” properties when creating a COP. If the OWS Context document is to be stored in the same GeoPackage as the content, then its URL is conventionally “.”.

Table 41. Datatype owc:Resource for GeoPackage Content Extension
Name GeoJSON location Definition Data Type and Values Multiplicity and Use

ID

<xz>.features[i].id

Unambiguous reference to the identification of the Context Resource (IRI)

{URL}/{gpkg_contents.table_name}

One (mandatory)

Title

<xz>.features[i].properties.title

Title given to the Context resource

gpkg_contents.identifier

One (mandatory)

Update Date

<xz>.features[i].properties.updated

Date of the last update of the Context resource

gpkg_contents.last_change

One (mandatory)

Offering

<xz>.features[i].properties.offering

Service or inline content offering for the resource target at OGC compliant clients

see OWC:Offering

One (mandatory)

OWC:Offering

Table 31 shows the properties that are constrained when GeoPackage content is used as an OWC Offering.

Table 42. Datatype owc:Offering for GeoPackage Content Extension
Name GeoJSON location Definition Data Type and Values Multiplicity and Use

Code

<off>.code

Code identifying the type of offering

"http://www.opengis.net/spec/owc-geojson/1.1/req/gpkg/{gpkg_contents.data_type}"

One (mandatory)

Operation

<off>.operations[k]

Array of operations used to invoke the service

see OWC:Operation

One (mandatory)

Content

<off>.contents[k]

Array of contents (inline or byRef)

N/A

Zero (prohibited)

Style Set

<off>.styles[k]

Array of style sets

see OWC:styleSet

Zero or more (optional)

OWC:Operation

Table 32 shows the properties that are constrained when GeoPackage content is used as an OWC Operation. If the OWS Context document is to be stored in the same GeoPackage as the content, then its URL is conventionally “.”.

Table 43. Datatype owc:Operation for GeoPackage Content Extension
Name GeoJSON location Definition Data Type and Values Multiplicity and Use

Code

<op>.code

Code identifying the type of operation

GPKG

One (mandatory)

Method

<op>.method

Code identifying the HTTP verb type of Operation

SELECT

One (mandatory)

Type

<op>.type

MIME type of the expected results

N/A

Zero (prohibited)

Request URL

<op>.href

Service Request URL

{URL}

One (mandatory)

Request

<op>.request

Optional request body content

N/A

Zero (prohibited)

Result

<op>.result

Result payload of the operation

N/A

Zero (prohibited)

OWC:styleSet

Table 33 shows the properties that are constrained when GeoPackage content is used as an OWC Style Set. Other elements are optional and have no further constraints other than what is presented in OWS Context.

Table 44. Datatype owc:styleSet for GeoPackage Content Extension
Name GeoJSON location Definition Data Type and Values Multiplicity and Use

Name

<style>.name

Unique name of the style set within a given offering

gpkgext_styles.uri

One (mandatory)

Title

<style>.title

Human-readable title of the style set within a given offering

gpkgext_styles.style

One (mandatory)

Abstract

<style>.abstract

Description of the style set

gpkgext_styles.description

Zero or one (optional)

Default

<style>.default

Whether this style set is the one to be defined by default

“true” or “false” (default)

Zero or one (optional)

legend URL

<style>.legendURL

URL of a legend image for the style set

{URL}

Zero or one (optional)

Content

<style>.content

The inline or an external reference to the style set definition

N/A

Zero (prohibited)

Note

If there is more than one style set element for a particular offering, the “default” property should be populated with "true" or "false".

B.9. GeoPackage Generalized Tables Extension

Extension Title

Generalized tables extension

Introduction

A generalized table is a feature table that is designed for faster display at lower scales than the base table. A generalized table contains a filtered set of features which can be used without potentially expensive join operations. It also contains simplified geometries designed. This approach is designed to improve client performance at the expense of a small increase of GeoPackage size. This extension defines the relationship between base tables and generalized tables.

Extension Author

The participants of OGC Testbed-16.

Extension Name or Template

tb16_generalized (will become gpkg_generalized if adopted by the OGC)

Extension Type

New requirement dependent on the GeoPackage Features clause.

Applicability

This extension can be applied to GeoPackage feature entries (tiles entries already embed a notion of multi-resolution representation)

Scope

read-write

Specification

gpkg_extensions

To use this extension, add the following rows to this table in addition to the rows required for the Schema Extension (if used).

Table 45. gpkg_extensions table row
table_name column_name extension_name definition scope

gpkgext_generalized

null

tb16_generalized

a reference to this file

read-write

Note

The values in the definition column SHOULD refer in some human-readable way to this extension specification. If the extension is adopted by OGC, it will gain the "gpkg_" prefix and get a different definition permalink.

New Table Definitions

Following are definitions of the tables for this extension. As with other GeoPackage tables, this extension takes no position on how either of these tables are to be used by a client.

gpkgext_generalized

When this extension is in use, add a table with this name and the following columns:

  • primary_table is the primary table to which a generalized table refers to,

  • generalized_table, name of the generalized table text,

  • distance, the generalization distance used to create the simplified geometries, expressed in the native unit of measure of the data itself

  • scale_denominator, the scale denominator at which the generalized table should be used

  • provenance, a human readable description of how the generalized table was created

Using Generalized Tables

In order to use the generalized tables extension, on the write side:

  • Look at the set of styles that will be used to render the data.

  • Check for significant data filtering associated to scale dependencies (record reduction is where the main performance boost is obtained).

  • Create one or more generalized tables based on the scale dependencies and the filters, with the target of significantly reducing the record count of the table (2 or more times at each step).

  • As a secondary goal, use the generalized tables to simply reduce the size of geometries, in case the geometries prove to be particularly complex.

  • Register each generalized table in the gpkext_generalized table.

On the read side, instead:

  • For each base table, look-up the associated generalized tables.

  • Sort the generalized table by scale denominator, ascending.

  • The previous sorting generates a set of scale intervals:

    • The main table is meant to be used from 1:1 to the scale denominator of the first generalized table

    • The first generalized table, from its scale denominator, to the one of the next table

    • Repeat until the last generalized table, which should be use for all scale denominators above the scale denominator found in gpkext_generalized.

To avoid issues with mis-aligned scale calculations between server and client, the generalization distance can also be used for the purpose. For the same reason, it is warmly advised to setup generalized tables so that each new generalized table contains a strict subset of the features in the previous generalized table, or base table. With this setup, at worst the client will keep on reading a higher resolution table, but will not lose contents in the map.

B.10. GeoPackage Index extension

Introduction

Since the performance of GeoPackage features data degrades with GeoPackage size, it is often prudent to split GeoPackages into well-defined partitions. This approach is useful in scenarios that require opening and processing features data over a small geographic area. The purpose of this extension is to allow for the creation of an index GeoPackage that can point to a set of segment GeoPackages, each containing a partition. A client of the GeoPackage Index extension should be able to inspect the index GeoPackage to find all the metadata information about a feature entry in the main GeoPackage, including attribute information, geometry, schema, proper metadata, styles, and the overall bounding box of the layer. Then the client can determine which GeoPackages contain features of a particular feature type and bounding box.

This extension describes an index table which establishes the partitions, including the bounding boxes, for various features entries that comprise the full dataset. There should be separate information for each entry because not all features will be present in each partition. (Entries might not necessarily even have the same SRS.) Bounding boxes for separate partitions should be set up in such a way that features shared among packages are found at least once. However, there is no benefit for them to overlap.

Once the partition pattern is established, the features are then inserted into the corresponding segment GeoPackage. If a particular geometry spans multiple GeoPackages as illustrated in Figure 26, it should be encoded in all of them. In most cases, the required data will be present in a single GeoPackage. In the worst case, the maximum number of GeoPackages that will have to be opened is four. Use of a key column will allow clients to identify duplicates.

gpkg index shared feature
Figure 28. Features that span multiple partitions
Note

The idea is borrowed from MapServer’s ogrtindex tool.

Extension authors

Testbed-16 participants

Extension Name or Template

tb16_index

Extension type

New requirement dependent on [GeoPackage Core (Clause 1)](http://www.geopackage.org/spec/#core).

Applicability

This extension adds an additional level of organization to existing GeoPackage data.

Scope

read-write

Specification

To use this extension, add the following rows to the gpkg_extensions table:

table_name

column_name

extension_name

definition

scope

gpkgext_index

null

tb16_index

a reference to the TB16 ER

read-write

<feature_entry_tablename>

null

tb16_index

a reference to the TB16 ER

read-write

Where <feature_entry_tablename> is the name of the index table for each feature entry that has been split among multiple files.

gpkgext_index

Main index table, tells the client where to locate the index of each feature entry. The columns of this table are:

  • table_name is the table for feature entry, references gpkg_contents.table_name

  • index_table_name is the name of the table indexing the files in which the feature entry has been split

  • key_column is the key column used to locate duplicate features.

CREATE TABLE IF NOT EXISTS gpkgext_index (
  table_name TEXT NOT NULL,
  index_table_name TEXT NOT NULL,
  key_column TEXT NOT NULL,
  CONSTRAINT uk_name_index UNIQUE (table_name, index_table_name),
  CONSTRAINT fk_table_name FOREIGN KEY(table_name) REFERENCES gpkg_contents(table_name)
)
<index_table_name>

For each feature entry, a table <index_table_name> is created with the following columns:

  • file is the name of the file containing a portion of the features

  • min_x, min_y, max_x, and max_y are the bounding box coordinates for the contents of the entry, in the SRS of the entry (this bounding box may be smaller than the bounding box for the segment GeoPackage)

Bounding boxes for separate files should not overlap, and should be setup in such a way that features shared among packages are found at least once.

The index tables names are free, but using a consistent naming convention is recommended, e.g. gpkgext_<tablename>_index. For example, the index for a boundaryline table could be:

CREATE TABLE IF NOT EXISTS gpkgext_boundaryline_index (
  file TEXT NOT NULL PRIMARY KEY,
  min_x DOUBLE NOT NULL,
  min_y DOUBLE NOT NULL,
  max_x DOUBLE NOT NULL,
  max_y DOUBLE NOT NULL,
  CHECK (max_x >= min_x),
  CHECK (max_y >= min_y),
)

Appendix C: Sample Documents

C.1. WPS Requests

The following subsections describe WPS requests that were used to produce GeoPackages.

C.1.1. Full ZoomStack

Downloading full ZoomStack, with styles, and overview table directives controlling both geometry resolution and overview table contents:

<?xml version="1.0" encoding="UTF-8"?>
<wps:Execute xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" service="WPS" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
   <ows:Identifier>gs:GeoPackage</ows:Identifier>
   <wps:DataInputs>
      <wps:Input>
         <ows:Identifier>contents</ows:Identifier>
         <wps:Data>
            <wps:ComplexData mimeType="text/xml; subtype=geoserver/geopackage">
               <![CDATA[
                <geopackage xmlns="http://www.opengis.net/gpkg" name="zoomstack-styles-generalized2">
                  <features name="land" identifier="land">
                    <description>land</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:land</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- no scale dependencies linked with filters, but complex geometries -->
                    <overviews>
                      <overview>
                        <name>land_g1</name>
                        <scaleDenominator>500000</scaleDenominator>
                      </overview>
                      <overview>
                        <name>land_g2</name>
                        <scaleDenominator>1000000</scaleDenominator>
                      </overview>
                      <overview>
                        <name>land_g3</name>
                        <scaleDenominator>2000000</scaleDenominator>
                      </overview>
                      <overview>
                        <name>land_g4</name>
                        <scaleDenominator>4000000</scaleDenominator>
                      </overview>
                    </overviews>
                  </features>
                  <features name="national_parks" identifier="national_parks">
                    <description>national_parks</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:national_parks</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- no scale dependencies linked with filters -->
                  </features>
                  <features name="urban_areas" identifier="urban_areas">
                    <description>urban_areas</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:urban_areas</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <overviews>
                      <overview>
                        <name>urban_areas_g1</name>
                        <scaleDenominator>640000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>National</fes:Literal>
                          </fes:PropertyIsEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="sites" identifier="sites">
                    <description>sites</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:sites</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- all scale depencies activate when fairly zoomed in -->
                  </features>
                  <features name="greenspace" identifier="greenspace">
                    <description>greenspace</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:greenspace</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- all scale depencies activate when fairly zoomed in -->
                  </features>
                  <features name="woodland" identifier="woodland">
                    <description>woodland</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:woodland</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <overviews>
                      <overview>
                        <name>woodland_g1</name>
                        <scaleDenominator>80000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:Or>
                            <!-- Keeping this one because the oveview tables generate
                                                       on top of the previous... not sure how to handle
                                                       an exact swith here though, would need scale dependencies...
                                                  -->
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>National</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Regional</fes:Literal>
                            </fes:PropertyIsEqualTo>
                          </fes:Or>
                        </filter>
                      </overview>
                      <overview>
                        <name>woodland_g2</name>
                        <scaleDenominator>320000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>National</fes:Literal>
                          </fes:PropertyIsEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="contours" identifier="contours">
                    <description>contours</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:contours</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <overviews>
                      <overview>
                        <name>contours_g1</name>
                        <scaleDenominator>120000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>Index</fes:Literal>
                          </fes:PropertyIsEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="district_buildings" identifier="district_buildings">
                    <description>district_buildings</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:district_buildings</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- no scale based filtering -->
                  </features>
                  <features name="local_buildings" identifier="local_buildings">
                    <description>local_buildings</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:local_buildings</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- no scale based filtering -->
                  </features>
                  <features name="surfacewater" identifier="surfacewater">
                    <description>surfacewater</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:surfacewater</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <overviews>
                      <overview>
                        <name>surfacewater_g1</name>
                        <scaleDenominator>40000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:Or>
                            <!-- Keeping this one because the oveview tables generate
                                                       on top of the previous... not sure how to handle
                                                       an exact swith here though, would need scale dependencies...
                                                  -->
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>National</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Regional</fes:Literal>
                            </fes:PropertyIsEqualTo>
                          </fes:Or>
                        </filter>
                      </overview>
                      <overview>
                        <name>surfacewater_g2</name>
                        <scaleDenominator>100000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>National</fes:Literal>
                          </fes:PropertyIsEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="foreshore" identifier="foreshore">
                    <description>foreshore</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:foreshore</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                  <features name="waterlines" identifier="waterlines">
                    <description>waterlines</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:waterlines</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <overviews>
                      <overview>
                        <name>waterlines_g1</name>
                        <scaleDenominator>40000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:Or>
                            <!-- Keeping this one because the oveview tables generate
                                                       on top of the previous... not sure how to handle
                                                       an exact swith here though, would need scale dependencies...
                                                  -->
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>National</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Regional</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>District</fes:Literal>
                            </fes:PropertyIsEqualTo>
                          </fes:Or>
                        </filter>
                      </overview>
                      <overview>
                        <name>waterlines_g2</name>
                        <scaleDenominator>200000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:Or>
                            <!-- Keeping this one because the oveview tables generate
                                                       on top of the previous... not sure how to handle
                                                       an exact swith here though, would need scale dependencies...
                                                  -->
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>National</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Regional</fes:Literal>
                            </fes:PropertyIsEqualTo>
                          </fes:Or>
                        </filter>
                      </overview>
                      <overview>
                        <name>waterlines_g3</name>
                        <scaleDenominator>600000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>National</fes:Literal>
                          </fes:PropertyIsEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="roads_local" identifier="roads_local">
                    <description>roads_local</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:roads_local</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- everythig but this one displays up to 40000, this one, from 40k up to 100k -->
                    <overviews>
                      <overview>
                        <name>roads_local_g1</name>
                        <scaleDenominator>40000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>Minor</fes:Literal>
                          </fes:PropertyIsEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="roads_regional" identifier="roads_regional">
                    <description>roads_regional</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:roads_regional</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- actual data does not seem to be much scale dependent, symbology is -->
                  </features>
                  <features name="roads_national" identifier="roads_national">
                    <description>roads_national</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:roads_national</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- actual data does not seem to be much scale dependent, symbology is -->
                  </features>
                  <features name="rail" identifier="rail">
                    <description>rail</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:rail</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- Narrow Gauge is restricted to higher scales -->
                    <overviews>
                      <overview>
                        <name>rail_g1</name>
                        <scaleDenominator>40000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <fes:PropertyIsNotEqualTo>
                            <fes:ValueReference>type</fes:ValueReference>
                            <fes:Literal>Narrow Gauge</fes:Literal>
                          </fes:PropertyIsNotEqualTo>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                  <features name="boundaries" identifier="boundaries">
                    <description>boundaries</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:boundaries</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- no scale dependencies -->
                  </features>
                  <features name="etl" identifier="etl">
                    <description>etl</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:etl</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- displays only up to 40k -->
                  </features>
                  <features name="railway_stations" identifier="railway_stations">
                    <description>railway_stations</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:railway_stations</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- displays only up to 40k -->
                  </features>
                  <features name="airports" identifier="airports">
                    <description>airports</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:airports</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- displays only up to 320k -->
                  </features>
                  <features name="names" identifier="names">
                    <description>names</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>oszoom:names</featuretype>
                    <indexed>true</indexed>
                    <styles>true</styles>
                    <!-- Lots of potential scales, had to group ranges -->
                    <overviews>
                      <overview>
                        <name>names_g1</name>
                        <scaleDenominator>40000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <!-- Filtering by exclusion -->
                          <fes:And>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Small Settlements</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Greenspace</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Motorway Junctions</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                          </fes:And>
                        </filter>
                      </overview>
                      <overview>
                        <name>names_g2</name>
                        <scaleDenominator>80000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <!-- Filtering by exclusion -->
                          <fes:And>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Small Settlements</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Greenspace</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Water</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Woodland</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                            <fes:PropertyIsNotEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Motorway Junctions</fes:Literal>
                            </fes:PropertyIsNotEqualTo>
                          </fes:And>
                        </filter>
                      </overview>
                      <overview>
                        <name>names_g3</name>
                        <scaleDenominator>100000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <!-- Filtering by inclusion -->
                          <fes:Or>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Hamlet</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Suburban Area</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Village</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Town</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>City</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>National Park</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Capital</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Country</fes:Literal>
                            </fes:PropertyIsEqualTo>
                          </fes:Or>
                        </filter>
                      </overview>
                      <overview>
                        <name>names_g4</name>
                        <scaleDenominator>200000</scaleDenominator>
                        <filter xmlns:fes="http://www.opengis.net/fes/2.0">
                          <!-- Filtering by inclusion -->
                          <fes:Or>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Town</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>City</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>National Park</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Capital</fes:Literal>
                            </fes:PropertyIsEqualTo>
                            <fes:PropertyIsEqualTo>
                              <fes:ValueReference>type</fes:ValueReference>
                              <fes:Literal>Country</fes:Literal>
                            </fes:PropertyIsEqualTo>
                          </fes:Or>
                        </filter>
                      </overview>
                    </overviews>
                  </features>
                </geopackage>
              ]]>
            </wps:ComplexData>
         </wps:Data>
      </wps:Input>
   </wps:DataInputs>
   <wps:ResponseForm>
      <wps:RawDataOutput>
         <ows:Identifier>geopackage</ows:Identifier>
      </wps:RawDataOutput>
   </wps:ResponseForm>
</wps:Execute>

C.1.2. MasterMap Subset

Downloading a small subset of mastermap, by bounding box, with full metadata:

<?xml version="1.0" encoding="UTF-8"?>
<wps:Execute xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" service="WPS" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
   <ows:Identifier>gs:GeoPackage</ows:Identifier>
   <wps:DataInputs>
      <wps:Input>
         <ows:Identifier>contents</ows:Identifier>
         <wps:Data>
            <wps:ComplexData mimeType="text/xml; subtype=geoserver/geopackage">
               <![CDATA[
               <geopackage xmlns="http://www.opengis.net/gpkg" name="test">

                  <features name="boundaryline" identifier="boundaryline">
                     <description>boundaryline</description>
                     <srs>EPSG:27700</srs>
                     <bbox>
                        <minx>524500</minx>
                        <maxx>526500</maxx>
                        <miny>174500</miny>
                        <maxy>176500</maxy>
                     </bbox>
                     <featuretype>osmm:boundaryline</featuretype>
                     <indexed>true</indexed>
                     <styles>true</styles>
                  </features>

                  <features name="cartographicsymbol"
                            identifier="cartographicsymbol">
                     <description>boundaryline</description>
                     <srs>EPSG:27700</srs>
                     <bbox>
                        <minx>524500</minx>
                        <maxx>526500</maxx>
                        <miny>174500</miny>
                        <maxy>176500</maxy>
                     </bbox>
                     <featuretype>osmm:cartographicsymbol</featuretype>
                     <indexed>true</indexed>
                          <styles>true</styles>
                  </features>

                  <features name="cartographictext"
                            identifier="cartographictext">
                     <description>boundaryline</description>
                     <srs>EPSG:27700</srs>
                     <bbox>
                        <minx>524500</minx>
                        <maxx>526500</maxx>
                        <miny>174500</miny>
                        <maxy>176500</maxy>
                     </bbox>
                     <featuretype>osmm:cartographictext</featuretype>
                     <indexed>true</indexed>
                     <styles>true</styles>
                      </features>

                  <features name="topographicarea"
                            identifier="topographicarea">
                     <description>boundaryline</description>
                     <srs>EPSG:27700</srs>
                     <bbox>
                        <minx>524500</minx>
                        <maxx>526500</maxx>
                        <miny>174500</miny>
                        <maxy>176500</maxy>
                     </bbox>
                     <featuretype>osmm:topographicarea</featuretype>
                     <indexed>true</indexed>
                       <styles>true</styles>
                  </features>

                  <features name="topographicline"
                            identifier="topographicline">
                     <description>boundaryline</description>
                     <srs>EPSG:27700</srs>
                     <bbox>
                        <minx>524500</minx>
                        <maxx>526500</maxx>
                        <miny>174500</miny>
                        <maxy>176500</maxy>
                     </bbox>
                     <featuretype>osmm:topographicline</featuretype>
                     <indexed>true</indexed>
                        <styles>true</styles>
                  </features>

                  <features name="topographicpoint"
                            identifier="topographicpoint">
                     <description>boundaryline</description>
                     <srs>EPSG:27700</srs>
                     <bbox>
                        <minx>524500</minx>
                        <maxx>526500</maxx>
                        <miny>174500</miny>
                        <maxy>176500</maxy>
                     </bbox>
                     <featuretype>osmm:topographicpoint</featuretype>
                     <indexed>true</indexed>
                     <styles>true</styles>
                   </features>
              </geopackage>
              ]]>
            </wps:ComplexData>
         </wps:Data>
      </wps:Input>
   </wps:DataInputs>
   <wps:ResponseForm>
      <wps:RawDataOutput>
         <ows:Identifier>geopackage</ows:Identifier>
      </wps:RawDataOutput>
   </wps:ResponseForm>
</wps:Execute>

C.1.3. Full MasterMap

Downloading full mastermap, sorting records by the geometry field, in other words, by GeoHash:

<?xml version="1.0" encoding="UTF-8"?>
<wps:Execute xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" service="WPS" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
   <ows:Identifier>gs:GeoPackage</ows:Identifier>
   <wps:DataInputs>
      <wps:Input>
         <ows:Identifier>contents</ows:Identifier>
         <wps:Data>
            <wps:ComplexData mimeType="text/xml; subtype=geoserver/geopackage">
               <![CDATA[
                <geopackage xmlns="http://www.opengis.net/gpkg" name="test">
                  <features name="boundaryline" identifier="boundaryline">
                    <description>boundaryline</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>osmm:boundaryline</featuretype>
                    <sort xmlns:fes="http://www.opengis.net/fes/2.0">
                      <fes:SortProperty>
                        <fes:ValueReference>wkb_geometry</fes:ValueReference>
                      </fes:SortProperty>
                    </sort>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                  <features name="cartographicsymbol" identifier="cartographicsymbol">
                    <description>boundaryline</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>osmm:cartographicsymbol</featuretype>
                    <sort xmlns:fes="http://www.opengis.net/fes/2.0">
                      <fes:SortProperty>
                        <fes:ValueReference>wkb_geometry</fes:ValueReference>
                      </fes:SortProperty>
                    </sort>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                  <features name="cartographictext" identifier="cartographictext">
                    <description>boundaryline</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>osmm:cartographictext</featuretype>
                    <sort xmlns:fes="http://www.opengis.net/fes/2.0">
                      <fes:SortProperty>
                        <fes:ValueReference>wkb_geometry</fes:ValueReference>
                      </fes:SortProperty>
                    </sort>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                  <features name="topographicarea" identifier="topographicarea">
                    <description>boundaryline</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>osmm:topographicarea</featuretype>
                    <sort xmlns:fes="http://www.opengis.net/fes/2.0">
                      <fes:SortProperty>
                        <fes:ValueReference>wkb_geometry</fes:ValueReference>
                      </fes:SortProperty>
                    </sort>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                  <features name="topographicline" identifier="topographicline">
                    <description>boundaryline</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>osmm:topographicline</featuretype>
                    <sort xmlns:fes="http://www.opengis.net/fes/2.0">
                      <fes:SortProperty>
                        <fes:ValueReference>wkb_geometry</fes:ValueReference>
                      </fes:SortProperty>
                    </sort>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                  <features name="topographicpoint" identifier="topographicpoint">
                    <description>boundaryline</description>
                    <srs>EPSG:27700</srs>
                    <featuretype>osmm:topographicpoint</featuretype>
                    <sort xmlns:fes="http://www.opengis.net/fes/2.0">
                      <fes:SortProperty>
                        <fes:ValueReference>wkb_geometry</fes:ValueReference>
                      </fes:SortProperty>
                    </sort>
                    <indexed>true</indexed>
                    <styles>true</styles>
                  </features>
                </geopackage>
                                                        ]]>
            </wps:ComplexData>
         </wps:Data>
      </wps:Input>
   </wps:DataInputs>
   <wps:ResponseForm>
      <wps:RawDataOutput>
         <ows:Identifier>geopackage</ows:Identifier>
      </wps:RawDataOutput>
   </wps:ResponseForm>
</wps:Execute>

C.2. Metadata Documents

C.2.1. GeoPackage Provenance OWS Context (GeoJSON)

This document is an example GeoJSON feature collection that includes a feature describing the WPS request that was used to create it.

{
   "type":"FeatureCollection",
   "id":"http://www.opengis.net/owc/1.0/examples/gml",
   "geometry":{
      "type":"Polygon",
      "coordinates":[
         [
            [
               -180.0,
               -90.0
            ],
            [
               -180.0,
               90.0
            ],
            [
               180.0,
               90.0
            ],
            [
               180.0,
               -90.0
            ],
            [
               -180.0,
               -90.0
            ]
         ]
      ]
   },
   "properties":{
      "lang":"en",
      "title":"Context Example :: Examples of GML",
      "updated":"2012-02-21T11:58:23Z",
      "generator":"ACME OWS Context Server",
      "rights":"Copyright (c) 2012. Some rights reserved. This feed licensed under a Creative Commons Attribution 3.0 License.",
      "authors":[
         {
            "name":"John Doe",
            "email":"JohnDoe@example.com",
            "uri":"http://example.com/~johndoe"
         }
      ],
      "links":[
         {
            "rel":"profile",
            "href":"http://www.opengis.net/spec/owc-atom/1.0/req/core",
            "title":"This file is compliant with version 1.0 of OGC Context"
         }
      ]
   },
   "features":[
      {
         "type":"Feature",
         "id":"http://www.opengis.net/owc/1.0/examples/wps/1",
         "properties":{
            "title":"WPS",
            "updated":"2012-05-10T14:35:00.400Z",
            "links":[
               {
                  "rel":"data",
                  "type":"text/xml",
                  "href":"wps_execute.xml"
               }
            ],
            "offerings":[
              {
                "code":"http://www.opengis.net/spec/owc-geojson/1.0/req/wps",
                "operations":[
                  {
                    "code":"Execute",
                    "method":"POST",
                    "type":"application/xml",
                    "href":"...",
                    "request":{
                      "type":"application/xml",
                      "content":"
                      <?xml version=\"1.0\" encoding=\"UTF-8\"?>
                      <wps:Execute version=\"1.0.0\" service=\"WPS\"
                        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
                        xmlns=\"http://www.opengis.net/wps/1.0.0\"
                        xmlns:wfs=\"http://www.opengis.net/wfs\"
                        xmlns:wps=\"http://www.opengis.net/wps/1.0.0\"
                        xmlns:ows=\"http://www.opengis.net/ows/1.1\"
                        xmlns:gml=\"http://www.opengis.net/gml\"
                        xmlns:ogc=\"http://www.opengis.net/ogc\"
                        xmlns:wcs=\"http://www.opengis.net/wcs/1.1.1\"
                        xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">
                        <ows:Identifier>gs:GeoPackage</ows:Identifier>
                        <wps:DataInputs>
                          <wps:Input>
                            <ows:Identifier>contents</ows:Identifier>
                            <wps:Data>
                              <wps:ComplexData mimeType=\"text/xml; subtype=geoserver/geopackage\">
                                <geopackage name=\"test\"
                                  xmlns=\"http://www.opengis.net/gpkg\">
                                  <metadata>true</metadata>  <!-- idea to make it include the metadata from the server configuration -->
                                  <features name=\"fifteen\" identifier=\"f15\">
                                    <styles>true</style>  <!-- include all styles available in the server for these layers -->
                                    <metadata>true</metadata>  <!-- idea to make it include the metadata from the server configuration -->
                                    <description>fifteen description</description>
                                    <srs>EPSG:32615</srs>
                                    <bbox>
                                      <minx>500000</minx>
                                      <maxx>500100</maxx>
                                      <miny>500000</miny>
                                      <maxy>500100</maxy>
                                    </bbox>
                                    <featuretype>cdf:Fifteen</featuretype>
                                    <propertynames>pointProperty</propertynames>
                                  </features>
                                  <features name=\"lakes\" identifier=\"lakes1\">
                                    <description>lakes description</description>
                                    <featuretype>cite:Lakes</featuretype>
                                    <filter
                                      xmlns:fes=\"http://www.opengis.net/fes/2.0\">
                                      <fes:PropertyIsEqualTo>
                                        <fes:ValueReference>NAME</fes:ValueReference>
                                        <fes:Literal>Blue Lake</fes:Literal>
                                      </fes:PropertyIsEqualTo>
                                    </filter>
                                    <indexed>true</indexed>
                                  </features>
                                  <tiles name=\"world_lakes\" identifier=\"wl1\">
                                    <description>world and lakes overlay</description>
                                    <srs>EPSG:4326</srs>
                                    <bbox>
                                      <minx>-0.17578125</minx>
                                      <maxx>0.17578125</maxx>
                                      <miny>-0.087890625</miny>
                                      <maxy>0.087890625</maxy>
                                    </bbox>
                                    <layers>wcs:World,cite:Lakes</layers>
                                    <styles></styles>
                                    <format>png</format>
                                    <bgcolor>aaaaaa</bgcolor>
                                    <transparent>true</transparent>
                                    <coverage>
                                      <minZoom>10</minZoom>
                                      <maxZoom>11</maxZoom>
                                    </coverage>
                                    <gridset>
                                      <grids>
                                        <grid>
                                          <zoomlevel>10</zoomlevel>
                                          <tilewidth>256</tilewidth>
                                          <tileheight>256</tileheight>
                                          <matrixwidth>2048</matrixwidth>
                                          <matrixheight>1024</matrixheight>
                                          <pixelxsize>0.00068</pixelxsize>
                                          <pixelysize>0.00068</pixelysize>
                                        </grid>
                                      </grids>
                                    </gridset>
                                  </tiles>
                                  <tiles name=\"world_lakes2\" identifier=\"wl2\">
                                    <description>world and lakes overlay 2</description>
                                    <srs>EPSG:4326</srs>
                                    <bbox>
                                      <minx>-0.17578125</minx>
                                      <maxx>0.17578125</maxx>
                                      <miny>-0.087890625</miny>
                                      <maxy>0.087890625</maxy>
                                    </bbox>
                                    <layers>wcs:World,cite:Lakes</layers>
                                    <styles></styles>
                                    <format>png</format>
                                    <bgcolor>aaaaaa</bgcolor>
                                    <transparent>true</transparent>
                                    <coverage>
                                      <minZoom>10</minZoom>
                                      <maxZoom>11</maxZoom>
                                    </coverage>
                                  </tiles>
                                </geopackage>
                              </wps:ComplexData>
                            </wps:Data>
                          </wps:Input>
                        </wps:DataInputs>
                        <wps:ResponseForm>
                          <wps:RawDataOutput>
                            <ows:Identifier>geopackage</ows:Identifier>
                          </wps:RawDataOutput>
                        </wps:ResponseForm>
                      </wps:Execute>
                      "
                    }
                  }
                ]
              }
            ]
         }
      }
   ]
}

C.2.2. Dataset Provenance OWS Context Fragment (GeoJSON)

This document is an example GeoJSON feature that can be linked to the parent (GeoPackage) document through hierarchical metadata.

{
   "type":"Feature",
   "id":"http://www.opengis.net/owc/1.0/examples/gml/boundaryline",
   "properties":{
      "title":"boundaryline",
      "abstract":"OS MasterMap Boundary Lines",
      "updated":"2012-05-10T14:35:00.400Z",
      "links":[
         {
            "rel":"data",
            "type":"application/gml+xml",
            "href":"..."
         }
      ],
      "offerings":{
        "code":"http://www.opengis.net/spec/owc-geojson/1.0/req/wfs",
        "operations":[
          {
            "code":"GetCapabilities",
            "method":"GET",
            "type":"application/xml",
            "href":"http://www.someserver.com/wrs.cgi?REQUEST=GetCapabilities&amp;SERVICE=WFS&VERSION=1.1.0"
          },
          {
            "code":"GetFeature",
            "method":"GET",
            "type":"application/gml+xml",
            "href":"http://www.someserver.com/wrs.cgi?REQUEST=GetFeature&amp;SERVICE=WFS&VERSION=1.1.0"
          }
        ]
      }
   }
}

C.3. Styles and Symbols

To facilitate loading style and symbol information into the GeoPackage, the participants produced the following JSON documents. These documents can also be used to verify that the correct style and symbol information was used.

Styles

{
  "styles": [
    {
      "style": "Boundary Line Backdrop",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-backdrop.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-backdrop.sld"
    },
    {
      "style": "Boundary Line Light",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-light.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-light.sld"
    },
    {
      "style": "Boundary Line Outdoor",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-outdoor.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-outdoor.sld"
    },
    {
      "style": "Boundary Line Standard",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-standard.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/boundaryline-standard.sld"
    },
    {
      "style": "Cartographic Symbol Backdrop",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-backdrop.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-backdrop.sld"
    },
    {
      "style": "Cartographic Symbol Light",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-light.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-light.sld"
    },
    {
      "style": "Cartographic Symbol Outdoor",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-outdoor.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-outdoor.sld"
    },
    {
      "style": "Cartographic Symbol Standard",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-standard.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographicsymbol-standard.sld"
    },
    {
      "style": "Cartographic Text Backdrop",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-backdrop.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-backdrop.sld"
    },
    {
      "style": "Cartographic Text Light",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-light.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-light.sld"
    },
    {
      "style": "Cartographic Text Outdoor",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-outdoor.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-outdoor.sld"
    },
    {
      "style": "Cartographic Text Standard",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-standard.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/cartographictext-standard.sld"
    },
    {
      "style": "Topographic Area Backdrop",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-backdrop.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-backdrop.sld"
    },
    {
      "style": "Topographic Area Light",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-light.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-light.sld"
    },
    {
      "style": "Topographic Area Outdoor",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-outdoor.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-outdoor.sld"
    },
    {
      "style": "Topographic Area Standard",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-standard.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicarea-standard.sld"
    },
    {
      "style": "Topographic Line Backdrop",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-backdrop.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-backdrop.sld"
    },
    {
      "style": "Topographic Line Light",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-light.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-light.sld"
    },
    {
      "style": "Topographic Line Outdoor",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-outdoor.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-outdoor.sld"
    },
    {
      "style": "Topographic Line Standard",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-standard.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicline-standard.sld"
    },
    {
      "style": "Topographic Point Backdrop",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-backdrop.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-backdrop.sld"
    },
    {
      "style": "Topographic Point Light",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-light.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-light.sld"
    },
    {
      "style": "Topographic Point Outdoor",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-outdoor.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-outdoor.sld"
    },
    {
      "style": "Topographic Point Standard",
      "uri": "https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-standard.sld",
      "filename": "https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/topographicpoint-standard.sld"
    }
  ]
}

Symbols

{
  "symbols":[
    {
      "symbol":"osmmsymbols/benchMarkSymbol-backdrop.svg",
      "description":"bench mark symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/benchMarkSymbol-light.svg",
      "description":"bench mark symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/benchMarkSymbol-outdoor.svg",
      "description":"bench mark symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/benchMarkSymbol.svg",
      "description":"bench mark symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryMereingChangeSymbol-backdrop.svg",
      "description":"boundary mereing change symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryMereingChangeSymbol-light.svg",
      "description":"boundary mereing change symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryMereingChangeSymbol-outdoor.svg",
      "description":"boundary mereing change symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryMereingChangeSymbol.svg",
      "description":"boundary mereing change symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryMereingChangeSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryPost-backdrop.svg",
      "description":"boundary post symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryPost-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryPost-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryPost-light.svg",
      "description":"boundary post symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryPost-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryPost-light.svg"
    },
    {
      "symbol":"osmmsymbols/boundaryPost.svg",
      "description":"boundary post symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryPost.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/boundaryPost.svg"
    },
    {
      "symbol":"osmmsymbols/culvertSymbol-backdrop.svg",
      "description":"culvert symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/culvertSymbol-light.svg",
      "description":"culvert symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/culvertSymbol-outdoor.svg",
      "description":"culvert symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/culvertSymbol.svg",
      "description":"culvert symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/culvertSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/fillBoulders-light.svg",
      "description":"fill boulders (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillBoulders-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillBoulders-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillBoulders.svg",
      "description":"fill boulders (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillBoulders.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillBoulders.svg"
    },
    {
      "symbol":"osmmsymbols/fillConiferousTrees-light.svg",
      "description":"fill coniferous trees (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillConiferousTrees-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillConiferousTrees-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillConiferousTrees.svg",
      "description":"fill coniferous trees (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillConiferousTrees.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillConiferousTrees.svg"
    },
    {
      "symbol":"osmmsymbols/fillCoppiceOrOsiers-light.svg",
      "description":"fill coppice or osiers (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillCoppiceOrOsiers-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillCoppiceOrOsiers-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillCoppiceOrOsiers.svg",
      "description":"fill coppice or osiers (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillCoppiceOrOsiers.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillCoppiceOrOsiers.svg"
    },
    {
      "symbol":"osmmsymbols/fillHealth-light.svg",
      "description":"fill health (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillHealth-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillHealth-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillHealth.svg",
      "description":"fill health (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillHealth.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillHealth.svg"
    },
    {
      "symbol":"osmmsymbols/fillMarsh-light.svg",
      "description":"fill marsh (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillMarsh-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillMarsh-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillMarsh.svg",
      "description":"fill marsh (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillMarsh.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillMarsh.svg"
    },
    {
      "symbol":"osmmsymbols/fillMixedWoodland-light.svg",
      "description":"fill mixed woodland (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillMixedWoodland-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillMixedWoodland-light.svg"
    },
    {
      "symbol":"osmmsymbols/benchMarkSymbol.svg",
      "description":"fill mixed woodland (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/fillNonconiferousTrees-light.svg",
      "description":"fill nonconiferous trees (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillNonconiferousTrees-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillNonconiferousTrees-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillNonconiferousTrees.svg",
      "description":"fill nonconiferous trees (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillNonconiferousTrees.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillNonconiferousTrees.svg"
    },
    {
      "symbol":"osmmsymbols/fillOrchard-light.svg",
      "description":"fill orchard (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillOrchard-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillOrchard-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillOrchard.svg",
      "description":"fill orchard (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillOrchard.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillOrchard.svg"
    },
    {
      "symbol":"osmmsymbols/fillRock-light.svg",
      "description":"fill rock (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRock-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRock-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillRock.svg",
      "description":"fill rock (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRock.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRock.svg"
    },
    {
      "symbol":"osmmsymbols/fillRoughGrassland-light.svg",
      "description":"fill rough grassland (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRoughGrassland-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRoughGrassland-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillRoughGrassland.svg",
      "description":"fill rough grassland (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRoughGrassland.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillRoughGrassland.svg"
    },
    {
      "symbol":"osmmsymbols/fillScree-light.svg",
      "description":"fill scree (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScree-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScree-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillScree.svg",
      "description":"fill scree (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScree.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScree.svg"
    },
    {
      "symbol":"osmmsymbols/fillScrub-light.svg",
      "description":"fill scrub (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScrub-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScrub-light.svg"
    },
    {
      "symbol":"osmmsymbols/fillScrub.svg",
      "description":"fill scrub (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScrub.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/fillScrub.svg"
    },
    {
      "symbol":"osmmsymbols/flowArrowSymbol-backdrop.svg",
      "description":"flow arrow symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/flowArrowSymbol-light.svg",
      "description":"flow arrow symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/flowArrowSymbol-outdoor.svg",
      "description":"flow arrow symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/flowArrowSymbol.svg",
      "description":"flow arrow symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/flowArrowSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/heritageSiteOfSymbol-backdrop.svg",
      "description":"heritage site of symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/heritageSiteOfSymbol-light.svg",
      "description":"heritage site of symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/heritageSiteOfSymbol-outdoor.svg",
      "description":"heritage site of symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/heritageSiteOfSymbol.svg",
      "description":"heritage site of symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/heritageSiteOfSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/positionedBoulder-backdrop.svg",
      "description":"positioned boulder symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/benchMarkSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/positionedBoulder-light.svg",
      "description":"positioned boulder symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedBoulder-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedBoulder-light.svg"
    },
    {
      "symbol":"osmmsymbols/positionedBoulder-outdoor.svg",
      "description":"positioned boulder symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedBoulder-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedBoulder-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/positionedBoulder.svg",
      "description":"positioned boulder symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedBoulder.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedBoulder.svg"
    },
    {
      "symbol":"osmmsymbols/positionedConiferousTreeSymbol-backdrop.svg",
      "description":"positioned coniferous tree symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/positionedConiferousTreeSymbol-light.svg",
      "description":"positioned coniferous tree symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/positionedConiferousTreeSymbol-outdoor.svg",
      "description":"positioned coniferous tree symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/positionedConiferousTreeSymbol.svg",
      "description":"positioned coniferous tree symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedConiferousTreeSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/positionedNonconiferousTreeSymbol-backdrop.svg",
      "description":"positioned nonconiferous tree symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/positionedNonconiferousTreeSymbol-light.svg",
      "description":"positioned nonconiferous tree symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/positionedNonconiferousTreeSymbol-outdoor.svg",
      "description":"positioned nonconiferous tree symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/positionedNonconiferousTreeSymbol.svg",
      "description":"positioned nonconiferous tree symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/positionedNonconiferousTreeSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/railwaySwitchSymbol-backdrop.svg",
      "description":"railway switch symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/railwaySwitchSymbol-light.svg",
      "description":"railway switch symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/railwaySwitchSymbol-outdoor.svg",
      "description":"railway switch symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/railwaySwitchSymbol.svg",
      "description":"railway switch symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/railwaySwitchSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/roadFlowSymbol-backdrop.svg",
      "description":"road flow symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/roadFlowSymbol-light.svg",
      "description":"road flow symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/roadFlowSymbol-outdoor.svg",
      "description":"road flow symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/roadFlowSymbol.svg",
      "description":"road flow symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/roadFlowSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/spotHeightSymbol-backdrop.svg",
      "description":"spot height symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/spotHeightSymbol-light.svg",
      "description":"spot height symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/spotHeightSymbol-outdoor.svg",
      "description":"spot height symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/spotHeightSymbol.svg",
      "description":"spot height symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/spotHeightSymbol.svg"
    },
    {
      "symbol":"osmmsymbols/triangulationStationSymbol-backdrop.svg",
      "description":"triangulation station symbol (backdrop)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol-backdrop.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol-backdrop.svg"
    },
    {
      "symbol":"osmmsymbols/triangulationStationSymbol-light.svg",
      "description":"triangulation station symbol (light)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol-light.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol-light.svg"
    },
    {
      "symbol":"osmmsymbols/triangulationStationSymbol-outdoor.svg",
      "description":"triangulation station symbol (outdoor)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol-outdoor.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol-outdoor.svg"
    },
    {
      "symbol":"osmmsymbols/triangulationStationSymbol.svg",
      "description":"triangulation station symbol (standard)",
      "uri":"https://github.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/blob/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol.svg",
      "type":"image/svg+xml",
      "filename":"https://raw.githubusercontent.com/OrdnanceSurvey/OSMM-Topography-Layer-stylesheets/master/Schema%20version%209/Stylesheets/Geoserver%20stylesheets%20(SLD)/osmmsymbols/triangulationStationSymbol.svg"
    }
  ]
}

Appendix D: Schemas

D.1. Database Schemas

The following subsections describe the database structure, including a picture from the corresponding feature type in the XML schemas (this helps to see how the GML encoding was mapped into a relational table) and an estimate of how much space each column is using.

The query used to estimate the disk usage by column is:

DROP FUNCTION IF EXISTS tc_column_size;
CREATE FUNCTION tc_column_size(table_name varchar(255), column_name varchar(255))
    RETURNS BIGINT AS
$$
    declare response BIGINT;
BEGIN
    EXECUTE 'select sum(pg_column_size(t."' || column_name || '")) from ' || table_name || ' t ' into response;
    return response;
END;
$$
    LANGUAGE plpgsql;

select z.table_name, z.column_name, z.data_type, z.size, pg_size_pretty(z.size) from(
select table_name, column_name, data_type, tc_column_size(table_name::varchar,
                                                               column_name::varchar) size
from information_schema.columns where table_schema='translator2') as z
where size is not null
order by z.table_name, z.size desc;

D.1.1. BoundaryLine

image
Figure 29. BoundaryLine schema
Table 46. translator2.boundaryline
Column Type Modifiers

ogc_fid

integer

not null

fid

character varying

featurecode

integer

version

integer

versiondate

character varying

theme

character varying[]

accuracyofposition

character varying

changedate

character varying[]

reasonforchange

character varying[]

descriptivegroup

character varying[]

descriptiveterm

character varying[]

make

character varying

physicallevel

integer

physicalpresence

character varying

wkb_geometry

geometry(LineString,27700)

style_description

text

style_code

integer

Indexes:

    "boundaryline_pkey" PRIMARY KEY, btree (ogc_fid)
    "boundaryline_fid_hash" hash (fid)
    "boundaryline_wkb_geometry_gist" gist (wkb_geometry)
Table 47. Column Sizes
table_name column_name data_type size pg_size_pretty

boundaryline

wkb_geometry

USER-DEFINED

265161565

253 MB

boundaryline

changedate

ARRAY

38938975

37 MB

boundaryline

reasonforchange

ARRAY

34801204

33 MB

boundaryline

descriptivegroup

ARRAY

27377612

26 MB

boundaryline

theme

ARRAY

27375861

26 MB

boundaryline

descriptiveterm

ARRAY

17420125

17 MB

boundaryline

fid

character varying

10855467

10 MB

boundaryline

style_description

text

8686231

8483 kB

boundaryline

versiondate

character varying

5686197

5553 kB

boundaryline

physicalpresence

character varying

4652343

4543 kB

boundaryline

accuracyofposition

character varying

2622003

2561 kB

boundaryline

featurecode

integer

2067708

2019 kB

boundaryline

version

integer

2067708

2019 kB

boundaryline

ogc_fid

integer

2067708

2019 kB

boundaryline

physicallevel

integer

2067708

2019 kB

boundaryline

style_code

integer

2067708

2019 kB

D.1.2. CartographicSymbol

image
Figure 30. CartographicSymbol schema
Table 48. translator2.cartographicsymbol
Column Type Modifiers

ogc_fid

integer

not null

fid

character varying

featurecode

integer

version

integer

versiondate

character varying

theme

character varying[]

changedate

character varying[]

reasonforchange

character varying[]

descriptivegroup

character varying[]

descriptiveterm

character varying[]

orientation

integer

physicallevel

integer

physicalpresence

character varying

referencetofeature

character varying

wkb_geometry

geometry(Point,27700)

style_description

text

style_code

integer

Indexes:

    "cartographicsymbol_pkey" PRIMARY KEY, btree (ogc_fid)
    "cartographicsymbol_fid_hash" hash (fid)
    "cartographicsymbol_wkb_geometry_gist" gist (wkb_geometry)
Table 49. Column Sizes
table_name column_name data_type size pg_size_pretty

cartographicsymbol

changedate

ARRAY

184872674

176 MB

cartographicsymbol

descriptivegroup

ARRAY

155023485

148 MB

cartographicsymbol

descriptiveterm

ARRAY

152119373

145 MB

cartographicsymbol

reasonforchange

ARRAY

151525579

145 MB

cartographicsymbol

theme

ARRAY

147975353

141 MB

cartographicsymbol

wkb_geometry

USER-DEFINED

107447581

102 MB

cartographicsymbol

style_description

text

81242928

77 MB

cartographicsymbol

fid

character varying

77806869

74 MB

cartographicsymbol

versiondate

character varying

40755979

39 MB

cartographicsymbol

referencetofeature

character varying

27103252

26 MB

cartographicsymbol

version

integer

14820356

14 MB

cartographicsymbol

physicallevel

integer

14820356

14 MB

cartographicsymbol

orientation

integer

14820356

14 MB

cartographicsymbol

ogc_fid

integer

14820356

14 MB

cartographicsymbol

style_code

integer

14820356

14 MB

cartographicsymbol

featurecode

integer

14820356

14 MB

cartographicsymbol

physicalpresence

character varying

9691460

9464 kB

D.1.3. CartographicText

image
Figure 31. CartographicText schema
Table 50. translator2.cartographictext
Column Type Modifiers

ogc_fid

integer

not null

fid

character varying

featurecode

integer

version

integer

versiondate

character varying

theme

character varying[]

changedate

character varying[]

reasonforchange

character varying[]

descriptivegroup

character varying[]

descriptiveterm

character varying[]

make

character varying

physicallevel

integer

physicalpresence

character varying

anchorposition

integer

font

integer

height

double precision

orientation

integer

textstring

character varying

wkb_geometry

geometry(Point,27700)

style_description

text

style_code

integer

colour_code

integer

font_code

integer

rotation

integer

geo_x

numeric

geo_y

numeric

anchor

text

Indexes:

    "cartographictext_pkey" PRIMARY KEY, btree (ogc_fid)
    "cartographictext_fid_hash" hash (fid)
    "cartographictext_wkb_geometry_gist" gist (wkb_geometry)
Table 51. Column Sizes
table_name column_name data_type size pg_size_pretty

cartographictext

changedate

ARRAY

1073173561

1023 MB

cartographictext

descriptivegroup

ARRAY

994331900

948 MB

cartographictext

reasonforchange

ARRAY

900712429

859 MB

cartographictext

theme

ARRAY

842627372

804 MB

cartographictext

wkb_geometry

USER-DEFINED

633790244

604 MB

cartographictext

fid

character varying

458951556

438 MB

cartographictext

style_description

text

312723453

298 MB

cartographictext

versiondate

character varying

240403196

229 MB

cartographictext

height

double precision

174838688

167 MB

cartographictext

textstring

character varying

132767996

127 MB

cartographictext

make

character varying

132212048

126 MB

cartographictext

geo_x

numeric

89961040

86 MB

cartographictext

ogc_fid

integer

87419344

83 MB

cartographictext

featurecode

integer

87419344

83 MB

cartographictext

version

integer

87419344

83 MB

cartographictext

physicallevel

integer

87419344

83 MB

cartographictext

anchorposition

integer

87419344

83 MB

cartographictext

font

integer

87419344

83 MB

cartographictext

orientation

integer

87419344

83 MB

cartographictext

style_code

integer

87419344

83 MB

cartographictext

colour_code

integer

87419344

83 MB

cartographictext

font_code

integer

87419344

83 MB

cartographictext

rotation

integer

87419344

83 MB

cartographictext

descriptiveterm

ARRAY

81930644

78 MB

cartographictext

geo_y

numeric

76737608

73 MB

cartographictext

anchor

text

50470352

48 MB

D.1.4. TopographicArea

image
Figure 32. TopographicArea schema
Table 52. translator2.topographicarea
Column Type Modifiers

ogc_fid

integer

not null

fid

character varying

featurecode

integer

version

integer

versiondate

character varying

theme

character varying[]

broken

integer

calculatedareavalue

double precision

changedate

character varying[]

reasonforchange

character varying[]

descriptivegroup

character varying[]

descriptiveterm

character varying[]

make

character varying

physicallevel

integer

physicalpresence

character varying

wkb_geometry

geometry(Polygon,27700)

style_description

text

style_code

integer

Indexes:

    "topographicarea_pkey" PRIMARY KEY, btree (ogc_fid)
    "topographicarea_fid_hash" hash (fid)
    "topographicarea_wkb_geometry_gist" gist (wkb_geometry)
Table 53. Column Sizes
table_name column_name data_type size pg_size_pretty

topographicarea

wkb_geometry

USER-DEFINED

47102105309

44 GB

topographicarea

changedate

ARRAY

6812855167

6497 MB

topographicarea

reasonforchange

ARRAY

5668421069

5406 MB

topographicarea

descriptivegroup

ARRAY

4569163202

4357 MB

topographicarea

theme

ARRAY

4179107948

3986 MB

topographicarea

fid

character varying

2446176579

2333 MB

topographicarea

descriptiveterm

ARRAY

2037717656

1943 MB

topographicarea

style_description

text

1984705349

1893 MB

topographicarea

versiondate

character varying

1334032546

1272 MB

topographicarea

make

character varying

1004779155

958 MB

topographicarea

calculatedareavalue

double precision

970205488

925 MB

topographicarea

physicallevel

integer

485102744

463 MB

topographicarea

ogc_fid

integer

485102744

463 MB

topographicarea

version

integer

485102744

463 MB

topographicarea

featurecode

integer

485102744

463 MB

topographicarea

style_code

integer

485102744

463 MB

topographicarea

physicalpresence

character varying

20709

20 kB

D.1.5. TopographicLine

image
Figure 33. TopographicLine schema
Table 54. translator2.topographicline
Column Type Modifiers

ogc_fid

integer

not null

fid

character varying

featurecode

integer

version

integer

versiondate

character varying

theme

character varying[]

broken

integer

accuracyofposition

character varying

changedate

character varying[]

reasonforchange

character varying[]

descriptivegroup

character varying[]

descriptiveterm

character varying[]

stringlist

character varying[]

heightabovedatum

double precision

accuracyofheightabovedatum

character varying

heightabovegroundlevel

double precision

accuracyofheightabovegroundlevel

character varying

make

character varying

physicallevel

integer

physicalpresence

character varying

wkb_geometry

geometry(LineString,27700)

style_description

text

style_code

integer

Indexes:

    "topographicline_pkey" PRIMARY KEY, btree (ogc_fid)
    "topographicline_fid_hash" hash (fid)
    "topographicline_wkb_geometry_gist" gist (wkb_geometry)
Table 55. Column Sizes
table_name column_name data_type size pg_size_pretty

topographicline

wkb_geometry

USER-DEFINED

37495346246

35 GB

topographicline

changedate

ARRAY

16384605821

15 GB

topographicline

theme

ARRAY

14190603699

13 GB

topographicline

reasonforchange

ARRAY

13698155074

13 GB

topographicline

descriptivegroup

ARRAY

13375347282

12 GB

topographicline

fid

character varying

7111120968

6782 MB

topographicline

style_description

text

5585482278

5327 MB

topographicline

descriptiveterm

ARRAY

5145212712

4907 MB

topographicline

physicalpresence

character varying

4028977289

3842 MB

topographicline

versiondate

character varying

3724872888

3552 MB

topographicline

accuracyofposition

character varying

1744975185

1664 MB

topographicline

style_code

integer

1354499232

1292 MB

topographicline

featurecode

integer

1354499232

1292 MB

topographicline

physicallevel

integer

1354499232

1292 MB

topographicline

ogc_fid

integer

1354499232

1292 MB

topographicline

version

integer

1354499232

1292 MB

topographicline

make

character varying

997926576

952 MB

topographicline

stringlist

ARRAY

235813655

225 MB

D.1.6. TopographicPoint

image
Figure 34. TopographicPoint schema
Table 56. translator2.topographicpoint
Column Type Modifiers

ogc_fid

integer

not null

fid

character varying

featurecode

integer

version

integer

versiondate

character varying

theme

character varying[]

accuracyofposition

character varying

changedate

character varying[]

reasonforchange

character varying[]

descriptivegroup

character varying[]

descriptiveterm

character varying[]

heightabovedatum

double precision

accuracyofheightabovedatum

character varying

heightabovegroundlevel

double precision

accuracyofheightabovegroundlevel

character varying

make

character varying

physicallevel

integer

physicalpresence

character varying

wkb_geometry

geometry(Point,27700)

style_description

text

style_code

integer

Indexes:

    "topographicpoint_pkey" PRIMARY KEY, btree (ogc_fid)
    "topographicpoint_fid_hash" hash (fid)
    "topographicpoint_wkb_geometry_gist" gist (wkb_geometry)
Table 57. Column Sizes
table_name column_name data_type size pg_size_pretty

topographicpoint

changedate

ARRAY

226922858

216 MB

topographicpoint

reasonforchange

ARRAY

189564274

181 MB

topographicpoint

descriptivegroup

ARRAY

173929336

166 MB

topographicpoint

theme

ARRAY

166278940

159 MB

topographicpoint

descriptiveterm

ARRAY

155635062

148 MB

topographicpoint

wkb_geometry

USER-DEFINED

123822460

118 MB

topographicpoint

fid

character varying

89664540

86 MB

topographicpoint

style_description

text

79341562

76 MB

topographicpoint

versiondate

character varying

46967140

45 MB

topographicpoint

make

character varying

23644160

23 MB

topographicpoint

accuracyofposition

character varying

21611497

21 MB

topographicpoint

version

integer

17078960

16 MB

topographicpoint

physicallevel

integer

17078960

16 MB

topographicpoint

style_code

integer

17078960

16 MB

topographicpoint

featurecode

integer

17078960

16 MB

topographicpoint

ogc_fid

integer

17078960

16 MB

topographicpoint

heightabovedatum

double precision

10227152

9987 kB

topographicpoint

accuracyofheightabovedatum

character varying

6534602

6381 kB

topographicpoint

physicalpresence

character varying

61740

60 kB

D.1.7. Enumerations

The following XML schema extract shows all potential enumerations.

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns:osgb="http://www.ordnancesurvey.co.uk/xml/namespaces/osgb" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ordnancesurvey.co.uk/xml/namespaces/osgb" elementFormDefault="qualified" attributeFormDefault="unqualified" version="3.5">
        <annotation>
                <appinfo>OSSimpleTypes.xsd 3.5 2014/04/29</appinfo>
                <documentation xml:lang="en">Ordnance Survey, (c) Crown Copyright. All Rights Reserved April 2014</documentation>
                <documentation xml:lang="en">See http://www.ordnancesurvey.co.uk/xml/schema for guidelines and related information</documentation>
                <documentation xml:lang="en">This schema defines the simple types used as properties on features.</documentation>
        </annotation>
        <!-- ================================================================
        Simple Type Definitions
        ================================================================ -->
        <simpleType name="accuracyOfPositionType">
                <restriction base="string">
                        <enumeration value="1.0m"/>
                        <enumeration value="2.5m"/>
                        <enumeration value="6.0m"/>
                        <enumeration value="8.0m"/>
                        <enumeration value="Unknown"/>
                </restriction>
        </simpleType>
        <simpleType name="deliveryPointSuffixType">
                <restriction base="string">
                        <maxLength value="2"/>
                </restriction>
        </simpleType>
        <simpleType name="descriptiveGroupType">
                <restriction base="string">
                        <enumeration value="A Road"/>
                        <enumeration value="B Road"/>
                        <enumeration value="Building"/>
                        <enumeration value="Buildings Or Structure"/>
                        <enumeration value="Built Environment"/>
                        <enumeration value="Ferry Connection"/>
                        <enumeration value="General Feature"/>
                        <enumeration value="General Surface"/>
                        <enumeration value="Glasshouse"/>
                        <enumeration value="Height Control"/>
                        <enumeration value="Historic Interest"/>
                        <enumeration value="Information Point"/>
                        <enumeration value="Inland Water"/>
                        <enumeration value="Landform"/>
                        <enumeration value="Motorway"/>
                        <enumeration value="Named Path"/>
                        <enumeration value="Named Road"/>
                        <enumeration value="Natural Environment"/>
                        <enumeration value="Network Connection"/>
                        <enumeration value="Network Or Polygon Closing Geometry"/>
                        <enumeration value="Non Specification Detail"/>
                        <enumeration value="Path"/>
                        <enumeration value="Path Routing Information"/>
                        <enumeration value="Path Topology"/>
                        <enumeration value="Political Or Administrative"/>
                        <enumeration value="Rail"/>
                        <enumeration value="Road Or Track"/>
                        <enumeration value="Road Routing Information"/>
                        <enumeration value="Road Topology"/>
                        <enumeration value="Roadside"/>
                        <enumeration value="Structure"/>
                        <enumeration value="Terrain And Height"/>
                        <enumeration value="Tidal Water"/>
                        <enumeration value="Unclassified"/>
                </restriction>
        </simpleType>
        <simpleType name="descriptiveTermType">
                <restriction base="string">
                        <enumeration value="A Road"/>
                        <enumeration value="Agricultural Land"/>
                        <enumeration value="Air Height"/>
                        <enumeration value="Alley"/>
                        <enumeration value="Aqueduct"/>
                        <enumeration value="Archway"/>
                        <enumeration value="B Road"/>
                        <enumeration value="Bench Mark"/>
                        <enumeration value="Bottom Of Cliff"/>
                        <enumeration value="Bottom Of Slope"/>
                        <enumeration value="Boulders"/>
                        <enumeration value="Boulders (Scattered)"/>
                        <enumeration value="Boundary Half Mereing"/>
                        <enumeration value="Boundary Post Or Stone"/>
                        <enumeration value="Bridge"/>
                        <enumeration value="Bridleway"/>
                        <enumeration value="Buffer"/>
                        <enumeration value="Canal"/>
                        <enumeration value="Canal Feeder"/>
                        <enumeration value="Canal Path"/>
                        <enumeration value="Capstan"/>
                        <enumeration value="Cattle Grid"/>
                        <enumeration value="Cave"/>
                        <enumeration value="Chimney"/>
                        <enumeration value="Cliff"/>
                        <enumeration value="Collects"/>
                        <enumeration value="Compound"/>
                        <enumeration value="Conduit"/>
                        <enumeration value="Coniferous Trees"/>
                        <enumeration value="Coniferous Trees (Scattered)"/>
                        <enumeration value="Conveyor"/>
                        <enumeration value="Coppice Or Osiers"/>
                        <enumeration value="County"/>
                        <enumeration value="Course Of Heritage"/>
                        <enumeration value="Crane"/>
                        <enumeration value="Cross"/>
                        <enumeration value="Culvert"/>
                        <enumeration value="Cycle Path"/>
                        <enumeration value="Direction Of Flow"/>
                        <enumeration value="Distance Marker"/>
                        <enumeration value="District"/>
                        <enumeration value="Disused Feature"/>
                        <enumeration value="Division"/>
                        <enumeration value="Drain"/>
                        <enumeration value="Electoral"/>
                        <enumeration value="Electricity Sub Station"/>
                        <enumeration value="Emergency Telephone"/>
                        <enumeration value="Ferry"/>
                        <enumeration value="Flagstaff"/>
                        <enumeration value="Footbridge"/>
                        <enumeration value="Footpath"/>
                        <enumeration value="Ford"/>
                        <enumeration value="Foreshore"/>
                        <enumeration value="Fountain"/>
                        <enumeration value="Gantry"/>
                        <enumeration value="Gas Governor"/>
                        <enumeration value="Gate"/>
                        <enumeration value="Groyne"/>
                        <enumeration value="Guide Post"/>
                        <enumeration value="Heath"/>
                        <enumeration value="Inferred Property Closing Link"/>
                        <enumeration value="Issues"/>
                        <enumeration value="Land Use Change Polygon Closing Link"/>
                        <enumeration value="Landfill"/>
                        <enumeration value="Landfill (Inactive)"/>
                        <enumeration value="Letter Box"/>
                        <enumeration value="Level Crossing"/>
                        <enumeration value="Lighting Gantry"/>
                        <enumeration value="Line Of Mooring Posts"/>
                        <enumeration value="Line Of Posts"/>
                        <enumeration value="Local Street"/>
                        <enumeration value="Lock"/>
                        <enumeration value="Lock Gate"/>
                        <enumeration value="Map Detail Traverse Station"/>
                        <enumeration value="Marsh"/>
                        <enumeration value="Marsh Reeds Or Saltmarsh"/>
                        <enumeration value="Mast"/>
                        <enumeration value="Mean High Water (Springs)"/>
                        <enumeration value="Mean Low Water (Springs)"/>
                        <enumeration value="Mill Leat"/>
                        <enumeration value="Mine Leat"/>
                        <enumeration value="Minor Road"/>
                        <enumeration value="Mineral Workings"/>
                        <enumeration value="Mineral Workings (Inactive)"/>
                        <enumeration value="Mooring Post"/>
                        <enumeration value="Motorway"/>
                        <enumeration value="Mud"/>
                        <enumeration value="Multi Surface"/>
                        <enumeration value="Narrow Gauge"/>
                        <enumeration value="Network Closing Link"/>
                        <enumeration value="Nonconiferous Trees"/>
                        <enumeration value="Nonconiferous Trees (Scattered)"/>
                        <enumeration value="Normal Tidal Limit"/>
                        <enumeration value="Orchard"/>
                        <enumeration value="Outline"/>
                        <enumeration value="Overhead Construction"/>
                        <enumeration value="Parish"/>
                        <enumeration value="Parliamentary"/>
                        <enumeration value="Pedestrian Crossing"/>
                        <enumeration value="Pedestrian"/>
                        <enumeration value="Pedestrianised Street"/>
                        <enumeration value="Pole"/>
                        <enumeration value="Polygon Closing Link"/>
                        <enumeration value="Positioned Boulder"/>
                        <enumeration value="Positioned Coniferous Tree"/>
                        <enumeration value="Positioned Nonconiferous Tree"/>
                        <enumeration value="Post"/>
                        <enumeration value="Primary Route"/>
                        <enumeration value="Private Road - Publicly Accessible"/>
                        <enumeration value="Private Road - Restricted Access"/>
                        <enumeration value="Public"/>
                        <enumeration value="Public Convenience"/>
                        <enumeration value="Public Telephone"/>
                        <enumeration value="Pylon"/>
                        <enumeration value="Rail Signal Gantry"/>
                        <enumeration value="Reeds"/>
                        <enumeration value="Reservoir"/>
                        <enumeration value="Ridge Or Rock Line"/>
                        <enumeration value="Road"/>
                        <enumeration value="Road Name Or Classification"/>
                        <enumeration value="Road Related Flow"/>
                        <enumeration value="Rock"/>
                        <enumeration value="Rock (Scattered)"/>
                        <enumeration value="Rough Grassland"/>
                        <enumeration value="Saltmarsh"/>
                        <enumeration value="Sand"/>
                        <enumeration value="Scree"/>
                        <enumeration value="Scrub"/>
                        <enumeration value="Shared Use"/>
                        <enumeration value="Shingle"/>
                        <enumeration value="Signal"/>
                        <enumeration value="Sinks"/>
                        <enumeration value="Site Of Heritage"/>
                        <enumeration value="Slag Heap"/>
                        <enumeration value="Slag Heap (Inactive)"/>
                        <enumeration value="Slipway"/>
                        <enumeration value="Slope"/>
                        <enumeration value="Sloping Masonry"/>
                        <enumeration value="Sluice"/>
                        <enumeration value="Spoil Heap"/>
                        <enumeration value="Spoil Heap (Inactive)"/>
                        <enumeration value="Spot Height"/>
                        <enumeration value="Spreads"/>
                        <enumeration value="Spring"/>
                        <enumeration value="Standard Gauge Track"/>
                        <enumeration value="Step"/>
                        <enumeration value="Static Water"/>
                        <enumeration value="Structure"/>
                        <enumeration value="Subway"/>
                        <enumeration value="Switch"/>
                        <enumeration value="Swimming Pool"/>
                        <enumeration value="Tank"/>
                        <enumeration value="Telecommunications Mast"/>
                        <enumeration value="Top Of Cliff"/>
                        <enumeration value="Top Of Slope"/>
                        <enumeration value="Track"/>
                        <enumeration value="Traffic Calming"/>
                        <enumeration value="Triangulation Point Or Pillar"/>
                        <enumeration value="Trunk Road"/>
                        <enumeration value="Tunnel Edge"/>
                        <enumeration value="Unmade Path Alignment"/>
                        <enumeration value="Upper Level Of Communication"/>
                        <enumeration value="Watercourse"/>
                        <enumeration value="Waterfall"/>
                        <enumeration value="Waterfall (Vertical)"/>
                        <enumeration value="Weir"/>
                        <enumeration value="Well"/>
                        <enumeration value="Wind Turbine"/>
                </restriction>
        </simpleType>
        <simpleType name="makeType">
                <restriction base="string">
                        <enumeration value="Manmade"/>
                        <enumeration value="Multiple"/>
                        <enumeration value="Natural"/>
                        <enumeration value="Unclassified"/>
                        <enumeration value="Unknown"/>
                </restriction>
        </simpleType>
        <simpleType name="matchStatusType">
                <restriction base="string">
                        <enumeration value="Unmatched"/>
                        <enumeration value="Matched"/>
                        <enumeration value="Matched With Discrepancy (Pending)"/>
                        <enumeration value="Matched With Discrepancy (Referred)"/>
                        <enumeration value="Matched With Discrepancy (Unresolved)"/>
                </restriction>
        </simpleType>
        <simpleType name="multipleOccupancyCountType">
                <restriction base="unsignedShort">
                        <minInclusive value="2"/>
                        <maxInclusive value="9999"/>
                </restriction>
        </simpleType>
        <simpleType name="NatureOfRoadType">
                <restriction base="string">
                        <enumeration value="Single Carriageway"/>
                        <enumeration value="Dual Carriageway"/>
                        <enumeration value="Slip Road"/>
                        <enumeration value="Roundabout"/>
                        <enumeration value="Enclosed Traffic Area Link"/>
                        <enumeration value="Traffic Island Link At Junction"/>
                        <enumeration value="Traffic Island Link"/>
                </restriction>
        </simpleType>
        <simpleType name="orientationType">
                <restriction base="unsignedShort">
                        <minInclusive value="0"/>
                        <maxInclusive value="3599"/>
                </restriction>
        </simpleType>
        <simpleType name="physicalLevelType">
                <restriction base="short">
                        <minInclusive value="-1"/>
                        <maxInclusive value="51"/>
                </restriction>
        </simpleType>
        <simpleType name="physicalPresenceType">
                <restriction base="string">
                        <enumeration value="Boundary"/>
                        <enumeration value="Closing"/>
                        <enumeration value="Edge / Limit"/>
                        <enumeration value="Extent"/>
                        <enumeration value="Indicator"/>
                        <enumeration value="Minor Detail"/>
                        <enumeration value="Moveable"/>
                        <enumeration value="Network"/>
                        <enumeration value="Obstructing"/>
                        <enumeration value="Overhead"/>
                </restriction>
        </simpleType>
        <simpleType name="physicalStatusType">
                <restriction base="string">
                        <enumeration value="Demolished"/>
                        <enumeration value="Existing"/>
                        <enumeration value="Planned"/>
                        <enumeration value="Unknown"/>
                </restriction>
        </simpleType>
        <simpleType name="positionalQualityStringType">
                <restriction base="string">
                        <enumeration value="Final"/>
                        <enumeration value="Provisional"/>
                </restriction>
        </simpleType>
        <simpleType name="positionalQualityAccuracyType">
                <restriction base="string">
                        <enumeration value="Approximate"/>
                        <enumeration value="Estimate"/>
                        <enumeration value="Postcode Sector Mean"/>
                        <enumeration value="Postcode Unit Mean"/>
                        <enumeration value="Surveyed"/>
                </restriction>
        </simpleType>
        <simpleType name="postCodeStringType">
                <restriction base="string">
                        <maxLength value="8"/>
                </restriction>
        </simpleType>
        <simpleType name="postCodeTypeType">
                <restriction base="string">
                        <enumeration value="Small"/>
                        <enumeration value="Large"/>
                </restriction>
        </simpleType>
        <simpleType name="reasonForChangeType">
                <restriction base="string">
                        <enumeration value="Attributes"/>
                        <enumeration value="Incomplete"/>
                        <enumeration value="Modified"/>
                        <enumeration value="New"/>
                        <enumeration value="Position"/>
                        <enumeration value="Reclassified"/>
                        <enumeration value="Restructured"/>
                        <enumeration value="Software"/>
                        <enumeration value="TextChange"/>
                </restriction>
        </simpleType>
        <simpleType name="signType">
                <restriction base="string">
                        <enumeration value="+"/>
                        <enumeration value="-"/>
                </restriction>
        </simpleType>
        <simpleType name="structureTypeType">
                <restriction base="string">
                        <enumeration value="Other Structure"/>
                        <enumeration value="Permanent Building"/>
                        <enumeration value="Unknown"/>
                </restriction>
        </simpleType>
        <simpleType name="themeType">
                <restriction base="string">
                        <enumeration value="Address"/>
                        <enumeration value="Administrative Boundaries"/>
                        <enumeration value="Buildings"/>
                        <enumeration value="Heritage And Antiquities"/>
                        <enumeration value="Land"/>
                        <enumeration value="Multi Occupancy"/>
                        <enumeration value="Non Postal"/>
                        <enumeration value="Being Built"/>
                        <enumeration value="Path Network"/>
                        <enumeration value="Path Routing Information"/>
                        <enumeration value="Postal"/>
                        <enumeration value="Rail"/>
                        <enumeration value="Road Network"/>
                        <enumeration value="Road Routing Information"/>
                        <enumeration value="Roads Tracks And Paths"/>
                        <enumeration value="Structures"/>
                        <enumeration value="Terrain And Height"/>
                        <enumeration value="Water"/>
                </restriction>
        </simpleType>
</schema>

D.2. JSON Schemas

D.2.1. Dataset Provenance GeoJSON Schema

Note

A number of low-importance optional elements are omitted from this schema.

{
  "id":"TBD",
  "$schema":"https://json-schema.org/draft/2019-09/schema",
  "type":"object",
  "properties":{
    "type":{
      "type":"string",
      "description":"Type of GeoJSON object",
      "pattern":"FeatureCollection"
    },
    "properties":{
      "type":"object",
      "properties":{
        "links":{
          "type":"array",
          "items":{
            "type":"object",
            "properties":{
              "rel":{
                "type":"string"
              },
              "href":{
                "type":"string"
              },
              "title":{
                "type":"string"
              }
            }
          }
        },
        "lang":{
          "type":"string",
          "description":"Language of Context document content"
        },
        "title":{
          "type":"string",
          "description":"Title for the Context document"
        },
        "subtitle":{
          "type":"string",
          "description":"Description of the Context document purpose or content"
        },
        "updated":{
          "type":"string",
          "description":"Date of a creation or update of the Context document",
          "format":"date"
        },
        "authors":{
          "type":"array",
          "description":"Entity primarily responsible for making the Context document",
          "items":{
            "type":"string"
          }
        },
        "publisher":{
          "type":"string",
          "description":"Identifier for the publisher of the Context document"
        },
        "generator":{
          "type":"string",
          "description":"Tool/application used to create the Context document and its properties"
        },
        "rights":{
          "type":"string",
          "description":"Information about rights held in and over the Context document"
        },
        "categories":{
          "type":"object",
          "properties":{
            "term":{
              "type":"array",
              "description":"Category related to this context document. It MAY have a related code-list that is identified by the scheme attribute"
              "items":{
                "type":"string"
              }
            }
          }
        }
      },
      "required":["links","lang","title","updated"]
    },
    "id":{
      "type":"string",
      "description":"Unambiguous reference to the identification of the Context document (IRI)"
    },
    "bbox":{
      "type":"array",
      "description":"Geographic Area of interest of the users of the Context document according to the GeoJSON “bbox” definition",
      "items":{
        "type":"number"
      }
    },
    "date":{
      "type":"string",
      "description":"Date or range of dates relevant to the resource"
    },
    "features":{
      "type":"array",
      "description":"Resources available on the Context document"
      "items":{
        "type":"object",
        "properties":{
          "id":{
            "type":"string",
            "description":"Unambiguous reference to the identification of the Context resource (IRI)"
          },
          "properties":{
            "type":"object",
            "properties":{
              "title":{
                "type":"string",
                "description":"Title given to the Context resource"
              },
              "abstract":{
                "type":"string",
                "description":"Account of the content of the Context resource. The purpose is to provide a generic description of the content in a format understandable by generic readers."
              },
              "updated":{
                "type":"string",
                "description":"Date of a creation or update of the Context document",
                "format":"date"
              },
              "authors":{
                "type":"array",
                "description":"Entity primarily responsible for making the content of the Context resource",
                "items":{
                  "type":"string"
                }
              },
              "publisher":{
                "type":"string",
                "description":"Entity responsible for making the Context resource available"
              },
              "rights":{
                "type":"string",
                "description":"Information about rights held in and over the Context resource"
              },
              "date":{
                "type":"string",
                "description":"Date or range of dates relevant to the Context resource"
              },
              "links":{
                "type":"array",
                "items":{
                  "type":"object",
                  "properties":{
                    "rel":{
                      "type":"string"
                    },
                    "href":{
                      "type":"string"
                    },
                    "title":{
                      "type":"string"
                    }
                  }
                }
              },
              "offerings":{
                "type":"array",
                "items":{
                  "type":"object",
                  "properties":{
                    "code":{
                      "type":"string"
                    },
                    "operations":{
                      "type":"array",
                      "items":{
                        "type":"object",
                        "properties":{
                          "method":{
                            "type":"string"
                          },
                          "code":{
                            "type":"string"
                          },
                          "href":{
                            "type":"string"
                          },
                          "type":{
                            "type":"string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "required":["title","updated","links"]
          },
          "geometry":{
            "type":"object",
            "description":"Spatial extent or scope of the content of the Context resource"
          },
          "required":["id","properties"]
        }
      }
    }
  },
  "required":["type","properties"]
}

Appendix E: Revision History

Table 58. Revision History
Date Editor Release Primary clauses modified Descriptions

April 17, 2020

J. Yutzler

.1

all

initial version

November 16, 2020

J. Yutzler

.9

all

3 week rule

Appendix F: Bibliography

bibliography::[]


1. In some cases, URIs need to be generated but since styles already have URIs, those URIs are used for consistency.
2. The JDBC interface, used to interact with SQLite, offers a notion of PreparedStament to interact with the database. A prepared statement is a SQL statement with parameters, that gets parsed once by the database, and executed many times providing only the value of the parameters. Prepared statement calls can also be queued, and then executed in batches, further reducing the number of messages exchanged between client and database. In the case of SQLite this is still relevant, as it reduces the number of JNI calls executed down to the native SQLite library
3. If the semantic annotation represents a metadata profile, then the extension name for the metadata profile should be used as the type.