Skip to content

Guidance on referencing an existing feature geometry in spatial filters #1052

Description

@esgn

Context

We are working on GeoContext, an MCP server developed at IGN France to let AI assistants discover, query, and reason over French geospatial reference data exposed through standard APIs.

GeoContext provides tools for geocoding, elevation, administrative context, cadastral data, urban planning data, and WFS-backed feature queries. Users interact with those tools through natural language, while GeoContext translates structured tool calls into geospatial API requests.

A common use case is to answer questions that involve:

  • a first feature used as a spatial reference;
  • a second feature collection to query;
  • optional attribute filters.

For example:

Find buildings higher than 20 meters in Vincennes.

This involves two different feature collections:

  • an administrative collection, used to identify the municipality of Vincennes;
  • a building collection, queried with an attribute filter and a spatial filter.

GeoContext workflow

In GeoContext, the assistant does not directly manipulate CQL filters or large geometries. It calls structured tools.

The first step is to resolve Vincennes as an existing administrative feature. Conceptually, GeoContext may query the administrative collection like this:

{
  "typename": "ADMINEXPRESS-COG.LATEST:commune",
  "where": [
    {
      "property": "code_insee",
      "operator": "eq",
      "value": "94080"
    }
  ],
  "limit": 1,
  "result_type": "results"
}

GeoContext returns the matching feature without exposing the full geometry to the language model. Instead, the returned feature contains a lightweight feature_ref object:

{
  "type": "Feature",
  "id": "commune.<wfs-feature-id>",
  "geometry": null,
  "properties": {
    "code_insee": "94080",
    "nom_officiel": "Vincennes"
  },
  "feature_ref": {
    "typename": "ADMINEXPRESS-COG.LATEST:commune",
    "feature_id": "commune.<wfs-feature-id>"
  }
}

The exact feature_id is the WFS feature identifier returned by the service. The important point is that the assistant can reuse this feature_ref without receiving, serializing, or passing around the municipality geometry.

The second step is to query the building collection using that feature_ref as the spatial reference:

{
  "typename": "BDTOPO_V3:batiment",
  "where": [
    {
      "property": "hauteur",
      "operator": "gt",
      "value": "20"
    }
  ],
  "intersects_feature_filter": {
    "typename": "ADMINEXPRESS-COG.LATEST:commune",
    "feature_id": "commune.<wfs-feature-id>"
  },
  "result_type": "results"
}

Internally, GeoContext then:

  1. fetches the referenced administrative feature by typename and feature_id;
  2. extracts its geometry;
  3. converts that geometry to the representation needed by the WFS / CQL filter;
  4. builds the final spatial predicate against the building collection.

Conceptually, the final filter is equivalent to:

INTERSECTS(
  building_geometry,
  geometry_of("ADMINEXPRESS-COG.LATEST:commune", "commune.<wfs-feature-id>")
)
AND hauteur > 20

The geometry_of(...) expression above is only illustrative. It is not meant as a proposed syntax.

The underlying need is to express that the geometry operand of a spatial predicate is the geometry of an existing feature, identified by collection/type name and feature identifier.

Current limitation

With OGC API - Features Part 3 and CQL2, spatial predicates can be expressed using geometry literals, for example:

S_INTERSECTS(geometry, POLYGON (...))

This works when the geometry is small and directly available to the client.

However, in workflows like the one described above, the reference geometry is already associated with an existing feature resource. Inlining it as a geometry literal has several drawbacks:

  • the geometry may be large;
  • the resulting CQL2 filter may become very long;
  • GET URLs may become impractical or invalid;
  • POST payloads become heavier than necessary;
  • the client has to fetch, serialize, and re-inject a geometry that the server may already be able to resolve;
  • the geometry may have to pass through an AI assistant context, which is undesirable;
  • CRS transformation, simplification, validation, and access control may be better handled server-side;
  • implementations may end up creating vendor-specific mechanisms for the same recurring pattern.

Question

Is there currently an intended pattern in OGC API - Features / CQL2 to express a spatial filter where one operand is the geometry of an existing feature resource?

For example, something conceptually equivalent to:

S_INTERSECTS(
  geometry,
  GEOMETRY_OF('/collections/administrative_units/items/12345')
)

or:

S_INTERSECTS(
  geometry,
  FEATURE_GEOMETRY('administrative_units', '12345', 'geometry')
)

Again, the exact syntax above is only illustrative. The question is about the intended standard pattern, not about proposing a specific syntax.

Related implementation precedent

GeoServer has a WFS / ECQL extension called querylayer, with functions such as:

  • querySingle;
  • queryCollection;
  • collectGeometries.

This allows filters on one layer to use values, including geometries, queried from another layer.

This seems close to the use case described above, but it appears to be a GeoServer-specific extension rather than a standardized OGC API - Features / CQL2 mechanism.

Possible standardization directions

We are not necessarily proposing a specific solution, but we would appreciate guidance on whether this belongs in:

  • OGC API - Features Part 3: Filtering / CQL2;
  • standardized CQL2 functions;
  • OGC API - Features Part 10: Query;
  • another OGC API building block;
  • a future extension;
  • or whether this should remain implementation-specific.

Possible approaches could include:

  1. A standardized CQL2 function to dereference a feature geometry.
  2. A standardized way to use feature resource URIs as geometry operands.
  3. A query resource / POST query pattern where reference geometries can be passed by identifier.
  4. A standard mechanism for same-service feature geometry references.
  5. Guidance that services may expose server-side named, temporary, or cached geometries.
  6. Explicit guidance that this is out of scope for OGC API - Features.

Constraints and concerns

Any standardized approach would likely need to address:

  • same-service vs remote feature references;
  • authorization and access control when dereferencing another feature;
  • CRS handling;
  • geometry property selection when a feature has multiple geometries;
  • performance and memory limits;
  • maximum number of referenced features;
  • caching behavior;
  • lifecycle of temporary references, if any;
  • error behavior when the referenced feature does not exist;
  • error behavior when the referenced feature has no usable geometry;
  • whether the referenced geometry may be simplified, transformed, or validated by the server;
  • whether this should work only for spatial predicates or more generally for cross-collection queries.

Expected outcome

We would like to know whether the OGC API - Features SWG sees this use case as:

  • already supported by an existing standard pattern;
  • intentionally out of scope;
  • suitable for a future requirement class;
  • better handled in CQL2;
  • better handled in OGC API - Features Part 10: Query;
  • better handled by implementation-specific extensions;
  • or worth documenting as a recommended implementation pattern.

Any guidance would be useful for implementers trying to avoid non-interoperable vendor-specific filter functions while still supporting practical workflows involving existing feature geometries.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions