Table of Contents
Warning: partially outdated
CRS GML definition candidates for SECORE
Preface
The opportunity to create arbitrary n-dimensional collections with rasdaman
raises the
need to properly address the referencing of, say, unconventional situations which can easily
go beyond the simple pure spatial 1D to 3D coverages.
Whereas the latter ones can still be correctly referenced with existing Coordinate Reference Systems
(CRSs) — usually by means of EPSG registered definitions (if we remain on Earth) — there are some other cases
which call for definitions to be designed: it is for example the case of pure pixel-space indexing of
images of whatever the dimensionality (what is usually known as CRS:1
space by the rasdaman
community), or else the case of CRS composition (or compounding) which can take place e.g. when a pressure
vertical axis gives volume to a 2D image, or when time shapes a group of spatial datasets into a series.
In line with the URL-oriented concept of CRS handling, where all the referencing metadata of a collection is moved to a separate web resolver in the form of a GML definition, this page proposes GML definitions and associated URI labeling needed to address this gap.
Image1D
<resolver>/def/crs/OGC/0.1/Image1D
E.g. for time dimension until GML issues are solved.
NOTE: showing optional components as <--comments—>.
<gml:ImageCRS gml:id="img1D"> <!-- gml:description>string</gml:description --> <!-- gml:descriptionReference/ --> <gml:identifier codeSpace="OGP">urn:ogc:def:crs:OGC:0.1:Image1D</gml:identifier> <!-- gml:name>string</gml:name --> <gml:remarks>CRS for 1D pixel-domain referenced axes.</gml:remarks> <!-- gml:domainOfValidity> <gmd:EX_Extent> <gmd:description>... </gmd:description> <gmd:geographicElement>... </gmd:geographicElement> <gmd:temporalElement>... </gmd:temporalElement> <gmd:verticalElement>... </gmd:verticalElement> </gmd:EX_Extent> </gml:domainOfValidity --> <gml:scope>Default CRS for 1D axis that are referenced in the pixel domain.</gml:scope> <gml:cartesianCS> <gml:CartesianCS gml:id="cartesian1D"> <!-- gml:description>string</gml:description --> <!-- gml:descriptionReference/ --> <gml:identifier codeSpace="OGP">urn:ogc:def:cs:OGC:0.1:Cartesian1D</gml:identifier> <!-- gml:name>string</gml:name --> <!-- gml:remarks>string</gml:remarks --> <gml:axis> <gml:CoordinateSystemAxis gml:id="i" uom="urn:ogc:def:uom:OGC:1.0:GridSpacing"> <!-- gml:description>string</gml:description --> <!-- gml:descriptionReference/ --> <gml:identifier codeSpace="OGP">urn:ogc:def:axis:OGC:0.1:i</gml:identifier> <gml:name>i</gml:name> <!-- gml:remarks>string</gml:remarks --> <gml:axisAbbrev>i</gml:axisAbbrev> <gml:axisDirection codeSpace="EPSG">positive</gml:axisDirection> <!-- gml:minimumValue>1.0</gml:minimumValue --> <!-- gml:maximumValue>1.0</gml:maximumValue --> <!-- gml:rangeMeaning codeSpace="http://www.example.com/">string</gml:rangeMeaning --> </gml:CoordinateSystemAxis> </gml:axis> </gml:CartesianCS> </gml:cartesianCS> <gml:imageDatum> <gml:ImageDatum gml:id="imageDatum"> <!-- gml:description>string</gml:description --> <!-- gml:descriptionReference/ --> <gml:identifier codeSpace="OGP">urn:ogc:def:datum:OGC:0.1:ImageDatumCellLowerBound</gml:identifier> <!-- gml:name>string</gml:name --> <!-- gml:remarks>string</gml:remarks --> <!-- gml:domainOfValidity>...</gml:domainOfValidity --> <gml:scope>A 1D image datum with the origin at the lower bound of the first cell in the axis.</gml:scope> <!-- gml:anchorDefinition>string</gml:anchorDefinition --> <!-- gml:realizationEpoch>2000-01-01</gml:realizationEpoch --> <gml:pixelInCell codeSpace="OGP">urn:ogc:def:pixelInCell:OGC:0.1:cellLowerBound</gml:pixelInCell> </gml:ImageDatum> </gml:imageDatum> </gml:ImageCRS>
Image2D
<resolver>/def/crs/OGC/0.1/Image2D
E.g. for 2D rasters with no geo-reference.
<gml:ImageCRS gml:id="img2D"> <!-- gml:identifier is optional but we *must* put it for SECORE to assign the URL --> <gml:identifier codeSpace="OGP">urn:ogc:def:crs:OGC:0.1:Image2D</gml:identifier> <gml:remarks>CRS for 2D pixel-domain referenced images.</gml:remarks> <!-- gml:scope is mandatory: --> <!-- The gml:scope property provides a description of the usage, or limitations of usage, --> <!-- for which this CRS-related object is valid. If unknown, enter "not known". --> <gml:scope>Default CRS for 2D images that are referenced in the pixel domain.</gml:scope> <!-- Not deprecated choices: gml:cartesianCS and gml:affineCS --> <gml:cartesianCS> <!-- gml:cartesianCS just contains one element: gml:CartesianCS (is it a joke?) --> <gml:CartesianCS gml:id="cartesian2D"> <gml:identifier codeSpace="OGP">urn:ogc:def:cs:OGC:0.1:Cartesian2D</gml:identifier> <!-- Here we can put from 1 to 3 axes: just one in this case. --> <gml:axis> <!-- Another so-called "association-role": contains just one element, a gml:CoordinateSystemAxis. --> <!-- I found this OGG:GridSpacing UoM (see [5] and [6]): we should upload it to SECORE as well --> <gml:CoordinateSystemAxis gml:id="i" uom="urn:ogc:def:uom:OGC:1.0:GridSpacing"> <gml:identifier codeSpace="OGP">urn:ogc:def:axis:OGC:0.1:i</gml:identifier> <gml:name>i</gml:name> <gml:axisAbbrev>i</gml:axisAbbrev> <gml:axisDirection codeSpace="EPSG">horizontal</gml:axisDirection> </gml:CoordinateSystemAxis> </gml:axis> <gml:axis> <gml:CoordinateSystemAxis gml:id="j" uom="urn:ogc:def:uom:OGC:1.0:GridSpacing"> <gml:identifier codeSpace="OGP">urn:ogc:def:axis:OGC:0.1:j</gml:identifier> <gml:name>j</gml:name> <gml:axisAbbrev>j</gml:axisAbbrev> <gml:axisDirection codeSpace="EPSG">vertical</gml:axisDirection> </gml:CoordinateSystemAxis> </gml:axis> </gml:CartesianCS> </gml:cartesianCS> <gml:imageDatum> <!-- Another "association-role" --> <gml:ImageDatum gml:id="imageDatum"> <gml:identifier codeSpace="OGP">urn:ogc:def:datum:OGC:0.1:ImageDatumGridUpperLeft</gml:identifier> <!-- Origin in the pixel domain is the upper-left pixel --> <gml:scope>A 2D image datum with the origin in the upper-left corner pixel of the grid.</gml:scope> <!-- gml:pixelInCell is a specification of the way an image grid is associated with the image data attributes. --> <!-- The required codeSpace attribute shall reference a source of information specifying the values and --> <!-- meanings of all the allowed string values for this property (see [8]). --> <gml:pixelInCell codeSpace="OGP">urn:ogc:def:pixelInCell:OGC:0.1:cellLowerBound</gml:pixelInCell> </gml:ImageDatum> </gml:imageDatum> </gml:ImageCRS>
Image3D
<resolver>/def/crs/OGC/0.1/Image3D
E.g. for 3D rasters with no geo-reference (CTs?).
<gml:ImageCRS gml:id="img3D"> <!-- gml:identifier is optional but we *must* put it for SECORE to assign the URL --> <gml:identifier codeSpace="OGP">urn:ogc:def:crs:OGC:0.1:Image3D</gml:identifier> <gml:remarks>CRS for 3D pixel-domain referenced images.</gml:remarks> <!-- gml:scope is mandatory: --> <!-- The gml:scope property provides a description of the usage, or limitations of usage, --> <!-- for which this CRS-related object is valid. If unknown, enter "not known". --> <gml:scope>Default CRS for 3D images that are referenced in the pixel domain.</gml:scope> <!-- Not deprecated choices: gml:cartesianCS and gml:affineCS --> <gml:cartesianCS> <!-- gml:cartesianCS just contains one element: gml:CartesianCS (is it a joke?) --> <gml:CartesianCS gml:id="cartesian3D"> <gml:identifier codeSpace="OGP">urn:ogc:def:cs:OGC:0.1:Cartesian3D</gml:identifier> <!-- Here we can put from 1 to 3 axes: just one in this case. --> <gml:axis> <!-- Another so-called "association-role": contains just one element, a gml:CoordinateSystemAxis. --> <!-- I found this OGG:GridSpacing UoM (see [5] and [6]): we should upload it to SECORE as well --> <gml:CoordinateSystemAxis gml:id="i" uom="urn:ogc:def:uom:OGC:1.0:GridSpacing"> <gml:identifier codeSpace="OGP">urn:ogc:def:axis:OGC:0.1:i</gml:identifier> <gml:name>i</gml:name> <gml:axisAbbrev>i</gml:axisAbbrev> <gml:axisDirection codeSpace="EPSG">base-horizontal</gml:axisDirection> </gml:CoordinateSystemAxis> </gml:axis> <gml:axis> <gml:CoordinateSystemAxis gml:id="j" uom="urn:ogc:def:uom:OGC:1.0:GridSpacing"> <gml:identifier codeSpace="OGP">urn:ogc:def:axis:OGC:0.1:j</gml:identifier> <gml:name>j</gml:name> <gml:axisAbbrev>j</gml:axisAbbrev> <gml:axisDirection codeSpace="EPSG">base-vertical</gml:axisDirection> </gml:CoordinateSystemAxis> </gml:axis> <gml:axis> <gml:CoordinateSystemAxis gml:id="h" uom="urn:ogc:def:uom:OGC:1.0:GridSpacing"> <gml:identifier codeSpace="OGP">urn:ogc:def:axis:OGC:0.1:k</gml:identifier> <gml:name>h</gml:name> <gml:axisAbbrev>h</gml:axisAbbrev> <gml:axisDirection codeSpace="EPSG">vertical</gml:axisDirection> </gml:CoordinateSystemAxis> </gml:axis> </gml:CartesianCS> </gml:cartesianCS> <gml:imageDatum> <!-- Another "association-role" --> <gml:ImageDatum gml:id="imageDatum"> <gml:identifier codeSpace="OGP">urn:ogc:def:datum:OGC:0.1:ImageDatumCubeUpperLeft</gml:identifier> <!-- Origin in the pixel domain is the upper-left pixel of the cube base --> <gml:scope>A 3D image datum with the origin in the upper-left corner pixel of the gridded cube base.</gml:scope> <!-- gml:pixelInCell is a specification of the way an image grid is associated with the image data attributes. --> <!-- The required codeSpace attribute shall reference a source of information specifying the values and --> <!-- meanings of all the allowed string values for this property (see [8]). --> <gml:pixelInCell codeSpace="OGP">urn:ogc:def:pixelInCell:OGC:0.1:cellLowerBound</gml:pixelInCell> </gml:ImageDatum> </gml:imageDatum> </gml:ImageCRS>
Cartesian?D
<resolver>/def/crs/OGC/0.1/Cartesian1D
<resolver>/def/crs/OGC/0.1/Cartesian2D
…
E.g. when elevation on a 3D dataset is based upon pressure: CCRS = (CRS2D + Cartesian1D). Otherwise when an arbitrary custom reference is needed.
Ideas:
- For single axis CRS:
EngineeringCRS
withlinearCS
, which is defined as "a one-dimensional coordinate system that consists of the points that lie on the single axis described; the associated coordinate is the distance – with or without offset – from the specified datum to the point along the axis". - For 2 or 3 axes CRS:
EngineeringCRS
withCartesianCS
, which is a 1-, 2-, or 3-dimensional coordinate system (in the 1-dimensional case, it contains a single straight coordinate axis; in the 2- and 3-dimensional cases gives the position of points relative to orthogonal straight axes; in the multi-dimensional case, all axes shall have the same length unit of measure) orUserDefinedCS
, which is "a two- or three-dimensional coordinate system that consists of any combination of coordinate axes not covered by any other coordinate system type."
The datum used must be an EngineeringDatum
, which simply defines the origin (namely the gml:anchorDefinition
) of the coordinate reference system.
the anchorDefinition is defined as a description, possibly including coordinates, of the definition used to anchor the datum to the Earth. Also known as the "origin", especially for engineering and image datums. The codeSpace attribute may be used to reference a source of more detailed on this point or surface, or on a set of such descriptions.
- For a geodetic datum, this point is also known as the fundamental point, which is traditionally the point where the relationship between geoid and ellipsoid is defined. In some cases, the "fundamental point" may consist of a number of points. In those cases, the parameters defining the geoid/ellipsoid relationship have been averaged for these points, and the averages adopted as the datum definition.
- For an engineering datum, the anchor definition may be a physical point, or it may be a point with defined coordinates in another CRS.may
- For an image datum, the anchor definition is usually either the centre of the image or the corner of the image.
- For a temporal datum, this attribute is not defined. Instead of the anchor definition, a temporal datum carries a separate time origin of type DateTime.
Example of EngineeringCRS
: http://www.epsg-registry.org/export.htm?gml=urn:ogc:def:crs:EPSG::5801
which uses the engineeringDatum
: http://www.epsg-registry.org/export.htm?gml=urn:ogc:def:datum:EPSG::9301
The preferred approach might be to define personal GML definitions with defined custom codes (e.g. MyCartesian1D
or PressureWGS84
),
instead of defining a single template to be customised via key/value pairs. It is straightforward and less prone to problems and errors.
TemporalCRSs
<resolver>/def/crs/OGC/0.1/ANSI-Date
<resolver>/def/crs/OGC/0.1/2000-mins
CRSs for temporal axes mapping. They could be created for standard measurements of time/date (e.g. Julian day, ANSI date), or for custom ad-hoc ones (e.g. the minutes' count from the beginning of 2000).
Template
<TemporalCRS xmlns="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" id="ID"> <description/> <!-- [0..1] Text description of the object (simple string) --> <descriptionReference/> <!-- [0..1] xlink:href attribute that references the an external description --> <identifier codeSpace="http://www.opengeospatial.org">ogc:def:crs:(AUTH):(VERSION):(CODE)</identifier> <name/> <!-- [0..*] One or more descriptive names --> <remarks>string</remarks> <!-- [0..1] --> <domainOfValidity> <!-- [0..1] (optional) This could be useful to define the MIN and MAX extent that this CRS offers --> <gmd:EX_Extent> <gmd:description>...</gmd:description> <gmd:temporalElement> <!-- Can also be geographicElement or verticalElement, but we need a temporal extent in this case --> <gmd:EX_TemporalExtent> <gmd:extent> <TimePeriod id="ID"> <!-- beginPosition and endPosition are of type __TimePoistion__ --> <!-- + It supports the description of temporal position according to the subtypes described in ISO:19108; --> <!-- + Values based on calendars and clocks use lexical formats that are based on ISO:8601, --> <!-- as described in XML Schema Part 2:2001; --> <!-- + A decimal value may be used with coordinate systems such as GPS time or UNIX time; --> <!-- + A URI may be used to provide a reference to some era in an ordinal reference system; --> <!-- Three XML __attributes__ appear on TimePositionType: --> <!-- * frame [anyURI] : temporal reference system (default ISO:8601, i.e. Gregorian calendar with UTC) --> <!-- * calendarEraName [string] : era name for time values using a calendar containing more than one era --> <!-- * indeterminatePosition [...] --> <beginPosition>(TimePosition)</beginPosition> <endPosition>(TimePosition)</endPosition> </TimePeriod> </gmd:extent> </gmd:EX_TemporalExtent> </gmd:temporalElement> </gmd:EX_Extent> </domainOfValidity> <!-- gmlscopeL: description/limitations of the usage, for which this CRS-related object is valid. If unknown, enter "not known". --> <scope>string</scope> <timeCS> <!-- "association role" --> <!-- TimeCS is a one-dimensional coordinate system containing a time axis, used to describe the temporal position of a --> <!-- point in the specified time units from a specified time origin. A TimeCS shall have *one* axis property element. --> <TimeCS id="ID"> <identifier codeSpace="http://www.opengeospatial.org">ogc:def:cs:(AUTH):(VERSION):(CODE)</identifier> <axis> <!-- UoM can be a URI identifier, but as well directly a string that defines it. --> <!-- As reference, visit: http://unitsofmeasure.org/ucum.html#iso1000 --> <CoordinateSystemAxis id="ID" uom="(uom)"> <identifier codeSpace="http://www.opengeospatial.org">ogc:def:axis:(AUTH):(VERSION):(CODE)</identifier> <!-- axisAbbrev [string] is the abbreviation used for this coordinate system axis; --> <!-- this abbreviation is also used to identify the coordinates in the coordinate tuple. --> <axisAbbrev>(abbreviation)</axisAbbrev> <!-- axisDirection can provide a human interpretable meaning to the axis; the *codeSpace* attribute shall reference a --> <!-- source of information specifying the values and meanings of all the allowed string values for this property. --> <axisDirection codeSpace="http://www.opengeospatial.org">(direction)</axisDirection> <!-- these next values are optional --> <minimumValue>(minValue)</minimumValue> <maximumValue>(maxValue)</maximumValue> <rangeMeaning codeSpace="http://www.opengeospatial.org"/> </CoordinateSystemAxis> </axis> </TimeCS> </timeCS> <temporalDatum> <!-- "association role" --> <TemporalDatum id="ID"> <!-- A TemporalDatum defines the origin of a Temporal Reference System. --> <identifier codeSpace="http://www.opengeospatial.org">ogc:def:datum:(AUTH):(VERSION):(CODE)</identifier> <scope>string</scope> <origin>(origin timestamp)</origin> </TemporalDatum> </temporalDatum> </TemporalCRS>
Example: ANSI date
<TemporalCRS xmlns="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" id="ANSI-Date-CRS"> <description>Continuous count of days starting from Jan 1, 1601 (00h00). Equal to floor(JulianDate-2305812.5)</description> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:crs:OGC:0.1:ANSI-Date</identifier> <name>ANSI date number (origin of COBOL integers dates)</name> <domainOfValidity> <gmd:EX_Extent> <gmd:description>Bottleneck in this case is date/time ranges accepted by current Java library (Date4j)</gmd:description> <gmd:temporalElement> <gmd:EX_TemporalExtent> <gmd:extent> <TimePeriod id="date4j-TP"> <beginPosition>0001-01-01</beginPosition> <endPosition>9999-12-31</endPosition> </TimePeriod> </gmd:extent> </gmd:EX_TemporalExtent> </gmd:temporalElement> </gmd:EX_Extent> </domainOfValidity> <timeCS> <TimeCS id="days-CS"> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:cs:OGC:0.1:days</identifier> <axis> <CoordinateSystemAxis id="day-axis" uom="d"> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:axis:OGC:0.1:days</identifier> <axisAbbrev>t</axisAbbrev> <!-- "wikipedia" codespace seems a joke but.. actually can give information of what "future" is! --> <axisDirection codeSpace="http://www.wikipedia.org">future</axisDirection> </CoordinateSystemAxis> </axis> </TimeCS> </timeCS> <temporalDatum> <TemporalDatum id="ANSI-TD"> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:datum:OGC:0.1:ANSI-Date</identifier> <origin>1601-01-01</origin> </TemporalDatum> </temporalDatum> </TemporalCRS>
Example: Minutes from 2000
<TemporalCRS xmlns="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" id="2000-mins-CRS"> <description>Continuous count of minutes starting from Jan 1, 2000 (00h00)</description> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:crs:OGC:0.1:2000-mins</identifier> <name>Minutes from 2000</name> <domainOfValidity> <gmd:EX_Extent> <gmd:description> Bottleneck in this case is time ranges accepted by current Java library Date4j (+- 0..9999) [need to find new library or manually understand e.g. how many years/days/hours/minutes are NNNNN minutes </gmd:description> <gmd:temporalElement> <gmd:EX_TemporalExtent> <gmd:extent> <TimePeriod id="date4j-TP"> <beginPosition>1999-12-25T01:21</beginPosition> <endPosition>2000-01-07T22:39</endPosition> </TimePeriod> </gmd:extent> </gmd:EX_TemporalExtent> </gmd:temporalElement> </gmd:EX_Extent> </domainOfValidity> <timeCS> <TimeCS id="minutes-CS"> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:cs:OGC:0.1:minutes</identifier> <axis> <CoordinateSystemAxis id="minutes-axis" uom="min"> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:axis:OGC:0.1:minutes</identifier> <axisAbbrev>t</axisAbbrev> <axisDirection codeSpace="http://www.wikipedia.org">future</axisDirection> </CoordinateSystemAxis> </axis> </TimeCS> </timeCS> <temporalDatum> <TemporalDatum id="2000-TD"> <identifier codeSpace="http://www.opengeospatial.org">urn:ogc:def:datum:OGC:0.1:2000</identifier> <origin>2000-01-01T00:00</origin> </TemporalDatum> </temporalDatum> </TemporalCRS>
NOTE: do not set "http://www.opengis.net/gml/3.2" as the XML namespace for GML, since SECORE does won't accept the definition, but silently (#233).
Referenced definitions:
- http://rasdaman.org:8080/def/pixelInCell/OGC/1.0/cellLowerBound would resolve to:
<gml:Definition gml:id="ogc-def-cellLowerBound"> <gml:description>The origin of the image coordinate system is at the lower bound of a grid cell.</gml:description> <!--gml:descriptionReference/--> <gml:identifier codeSpace="OGP">urn:ogc:def:pixelInCell:OGC:0.1:cellLowerBound</gml:identifier> <!--gml:name>string</gml:name--> <!--gml:remarks>string</gml:remarks--> </gml:Definition>
- http://rasdaman.org:8080/def/uom/OGC/1.0/GridSpacing would resolve to:
<BaseUnit xmlns="http://www.opengis.net/gml" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/base/units.xsd" gml:id="GridSpacing"> <gml:name>pixels</gml:name> <gml:description>Spacing between adjacent pixels points, or between centers of adjacent pixels</gml:description> <gml:identifier codeSpace="OGP">urn:ogc:def:uom:OGC:1.0:GridSpacing</gml:identifier> <gml:quantityType>Pixels</gml:quantityType> <gml:unitsSystem xlink:href="urn:ogc:def:nil:OGC:0:inapplicable"/> </BaseUnit>
- …
Issues
- does each datum (1D, 2D, 3D) require its own
pixelInCell
definition, or can thecellLowerBound
be adopted for grids of any dimension? - are the so-called association roles necessary? For instance
cartesianCS
to includeCartesianCS
: SECORE output directly puts aCartesianCS
, but is this valid GML? - …
External links:
- Image CRSs
- Cartesian CRSs
- Temporal CRSs