Study alignment of the gpf_wfs_get_features filtering language with OGC API Features / CQL2 Basic
Context
The project currently exposes a structured query language through gpf_wfs_get_features, designed to avoid requiring the model to write raw CQL or WFS queries directly.
This language already covers several concepts that are close to OGC filtering standards:
- attribute filtering through
where:
eq
ne / neq naming to clarify
lt
lte
gt
gte
in
is_null
- implicit
AND combination between where clauses
- attribute selection through
select
- sorting through
order_by
- spatial filtering through
spatial_operator:
bbox
intersects_point
dwithin_point
intersects_feature
- generation of WFS requests using
cql_filter
- prior validation of property names through the embedded catalog /
gpf_wfs_describe_type
This approach is intentionally safer and more guided than exposing raw CQL. However, it would be useful to formally compare it with the current OGC state of the art, especially:
- OGC API Features Part 3: Filtering
- CQL2 1.0.0
- CQL2 Basic
- CQL2 Text
- CQL2 JSON
- Queryables
Goal
Study how the current geocontext query language could be brought closer to OGC API Features Part 3 / CQL2, while preserving the current benefits:
- robustness for LLM-driven calls;
- strict validation of property names;
- abstraction over WFS / GeoServer-specific details;
- ergonomic MCP JSON contract;
- compatibility with the GeoPlateforme WFS service.
The goal is not necessarily to make the tool fully OGC API Features-compliant immediately, but to define a clear roadmap:
- what is already aligned;
- what diverges;
- what could be renamed or restructured;
- what would require a proper CQL2 translation layer;
- what should remain intentionally project-specific.
Questions to investigate
1. Comparison with CQL2 Basic
Compare the current operators with those expected in CQL2 Basic:
- equality;
- inequality;
- ordered comparisons;
IS NULL;
- logical combinations;
- parenthesized expressions;
- literal handling;
- value typing;
- queryable properties.
Questions to address:
- Should
ne remain as-is, or should it be renamed to neq, not_eq, or another spelling?
- Should
and, or, and not be exposed explicitly?
- Should implicit
AND combination be preserved for simple use cases?
- Should we introduce an expression tree representation closer to CQL2 JSON?
- Should the supported subset be documented as a “CQL2 Basic-like” profile?
2. Filter representation
The current model uses a flat list:
{
"where": [
{
"property": "code_insee",
"operator": "eq",
"value": "75056"
}
]
}
Study whether the language should evolve toward a representation closer to CQL2 JSON, for example:
{
"filter": {
"op": "=",
"args": [
{ "property": "code_insee" },
"75056"
]
}
}
Or toward an intermediate representation that remains easier for LLMs to produce:
{
"filter": {
"and": [
{
"property": "code_insee",
"operator": "eq",
"value": "75056"
},
{
"property": "population",
"operator": "gt",
"value": "100000"
}
]
}
}
Points to assess:
- readability for an LLM;
- ease of validation with Zod;
- backward compatibility;
- expressiveness;
- proximity to CQL2 JSON;
- ability to compile to:
- WFS
cql_filter;
- OGC API Features
filter;
- CQL2 Text;
- CQL2 JSON.
3. Attribute selection
Compare the current select parameter with OGC API Features practices.
Points to assess:
- whether
select maps to concepts such as properties in some OGC API implementations;
- compatibility with WFS
propertyName;
- current behavior where geometry is automatically added in
result_type="request" mode;
- distinction between:
- returned properties;
- filterable properties;
- sortable properties;
- geometry properties.
4. Queryables
Study how gpf_wfs_describe_type could be brought closer to the OGC API Features queryables concept.
Questions:
- Can we expose an internal structure close to a JSON Schema queryables response?
- Which metadata should be published?
- exact property name;
- type;
- enum values, if any;
- nullable status;
- filterable status;
- sortable status;
- geometry or non-geometry property;
- CRS / geometry type;
- Should we introduce a dedicated tool such as
gpf_wfs_get_queryables?
- Should we generate an output compatible, or nearly compatible, with
/collections/{collectionId}/queryables?
5. Spatial operators
Compare the current spatial operators with CQL2 and OGC API Features Part 3.
Current operators:
bbox
intersects_point
dwithin_point
intersects_feature
Points to assess:
- mapping to
S_INTERSECTS;
- mapping to
BBOX;
- status of
DWITHIN, which is closer to an extension than to the CQL2 Basic core;
- geometry representation in CQL2 Text;
- geometry representation in CQL2 JSON;
- CRS handling through
filter-crs;
- difference between:
- simplified LLM-friendly operators;
- standard CQL2 spatial functions;
- GeoServer CQL functions supported in practice.
Open questions:
- Should
intersects_point be renamed to something closer to the standard?
- Should simplified operators remain as a façade?
- Should we add a compilation layer toward
S_INTERSECTS(geom, POINT(...))?
- Should
dwithin_point be documented as a non-Basic extension?
- Should operators such as
contains, within, crosses, touches, etc. be added, or should the language intentionally remain minimal?
6. Transport and protocol
The current system compiles to a WFS request using cql_filter.
OGC API Features Part 3 uses concepts such as:
filter
filter-lang
filter-crs
/queryables
- optionally
/functions
Questions to investigate:
- Should we only align the internal language?
- Should we produce CQL2 Text output?
- Should we produce CQL2 JSON output?
- Should we introduce a multi-target compilation backend?
wfs-cql
cql2-text
cql2-json
- possibly
ogc-api-features-url
Possible target output example:
{
"result_type": "request",
"target": "ogcapi-features",
"filter_lang": "cql2-text",
"filter": "code_insee = '75056'"
}
7. Backward compatibility
The study should propose a migration strategy:
- keep the current contract;
- add a new experimental field;
- introduce a
v2 query language;
- temporarily support both syntaxes;
- clearly document any future deprecations.
Important point: the current language is probably more robust for LLM usage than raw CQL2 syntax. We should not sacrifice reliability for theoretical standards alignment.
Expected deliverables
Proposed scope
This issue should focus on study and design only.
Out of scope for this issue:
- full CQL2 implementation;
- OGC certification;
- implementation of a complete OGC API Features server;
- replacement of the WFS backend;
- full support for CQL2 Advanced.
Design options
Option A: Minimal alignment
Keep the current language, but:
- explicitly document the supported subset;
- harmonize operator names;
- produce a mapping table with CQL2;
- clarify that the language compiles to GeoServer / WFS CQL, not to OGC API Features.
Pros:
- low risk;
- minimal changes;
- preserves current ergonomics.
Cons:
- limited interoperability;
- mostly documentary alignment.
Option B: Current façade + CQL2 compilation
Keep the current MCP contract, but add optional compilation to:
- CQL2 Text;
- CQL2 JSON;
- the current WFS CQL target.
Pros:
- good backward compatibility;
- improves interoperability;
- keeps the LLM-friendly interface.
Cons:
- requires a clean compilation layer;
- requires careful handling of unsupported operators and edge cases.
Option C: New filter model close to CQL2 JSON
Introduce a new filter field represented as a logical expression tree, closer to CQL2 JSON.
Pros:
- better expressiveness;
- closer to the standard;
- easier to target multiple backends cleanly.
Cons:
- more complex for LLMs to produce reliably;
- larger migration effort;
- requires more extensive validation and tests.
Option D: Direct CQL2 Text support
Allow callers to provide a raw CQL2 Text string directly.
Pros:
- highly standard;
- useful for expert users;
- potentially easy to expose.
Cons:
- riskier;
- less controlled;
- weaker validation;
- less aligned with the current LLM-first design.
Acceptance criteria
This issue can be considered complete when we have:
- a clear diagnosis of the current alignment level;
- an argued recommendation;
- a validated target direction;
- a breakdown into smaller implementation issues;
- before / after examples;
- an explicit position on CQL2 Basic compatibility;
- an explicit position on what remains GeoServer / WFS-specific.
References
Study alignment of the
gpf_wfs_get_featuresfiltering language with OGC API Features / CQL2 BasicContext
The project currently exposes a structured query language through
gpf_wfs_get_features, designed to avoid requiring the model to write raw CQL or WFS queries directly.This language already covers several concepts that are close to OGC filtering standards:
where:eqne/neqnaming to clarifyltltegtgteinis_nullANDcombination betweenwhereclausesselectorder_byspatial_operator:bboxintersects_pointdwithin_pointintersects_featurecql_filtergpf_wfs_describe_typeThis approach is intentionally safer and more guided than exposing raw CQL. However, it would be useful to formally compare it with the current OGC state of the art, especially:
Goal
Study how the current
geocontextquery language could be brought closer to OGC API Features Part 3 / CQL2, while preserving the current benefits:The goal is not necessarily to make the tool fully OGC API Features-compliant immediately, but to define a clear roadmap:
Questions to investigate
1. Comparison with CQL2 Basic
Compare the current operators with those expected in CQL2 Basic:
IS NULL;Questions to address:
neremain as-is, or should it be renamed toneq,not_eq, or another spelling?and,or, andnotbe exposed explicitly?ANDcombination be preserved for simple use cases?2. Filter representation
The current model uses a flat list:
{ "where": [ { "property": "code_insee", "operator": "eq", "value": "75056" } ] }Study whether the language should evolve toward a representation closer to CQL2 JSON, for example:
{ "filter": { "op": "=", "args": [ { "property": "code_insee" }, "75056" ] } }Or toward an intermediate representation that remains easier for LLMs to produce:
{ "filter": { "and": [ { "property": "code_insee", "operator": "eq", "value": "75056" }, { "property": "population", "operator": "gt", "value": "100000" } ] } }Points to assess:
cql_filter;filter;3. Attribute selection
Compare the current
selectparameter with OGC API Features practices.Points to assess:
selectmaps to concepts such aspropertiesin some OGC API implementations;propertyName;result_type="request"mode;4. Queryables
Study how
gpf_wfs_describe_typecould be brought closer to the OGC API Featuresqueryablesconcept.Questions:
gpf_wfs_get_queryables?/collections/{collectionId}/queryables?5. Spatial operators
Compare the current spatial operators with CQL2 and OGC API Features Part 3.
Current operators:
bboxintersects_pointdwithin_pointintersects_featurePoints to assess:
S_INTERSECTS;BBOX;DWITHIN, which is closer to an extension than to the CQL2 Basic core;filter-crs;Open questions:
intersects_pointbe renamed to something closer to the standard?S_INTERSECTS(geom, POINT(...))?dwithin_pointbe documented as a non-Basic extension?contains,within,crosses,touches, etc. be added, or should the language intentionally remain minimal?6. Transport and protocol
The current system compiles to a WFS request using
cql_filter.OGC API Features Part 3 uses concepts such as:
filterfilter-langfilter-crs/queryables/functionsQuestions to investigate:
wfs-cqlcql2-textcql2-jsonogc-api-features-urlPossible target output example:
{ "result_type": "request", "target": "ogcapi-features", "filter_lang": "cql2-text", "filter": "code_insee = '75056'" }7. Backward compatibility
The study should propose a migration strategy:
v2query language;Important point: the current language is probably more robust for LLM usage than raw CQL2 syntax. We should not sacrifice reliability for theoretical standards alignment.
Expected deliverables
Proposed scope
This issue should focus on study and design only.
Out of scope for this issue:
Design options
Option A: Minimal alignment
Keep the current language, but:
Pros:
Cons:
Option B: Current façade + CQL2 compilation
Keep the current MCP contract, but add optional compilation to:
Pros:
Cons:
Option C: New filter model close to CQL2 JSON
Introduce a new
filterfield represented as a logical expression tree, closer to CQL2 JSON.Pros:
Cons:
Option D: Direct CQL2 Text support
Allow callers to provide a raw CQL2 Text string directly.
Pros:
Cons:
Acceptance criteria
This issue can be considered complete when we have:
References
OGC API - Features - Part 3: Filtering
https://docs.ogc.org/is/19-079r2/19-079r2.html
Common Query Language CQL2 1.0.0
https://docs.ogc.org/is/21-065r2/21-065r2.html
OGC API - Features Standards
https://www.ogc.org/publications/standard/ogcapi-features/
CQL2 Standard
https://www.ogc.org/standards/cql2/