Skip to main content

Geospatial

In Cognite Data Fusion (CDF), the geospatial endpoint is the base entry point for many resource types that enable storing and querying item collections that have a geospatial nature. Those items, called features in Geographic Information System (GIS) terminology, are grouped in feature types. Features of the same type share several properties (a name, a type, and a value) and have more than one spatial representation, all stored in configurable properties.

In addition, and following the Open Geospatial Consortium recommendation, each spatial representation should have an associated Coordinate Reference System (CRS), but this is not mandatory. The Geospatial API also enables feature search using filters of arbitrary complexity, with a boolean expression of conditions on the properties. Defining a feature type is up to the client, and CDF geospatial does not come with pre-configured schemas and provides excellent flexibility for modelling the client problem domain.

tip

See the Geospatial API documentation for more information.

Authentication and authorization

All HTTP endpoints served by the Geospatial API require a valid ticket from the Auth service.

Feature type and feature related endpoints require the GEOSPATIAL capability (READ or WRITE).

CRS related endpoints require the GEOSPATIAL_CRS capability to be enabled (READ or WRITE). Note that reading the predefined CRSs is possible with the GEOSPATIAL capability.

NOTE

Datasets are not supported currently.

Feature types

A CDF feature type defines a class of spatial features with a common specification. The specification defines the property names and their types and what indexes should be maintained to fulfill performance requirements a client might have. Indexing properties come at a price when creating features, and it is crucial to consider whether an index is necessary or not. The choice depends on the size and number of entries for a given feature type and the frequency of access to that particular property.

Features

A feature is an item following the specification given by its corresponding feature type. A parallel with a class and an object is perfectly valid.

Properties

Default properties

A feature type comes with predefined properties that enable close integration with the rest of the CDF. The default properties are:

NameTypeDescription
externalIdStringThe standard CDF external id
createdTimeTimestampThe standard CDF resource item created time
lastUpdatedTimeTimestampThe standard CDF resource item last update time

The following property names are reserved for future use:

  • id
  • dataSetId
  • assetIds
  • metadata
  • defaultGeometry
  • labels

Property types

The GeoJSON specification can be found at GeoJSON.

The Well-Known-Text specification can be found at Open Geospatial Consortium.

2D

The Geospatial service supports the following vector types, located in a 2-dimensional space, each as an X and a Y coordinate:

TypeDescriptionExample WKTExample Geojson
POINTA simple point.POINT(1 -1){"type": "Point", "coordinates": [1, -1]}
LINESTRINGA simple linestring specified by two or more distinct POINTs.LINESTRING(0 0, 1 1, 1 -1, 3 4){"type": "LineString", "coordinates": [[0, 0], [1, 1], [1, -1], [3, 4]]}
POLYGONA set of closed LINESTRINGs. A polygon must have exactly one exterior ring and can have one or more inner rings.POLYGON(

((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))

{"type": "Polygon", "coordinates": [[[35, 10], [45, 45], [15, 40], [10, 20], [35, 10]], [[20, 30], [35, 35], [30, 20], [20, 30]]]}
MULTIPOINTA set of POINTs.MULTIPOINT(-1 1, 0 0, 2 3)
MULTILINESTRINGA set of LINESTRINGs.MULTILINESTRING((0 0,0 1,1 1), (-1 1,-1 -1))
MULTIPOLYGONA set of POLYGONs.MULTIPOLYGON(((2.25 0,1.25 1,1.25 -1,2.25 0)),((1 -1,1 1,0 0,1 -1)))

3D

The Geospatial service supports the following vector types, located in a 3-dimensional space, each as an X, Y, and Z coordinate. The GeoJSON notation do not support the below vector types:

TypeDescriptionExample WKT
POINTZA simple point.POINTZ(1 -1 1)
LINESTRINGZA linestring in 2D specified by two or more distinct POINTZsLINESTRINGZ(0 0 2, 1 1 3, 1 -1 4, 3 4 5)
POLYGONZA set of closed LINESTRINGZ. A polygon must have exactly one exterior ring and can have one or more inner rings.POLYGONZ(((35 10 3, 45 45 4, 15 40 4, 10 20 5, 35 10 3), (20 30 3, 35 35 4, 30 20 5, 20 30 3))
MULTIPOINTZA set of POINTZs.MULTIPOINTZ(-1 1 1, 0 0 3, 2 3 2)
MULTILINESTRINGA set of LINESTRINGZs.MULTILINESTRINGZ((0 0 1, 0 1 2, 1 1 3), (-1 1 2, -1 -1 2))
MULTIPOLYGONA set of POLYGONZs.MULTIPOLYGONZ(((2.25 0,1.25 1,1.25 -1,2.25 0)),((1 -1,1 1,0 0,1 -1)))

The fact that a geometry has a Z coordinate does not make it a volumetric geometry. It remains a planar 2D geometry described in a 3D space.

2D + measurement / time

The Geospatial service supports the following vector types, located in a 2-dimensional space plus an additional measure, each as an X, Y, and M coordinates. The GeoJSON notation do not support the below vector types:

TypeDescriptionExample WKT
POINTMA simple point.POINTM(1 -1 1122)
LINESTRINGMA linestring in 2D specified by two or more distinct POINTMs.LINESTRINGM(0 0 2, 1 1 3, 1 -1 4, 3 4 5)
POLYGONMA set of closed LINESTRINGMs. A polygon must have exactly one exterior ring and can have one or more inner rings.POLYGONM(((35 10 3, 45 45 4, 15 40 4, 10 20 5, 35 10 3), (20 30 3, 35 35 4, 30 20 5, 20 30 3))
MULTIPOINTMA set of points.MULTIPOINTM(-1 1 1, 0 0 3, 2 3 2)
MULTILINESTRINGMA set of LINESTRINGMs.MULTILINESTRINGM((0 0 1, 0 1 2, 1 1 3), (-1 1 2, -1 -1 2))
MULTIPOLYGONMA set of POLYGONMs.MULTIPOLYGONM(((2.25 0,1.25 1,1.25 -1,2.25 0)),((1 -1,1 1,0 0,1 -1)))

The M coordinate is convenient to associate a measure with a point in space. Without the M coordinate, you would require an extra property (of array type, not supported by the service) to store the measurement. The M coordinate does not require a spatial interpretation, and its unit is not related to the X, Y, Z coordinates. The M coordinate remains unchanged when the geometry gets transformed.

3D + measurement / time

The Geospatial service supports the following vector types, located in a 3-dimensional space plus an additional measure, each as an X, Y, Z, and M coordinates. The GeoJSON notation do not support the below vector types:

TypeDescriptionExample WKT
POINTZMA simple point.POINTZM(1 -1 11 22)
LINESTRINGZMA linestring in 3D specified by two or more distinct POINTZMs.LINESTRINGZM(0 0 2 233, 1 1 3 566, 1 -1 4 788, 3 4 5 988)
POLYGONZMA set of closed LINESTRINGZMs. A polygon must have exactly one exterior ring and can have one or more inner rings.POLYGONZM(((35 10 3 122, 45 45 4 211, 15 40 4 344, 10 20 5 566, 35 10 3 544), (20 30 3 233, 35 35 4 455, 30 20 5 677, 20 30 3 899))
MULTIPOINTZMA set of POINTZMs.MULTIPOINTZM(-1 1 1 0, 0 0 3 0, 2 3 2 0)
MULTILINESTRINGZMA set of LINESTRINGZMs.MULTILINESTRINGZM((0 0 1 1, 0 1 2 2, 1 1 3 3), (-1 1 2 1, -1 -1 2 2))
MULTIPOLYGONZMA set of POLYGONZMs.MULTIPOLYGONZM(((2.25 0 1 1,1.25 1 1 1,1.25 -1 1 1,2.25 0 1 1)),((1 -1 1 1,1 1 1 1,0 0 1 1,1 -1 1 1)))

Geometry collections

The Geospatial service finally supports collections of the previous vector types. It is a collection of heterogeneous vector types. The GeoJSON notation do not support the below vector types:

TypeDescriptionExample WKT
GEOMETRYCOLLECTIONA collection of 2D geometries.GEOMETRYCOLLECTION(MULTIPOINT(-1 1, 0 0, 2 3), MULTILINESTRING((0 0, 0 1, 1 1),(-1 1, -1 -1)),POLYGON((-0.25 -1.25, -0.25 1.25, 2.5 1.25, 2.5 -1.25, -0.25 -1.25)))
GEOMETRYCOLLECTIONZA collection of 3D geometries.GEOMETRYCOLLECTION Z (MULTIPOINT Z(-1 1 4, 0 0 2, 2 3 2), MULTILINESTRING Z ((0 0 1, 0 1 2, 1 1 3), (-1 1 1, -1 -1 2)), POLYGON Z(

(-0.25 -1.25 1, -0.25 1.25 2, 2.5 1.25 3, 2.5 -1.25 1, -0.25 -1.25 1),(2.25 0 2, 1.25 1 1, 1.25 -1 1, 2.25 0 2),(1 -1 2, 1 1 2, 0 0 2,1 -1 2)))

GEOMETRYCOLLECTIONMA collection of 2D geometries with a measurement.GEOMETRYCOLLECTION M (MULTIPOINT Z(-1 1 4, 0 0 2, 2 3 2), MULTILINESTRING M ((0 0 1, 0 1 2, 1 1 3), (-1 1 1, -1 -1 2)), POLYGON M(

(-0.25 -1.25 1, -0.25 1.25 2, 2.5 1.25 3, 2.5 -1.25 1, -0.25 -1.25 1),(2.25 0 2, 1.25 1 1, 1.25 -1 1, 2.25 0 2),(1 -1 2, 1 1 2, 0 0 2,1 -1 2)))

GEOMETRYCOLLECTIONZMA collection of 3D geometries with a measurement.GEOMETRYCOLLECTION ZM (MULTIPOINT ZM(-1 1 4 5, 0 0 2 5, 2 3 2 5))

Simple types

In addition to spatial property types, the following versatile types are supported:

TypeDescriptionExample
StringA character string.“Powered by geospatial”
LongA 64-bit signed integer.1234567
DoubleA 64-bit double precision floating point number.12345.6789
BooleanTrue or False.true
TimestampUnix timestamp, number of milliseconds since epoch.1637764395456

More on properties

By default, the feature type properties are non-null. It is possible to define optional properties simply by adding an optional field with true value in the property definition. In addition to this, it is possible to provide a note on a property using the description field.

...
{
...
"properties": {
"temperature": {
"type": "DOUBLE",
"optional": true,
"description": "air temperature in Celsius"
},
},
...
}
...

It is legal to define several geometry properties, each one with its SRID constraint.

This can for instance, be used to store different levels of details for a given feature type, or store geometries of varying nature:

 ...
{
"externalId": "multiple_geometries",
"properties": {
"centerOfGravity": {
"type": "POINT",
"srid": 4326
},
"centroid": {
"type": "POINT",
"srid": 4326
},
"shape": {
"type": "POLYGON",
"srid": 4326
},
"shapeOrig": {
"type": "POLYGON",
"srid": 2001
}
}
}
...

Defining a feature type with geometry properties without SRID constraint is also legal. In this case, the server allows mixing geometries located in different CRSs. The drawback is that the property cannot be indexed and used in search constraints; it can store and retrieve the geometry. When a modeling choice is made, the common practice is to project the geometries and store these copies in another geometry property with a fixed CRS, making it possible to apply search constraints on that additional geometry property.

...
{
"externalId": "multiple_geometries",
"properties": {
...
"trajectoryOrig": {
"type": "LINESTRING"
},
"trajectory": {
"type": "LINESTRING",
"srid": 4326
},
...
}
...
}
...

Searching for features

It is possible to retrieve a feature if you know its external id. But the typical use case with geospatial data is searching for data using a geospatial filter. The following operators are currently supported:

  • stWithin
  • stWithinProperly
  • stIntersects
  • stContains
  • stContainsProperly
  • stWithinDistance

The meaning of those operators follows the OpenGIS specification.

A filter expression example:

...
{
"stWithin": {
"property": "location",
"value": {
"wkt": "POLYGON((60.547602 -5.423433, 60.547602 -6.474416, 60.585858 -6.474416, 60.585858 -5.423433, 60.547602 -5.423433))"
}
}
}
...

A filter expression can combine multiple property constraints:

...
{
"and": [
{
"range": {
"property": "temperature",
"gt": 3.14
},
{
"not": {
"stWithin": {
"property": "location",
"value": {
"wkt": "POLYGON((60.547602 -5.423433, 60.547602 -6.474416, 60.585858 -6.474416, 60.585858 -5.423433, 60.547602 -5.423433))"
}
}
}
}
]
}
...

The spatial filtering is not required:

...
{
"and": [
{
"range": {
"property": "temperature",
"gt": 3.14
},
{
"range": {
"property": "pressure",
"lt": 129.4
}
}
]
}
...

The filter specification for feature search allows arbitrary complexity and depth:

...
{
"or": [
{
"and": [
{
"range": {
"property": "attr1",
"gt": 3.14
}
},
{
"range": {
"property": "attr1",
"lt": 5.03
}
}
]
},
{
"not": {
"range": {
"property": "attr2",
"lt": 6.28
}
}
}
]
}
...

The full filter language specification is available in the API specification.

Spatial filter operators

  1. stIntersects

    Geometry A intersects geometry B if and only if there are points belonging both to A and B. In particular any geometry intersects itself.

    In each of the examples below, the green geometry intersects the orange geometry.

  2. stWithin

    Geometry A is within geometry B if and only if all the points of A belong also to B. In particular every geometry is within itself. In each of the examples below, the green geometry is within the orange geometry. In each of the examples below, the green geometry is not within the orange geometry.

  3. stWithinProperly

    Geometry A is completely within geometry B if and only if all the points of A lie in the interior of B. Alternatively, geometry A is completely within geometry B if and only if A is within B and intersection of A and boundary of B is empty. Any geometry A is not completely within itself.

  4. stContains

    Relation "contains" is an oposite relation to "within": geometry A contains geometry B if and only if B is within A.

  5. stContainsProperly

    Relation "contains properly" is an oposite relation to "within properly": geometry A properly contains geometry B if and only if B is properly within A.

  6. stWithinDistance

    Geometry A is within distance of geometry B if and only if there is a pair of points a in A and b in B and distance between a and b is less than or equal the given distance. The distance is specified in units defined by the coordinate reference system (CRS). \ In the example below the geometries are within distance d from each other.

Indexes

By default, features index their externalId, createdTime, and lastUpdatedTime.

Several features in a given feature type impact the filtering features. Associating an index with a property allows for more efficient filtering when the property is present in the filter expression, but this is not a guarantee since it will depend on the index's selectivity, which is data-dependent.

Example of specifying an index on the point2d property:

...
{
...
"properties": {
...
"point2d": {
"type": "POINT",
"srid": 4326
},
...
},
"searchSpec": {
...
"point2d_idx": {
"properties": [ "point2d" ]
},
...
}
}
...

Indexes can span multiple properties, possibly of different types:

...
{
...
"properties": {
...
"point2d": {
"type": "POINT",
"srid": 4326
},
"temperature": {
"type": "DOUBLE"
},
...
},
"searchSpec": {
"point2d_temperature_idx": {
"properties": [ "point2d", "temperature" ]
}
}
}
...

Coordinate Reference Systems

A Coordinate Reference System (CRS) defines a 2D or 3D reference somewhere on or above/below the Earth's surface. Coordinates are usually defined in East/North/Height order but this can vary from one CRS to the next. Most CRSs are only valid over a limited part of the globe so for global mapping purposes it is common to use GPS latitude/longitude values as defined by WGS84 and encoded as the EPSG/SRID (Spatial Reference ID) number 4326.

Predefined CRSs

We currently support about 8500 well known CRSs, all defined by European Petroleum Survey Group (EPSG).

Custom CRS

If a user needs an EPSG entry that is currently missing, you can add it as a custom CRS.

Any API user can create a custom CRS; there will be a limit on how many such definitions each customer can make. A custom CRS is defined by a reference number (a positive integer), by a wkt (Well Known Text) string, and by a projString. The projString defines the geometrical projection needed to convert coordinates in this CRS into one of the standard CRSs. The projString needs to be in the format defined by the industry-standard PROJ library (https://proj.org/).

As an example the string +proj=ortho +lat_0=59.123456 +lon_0=4.7654321 +x_0=0 +y_0=0 +ellps=intl defines an orthogonal 3D CRS located at a point in the North Sea, oriented so that geographic east is the x-direction, y is north, and z points up. The ellipsoid used (International 1924) means that the lat/long values are according to that older standard, resulting in an offset (in this particular region) of about 30 m east-west from the GPS coordinate with the same numeric latitude/longitude values.

Automatic CRS transformations

When working with a feature type with a defined geometry property in a given CRS, by default it is illegal to use different CRS when creating/updating features or in geometry filters when searching/aggregating. This behavior can be changed using the allowCrsTransformation flag.

The Geospatial service will internally transform input CRS into the CRS defined in the feature type when the flag is true. It will be convenient to create representations in a preferable CRS of geometries originally defined in different CRS. This enhances a better way to search among these geometries. The drawback of this approach is a potential loss of precision. In that case, it is recommended to define another no CRS/mixed CRS geometry property with geometries stored in original CRSes, and use the first property only for spatial search.

The user can insert any geometry in the example below since the geometryOriginal property has no SRID defined. To enable search, the geometry4326 property is defined to store the same geometries, but in EPSG:4326. To automatically transform geometry to EPSG:4326, the allowCrsTransformation flag has to be set to true when creating/updating features and when defining spatial filters for search/aggregation.

...
{
...
"properties": {
...
"geometryOriginal": {
"type": "POINT"
},
"geometry4326": {
"type": "POINT",
"srid": 4326
},
...
},
...
}
...