Skip to content

schemas: Changes to sync OGC API - Common review #953

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jerstlouis
Copy link
Member

@jerstlouis jerstlouis commented Sep 24, 2024

@jerstlouis
Copy link
Member Author

It seems like the correct thing should be "oneOf" rather than "anyOf" to reflect the mutual exclusion.

There's a discussion in the S/O post (which suggested anyOf) about this. I'm leaning towards "oneOf" and thinking of fixing Common to use "oneOf".

Copy link
Member

@cportele cportele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the specific comments.

On "anyOf" vs "oneOf": If used for validation, both will deliver the same result, if all options are mutually exclusive. With "oneOf" validation will take longer, but one could argue that it expresses the semantics more clearly. Anyhow, I really think we should avoid recommending the use of "anyOf" or "oneOf".

@@ -9,7 +9,7 @@ The following normative documents contain provisions that, through reference in

* [[ogc06_103r4]] Open Geospatial Consortium (OGC). OGC 06-103r4: **OpenGIS® Implementation Standard for Geographic information - Simple feature access - Part 1: Common architecture**. Edited by J. Herring. 2011. Available at http://portal.opengeospatial.org/files/?artifact_id=25355

* [[qudtunits]] QUDT.org. **QUDT Units Vocabulary 2.1**. Edited by R. Hodgson. 2024. Available at https://www.qudt.org/doc/DOC_VOCAB-UNITS.html.
* [[qudt]] QUDT.org. **QUDT Ontologies, derived models and vocabularies 2.1**. Edited by R. Hodgson. 2024. Available at https://www.qudt.org/.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not correct. Only the QUDT Units Vocabulary is a normative reference. The QUDT Ontologies could be added to the bibliography.

Copy link
Member

@cportele cportele Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meeting 2024-10-07: This change should be reversed. QUDT can be added to the bibliography.

@@ -12,7 +12,7 @@ The Requirements Class "Schemas" specifies basic provisions for schemas of items
|Indirect Dependency |<<json-schema-validation,JSON Schema Validation: A Vocabulary for Structural Validation of JSON>>
|Indirect Dependency |<<ogc06_103r4,Simple feature access - Part 1: Common architecture>>
|Indirect Dependency |<<ucum,The Unified Code for Units of Measure>>
|Indirect Dependency |<<qudtunits,QUDT Units Vocabulary>>
|Indirect Dependency |<<qudt,QUDT Ontologies, derived models and vocabularies>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not correct. Only the QUDT Units Vocabulary is normatively referenced from provisions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meeting 2024-10-07: Same as above, this should be reversed.

^|J |Required properties SHOULD be included in "required".
^|K |The JSON Schema keywords SHOULD be constrained to the those mentioned in this recommendation and requirement `/req/{req-class}/properties`.
^|H |For integer properties that represent enumerated values without providing a description for each, "enum" SHOULD be provided.
^|I |For integer properties that represent enumerated values while providing a description for each, "oneOf" with a combination of "const" and "title" for each entry SHOULD be provided.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using "enum" for all lists of enumerated values is easier to parse and more predictable. "oneOf" is always more problematic as one never knows how complex the different options are. And "oneOf" is often not supported in tooling.

Having descriptions for each enum could also be handled as an orthogonal capability. In ldproxy, for example, we support references to a dictionary/object that maps codes/values to titles (we call them codelists). An example: schema and a codelist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meeting 2024-10-07: Both options are valid and they have their drawbacks. We need more time to think about this more and work this out. @cportele will document other options.

|===
^|*Requirement {counter:req-num}* |/req/{req-class}/{req}
^|A |The keyword "x-ogc-nilValues" SHALL be used to identify the values considered nil.
^|B |The value of the keyword "x-ogc-nilValues" SHALL be an array of objects, each including a mandatory "const" value and an optional "title" explanation of the meaning of that particular nil value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. Using "enum" seems to be cleaner.

@cportele
Copy link
Member

As discussed earlier in this PR, I have created examples for two options for representing properties with an enumerated list of values.

The first option has the advantage that all information is in the schema; no external information needs to be accessed.

The second option has the advantage that enum is easier to parse/handle than oneOf and that a separate resource for codelists may be useful for other purposes (in the API or separate from the API). A codelist URI may exist and the codelist may already be managed / published at the URI.

  1. Using oneOf with each option with a const and optional title / description values.

Example, see properties ZI037_REL and F_CODE:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://demo.ldproxy.net/daraa/collections/CulturePnt/schema",
  "title": "Cultural (Points)",
  "type": "object",
  "required": [
    "geometry",
    "ZI001_SDV"
  ],
  "properties": {
    "ZI006_MEM": {
      "title": "Memorandum",
      "type": "string"
    },
    "FCSUBTYPE": {
      "title": "Feature Subtype Code",
      "type": "integer"
    },
    "ZI037_REL": {
      "title": "Religious Designation",
      "oneOf": [
        {
          "const": 1,
          "title": "Buddhism"
        },
        {
          "const": 2,
          "title": "Islam"
        },
        {
          "const": 3,
          "title": "Roman Catholic"
        },
        {
          "const": 5,
          "title": "Judaism"
        },
        {
          "const": 6,
          "title": "Orthodox"
        },
        {
          "const": 7,
          "title": "Protestant"
        },
        {
          "const": 8,
          "title": "Shinto"
        },
        {
          "const": 9,
          "title": "Hinduism"
        },
        {
          "const": 10,
          "title": "Shia"
        },
        {
          "const": 11,
          "title": "Sunni"
        },
        {
          "const": 12,
          "title": "Nestorian"
        },
        {
          "const": 13,
          "title": "Chaldean"
        },
        {
          "const": 14,
          "title": "Mixed and/or No Designation"
        },
        {
          "const": -999999,
          "title": "No Information"
        }
      ]
    },
    "ZI001_SDP": {
      "title": "Source Description",
      "type": "string"
    },
    "UFI": {
      "title": "Unique Entity Identifier",
      "type": "string"
    },
    "geometry": {
      "x-ogc-role": "primary-geometry",
      "format": "geometry-point"
    },
    "id": {
      "x-ogc-role": "id",
      "type": "integer"
    },
    "F_CODE": {
      "title": "Feature Type Code",
      "x-ogc-role": "type",
      "oneOf": [
        {
          "const": "AK121",
          "title": "Lookout"
        },
        {
          "const": "AL012",
          "title": "Archaeological Site"
        },
        {
          "const": "AL030",
          "title": "Cemetery"
        },
        {
          "const": "AL130",
          "title": "Memorial Monument"
        },
        {
          "const": "BH075",
          "title": "Fountain"
        }
      ]
    },
    "ZI001_SDV": {
      "title": "Last Change",
      "x-ogc-role": "primary-instant",
      "format": "date-time",
      "type": "string"
    },
    "ZI005_FNA": {
      "title": "Name",
      "type": "string"
    }
  }
}
  1. Using enum and a separate codelist resource.

Same example (link):

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://demo.ldproxy.net/daraa/collections/CulturePnt/schema",
  "title": "Cultural (Points)",
  "type": "object",
  "required": [
    "geometry",
    "ZI001_SDV"
  ],
  "properties": {
    "ZI006_MEM": {
      "title": "Memorandum",
      "type": "string"
    },
    "FCSUBTYPE": {
      "title": "Feature Subtype Code",
      "type": "integer"
    },
    "ZI037_REL": {
      "title": "Religious Designation",
      "x-ldproxy-codelistUri": "https://demo.ldproxy.net/daraa/codelists/daraa%2Frel",
      "enum": [
        -999999,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14
      ],
      "type": "integer"
    },
    "ZI001_SDP": {
      "title": "Source Description",
      "type": "string"
    },
    "UFI": {
      "title": "Unique Entity Identifier",
      "type": "string"
    },
    "geometry": {
      "x-ogc-role": "primary-geometry",
      "format": "geometry-point"
    },
    "id": {
      "x-ogc-role": "id",
      "type": "integer"
    },
    "F_CODE": {
      "title": "Feature Type Code",
      "x-ldproxy-codelistUri": "https://demo.ldproxy.net/daraa/codelists/daraa%2Ff_code",
      "x-ogc-role": "type",
      "enum": [
        "AK121",
        "AL012",
        "AL030",
        "AL130",
        "BH075"
      ],
      "type": "string"
    },
    "ZI001_SDV": {
      "title": "Last Change",
      "x-ogc-role": "primary-instant",
      "format": "date-time",
      "type": "string"
    },
    "ZI005_FNA": {
      "title": "Name",
      "type": "string"
    }
  }
}

@cportele
Copy link
Member

@jerstlouis - Now that we have merged #979, we probably need to close this PR and start from or at least update the pull request.

@jerstlouis
Copy link
Member Author

Thanks @cportele . We will try to review this Thursday with @joanma747 and we'll update this PR.

- The main change relates to the ability to describe meaning of enum values
  related to opengeospatial/ogcapi-coverages#173 (comment)
  using a combination of `anyOf` with `const` + `title` as described in
  https://stackoverflow.com/questions/64233370/in-json-schema-how-to-define-an-enum-with-description-of-each-elements-in-the-e
- Changes also introduce a new `x-ogc-nilValues` keyword for identifying nil values
- Other changes are gramamr fixes and minor clarifications
- Changing indirect dependency to QUDT in general as opposed to QUDT units since QUDT can also used for
  semantic definitions (not only QUDT units)
- Clarified that JSON Schema keywords can also include additional keywords in section below
@jerstlouis
Copy link
Member Author

jerstlouis commented May 2, 2025

@cportele We started reviewing this together with @joanma747 today .
I rebased and updated the PR and addressed some of the concerns.

Because the document structure in the Common proposal is so different now, having split the requirements into separate files to follow the previous practice (which I personally find very cumbersome), we discussed how to proceed.

We would like to review/contribute directly in this Features repo / current document structure instead, but ensure that the document is agnostic of OGC API - Features. We added a new commit with some initial changes to that effect.
We will probably abandon the Common proposal document for now, trying to synchronize any important changes that was there.

There is still a concern about the potential for confusion for implementations of e.g., OGC API - Coverages to reference conformance URIs for an OGC API - Features extension. One potential solution is that we later produce a very simple Common - Part 3 document which simply references OGC API - Features - Part 5: Schemas as a dependency with no additional requirements.

This brings us to ask about the normative references including OGC API - Features - Part 1 in Part 5.

By the same logic why QUDT ontology should not have been a normative reference because it was not referenced in any of the requirements text, shoudn't Features - Part 1 also not be? There is no dependency on OGC API - Features - Part 1 in any of the requirement classes.

Considering that everything in the document would be agnostic of OGC API - Features, wouldn't the scope also be wrong in saying that it is an extension to OGC API - Features - Part 1: Core ?
It makes a lot more sense as an extension to OGC API - Common :)

One other thing we discussed was that the x-ogc-collectionId referencing a collection on the same server seems overly restrictive. Was this previously discussed and/or is there another mechanism to reference an arbitrary collection on any server?

Thanks!

@cportele
Copy link
Member

cportele commented May 4, 2025

@jerstlouis

The PR seems to be a mix of changes for which no issues exist. That makes it hard to review the PR and eventually accept it. My proposal is to close this PR and create issues for the different topics first (or where it is a simple editorial change, also a PR, but focussed on a single aspect). I can see at least the following unrelated topics in the current PR which should be discussed separately, not in a single PR:

  • Wording changes to replace "feature" by "data".
  • Wording changes related to units.
  • A capability to identify null values.

On replacing "feature" by "data": I agree that there are cases where we can reduce the use of "feature" in the document. In other cases, mainly the req classes "Core roles for features" and those about feature references, this is about feature data. At least all the normative and informative text have been driven by features as the resources. Maybe they can be generalized, but I don't think that simply replacing "feature" by "data" works or is the right thing to do. This could be a future task for the Common group.

This brings us to ask about the normative references including OGC API - Features - Part 1 in Part 5.

By the same logic why QUDT ontology should not have been a normative reference because it was not referenced in any of the requirements text, shoudn't Features - Part 1 also not be? There is no dependency on OGC API - Features - Part 1 in any of the requirement classes.

Correct, there is currently no dependency on Features Part 1 in any of the requirements classes - at least at the moment. If there is really no dependency, then this document reference has to be moved to the bibliography.

Considering that everything in the document would be agnostic of OGC API - Features, wouldn't the scope also be wrong in saying that it is an extension to OGC API - Features - Part 1: Core ?
It makes a lot more sense as an extension to OGC API - Common :)

Not in my view, see above.

One other thing we discussed was that the x-ogc-collectionId referencing a collection on the same server seems overly restrictive. Was this previously discussed and/or is there another mechanism to reference an arbitrary collection on any server?

Currently only the simple case of feature references in the same dataset and where all references target the same collection are considered. We have an issue to explore, if this is ok for now or if we should support additional requirements in v1.0, see #938.

We frequently have more complex cases and support them in ldproxy (references to external resources or references to varying collections), but when drafting the text we focussed on the main use case. It might be better to explore the more complex cases in a code sprint first and test options with running code (that is, after v1.0).

Edited to add: For this particular case, one can use "x-ogc-uriTemplate" instead of "x-ogc-collectionId" to reference a feature in a collection in another API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants