Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define behaviour of bbox, bbox-crs and crs parameters #82

Closed
pomakis opened this issue Nov 29, 2021 · 7 comments
Closed

Define behaviour of bbox, bbox-crs and crs parameters #82

pomakis opened this issue Nov 29, 2021 · 7 comments

Comments

@pomakis
Copy link

pomakis commented Nov 29, 2021

I'm trying to work out the relationship between the bbox, bbox-crs and crs parameters as it pertains to map endpoints.

The bbox and bbox-crs parameters are defined clearly and completely in the draft "OGC API - Common - Part 2: Geospatial Data" specification, section 9.1.1. In this definition it clearly states that "the coordinate reference system of the values SHALL be interpreted as WGS 84 longitude/latitude (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a different coordinate reference system is specified in a parameter bbox-crs". I believe this requirement was inherited from the "OGC API - Features" specification, and it's a reasonable requirement.

The "OGC API - Features" specification also defines a parameter called crs, which indicates the coordinate system that the data should be returned in (irrespective of the coordinate system that the bounding box was expressed in), with the default being the native coordinate system of the collection. This parameter isn't defined in "OGC API - Common" yet, but it's generic enough that I believe someday it might.

The current draft of the "OGC API - Maps" specification doesn't really say anything about these parameters other than saying they'll be covered in a "bbox extension". But putting two and two together, it seems to imply the following behaviours:

  map parameters:  none
  map returned in: the collection's native extent, in the collection's
                   native coordinate system

  map parameters:  bbox=<bbox>
  map returned in: the minimum extent in the collection's native coordinate
                   that contains the specified CRS:84 <bbox> extent

  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>
  map returned in: the minimum extent in the collection's native coordinate
                   that contains the specified <bboxCrs> <bbox> extent

  map parameters:  crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the collection's native extent

  map parameters:  bbox=<bbox>&crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the specified CRS:84 <bbox> extent

  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>&crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the specified <bboxCrs> <bbox> extent

  (special case of the previous one)
  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>&crs=<bboxCrs>
  map returned in: the <bbox> extent, in the <bboxCrs> coordinate system

In all but the first and last cases, the actual extent of the returned image isn't guaranteed to be the same as the specified bbox. If a client wants a map of a specific extent in a specific coordinate system (which is probably the most common use case), then all three parameters must be provided, and the values of bbox-crs and bbox must be the same.

This behaviour seems a bit awkward, since both bbox-crs and bbox must be provided with the same values in the common use case. So what's probably a better way to go (for "OGC API - Maps" at least) would be to say that crs defaults to bbox-crs if the bbox parameter is explicitly present; otherwise it defaults to the collection's native coordinate system. Then we'd have the following:

  map parameters:  none
  map returned in: the collection's native extent, in the collection's
                   native coordinate system

  map parameters:  bbox=<bbox>
  map returned in: the <bbox> extent, in the CRS:84 coordinate system

  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>
  map returned in: the <bbox> extent, in the <bboxCrs> coordinate system

  map parameters:  crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the collection's native extent

  map parameters:  bbox=<bbox>&crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the specified CRS:84 <bbox> extent

  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>&crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the specified <bboxCrs> <bbox> extent

Since this is the behaviour that makes the most sense to me, this is how the CubeWerx OGC API server will be implemented (for now, at least).

Comments? Opinions?

@pomakis
Copy link
Author

pomakis commented Nov 29, 2021

Hmmm, how can a "OGC API - Maps" client even tell what the native coordinate reference system of a collection is? And is it even important to know? If the answer to these questions are "it can't" and "no", then if a map endpoint is invoked without any bbox, bbox-crs or crs parameters, it should return a CRS:84 map with the exact extent that's advertised as the CRS:84 spatial extent of the collection.

So that would leave us with:

  map parameters:  none
  map returned in: the collection's advertised CRS:84 extent

  map parameters:  bbox=<bbox>
  map returned in: the specified CRS:84 extent

  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>
  map returned in: the <bbox> extent, in the <bboxCrs> coordinate system

  map parameters:  crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the collection's native extent

  map parameters:  bbox=<bbox>&crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the specified CRS:84 <bbox> extent

  map parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>&crs=<crs>
  map returned in: the minimum extent in the <crs> coordinate system that
                   contains the specified <bboxCrs> <bbox> extent

Note in the case where just the crs parameter is specified, that the collection's native extent isn't necessarily its advertised CRS:84 extent, and that's okay. Also, in any request where crs != bbox-crs, the client will have no reliable way of knowing what the actual spatial extent of the returned map is (unless, of course, it's geotagged in some way). So the crs parameter should only be used when knowledge of the actual spatial extent of the returned map isn't necessary.

@pomakis
Copy link
Author

pomakis commented Nov 29, 2021

And of course the value of the crs parameter (or the value of the bbox-crs parameter if the crs parameter isn't present) needs to be one of the coordinate reference systems advertised in the collection's "crs" array.

Since the default value of bbox-crs is CRS:84, this has the interesting implication that all maps must be requestable in CRS:84. This is probably an unrealistic requirement. Hmmm....

@jerstlouis
Copy link
Member

jerstlouis commented Feb 13, 2022

@pomakis NOTE: The Maps SWG is about to start meeting more actively now that Tiles is almost done (Thursdays / 10:30 AM Ottawa/Gatineau time).

I believe that we have figured out more or less how (output) crs / bbox-crs / subset-crs can be implemented consistently in a logical manner across the different specifications (see also opengeospatial/ogcapi-coverages#144 in Coverages):

  1. The crs advertised in the collection's spatial extent is always in CRS84 (at least for Earthly data), because that is a requirement of Features and we want to be able to offer the same collection as e.g. Features + Maps + Vector Tiles + Map Tiles (multiple access mechanisms).
  2. The default output CRS for Features access when not specified is CRS84(h). For Maps and Coverages, I think it makes more sense that the default output CRS be the native/storage CRS instead. This avoids this unrealistic requirement you mention.
  3. Regarding "the client will have no reliable way of knowing what the actual spatial extent of the returned map", we will specify a response header to indicate the extent (in the output CRS) of the response, in addition to the CRS of the response (as done in Features - Part 2).
  4. client even tell what the native coordinate reference system of a collection -- With the storageCRS value, as defined in Features - Part 2
  5. The only case left to decide I think (Option A vs. Option B below) is the implied crs for the bbox parameter when bbox-crs is not specified and the storageCRS is NOT CRS84(h). We would have to pick whether that should be CRS84(h) or the storageCRS.

So to reconsider your different scenarios for Maps requests:

  parameters:  none
  output CRS: storageCRS
  extent: the collection's native extent in its storageCRS (may differ from the advertised CRS84 extent)

  parameters:  bbox=<bbox>
  output CRS: storageCRS
  extent:
     Option A: the bbox is interpreted as CRS84, and the extent is the minimum extent in the storageCRS
         containing the CRS84 bbox
     Option B: the bbox is interpreted as the storage CRS, and the extent is that specified in the storageCRS

  parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>
  output CRS: storageCRS (NOT the bboxCRS!)
  extent: the bbox is interpreted as BBOX CRS, and the extent is the minimum extent in the storageCRS
     that contains the bbox specified in that bbox CRS

  parameters:  crs=<crs>
  output CRS: the CRS specified
  extent: the minimum extent in the <crs> coordinate system that contains the collection's native extent

  parameters:  bbox=<bbox>&crs=<crs>
  output CRS: the crs specified
  extent:
     Option A:  the bbox is interpreted as CRS84, and the extent is the minimum extent in the output crs
        specified ontaining the CRS84 bbox
     Option B: the bbox is interpreted as the storage CRS, and the extent is the minimum extent in the
        <crs> coordinate system that contains the specified storageCRS <bbox> extent

  parameters:  bbox=<bbox>&bbox-crs=<bboxCrs>&crs=<crs>
  output CRS: the CRS specified
  extent: the minimum extent in the <crs> that contains the specified <bboxCrs> <bbox> extent

Note that we have implemented this approach on our sample server:

https://maps.ecere.com/ogcapi/collections/blueMarble/map?crs=EPSG:3395&bbox-crs=EPSG:4326&bbox=30,40,60,70

In our case currently all collections have a CRS84 storageCRS, so Options A and B are equivalent.

@joanma747
Copy link
Contributor

1.-
The spatial extent advertised in the collection's should always be in the CRS CRS84 (for Earthly data)
NOTE: That is a requirement of Features and we want to be able to offer the same collection as e.g. Features + Maps + Vector Tiles + Map Tiles (multiple access mechanisms)
NOTE: There is no obligation to provide the maps in CRS84
The extent should also be adverticed in the storageCRS ( storageCrsExtent ?)

2.-
The collections description will contain a storage CRS. If it is not there then we will assume CRS84.

3.-
The default output CRS for Maps with be be the native/storage CRS in the collection description.
If not CRS= param then storage CRS is returned.

4.-
New headers to report the ogcapi-bbox (copies an approach in tiles) and the content-crs (comes from features). It is a requirement (#87)

5.-
If bbox= is provided and there is no bbox-crs then the bbox is in CRS84

6.-
We have a list of supported CRS's in the collection. The first should be storage CRS.

  • The default CRS of the BBOX is CRS84
  • The default CRS of the map is storageCRS

@joanma747
Copy link
Contributor

joanma747 commented Aug 13, 2022

We agreed on: "2.- The collections description will contain a storage CRS. If it is not there then we will assume CRS84." but I'm not sure if we agreed on the "how" and if we need to specify this in OGC API Maps or request Common to do that.

We agreed that : NOTE: There is no obligation to provide the maps in CRS84 The extent should also be advertised in the storageCRS ( storageCrsExtent ?) but again, I'm not sure if we agreed on the "how" and if we need to specify this in OGC API Maps or request Common to do that.

We agreed that: 6.- We have a list of supported CRS's in the collection. The first should be storage CRS. but again, I'm not sure if we agreed on the "how" and if we need to specify this in OGC API Maps or request Common to do that.

For the moment I'm leaving these 3 aspects open in OGC API maps

@jerstlouis
Copy link
Member

jerstlouis commented Aug 13, 2022

@joanma747

  • On the first point, this would be handled by the requirements for point 3 that would specify that the server SHALL return a map output in the native CRS (storageCRS) specified in the collection description, or CRS84 if none is specified, unless overridden by the crs= query parameter. I don't think we need to care about storage / native CRS anywhere else, but we should make sure this all works well with collections also offered as Features, Coverages, Tiles, EDR... (related to Visualizing the payload from an implementation of OGC API - Features or the EDR API #53). Eventually this CRS stuff should really all be specified in Common.
  • About The extent should also be advertised in the storageCRS ( storageCrsExtent ?), that is really the topic of Do we need a spatial extent for each CRS that the server supports #45. Personally I feel like a requirement to include storageCrsExtent that eventually makes it to Common would be a good approach. Features - Part 2: CRS doesn't have that, but it also has a storageCrsCoordinateEpoch that we might need to consider.
  • About The first should be storage CRS I believe that Features eventually got rid of that requirement, so we might not need to specify that.

@joanma747
Copy link
Contributor

joanma747 commented Sep 1, 2022

We will use "storage CRS" because Feature API already defined this term. (A note saying that in coverages "native CRS" is used will be added). We applied all this in the standard.

OGC API - Maps Part 1: Core (1.0) automation moved this from Decided and To Be Applied to Done Sep 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants