Draft

OGC Standard

OGC SensorThings API 2.0
Hylke van der Schaaf Editor Steve Liang Editor
Version: 0.1
Additional Formats: XML PDF DOC
OGC Standard

Draft

Document number:23-019
Document type:OGC Standard
Document subtype:Implementation
Document stage:Draft
Document language:English

License Agreement

Use of this document is subject to the license agreement at https://www.ogc.org/license

Suggested additions, changes and comments on this document are welcome and encouraged. Such suggestions may be submitted using the online change request form on OGC web site: http://ogc.standardstracker.org/




I.  Abstract

<Insert Abstract Text here>

II.  Keywords

The following are keywords to be used by search engines and document catalogues.

ogcdoc, OGC document, API, OData, openapi, html, MQTT


III.  Preface

NOTE:    Insert Preface Text here. Give OGC specific commentary: describe the technical content, reason for document, history of the document and precursors, and plans for future work.

There are two ways to specify the Preface: “simple clause” or “full clasuse”

If the Preface does not contain subclauses, it is considered a simple preface clause. This one is entered as text after the .Preface label and must be placed between the AsciiDoc document attributes and the first AsciiDoc section title. It should not be give a section title of its own.

If the Preface contains subclauses, it needs to be encoded as a full preface clause. This one is recognized as a full Metanorma AsciiDoc section with te title “Preface”, i.e. == Preface. (Simple preface content can also be encoded like full preface.)

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

V.  Submitting Organizations

The following organizations submitted this Document to the Open Geospatial Consortium (OGC):

  • Fraunhofer-Gesellschaft, Germany
  • University of Calgary, Canada
  • SensorUp Inc., Canada
  • Keys, USA
  • DataCove e.U., Austria
  • Secure Dimensions, Germany
  • CREAF, Spain

1.  Scope

NOTE:    Insert Scope text here. Give the subject of the document and the aspects of that scope covered by the document.

2.  Conformance

This standard defines XXXX.

Requirements for N standardization target types are considered:

  • AAAA

  • BBBB

Conformance with this standard shall be checked using all the relevant tests specified in Annex A (normative) of this document. The framework, concepts, and methodology for testing, and the criteria to be achieved to claim conformance are specified in the OGC Compliance Testing Policies and Procedures and the OGC Compliance Testing web site.

In order to conform to this OGC® interface standard, a software implementation shall choose to implement:

  • Any one of the conformance levels specified in Annex A (normative).

  • Any one of the Distributed Computing Platform profiles specified in Annexes TBD through TBD (normative).

All requirements-classes and conformance-classes described in this document are owned by the standard(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.

Identification of Common Molecular Subsequences. Smith, T.F., Waterman, M.S., J. Mol. Biol. 147, 195–197 (1981)

ZIB Structure Prediction Pipeline: Composing a Complex Biological Workflow through Web Services. May, P., Ehrlich, H.C., Steinke, T. In: Nagel, W.E., Walter, W.V., Lehner, W. (eds.) Euro-Par 2006. LNCS, vol. 4128, pp. 1148–1158. Springer, Heidelberg (2006)

The Grid: Blueprint for a New Computing Infrastructure., Foster, I., Kesselman, C.. Morgan Kaufmann, San Francisco (1999).

Grid Information Services for Distributed Resource Sharing. Czajkowski, K., Fitzgerald, S., Foster, I., Kesselman, C. In: 10th IEEE International Symposium on High Performance Distributed Computing, pp. 181–184. IEEE Press, New York (2001)

The Physiology of the Grid: an Open Grid Services Architecture for Distributed Systems Integration. Foster, I., Kesselman, C., Nick, J., Tuecke, S. Technical report, Global Grid Forum (2002)

National Center for Biotechnology Information, http://www.ncbi.nlm.nih.gov

ISO: ISO 19101-1:2014, Geographic information — Reference model — Part 1: Fundamentals. International Organization for Standardization, Geneva (2014). https://www.iso.org/standard/59164.html.

ISO: ISO 19115-1:2014, Geographic information — Metadata — Part 1: Fundamentals. International Organization for Standardization, Geneva (2014). https://www.iso.org/standard/53798.html.

ISO: ISO 19157:2013, Geographic information  — Data quality. International Organization for Standardization, Geneva (2013). https://www.iso.org/standard/32575.html.

ISO: ISO 19139:2007, Geographic information — Metadata — XML schema implementation. ISO (2007).

ISO: ISO 19115-3, Geographic information — Metadata — Part 3: XML schema implementation for fundamental concepts. International Organization for Standardization, Geneva https://www.iso.org/standard/80874.html.

Joan Masó and Lucy Bastin: OGC 15-097r1, OGC® Geospatial User Feedback Standard: Conceptual Model. Open Geospatial Consortium (2016). http://www.opengis.net/doc/IS/guf-conceptual/1.0.0.

Gerhard Gröger, Thomas H. Kolbe, Claus Nagel, Karl-Heinz Häfele: OGC 12-019, OGC City Geography Markup Language (CityGML) Encoding Standard. Open Geospatial Consortium (2012). http://www.opengis.net/spec/citygml/2.0.

Jiyeong Lee, Ki-Joune Li, Sisi Zlatanova, Thomas H. Kolbe, Claus Nagel, Thomas Becker: OGC 14-005r3, OGC® IndoorGML. Open Geospatial Consortium (2014). http://www.opengis.net/doc/IS/indoorgml/1.0.0.

Arliss Whiteside Jim Greenwood: OGC 06-121r9, OGC Web Service Common Implementation Specification. Open Geospatial Consortium (2010).

4.  Terms and definitions

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.

This document uses the terms defined in Sub-clause 5.3 of [OGC06-121r9], 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 standard.

For the purposes of this document, the following additional terms and definitions apply.

term used for exemplary purposes

Note 1 to entry: An example note.

Example

Here’s an example of an example term.

[SOURCE: ISO 19101-1:2014]

5.  Conventions

This sections 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.1.  Identifiers

The normative provisions in this standard are denoted by the URI

http://www.opengis.net/spec/sensorthings/2.0

All requirements and conformance tests that appear in this document are denoted by partial URIs which are relative to this base.

6.  SensorThings API overview

6.1.  Who should use the OGC SensorThings API

Organizations that need web-based platforms to manage, store, share, and analyze IoT-based sensor observation data should use the OGC SensorThings API. The OGC SensorThings API simplifies and accelerates the development of IoT applications. Application developers can use this open Standard to connect to various IoT devices and create innovative applications without worrying the daunting heterogeneous protocols of the different IoT devices, gateways and services. IoT device manufacturers can also use OGC SensorThings API as the API can be embedded within various IoT hardware and software platforms, so that the various IoT devices can effortlessly connect with the OGC Standard-compliant servers around the world. In summary, the OGC SensorThings API is transforming the numerous disjointed IoT systems into a fully connected platform where complex tasks can be synchronized and performed.

EDITORIAL NOTE

Add the many non-IoT uses!

6.2.  Benefits of the OGC SensorThings API

In today’s world, most IoT devices (e.g., sensors and actuators) have proprietary software interfaces defined by their manufacturers and used selectively. New APIs are often required and developed on an as-needed basis, often in an environment with resource limitations and associated risks. This situation requires significant investment on the part of developers for each new sensor or project involving multiple systems and on the part of the providers of sensors, gateways, and portals or services where observations and measurements are required.

As a standardized data model and interface for sensors in the WoT and IoT, the OGC SensorThings API offers the following benefits: (1) it permits the proliferation of new high value services with lower overhead of development and wider reach, (2) it lowers the risks, time and cost across a full IoT product cycle, and (3) it simplifies the connections between devices-to-devices and devices-to-applications.

6.3.  SensorThings API Overview

The OGC SensorThings API data model consists of three main parts: (1) the Sensing part, (2) the Sampling part and (3) the Tasking part. Additionally, SensorThings API supports the following two extensions to the data model: (1) the Sensing Extension (Observations & Measurements) and (2) the Relations extension

The Sensing part allows IoT devices and applications to CREATE, READ, UPDATE, and DELETE (i.e., HTTP POST, GET, PATCH, and DELETE) IoT data and metadata in a SensorThings service. The Sensing part is designed based on the OGC/ISO Observation, Measurements and Samples (OMS) model [OGC 20-004r3 and ISO 19156:2023]. An Observation is modeled as an act that produces a result whose value is an estimate of a property of a given Feature. An Observation instance is characterized by its event time (e.g., resultTime and phenonmenonTime), Feature, ObservedProperty, and the procedure used (often a Sensor). Moreover, Things are also modeled in the SensorThings API. A Thing draws from the same concept as a Host in OMS where a Host is defined as a collection of Observers (defined as Sensor in SensorThings API). Formally, its definition follows the ITU-T definition: “an object of the physical world (physical things) or the information world (virtual things) that is capable of being identified and integrated into communication networks” [ITU-T Y.2060]. The geographical Locations of Things are useful in almost every application and as a result are included as well. For the Things whose location changed, the HistoricalLocations entities offer the history of the Thing’s locations. A Thing also can have multiple Datastreams. A Datastream is a collection of Observations grouped by the same ObservedProperty, Sensor and optionally by Feature and ObservingProcedure. An Observation is an event performed by a Sensor that produces a result whose value is an estimate of an ObservedProperty of any given Feature which may be a proximate or ultimate FeatureofInterest. Details of each above described entity are provided in Clause 7.

The Sampling part is a new addition to the SensorThings API. As is often the case, an Observation may not be a true representation of the intended Feature’s Property that an Observer may be trying to Observe. Sampling is a common strategy to understand the characteristics of an otherwise difficult-to-measure Property of any feature-of-interest. Samples are created by a Sampler, that may be a physical device or a human being. The method used to execute a Sampling may be described by a SamplingProcedure. This SamplingProcedure can be used by multiple Samplers and conversely, a Sampler may implement multiple SamplingProcedures. However, any Sampling that is executed by a Sampler is always associated with a unique SamplingProcedure. In addition, various preparation steps may be performed on samples both before and after observations are performed on the sample. The entities are explained in detail in [sampling-extension].

The Tasking part provides a standard way for parameterizing — also called tasking — of taskable IoT devices, such as individual sensors and actuators, composite consumer / commercial / industrial / smart cities in-situ platforms, mobile and wearable devices, or even unmanned systems platforms such as drones, satellites, connected and autonomous vehicles, etc. A Task defines a control action executed by an Actuator. Actuator is modeled to describe a device that is equipped with Tasking Capabilities. A TaskingCapability characterizes an Actuator’s (or in some cases, a Thing’s) ability to trigger a change in ActuableProperties of any FeatureOfInterest by executing the given Task. The Tasking Data Model thus mirrors the Sensing Data Model. Each of these entities are elaborated further in [actuation-extension].

The [sensing-OM-extension] and [relations-extension] are optional extensions to the data model that may be used for extended data modelling requirements.

6.4.  SensorThings API and Relation to ISO/OGC Observations, Measurements and Samples

Managing and retrieving observations and metadata from IoT sensor systems is one of the most common use cases. As a result, SensorThings API’s sensing part is designed based on the OMS model. OMS defines models for the exchange of information describing observation acts, their results as well as the feature involved in sampling when making observations.

SensorThings API defines nine entities for the IoT sensing applications and several additional entities in various extensions. base lists each component and its relationship with OMS. SensorThings API uses the term of Sensor to describe the Observer that is used in generating an Observation, instead of using OMS’ term of Observer.

Table 1 — SensorThings API Sensing entities and equivalent concepts in OMS 3.0

SensorThings API Entities
OMS 3.0 Concepts
Thing
Host
Datastream
ObservationCollection
Sensor
Observer
Observation
Observation
ObservedProperty
Observed Property
Feature
Feature
Deployment (OM Extension)
Deployment
ObservingProcedure (OM Extension)
Observing Procedure
Sample (Sampling Extension)
Sample
Sampling (Sampling Extension)
Sampling
SamplingProcedure (Sampling Extension)
Sampling Procedure
PreparationProcedure (Sampling Extension)
Preparation Procedure
PreparationStep (Sampling Extension)
Preparation Step

6.5.  SensorThings API 2.0 changes from 1.1

From the SensorThings API version 1.1 to 2.0 changes have been made to both the data model and the API. The changes to the data model have been summarised in Table 2 and Figure 1.

Table 2 — Changes in the SensorThings API 2.0 data model compared to v1.1

EntityChanges
Sensor
  • description attribute is now optional and not mandatory

  • definition attribute added

Thing
  • description attribute is now optional and not mandatory

  • definition attribute added

Location
  • description attribute is now optional and not mandatory

  • For a Thing having multiple Locations, these Locations MAY be in same encodingTypes OR the encodingTypes MAY be be in different spaces (e.g., one encodingType in Geometrical space and one encodingType in Topological space).

  • definition attribute added

Datastream
  • description attribute is now optional and not mandatory

  • resultType replaces the observationType attribute, this eliminates MultiDatastream entity

  • unitOfMeasurement SHALL be embedded within the observedType attribute and does not exist as an independent attribute within the Datastream entity

  • A Datastream can link to multiple ObservedProperties which was only possible with MultiDatastream entity earlier. The SWE-Common based resultType attribute eliminates the need for having a separate MultiDatastream entity

  • A Datastream can now be linked to the Feature it observes as an optional link, named UltimateFeatureOfInterest, between Datastream and Feature is introduced

  • definition attribute added

ObservedProperty

description attribute is now optional and not mandatory

Observation
  • properties replaces the parameters attribute.

  • An Observation may or may not link to any Feature in contrast to the mandatory link between Observation and FeatureOfInterest from v1.x.

  • resultTime is now optional and can be left out completely, instead of defaulting to a null value.

Feature
  • The Feature entity replaces the FeatureOfInterest entity from 1.x as it now takes the role of UltimateFeatureOfInterest or ProximateFeatureOfInterest depending upon the context and links with Observation and Datastream entities

  • definition attribute added

FeatureType

The FeatureType entity is added, and makes it easier to handle type information for Features

Sensing Core Changes

Figure 1 — Sensing Core Changes

6.6.  Relation to OASIS-OData

OData is an API standard for exchanging relational data. It allows for the definition of a consistent REST API on any relational data model. OData specifies how clients can inspect the data model and how they can perform Create, Read, Update and Delete actions. OData comes with a very powerful query language that allows users to compose the response to queries such that only a minimal number of queries is required to fetch needed data, regardless of the use case of the client. The OData specification also defines filtering mechanisms that allows filtering across relations. OData uses JSON-encoding by default, and specifies generic rules for encoding relational data models in JSON.

The OGC SensorThings API v2 interface is not an OData interface and does not claim to be an OData service. It specifies a subset of the OData 4.01 interface, and extends it at the same time. A SensorThings API Server implementation can implement the full OData specification. An OData client can access a SensorThings API service.

EDITORIAL NOTE

Check if this is true

7.  The SensorThings API Core Data Model

All data model requirements classes are grouped in the following requirements class:

Requirements class 1: Sensing Entities

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirements class 2: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/thing
Requirements class 3: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/location
Requirements class 4: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/historical-location
Requirements class 5: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/datastream
Requirements class 6: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/sensor
Requirements class 7: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observed-property
Requirements class 8: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observation
Requirements class 9: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature

The OGC SensorThings API v2.0 depicts the Core Sensing entities in Figure 2

Sensing Core

Figure 2 — Sensing Core

In this section, we define each entity depicted in Figure 2 and its relationships with other entities. Additionally, we also provide examples to model the entities in different contexts.

7.1.  Recurring attributes

Several attributes are used in several classes. They always have the same semantic meaning, regarless of the class they are used in.

id

The primary key of the class. An Entity is uniquely identified, among Entities of the same class and in the same service, by its id value. The data type of the id attribute may vary between services, or even between classes in the same service, but must be the same for all Entities of the same class in the same service. In most cases the value of the id attribute of an Entity will be generated by the service when the Entity is created, but a service may allow users to specify a value.

name

The name of an Entity is a (short) character string that describes the Entity. It does not need to be unique among entities of the same type, though, when two entities of the same type have the same name, there should be another distinguishing attribute. Two Things with the same name are likely to cause confusion, but two Datastreams with the same name are generally acceptable, as long as these Datastreams are associated to different Things.

description

The description of an Entity is a longer, human readable, character string giving a descriptive text of the Entity.

definition

The definition of an Entity is a unique external identifier, linking the Entity to an external, autorative source. The definition allows for different services to represent different aspects of the same systems. It can, for instance, be a URL to a feature in an OGC API — Features service, or a DID pointing to a crytographically signed resource.

properties

A set of user-defined named values. The values may be of any type, including nested arrays or name-value sets. In the default JSON encoding the properties attribute is a JSON-Object.

7.2.  Thing

Requirements class 2: Class Thing

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/thing
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 1: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/thing/attributes
Requirement 2: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/thing/relations

The SensorThings API follows the ITU-T definition, i.e., with regard to the Internet of Things, a thing is an object of the physical world (physical things) or the information world (virtual things) that is capable of being identified and integrated into communication networks [ITU-T Y.2060]. A Thing is related to the Platform entity as described in Section 4.9.2.1 of [OGC 16-079] in a way that any entity that can be modelled as a Thing MAY be subsequently translated to a Platform and vice versa.

Thing Examples

  • A weather station that houses a varying set of environmental sensors

  • A drone that mounts a LiDAR sensor for mapping purposes

  • A science vessel that has many sensors installed

  • An upstream oil well that is equipped with compound gas detection devices

Requirement 1

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/thing/attributes
Included inRequirements class 2: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/thing
Statement

Each Thing entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 3.

Table 3 — Attributes of a Thing entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for Thing entity, commonly a descriptive name.

String

1

definition

The URI linking the Thing to an external definition. Dereferencing this URI SHOULD result in a representation of the definition of the Thing.

URI

0..1

description

This is a short description of the corresponding Thing entity.

String

0..1

properties

A JSON Object containing user-annotated properties.

JSON Object

0..1

Requirement 2

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/thing/relations
Included inRequirements class 2: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/thing
Statement

Each Thing entity SHALL have the direct relation between a Thing entity and other entity types listed in Table 4.

Table 4 — Direct relation between a Thing entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Location

The Location entity locates the Thing. Multiple Things MAY be located at the same Location. A Thing MAY not have a Location.

A Thing SHOULD have only one physical location, but this location may be described in different ways, using different representations. In such case, the Thing MAY have more than one Locations.

Location

0..1

HistoricalLocations

A Thing has zero-to-many HistoricalLocations. A HistoricalLocation has one-and-only-one Thing.

HistoricalLocation

0..*

Datastreams

A Thing MAY have zero-to-many Datastreams.

Datastream

0..*
{
 
"@context": "https://example.org/v2.0/$metadata#Things/$entity",
 
"@id": "Things(1)",
 
"id": 1,
 
"name": "Oven",
 
"description": "This thing is an oven.",
 
"properties": {
   
"owner": "Ulrike Schmidt",
   
"color": "Black"
 
},
 
"Locations@navigationLink": "Things(1)/Locations",
 
"Datastreams@navigationLink": "Things(1)/Datastreams",
 
"HistoricalLocations@navigationLink": "Things(1)/HistoricalLocations"
}

Listing 1 — Example of a Thing entity returned by a HTTP end point.

7.3.  Location

Requirements class 3: Class Location

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/location
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 3: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/location/attributes
Requirement 4: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/location/relations

The Location entity geo-locates the Thing or the Things it associated with. A Thing’s Location entity is defined as the last known location of the Thing.

The Feature can be either a proximate feature of interest or the ultimate feature of interest depending upon the context of the Observation. For in-situ sensing applications, the Location MAY describe the coordinates of where the Thing is located. The Feature is the entity for which the value of a property was determined by the Sensor. The ObservedProperty in this case MAY characterize only the area around the sensing device or it MAY characterize the larger observedArea that the sensing application intends to capture. Thus, depending upon the feature-of-interest, the Feature can then be either a ProximateFeatureOfInterest or UltimateFeatureOfInterest. For ex-situ sensing applications, the Location MAY describe the coordinates of where the Thing is located, whereas the feature MAY be the point location of the observed Feature.

EDITORIAL NOTE

Explain all 4 possible options? in-situ, local; in-site, remote; ex-situ, local; ex-situ, remote

Section 7.1.4 of [OGC 20-082r4 and ISO 19156:2023] provides a detailed explanation of observation location.

Location Examples

  • An air quality sensing facility’s Location can be the physical location where the facility is situated, but the (proximate) Feature that is characterized by the Observation could be the air envelope around the Sensor which is subsequently used to estimate the air quality of the district where the facility is situated.

  • A drone that mounts a LiDAR Sensor may have its Location as the geo-referenced area over which the drone is scheduled to fly, whereas the Feature could be the individual objects mapped by the Sensor within that geo-referenced area

Requirement 3

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/location/attributes
Included inRequirements class 3: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/location
Statement

Each Location entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 5.

Table 5 — Attributes of a Location entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for Location entity, commonly a descriptive name.

String

1

encodingType

The encoding type of the Location property. (see Table 7 for some suggested ValueCodes)

String

1

location

The identifiable location of the Thing

ANY

1

description

The description about the Location

String

0..1

properties

A JSON Object containing user-annotated properties.

JSON Object

0..1

Requirement 4

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/location/relations
Included inRequirements class 3: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/location
Statement

Each Location entity SHALL have the direct relation between a Location entity and other entity types listed in Table 6.

Table 6 — Direct relation between a Location entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Things

The Things located at the source Location. Multiple Things MAY locate at the same Location.

Thing

0..*

HistoricalLocations

The HistoricalLocations of things that have been located at this Location.

HistoricalLocation

0..*

Table 7 — Non-exhaustive list of code values used for identifying types for the encodingType of the Location and Feature entities

encodingTypeValueCode Value
GeoJSONapplication/geo+json
GeoPoseapplication/geopose+json
WKTtext/plain

EDITORIAL NOTE

Add example for wkt, jsonFG

{
 
"@context": "https://example.org/v2.0/$metadata#Locations/$entity",
 
"@id": "Locations(1)",
 
"id": 1,
 
"name": "CCIT",
 
"description": "Calgary Center for Innvative Technologies",
 
"encodingType": "application/geo+json",
 
"location": {
   
"type": "Feature",
   
"geometry":{
     
"type": "Point",
     
"coordinates": [-114.06,51.05]
   
}
 
},
 
"Things@navigationLink": "Locations(1)/Things",
 
"HistoricalLocations@navigationLink": "Locations(1)/HistoricalLocations",
}

Listing 2 — Example of a Location entity using a GeoJSON Feature.

{
 
"@context": "https://example.org/v2.0/$metadata#Locations/$entity",
 
"@id": "Locations(2)",
 
"id": 2,
 
"name": "IOSB",
 
"description": "Fraunhofer-Institut für Optronik, Systemtechnik und Bildauswertung IOSB",
 
"encodingType": "application/geo+json",
 
"location": {
   
"type": "Point",
   
"coordinates": [8.426, 49.015]
 
},
 
"Things@navigationLink": "Locations(2)/Things",
 
"HistoricalLocations@navigationLink": "Locations(2)/HistoricalLocations",
}

Listing 3 — Example of a Location entity using a GeoJSON Geometry.

NOTE:    When using a GeoJSON encoding for the location attribute, the value can either be a GeoJSON Feature or a GeoJSON Geometry.

7.4.  HistoricalLocation

Requirements class 4: Class HistoricalLocation

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/historical-location
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 5: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/attributes
Requirement 6: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/relations
Requirement 7: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/create-update-delete/historical-location-auto-creation
Requirement 8: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/create-update-delete/historical-location-manual-creation

A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and previous locations of the Thing. It can be used to model the path observed by a moving Thing.

HistoricalLocation Examples

  • A drone that measures methane leaks over a large basin may want to record the trajectory through which it flies. HistoricalLocation should then record the individual Locations of the drone over time

Requirement 5

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/attributes
Included inRequirements class 4: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/historical-location
Statement

Each HistoricalLocation entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 8.

Requirement 6

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/relations
Included inRequirements class 4: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/historical-location
Statement

Each HistoricalLocation entity SHALL have the direct relation between a HistoricalLocation entity and other entity types listed in Table 9.

Requirement 7

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/create-update-delete/historical-location-auto-creation
Included inRequirements class 4: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/historical-location
Statement

When a Thing has a new Location, a new HistoricalLocation SHALL be created and added to the Thing automatically by the service. The current Location of the Thing SHALL only be added to this autogenerated HistoricalLocation automatically by the service, and SHALL not be created as HistoricalLocation directly by user.

The HistoricalLocation can also be created, updated and deleted. One use case is to migrate historical observation data from an existing observation data management system to a SensorThings API system. Another use case is to track the Location of a Thing, when a permanent network connection is not available. If the Location of a Thing is changed at a later time, when a network connection is available again, then the auto-generated Time of the HistoricalLocation entity would not reflect the time when the Thing was actually at the set Location, but only the time at which the change was sent to the server. To resolve this, the Location of a Thing can also be changed by adding a HistoricalLocation. If the time of a manually created HistoricalLocation is later than the time of all existing HistoricalLocations, then the Location of the Thing is updated to the Location of this manually created HistoricalLocation.

Requirement 8

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/historical-location/create-update-delete/historical-location-manual-creation
Included inRequirements class 4: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/historical-location
Statement

When a user directly adds new HistoricalLocation, and the time of this new HistoricalLocation is later than the latest HistoricalLocation for the Thing, then the Locations of the Thing are changed to the Locations of this new HistoricalLocation.

Table 8 — Attributes of a HistoricalLocation entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

time

The time when the Thing is known at the Location.

TM_Instant

1

Table 9 — Direct relation between a HistoricalLocation entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Locations

The Locations for this HistoricalLocation. One HistoricalLocation SHALL have at least one Location.

Location

1..*

Thing

The Thing this HistoricalLocation positions in time. A HistoricalLocation has exactly one Thing.

Thing

1
{
 
"@context": "https://example.org/v2.0/$metadata#HistoricalLocations/$entity",
 
"@id": "HistoricalLocations(1)",
 
"id": 1,
 
"time": "2020-03-20T16:35:23.383586Z",
 
"Thing@navigationLink": "HistoricalLocations(1)/Thing",
 
"Locations@navigationLink": "HistoricalLocations(1)/Locations"
}

Listing 4 — Example of a HistoricalLocation entity returned by a HTTP end point.

7.5.  Datastream

Requirements class 5: Class Datastream

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/datastream
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 9: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/datastream/attributes
Requirement 10: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/datastream/relations

A Datastream groups a collection of Observations into a time series measuring the same ObservedProperty by the same Sensor for the same Feature for the same Thing.

EDITORIAL NOTE

Note something about the SWE-Common Datastream class

Datastream Examples

  • An air quality monitoring station may have multiple Datastreams each recording a specific pollutant measured by the sensors

  • A sensor that measures multiple ObservedProperties can generate a single Datastream of composite resultTypes

Requirement 9

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/datastream/attributes
Included inRequirements class 5: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/datastream
Statement

Each Datastream entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 10.

Requirement 10

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/datastream/relations
Included inRequirements class 5: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/datastream
Statement

Each Datastream entity SHALL have the direct relation between a Datastream entity and other entity types listed in Table 11.

Table 10 — Attributes of a Datastream entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for Datastream entity, commonly a descriptive name.

String

1

description

The description of the Datastream entity.

String

0..1

resultType

The formal description of the result field of the Observations in this Datastream. Contains the unit of measurement.

JSON Object (SWE-Common AbstractDataComponent)

1

observedArea

The spatial bounding box of the spatial extent of the Feature that belong to the Observations associated with this Datastream. This is usually generated by the server.

Geometry

0..1

phenomenonTime

The temporal interval of the phenomenon times of all observations belonging to this Datastream. This is usually generated by the server.

TM_Period

0..1

resultTime

The temporal interval of the result times of all observations belonging to this Datastream. This is usually generated by the server.

TM_Period

0..1

properties

A JSON Object containing user-annotated properties.

JSON Object

0..1

TM_Period is by default encoded as a complex type with a start (mandatory) and end (mandatory) attributes of type TM_Instant.

Table 11 — Direct relation between a Datastream entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Thing

The Thing this Datastream holds Observations for.

Thing

1

Sensor

The Sensor that made the Observations in this Datastream.

Sensor

1

ObservedProperty

The ObservedProperty of the Observations in this Datastream. The Observations in a Datastream may hold values for multiple ObservedProperties, but the ObservedProperties are the same for all Observations in the same Datastream. See resultType for the details on the encoding of results.

ObservedProperty

1..*

Observations

The Observations for a Datastream.

Observation

0..*

UltimateFeatureOfInterest

The Feature has the role UltimateFeatureOfInterest so that all the Observations in a Datastream pertain only to the same linked Feature

Feature

0..1

The resultType defines the result types for specialized single and multi observations based on the JSON encoding of the SWE Common Data Model [OGC 08-094r1 and OGC 17-011r2]. The result of an Observation may be a single simple number or String, or it may contain a complex JSON structure holding multiple values for multiple ObservedProperties. The exact definition for this result structure, and which unit of measurement and which ObservedProperty pertains to each value in the result structure is exactly described by this resultType Object.

{
 
"name": "Oven temperature",
 
"description": "This is a datastream measuring the air temperature in an oven.",
 
"resultType": {
   
"type": "Quantity",
   
"definition": "http://mmisw.org/ont/cf/parameter/air_temperature",
   
"uom": { "code": "Cel", "label": "degree Celsius", "symbol": "°C" }
 
}
}

Listing 5 — A Datastream example measuring a scalar Observation

{
 
"result": 25.1,
 
"phenomenonTime":  {
   
"start": "2021-13-14T15:16:00Z"
 
}
}

Listing 6 — An Observation for the Datastream defined in the example above

{
 
"name": "Sample Datings",
 
"description": "This is a datastream containing the geological datings of rock samples.",
 
"resultType": {
   
"type": "Category",
   
"definition": "http://sweet.jpl.nasa.gov/2.0/timeGeologic.owl#GeologicTime",
   
"codeSpace": "http://sweet.jpl.nasa.gov/2.0/timeGeologic.owl#Era"
 
}
}

Listing 7 — A Datastream example for Observations with category values from a predefined code space

{
 
"result": "Jurassic",
 
"phenomenonTime":  {
   
"start": "2021-13-14T15:16:00Z"
 
}
}

Listing 8 — An Observation for a Datastream defined in the example above

{
 
"name": "Temperature and Pressure",
 
"description": "This is a datastream containing temperature and pressure measurement sets.",
 
"resultType": {
   
"type": "DataRecord",
   
"name": "Measurement set",
   
"fields": [
     
{
       
"name": "temp",
       
"type": "Quantity",
       
"definition": "http://mmisw.org/ont/cf/parameter/air_temperature",
       
"label": "Air Temperature",
       
"uom": { "code": "Cel", "label": "degree Celsius", "symbol": "°C"  }
     
},
     
{
       
"name": "press",
       
"type": "Quantity",
       
"definition": "http://mmisw.org/ont/cf/parameter/air_pressure_at_mean_sea_level",
       
"label": "Air Pressure",
       
"uom": { "code": "mbar", "label": "Millibar", "symbol": "mBar"  }
     
}
   
]
 
}
}

Listing 9 — A Datastream example measuring multiple observedProperties

{
 
"result": {
   
"temp": 15,
   
"press": 1024
 
},
 
"phenomenonTime": {
   
"start": "2021-13-14T15:16:00Z"
 
}
}

Listing 10 — An Observation for a Datastream defined in the example above

EDITORIAL NOTE

Discuss the phenomenonTime examples above

7.6.  Sensor

Requirements class 6: Class Sensor

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/sensor
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 11: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/sensor/attributes
Requirement 12: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/sensor/relations

A Sensor is an instrument that observes a property or phenomenon with the goal of producing an estimate of the value of the property

Requirement 11

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/sensor/attributes
Included inRequirements class 6: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/sensor
Statement

Each Sensor entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 12.

Requirement 12

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/sensor/relations
Included inRequirements class 6: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/sensor
Statement

Each Sensor entity SHALL have the direct relation between a Sensor entity and other entity types listed in Table 13.

Table 12 — Attributes of a Sensor entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for Sensor entity, commonly a descriptive name.

String

1

description

The description of the Sensor entity.

String

0..1

encodingType

The encoding type of the metadata property. Its value is one of the ValueCode enumeration (see Table 14 for some suggested ValueCodes)

ValueCode

1

metadata

The detailed description of the Sensor or system. The metadata type is defined by encodingType.

String

1

properties

A JSON Object containing user-annotated properties as key-value pairs

JSON Object

0..1

Table 13 — Direct relation between a Sensor entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Datastreams

The Datastreams that hold Observations produced by this Sensor.

Datastream

0..*

Table 14 — Non-exhaustive list of code values used for identifying types for the encodingType of the Sensor entity

Sensor encodingTypeValueCode Value
PDFapplication/pdf
SensorMLhttp://www.opengis.net/doc/IS/SensorML/2.0
HTMLtext/html

The Sensor encodingType allows clients to know how to interpret the metadata value. Currently SensorThings API defines two common Sensor metadata encodingTypes. Most sensor manufacturers provide their sensor datasheets in a PDF format. As a result, PDF is a Sensor encodingType supported by SensorThings API. The second Sensor encodingType is SensorML. Lastly, some sensor datasheets are HTML documents rather than PDFs. Other encodingTypes are permitted (e.g., text/plain). Note that the metadata property may contain either a URL to metadata content (e.g., an https://, ftp://, etc. link to a PDF, SensorML, or HTML document) or the metadata content itself (in the case of text/plain or other encodingTypes that can be represented as valid JSON). It is up to clients to perform string parsing necessary to properly handle metadata content.

{
 
"@context": "https://example.org/v2.0/$metadata#Sensors/$entity",
 
"@id": "Sensors(1)",
 
"id": 1,
 
"name": "TMP36",
 
"description": "TMP36 - Analog Temperature sensor",
 
"encodingType": "application/pdf",
 
"metadata": "http://example.org/TMP35_36_37.pdf",
 
"Datastreams@navigationLink": "Sensors(1)/Datastreams"
}

Listing 11 — Example of a Sensor entity returned by a HTTP end point.

7.7.  ObservedProperty

Requirements class 7: Class ObservedProperty

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observed-property
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 13: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observed-property/attributes
Requirement 14: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observed-property/relations

An ObservedProperty is a property of a Feature that is being observed by a Sensor, such as temperature, humidity, population count or colour. It should be uniquely identified by its definition, which should point to an external vocabulary by means of a URL, URI or DID.

Requirement 13

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observed-property/attributes
Included inRequirements class 7: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observed-property
Statement

Each ObservedProperty entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 15.

Requirement 14

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observed-property/relations
Included inRequirements class 7: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observed-property
Statement

Each ObservedProperty entity SHALL have the direct relation between an ObservedProperty entity and other entity types listed in Table 16.

Table 15 — Attributes of an ObservedProperty entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for ObservedProperty entity, commonly a descriptive name.

String

1

definition

The URI of the ObservedProperty. Dereferencing this URI SHOULD result in a representation of the definition of the ObservedProperty

URI

1

description

A description about the ObservedProperty.

String

0..1

properties

A JSON Object containing user-annotated properties as key-value pairs

JSON Object

0..1

Table 16 — Direct relation between an ObservedProperty entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Datastreams

Datastreams that hold Observations that observed this ObservedProperty.

Datastream

0..*
{
 
"@context": "https://example.org/v2.0/$metadata#ObservedProperties/$entity",
 
"@id": "ObservedProperties(1)",
 
"id": 1,
 
"name": "DewPoint Temperature",
 
"description": "The dewpoint temperature is the temperature to which the
                  air must be cooled, at constant pressure, for dew to form.
                  As the grass and other objects near the ground cool to
                  the dewpoint, some of the water vapor in the atmosphere
                  condenses into liquid water on the objects."
,
 
"definition": "http://dbpedia.org/page/Dew_point",
 
"Datastreams@navigationLink": "ObservedProperties(1)/Datastreams"
}

Listing 12 — Example of an ObservedProperty entity returned by a HTTP end point.

7.8.  Observation

Requirements class 8: Class Observation

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observation
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 15: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observation/attributes
Requirement 16: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observation/relations

An Observation provides a value for an ObservedProperty of a Feature, as observed by a Sensor. This value can be of any type, as described by the resultType of the Datastream that Observation is associated with.

Requirement 15

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observation/attributes
Included inRequirements class 8: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observation
Statement

Each Observation entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 17.

Requirement 16

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/observation/relations
Included inRequirements class 8: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/observation
Statement

Each Observation entity SHALL have the direct relation between an Observation entity and other entity types listed in Table 18.

Table 17 — Attributes of an Observation entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

phenomenonTime

The time instant or period of when the Observation happens.

Note: Many resource-constrained sensing devices do not have a clock. As a result, a client may omit phenomenonTime when POST new Observations, even though phenomenonTime is a mandatory property. When a SensorThings service receives a POST Observations without phenomenonTime, the service SHALL assign the current server time to the value of the phenomenonTime

TM_Object

1

result

The estimated value of an ObservedProperty from the Observation.

ANY

1

resultTime

The time of the Observation’s result was generated

TM_Instant

0..1

validTime

The time period during which the result may be used

TM_Period

0..1

properties

A JSON Object containing user-annotated properties as key-value pairs (usually showing the environmental conditions during measurement)

JSON Object

0..1

TM_Object is by default encoded as a complex type with a start (mandatory) and end (optional) attributes of type TM_Instant. This means it can either describe a time instant, when only the start is present, or a time interval with both stand and end are present.

TM_Period is by default encoded as a complex type with a start (mandatory) and end (mandatory) attributes of type TM_Instant. This means it always describes a time interval with fixed starting and ending instants.

Table 18 — Direct relation between an Observation entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Datastream

The Datastream this Observation exists in.

Datastream

1

ProximateFeatureOfInterest

The Feature observed by the Observation.

Feature

0..1

An Observation can be directly linked to a Feature, through the relation ProximateFeatureOfInterest. Features linked to an Observation in this way are generally samples, either real, physical ones, like water samples taken from a river, or transient ones, to fix the place that a moving Thing happended to be in, when it made a measurement.

In case the Feature is a domain object, like a river, a building, or a plot of land, the Feature is indirectly linked to the Observation through the UltimateFeatureOfInterest relation on the Datastream. It is also possible for both relations to exist, in which case the ProximateFeatureOfInterest is a sample of the UltimateFeatureOfInterest.

A third case is possible, when the target of the observation is (a sub-part of) the Thing itself. For instance, when the Observation is on the battery-level of a drone. In this case neither the ProximateFeatureOfInterest, nor the UltimateFeatureOfInterest need to be set.

{
 
"@context": "https://example.org/v2.0/$metadata#Observations/$entity",
 
"@id": "Observations(1)",
 
"id": 1,
 
"phenomenonTime": {
   
"start": "2017-11-12T13:00:00Z",
   
"end": "2017-11-12T14:00:00Z"
 
},
 
"resultTime": "2017-11-12T14:00:00Z",
 
"result": 12.5,
 
"Datastream@navigationLink": "Observations(1)/Datastream",
 
"proximateFeatureOfInterest@navigationLink": "Observations(1)/proximateFeatureOfInterest"
}

Listing 13 — Example of an Observation entity returned by a HTTP end point.

7.9.  Feature

Requirements class 9: Class Feature

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 17: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature/attributes
Requirement 18: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature/relations

An Observation assigns a value to a property of a subject by applying an ObservingProcedure. The subject is the Feature that can take the role of ProximateFeatureOfInterest or ultimateFeatureOfInterest of the Observation [OGC 20-082r4 and ISO 19156:2023]. In cases where estimating the value of a property of interest is not possible directly, a proxy feature MAY be used. Such an application typically requires Sampling the UltimateFeatureOfInterest such that the observed Feature represents an approximation of the domain feature. In many sensing applications, the Observations’ Feature can be ambiguous with the Location of the Thing. Thus the concept of roles is introduced to better describe the relationship between an Observation and it’s Feature.

Feature Examples

  • The Feature of a WiFi enabled thermostat can be the Location of the thermostat (i.e., the living room where the thermostat is located in). However, in such cases, it is recommended to use the Location entity to store this information while the Feature entity (with the role of proximateFeatureOfInterest) can be used to model the ambient indoor atmosphere around the thermostat that approximates the overall room’s temperature.

  • In the case of remote sensing, the Feature observed can be the individual geographical parcel or swath that is being sensed, while the Location entity can maintain the larger geographical region that is being monitored.

Requirement 17

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature/attributes
Included inRequirements class 9: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature
Statement

Each Feature entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 19.

Requirement 18

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature/relations
Included inRequirements class 9: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature
Statement

Each Feature entity SHALL have the direct relation between a Feature entity and other entity types listed in Table 20.

Table 19 — Attributes of a Feature entity

NameDefinitionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for Feature entity, commonly a descriptive name.

String

1

description

The description about the Feature

String

0..1

encodingType

The encoding type of the feature property. (see Table 7 for some suggested ValueCodes)

String

1

feature

The detailed description of the feature. The data type is defined by encodingType.

ANY

0..1

properties

A JSON Object containing user-annotated properties as key-value pairs

JSON Object

0..1

Table 20 — Direct relation between a Feature entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Observations

All Observations that are made on this Feature

Observation

0..*

Datastreams

All Datastreams that contain Observations relevant for this Feature.

Datastream

0..*
{
 
"@context": "https://example.org/v2.0/$metadata#Features/$entity",
 
"@id": "Features(1)",
 
"id": 1,
 
"name": "0113700020130227",
 
"description": "Water Sample from LA NOYE À DOMMARTIN (80) taken on 2013-02-27 at 10:20:00",
 
"encodingType": "application/geo+json",
 
"feature": {
   
"type": "Point",
   
"coordinates": [
     
2.38961955,
     
49.800951554
   
]
 
},
 
"FeatureType@navigationLink": "FeaturesOfInterest(1)/FeatureType",
 
"Datastreams@navigationLink": "FeaturesOfInterest(1)/Datastreams",
 
"Observations@navigationLink": "FeaturesOfInterest(1)/Observations"
}

Listing 14 — Example of a Feature entity using a GeoJSON Geometry.

EDITORIAL NOTE

Add non-GeoJSON examples!

7.10.  FeatureType

Requirements class 10: Class FeatureType

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature-type
Obligationrequirement
Target typeTarget Type: Data Model
Normative statementsRequirement 19: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature-type/attributes
Requirement 20: http://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature-type/relations

The type or types of each Feature can be specified using the FeatureType class. The definition attribute of the FeatureType should point to an external registry or code list, that defines the Type.

Requirement 19

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature-type/attributes
Included inRequirements class 10: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature-type
Statement

Each FeatureType entity SHALL have the mandatory attributes and MAY have the optional attributes listed in Table 21.

Requirement 20

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req/datamodel/sensing/feature-type/relations
Included inRequirements class 10: http://www.opengis.net/spec/sensorthings/2.0/req-class/datamodel/sensing/feature-type
Statement

Each FeatureType entity SHALL have the direct relation between a FeatureType entity and other entity types listed in Table 22.

Table 21 — Attributes of a FeatureType entity

NameDescriptionData TypeMultiplicity

id

A unique, read-only attribute that serves as an identifier for the entity.

ANY

1

name

A property provides a label for Feature entity, commonly a descriptive name.

String

1

description

The description about the Feature

String

0..1

definition

The URI the defines this FeatureType. Dereferencing this URI SHOULD result in a representation of the definition of the FeatureType.

URI

0..1

properties

A JSON Object containing user-annotated properties as key-value pairs

JSON Object

0..1

Table 22 — Direct relation between a FeatureType entity and other entity types

RoleDescriptionTarget Entity TypeMultiplicity

Features

All Features of a FeatureType.

Feature

0..*
{
 
"@context": "https://example.org/v2.0/$metadata#FeatureType/$entity",
 
"@id": "FeatureType(1)",
 
"id": 1,
 
"name": "Water Sample",
 
"description": "A Sample taken from a river, lake or sea",
 
"definition": "https://example.org/water_sample",
 
"Features@navigationLink": "FeatureType(1)/Features"
}

Listing 15 — Example of a FeatureType entity.

8.  Abstract OData API

This section describes the abstract OData API. The abstract OData API can be implemented using various protocols, like HTTP or MQTT version 5.

Requirements class 11: Abstract API

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/api/abstract
Obligationrequirement
Target typeTarget Type: Abstract API
Normative statementRequirement 21: http://www.opengis.net/spec/sensorthings/2.0/req-class/api/abstract/csdl

8.1.  OData Entity Model

Every OData service utilizes an entity model which MAY be distributed over several schemas. The service describes this model through a metadata document accessible by a simple HTTP GET request to the <serviceRoot>/$metadata path. This chapter describes an overview of the types of entities in the metadata document that will be used to describe the SensorThings API data model and its data model extensions. The entities listed below are also used to describe the REST and MQTT bindings of the SensorThings API service.

This section is base on:

The entity model consists of the following elements:

  • Entity Type: named, structured, keyed element that defines the properties and relations of Entities. The key of an Entity Type consists of one or more primitive properties of the Entity Type.

  • Entity: instance of an Entity Type. An Entity can have only one Entity Type.

  • Primitive Type: unnamed, unstructured type, such as String, Integer or DateTime. The full list can be found at: https://docs.oasis-open.org/odata/odata-csdl-json/v4.01/odata-csdl-json-v4.01.html#sec_PrimitiveTypes

  • Complex Type: named, structured, keyless, element consisting of a set of named properties. Instances of Complex Types can not be accessed outside of the Entity they are contained in. A property with a Primitive Type is called a primitive property.

  • Relation: named connections between Entities. Relations defined as navigation properties in Entity Types. Relations have a cardinality.

  • Properties: named elements that are part of structured types (Entity Types and Complex Types). Properties can be Primitive-, Complex- or Navigation properties. Properties defined as part of a structured type (Entity/Complex Type) are declared properties. A structured type can allow properties that are added dynamically, as long as these dynamic properties do not have the same name as a declared property. Structured types that allow dynamic properties are called Open Types.

  • Entity Set: a named collection of Entities of the same Entity Type. Each Entity is uniquely identified among other Entities in the same Entity Set, by its key. Entity Sets are the entry points into the data model.

  • Annotation: additional information attached to model or instance elements. annotations can be identified by the @ character. If the annotation starts with the @ character, then the annotation pertains to the object containing the annotation. If the annotation has a property name before the @ charater, then the annotation pertains the property with that name. Annotations are server-generated additional information that a client can use when processing the data. A client can ignore any annotations it does not understand. The default annotations can be found in Table 23. Additional annotations may be defined in the service metadata.

  • EntityId: a globally unique identifier for an Entity. If present in Entity representations, the EntityId is specified in the @id annotation.

Each Entity has a primary key that is composed of one or more of the declared properties of the entity type. Which properties of the Entity Type make up the primary key of the Entity Type is specified in the service metadata document. For the data models specified in this document the primary key is always the field id, though the data type of the field may vary between services. In most cases the primary key field will be server generated at the time an Entity is created, but a service may allow for client-specified primary key fields.

URLs in documents may be absolute or relative. Relative URLs are relative to the context URL in the document, or if there is no context url, relative to the request URL. See https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_RelativeURLs.

Table 23 — Common control annotations

NameDefinitionData Type

@context

The context url contains the metadata document that describes the context of a payload. See Clause 8.2

URL

@id

The annotation @id is the entity-id, an absolute or relative URL of an entity that uniquely resolves to this entity.

URL

linkName@navigationLink

Annotations of the form linkName@navigationLink are the relative or absolute URL that retrieves the related entity or entities for the navigation property linkName.

URL

8.2.  OData Common Schema Definition Language

The data model is specified in the metadata document that can be retrieved from the context url. It is described in a machine-readable way using the OData Common Schema Definition Language. See https://docs.oasis-open.org/odata/odata-csdl-json/v4.01/odata-csdl-json-v4.01.html

An example CSDL document describing a service hosting a SensorThings API v2.0 core data model can be found in Annex C. A shortened example with comments can be found in Annex B.

Requirement 21

Identifierhttp://www.opengis.net/spec/sensorthings/2.0/req-class/api/abstract/csdl
Included inRequirements class 11: http://www.opengis.net/spec/sensorthings/2.0/req-class/api/abstract
Statement

A service that implements the absract REST API SHALL make a service metadata document available as described in Clause 8.2.

EDITORIAL NOTE

Mention TM_Object and TM_Interval here?

8.3.  URI Patterns

URI Patterns in the SensorThings API consist of three parts: the URI-Root, the resource path and query options. The URI-Root always ends with the version number of the standard, encoded as: "v"majorversionnumber + "." + minorversionnumber. The resource path consists of zero to many parts separated with by the slash (/) character. Resource paths are case sensitive. The query options start with a question mark (?) character. At the top level, query options are separated with the ampersant (&) character.

http://example.org/v2.0/Datastreams(5)/Observations?$orderby=ID&$top=10
_______________________/__________________________/___________________/
          |                          |                      |
  service root URI             resource path           query options

Example 1: Complete URI example using HTTP bindings

base/topic/v2.0/Datastreams(5)/Observations?$orderby=ID&$top=10
_______________/__________________________/___________________/
      |                      |                      |
   root URI            resource path           query options

Example 2: Complete URI example using MQTT bindings

8.3.1.  Service Document

URI Pattern: v2.0

Requests to the URL pattern consisting of just the version number, optionally followed by a slash (/) address the service document.

8.3.2.  Service Metadata Document

URI Pattern: v2.0/$metadata

Requests to the URL pattern consisting of the API version number followed by /$metadata address the service metadata document that describes the data model that the service exposes. The service metadata document is described in Clause 8.2.

8.3.3.  Entity Set

URI Pattern: v2.0/EntityTypeName

Requests to a URL pattern consisting of the API version number followed by / and the name of an entity type address the set of all entities of the requested type.

v2.0/Datastreams

Example 3: Resource pattern for the Datastreams Entity Set

8.3.4.  Entity

URI Pattern: v2.0/EntityTypeName(<primaryKey>)

Requests to a URL pattern consisting of the name of an EntitySet URL, followed by, in brackets, a primary key value fitting the entity type of the set, address the single Entity from the set, that has the given primary key.

v2.0/Datastreams(4)

Example 4: Resource pattern for a specific Datastream, for a service that uses Integers for the id field of Datastreams

v2.0/Datastreams('xz42df')

Example 5: Resource pattern for a specific Datastream, for a service that uses Strings for the id field of Datastreams

8.3.5.  Entity Property

URI Pattern: v2.0/EntityTypeName(<primaryKey>)/entityProperty

Requests to a URL pattern consisting of a URL that addresses an Entity (the base entity), followed by an Entity Property, address the value of this Entity Property of the base Entity. The used URL for the base entity may itself be a related entity URL.

v2.0/Datastreams(4)/name

Example 6: Resource pattern for the name of a specific Datastream

v2.0/Datastreams(4)/Thing/name

Example 7: Resource pattern for the name of the Thing of a specific Datastream

8.3.6.  Entity Property raw value ($value)

URI Pattern: v2.0/EntityTypeName(<primaryKey>)/entityProperty/$value

Requests to a URL pattern consisting of a URL that addresses an Entity (the base entity), followed by an Entity Property, followed by /$value, address the raw value of this Entity Property of the base Entity. The used URL for the base entity may itself be a related entity URL.

v2.0/Datastreams(4)/name/$value

Example 8: Resource pattern for the raw name of a specific Datastream

v2.0/Datastreams(4)/Thing/name/$value

Example 9: Resource pattern for the raw name of the Thing of a specific Datastream

8.3.9.  Association link ($ref)

URI Pattern: v2.0/EntityTypeName(<primaryKey>)/NavigationProperty/$ref

Requests to a URL pattern consisting of a URL that addresses an Entity (the base entity), followed by a navigation property, followed by /$ref, address the entity-id(s) of the related entity or entities of the given navigation property. For navigation property with a cardinality of many, the navigation property may be followed by a primary-key in brackets, to address the specific association between the base entity and the related entity. The association link can be used to modify the relation(s).

v2.0/Datastreams(4)/Thing/$ref

Example 14: Resource pattern for the association link of the Thing of a specific Datastream

v2.0/Datastreams(4)/Observations/$ref

Example 15: Resource pattern for the association link to the Observations related to a specific Datastream

v2.0/Datastreams(4)/Observations(1)/$ref

Example 16: Resource pattern for the association link between a specific Datastream and a specific Observation

8.3.10.  More complex examples

v2.0/EntityTypeName(<primaryKey>)/EntitySetNavigationProperty(<primaryKey>)

The pattern Clause 8.3.8 and Clause 8.3.4 can be combined to address a specific entity from a related set. This will return a Not Found error when the requested entity is not actually in the related set.

v2.0/Datastreams(4)/Observations(5321)

Example 17: Resource pattern for a specific Observation of a specific Datastream

The above example addresses the same entity as v2.0/Observations(5321), except when Observation 5321 is not actually contained in Datastream 4, since in that case any action on the resource would return a Not Found error.

8.4.  Encoding rules for constants

Encoding rules for constants in resource paths and query options are listed in Table 24

Table 24 — Encoding rules for constants in requests

TypeDescriptionExample

String

Quoted using single-quotes ('). Single quotes in a string are doubled.

'degree Celsius'
'Abby''s Car'

Number

Numbers are not quoted, use a decimal point (.), no thousands separator.

0.31415926535897931e1
-42

Datetime

Not quoted ISO8601 time with timezone. Special characters (+) must be URL-Encoded.

2012-12-03T07:16:23Z
2012-12-03T07:16:23%2B08:00

Boolean

Literal value true or false

true
false

Null

Literal value null

null

Time Duration

the keyword duration followed by an ISO8601 Druation in single quotes.

duration’P1DT30M'

Geometry

the keyword geography followed by WKT in single quotes.

geography’POINT(-122 43)'

8.5.  Requesting Data

This section describes how to read data from a SensorThings API compatible service. Details on how to send requests and how to receive responses are described in the protocol bindings sections. For example, when using the HTTP bindings, GET is used for read requests.

8.5.1.  Service Document

A read (GET) Requests to the Service Document URL pattern (Clause 8.3.1) returns the service document.

The Service document is a JSON object with a property named value and a property named serverSettings. The content of the property named value SHALL be a JSON Array containing one element for each entity set of the SensorThings Service. The content of the property named serverSettings SHALL be a JSON Object describing the features the server supports that can not easily be detected by querying the service.

Each element of the value array SHALL be a JSON object with at least two name/value pairs, one with name name containing the name of the entity set (e.g., Things, Locations, Datastreams, Observations, ObservedProperties and Sensors) and one with name url containing the URL of the entity set, which may be an absolute or a relative URL. (Adapted from OData 4.01-JSON-Format section 5)

The serverSettings object SHALL contain the property conformance of the type Array, containing the URIs of all requirements from this specification and any extensions that the service implements. If a service implements all requirements from a requirements class, it only needs to list the requirements class id.

Security extensions can modify the list of requirements to only show those requirements that the user is allowed to use. For example, if a user is not allowed to delete entities, the security extension can hide the create-update-delete/delete-entity requirement. In the most extreme case, a security extension would hide all requirements for a user that is not authenticated, except its own requirement and the instructions on how to authenticate.

Extensions that need to expose additional server settings may do so in a property of the serverSettings object that is named after the conformance class URI of the requirement that defines this setting.

{
 
"value": [
   
{
     
"name": "Things",
     
"url": "https://example.org/v2.0/Things"
   
},
   
{
     
"name": "Locations",
     
"url": "https://example.org/v2.0/Locations"
   
},
   
{
     
"name": "Datastreams",
     
"url": "https://example.org/v2.0/Datastreams"
   
},
   
{
     
"name": "Sensors",
     
"url": "https://example.org/v2.0/Sensors"
   
},
   
{
     
"name": "Observations",
     
"url": "https://example.org/v2.0/Observations"
   
},
   
{
     
"name": "ObservedProperties",
     
"url": "https://example.org/v2.0/ObservedProperties"
   
},
   
{
     
"name": "Features",
     
"url": "https://example.org/v2.0/Features"
   
},
   
{
     
"name": "FeatureTypes",
     
"url": "https://example.org/v2.0/FeatureTypes"
   
}
 
],
 
"serverSettings": {
   
"conformance": [
       
"http://www.opengis.net/spec/sensorthings/2.0/req/datamodel",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/resource-path/resource-path-to-entities",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/request-data",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/create-entity",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/link-to-existing-entities",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/deep-insert",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/deep-insert-status-code",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/update-entity",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/delete-entity",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-update-delete/historical-location-auto-creation",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/create-observations-via-mqtt/observations-creation",
       
"http://www.opengis.net/spec/sensorthings/2.0/req/receive-updates-via-mqtt/receive-updates"
   
],
   
"http://www.opengis.net/spec/sensorthings/2.0/req/receive-updates-via-mqtt/receive-updates": {
     
"endpoints": [
       
"mqtt://server.example.com:1833",
       
"ws://server.example.com/sensorThings",
     
]
   
},
   
"http://www.opengis.net/spec/sensorthings/2.0/req/create-observations-via-mqtt/observations-creation": {
     
"endpoints": [
       
"mqtts://server.example.com:8883",
       
"wss://server.example.com:443/sensorThings"
     
]
   
}
 
}
}

Listing 16 — A service document using absolute HTTPS-URLs

EDITORIAL NOTE

Add section on listing implemented features, like filter functions.

8.5.2.  EntitySet

A Read (GET) request to a URI pattern that returns an entity set can use all query options: $filter, $count, $orderby, $skip, $top, $expand, $select and $format.

8.5.3.  Single Entity

A Read (GET) request to a URI pattern that returns a single entity can use the $expand, $select and $format query options.

https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html

8.6.  Request Query Options

8.6.1.  Evaluation Order

The OGC SensorThings API adapts many of OData’s system query options and their usage. These query options allow refining the request. The result of the service request is as if the system query options were evaluated in the following order.

Prior to applying any server-driven pagination:

  • $filter

  • $count

  • $orderby

  • $skip

  • $top

After applying any server-driven pagination:

  • $expand

  • $select

  • $format

8.6.2.  $select

The $select system query option requests the service to return only the properties explicitly requested by the client. The value of a $select query option SHALL be a comma-separated list of selection clauses. Each selection clause SHALL be a property name (including navigation property names). For navigation properties, $select controls the inclusion of the navigationLink in the response.

In the response, the service SHALL return the specified content, if available. Expanded navigation properties do not need to be added to the $select list, they SHALL always be included in the response. The $select option can be applied to any request that returns an Entity or an EntitySet.

Note: Adapted from OData 4.01-Protocol 11.2.5.1



v2.0/Things?$select=id,name

Example 18: Resource pattern returning only the id and name of the Entities in the Things EntitySet.

8.6.3.  $select distinct

It is quite useful to give Entities common properties, like a “type”. But when filtering on such a common property the client needs to know what the used values are. Distinct select allows a client to request all distinct values for a field or a set of fields.

Distinct select can be used in expands, and can be ordered. When combining $orderby with a distinct select, it is only possible to order by the exact fields that are selected.

Note that selecting distinct values for the primary key field (id) makes no sense, since this field is unique for each entity.

To request the distinct values for a set of selected fields, add the distinct: keyword at the start of the $select parameter.

The returned data is formatted just like a non-distinct request of the same type would be.

v2.0/Things?$select=distinct:properties/type

Example 19: request returning all distinct values of the properties/type field of all Things

{
   
"value": [
       
{ "properties": { "type": "waterBody" } },
       
{ "properties": { "type": "station" } },
       
{ "properties": { "type": "aquifer" } }
   
]
}

Example 20: possible response to the above request

8.6.4.  $expand

The $expand system query option indicates the related entities to be represented inline. The value of the $expand query option SHALL be a comma separated list of navigation property names. Query options can be applied to the expanded navigation property by appending a semicolon-separated list of query options, enclosed in parentheses, to the navigation property name. Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, and $expand.

The $expand option can be applied to any request that returns an Entity or an EntitySet.

Note: Adapted from OData 4.01-Protocol 11.2.5.2

v2.0/Things?$expand=Datastreams($expand=ObservedProperty)

Example 21: Resource pattern returning Things, with their Datastreams, and the ObservedProperty for each Datastream.

v2.0/Datastreams?$expand=Observations($select=result,phenomenonTime;$orderby=phenomenonTime desc;$top=1),ObservedProperty

Example 22: Resource pattern returning Datastream as well as the result and phenomenonTime of the last Observation (as ordered by phenomenonTime) and the ObservedProperty associated with this Datastream.

8.6.5.  $top

The $top system query option specifies the limit on the number of items returned from an EntitySet. The value of the $top system query option SHALL be a non-negative integer. The service SHALL return the number of available items up to but not greater than the specified value.

If no unique ordering is imposed through an $orderby query option, the service SHALL impose a stable ordering across requests that include $top.

In addition, if the $top value exceeds the service-driven pagination limitation (i.e., the largest number of entities the service can return in a single response), the $top query option SHALL be discarded and the server-side pagination limitation SHALL be imposed.

Note: Adapted from OData 4.01-Protocol 11.2.6.3

v2.0/Things?$top=5

Example 23: Resource pattern returning only the first five entities in the Things EntitySet.

v2.0/Observations?$top=5&$orderby=phenomenonTime%20desc

Example 24: Resource pattern returning the first five Observation entries after sorting by the phenomenonTime property in descending order.

8.6.7.  $count

The $count system query option with a value of true specifies that the total count of items within an EntitySet matching the request SHALL be returned along with the result. A $count query option with a value of false specifies that the service SHALL not return a count.

The service SHALL return an HTTP Status code of 400 Bad Request if a value other than true or false is specified.

The $count system query option SHALL ignore any $top, $skip, or $expand query options, and SHALL return the total count of results across all pages including only those results matching any specified $filter.

Clients should be aware that the count returned inline may not exactly equal the actual number of items returned, due to latency between calculating the count and enumerating the last value or due to inexact calculations on the service.

Note: Adapted from OData 4.01-Protocol 11.2.6.5

8.6.8.  $orderby

The $orderby system query option specifies the order in which items are returned from the service. The value of the $orderby system query option SHALL contain a comma-separated list of expressions whose primitive result values are used to sort the items. A special case of such an expression is a property path terminating on a primitive property.

The expression MAY include the suffix asc for ascending or desc for descending, separated from the property name by one or more spaces. If asc or desc is not specified, the service SHALL order by the specified property in ascending order.

Null values SHALL come before non-null values when sorting in ascending order and after non-null values when sorting in descending order.

Items SHALL be sorted by the result values of the first expression, and then items with the same value for the first expression SHALL be sorted by the result value of the second expression, and so on.

Note: Adapted from OData 4.01-Protocol 11.2.6.2

v2.0/Observations?$orderby=result

Example 27: Resource pattern returning all Observations ordered by the result property in ascending order.

v2.0/Observations?$orderby=Datastreams/id desc, phenomenonTime

Example 28: Resource pattern returning all Observations ordered by the id property of the linked Datastream entry in descending order, then by the phenomenonTime property of Observations in ascending order.

8.6.9.  $filter

The $filter option can be used to filter the entities returned by a request to any EntitySet. The expression specified with $filter is evaluated for each entity in the collection, and only items where the expression evaluates to true SHALL be included in the response. Entities for which the expression evaluates to false or to null, or which reference properties that are unavailable due to permissions, SHALL be omitted from the response.

The expression language that is used in $filter operators SHALL support references to properties and literals. The literal values SHALL be strings enclosed in single quotes, numbers, boolean values (true or false), null, datetime values as ISO 8601 time string, duration values or geometry values. Encoding rules for constants are listed in Table 24 Properties of Entities are addressed by their name.

Note: Adapted from OData 4.01-Protocol 11.2.6.1

v2.0/Datastreams(42)/Observations?$filter=result gt 5

Example 29: Observations of Datastream 42 that have a result greater than 5.

v2.0/Locations?$filter=st_within(location, geography'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))')

Example 30: Locations inside a given area.

Sub-proprties of complex properties are addressed using the complex property name, followed by a /, followed by the sub-property name.

v2.0/Observations?$filter=validTime/start lt 2012-12-03T07:16:23Z

Example 31: Observations with a valid time that started before the given timestamp.

Entities can be filtered on properties of related entities by using the navigationProperty, followed by a /, followed by a property of the related entity. This can be used recursively. For filtering on properties of entities in a related EntitySet see the any() function.

v2.0/Observations?$filter=Datastream/name eq 'Temperature'

Example 32: Observations of all Datastreams that are named Temperature.

v2.0/Observations?$filter=Datastream/Thing/name eq 'House 1'

Example 33: Observations of all Things that are named House 1.

8.6.9.1.  Built-in filter operations

The OGC SensorThings API supports a set of built-in filter operations, as described in the following table. These built-in filter operator usages and definitions follow the [OData Version 4.01. Part 1: Protocol 11.2.6.1.1] and [OData Version 4.01 ABNF]. The operator precedence is described in [OData Version 4.01. Part 2: URL Conventions Section 5.1.1.17].

Table 25 — Built-in Filter Operators

OperatorDescriptionExample
Comparison Operators
eqEqual/Datastreams?$filter=resultType/type eq 'Quantity'
neNot equal/Datastreams?$filter=resultType/type ne 'Quantity'
gtGreater than/Observations?$filter=result gt 20.0
geGreater than or equal/Observations?$filter=result ge 20.0
ltLess than/Observations?$filter=result lt 100
leLess than or equal/Observations?$filter=result le 100
Logical Operators
andLogical and/Observations?$filter=result le 3.5 and FeatureOfInterest/id eq 1
orLogical or/Observations?$filter=result gt 20 or result le 3.5
notLogical negation/Things?$filter=not startswith(description,'test')
Arithmetic Operators
addAddition/Observations?$filter=result add 5 gt 10
subSubtraction/Observations?$filter=result sub 5 gt 10
mulMultiplication/Observations?$filter=result mul 2 gt 2000
divDivision/Observations?$filter=result div 2 gt 4
modModulo/Observations?$filter=result mod 2 eq 0
Grouping Operators
( )Precedence grouping/Observations?$filter=(result sub 5) gt 10

8.6.9.2.  Built-in query functions

The OGC SensorThings API supports a set of functions that can be used with the $filter or $orderby query operations. The following table lists the available functions and they follows the OData Canonical function definitions listed in OData Version 4.01 Part 2: URL Conventions, Section 5.1.1.4.

In order to support spatial relationship functions, SensorThings API defines nine additional geospatial functions based on the spatial relationship between two geometry objects. The spatial relationship functions are defined in the OGC Simple Feature Access specification [OGC 06-104r4 part 1, clause 6.1.2.3]. The names of these nine functions start with a prefix st_ following the OGC Simple Feature Access specification [OGC 06-104r4]. In addition, the Well-Known Text (WKT) format is the default input geometry for these nine functions.

Table 26 — Built-in Query Functions

FunctionExample

String Functions

bool substringof(string p0, string p1)

substringof('Sensor Things',description)

bool endswith(string p0, string p1)

endswith(description,'Things')

bool startswith(string p0, string p1)

startswith(description,'Sensor')

int length(string p0)

length(description) eq 13

int indexof(string p0, string p1)

indexof(description,'Sensor') eq 1

string substring(string p0, int p1)
string substring(string p0, int p1, int p2)

substring(description,1) eq 'ensor Things'
substring(description,2,4) eq 'nsor'

string tolower(string p0)

tolower(description) eq 'sensor things'

string toupper(string p0)

toupper(description) eq 'SENSOR THINGS'

string trim(string p0)

trim(description) eq 'Sensor Things'

string concat(string p0, string p1)

concat(concat(unitOfMeasurement/symbol,', '), unitOfMeasurement/name) eq 'degree, Celsius'

Date Functions

int year

year(resultTime) eq 2015

int month

month(resultTime) eq 12

int day

day(resultTime) eq 8

int hour

hour(resultTime) eq 1

int minute

minute(resultTime) eq 0

int second

second(resultTime) eq 0

int fractionalseconds

second(resultTime) eq 0

int date

date(resultTime) ne date(validTime)

time

time(resultTime) le validTime

int totaloffsetminutes

totaloffsetminutes(resultTime) eq 60

now

resultTime ge now()

mindatetime

resultTime eq mindatetime()

maxdatetime

resultTime eq maxdatetime()

Math Functions

round

round(result) eq 32

floor

floor(result) eq 32

ceiling

ceiling(result) eq 33

Geospatial Functions

double geo.distance(Point p0, Point p1)

geo.distance(location, geography'POINT (30 10)')

double geo.length(LineString p0)

geo.length(geography'LINESTRING (30 10, 10 30, 40 40)')

bool geo.intersects(Point p0, Polygon p1)

geo.intersects(location, geography'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))')

Spatial Relationship Functions

bool st_equals

st_equals(location, geography'POINT (30 10)')

bool st_disjoint

st_disjoint(location, geography'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))')

bool st_touches

st_touches(location, geography'LINESTRING (30 10, 10 30, 40 40)')

bool st_within

st_within(location, geography'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))')

bool st_overlaps

st_overlaps(location, geography'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))')

bool st_crosses

st_crosses(location, geography'LINESTRING (30 10, 10 30, 40 40)')

bool st_intersects

st_intersects(location, geography'LINESTRING (30 10, 10 30, 40 40)')

bool st_contains

st_contains(location, geography'POINT (30 10)')

bool st_relate

st_relate(location, geography'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))', 'T********')

8.6.9.3.  Any

The any() operator applies a boolean expression to each member of a collection and returns true if the expression returns true for any member of the collection.

EDITORIAL NOTE

  • add cast,

  • add any(),

  • add in(),

  • time interval functions?

  • …​

8.6.10.  $format

EDITORIAL NOTE

TODO

8.6.11.  Server driven pagination

Responses that include only a partial set of the items identified by the request URL SHALL contain a link that allows retrieving the next partial set of items. This link is called a nextLink; its representation is format-specific. The final partial set of items (the last page) SHALL NOT contain a nextLink.

The nextLink annotation indicates that a response is only a subset of the requested collection of entities or collection of entity references. It contains a URL that allows retrieving the next subset of the requested collection.

SensorThings clients SHALL treat the URL of the nextLink as opaque, and SHALL NOT append system query options to the URL of a next link. Services may disallow a change of format on requests for subsequent pages using the next link.

Note: Adapted from OData 4.01-Protocol 11.2.6.7

8.7.  Modifying Data

This section describes how to create, update and delete Entities. Deltails on how to send POST, PATCH, PUT and DELETE requests and how responses are received are described in the protocol bindings sections.

8.7.1.  Requirement Class A or Requirement A Example

intro text for the requirement class.

Use the following table for Requirements Classes.

8.7.1.1.  Requirement 1

intro text for the requirement.

Use the following table for Requirements, number sequentially.

8.7.1.2.  Requirement 2

intro text for the requirement.

Use the following table for Requirements, number sequentially.

9.  HTTP Interface Bindings

The HTTP Bindings specify how access the SensorThings API using the HTTP protocol.

9.1.  GET

intro text for the requirement class.

Use the following table for Requirements Classes.

9.2.  POST

9.7.  OPTIONS

9.7.1.  Requirement 1

intro text for the requirement.

Use the following table for Requirements, number sequentially.

9.7.2.  Requirement 2

intro text for the requirement.

Use the following table for Requirements, number sequentially.

10.  MQTT Interface Bindings

The MQTT Bindings specify how to access the SensorThings API using the MQTT 5 protocol.

10.1.  Request / Response

intro text for the requirement class.

Use the following table for Requirements Classes.

10.2.  Publish / Subscribe

10.2.1.  Requirement 1

intro text for the requirement.

Use the following table for Requirements, number sequentially.

10.2.2.  Requirement 2

intro text for the requirement.

Use the following table for Requirements, number sequentially.

11.  AMQP Interface Bindings

The AMQP Bindings specify how to access the SensorThings API using the AMQP protocol.

11.1.  Request / Response

intro text for the requirement class.

Use the following table for Requirements Classes.

11.2.  Publish / Subscribe

11.2.1.  Requirement 1

intro text for the requirement.

Use the following table for Requirements, number sequentially.

11.2.2.  Requirement 2

intro text for the requirement.

Use the following table for Requirements, number sequentially.

12.  OGC API — Common Interface Bindings

The OGC API — Common Bindings specify how to combine the SensorThings API with other OGC APIs.

12.1.  Request / Response

intro text for the requirement class.

Use the following table for Requirements Classes.

12.2.  Publish / Subscribe

12.2.1.  Requirement 1

intro text for the requirement.

Use the following table for Requirements, number sequentially.

12.2.2.  Requirement 2

intro text for the requirement.

Use the following table for Requirements, number sequentially.

13.  Media Types for any data encoding(s)

A section describing the MIME-types to be used is mandatory for any standard involving data encodings. If no suitable MIME type exists in http://www.iana.org/assignments/media-types/index.html then this section may be used to define a new MIME type for registration with IANA.


Annex A
(informative)
Conformance Class Abstract Test Suite (Normative)

NOTE:    Ensure that there is a conformance class for each requirements class and a test for each requirement (identified by requirement name and number)

A.1.  Conformance Class A

Example

label

http://www.opengis.net/spec/name-of-standard/1.0/conf/example1

subject

Requirements Class “example1”

classification

Target Type:Web API

A.1.1.  Example 1

Abstract test A.1

Subject/req/req-class-a/req-name-1
Label/conf/core/api-definition-op
Test purpose

Validate that the API Definition document can be retrieved from the expected location.

Test method
  1. Construct a path for the API Definition document that ends with /api.

  2. Issue a HTTP GET request on that path

  3. Validate the contents of the returned document using test /conf/core/api-definition-success.

A.1.2.  Example 2

Abstract test A.2

Subject/req/req-class-a/req-name-2
Label/conf/core/http
Test purpose

Validate that the resource paths advertised through the API conform with HTTP 1.1 and, where appropriate, TLS.

Test method
  1. All compliance tests SHALL be configured to use the HTTP 1.1 protocol exclusively.

  2. For APIs which support HTTPS, all compliance tests SHALL be configured to use HTTP over TLS (RFC 2818) with their HTTP 1.1 protocol.


Annex B
(informative)
Short CSDL example with comments

{
   
"$Version": "4.01",  // OData version
   
"$EntityContainer": "org.OGC.SensorThingsV2",  // Namespace + . + container name
   
"org.OGC": {         // Namespace
       
"Datastream": {  // EntityType name
           
"$Kind": "EntityType",  // Object is an EntityType
           
"$Key": [    // Primary key of the EntityType
               
"id"     // Primary key consists of the id field
           
],
           
"id": {                   // id field, structural properties have no $Kind
               
"$Type": "Edm.Int64"  // Type of the id field
           
},                        // Not nullable, but PrimaryKeys are auto generated
           
"name": {},   // name field, Default $Type=Edm.String, not nullable
           
"properties": {                 // Property properties
               
"$Type": "org.OGC.Object",  // custom type defined in org.OGC namespace
               
"$Nullable": true           // Nullable, thus Optional
           
},
           
"phenomenonTime": {               // Property phenomenonTime
               
"$Type": "org.OGC.TM_Period", // custom type defined in org.OGC namespace
               
"$Nullable": true             // Nullable, thus Optional
           
},
           
"Observations": {                   // Property Observations
               
"$Kind": "NavigationProperty",  // NavigationProperty
               
"$Collection": true,            // links to a Set of Entities
               
"$Partner": "Datastream",       // inverse link is called Datastream
               
"$Type": "org.OGC.Observation", // Target is of type Observation
               
"$Nullable": true               // can be an empty set
           
}
       
},
       
"Observation": {            // EntityType name
           
"$Kind": "EntityType",  // Object is an EntityType
           
"$Key": [               // Primary key of the EntityType
               
"id"                // Primary key consists of the id field
           
],
           
"id": {                   // id field, structural properties have no $Kind
               
"$Type": "Edm.Int64"  // Type of the id field
           
},                        // Not nullable, but PrimaryKeys are auto generated
           
"result": {
               
"$Type": "Edm.Untyped"  // Untyped=can be anything
           
},
           
"Datastream": {                    // Property Datastream linking to a single Entity
               
"$Kind": "NavigationProperty", // is a NavigationProperty
               
"$Partner": "Observations",    // inverse relation is called Observations
               
"$Type": "org.OGC.Datastream"  //  links to a Datastream
           
}                                  // No $Nullable, thus mandatory!
       
},
       
"Object": {                 // Custom type Object
           
"$Kind": "ComplexType", // is a complex type
           
"$OpenType": true       // Open, thus can hold user-defined properties
       
},
       
"TM_Period": {                         // Custom type TM_Period
           
"$Kind": "ComplexType",            // is a complex type
           
"start": {                         // Has a structural property named start
               
"$Type": "Edm.DateTimeOffset"  // that is of type DataTimeOffset
           
},                                 // No $Nullable, thus mandatory!
           
"end": {                           // Has a structural property named end
               
"$Type": "Edm.DateTimeOffset"  // that is of type DataTimeOffset
           
}
       
},
       
"SensorThingsV2": {             // The entity container defining the base entity sets
           
"$Kind": "EntityContainer",
           
"Datastreams": {                     // The v2.0/Datastreams entitySet
               
"$Collection": true,             // is an entity set
               
"$Type": "org.OGC.Datastream",   // containing Datastreams
               
"$NavigationPropertyBinding": {  // The navigationProperties link to other top-level sets
                   
"Observations": "Observations"  // v2.0/Datastreams(x)/Observations are also in v2.0/Observations
               
}
           
},
           
"Observations": {                    // The v2.0/Observations entitySet
               
"$Collection": true,             // is an entity set
               
"$Type": "org.OGC.Observation",  // containing Observations
               
"$NavigationPropertyBinding": {
                   
"Datastream": "Datastreams"  // v2.0/Observations(x)/Datastream is also in v2.0/Datastreams
               
}
           
}
       
}
   
}
}

Listing B.1 — A shortened example CSDL definition with only (incomplete) Datastreams and Observations.


Annex C
(informative)
Example SensorThings API Core CSDL

{
   
"$Version": "4.01",
   
"$EntityContainer": "org.OGC.SensorThingsV2",
   
"org.OGC": {
       
"Datastream": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"resultType": {
               
"$Type": "org.OGC.Object"
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"observedArea": {
               
"$Type": "Edm.Geometry",
               
"$Nullable": true
           
},
           
"phenomenonTime": {
               
"$Type": "org.OGC.TM_Period",
               
"$Nullable": true
           
},
           
"resultTime": {
               
"$Type": "org.OGC.TM_Period",
               
"$Nullable": true
           
},
           
"Observations": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Datastream",
               
"$Type": "org.OGC.Observation",
               
"$Nullable": true
           
},
           
"ObservedProperties": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Datastreams",
               
"$Type": "org.OGC.ObservedProperty",
               
"$Nullable": true
           
},
           
"Sensor": {
               
"$Kind": "NavigationProperty",
               
"$Partner": "Datastreams",
               
"$Type": "org.OGC.Sensor"
           
},
           
"Thing": {
               
"$Kind": "NavigationProperty",
               
"$Partner": "Datastreams",
               
"$Type": "org.OGC.Thing"
           
},
           
"ultimateFeatureOfInterest": {
               
"$Kind": "NavigationProperty",
               
"$Partner": "Datastreams",
               
"$Type": "org.OGC.Feature",
               
"$Nullable": true
           
}
       
},
       
"Feature": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"encodingType": {
               
"$Nullable": true
           
},
           
"feature": {
               
"$Type": "org.OGC.Geometry",
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"Datastreams": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "ultimateFeatureOfInterest",
               
"$Type": "org.OGC.Datastream",
               
"$Nullable": true
           
},
           
"FeatureTypes": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Features",
               
"$Type": "org.OGC.FeatureType",
               
"$Nullable": true
           
},
           
"Observations": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "proximateFeatureOfInterest",
               
"$Type": "org.OGC.Observation",
               
"$Nullable": true
           
}
       
},
       
"FeatureType": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"definition": {
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"Features": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "FeatureTypes",
               
"$Type": "org.OGC.Feature",
               
"$Nullable": true
           
}
       
},
       
"HistoricalLocation": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"time": {
               
"$Type": "Edm.DateTimeOffset"
           
},
           
"Locations": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "HistoricalLocations",
               
"$Type": "org.OGC.Location",
               
"$Nullable": true
           
},
           
"Thing": {
               
"$Kind": "NavigationProperty",
               
"$Partner": "HistoricalLocations",
               
"$Type": "org.OGC.Thing"
           
}
       
},
       
"Location": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"encodingType": {
               
"$Nullable": true
           
},
           
"location": {
               
"$Type": "org.OGC.Geometry",
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"HistoricalLocations": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Locations",
               
"$Type": "org.OGC.HistoricalLocation",
               
"$Nullable": true
           
},
           
"Things": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Locations",
               
"$Type": "org.OGC.Thing",
               
"$Nullable": true
           
}
       
},
       
"Observation": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"phenomenonTime": {
               
"$Type": "org.OGC.TM_Object",
               
"$Nullable": true
           
},
           
"resultTime": {
               
"$Type": "Edm.DateTimeOffset",
               
"$Nullable": true
           
},
           
"validTime": {
               
"$Type": "org.OGC.TM_Period",
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"result": {
               
"$Type": "Edm.Untyped",
               
"$Nullable": true
           
},
           
"Datastream": {
               
"$Kind": "NavigationProperty",
               
"$Partner": "Observations",
               
"$Type": "org.OGC.Datastream"
           
},
           
"proximateFeatureOfInterest": {
               
"$Kind": "NavigationProperty",
               
"$Partner": "Observations",
               
"$Type": "org.OGC.Feature",
               
"$Nullable": true
           
}
       
},
       
"ObservedProperty": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"definition": {},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"Datastreams": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "ObservedProperties",
               
"$Type": "org.OGC.Datastream",
               
"$Nullable": true
           
}
       
},
       
"Sensor": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"encodingType": {
               
"$Nullable": true
           
},
           
"metadata": {
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"Datastreams": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Sensor",
               
"$Type": "org.OGC.Datastream",
               
"$Nullable": true
           
}
       
},
       
"Thing": {
           
"$Kind": "EntityType",
           
"$Key": [
               
"id"
           
],
           
"id": {
               
"$Type": "Edm.Int64"
           
},
           
"name": {},
           
"description": {
               
"$Nullable": true
           
},
           
"properties": {
               
"$Type": "org.OGC.Object",
               
"$Nullable": true
           
},
           
"Datastreams": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Thing",
               
"$Type": "org.OGC.Datastream",
               
"$Nullable": true
           
},
           
"HistoricalLocations": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Thing",
               
"$Type": "org.OGC.HistoricalLocation",
               
"$Nullable": true
           
},
           
"Locations": {
               
"$Kind": "NavigationProperty",
               
"$Collection": true,
               
"$Partner": "Things",
               
"$Type": "org.OGC.Location",
               
"$Nullable": true
           
}
       
},
       
"Geometry": {
           
"$Kind": "TypeDefinition",
           
"$UnderlyingType": "Edm.Geometry",
           
"@Core.Description": "A Free Location object"
       
},
       
"Object": {
           
"$Kind": "ComplexType",
           
"$OpenType": true,
           
"@Core.Description": "A free object that can contain anything"
       
},
       
"TM_Object": {
           
"$Kind": "ComplexType",
           
"@Core.Description": "An ISO time instant or time interval.",
           
"start": {
               
"$Type": "Edm.DateTimeOffset"
           
},
           
"end": {
               
"$Type": "Edm.DateTimeOffset",
               
"$Nullable": true
           
}
       
},
       
"TM_Period": {
           
"$Kind": "ComplexType",
           
"@Core.Description": "An ISO time interval.",
           
"start": {
               
"$Type": "Edm.DateTimeOffset"
           
},
           
"end": {
               
"$Type": "Edm.DateTimeOffset"
           
}
       
},
       
"SensorThingsV2": {
           
"$Kind": "EntityContainer",
           
"Datastreams": {
               
"$Collection": true,
               
"$Type": "org.OGC.Datastream",
               
"$NavigationPropertyBinding": {
                   
"ultimateFeatureOfInterest": "Features",
                   
"Observations": "Observations",
                   
"ObservedProperties": "ObservedProperties",
                   
"Thing": "Things",
                   
"Sensor": "Sensors"
               
}
           
},
           
"Features": {
               
"$Collection": true,
               
"$Type": "org.OGC.Feature",
               
"$NavigationPropertyBinding": {
                   
"Datastreams": "Datastreams",
                   
"FeatureTypes": "FeatureTypes",
                   
"Observations": "Observations"
               
}
           
},
           
"FeatureTypes": {
               
"$Collection": true,
               
"$Type": "org.OGC.FeatureType",
               
"$NavigationPropertyBinding": {
                   
"Features": "Features"
               
}
           
},
           
"HistoricalLocations": {
               
"$Collection": true,
               
"$Type": "org.OGC.HistoricalLocation",
               
"$NavigationPropertyBinding": {
                   
"Locations": "Locations",
                   
"Thing": "Things"
               
}
           
},
           
"Locations": {
               
"$Collection": true,
               
"$Type": "org.OGC.Location",
               
"$NavigationPropertyBinding": {
                   
"Things": "Things",
                   
"HistoricalLocations": "HistoricalLocations"
               
}
           
},
           
"Observations": {
               
"$Collection": true,
               
"$Type": "org.OGC.Observation",
               
"$NavigationPropertyBinding": {
                   
"Datastream": "Datastreams",
                   
"proximateFeatureOfInterest": "Features"
               
}
           
},
           
"ObservedProperties": {
               
"$Collection": true,
               
"$Type": "org.OGC.ObservedProperty",
               
"$NavigationPropertyBinding": {
                   
"Datastreams": "Datastreams"
               
}
           
},
           
"Sensors": {
               
"$Collection": true,
               
"$Type": "org.OGC.Sensor",
               
"$NavigationPropertyBinding": {
                   
"Datastreams": "Datastreams"
               
}
           
},
           
"Things": {
               
"$Collection": true,
               
"$Type": "org.OGC.Thing",
               
"$NavigationPropertyBinding": {
                   
"Datastreams": "Datastreams",
                   
"Locations": "Locations",
                   
"HistoricalLocations": "HistoricalLocations"
               
}
           
}
       
}
   
}
}

Listing C.1 — A CSDL example for the SensorThings API Core


Annex D
(informative)
Revision History

Table D.1 — Revision History

DateReleaseEditorPrimary clauses modifiedDescription
2023-05-090.1Hylke van der Schaafallinitial version

Bibliography

NOTE:    The TC has approved Springer LNCS as the official document citation type.

Springer LNCS is widely used in technical and computer science journals and other publications

– Actual References:

[n] Journal: Author Surname, A.: Title. Publication Title. Volume number, Issue number, Pages Used (Year Published)

[1]  OGC: OGC Testbed 12 Annex B: Architecture (2015).