I. Abstract
This best practice document on UML to JSON encoding rules is an initiative of Geonovum. The aim is to come to a standardized encoding from UML to JSON, in order to achieve technical interoperability in the chain from conceptual models to JSON implementation. In this document, JSON implementation includes plain JSON, GeoJSON and JSON-FG.
Application schemas in UML are used to model geospatial information for a given domain, as part of data specifications defining information and data content of a relevant universe of discourse. In the geospatial domain, UML profiles are defined by ISO 19103:2015 and ISO 19109:2015. These profiles are also used in this document. Application schemas operate at the conceptual level. At the implementation or data level, JSON is one of the major data encodings used by current web applications. The UML to JSON encoding rules defined in the context of this document is a best practice. Eventually, this document may also support the development of an international standard for the conversion of UML to JSON (Schema) in the geospatial domain.
To facilitate a proper JSON encoding, an extension of the ISO 19103 and 19109 UML profiles is proposed, resulting in a UML-JSON encoding profile.
The encoding rules are structured in 40 requirements and a number of recommendations, subdivided into 18 core requirements, 1 requirement specific for plain JSON schema format, 5 for GeoJSON format, 5 for JSON-FG Schema format, 3 requirements for binding and referencing of elements, 2 for union constructs, 5 for code lists and 1 for encoding a dedicated entity property in JSON. The requirement classes are supported by UML examples and subsequent JSON encodings.
II. Keywords
The following are keywords to be used by search engines and document catalogues.
ogcdoc, OGC document, UML, JSON, JSON Schema, encoding, GeoJSON, JSON-FG
III. Preface
The project leading to this document was initiated by Geonovum. In collaboration with Interactive Instruments a best practice is developed on encoding UML to JSON. The project team consisted of the following persons:
Clemens Portele (Interactive Instruments)
Johannes Echterhoff (Interactive Instruments)
Linda van den Brink (Geonovum)
Paul Janssen (Geonovum)
Pieter Bresters (Geonovum)
Wilko Quak (Geonovum).
This document defines how a conceptual schema in UML, compliant to ISO 19103:2015 and ISO 19109:2015, can be encoded in JSON. A number of requirements classes are defined, which contain the necessary requirements and technical details.
JSON is one of the major data encodings used by current web applications. In order to achieve a high level of interoperability when exchanging JSON encoded data between such applications, especially when the applications are developed by different entities, the semantics and structure of the data need to be well defined. In the geospatial domain, conceptual schemas are used to define application relevant information. Typically, some additional schema language is used to define the structures for encoding the information. For JSON encoded data, such a schema language is JSON Schema. Ideally, the JSON Schema constructs can automatically be derived from a conceptual schema. For that task, a set of encoding rules is needed.
Within the OGC, the UML-to-GML Application Schema Pilot 2020 (UGAS-2020) was the first innovation initiative that produced a comprehensive set of encoding rules, for the conversion of ISO 19109 compliant application schemas in UML to JSON Schema. The UGAS-2020 Engineering Report documents the findings of that initiative.
This document is based on and extends the results of UGAS-2020 regarding JSON Schema encoding rules. It defines the conversion behavior in an implementation agnostic way, adhering to the requirements defined in OGC 08-131r3 for writing OGC standards. This document thus represents the next step on the way to standardizing JSON Schema encoding rules in the geospatial domain.
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.
IV. Security Considerations
No security considerations have been made for this document.
V. Submitting Organizations
The following organizations submitted this Document to the Open Geospatial Consortium (OGC):
- Geonovum
- interactive instruments GmbH
Best Practice for OGC - UML to JSON Encoding Rules
1. Scope
This document defines requirements for encoding application schemas in UML, which conform to the UML profile defined by ISO 19103:2015 and potentially also ISO 19109:2015, as JSON schemas. The requirements classes cover the creation of JSON schemas for:
a plain JSON encoding;
a GeoJSON-compliant encoding; and
a JSON encoding compliant to JSON-FG 0.1
Additional requirements classes support encoding choices for unions, code list valued properties, property values given by reference, and entity types.
2. Conformance
This Best Practice defines a number of requirements classes, which specify encoding (elements of) an application schema in UML in JSON (Schema). The standardization target for all these classes are JSON (Schema) documents. Figure 1 provides an overview of the requirements classes, together with their dependencies.
Figure 1 — Requirements classes for encoding an application schema in UML as a JSON Schema
Common encoding behavior is defined in the core requirements class (Clause 7.3). Additional requirements classes exist, which serve different purposes:
Three requirements classes for basic JSON encodings are defined:
a plain encoding (Clause 7.4),
a GeoJSON encoding (Clause 7.6), and
a JSON-FG encoding (Clause 7.7).
There are two requirements classes that represent options for realizing a by-reference encoding of property values, one using URIs (Clause 7.8.3, and one using link objects Clause 7.8.4).
Requirements classes also exist for the two ways in which «union» types are used in practice: as type discriminator (Clause 7.9.2) and as property choice (Clause 7.9.3).
Code list valued properties can be represented in one of three ways, defined by requirements classes: as a literal (Clause 7.10.3), as URI (Clause 7.10.4), and as link object (Clause 7.10.5).
Finally, an additional requirements class supports the encoding of a JSON member for storing the name of the conceptual type that a JSON object encodes (Clause 7.11).
A community can combine these requirements classes as needed to achieve a full JSON Schema encoding, which satisfies their specific JSON encoding requirements. For example, a community might choose a GeoJSON compliant encoding, together with the property choice encoding for unions, as well as using link objects for by-reference encoding and code values.
Table 1 lists all requirements classes defined by this specification.
Table 1 — Requirements classes overview
This document does not define conformance classes. Such classes become relevant if and when this specification moves on in the OGC standardization process, i.e., if the document type changes from Best Practice to Standard. It is expected that the standardization process will involve further review and discussion, and may lead to changes within the specification. Once the specification has reached a stable state during that process, that would be a good time to define conformance classes.
All requirements-classes described in this document are owned by the document(s) identified.
3. Normative references
The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.
T. Bray (ed.): IETF RFC 8259, The JavaScript Object Notation (JSON) Data Interchange Format. RFC Publisher (2017). https://www.rfc-editor.org/info/rfc8259.
H. Butler, M. Daly, A. Doyle, S. Gillies, S. Hagen, T. Schaub: IETF RFC 7946, The GeoJSON Format. RFC Publisher (2016). https://www.rfc-editor.org/info/rfc7946.
K. Zyp: IETF RFC 6901, JavaScript Object Notation (JSON) Pointer. RFC Publisher (2013). https://www.rfc-editor.org/info/rfc6901.
Austin Wright, Henry Andrews, Ben Hutton, Greg Dennis: Internet-Draft draft-bhutton-json-schema-01, JSON Schema: A Media Type for Describing JSON Documents. (2022). https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.txt.
Austin Wright, Henry Andrews, Ben Hutton: Internet-Draft draft-bhutton-json-schema-validation-01, JSON Schema Validation: A Vocabulary for Structural Validation of JSON. (2022). https://www.ietf.org/archive/id/draft-bhutton-json-schema-validation-01.txt.
ISO: ISO 8601-2:2019, Date and time — Representations for information interchange — Part 2: Extensions. International Organization for Standardization, Geneva (2019). https://www.iso.org/standard/70908.html.
ISO: ISO 19103:2015, Geographic information — Conceptual schema language. International Organization for Standardization, Geneva (2015). https://www.iso.org/standard/56734.html.
ISO: ISO 19107:2003, Geographic information — Spatial schema. International Organization for Standardization, Geneva (2003). https://www.iso.org/standard/26012.html.
ISO: ISO 19109:2015, Geographic information — Rules for application schema. International Organization for Standardization, Geneva (2015). https://www.iso.org/standard/59193.html.
ECMA-262, 11th edition specification, June 2020, https://www.ecma-international.org/ecma-262/11.0/index.html
OGC Features and Geometries JSON — Part 1: Core, draft 0.2.2, https://github.com/opengeospatial/ogc-feat-geo-json/releases/tag/v0.2.2
Policy SWG: OGC 08-131r3, The Specification Model — Standard for Modular specifications. Open Geospatial Consortium (2009). https://portal.ogc.org/files/?artifact id=34762&version=2.
4. Terms, definitions and abbreviated terms
This document uses the terms defined in OGC Policy Directive 49, which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this document and OGC documents do not use the equivalent phrases in the ISO/IEC Directives, Part 2.
This document also uses terms defined in the OGC Standard for Modular specifications (OGC 08-131r3), also known as the ‘ModSpec’. The definitions of terms such as standard, specification, requirement, and conformance test are provided in the ModSpec.
For the purposes of this document, the following additional terms and definitions apply.
4.1. Terms and definitions
4.1.1. linked data
Linked data is the data format that supports the Semantic Web. The basic rules for linked data are defined as:
Use Uniform Resource Identifiers (URIs) to identify things;
Use HTTP URIs so that these things can be referred to and looked up (“dereferenced”) by people and user agents;
Provide useful information about the thing when its URI is dereferenced, using standard formats such as RDF/XML; and
Include links to other, related URIs in the exposed data to improve discovery of other related information on the Web.
Source: W3C Semantic Web Wiki
4.1.2. feature type
A feature type as defined by the General Feature Model (see ISO 19109:2015). In an application schema, a feature type is typically modeled using stereotype «FeatureType», or a stereotype that maps to that stereotype.
4.1.3. object type
An object type is an interface or class. An object type is not a feature type. In an application schema, an object type is an interface, or a class with no stereotype, stereotype «Type», or a stereotype that maps to one of the two options.
4.1.4. data type
As defined by ISO 19103:2015, section 6.10, a data type is a class with stereotype «DataType» (or a stereotype that maps to that stereotype), which is a set of properties that lacks identity.
4.1.5. type with identity
A class that is a feature type or an object type.
4.2. Abbreviated terms
API
Application Programming Interface
ECMA
European association for standardizing information and communication systems
GML
Geography Markup Language
HTTP
Hypertext Transfer Protocol
IETF
Internet Engineering Task Force
INSPIRE
Infrastructure for spatial information in Europe
IRI
Internationalized Resource Identifier
ISO
International Organization for Standardization
JSON
JavaScript Object Notation
JSON-FG
OGC Features and Geometries JSON
JSON-LD
JSON for Linked Data
OCL
Object Constraint Language
OGC
Open Geospatial Consortium
OWL
Web Ontology Language
RDF
Resource Description Framework
RDFS
RDF Schema
UGAS
UML to GML Application Schema
UML
Unified Modeling Language
URI
Uniform Resource Identifier
URL
Unform Resource Locator
W3C
World Wide Web Consortium
XML
Extensible Markup Language
5. Conventions
5.1. General
This section provides details and examples for any conventions used in the document. Examples of conventions are symbols, abbreviations, use of XML schema, or special notes regarding how to read the document.
5.2. Identifiers
The normative provisions in this document are denoted by the URI
http://www.opengis.net/spec/uml2json/1.0
All requirements and conformance tests that appear in this document are denoted by partial URIs which are relative to this base.
5.3. JSON Schema URLs
This document uses the following base URLs for relevant JSON Schema files:
GeoJSON: https://geojson.org/schema
UML2JSON (defined by this specification): https://register.geostandaarden.nl/jsonschema/uml2json/0.1
NOTE The JSON-FG schemas have not been published at https://beta.schemas.opengis.net/json-fg yet (as of Dec 12, 2022). The schema definition from this specification — see Annex C — has been published at a temporary location. In both cases, the schema locations are expected to change during the OGC publication process.
5.4. Stereotype Names
Stereotype names within figures are written in lowerCamelCase, whereas stereotype names in the text are written in UpperCamelCase. In a future version of this document, all stereotype names should be written in UpperCamelCase, to follow UML 2 practice.
6. Overview
ISO / TC 211 defines Standards in the field of digital geographic information. A couple of these Standards, especially ISO 19109, are used by the geospatial community to define so called application schemas. An application schema is a conceptual schema for data required by one or more applications. It is typically defined using the Unified Modeling Language (UML).
OGC 07-036r1 defines rules for encoding an application schema in XML. The result is an XML Schema, which defines the structure for encoding application data in XML. Applications would use this XML as a format for interoperable information exchange.
JSON is a prominent format for encoding and exchanging data on the web. JSON Schema can be used to validate syntactical constraints for — i.e., the structure of — a specific JSON format. This document defines a set of requirements classes for encoding an application schema in UML in JSON Schema. The UML profiles defined by ISO 19103:2015 and ISO 19109:2015 are used as the base UML profile in this document.
NOTE The results and findings from OGC 20-012 have been an important foundation for the UML to JSON Schema encoding requirements defined in this specification.
7. UML to JSON Schema Encoding
7.1. Introduction
This chapter defines requirements classes for the encoding of application schemas in UML as JSON Schema, and likewise for the encoding of application data as JSON data.
7.2. UML profile
The stereotypes as well as tagged values that are relevant for JSON Schema encodings are listed in Table 2 and Table 3.
Table 2 — Stereotypes relevant for JSON Schema encodings
Stereotype / keyword | Model element | Description |
---|---|---|
applicationSchema | Package | A conceptual schema for data required by one or more applications. Source: ISO 19109:2015, especially chapter 8.2. |
schema | Package | This stereotype is typically used in abstract schemas defined by ISO TC 211. For further details on abstract schemas, see ISO 19103:2015, chapter 6.2 and figure 4. An abstract schema and an application schema are both conceptual schemas, but they are on different levels of abstraction. The stereotype «Schema» has been introduced for schemas that conform to ISO 19103, but do not follow the rules for application schemas from ISO 19109, but still need a stereotype on the schema package for adding tagged values. |
featureType | Class | A feature type as defined by ISO 19109:2015. |
interface | Interface | An abstract classifier with operations, attributes and associations, which can only inherit from or be inherited by other interfaces. Other classifiers may realize an interface by implementing its operations and supporting its attributes and associations (at least through derivation). Source: ISO 19103:2015 This stereotype is typically used in conceptual schemas from ISO TC 211. It should not be used in application schemas, as these are on a different conceptual level than classifiers with this stereotype. |
dataType | DataType | A set of properties that lack identity (independent existence and the possibility of side effects). A data type is a classifier with no operations, whose primary purpose is to hold information. Source: ISO 19103:2015 |
union | Class | Either used as A structured data type without identity where exactly one of the properties of the type is present in an instance (property choice) or type consisting of one and only one of several alternative datatypes (type discriminator; source: ISO 19103:2015) — in both cases the options are listed as member attributes. |
enumeration | Enumeration | A fixed list of valid identifiers of named literal values. Attributes of an enumerated type may only take values from this list. Source: ISO 19103:2015 |
codeList | Class | A flexible enumeration that uses string values for expressing a list of potential values. Source: ISO 19103:2015 |
property | Property (attribute [not of an enumeration or code list] or association role) | A property of a schema type which is not an enumeration or code list. |
NOTE 1 Communities may use aliases for the stereotypes listed above. NOTE 2 For backwards-compatibility to UML 1 schemas (that comply with earlier versions of ISO 19103:2015), a class with stereotype «Type» can be used instead of an interface. NOTE 3 Some conceptual schemas and application schemas do not make use of the stereotypes «property», but still attach certain tagged values to according properties in their UML model. That approach is supported by some UML modeling tools, even though tagged values typically belong to a certain stereotype. For the purposes of this specification, the stereotype «property» is assumed to be applied in schemas that shall be converted from UML to JSON Schema. Nevertheless, it is allowed for schemas to omit the stereotypes, and just use the associated tagged values (see below) on according model elements. This kind of use implies the presence of an ad-hoc stereotype, which is considered to represent the «property» stereotype. |
Table 3 lists the tagged values relevant for the JSON Schema encodings, together with the stereotype(s) they apply to, as well as relevant requirements class(es).
Table 3 — Tagged values relevant for JSON Schema encodings
Applicable stereotype(s) | Tagged value | Relevant requirements class(es) | Comment |
---|---|---|---|
«applicationSchema» and «schema» | jsonDocument | /req/core | see Clause 7.3.1 |
jsonId | /req/core | ||
«Enumeration» and «CodeList» | literalEncodingType | /req/core and /req/codelists-literal | see Clause 7.3.3.8 and Clause 7.10.3 |
«property» | inlineOrByReference | /req/by-reference-basic | see Clause 7.8.2 |
jsonFormat | /req/core | only relevant for basic types, see Clause 7.3.3.9 | |
jsonPattern | /req/core | ||
maxLength | /req/core | ||
minExclusive | /req/core | ||
minInclusive | /req/core | ||
maxExclusive | /req/core | ||
maxInclusive | /req/core | ||
primaryGeometry | /req/geojson and /req/jsonfg | see Clause 7.6.3 and Clause 7.7.3 | |
primaryInstant | /req/jsonfg | see Clause 7.7.4 | |
primaryInterval | /req/jsonfg | ||
unit | /req/core | see Clause 7.3.3.1 |
7.3. Requirements class: Core
7.3.1. Definitions schema
Schema packages have the stereotype «applicationSchema», «schema», or an alias (e.g., using a specific language, like in German: «anwendungsschema»). An «applicationSchema» package represents an application schema according to ISO 19109. The stereotype «schema» has been introduced for packages that should be treated like application schemas, but do not contain feature types.
Requirement 1 | |
---|---|
Identifier | /req/core/definitions-schema |
Included in | Requirements class 1: /req/core |
A | A UML application schema and its classes shall be converted into a single definitions schema. NOTE 1 A definitions schema is a JSON Schema that uses the “$defs” keyword. |
B | The file name of the definitions schema shall be constructed as follows: If tagged value jsonDocument is set on the application schema package, with a value that is not blank (i.e., purely whitespace characters), then the tag value shall be used as the file name of the definitions schema. Otherwise, the package name shall be used as fallback, replacing all spaces and forward slashes with underscores, and appending ‘.json’. |
C | The “$schema” keyword shall be added to the definitions schema. Its value shall be “https://json-schema.org/draft/2020-12/schema”. |
D | The definitions schema shall have an “$id” member, whose value is the value of tag jsonId, as defined on the application schema package. |
E | The “$defs” keyword shall have a JSON object as value, where each member represents the JSON Schema definition of a class from the application schema. |
NOTE 2 When encoding the content of an application schema in a single definitions schema, it is straightforward to assign the JSON Schema URL whenever such a reference is required for one of the application schema classes. If the content of the application schemas was distributed over multiple definitions schema files, it would be necessary to maintain a mapping for each application schema class, to the URL of the JSON Schema that contains the definition of that class.
NOTE 3 The “$id” identifies the schema resource with its canonical URI. The URI is an identifier and not necessarily a resolvable URL. If the “$id” is a URL, there is no expectation that the JSON Schema can be downloaded at that URL.
NOTE 4 If the value of tag jsonId is a URI with a path to a named file, then the file name given in tag jsonDocument should match the file name in tag jsonId. It is not required to do so, because the JSON Schema file can be re-named during the publication process.
Recommendation 1 | |
---|---|
Identifier | /req/core/id-characteristics |
Included in | Requirements class 1: /req/core |
Statement | It is recommended that the “$id” URI should be stable, persistent, and globally unique. |
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/some-definitions-schema.json", |
4 | "$defs": { |
5 | "Class1": { |
6 | "type": "object", |
7 | "properties": { |
8 | "prop1": {"type": "string"} |
9 | }, |
10 | "required": ["prop1"] |
11 | }, |
12 | "Class2": { |
13 | "type": "object", |
14 | "properties": { |
15 | "prop2": {"type": "number"} |
16 | }, |
17 | "required": ["prop2"] |
18 | } |
19 | } |
20 | } |
Figure 2 — JSON Schema example of a definitions schema
NOTE 5 The “$id” of the definitions schema has been omitted in some examples within this chapter. Declaring an absolute, non-existent URL as “$id” in these examples can prevent the examples from working, when testing them using certain JSON Schema validators, for instance on https://www.jsonschemavalidator.net/.
Requirement 2 | |
---|---|
Identifier | /req/core/schema-references |
Included in | Requirements class 1: /req/core |
Statement | References from types of the application schema to other types — within the same or within an external schema — shall be encoded as references to the according definitions schemas, using the JSON Schema keyword “$ref” — see Figure 3. |
Figure 3 — References between JSON Schemas using $ref with JSON pointers as values
It is up to the encoder to use an absolute or relative URI for a reference to a schema definition within an external JSON Schema file. A reference to a schema definition within the same JSON Schema file should be encoded as a relative URL that consists of a fragment identifier, either using a JSON Pointer (e.g., #/$defs/XYZ) or an anchor (e.g., #XYZ).
A link to a particular definition within a definitions schema requires the use of a JSON Pointer or an anchor in the fragment identifier of the link URL. JSON Pointer, chapter 6, explicitly states that the media type in which a JSON value is provided needs to support this kind of fragment identifier, and that this is not the case for the media type application/json. If a JSON Schema was published with this media type, then it is possible that the application ignores a fragment identifier (because the media type does not support fragment identifiers). If a JSON Schema is published with media type application/schema+json, using anchors and JSON Pointers as fragment identifiers is supported.
The JSON Schema should be published with media type application/schema+json — which is defined by the JSON Schema specification. The media type application/schema+json supports JSON Pointers and plain names as fragment identifiers. For further details, see JSON Schema core, chapter 5.
NOTE 6 The JSON Schema with which to validate a JSON document cannot be identified within that document itself. In other words, JSON Schema does not define a concept like an xsi:schemaLocation, which is typically used in an XML document to reference the applicable XML Schema(s). Instead, JSON Schema uses link headers and media type parameters to tie a JSON Schema to a JSON document (for further details, see JSON Schema core, section 9.5).
Specific formats may encode such links in the JSON data itself. Also see https://ietf-wg-httpapi.github.io/mediatypes/draft-ietf-httpapi-rest-api-mediatypes.html and the “schema” parameter defined there. Some tools (e.g., the oXygen editor) use a “$schema” member in JSON (instance) data to reference the applicable JSON Schema. However, that is a tool-specific approach. In principle, tool-specific approaches are allowed. However, the choice of re-using the “$schema” keyword in that way is problematic, since it does not reflect the intent of “$schema” as defined by JSON Schema core, section 8.1.1. The relationship between a JSON document and the JSON Schema for validation can also be defined explicitly by an application, i.e., in an application specific way.
7.3.2. Documentation
Descriptive information of application schema elements (packages, classes, attributes and association roles) may be encoded via JSON Schema annotations.
NOTE 1 Annotations represent one category of JSON Schema keywords (for further details, see JSON Schema core, section 7). Annotations attach information that applications can use as they see fit. The other categories are assertions, which validate that a JSON instance satsifies constraints, and applicators, which apply subschemas to parts of the instance and combine their results.
The documentation of an application schema element may be encoded using the JSON Schema “description” annotation. Additional annotations, such as “title” and “examples”, may be used as well, where applicable.
NOTE 2 Potential reasons for NOT using JSON Schema annotations are:
Omitting the documentation will result in significantly smaller JSON Schema documents. The reduction of file size is preferable for processes that need to download the schema in order to apply validation. This is even more important if cross-references between JSON Schemas exist.
When validating JSON data against a JSON Schema, a JSON Schema validator typically focuses on the JSON Schema assertions and applicators, and will ignore most JSON Schema annotations — especially meta-data annotations, such as “title” and “description.”
7.3.3. Types
7.3.3.1. External types
Application schemas typically use types from other schemas, for example the types defined by ISO 19103 and ISO 19107. External types can be used as value types of properties, and as supertypes for types defined in the application schema that is being converted.
Whenever an external type is used, its JSON Schema definition is needed. Either an external type is implemented as one of the simple JSON value types (e.g., string — maybe with a certain format or pattern), or it is defined by a particular JSON Schema. In case of a JSON Schema, the URL of that schema needs to be known during the encoding process. If the schema is a definitions schema, then the URL typically needs to be augmented with a fragment identifier that includes a JSON Pointer or an anchor reference within the schema.
Requirement 3 | |
---|---|
Identifier | /req/core/iso19103-primitive-types |
Included in | Requirements class 1: /req/core |
Statement | If a UML property is encoded in JSON Schema, and the value type is one of the ISO 19103 primitive types listed in Table 4, then the simple JSON Schema type as well as the JSON Schema keywords listed in Table 4 shall be used in the JSON Schema definition of the property. |
Table 4 — JSON Schema implementation of ISO 19103 primitive types
UML class | JSON Schema simple type | JSON Schema keywords |
---|---|---|
Boolean | boolean | |
CharacterString | string | |
Date | string | format=date |
DateTime | string | format=date-time |
Decimal | number | |
Integer | integer | |
Number | number | |
Real | number | |
Time | string | format=time |
URI | string | format=uri |
Some JSON Schema validators do not support or ignore the JSON Schema keyword “format”. That can be an issue, especially if a JSON Schema definition represented a choice (e.g., using the JSON Schema keyword “oneOf”) between simple JSON Schema types. In that case, such a validator might complain that the choice cannot be made because both options match the simple type definition. The following recommendation is meant to prevent that issue.
Recommendation 2 | |
---|---|
Identifier | /req/core/format-and-pattern |
Included in | Requirements class 1: /req/core |
Statement | Whenever an external type is implemented by a simple JSON Schema type with specific “format”, it is recommended that the type definition be accompanied by a “pattern” member, whose value should contain a regular expression that is sufficient to represent the intended format. |
A | Table 5 provides a list of regular expressions for a number of types from ISO 19103:2015. If the “pattern” keyword is used, these expressions should be used. However, applications may also use different regular expressions. For example, a community may choose to only allow date time values in Zulu time (i.e., requiring the time zone designator to always be ‘Z’). |
Table 5 — Regular expressions for some ISO 19103 types, to be used in the JSON Schema ‘pattern’ keyword
UML class | Regular expression for use in JSON Schema ‘pattern’ keyword |
---|---|
Date | ^\d{4}-\d{2}-\d{2}$ |
DateTime | ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d)?(Z|((\+|-)\d{2}:\d{2}))$ |
Time | ^\d{2}:\d{2}:\d{2}(\.\d)?(Z|((\+|-)\d{2}:\d{2}))$ |
URI | ^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$ |
Requirement 4 | |
---|---|
Identifier | /req/core/iso19103-measure-types |
Included in | Requirements class 1: /req/core |
Statement | If a UML property is encoded in JSON Schema, and the value type is one of the ISO 19103 measure types (e.g., Measure, Length, Speed, Angle, Area, or Volume), then the JSON Schema definition of the property shall be constructed as follows: |
A | If tagged value unit is defined on the UML property, with a non-blank value, then member “type” with value “number”, and member “unit”, with value being the value of tag unit, shall be encoded in the definition. If the multiplicity upper bound of the UML property is greater than 1, then as defined by /req/core/property-multiplicity, “type”: “number” will be moved into the “items” member; however, the “unit” member shall still be encoded in the definition schema for the UML property, and not in the “items” member. |
B | Otherwise, i.e., tag unit is undefined on the property, member “$ref” shall be added to the definition, with value “https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/Measure” (the JSON Schema for measure is defined in Annex C). |
NOTE 1 Tag unit identifies that the UML property has a fixed unit of measure. Having a fixed unit for a given property is highly beneficial for practical applications, for example when writing queries and filter statements. Note that it is perfectly valid for an application schema to still use a measure type for an attribute with a fixed unit, instead of just type ‘Number’ or ‘Real’. The reason is that the application schema is defined on the conceptual level. From that point of view, a measure typed attribute with a fixed unit still has a measure as value type, not just a number. It is on the implementation level that the simplification of just using a number value for a measure typed property with fixed unit makes sense.
NOTE 2 If ISO TC 211 defines a JSON Schema for ISO 19103 measure types, then that JSON Schema definition can be used.
NOTE 3 If an external type is not covered by the mapping tables defined in this document, then a suitable mapping needs be found on a case by case basis. For example, if CI_Citation from ISO 19115 was used by an application schema, a reference to a suitable JSON Schema definition needs to be identified. Such a schema definition could be created manually, or (semi-) automatically, for example using the encoding behavior defined in this specification.
7.3.3.2. Class name
Requirement 5 | |
---|---|
Identifier | /req/core/class-name |
Included in | Requirements class 1: /req/core |
Statement | The name of a class shall be encoded as value of an “$anchor” member in the schema definition of the class (within the definitions schema). |
NOTE 1 Schema definitions that have an “$anchor” can be referenced using the plain text value of the anchor as fragment identifier, instead of using a more complex JSON Pointer.
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "TypeA": { |
5 | "$anchor": "TypeA", |
6 | "...": "..." |
7 | }, |
8 | "TypeB": { |
9 | "$anchor": "TypeB", |
10 | "...": "..." |
11 | } |
12 | } |
13 | } |
Figure 4 — Example of a JSON Schema with $anchor members
Examples of referring to the schema definition of “TypeA” from a “$ref” member:
within the JSON schema itself:
using the “$anchor” value: “$ref” = “#TypeA”
using a JSON Pointer: “$ref” = “#/$defs/TypeA”
from another JSON Schema:
using the “$anchor” value: “$ref” = “https://example.org/schemas/schema_definitions.json#TypeA”
using JSON Pointer: “$ref” = “https://example.org/schemas/schema_definitions.json#/$defs/TypeA”
NOTE: If the referenced schema is a draft 07 JSON Schema, the JSON Pointer would have to change as follows: https://example.org/schemas/schema_definitions.json#/definitions/TypeA
NOTE 2 Keep in mind that the use of a fragment identifier with anchor or JSON Pointer value in $ref references can depend upon the media type with which the referenced JSON schema is published, as is explained in more detail here.
7.3.3.3. Abstractness
Requirement 6 | |
---|---|
Identifier | /req/core/abstract-types |
Included in | Requirements class 1: /req/core |
Statement | An abstract class shall be encoded like a non-abstract class. |
NOTE JSON Schema does not directly support abstractness.
Encoding an abstract class as a schema definition allows that definition to be referenced from the schema definitions that are created for the subclasses of the abstract class.
7.3.3.4. Inheritance
JSON Schema does not support the concept of inheritance itself. In practice, an inheritance relationship is important in two areas:
when defining the structure of a subtype, which inherits the properties of its supertypes through the generalization relationships to those supertypes, and
when using a supertype as UML property value; in that case, subtypes can be used as property value, too, and validation is typically expected to check a value based upon its actual type — especially if a subtype is used as value.
Generalization can be represented in JSON Schemas. Validation of property values that are subtypes of the defined property value type cannot fully be represented in JSON Schema.
Requirement 7 | |
---|---|
Identifier | /req/core/generalization |
Included in | Requirements class 1: /req/core |
Statement | The generalization relationship of a subtype to its supertype shall be encoded by combining the structural constraints of the subtype and its supertype using the “allOf” JSON Schema keyword in the JSON Schema definition of the subtype. |
Multiple inheritance is supported by adding all supertypes as elements of “allOf.”
Figure 5 — Example of type inheritance
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "TypeA": { |
5 | "properties": { |
6 | "propertyA": { |
7 | "type": "number" |
8 | } |
9 | }, |
10 | "required": [ |
11 | "propertyA" |
12 | ] |
13 | }, |
14 | "TypeB": { |
15 | "allOf": [ |
16 | { |
17 | "$ref": "#/$defs/TypeA" |
18 | }, |
19 | { |
20 | "type": "object", |
21 | "properties": { |
22 | "propertyB": { |
23 | "type": "string" |
24 | } |
25 | }, |
26 | "required": [ |
27 | "propertyB" |
28 | ] |
29 | } |
30 | ] |
31 | } |
32 | }, |
33 | "$ref": "#/$defs/TypeB" |
34 | } |
Figure 6 — JSON Schema example for realizing generalization using "allOf"
This JSON object is valid against the schema:
{
"propertyA": 2,
"propertyB": "x"
}
Figure 7
This JSON object is invalid (because “propertyA” is missing) against the schema:
{
"propertyB": "x"
}
Figure 8
NOTE 1 This also works for an encoding where the properties of a class are nested within a key-value pair (like “properties” for a GeoJSON encoding).
NOTE 2 The case where a property from a supertype is redefined by a property from the subtype is supported. Redefinition in UML requires that the value type of the subtype property is “kind of” the type of the redefined property of the supertype. Therefore, the property value, when encoded in JSON, would satisfy the JSON Schema constraints defined by both the subtype property and the redefined supertype property.
This approach to converting a generalization relationship has the following restrictions.
The JSON Schema keyword “additionalProperties” cannot be set to false in the definitions of both the super- and the subtype.
The approach is only defined for generalization relationships of feature, object, and data types. For unions, enumerations, and code lists, generalization relationships are not defined by ISO 19103:2015.
It only converts the generalization relationship from subtype to supertype. It does not support the other direction of an inheritance relationship, i.e., specialization. Given a JSON object that encodes a subtype, and the JSON Schema of the supertype, then by validating the JSON object against that JSON Schema, only the constraints of the supertype are checked, but not all the constraints that apply to the subtype. That is an issue when encoding a UML property whose value type is or could be a supertype (via a subtype that is added by an external, so far unknown schema). Conceptually, the actual value of that property can be a supertype object, but it could just as well be an object whose type is a subtype of that supertype. This issue can only be solved to a certain degree with JSON Schema, as explained in OGC 20-012, section Class Specialization and Property Ranges.
7.3.3.5. Common base schema
It is often useful to encode all classes that have a certain stereotype with a common base type. The generalization relationship to such a base type is often implied with the stereotype, for a given encoding. In GML, for example, the common base type for classes with stereotype «FeatureType» is gml:AbstractFeature. Rather than explicitly modeling such a base type (e.g., AnyFeature defined by ISO 19109), as well as explicitly modeling generalization relationships to the base type, the encoding rule typically takes care of adding that relationship to relevant schema types. Requirements class /req/core does not declare specific common base types. That is left to other requirements classes.
7.3.3.6. Feature and object type
In the conceptual model, feature and object types represent objects that have identity. That differentiates these types from, for example, data types. Other than that, feature and object types — in the following summarily called types with identity — are encoded as JSON objects, just like a data type.
Requirement 8 | |
---|---|
Identifier | /req/core/feature-and-object-types |
Included in | Requirements class 1: /req/core |
Statement | The feature and object types of an application schema shall be converted to JSON Schema definitions of JSON objects. These definitions shall be added to the definitions schema, using the type name as definition key. |
NOTE ISO 19109 requires class names to be unique within the scope of an application schema.
The conversion of the class properties is defined in Clause 7.3.4. General type conversion rules, such as those documented in Clause 7.3.3.2, may apply.
The conceptual model of a type with identity often does not contain an identifier property (a UML property whose value for field “isId” is set to true), whose value is used by applications to identify objects of that type. Instead, the according information is added or defined in platform specific encodings. For example, a GML application schema offers the gml:id attribute as well as the gml:identifier element to encode identifying information. In a web publishing context, the URI at which a JSON object is published can be used as its identifier. Requirements class /req/core does not declare any specific mechanism for adding an identifier property. That could be achieved through the definition of a common base schema (see Clause 7.3.3.5). However, requirements regarding such a base schema are left to other requirements classes. Likewise, this requirements class does not define any requirements regarding the number and characteristics of identifier properties. Again, that is left to other requirements classes.
7.3.3.7. Data type
Requirement 9 | |
---|---|
Identifier | /req/core/data-types |
Included in | Requirements class 1: /req/core |
Statement | A «DataType» shall be converted to a JSON Schema definition of a JSON object. That definition shall be added to the definitions schema, using the type name as definition key. |
7.3.3.8. Enumeration
Requirement 10 | |
---|---|
Identifier | /req/core/enumerations |
Included in | Requirements class 1: /req/core |
A | An «Enumeration» shall be converted to a JSON Schema definition with a type defined by evaluating tagged value literalEncodingType on the enumeration. The tagged value literalEncodingType identifies the conceptual type that applies to the enumeration values. If the tagged value is not set on the enumeration, or has an empty value, then the literal encoding type is defined to be CharacterString. |
B | The JSON Schema definition shall use the “enum” keyword to restrict the value to one of the enums from the enumeration. The “enum” value shall be an array with one element per enum defined by the enumeration. For each enum, the array element shall be the initial value of the enum, if defined, otherwise it shall be the name of the enum. |
The literal encoding type is one of the types from ISO 19103, which are implemented as a simple JSON Schema type — see Table 6.
Table 6 — Literal encoding type
Conceptual type from ISO 19103 | simple JSON Schema type |
---|---|
CharacterString | string |
Real, Number | number |
Integer | integer |
Figure 9 — «Enumeration» example
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Enumeration1": { |
5 | "type": "number", |
6 | "enum": [-5, 0, 5.5] |
7 | }, |
8 | "Enumeration2": { |
9 | "type": "string", |
10 | "enum": ["A","B","C"] |
11 | } |
12 | } |
13 | } |
Figure 10 — Example of enumerations encoded in JSON Schema
7.3.3.9. Basic Type
If a direct or indirect supertype of an application schema class is represented in JSON Schema by one of the simple JSON Schema types string, number, integer, or boolean, then that class represents a so called basic type. A basic type does not define a JSON object. It represents a simple data value, e.g., a string. The JSON Schema definition of a basic type thus defines a simple JSON Schema type.
Requirement 11 | |
---|---|
Identifier | /req/core/basic-types |
Included in | Requirements class 1: /req/core |
A | If the direct supertype of a basic type is implemented as one of the simple JSON Schema types, then the JSON Schema definition of the basic type shall have a “type” member with that simple JSON Schema type as value, and potentially additional JSON Schema keywords — especially “format” — which may be defined for the JSON Schema implementation of the supertype (for further details, see Clause 7.3.3.1). Otherwise, the JSON Schema definition of the basic type shall reference the JSON Schema definition of its supertype using the “$ref” member. NOTE If an official JSON Schema was published for the types defined in ISO 19103:2015, then the definitions of that schema could be referenced, instead of creating a “type” member. |
B | For each tag listed in Table 7, add the corresponding JSON Schema keyword (as defined in the table) to the JSON Schema definition of the basic type, with the tag value as value, if all of the following conditions are met:
|
C | If one or more JSON Schema keywords listed in Table 7 are added to the JSON Schema definition of the basic type, and that definition does not declare a “type” member — i.e., it references the JSON Schema definition of its supertype via “$ref” — then an “allOf” keyword shall be used to combine the referenced schema definition and the list of additional JSON Schema keywords. |
Table 7 — Basic type restrictions
tagged value (to define a restriction) | JSON Schema keyword | applicable JSON Schema type(s) |
---|---|---|
jsonFormat | format | string, number, integer |
maxLength | maxLength | string |
minLength | minLength | string |
jsonPattern | pattern | string |
minInclusive | minimum | number, integer |
minExclusive | exclusiveMinimum | number, integer |
maxInclusive | maximum | number, integer |
maxExclusive | exclusiveMaximum | number, integer |
NOTE 1 The JSON Schema keyword “format” is defined in chapter 7 of JSON Schema Validation: A Vocabulary for Structural Validation of JSON. The formats defined there (e.g., “date-time”, “uri”, and “json-pointer”) apply to JSON values of type string. Custom formats could apply to JSON values of type number and integer. NOTE 2 JSON Schema Validation: A Vocabulary for Structural Validation of JSON defines the JSON Schema keyword “pattern”. According to that specification, the value of the keyword should be a regular expression according to the ECMA-262 regular expression dialect. JSON Schema: A Media Type for Describing JSON Documents defines a number of recommendations for writing regular expressions in JSON Schema. NOTE 3 If the “format” keyword is used to restrict the structure of a JSON string, so that it matches a certain regular expression, then it is useful to add the “pattern” keyword as well, explicitly defining that regular expression (given that the regular expression follows an ECMA-262 regular expression dialect). The reason is that the “format” is first and foremost an annotation, so can be ignored by JSON Schema validators, whereas the “pattern” keyword will be evaluated by a JSON Schema validator. JSON Schema validators may treat the “format” keyword like an assertion, but that is not guaranteed. In any case, the “format” keyword helps to convey more information about the specific type of a JSON value (e.g., “date” instead of just “string”), and thus should not be omitted if a certain, well-known (i.e., defined by a JSON Schema vocabulary) format is applicable to a JSON value. |
Figure 11 provides a detailed example that illustrates a number of cases. The JSON Schema encoding is shown in Figure 12.
Figure 11 — Basic types example
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "EmailAddress": { |
5 | "allOf": [ |
6 | { |
7 | "$ref": "#/$defs/MyCharacterString" |
8 | }, |
9 | { |
10 | "format": "email" |
11 | } |
12 | ] |
13 | }, |
14 | "MyCharacterString": { |
15 | "type": "string" |
16 | }, |
17 | "MyNumber": { |
18 | "type": "number" |
19 | }, |
20 | "Number0to360": { |
21 | "allOf": [ |
22 | { |
23 | "$ref": "#/$defs/NumberNonNegative" |
24 | }, |
25 | { |
26 | "maximum": 360.0 |
27 | } |
28 | ] |
29 | }, |
30 | "NumberMinus180toPlus180": { |
31 | "allOf": [ |
32 | { |
33 | "$ref": "#/$defs/MyNumber" |
34 | }, |
35 | { |
36 | "minimum": -180.0, |
37 | "maximum": 180.0 |
38 | } |
39 | ] |
40 | }, |
41 | "NumberNonNegative": { |
42 | "allOf": [ |
43 | { |
44 | "$ref": "#/$defs/NumberOther" |
45 | }, |
46 | { |
47 | "minimum": 0.0 |
48 | } |
49 | ] |
50 | }, |
51 | "NumberOther": { |
52 | "$ref": "#/$defs/MyNumber" |
53 | }, |
54 | "String10": { |
55 | "allOf": [ |
56 | { |
57 | "type": "string" |
58 | }, |
59 | { |
60 | "maxLength": 10 |
61 | } |
62 | ] |
63 | }, |
64 | "StringPattern": { |
65 | "allOf": [ |
66 | { |
67 | "$ref": "#/$defs/MyCharacterString" |
68 | }, |
69 | { |
70 | "pattern": "^[abc]{3}$" |
71 | } |
72 | ] |
73 | } |
74 | } |
75 | } |
Figure 12 — Example of basic types encoded in JSON Schema
7.3.4. Properties
7.3.4.1. General
Requirement 12 | |
---|---|
Identifier | /req/core/properties |
Included in | Requirements class 1: /req/core |
Statement | A UML property shall be converted to a member of a JSON object — unless the encoding rule defines a different behavior for the type that owns the property (e.g., for enumerations, unions, and code lists). |
NOTE By default, UML properties are converted to keys within the “properties” member of the JSON Schema definition for the type that owns the property. Additional requirements may override this encoding (e.g., the type discriminator encoding of «union» properties), or augment the encoding (e.g., encoding the properties under the “properties” member of a GeoJSON-based feature).
The default result of converting a UML property, therefore, is a key within the “properties” key of the JSON Schema definition for the type that owns the property, with the key name being the name of the UML property, and the value being a JSON Schema with constraints and annotations that define the property (value type, multiplicity, etc).
The following figure and listing provide an example: Figure 13 shows a feature type with a number of properties. Figure 14 illustrates how the UML properties are represented within the “properties” of the JSON Schema that defines that type.
Figure 13 — UML type used to exemplify JSON Schema encoding of UML properties
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "TypeX": { |
5 | "type": "object", |
6 | "properties": { |
7 | "property1": {"type": "string"}, |
8 | "property2": {"type": "number"} |
9 | }, |
10 | "required": [ |
11 | "property1", "property2" |
12 | ] |
13 | } |
14 | } |
15 | } |
Figure 14 — Encoding UML properties in JSON Schema
7.3.4.2. Value Type
Requirement 13 | |
---|---|
Identifier | /req/core/property-inline |
Included in | Requirements class 1: /req/core |
Statement | The value type of a UML property shall be encoded as a JSON Schema constraint, as follows: |
A | If the value type of a UML property is an external type, and the JSON Schema definition of that external type is a simple JSON value type, i.e., “string”, “number”, “integer”, or “boolean”, then a “type” key shall be added to the JSON Schema definition of the property, with the simple JSON value type as value; |
B | Otherwise, a “$ref” key shall be added to the JSON Schema that constrains the property. The “$ref” value shall be a reference to the JSON Schema definition of the value type, within a particular definitions schema. The reference can be absolute or relative, and typically contains a fragment identifier to identify the definition of the value type. |
Examples:
using the “$anchor” value “TypeX” as fragment identifier: https://example.org/schemas/schema_definitions.json#TypeX
using JSON Pointer as fragment identifier: https://example.org/schemas/schema_definitions.json#/$defs/TypeX
NOTE: If the referenced schema is a draft 07 JSON Schema, the JSON Pointer would have to change as follows: https://example.org/schemas/schema_definitions.json#/definitions/TypeX
NOTE Keep in mind that the use of a fragment identifier with anchor or JSON Pointer value in $ref references can depend upon the media type with which the referenced JSON schema is published, as is explained in more detail here.
The behavior described in /req/core/property-inline covers the case of an inline encoding of the property value. That is sufficient for simple application schemas. For more complex schemas, typically ones that contain associations between feature types, it can be necessary or desired to encode property values by-reference, i.e., using links. However, multiple options exist for realizing a by-reference encoding. These options are defined in separate requirements classes — see Clause 7.8. A particular JSON Schema encoding of a given application schema needs to choose one of these options, in order to enable by-reference encoding for relevant properties.
Figure 15 — Examples of classes from two application schemas with properties that are implemented as simple JSON Schema types and as schema references
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/schema/schemaA.json", |
4 | "$defs": { |
5 | "Class1": { |
6 | "$anchor": "Class1", |
7 | "type": "object", |
8 | "properties": { |
9 | "attBoolean": { |
10 | "type": "boolean" |
11 | }, |
12 | "role2_1": { |
13 | "$ref": "#/$defs/Class2" |
14 | } |
15 | } |
16 | }, |
17 | "Class2": { |
18 | "$anchor": "Class2", |
19 | "type": "object", |
20 | "properties": { |
21 | "attInteger": { |
22 | "type": "integer" |
23 | } |
24 | } |
25 | } |
26 | } |
27 | } |
Figure 16 — Example schema A, encoded as JSON Schema
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/schema/schemaB.json", |
4 | "$defs": { |
5 | "Class3": { |
6 | "$anchor": "Class3", |
7 | "type": "object", |
8 | "properties": { |
9 | "role1_3": { |
10 | "$ref": "schemaA.json#/$defs/Class1" |
11 | }, |
12 | "attCharacterString": { |
13 | "type": "string" |
14 | } |
15 | } |
16 | } |
17 | } |
18 | } |
Figure 17 — Example schema B, encoded as JSON Schema
This JSON object is valid against the definition of “Class1” from Figure 16:
{
"attBoolean": true,
"role2_1": {
"attInteger": 2
}
}
Figure 18
This JSON object is invalid (because “attInteger” has a string value, where an integer value is expected) against the schema from Figure 16:
{
"attBoolean": true,
"role2_1": {
"attInteger": "X"
}
}
Figure 19
7.3.4.3. Multiplicity
Requirement 14 | |
---|---|
Identifier | /req/core/property-multiplicity |
Included in | Requirements class 1: /req/core |
A | If the multiplicity lower bound of a UML property is 1 or greater, and the class that owns the property is not a «union», then the property shall be listed under the “required” properties of the JSON object to which the property belongs. |
B | In addition, if the multiplicity upper bound of the property is greater than 1, then the JSON Schema definition for the property shall be created as follows.
|
Figure 20 — UML type used to exemplify JSON Schema encoding of multiplicity
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Type": { |
5 | "type": "object", |
6 | "properties": { |
7 | "property": { |
8 | "type": "array", |
9 | "minItems": 1, |
10 | "maxItems": 2, |
11 | "items": { |
12 | "type": "string" |
13 | }, |
14 | "uniqueItems": true |
15 | } |
16 | }, |
17 | "required": [ |
18 | "property" |
19 | ] |
20 | } |
21 | }, |
22 | "$ref": "#/$defs/Type" |
23 | } |
Figure 21 — Example for encoding multiplicity in JSON Schema
This JSON object is valid against the schema from Figure 21:
{
"property": ["a","b"]
}
Figure 22
This JSON object is invalid (because “property” has three values, which exceeds the maximum amount of allowed values) against the schema from Figure 21:
{
"property": ["a","b","c"]
}
Figure 23
NOTE All arrays in JSON are ordered, thus that the values of a UML property are ordered is always represented, and that the values of such a property are unordered cannot be represented. However, the latter should not matter to an application that does not expect ordered values for a certain property.
7.3.4.4. Fixed / readOnly
Requirement 15 | |
---|---|
Identifier | /req/core/property-fixed-readonly |
Included in | Requirements class 1: /req/core |
Statement | The JSON Schema definition of a UML property that is marked as read only or fixed shall include the “readOnly” annotation with JSON value true. |
Figure 24 — UML type used to exemplify JSON Schema encoding of a readOnly property
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "FeatureType1": { |
5 | "$anchor": "FeatureType1", |
6 | "type": "object", |
7 | "properties": { |
8 | "attribute": { |
9 | "type": "string", |
10 | "readOnly": true |
11 | } |
12 | } |
13 | } |
14 | } |
15 | } |
Figure 25 — Example for encoding a readOnly property in JSON Schema
7.3.4.5. Derived
Requirement 16 | |
---|---|
Identifier | /req/core/property-derived |
Included in | Requirements class 1: /req/core |
Statement | The JSON Schema definition of a UML property that is marked as derived shall include the “readOnly” annotation with JSON value true. |
Figure 26 — UML type used to exemplify JSON Schema encoding of a derived property
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "FeatureType2": { |
5 | "$anchor": "FeatureType2", |
6 | "type": "object", |
7 | "properties": { |
8 | "attribute": { |
9 | "type": "string", |
10 | "readOnly": true |
11 | } |
12 | } |
13 | } |
14 | } |
15 | } |
Figure 27 — Example for encoding a derived property in JSON Schema
7.3.4.6. Initial Value
Requirement 17 | |
---|---|
Identifier | /req/core/property-initial-value |
Included in | Requirements class 1: /req/core |
Statement | A UML attribute that has an initial value, is owned by a type with identity or a «DataType», and whose value type is encoded as one of the simple JSON Schema types “string”, “number”, “integer”, or “boolean”, shall be encoded as follows: |
A | The JSON Schema definition of the UML attribute shall include the “default” annotation with the initial value as value. |
B | The value of the annotation can have any JSON value type. The initial value shall be encoded accordingly:
|
NOTE Theoretically, the default value can also be a JSON array or object, but that cannot be represented in UML and thus is not a relevant use case.
Figure 28 — UML type used to exemplify JSON Schema encoding of properties with initial value
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "DataType": { |
5 | "$anchor": "DataType", |
6 | "type": "object", |
7 | "properties": { |
8 | "attInteger": { |
9 | "type": "integer", |
10 | "default": 1 |
11 | }, |
12 | "attNumber": { |
13 | "type": "number", |
14 | "default": 2.2 |
15 | } |
16 | } |
17 | }, |
18 | "FeatureType3": { |
19 | "$anchor": "FeatureType3", |
20 | "type": "object", |
21 | "properties": { |
22 | "attBoolean": { |
23 | "type": "boolean", |
24 | "default": true |
25 | }, |
26 | "attCharacterString": { |
27 | "type": "string", |
28 | "default": "xyz" |
29 | } |
30 | } |
31 | } |
32 | } |
33 | } |
Figure 29 — Example for encoding properties with initial value in JSON Schema
7.3.5. Association class
Standard UML supports the concept of association class, i.e., an association that has properties. There is no native represention for association classes in JSON or JSON Schema. Association classes therefore need to be converted to “intermediate” classes, before being serialized to JSON Schema. The conversion is illustrated in the following figures, with Figure 30 showing the original conceptual model, and Figure 31 showing the conversion result.
Figure 30 — Model with association classes
Figure 31 — Association classes transformed to intermediate classes
Requirement 18 | |
---|---|
Identifier | /req/core/association-class |
Included in | Requirements class 1: /req/core |
Statement | Before applying the conversion to JSON Schema, a UML association class that is a type with identity shall be transformed as follows (in the following description the source class of the association is called S and the target class is called T):
|
7.3.6. Constraints
OCL constraints can be used to enrich a conceptual model with requirements that cannot be expressed in UML alone. However, this specification does not define any requirements for converting OCL constraints to JSON Schema definitions, or to any other format with which the constraints can be checked on a JSON dataset.
7.3.7. Conceptual model transformations
The conceptual schema may need to be transformed, in order to deal with model elements:
that cannot be represented in a certain JSON format (e.g., a Solid — a 3D geometry type — as value for the “geometry” member of a GeoJSON feature); or
that are not (well) supported by client software (e.g., complex attribute values for styling, processing, and filtering).
No specific model transformation requirements and recommendations are defined in this document. Examples of model transformations are given in OGC 20-012 and in the GitHub repository with model transformation rules by the INSPIRE community.
7.3.8. Primary geometry
OGC 23-058r1 defines the concept of primary geometry:
primary geometry
the geometry that the publisher considers as the most important spatial characteristic of a feature
NOTE 1 A feature can be described by multiple spatial properties. For example, a radio tower can have a property with a point value that describes the location of the tower and another property with a multi-polygon value that describes the area of coverage. Some feature formats can represent only a single geometry per feature. In those cases, the primary geometry will be used when the feature is encoded in such a format.
NOTE 2 The primary geometry of a feature can also vary depending on the zoom level. At a smaller scale, the primary geometry could be a point while a polygon could be used at a larger scale.
— OGC API — Features — Part 5: Schemas, OGC 23-058r1, Section 4.1
The concept is generally applicable to feature types. Examples of data formats to which the concept applies are GeoJSON and JSON-FG. Requirements regarding the encoding of the primary geometry are defined in the according requirements classes (/req/geojson and /req/jsonfg).
In order to identify the UML property that represents the primary geometry of a feature type, the following approach is used in this specification:
If a single (direct or inherited, but ignoring redefined) UML property of the feature type has tag “primaryGeometry” with value equal to and ignoring case “true”, then that property is the primary geometry of the feature type.
Otherwise, if the set of (direct and inherited, but ignoring redefined) UML properties of the feature type only contains a single UML property with a geometric type, and that property is directly owned by the feature type, and that property does not have tag “primaryGeometry” with value equal to, ignoring case, “false”, then that property is the primary geometry of the feature type.
Otherwise, no primary geometry is defined for the feature type.
NOTE 3 A feature type that has multiple UML properties with tag “primaryGeometry” = true is not modeled correctly.
NOTE 4 Setting tagged value “primaryGeometry” = false can be useful in cases of geometric properties of classes that are (expected to be) subtyped, with the subtypes defining their own primary geometry properties. If the supertype had a geometric property without such a tagged value, the second part of the rule (for determining the primary geometry) would apply, thereby incorrectly identifying the supertype property as primary geometry. That can lead to undesired JSON Schema constraints.
7.3.9. Primary temporal information
OGC 23-058r1 defines the concept of primary temporal information:
primary temporal information
the time instant or time interval that the publisher considers as the most important temporal characteristic of a feature
NOTE 1 A feature can be described by multiple temporal properties. For example, an event can have a property with an instant or interval when the event occurred or will occur and another property when the event was recorded in the dataset. The primary temporal information can also be built from two properties, e.g., when the feature has two properties describing the start and end instants of an interval.
— OGC API — Features — Part 5: Schemas, OGC 23-058r1, Section 4.1
The concept is generally applicable to feature types. An example of a data format to which the concept applies is JSON-FG. Requirements regarding the encoding of primary temporal information are defined in the according requirements class (/req/jsonfg).
In order to identify the UML property that represents the primary geometry of a feature type, the following approach is used in this specification:
A UML property that is owned by the feature type and that has tag “primaryInstant” with value equal to and ignoring case “true” is the primary-instant of the feature type.
A UML property that is owned by the feature type and that has tag “primaryInterval” with value equal to and ignoring case:
“interval” is the primary-interval of the feature type.
“start” is the primary-interval-start of the feature type.
“end” is the primary-interval-end of the feature type.
NOTE 2 The value types of UML properties that represent or contribute to the primary interval should be compatible with that use. For example, properties marked as primary-interval-start or primary-interval-end can have value type “Date”, “DateTime”, or “TM_Instant”, whereas a property marked as primary-interval can have value type “TM_Period”.
NOTE 3 A feature type that does not satisfy the following conditions is not modeled correctly:
At most one of the (direct or inherited, but ignoring redefined) properties has tag “primaryInterval” = “interval”.
At most one of the (direct or inherited, but ignoring redefined) properties has tag “primaryInterval” = “start”.
At most one of the (direct or inherited, but ignoring redefined) properties has tag “primaryInterval” = “end”.
The use of “interval” and “start”/”end” are mutually exclusive within the (direct or inherited, but ignoring redefined) properties of the feature type:
If one property has tag “primaryInterval” = “interval”, then no other property has tag “primaryInterval” equal to “start” or “end”.
Likewise, if one property has tag “primaryInterval” equal to “start” or “end”, then no other property has tag “primaryInterval” = “interval”.
7.4. Requirements class: Encoding rule for a plain JSON Schema format
Requirements class 2 | |
---|---|
Identifier | /req/plain |
Target type | JSON (Schema) documents |
Prerequisites | Requirements class 1: /req/core IETF RFC 7946 |
Normative statement | Recommendation 3: /req/plain/iso19107-types |
NOTE An example of an application schema encoded in plain JSON Schema format is given in Annex B.2.
7.4.1. Common base schema
As described in the core requirements class, common base types or — for the purposes of this encoding rule — common JSON Schema definitions can be added to the schema definition of certain kinds of classes, for example, all feature types. This requirements class does not specify any such common JSON Schema definitions. As a consequence, if the types with identity defined by an application schema do not contain attributes that convey the identity of an actual object, according JSON objects cannot be identified using information from property values. Additional requirements classes, which depend on /req/plain, may add requirements regarding a common base.
7.4.2. Implementation of ISO 19107 types
Recommendation 3 | |
---|---|
Identifier | /req/plain/iso19107-types |
Included in | Requirements class 2: /req/plain |
Statement | If a UML property is encoded in JSON Schema, and the value type is one of the ISO 19107 geometry types listed in the first column of Table 8, then it is recommended that the JSON schema definition in the second column of that table be used in the JSON Schema definition of the property. |
Table 8 — JSON Schema implementation of types defined by ISO 19107 for the plain JSON Schema encoding rule
UML class | JSON Schema reference |
---|---|
GM_Point | https://geojson.org/schema/Point.json |
GM_Curve | https://geojson.org/schema/LineString.json |
GM_Surface | https://geojson.org/schema/Polygon.json |
GM_MultiPoint | https://geojson.org/schema/MultiPoint.json |
GM_MultiCurve | https://geojson.org/schema/MultiLineString.json |
GM_MultiSurface | https://geojson.org/schema/MultiPolygon.json |
GM_Aggregate | https://geojson.org/schema/GeometryCollection.json |
GM_Object | https://geojson.org/schema/Geometry.json |
NOTE 1 Table 8 uses geometry types defined by ISO 19107:2003. While this specification does not define mapping tables for newer versions of ISO 19107, application schemas may use geometry types from a newer version of ISO 19107. The mappings would then need to be adjusted accordingly (finding correct replacements for the types mentioned in the first column of the table). NOTE 2 For geometry typed properties whose value type is not covered in Table 8, a suitable mapping needs to be defined, as explained in Clause 7.3.3.1. NOTE 3 Other geometry encodings are allowed for the plain JSON Schema format, for example a WKT string or a JSON-FG geometry. Such geometry encodings may be useful in application scenarios where tools do not (only) support GeoJSON. |
7.4.3. Identifier property
This requirements class does not define a means to add an identifier property — i.e., a UML property that is modeled with “isId” = true — to the JSON Schema encoding of a feature type, if that type does not declare such a property. The application schema would need to be transformed, in order to add an identifier property, where necessary.
7.5. Requirements class: GeoJSON Formats
Requirements class 3 | |
---|---|
Identifier | /req/geojson-formats |
Target type | JSON (Schema) documents |
Prerequisites | Requirements class 1: /req/core IETF RFC 7946 |
Normative statements | Requirement 19: /req/geojson-formats/identifier Requirement 20: /req/geojson-formats/nesting-feature-type-properties |
7.5.1. Identifier property
Requirement 19 | |
---|---|
Identifier | /req/geojson-formats/identifier |
Included in | Requirements class 3: /req/geojson-formats |
Statement | If at least one UML property of a feature type is modeled with “isId” = true, then the top-level “id” member of GeoJSON features that encode instances of the feature type shall have a value. |
NOTE 1 A UML property of a feature type which is modeled with “isId” = true, is mapped to the “id” member of a GeoJSON feature. The mapping algorithm is community-specific. If a feature type has multiple UML properties where “isId” = true, or if the value type of such a property is not a simple type, some community specific conversion mechanism needs to be defined, for mapping the identifier value(s) to a simple string or number, which can be used as value of the “id” member of a GeoJSON feature.
NOTE 2 The UML properties with “isId” = true are encoded as any other property, in addition to being mapped to the top-level “id” member. That is especially useful in case multiple such properties exist in a feature type, because applications that know the conceptual schema can read these dedicated properties directly, in order to gather information about the ID of a given feature, rather than having to decode the “id” member.
7.5.2. Nesting feature type properties
Requirement 20 | |
---|---|
Identifier | /req/geojson-formats/nesting-feature-type-properties |
Included in | Requirements class 3: /req/geojson-formats |
Statement | Properties of a feature type shall be encoded within the GeoJSON “properties” member, i.e., within a nested “properties” member. |
NOTE 1 Additional requirements can override this behavior, by omitting certain UML properties or by mapping certain UML properties to first-level members of the resulting JSON object. An example is the identifier property.
NOTE 2 Properties of object types are encoded as first-level properties of the resulting JSON object. If object types should be encoded as feature types, then the object types would need to be transformed accordingly, before a JSON Schema encoding is created.
7.6. Requirements class: Encoding rule for a GeoJSON compliant JSON Schema format
Requirements class 4 | |
---|---|
Identifier | /req/geojson |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 3: /req/geojson-formats |
Normative statements | Requirement 21: /req/geojson/common-base Requirement 22: /req/geojson/iso19107-types-for-geometry-member Requirement 23: /req/geojson/primary-geometry |
NOTE An example of an application schema encoded in GeoJSON compliant JSON Schema format is given in Annex B.3.
7.6.1. Common base schema
As described in the core requirements class, common base types or — for the purposes of this encoding rule — common JSON Schema definitions can be added to the schema definition of certain kinds of classes, for example, all feature types.
Requirement 21 | |
---|---|
Identifier | /req/geojson/common-base |
Included in | Requirements class 4: /req/geojson |
Statement | All feature types shall use the GeoJSON Feature definition — https://geojson.org/schema/Feature.json — as common base. |
A | The relationship to the GeoJSON Feature definition schema shall be implemented by converting a feature type to a JSON Schema that consists of an “allOf” with two subschemas: the first being a “$ref” with value “https://geojson.org/schema/Feature.json”, the second being the schema produced by applying the other conversion rules to the feature type. However, if one of the supertypes of the feature type already has the GeoJSON Feature definition in its JSON Schema definition, then the JSON Schema definition of the feature type itself shall not define it again. |
B | If the feature type is encoded with an “allOf” for the GeoJSON Feature definition, then the “$anchor” member (see Clause 7.3.3.2) shall be encoded in the schema that contains the “allOf”, instead of within the second subschema. |
NOTE No common base schema is defined for object types. Such types need to be transformed to feature types if they should be encoded as GeoJSON features.
Figure 32 illustrates a feature type hierarchy, and Figure 33 shows how these feature types are encoded in JSON Schema using the common base schema. Note that the definitions of the individual feature types still state “type”: “object” in order to illustrate the place where object properties would be defined. However, such properties have been omitted in the example to avoid unnecessary complexity.
Figure 32 — Example of a feature type hierarchy in an application schema
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/schema/infra.json", |
4 | "$defs": { |
5 | "Building": { |
6 | "$anchor": "Building", |
7 | "allOf": [ |
8 | { |
9 | "$ref": "#/$defs/Building_Core" |
10 | }, |
11 | { |
12 | "type": "object" |
13 | } |
14 | ] |
15 | }, |
16 | "BuildingPart": { |
17 | "$anchor": "BuildingPart", |
18 | "allOf": [ |
19 | { |
20 | "$ref": "#/$defs/Building_Core" |
21 | }, |
22 | { |
23 | "type": "object" |
24 | } |
25 | ] |
26 | }, |
27 | "Building_Core": { |
28 | "$anchor": "Building_Core", |
29 | "allOf": [ |
30 | { |
31 | "$ref": "https://geojson.org/schema/Feature.json" |
32 | }, |
33 | { |
34 | "type": "object" |
35 | } |
36 | ] |
37 | }, |
38 | "Parcel": { |
39 | "$anchor": "Parcel", |
40 | "allOf": [ |
41 | { |
42 | "$ref": "https://geojson.org/schema/Feature.json" |
43 | }, |
44 | { |
45 | "type": "object" |
46 | } |
47 | ] |
48 | } |
49 | } |
50 | } |
Figure 33 — Example for encoding the common base schema for feature types
7.6.2. Implementation of ISO 19107 types for the “geometry” member
Requirement 22 | |
---|---|
Identifier | /req/geojson/iso19107-types-for-geometry-member |
Included in | Requirements class 4: /req/geojson |
Statement | If a UML property is encoded in JSON Schema, in the “geometry” top-level member of a JSON object that represents a type width identity, and the value type is one of the ISO 19107 geometry types listed in the first column of Table 9, then the JSON schema definition in the second column of that table shall be used in the JSON Schema definition of the property. |
Table 9 — JSON Schema implementation of types defined by ISO 19107, for the “geometry” member in the GeoJSON encoding rule
UML class | JSON Schema reference |
---|---|
GM_Point | https://geojson.org/schema/Point.json |
GM_Curve | https://geojson.org/schema/LineString.json |
GM_Surface | https://geojson.org/schema/Polygon.json |
GM_MultiPoint | https://geojson.org/schema/MultiPoint.json |
GM_MultiCurve | https://geojson.org/schema/MultiLineString.json |
GM_MultiSurface | https://geojson.org/schema/MultiPolygon.json |
GM_Aggregate | https://geojson.org/schema/GeometryCollection.json |
GM_Object | https://geojson.org/schema/Geometry.json |
NOTE 1 Table 9 uses geometry types defined by ISO 19107:2003. While this specification does not define mapping tables for newer versions of ISO 19107, application schemas may use geometry types from a newer version of ISO 19107. The mappings would then need to be adjusted accordingly (finding correct replacements for the types mentioned in the first column of the table). NOTE 2 For geometry typed properties that are not mapped to the “geometry” top-level member, a suitable mapping needs to be defined, as explained in Clause 7.3.3.1. |
7.6.3. Primary geometry
Requirement 23 | |
---|---|
Identifier | /req/geojson/primary-geometry |
Included in | Requirements class 4: /req/geojson |
A | If a feature type has a primary geometry property (identified following the rules in Clause 7.3.8), and that property is directly owned by the feature type, and the JSON Schema implementation of the property type is one of the GeoJSON geometry schemas (i.e., one of the JSON Schema references listed in Table 9), then:
|
NOTE UML properties of other kinds of classes — object types, data types, and unions — are not considered by this requirement. Object types are not encoded as GeoJSON features. Data types and unions may be used by other classes, which prevents a general exclusive mapping to the GeoJSON top-level “geometry” member. Only a direct property of a «FeatureType» can be mapped in this way.
Figure 34 — Example of a feature type with an attribute designated as primary geometry
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Parcel": { |
5 | "$anchor": "Parcel", |
6 | "allOf": [ |
7 | { |
8 | "$ref": "https://geojson.org/schema/Feature.json" |
9 | }, |
10 | { |
11 | "type": "object", |
12 | "properties": { |
13 | "geometry": { |
14 | "$ref": "https://geojson.org/schema/Polygon.json" |
15 | } |
16 | } |
17 | } |
18 | ] |
19 | } |
20 | } |
21 | } |
Figure 35 — Example for encoding a feature type with primary geometry
7.7. Requirements class: Encoding rule for a JSON-FG compliant JSON Schema format
Requirements class 5 | |
---|---|
Identifier | /req/jsonfg |
Target type | JSON (Schema) documents |
Prerequisites | Requirements class 3: /req/geojson-formats http://www.opengis.net/spec/json-fg-1/0.1/req/core |
Normative statements | Requirement 24: /req/jsonfg/common-base Requirement 25: /req/jsonfg/iso19107-types-for-place-member Requirement 26: /req/jsonfg/primary-geometry Requirement 27: /req/jsonfg/primary-temporal-information |
NOTE An example of an application schema encoded in JSON-FG compliant JSON Schema format is given in Annex B.4.
7.7.1. Common base schema
As described in the core requirements class, common base types or — for the purposes of this encoding rule — common JSON Schema definitions can be added to the schema definition of certain kinds of classes, for example, all feature types.
Requirement 24 | |
---|---|
Identifier | /req/jsonfg/common-base |
Included in | Requirements class 5: /req/jsonfg |
Statement | All feature types shall use the JSON-FG Feature definition — https://beta.schemas.opengis.net/json-fg/feature.json — as common base. |
A | The relationship to the JSON-FG Feature definition schema shall be implemented by converting a feature type to a JSON Schema that consists of an “allOf” with two subschemas: the first being a “$ref” with value “https://beta.schemas.opengis.net/json-fg/feature.json”, the second being the schema produced by applying the other conversion rules to the feature type. However, if one of the supertypes of the feature type already has the JSON-FG Feature definition in its JSON Schema definition, then the JSON Schema definition of the feature type itself shall not define it again. |
B | If the feature type is encoded with an “allOf” for the JSON-FG Feature definition, then the “$anchor” member (see Clause 7.3.3.2) shall be encoded in the schema that contains the “allOf”, instead of within the second subschema. |
NOTE No common base schema is defined for object types. Such types need to be transformed to feature types if they should be encoded as JSON-FG features.
An example of encoding feature types with a common base schema is given in Clause 7.6.1. It can easily be adapted to match /req/jsonfg/common-base by exchanging “https://geojson.org/schema/Feature.json” with “https://beta.schemas.opengis.net/json-fg/feature.json”.
7.7.2. Implementation of ISO 19107 types for the “place” member
Requirement 25 | |
---|---|
Identifier | /req/jsonfg/iso19107-types-for-place-member |
Included in | Requirements class 5: /req/jsonfg |
Statement | If a UML property is encoded in JSON Schema, in the “place” top-level member of a JSON object that represents a type with identity, and the value type is one of the ISO 19107 geometry types listed in the first column of Table 10, then the JSON schema definition in the second column of that table shall be used in the JSON Schema definition of the property. |
Table 10 — JSON Schema implementation of types defined by ISO 19107, for the “place” member
7.7.3. Primary geometry
Requirement 26 | |
---|---|
Identifier | /req/jsonfg/primary-geometry |
Included in | Requirements class 5: /req/jsonfg |
A | If a feature type has a primary geometry property (identified following the rules in Clause 7.3.8), and that property is directly owned by the feature type, and the JSON Schema implementation of the property type is one of the JSON-FG geometry schemas (i.e., one of the JSON Schema references listed in Table 10), then:
|
NOTE 1 In instance data, the value of such a property is typically encoded within the (JSON-FG) top-level “place” member of the JSON object that represents the «FeatureType». However, there can also be cases where the value is encoded in the top-level “geometry” member. For further details, see OGC 21-045, section “7.5 Geometry”.
NOTE 2 UML properties of other kinds of classes — object types, data types, and unions — are not considered by this requirement. Object types are not encoded as JSON-FG features. Data types and unions may be used by other classes, which prevents a general exclusive mapping to the JSON-FG top-level “place” member. Only a direct property of a «FeatureType» can be mapped in this way.
Figure 36 — Example of a feature type with an attribute designated as primary place
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "BuildingPart": { |
5 | "$anchor": "BuildingPart", |
6 | "allOf": [ |
7 | { |
8 | "$ref": "http://example.org/schema/infra.json#Building_Core" |
9 | }, |
10 | { |
11 | "type": "object", |
12 | "properties": { |
13 | "place": { |
14 | "oneOf": [ |
15 | { |
16 | "type": "null" |
17 | }, |
18 | { |
19 | "$ref": "https://beta.schemas.opengis.net/json-fg/geometry-objects.json#/$defs/Polyhedron" |
20 | } |
21 | ] |
22 | } |
23 | } |
24 | } |
25 | ] |
26 | } |
27 | } |
28 | } |
Figure 37 — Example for encoding a feature type with primary place
7.7.4. Primary temporal information
Requirement 27 | |
---|---|
Identifier | /req/jsonfg/primary-temporal-information |
Included in | Requirements class 5: /req/jsonfg |
A | In the JSON Schema definition of a feature, the primary-instant, primary-interval, primary-interval-start, and primary-interval-end properties (identified following the rules in Clause 7.3.9) shall not be encoded within the “properties” member. |
B | In instance data, the value of such a property shall be encoded within the (JSON-FG) “time” member of the JSON object that represents the feature type. |
NOTE UML properties of other kinds of classes — object types, data types, and unions — are not considered by this requirement. Object types are not encoded as JSON-FG features. Data types and unions may be used by other classes, which prevents a general exclusive mapping to the JSON-FG top-level “time” member. Only a direct property of a feature type can be mapped in this way.
Figure 38 — Example of a feature type with an attribute designated as primary instant
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Building_Core": { |
5 | "$anchor": "Building_Core", |
6 | "allOf": [ |
7 | { |
8 | "$ref": "https://beta.schemas.opengis.net/json-fg/feature.json" |
9 | }, |
10 | { |
11 | "type": "object" |
12 | } |
13 | ] |
14 | } |
15 | } |
16 | } |
Figure 39 — Example for encoding a feature type with primary instant
7.8. Additional requirements classes for the by-reference encoding of property values
7.8.1. Overview
Requirements class /req/core specifies an inline encoding of property values. In the case that the value type of a UML property is a type with identity (that is not implemented as a simple JSON Schema type), it can be preferable and maybe even necessary to encode the value by reference. In other cases, both options should be offered. That is similar to what the GML Application Schema encoding rules support (for further details, see OGC 07-036r1, Annex E, section E.2.4.11).
NOTE 1 An example where a reference to an object is needed, is when the object is the value of properties from multiple other objects that are encoded within the same JSON document. For example, a feature referenced from several other features. In such a situation, it is often desirable not to encode the object inline multiple times — especially if that object also references other objects.
NOTE 2 Some applications may prefer to reference types with identity using a code (of type string or number) instead of using a URI. That code could be seen as a foreign key. In such cases, a model transformation should be applied first, which, for all relevant properties whose value type is a type with identity, replaces the value type with CharacterString or Number.
Multiple options exist for realizing the by-reference encoding of property values. A requirements class is available for each option:
/req/by-reference-uri — by-reference encoding of property values using a plain URI (reference, i.e., an absolute or relative URI)
/req/by-reference-link-object — by-reference encoding of property values using a link object
NOTE 3 The conversion behavior does not support by reference encoding for value types that are data types. In general, a data type does not have identity, and therefore a data type value should always be encoded inline, not by reference.
7.8.2. Requirements class: basics for the by-reference encoding of property values
Requirements class 6 | |
---|---|
Identifier | /req/by-reference-basic |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 1: /req/core |
Normative statement | Requirement 28: /req/by-reference-basic/inline-or-by-reference-tag |
Requirement 28 | |
---|---|
Identifier | /req/by-reference-basic/inline-or-by-reference-tag |
Included in | Requirements class 6: /req/by-reference-basic |
Statement | For a UML property, whose value type is a type with identity that is not implemented as a simple JSON Schema type, the tag inlineOrByReference, if set, shall have one of three values: inlineOrByReference, byReference, or inline. If the tag is not set on a UML property, or has an empty value, then the following value shall be assumed as default value:
|
NOTE The default value for tag inlineOrByReference is different in GML. For the JSON Schema encoding, the default values have been chosen in order to reduce the degrees of freedom and to reduce the schema complexity. The separation into default value inline for UML attributes, and byReference for UML association roles has been made since that reflects the typical modeling approach, where association roles have a value type that is usually encoded by reference, and attributes have a value type that is usually encoded inline — especially if the attribute value type is a type with identity (e.g., an ISO 19107 geometry type).
7.8.3. Requirements class: by-reference encoding of property values using a plain URI reference
Requirements class 7 | |
---|---|
Identifier | /req/by-reference-uri |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 6: /req/by-reference-basic |
Normative statement | Requirement 29: /req/by-reference-uri/encoding |
Requirement 29 | |
---|---|
Identifier | /req/by-reference-uri/encoding |
Included in | Requirements class 7: /req/by-reference-uri |
Statement | If the value of tag inlineOrByReference of a UML property — whose value type is a type with identity that is not implemented as a simple JSON Schema type — is not inline: |
A | If the tag value is byReference, then the JSON Schema definition of the property shall contain a “type” member with value “string”, as well as a “format” member with value “uri-reference”; |
B | Otherwise — the tag value is inlineOrByReference — the inline and by-reference encoding cases shall be combined in the JSON Schema definition of the property using the “oneOf” keyword. |
NOTE The result is an XOR type of check, i.e., a value can either be given inline or by reference, but not both. This is different to GML, where in the case of inlineOrByReference and a type with identity as value type, a value can be encoded both inline and by reference.
Figure 40 — Example of an association between two feature types, where the association roles are to be encoded by reference
The JSON Schema encoding for the example in Figure 40, using URIs to realize by-reference encoding of property values, is given in Figure 41.
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Parcel": { |
5 | "$anchor": "Parcel", |
6 | "type": "object", |
7 | "properties": { |
8 | "owner": { |
9 | "type": "array", |
10 | "minItems": 1, |
11 | "items": { |
12 | "type": "string", |
13 | "format": "uri-reference" |
14 | }, |
15 | "uniqueItems": true |
16 | } |
17 | }, |
18 | "required": [ |
19 | "owner" |
20 | ] |
21 | }, |
22 | "Person": { |
23 | "$anchor": "Person", |
24 | "type": "object", |
25 | "properties": { |
26 | "owns": { |
27 | "type": "array", |
28 | "items": { |
29 | "type": "string", |
30 | "format": "uri-reference" |
31 | }, |
32 | "uniqueItems": true |
33 | } |
34 | } |
35 | } |
36 | } |
37 | } |
Figure 41 — Example for encoding association roles by-reference using URIs
This JSON object is valid against the schema definition of “Parcel” from Figure 41:
{
"owner": ["http://example.org/Person/d024i42sl"]
}
Figure 42
7.8.4. Requirements class: by-reference encoding of property values using a link object
Requirements class 8 | |
---|---|
Identifier | /req/by-reference-link-object |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 6: /req/by-reference-basic |
Normative statement | Requirement 30: /req/by-reference-link-object/encoding |
Requirement 30 | |
---|---|
Identifier | /req/by-reference-link-object/encoding |
Included in | Requirements class 8: /req/by-reference-link-object |
Statement | If the value of tag inlineOrByReference of a UML property — whose value type is a type with identity that is not implemented as a simple JSON Schema type — is not inline: |
A | If the tag value is byReference, then the JSON Schema definition of the property shall contain a “$ref” member with value “https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject” (the JSON Schema for that link object is defined in Annex C); |
B | Otherwise — the tag value is inlineOrByReference — the inline and by-reference encoding cases shall be combined in the JSON Schema definition of the property using the “oneOf” keyword. |
NOTE The result is an XOR type of check, i.e., a value can either be given inline or by reference, but not both. This is different to GML, where in the case of inlineOrByReference and a type with identity as value type, a value can be encoded both inline and by reference.
The JSON Schema encoding for the example in Figure 40, using link objects to realize by-reference encoding of property values, is given in Figure 43.
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Parcel": { |
5 | "$anchor": "Parcel", |
6 | "type": "object", |
7 | "properties": { |
8 | "owner": { |
9 | "type": "array", |
10 | "minItems": 1, |
11 | "items": { |
12 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
13 | }, |
14 | "uniqueItems": true |
15 | } |
16 | }, |
17 | "required": [ |
18 | "owner" |
19 | ] |
20 | }, |
21 | "Person": { |
22 | "$anchor": "Person", |
23 | "type": "object", |
24 | "properties": { |
25 | "owns": { |
26 | "type": "array", |
27 | "items": { |
28 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
29 | }, |
30 | "uniqueItems": true |
31 | } |
32 | } |
33 | } |
34 | } |
35 | } |
Figure 43 — Example for encoding association roles by-reference using link objects
This JSON object is valid against the schema definition of “Parcel” from Figure 43:
{
"owner": [
{
"title": "John Doe",
"href": "http://example.org/Person/d024i42sl"
}
]
}
Figure 44
7.9. Additional requirements classes for the encoding of union types
7.9.1. Overview
Application schemas have two ways of using types with stereotype «union».
According to ISO 19103:2015, a «union» type consists “of one and only one of several alternative datatypes (listed as member attributes). This is similar to a discriminated union in many programming languages”. According to this definition, only the types of the UML attributes defined for a «union» are of interest.
In practice, unions defined in application schemas are also used differently, defining a choice between a number of options, where each option is modeled as a UML attribute. In other words, the attribute itself has meaning — not just its value type. Multiple options can have the same value type. Options can have different maximum multiplicity (especially greater than 1). The UML-to-GML application schema encoding rules support this way of using unions (see OGC 07-036r1, section E.2.4.10).
The following sections document requirements classes for union encodings that support these two approaches.
7.9.2. Requirements class: JSON Schema encoding for unions representing type discriminators
Requirements class 9 | |
---|---|
Identifier | /req/union-type-discriminator |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 1: /req/core |
Normative statement | Requirement 31: /req/union-type-discriminator/encoding |
Requirement 31 | |
---|---|
Identifier | /req/union-type-discriminator/encoding |
Included in | Requirements class 9: /req/union-type-discriminator |
Statement | A «union» shall be encoded as a JSON Schema definition that represents a choice between the value types of the union properties.
|
The result of applying this encoding to the unions from Figure 45 is shown in Figure 46.
Figure 45 — Example of type discriminator unions
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Union_TypeDiscriminator": { |
5 | "oneOf": [ |
6 | { |
7 | "type": [ |
8 | "string", |
9 | "integer" |
10 | ] |
11 | }, |
12 | { |
13 | "$ref": "https://geojson.org/schema/Point.json" |
14 | } |
15 | ] |
16 | }, |
17 | "Union_TypeDiscriminator_OtherTypes": { |
18 | "oneOf": [ |
19 | { |
20 | "$ref": "https://geojson.org/schema/LineString.json" |
21 | }, |
22 | { |
23 | "$ref": "https://geojson.org/schema/Point.json" |
24 | } |
25 | ] |
26 | }, |
27 | "Union_TypeDiscriminator_SimpleTypes": { |
28 | "type": [ |
29 | "string", |
30 | "integer" |
31 | ] |
32 | } |
33 | } |
34 | } |
Figure 46 — Example of a JSON Schema for unions, encoding them as type discriminators
WARNING
Care must be taken, that the type choices of a type discriminator union are separate value spaces. Otherwise, validation may fail, if an actual value matches more than one of the type choices. That would break the rule of the “oneOf” JSON Schema keyword, that one and only one of its component schemas is satisfied. If, for example, the “Union_TypeDiscriminator” in Figure 46 had another option for a date value (“type”: “string”, “format”: “date”), and value “2022-12-09” was validated against the resulting JSON Schema definition, validation would fail — because that value matches both the string-or-number case and the string-with-format-date case.
7.9.3. Requirements class: JSON Schema encoding for unions representing property choices
Requirements class 10 | |
---|---|
Identifier | /req/union-property-choice |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 1: /req/core |
Normative statement | Requirement 32: /req/union-property-choice/encoding |
Requirement 32 | |
---|---|
Identifier | /req/union-property-choice/encoding |
Included in | Requirements class 10: /req/union-property-choice |
A | A «union» shall be encoded as a JSON Schema definition of a JSON object, where each union option is represented as an optional member of the JSON object. |
B | The choice between the options defined by the union shall be encoded using “maxProperties” = “minProperties” = 1. That is, the number of members that are allowed for the JSON object is restricted to exactly one. |
C | An "additionalProperties": false shall be used to prevent any undefined properties. |
The result of applying this encoding to the union from Figure 47 is shown in Figure 48.
Figure 47 — «union» example
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "UnionA": { |
5 | "type": "object", |
6 | "properties": { |
7 | "option1": { |
8 | "type": "string" |
9 | }, |
10 | "option2": { |
11 | "type": "number" |
12 | } |
13 | }, |
14 | "additionalProperties": false, |
15 | "minProperties": 1, |
16 | "maxProperties": 1 |
17 | } |
18 | }, |
19 | "$ref": "#/$defs/UnionA" |
20 | } |
Figure 48 — Example of a JSON Schema for a «union» class, representing the property choice using "minProperties" and "maxProperites"
NOTE An alternative approach would be using the “oneOf” keyword, with one subschema per union property, which only defines that property, and requires it (but does not perform any other checks). This option is more verbose, harder to read and understand and, therefore, not recommended.
This JSON object is valid against the schema:
{
"option1": "x"
}
Figure 49
This JSON object is invalid (because “option2” has a string value, rather than a numeric value) against the schema:
{
"option2": "x"
}
Figure 50
7.10. Additional requirements classes for the encoding of code list types
7.10.1. Overview
This specification defines three approaches for encoding the values of properties that have a «CodeList» as value type:
using a simple literal value, e.g., a string or number that represents a code,
using a URI as code value, and
using a link object to link to a code representation.
The following sections document requirements classes for code list encodings that support these three approaches. All of them inherit requirements from a common requirements class, which is defined in Clause 7.10.2.
7.10.2. Requirements class: Basic JSON Schema encoding for code lists
Requirements class 11 | |
---|---|
Identifier | /req/codelists-basic |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 1: /req/core |
Normative statements | Requirement 33: /req/codelists-basic/schema-definition Requirement 34: /req/codelists-basic/codelist-tag |
Requirement 33 | |
---|---|
Identifier | /req/codelists-basic/schema-definition |
Included in | Requirements class 11: /req/codelists-basic |
Statement | A «CodeList» shall be converted to a JSON Schema definition of a JSON object. That definition shall be added to the definitions schema, using the type name as definition key. |
Requirement 34 | |
---|---|
Identifier | /req/codelists-basic/codelist-tag |
Included in | Requirements class 11: /req/codelists-basic |
Statement | If the «CodeList» has tag codeList (which is defined by ISO 19103:2015), with a non-blank value, then a “codeList” member shall be added to the JSON Schema definition of the code list, with the tag value as value. |
Figure 51 — Example of a «CodeList» type with tagged value 'codeList'
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "SomeCodelist": { |
5 | ... |
6 | "codeList": "http://example.org/codelists/SomeCodelist", |
7 | ... |
8 | } |
9 | } |
10 | } |
Figure 52 — Example of the basic JSON Schema encoding of a «CodeList» type with tagged value 'codeList'
7.10.3. Requirements class: JSON Schema encoding for code lists — literal
Requirements class 12 | |
---|---|
Identifier | /req/codelists-literal |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 11: /req/codelists-basic |
Normative statement | Requirement 35: /req/codelists-literal/type |
Requirement 35 | |
---|---|
Identifier | /req/codelists-literal/type |
Included in | Requirements class 12: /req/codelists-literal |
Statement | The JSON Schema definition of a «CodeList» shall have a “type” member defined by evaluating tagged value literalEncodingType. The tagged value literalEncodingType identifies the conceptual type that applies to the code values. If the tagged value is not set on the code list, or has an empty value, then the literal encoding type is defined to be CharacterString. |
The literal encoding type is one of the types from ISO 19103, which are implemented as a simple JSON Schema type — see Table 6 in Clause 7.3.3.8.
Figure 53 — Example of «CodeList» types
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "CodelistNumeric": { |
5 | "type": "number" |
6 | }, |
7 | "CodelistString": { |
8 | "type": "string" |
9 | } |
10 | } |
11 | } |
Figure 54 — Example of the JSON Schema encodings of «CodeList» types
7.10.4. Requirements class: JSON Schema encoding for code lists — URI
Requirements class 13 | |
---|---|
Identifier | /req/codelists-uri |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 11: /req/codelists-basic |
Normative statement | Requirement 36: /req/codelists-uri/type |
Requirement 36 | |
---|---|
Identifier | /req/codelists-uri/type |
Included in | Requirements class 13: /req/codelists-uri |
Statement | The JSON Schema definition of a «CodeList» shall have a “type” member with value “string”, as well as a “format” member with value “uri”. |
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "CodelistUriFormat": { |
5 | "type": "string", |
6 | "format": "uri" |
7 | } |
8 | } |
9 | } |
Figure 55 — Example of the JSON Schema encodings of a «CodeList» type with the JSON Schema "type" being a URI
7.10.5. Requirements class: JSON Schema encoding for code lists — link object
Requirements class 14 | |
---|---|
Identifier | /req/codelists-link-object |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 11: /req/codelists-basic |
Normative statement | Requirement 37: /req/codelists-link-object/schema-ref |
Requirement 37 | |
---|---|
Identifier | /req/codelists-link-object/schema-ref |
Included in | Requirements class 14: /req/codelists-link-object |
Statement | The JSON Schema definition of a «CodeList» shall have a “$ref” member with value “https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject”. |
That means that a code value is essentially encoded as a “link object” as specified by IETF RFC 8288 and implemented in the OGC API standards. The link object provides “href” and “title” members like the simple Xlinks in GML.
7.11. Requirements class: Encoding of an additional entityType property
Requirements class 15 | |
---|---|
Identifier | /req/entitytype |
Target type | JSON (Schema) documents |
Prerequisite | Requirements class 1: /req/core |
Normative statements | Requirement 38: /req/entitytype/member Permission 1: /req/entitytype/json-fg-feature-type |
Requirement 38 | |
---|---|
Identifier | /req/entitytype/member |
Included in | Requirements class 15: /req/entitytype |
A | If the class C that is being converted is a feature type, an object type, or a data type, then the JSON member “entityType” shall be added to the properties of the JSON object that represents the class. If, however, the JSON Schema encoding of any of the potentially existing supertypes of the class already defines the “entityType” member, then the “entityType” member shall not be added to the JSON representation of class C. |
B | The “entityType” member shall be required and string-valued. |
C | The “entityType” member shall be used to encode the name of the conceptual type (i.e., the class) that is represented by the JSON object. |
Permission 1 | |
---|---|
Identifier | /req/entitytype/json-fg-feature-type |
Included in | Requirements class 15: /req/entitytype |
Statement | For a feature type that is encoded as a JSON-FG feature, the “entityType” member may be omitted. That is due to the fact that a JSON-FG feature already has a top-level “featureType” member, which serves the same purpose as the “entityType” member. |
NOTE 1 By default, the property value is not restricted using “const”, because doing so would prevent JSON Schema constraints that support inheritance-related checks. However, if the application schema did not use inheritance, then such restrictions could be defined.
NOTE 2 Encoding the type name in JSON objects can be useful, since, as described in chapter 6 of the OGC Testbed-14: Application Schemas and JSON Technologies Engineering Report, having a key within a JSON object with a string value that identifies the type of the object allows that object to be mapped to RDF. More specifically, the string value can be mapped to an IRI that identifies the type of an RDFS resource.
NOTE 3 Encoding a JSON object that represents an abstract type, with the “entityType” having the abstract type name as value, would be useful with regards to linked data applications, and conversion of JSON data to RDF using JSON-LD. Abstractness is also not supported in RDF/OWL, so RDF resources can define the RDFS/OWL class or datatype, which represent an abstract type from the conceptual model, as their type. That makes sense for cases in which the exact type of a resource or “thing” is not known yet, but a more general type is.
1 | { |
2 | "$schema": "http://json-schema.org/draft/2020-12/schema", |
3 | "$defs": { |
4 | "Person": { |
5 | "properties": { |
6 | "entityType": { |
7 | "type": "string" |
8 | }, |
9 | "name": { |
10 | "type": "string" |
11 | } |
12 | }, |
13 | "required": [ |
14 | "entityType", "name" |
15 | ] |
16 | } |
17 | }, |
18 | "$ref": "#/$defs/Person" |
19 | } |
Figure 56 — JSON Schema example with property "entityType" used for identifying the type of a JSON object
The following JSON instance is valid against the schema:
{
"entityType": "Person",
"name": "John Doe"
}
Figure 57
Annex A
(normative)
Conformance Class Abstract Test Suite
NOTE Conformance classes can be defined when this specification moves on in the OGC standardization process.
Annex B
(informative)
Example application schema
B.1. Overview
This Annex illustrates the results of applying the JSON Schema encoding rules on the application schema example shown in Figure B.1.
Figure B.1 — Example application schema in UML
NOTE The schema uses fixed units of measure for BuildingPart.clearanceHeight and Parcel.area. The units are defined in tagged value unit, using UCUM codes. BuildingPart.clearanceHeight has unit “m” (meter), and Parcel.area has unit “m2” (square meter).
B.2. Example schema in plain JSON encoding
The JSON Schema shown in Figure B.2 was created by applying requirements class /req/plain and /req/by-reference-link-object.
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/schema/infra.json", |
4 | "$defs": { |
5 | "Address": { |
6 | "$anchor": "Address", |
7 | "type": "object", |
8 | "properties": { |
9 | "street": { |
10 | "type": "string" |
11 | }, |
12 | "housenumber": { |
13 | "type": "string" |
14 | }, |
15 | "poBox": { |
16 | "type": "string" |
17 | }, |
18 | "city": { |
19 | "type": "string" |
20 | }, |
21 | "postalCode": { |
22 | "type": "string" |
23 | }, |
24 | "country": { |
25 | "type": "string" |
26 | } |
27 | }, |
28 | "required": [ |
29 | "city", |
30 | "postalCode" |
31 | ] |
32 | }, |
33 | "Building": { |
34 | "$anchor": "Building", |
35 | "allOf": [ |
36 | { |
37 | "$ref": "#/$defs/Building_Core" |
38 | }, |
39 | { |
40 | "type": "object", |
41 | "properties": { |
42 | "address": { |
43 | "$ref": "#/$defs/Address" |
44 | }, |
45 | "type": { |
46 | "$ref": "#/$defs/BuildingType" |
47 | } |
48 | }, |
49 | "required": [ |
50 | "address", |
51 | "type" |
52 | ] |
53 | } |
54 | ] |
55 | }, |
56 | "BuildingPart": { |
57 | "$anchor": "BuildingPart", |
58 | "allOf": [ |
59 | { |
60 | "$ref": "#/$defs/Building_Core" |
61 | }, |
62 | { |
63 | "type": "object", |
64 | "properties": { |
65 | "type": { |
66 | "$ref": "#/$defs/BuildingPartType" |
67 | }, |
68 | "clearanceHeight": { |
69 | "type": "number", |
70 | "unit": "m" |
71 | }, |
72 | "extent": { |
73 | "$ref": "https://beta.schemas.opengis.net/json-fg/geometry-objects.json#/$defs/Polyhedron" |
74 | }, |
75 | "belongsTo": { |
76 | "type": "array", |
77 | "items": { |
78 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
79 | }, |
80 | "uniqueItems": true |
81 | } |
82 | }, |
83 | "required": [ |
84 | "extent", |
85 | "type" |
86 | ] |
87 | } |
88 | ] |
89 | }, |
90 | "BuildingPartType": { |
91 | "$anchor": "BuildingPartType", |
92 | "type": "integer", |
93 | "enum": [ |
94 | 1000, |
95 | 2000, |
96 | 2100, |
97 | 3000, |
98 | 9999 |
99 | ] |
100 | }, |
101 | "BuildingType": { |
102 | "$anchor": "BuildingType", |
103 | "type": "string", |
104 | "enum": [ |
105 | "school", |
106 | "residential house", |
107 | "mixed", |
108 | "other" |
109 | ] |
110 | }, |
111 | "Building_Core": { |
112 | "$anchor": "Building_Core", |
113 | "type": "object", |
114 | "properties": { |
115 | "dateOfConstruction": { |
116 | "type": "string", |
117 | "format": "date", |
118 | "pattern": "^\\d{4}-\\d{2}-\\d{2}$" |
119 | } |
120 | }, |
121 | "required": [ |
122 | "dateOfConstruction" |
123 | ] |
124 | }, |
125 | "Parcel": { |
126 | "$anchor": "Parcel", |
127 | "type": "object", |
128 | "properties": { |
129 | "area": { |
130 | "type": "number", |
131 | "unit": "m2" |
132 | }, |
133 | "extent": { |
134 | "$ref": "https://geojson.org/schema/Polygon.json" |
135 | }, |
136 | "hasBuilding": { |
137 | "type": "array", |
138 | "items": { |
139 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
140 | }, |
141 | "uniqueItems": true |
142 | }, |
143 | "owner": { |
144 | "type": "array", |
145 | "minItems": 1, |
146 | "items": { |
147 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
148 | }, |
149 | "uniqueItems": true |
150 | } |
151 | }, |
152 | "required": [ |
153 | "area", |
154 | "extent", |
155 | "owner" |
156 | ] |
157 | }, |
158 | "Person": { |
159 | "$anchor": "Person", |
160 | "type": "object", |
161 | "properties": { |
162 | "firstName": { |
163 | "type": "string" |
164 | }, |
165 | "lastName": { |
166 | "type": "string" |
167 | }, |
168 | "owns": { |
169 | "type": "array", |
170 | "items": { |
171 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
172 | }, |
173 | "uniqueItems": true |
174 | } |
175 | }, |
176 | "required": [ |
177 | "firstName", |
178 | "lastName" |
179 | ] |
180 | } |
181 | } |
182 | } |
Figure B.2 — JSON Schema for the example application schema - plain JSON encoding
B.3. Example schema in GeoJSON-compliant encoding
The JSON Schema shown in Figure B.3 was created by applying requirements class /req/geojson and /req/by-reference-link-object.
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/schema/infra.json", |
4 | "$defs": { |
5 | "Address": { |
6 | "$anchor": "Address", |
7 | "type": "object", |
8 | "properties": { |
9 | "street": { |
10 | "type": "string" |
11 | }, |
12 | "housenumber": { |
13 | "type": "string" |
14 | }, |
15 | "poBox": { |
16 | "type": "string" |
17 | }, |
18 | "city": { |
19 | "type": "string" |
20 | }, |
21 | "postalCode": { |
22 | "type": "string" |
23 | }, |
24 | "country": { |
25 | "type": "string" |
26 | } |
27 | }, |
28 | "required": [ |
29 | "city", |
30 | "postalCode" |
31 | ] |
32 | }, |
33 | "Building": { |
34 | "$anchor": "Building", |
35 | "allOf": [ |
36 | { |
37 | "$ref": "#/$defs/Building_Core" |
38 | }, |
39 | { |
40 | "type": "object", |
41 | "properties": { |
42 | "properties": { |
43 | "type": "object", |
44 | "properties": { |
45 | "address": { |
46 | "$ref": "#/$defs/Address" |
47 | }, |
48 | "type": { |
49 | "$ref": "#/$defs/BuildingType" |
50 | } |
51 | }, |
52 | "required": [ |
53 | "address", |
54 | "type" |
55 | ] |
56 | } |
57 | }, |
58 | "required": [ |
59 | "properties" |
60 | ] |
61 | } |
62 | ] |
63 | }, |
64 | "BuildingPart": { |
65 | "$anchor": "BuildingPart", |
66 | "allOf": [ |
67 | { |
68 | "$ref": "#/$defs/Building_Core" |
69 | }, |
70 | { |
71 | "type": "object", |
72 | "properties": { |
73 | "properties": { |
74 | "type": "object", |
75 | "properties": { |
76 | "type": { |
77 | "$ref": "#/$defs/BuildingPartType" |
78 | }, |
79 | "clearanceHeight": { |
80 | "type": "number", |
81 | "unit": "m" |
82 | }, |
83 | "extent": { |
84 | "$ref": "https://beta.schemas.opengis.net/json-fg/geometry-objects.json#/$defs/Polyhedron" |
85 | }, |
86 | "belongsTo": { |
87 | "type": "array", |
88 | "items": { |
89 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
90 | }, |
91 | "uniqueItems": true |
92 | } |
93 | }, |
94 | "required": [ |
95 | "extent", |
96 | "type" |
97 | ] |
98 | } |
99 | }, |
100 | "required": [ |
101 | "properties" |
102 | ] |
103 | } |
104 | ] |
105 | }, |
106 | "BuildingPartType": { |
107 | "$anchor": "BuildingPartType", |
108 | "type": "integer", |
109 | "enum": [ |
110 | 1000, |
111 | 2000, |
112 | 2100, |
113 | 3000, |
114 | 9999 |
115 | ] |
116 | }, |
117 | "BuildingType": { |
118 | "$anchor": "BuildingType", |
119 | "type": "string", |
120 | "enum": [ |
121 | "school", |
122 | "residential house", |
123 | "mixed", |
124 | "other" |
125 | ] |
126 | }, |
127 | "Building_Core": { |
128 | "$anchor": "Building_Core", |
129 | "allOf": [ |
130 | { |
131 | "$ref": "https://geojson.org/schema/Feature.json" |
132 | }, |
133 | { |
134 | "type": "object", |
135 | "properties": { |
136 | "properties": { |
137 | "type": "object", |
138 | "properties": { |
139 | "dateOfConstruction": { |
140 | "type": "string", |
141 | "format": "date", |
142 | "pattern": "^\\d{4}-\\d{2}-\\d{2}$" |
143 | } |
144 | }, |
145 | "required": [ |
146 | "dateOfConstruction" |
147 | ] |
148 | } |
149 | }, |
150 | "required": [ |
151 | "properties" |
152 | ] |
153 | } |
154 | ] |
155 | }, |
156 | "Parcel": { |
157 | "$anchor": "Parcel", |
158 | "allOf": [ |
159 | { |
160 | "$ref": "https://geojson.org/schema/Feature.json" |
161 | }, |
162 | { |
163 | "type": "object", |
164 | "properties": { |
165 | "geometry": { |
166 | "$ref": "https://geojson.org/schema/Polygon.json" |
167 | }, |
168 | "properties": { |
169 | "type": "object", |
170 | "properties": { |
171 | "area": { |
172 | "type": "number", |
173 | "unit": "m2" |
174 | }, |
175 | "hasBuilding": { |
176 | "type": "array", |
177 | "items": { |
178 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
179 | }, |
180 | "uniqueItems": true |
181 | }, |
182 | "owner": { |
183 | "type": "array", |
184 | "minItems": 1, |
185 | "items": { |
186 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
187 | }, |
188 | "uniqueItems": true |
189 | } |
190 | }, |
191 | "required": [ |
192 | "area", |
193 | "owner" |
194 | ] |
195 | } |
196 | }, |
197 | "required": [ |
198 | "properties" |
199 | ] |
200 | } |
201 | ] |
202 | }, |
203 | "Person": { |
204 | "$anchor": "Person", |
205 | "allOf": [ |
206 | { |
207 | "$ref": "https://geojson.org/schema/Feature.json" |
208 | }, |
209 | { |
210 | "type": "object", |
211 | "properties": { |
212 | "properties": { |
213 | "type": "object", |
214 | "properties": { |
215 | "firstName": { |
216 | "type": "string" |
217 | }, |
218 | "lastName": { |
219 | "type": "string" |
220 | }, |
221 | "owns": { |
222 | "type": "array", |
223 | "items": { |
224 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
225 | }, |
226 | "uniqueItems": true |
227 | } |
228 | }, |
229 | "required": [ |
230 | "firstName", |
231 | "lastName" |
232 | ] |
233 | } |
234 | }, |
235 | "required": [ |
236 | "properties" |
237 | ] |
238 | } |
239 | ] |
240 | } |
241 | } |
242 | } |
Figure B.3 — JSON Schema for the example application schema - GeoJSON-compliant encoding
B.4. Example schema in JSON-FG-compliant encoding
The JSON Schema shown in Figure B.4 was created by applying requirements class /req/jsonfg and /req/by-reference-link-object.
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "http://example.org/schema/infra.json", |
4 | "$defs": { |
5 | "Address": { |
6 | "$anchor": "Address", |
7 | "type": "object", |
8 | "properties": { |
9 | "street": { |
10 | "type": "string" |
11 | }, |
12 | "housenumber": { |
13 | "type": "string" |
14 | }, |
15 | "poBox": { |
16 | "type": "string" |
17 | }, |
18 | "city": { |
19 | "type": "string" |
20 | }, |
21 | "postalCode": { |
22 | "type": "string" |
23 | }, |
24 | "country": { |
25 | "type": "string" |
26 | } |
27 | }, |
28 | "required": [ |
29 | "city", |
30 | "postalCode" |
31 | ] |
32 | }, |
33 | "Building": { |
34 | "$anchor": "Building", |
35 | "allOf": [ |
36 | { |
37 | "$ref": "#/$defs/Building_Core" |
38 | }, |
39 | { |
40 | "type": "object", |
41 | "properties": { |
42 | "properties": { |
43 | "type": "object", |
44 | "properties": { |
45 | "address": { |
46 | "$ref": "#/$defs/Address" |
47 | }, |
48 | "type": { |
49 | "$ref": "#/$defs/BuildingType" |
50 | } |
51 | }, |
52 | "required": [ |
53 | "address", |
54 | "type" |
55 | ] |
56 | } |
57 | }, |
58 | "required": [ |
59 | "properties" |
60 | ] |
61 | } |
62 | ] |
63 | }, |
64 | "BuildingPart": { |
65 | "$anchor": "BuildingPart", |
66 | "allOf": [ |
67 | { |
68 | "$ref": "#/$defs/Building_Core" |
69 | }, |
70 | { |
71 | "type": "object", |
72 | "properties": { |
73 | "place": { |
74 | "oneOf": [ |
75 | { |
76 | "type": "null" |
77 | }, |
78 | { |
79 | "$ref": "https://beta.schemas.opengis.net/json-fg/geometry-objects.json#/$defs/Polyhedron" |
80 | } |
81 | ] |
82 | }, |
83 | "properties": { |
84 | "type": "object", |
85 | "properties": { |
86 | "type": { |
87 | "$ref": "#/$defs/BuildingPartType" |
88 | }, |
89 | "clearanceHeight": { |
90 | "type": "number", |
91 | "unit": "m" |
92 | }, |
93 | "belongsTo": { |
94 | "type": "array", |
95 | "items": { |
96 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
97 | }, |
98 | "uniqueItems": true |
99 | } |
100 | }, |
101 | "required": [ |
102 | "type" |
103 | ] |
104 | } |
105 | }, |
106 | "required": [ |
107 | "properties" |
108 | ] |
109 | } |
110 | ] |
111 | }, |
112 | "BuildingPartType": { |
113 | "$anchor": "BuildingPartType", |
114 | "type": "integer", |
115 | "enum": [ |
116 | 1000, |
117 | 2000, |
118 | 2100, |
119 | 3000, |
120 | 9999 |
121 | ] |
122 | }, |
123 | "BuildingType": { |
124 | "$anchor": "BuildingType", |
125 | "type": "string", |
126 | "enum": [ |
127 | "school", |
128 | "residential house", |
129 | "mixed", |
130 | "other" |
131 | ] |
132 | }, |
133 | "Building_Core": { |
134 | "$anchor": "Building_Core", |
135 | "allOf": [ |
136 | { |
137 | "$ref": "https://beta.schemas.opengis.net/json-fg/feature.json" |
138 | }, |
139 | { |
140 | "type": "object" |
141 | } |
142 | ] |
143 | }, |
144 | "Parcel": { |
145 | "$anchor": "Parcel", |
146 | "allOf": [ |
147 | { |
148 | "$ref": "https://beta.schemas.opengis.net/json-fg/feature.json" |
149 | }, |
150 | { |
151 | "type": "object", |
152 | "properties": { |
153 | "place": { |
154 | "oneOf": [ |
155 | { |
156 | "type": "null" |
157 | }, |
158 | { |
159 | "$ref": "https://beta.schemas.opengis.net/json-fg/geometry-objects.json#/$defs/Polygon.json" |
160 | } |
161 | ] |
162 | }, |
163 | "properties": { |
164 | "type": "object", |
165 | "properties": { |
166 | "area": { |
167 | "type": "number", |
168 | "unit": "m2" |
169 | }, |
170 | "hasBuilding": { |
171 | "type": "array", |
172 | "items": { |
173 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
174 | }, |
175 | "uniqueItems": true |
176 | }, |
177 | "owner": { |
178 | "type": "array", |
179 | "minItems": 1, |
180 | "items": { |
181 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
182 | }, |
183 | "uniqueItems": true |
184 | } |
185 | }, |
186 | "required": [ |
187 | "area", |
188 | "owner" |
189 | ] |
190 | } |
191 | }, |
192 | "required": [ |
193 | "properties" |
194 | ] |
195 | } |
196 | ] |
197 | }, |
198 | "Person": { |
199 | "$anchor": "Person", |
200 | "allOf": [ |
201 | { |
202 | "$ref": "https://beta.schemas.opengis.net/json-fg/feature.json" |
203 | }, |
204 | { |
205 | "type": "object", |
206 | "properties": { |
207 | "properties": { |
208 | "type": "object", |
209 | "properties": { |
210 | "firstName": { |
211 | "type": "string" |
212 | }, |
213 | "lastName": { |
214 | "type": "string" |
215 | }, |
216 | "owns": { |
217 | "type": "array", |
218 | "items": { |
219 | "$ref": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json#/$defs/LinkObject" |
220 | }, |
221 | "uniqueItems": true |
222 | } |
223 | }, |
224 | "required": [ |
225 | "firstName", |
226 | "lastName" |
227 | ] |
228 | } |
229 | }, |
230 | "required": [ |
231 | "properties" |
232 | ] |
233 | } |
234 | ] |
235 | } |
236 | } |
237 | } |
Figure B.4 — JSON Schema for the example application schema - JSON-FG-compliant encoding
Annex C
(normative)
JSON Schema definitions
The following JSON Schema defines the schema for link object and measure, which are used in this specification.
1 | { |
2 | "$schema": "https://json-schema.org/draft/2020-12/schema", |
3 | "$id": "https://register.geostandaarden.nl/jsonschema/uml2json/0.1/schema_definitions.json", |
4 | "$defs": { |
5 | "LinkObject": { |
6 | "$anchor": "LinkObject", |
7 | "title": "link object", |
8 | "description": "definition of a link object", |
9 | "type": "object", |
10 | "required": ["href"], |
11 | "properties": { |
12 | "href": { |
13 | "type": "string", |
14 | "description": "Supplies the URI to a remote resource (or resource fragment).", |
15 | "example": "http://data.example.com/buildings/123" |
16 | }, |
17 | "rel": { |
18 | "type": "string", |
19 | "description": "The type or semantics of the relation.", |
20 | "example": "related" |
21 | }, |
22 | "type": { |
23 | "type": "string", |
24 | "description": "A hint indicating what the media type of the result of dereferencing the link should be.", |
25 | "example": "application/geo+json" |
26 | }, |
27 | "hreflang": { |
28 | "type": "string", |
29 | "description": "A hint indicating what the language of the result of dereferencing the link should be.", |
30 | "example": "en" |
31 | }, |
32 | "title": { |
33 | "type": "string", |
34 | "description": "Used to label the destination of a link such that it can be used as a human-readable identifier.", |
35 | "example": "Trierer Strasse 70, 53115 Bonn" |
36 | }, |
37 | "length": {"type": "integer"} |
38 | } |
39 | }, |
40 | "Measure": { |
41 | "$anchor": "Measure", |
42 | "title": "measure object", |
43 | "description": "definition of a measure object", |
44 | "type": "object", |
45 | "required": [ |
46 | "value", |
47 | "uom" |
48 | ], |
49 | "properties": { |
50 | "value": {"type": "number"}, |
51 | "uom": {"type": "string"} |
52 | } |
53 | } |
54 | } |
55 | } |
Figure C.1 — JSON Schema for link object and measure
Annex D
(informative)
JSON Schema definitions for collections
This specification defines requirements for the creation of schema definitions with the JSON Schema constraints to validate a JSON object that represents a type with identity. The specification does not define requirements (classes) with which to define the schema for collections of such types. There are different aspects to consider, when defining such collections. The following sections document considerations and ideas regarding these aspects, to be used as input for future discussion and possibly standardization work.
D.1. Scope and naming of collection definitions
In practice, uniform as well as mixed collections are possible. A uniform collection contains features of a single specific type, whereas a mixed collection can have objects of different type. JSON Schema definitions for uniform collections could be defined with name being {type name} + Collection, whereas a single definition with name FeatureCollection could cover the case of all mixed collections (at least for all types with identity defined by the application schema).
D.2. Structure of collection definitions
The definition for a uniform collection would ensure that the collection members are all valid against a single type definition.
The definition for the general FeatureCollection would use either an anyOf or oneOf, with a choice of schema definitions for all types with identity. Cases in which an object is valid against more than one of these definitions can be problematic:
In case of anyOf, maybe the schema definition for a more general type matches, causing the validator to stop the validation process, thus potentially not checking constraints for the specific schema definition for a given type.
In case of oneOf, the validator does not stop at the first matching schema definition, but continues validation against all options, until it has ensured that either all other definitions do not match, or one more does match. The latter case would result in the overall validation to fail. However, that can easily happen in case of similar class structures, or in case of inheritance hierarchies, where an object matches the schema defined by a supertype as well as that of a subtype.
D.3. Performance
It is unclear how performant the validation against the general FeatureCollection would be in practice, in case of a large or complex application schema. Then again, validation time may not be that critical to an application that wants to ensure that data within a collection is valid.
D.4. Abstract types
It is unclear if collection definitions should be created for or include abstract types. It may be useful to create such definitions for “uniform” collections of abstract types, even if that implies that actual collections may have objects of different subtypes of the abstract type. Definitions for abstract types should not be included in the general FeatureCollection.
D.5. Base schemas
Another aspect is which base schema to use for the collections. GeoJSON and JSON-FG both define schemas for feature collections (see https://geojson.org/schema/FeatureCollection.json and https://github.com/opengeospatial/ogc-feat-geo-json/blob/main/core/schemas/featurecollection.json). These schemas should be used as base in according encodings. For the plain JSON encoding, a simple JSON array could be used.
D.6. Requirements classes
Requirements for the generation of collections could be defined in the three encoding requirements classes. However, it may be better to create additional requirements classes that depend on them, since communities may want to create different schema definitions for collections. It would even be possible to have separate requirements classes for uniform collections and the general collection, since communities may or may not want to use both types of collections.
Annex E
(informative)
Revision History
Table E.1
Date | Release | Editor | Primary clauses modified | Description |
---|---|---|---|---|
2022-12-13 | 0.1 | Johannes Echterhoff | all | initial version for internal review |
2024-04-25 | 0.2 | Johannes Echterhoff | all | solving a number of issues |
Bibliography
[1] Johannes Echterhoff: OGC 20-012, UML-to-GML Application Schema Pilot (UGAS-2020) Engineering Report. Open Geospatial Consortium (2021). https://docs.ogc.org/per/20-012.html.
[2] Clemens Portele: OGC 07-036r1, OpenGIS Geography Markup Language (GML) Encoding Standard — with corrigendum. Open Geospatial Consortium (2018). https://portal.ogc.org/files/?artifact id=74183&version=2.
[3] Open Geospatial Consortium (OGC). OGC 23-058r1: OGC API — Features — Part 5: Schemas Implementation Specification