opengeospatial / coverage-implementation-schema

OGC Coverage Implementation Schema draft specifications
1 stars 1 forks source link

DomainSet: Specifying both Geospatial and Temporal CRS? #7

Open jerstlouis opened 3 years ago

jerstlouis commented 3 years ago

Currently GeneralGrid specifies a single srsName. Is that enough to specify both the spatial and temporal reference systems? Are there SRS defined supporting all combinations of srs & trs? The Common extent approach specifies those separately.

pebau commented 3 years ago

yes, it is - maybe look into CIS and the examples? Features are lagging behind, they still do not see space and time coordinates as one continuum, leading to several shortcomings.

jerstlouis commented 3 years ago

@pebau As we've identified, the latest CIS examples are currently lacking and misleading, and we are trying to improve on this and address those shortcomings.

The related example I see from the rasdaman OGC API server is:

"srsName" : "https://ows.rasdaman.org/def/crs-compound?1=https://ows.rasdaman.org/def/crs/OGC/0/AnsiDate&2=https://ows.rasdaman.org/def/crs/EPSG/0/4326",

Our client (and most clients) will not want to go and fetch and analyze responses from that server describing the SRS, nor will they want to do fragile parsing of such a combination string, rather we want to quickly identify known reference systems that we are already aware of. Developers (at least myself) would much prefer the following, using OGC NA definition servers, over that long string that we have no idea what to do with:

   "srsName" : "http://www.opengis.net/def/crs/EPSG/0/4326",
   "trsName" : "http://www.opengis.net/def/uom/ISO-8601/0/Gregorian",

This has nothing to do with seeing space and time as one continuum or not, it's the exact same idea of creating a "compound" SRS by combining a spatial and time reference sytems, but it would be done in a way that is actually practical.

pebau commented 3 years ago

@jerstlouis there are reasons behind this, you might want to understand coverages before writing standards about them; at least read the spec. When endeavoring new multi-dimensional pathways it might become necessary to get out of the comfort zone of 2-D flatland.

jerstlouis commented 3 years ago

Thank you @pebau .

I do see those two examples:

http://schemas.opengis.net/cis/1.1/json/examples/25_3D_time.json http://schemas.opengis.net/cis/1.1/json/examples/30_4D_height+time.json

also using http://www.opengis.net/def/crs-compound .

However, both fail to resolve because there is an XML character code (&) in there:

http://www.opengis.net/def/crs-compound?1=http://www.opengis.net/def/crs/EPSG/0/4979&2=http://www.opengis.net/def/crs/OGC/0/AnsiDate

should probably be

http://www.opengis.net/def/crs-compound?1=http://www.opengis.net/def/crs/EPSG/0/4979&2=http://www.opengis.net/def/crs/OGC/0/AnsiDate

I also see this text in the CIS 1.1 specifications:

Additionally, some redundant information is present in the domain set for efficiency reasons: the number of dimensions, axis labels, and UoM (Unit of Measure) labels simplify parsing the coverage as the parser does not have to retrieve the CRS definition, such as from the OGC CRS resolver at http://www.opengis.net/def/crs and http://www.opengis.net/def/crs-compound.

Yes this minimizes the problem of going and fetching the URL, but still it seems to me that having separate properties for the spatial and temporal CRS (with the exact same meaning as crs-compound), would be much more useful to clients, and that is the approach used in Common. Perhaps also allowing for referencing an SRS that defines them together would address these reasons you referred to, as well as backward compatibility?

On a separate note, I am struggling to find the CRS to use for Gregorian Date+Time, e.g. to use in Coverages API with ISO 8601 -- any help would be welcomed!

At http://www.opengis.net/def/crs/OGC/0 I see AnsiDate, JulianDate, UnixTime, ChronometricGeologicTime, and http://www.opengis.net/def/crs/OGC/0/Temporal but that seems to require an epoch and uom parameter.

UPDATE: I noticed that http://www.opengis.net/def/trs/ISO-8601/0/ is in /trs rather than /crs but then its member definition http://www.opengis.net/def/uom/ISO-8601/0/Gregorian is actually in /uom.

Would that be appropriate to use with combine-crs ? (No, it doesn't get resolved)

Thanks.

pebau commented 3 years ago

@jerstlouis I keep on bringing up personal opinions which you do not substantiate. You claim that something is "better" for "the user". I don't see that, practical experience is different. Normally only programs see that URL anyway, as well as script hackers; implementers just concatenate strings, which is trivial in all languages.

What actually is tedious is exactly what your idea does not remedy either: the limitation to CRS URLs is the source for these ugly, strange, and long CRS spelling. This focused behavior was dictated by CRS.SWG and OGC-NA, and we accepted that earlier; it is also easy to handle by program. But we might propose to extend with shorthands. For example, 3D WGS84+time might be written exactly like that: "EPSG:4326+OGC:AnsiDate"; the tool internally can expand this to OGC-NA conforming URLs (WCPS 1.1 does that). However, this is not in our power, OGC-NA needs to decide.

Separation of CRS axes is a dead end, a dinosaur from last millennium. Exactly the unification of all axes is a key progress in Earth data service science since then. Did you find out meantime why separation is a disadvantage?

We may want to concentrate on essentials rather than doing cosmetics at will now, without considering effects. Standards are about continuity.

jerstlouis commented 3 years ago

@pebau

I understand we want all axes to be treated the same, regardless of whether they represent spatial or temporal or other dimensions of the DomainSet. We are in complete agreement there.

We are also agreeing that defining ahead of time every single combination of spatial CRS and time and height is not very practical. And I understand that this is what crs-combine was trying to achieve.

But the issue I raise with crs-combine is that this information then becomes purely informative, and is not something clients can really make use of. This is because there are significant problems associated with both: A) trying to fetch that crs-combine result from the server, and B) trying to parse that crs-combine string to split it into its constituents CRSes

Specifying the constituent CRS as separate properties serves exactly the same objectives as the combine-crs (the resulting SRS is not any less unified), but that does not suffer from those limitations. Therefore clients can actually recognize these CRSes, and as a result this allows them to make sense of what each axis name enumerated in the DomainSet represents.

This is what I mean by "separate properties being more useful to the client" (from the client developer's perspective -- while concatenating strings is trivial for the server, splitting up URI strings is generally avoided in clients), and I am considering practical experience developing a OGC API - Coverages client & server and over the last year working on Technology Integration Experiments with multiple servers, whose implementers are still not clear on how to specify the combined spatial & temporal CRS because of this.

I agree it would be good to discuss this with OGC NA @ghobona and maybe @joanma747 might also be interested to chime in... Thank you!

KathiSchleidt commented 3 years ago

Trying to pick apart the multiple issues being mixed here. From what I read, this is actually several issues:

On the first 2 we can do something, on the third only warn developers to run some regex over their strings before trying to consume ;)

pebau commented 3 years ago

@jerstlouis "splitting up URI strings is generally avoided in clients" - to get out of the shifting sands of assumptions about developer capabilities, do we have a definition of the minimum capabilities any OAPI c/s developer must have? I mean, string splitting is 1-3 lines of JavaScript...

pebau commented 3 years ago

@kathischleidt:

What other alternatives would be available for the provision of multiple CRS?

The neatest that comes to my mind is like the above example: "EPSG:4326+OGC:AnsiDate"; GDAL understands similar syntax AFAIK, it can be mapped to ISO 19111, can be parsed trivially.

I am sure @jerstlouis has found this already, but just to illustrate one more reason for the simple single-CRS approach: "EPSG:4326+OGC:AnsiDate" can be differentiated from "OGC:AnsiDate+EPSG:4326". The separated approach cannot.

pebau commented 3 years ago

@kathischleidt:

The trickiness of formulating and using a CRS they way it's been defined by OGC

Actually, this is managed by ISO 19111 / CRS.SWG, and they are not amused about anybody bypassing their specs (which makes sense, no further islands please). Instead of GML you can use WKT, but experience tells this doesn't really make it easier. So: onboarding CRS experts would help so much.

jerstlouis commented 3 years ago

@pebau

I mean, string splitting is 1-3 lines of JavaScript...

It is not about string splitting being difficult, but that it then gets complicated to define (or properly implement) the rules surrounding the use of crs-compound and how one should extract the multiple constitutents out of it, and which combined CRSes are considered equivalent, etc. In other places in OGC API the CRS are URI which are compared as expected to be exactly the same, if I understand correctly. Essentially if we stick to a single srsName and the use of crs-compound, it would be useful for these rules to be clarified in a user's guide.

The fact that an issue like https://issues.apache.org/jira/browse/SIS-341 exists speaks to the fact that this is not trivial.

But what I am gathering is that in fact clients wishing to make use of the srsName property right now are more or less expected to recognize crs-compound and then parse the string to identify the consituent CRSes.

I am sure @jerstlouis has found this already, but just to illustrate one more reason for the simple single-CRS approach: "EPSG:4326+OGC:AnsiDate" can be differentiated from "OGC:AnsiDate+EPSG:4326".

I assume you are referring to the axis order being different... The axes are explicitly enumerated in the DomainSet in axisLabels and axis, so I would hope that this could provide the overall order if the spatial and temporal CRS were provided separately.

jerstlouis commented 3 years ago

Interestingly, the opengis.net crs-compound script seems to only resolve successfully in one order (with a confusing error message as well):

http://www.opengis.net/def/crs-compound?1=http://www.opengis.net/def/crs/OGC/0/AnsiDate&2=http://www.opengis.net/def/crs/EPSG/0/4326

says

Failed resolving CRS definition: 2=http://www.opengis.net/crs/EPSG/0/4326

While

http://www.opengis.net/def/crs-compound?1=http://www.opengis.net/def/crs/EPSG/0/4326&2=http://www.opengis.net/def/crs/OGC/0/AnsiDate

works.

However, this (flipping the numbers in the request URL instead) works and returns "Julian Date / WGS 84" instead of "WGS 84 / Julian Date":

http://www.opengis.net/def/crs-compound?2=http://www.opengis.net/def/crs/EPSG/0/4326&1=http://www.opengis.net/def/crs/OGC/0/AnsiDate

which is really confusing... Likely a bug on the definition server?

pebau commented 3 years ago

@jerstlouis

Essentially if we stick to a single srsName and the use of crs-compound, it would be useful for these rules to be clarified in a user's guide.

Best forward this request to CRS.SWG - just to repeat once more, CRS handling is, for a good purpose, not homebrewn here but adopted from the CRS.SWG. Or just start writing it and then get it scrutinized by them - as always in a do-ocracy this might speed things up.

The fact that an issue like https://issues.apache.org/jira/browse/SIS-341 exists speaks to the fact that this is not trivial.

ahem, issue is fixed and closed - that seems to me the regular software development process I am used to.

I assume you are referring to the axis order being different... The axes are explicitly enumerated in the DomainSet in axisLabels and axis, so I would hope that this could provide the overall order if the spatial and temporal CRS were provided separately.

...and this is less error prone, distributing information and hiding it?? I wouldn't want to sit in that jet. Ya know, change just for the sake of change and "I like this style better"... I remember in older times we had documented issues with detailed technical requirements and use cases, not just "but I prefer".

pebau commented 3 years ago

@jerstlouis

which is really confusing... Likely a bug on the definition server?

might be indeed, would be a nice catch - opening a ticket now, will report back.

jerstlouis commented 3 years ago

@pebau

"crs" : "http://www.opengis.net/def/crs/EPSG/0/4326",
"trs" : "http://www.opengis.net/def/crs/OGC/0/AnsiDate",

or

"crsComponents" : [
   "http://www.opengis.net/def/crs/EPSG/0/4326",
   "http://www.opengis.net/def/crs/OGC/0/AnsiDate"
]

is what is less error prone, less subject to misinterpretation and confusion, and much more straightforward than:

 "srsName" :
"http://www.opengis.net/def/crs-compound?1=http://www.opengis.net/def/crs/EPSG/0/4326&2=http://www.opengis.net/def/crs/OGC/0/AnsiDate",

as exemplified by:

I don't think it's a matter of preference or style :) But I realize there's an interoperability cost with any change, so perhaps it is not worth changing anything (other than clarifications / guidance on the use of crs-compound and more examples).

crs-compound is not happy with 2=http://www.opengis.net/def/uom/ISO-8601/0/Gregorian so I'm still wondering if we are missing a CRS definition for Date+Time using ISO-8601?

It would be nice if such a temporal CRS was defined where axisAbbrev is actually called time rather than ansi or unix (odd choices of abbreviation names for the axis).

Right now the closest thing accepted by crs-compound supporting time is http://www.opengis.net/def/crs/OGC/0/UnixTime, but specifying this in the DomainSet seems at odds with ISO-8601 values expected by the subset parameters (they're not seconds since 1970).

pebau commented 3 years ago

@jerstlouis

crs-compound is not happy with 2=http://www.opengis.net/def/uom/ISO-8601/0/Gregorian so I'm still wondering if we are missing a CRS definition for Date+Time using ISO-8601?

hm, not sure where that URL comes from. It refers to uom, BTW. If you use the one in the above URL you can get the proper path; here the overview: http://www.opengis.net/def/crs/OGC/0

If would be nice if a such a temporal CRS was defined where axisAbbrev is actually called time rather than ansi or unix (odd choices of abbreviation names for the axis).

it is, indeed - I share your view that this is counterintuitive -> OGC-NA could resolve to have aliases, then we can set that up on short notice.

Right now the closest thing accepted by crs-compound supporting time is http://www.opengis.net/def/crs/OGC/0/UnixTime, but specifying this in the DomainSet seems at odds with ISO-8601 values expected by the subset parameters (they're not seconds since 1970).

There was a long discussion with CRS.SWG at some time, with the effect that both should be possible. Roger Lott & friends (and GML folks!) for a long time insisted on seconds since epoch, and didn't like at all to have strings instead of numbers in coordinates; meantime they are converted and sell it as their outcome :) and 8601 is seen as a user-friendly way of specifying it, and it can be converted to seconds following standard tools like in Unix.

KathiSchleidt commented 3 years ago

What worries me most on this discussion is that just as CIS 1.1 has opened up the coverage perspective to be able to deal with all sorts of axes, this discussion is again focusing it down to the classical lat&long plus sorta-elevation (long as you're in m or a standard CRS) and time - does help to explain why some of the Copernicus DIAS are bypassing coverage models altogether and just going for a clean data cube solution

jerstlouis commented 3 years ago

@pebau Yes I know it refers to uom, and so it is understandable that it doesn't work, but as I mentioned above, that URI appears as a member definition of http://www.opengis.net/def/trs/ISO-8601/0/ (which also has me wondering why we have /trs but some temporal reference system are also found in /crs)

pebau commented 3 years ago

@jerstlouis

@pebau Yes I know it refers to uom, and so it is understandable that it doesn't work, but as I mentioned above, that URI appears as a member definition of http://www.opengis.net/def/trs/ISO-8601/0/ (which also has me wondering why we have /trs but some temporal reference system are also found in /crs)

diversity :) OGC has given up on clear guidance in favour of having competing ecosystems, and that is the effect now. Certainly for people outside even more confusing than for us. We might ask OGC-NA...

jonblower commented 3 years ago

Genuine question, which I'm sure is an old chestnut - if CRSs are denoted by name or identifier, what's the method for specifying a CRS that takes parameters, i.e. one that is not completely predefined at an existing URL?

pebau commented 3 years ago

@jonblower

this below is from a slide, sorry for the hasty copy. A paper is here:
D. Misev, M. Rusu, P. Baumann: A Semantic Resolver for Coordinate Reference Systems. Proc. 11th International Symposium on Web and Wireless Geographical Information Systems (W2GIS), Naples, Italy, April 12-13, 2012, Springer LNCS 7236

jerstlouis commented 3 years ago

In light of all this, how is a simple client expected to look at the single CRS URI, and say "yes, I know what this is, I can work with data expressed in this CRS and map it to what I support"?

If there are more than one single URI string which are equivalent, and the client is working offline or does not wish to make additional HTTP requests or perform analysis of yet another document at another location, how can this be done? Even if the client is ready to do some string parsing / analysis of the URI, there is nowhere to begin on how it should proceed to do so.

I feel like providing some guidance regarding this (whether in CIS itself, or a user's guide, or in OGC API - Coverages or its user's guide) would go long way, something like:

Is there anything like this, currently? Is that something covered by the CRS SWG? I don't think I am alone having difficulties coming across this this type of information, even when actively looking for it, while I think it should be very easy for developers to find.

This is because many clients are not really interested in looking up the CRS of every new coverage they come across using an online request, but rather are trying to identify the CRS used in that data to quickly identify it and/or look it up in their own local database.

jonblower commented 3 years ago

@pebau - thanks, very useful!

@jerstlouis - yes, I understand and feel this pain too. I also don't particularly want to dereference a URI in order to get the details of a CRS. I'd rather (a) get an identifier I can look up in my own database, or (b) see the complete definition of the CRS inline (does the "Inline CRS definition" Peter mentions above do the trick? What's the syntax for this?)

I'm biased by my background in CF-NetCDF, where (almost) everything is defined inline, and it's common to use CRSs that have not been defined in an external database. CF-NetCDF can also map different CRSs to different dimensions, and combinations of dimensions. I don't think this creates any limitations on use: you can still request arbitrary slices in any dimension of course and this takes care of CRSs of any dimensionality. I personally find the CF-NetCDF approach to be practical, which is why we used a similar-ish structure in CoverageJSON.

jerstlouis commented 3 years ago

@jonblower About b), that is great for custom CRS, but for cases that can be handled by a), I feel there should be a recommendation that the simpler aproach be used. Parsing a custom CRS makes it difficult to then map the data to a known CRS, unless you can somehow relate axis names and projections, e.g. to integrate multiple data sources, or visualize on a virtual globe.

A simple client may also not want to write or import tons of code to parse an inline CRS definition when it only supports one or two CRSes, only to try to figure out if the inline CRS defined is one of these.

For an inline CRS, I don't see any examples currently in the JSON examples. The CIS specs mentions "GML, WKT or otherwise" at one spot.

It is not clear to me how this should be done in CIS JSON, and I think a proper JSON encoding based on either the GML or WKT CRS definition should be required.

jonblower commented 3 years ago

About b), that is great for custom CRS, but for cases that can be handled by a), I feel there should be a recommendation that the simpler aproach be used. Parsing a custom CRS makes it difficult to then map the data to a known CRS, unless you can somehow relate axis names and projections, e.g. to integrate multiple data sources, or visualize on a virtual globe.

Oh, I totally agree. I wouldn't want to "spell out" EPSG:4326 inline every time I used it. Custom CRSs could get very tricky, but the main use case I'm thinking of here is a parameterised projection (e.g. polar stereographic, Lambert Equal-Area), or rotated-pole CRS (which is surprisingly common in meteorology, but does not appear in any external database that I know of).

It is not clear to me how this should be done in CIS JSON, and I think a proper JSON encoding based on either the GML or WKT CRS definition should be required.

Yes, I'd support that. We made a suggestion in CoverageJSON, but this isn't really fully baked so I'm certainly not going to propose it as a final solution, maybe just a starting point: https://covjson.org/spec/#514-providing-inline-definitions-of-crss.

pebau commented 3 years ago

@jonblower

So the two conflicting goals seem to be: simplicity and unique identification (aka URL resolution). Maybe we can get the ball rolling with OGC-NA ?

FWIW, the following mail I have sent to @ghobona on 2021-mar-16:

from various sides I hear that CRS URLs are considered quite inconvenient, in particular when it comes to compound CRSs as frequently used in coverages, but also in applications combining, eg, some random horizontal CRS with a vertical one. We have a case with a 6D cube, just imagine the CRS!

Actually, there are common notations which can make life easier - ESRI, PROJ, etc use that regularly in one or the other shape - simple example: EPSG:4326 = www.opengis.net/def/crs/EPSG/0/4326

OGC-NA could introduce well-defined shorthands, such as "EPSG:4326+OGC:AnsiDate+OGC:Index1D" with a simple mapping of

This mail is just a first ping to see whether there is an opportunity, so I am curious about your thoughts on it.

pebau commented 3 years ago

@jonblower

Oh, I totally agree. I wouldn't want to "spell out" EPSG:4326 inline every time I used it. Custom CRSs could get very tricky, but the main use case I'm thinking of here is a parameterised projection (e.g. polar stereographic, Lambert Equal-Area), or rotated-pole CRS (which is surprisingly common in meteorology, but does not appear in any external database that I know of).

It is not clear to me how this should be done in CIS JSON, and I think a proper JSON encoding based on either the GML or WKT CRS definition should be required.

exactly: CIS simply uses CRSs following the method that was given to us then. Any encoding, JSON or so, should come from CRS.SWG, therefore. They would not enjoy us defining a "proprietary" solution.

pebau commented 3 years ago

The CIS specs mentions "GML, WKT or otherwise" at one spot.

The silent, cautious opening of a door out of the GML cage!

jerstlouis commented 3 years ago

@jonblower the parameterized projection is definitely an interesting use case...

If we had a simple JSON data structure to easily describe a CRS by specifying projection, spheroid, units, etc., in the end I think that would be a lot more practical/recognizable than a URI that clients end up having to do some not well defined parsing, or deference like:

http://www.opengis.net/def/crs?authority=OGC&version=1.3&code=AUTO42003&UoM=m&CenterLongitude=-100& CenterLatitude=45

It doesn't seem that projinfo even supports these URLs from what I read there (they mention URN, but not URL).

Is there a JSON Schema for that WKT->JSON mapping? I am curious if there had previously been any other effort to map WKT CRS to JSON yet? Also, I also could not easily find any UML diagram on the WKT document... Maybe this is something that may also be related to the upcoming Testbed-17 Enhanced GeoJSON work? We should probably touch base with the CRS SWG to be aware of the latest developments.

I just discovered PROJJSON, which does provide a JSON schema:

PROJJSON is a JSON encoding of WKT2:2019 / ISO-19162:2019, which itself implements the model of OGC Topic 2: Referencing by coordinates. Apart from the difference of encodings, the semantics is intended to be exactly the same as WKT2:2019.

pebau commented 3 years ago

@jonblower @jerstlouis @KathiSchleidt

A simple client may also not want to write or import tons of code to parse an inline CRS definition when it only supports one or two CRSes, only to try to figure out if the inline CRS defined is one of these.

definitely agreed that parsing of the complete definition is undesirable. But bypassing is not an option either - the client wants to know the CRS to decide whether it can put the hurricane on the right spot on the map.

For an inline CRS, I don't see any examples currently in the JSON examples.

In XML it would be simply be a GML CRS definition embedded in the metadata. In JSON it would likewise be...no, that's really too ugly, XML in JSON. So we definitely need a JSON equivalent (earlier someone asked for the same in RDF), fully supported!

jonblower commented 3 years ago

@jerstlouis - I'm not aware of a formal WKT->JSON mapping, and we didn't do a schema for it ourselves, so I don't know, I'm afraid. If we want a syntax for a "parameterised" CRS, maybe there is inspiration we can take from CF (e.g. here).

@pebau - yes, I fully understand that CIS inherits this from CRS.SWG. And I quite like the shorthand you propose above, in principle at least. It's nice to have a simple and readable way to address common use cases.

I must admit I still don't quite understand how CIS maps the components of the compound CRS to the domain axes, but I'm sure this must be defined - do you have any quick pointers?

pebau commented 3 years ago

@jonblower

I must admit I still don't quite understand how CIS maps the components of the compound CRS to the domain axes, but I'm sure this must be defined - do you have any quick pointers?

that is simply by name: with "1=EPSG:4326 & 2=OGC:AnsiDate" (to use the shorthand) you get Lat/Long as axis 1 + 2, followed by axis 3 = time. So it is by position of the numeric key in the KVP.

jerstlouis commented 3 years ago

@jonblower

I'm not aware of a formal WKT->JSON mapping, and we didn't do a schema for it ourselves, so I don't know, I'm afraid

PROJJSON seems to be very promising, and seems in line with where you wanted to go next in terms of defining an encoding for WKT2?

It would be interesting to see if the CRS SWG might be willing to take on the standardization of the PROJJSON encoding as an OGC standard.

jonblower commented 3 years ago

that is simply by name: with "1=EPSG:4326 & 2=OGC:AnsiDate" (to use the shorthand) you get Lat/Long as axis 1 + 2, followed by axis 3 = time. So it is by position of the numeric key in the KVP.

Thanks @pebau - so in this case the underlying data array is 3D, and the client figures out that EPSG:4326 is a 2D CRS and therefore corresponds with the first two axes of the array - is that right?

Do the number of dimensions in the data array always have to match the sum of the dimensions of the CRSs? I'm wondering about the case where (for example) the data array is 1D, but the CRS is 3D (e.g. a 1D series of xyt points, like a ship track)?

Or, perhaps more awkwardly, a case where the data array is 2D but the CRS is 3D, e.g. an array with time on one axis and xy position on the other, representing a synchronised set of timeseries at a number of points on the Earth's surface? In this case, one domain axis (time) would have a 1D CRS and the other (position) would have a 2D CRS (like EPSG:4326).

(In case it helps, a CovJSON example of something similar is here - see Trajectory: https://covjson.org/spec/#613-examples and a few more examples in the Domain Specs: https://covjson.org/domain-types/)

jonblower commented 3 years ago

(@jerstlouis - at first glance, PROJJSON looks just the thing!)

pebau commented 3 years ago

@jonblower

that is simply by name: with "1=EPSG:4326 & 2=OGC:AnsiDate" (to use the shorthand) you get Lat/Long as axis 1 + 2, followed by axis 3 = time. So it is by position of the numeric key in the KVP.

Thanks @pebau - so in this case the underlying data array is 3D, and the client figures out that EPSG:4326 is a 2D CRS and therefore corresponds with the first two axes of the array - is that right?

pretty much - see CIS 1.0 + 1.1 for details

Do the number of dimensions in the data array always have to match the sum of the dimensions of the CRSs? I'm wondering about the case where (for example) the data array is 1D, but the CRS is 3D (e.g. a 1D series of xyt points, like a ship track)?

that's the difference between geometric and topological dimensions, yes.

Or, perhaps more awkwardly, a case where the data array is 2D but the CRS is 3D, e.g. an array with time on one axis and xy position on the other, representing a synchronised set of timeseries at a number of points on the Earth's surface? In this case, one domain axis (time) would have a 1D CRS and the other (position) would have a 2D CRS (like EPSG:4326).

see CIS 1.1 axis types here.

jonblower commented 3 years ago

Thanks @pebau - it seems that the key is in the difference between geometric and topological dimensions, but I can't find an explanation of these in the CIS1.1 spec. There are a couple of mentions of those terms in the spec but I can't see a definition of either. Could you point me in the right direction please?

Alternatively, are there examples of CIS encoding (XML or JSON, I don't mind) of those things (e.g. 1D series of xyt points, like a ship track)?

(I'm aware this might be a bit off-topic from this original ticket, so we could open a new one - but it's related to the problem of interpreting CRSs.)

jerstlouis commented 3 years ago

@joanma747 The CIS 1.1 examples are at http://schemas.opengis.net/cis/1.1/json/examples/ I'm not sure if that scenario is covered though...

jonblower commented 3 years ago

@jerstlouis - thanks, yes, I've seen the examples but I don't think there's one there yet that fits that specific use case. The point cloud use case is probably the closest, but that example doesn't have any coordinate referencing information in the domainSet (although it's there in the envelope).

I assume that (if there were an srsName in that particular domainSet) that could be a compound CRS that shows how to interpret the coordinate tuples in directMultiPoint.coordinates. Could that include a time dimension too?

By the way, I think this use case argues against having separate srsName and trsName attributes, because of the need to create coordinate tuples which have a predictable relationship with CRS axes. It might not be clear which of the members of each tuple represents time. (Plus there might be more than one spatial reference system (xy and z), and even more than one temporal reference system, if you're dealing with overlapping forecasts - blame the meteorologists for that one!)

pebau commented 3 years ago

@jonblower

I assume that (if there were an srsName in that particular domainSet) that could be a compound CRS that shows how to interpret the coordinate tuples in directMultiPoint.coordinates. Could that include a time dimension too?

yes, absolutely - any spatial, temporal, or "abstract" axis qualifies.

By the way, I think this use case argues against having separate srsName and trsName attributes, because of the need to create coordinate tuples which have a predictable relationship with CRS axes. It might not be clear which of the members of each tuple represents time. (Plus there might be more than one spatial reference system (xy and z), and even more than one temporal reference system, if you're dealing with overlapping forecasts - blame the meteorologists for that one!)

couldn't agree more! We had this discussion just this afternoon in the OGC TC meeting; the separation is unfortunate, backwards oriented, and closes doors for several use cases. And complicates artificially.

What is really ugly is the requirement to have mile-long URLs for CRS identifiers. I have made a proposal today, let's see whether it gets through.

jonblower commented 3 years ago

Thanks @pebau. Just thinking further about linking CRS axes with grid axes, or positions in a coordinate tuple. If I've understood correctly (please let me know if I'm wrong!) the CIS structure means that the axes must be used in the same order that they are in the component CRSs, and that axes from different CRSs can't be interleaved?

This probably isn't very clear, so here's an example. Let's say I have a 4D grid that uses CRS:84 for the xy positions, SomeVerticalCRS for the z positions and AnsiTime for the t positions. If the order of axes in my data array are lon-lat-height-time, I don't have a problem; my CRS string would be something like "1=CRS:84,2=SomeVerticalCRS,3=time", using the handy shorthand syntax.

But let's say that I want to express my data array using a different axis order, e.g. lat-time-lon-height. Could I do this? I can't quite see how that would work, as you need more information than just the order of CRSs. You need to think about the CRS axes individually and reorder them.

You could create a custom CRS with the axis order you want, I suppose. Maybe that could be done inline, as you probably wouldn't want to define it and host it at a URL? In CF-NetCDF (and in CoverageJSON) you don't have the same issue because the CRS-data axis mapping is more explicit.

I do appreciate that this looks like a rather contrived use case, and it probably doesn't come up very often, but I have used it myself, mainly when thinking about performance (reordering the axes on disk is a good way to increase performance for certain extraction use cases, as of course you know!)

KathiSchleidt commented 3 years ago

I'm not the expert here, but would expect this to be explained in the coverageFunction: It describes the mapping function from the domain to the range of the coverage. For a grid coverage, it specifies the serialization of the multi-dimensional grid in the range set.

pebau commented 3 years ago

@jonblower normally you would not want to split Lat+Long, but you can go down to axis level for a free combination. However, differentiating EPSG:4326+OGC:AnsiDate vs OGC:AnsiDate+EPSG:4326 is an issue of practical relevance indeed.

jonblower commented 3 years ago

but you can go down to axis level for a free combination

@pebau can you confirm if the coverageFunction is the way to do this, as @KathiSchleidt suggests? In the examples I've seen I have only seen this used for modifying the grid offsets, but maybe there's a structure that can map the axis order like this?

(I know doing things like splitting lat and lon is a bit of an obscure use case, but I think it's a valid one that I'd have an occasional need for.)

pebau commented 3 years ago

@jonblower no, as stated it is about assembling the axes in the domain set. CIS has made the world a little easier to handle, in particular CIS 1.1.

jonblower commented 3 years ago

@pebau - thanks, but I don't think I've quite understood yet. I wonder if an example of my use case could be created to clarify things? I think it would be helpful in any mapping from NetCDF to CIS. Let me know if I should raise a ticket somewhere else about this for consideration.