Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Note: Minor version `0.X.0` update might break the API, It's recommended to pin

## [unreleased]

* switch from pygeofilter to cql2

## [1.2.1] - 2025-08-26

* update `starlette-cramjam` requirement to `>=0.4,<0.6`
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
dynamic = ["version"]
dependencies = [
"orjson",
"cql2",
"asyncpg>=0.23.0",
"buildpg>=0.3",
"fastapi>=0.100.0",
Expand All @@ -31,7 +32,6 @@ dependencies = [
"pydantic>=2.4,<3.0",
"pydantic-settings~=2.0",
"geojson-pydantic>=1.0,<3.0",
"pygeofilter>=0.2.0,<0.3.0",
"ciso8601~=2.3",
"starlette-cramjam>=0.4,<0.6",
]
Expand Down
23 changes: 14 additions & 9 deletions tipg/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from buildpg import funcs as pg_funcs
from buildpg import logic, render
from ciso8601 import parse_rfc3339
from cql2 import Expr
from geojson_pydantic.geometries import Polygon
from morecantile import Tile, TileMatrixSet
from pydantic import BaseModel, Field, model_validator
from pygeofilter.ast import AstType
from pyproj import Transformer

from tipg.errors import (
Expand All @@ -24,8 +25,6 @@
InvalidPropertyName,
MissingDatetimeColumn,
)
from tipg.filter.evaluate import to_filter
from tipg.filter.filters import bbox_to_wkt
from tipg.logger import logger
from tipg.model import Extent
from tipg.settings import (
Expand All @@ -44,6 +43,12 @@
TransformerFromCRS = lru_cache(Transformer.from_crs)


def bbox_to_wkt(bbox: List[float], srid: int = 4326) -> str:
"""Return WKT representation of a BBOX."""
poly = Polygon.from_bounds(*bbox) # type:ignore
return f"SRID={srid};{poly.wkt}"


def debug_query(q, *p):
"""Utility to print raw statement to use for debugging."""

Expand Down Expand Up @@ -522,7 +527,7 @@ def _where( # noqa: C901
datetime: Optional[List[str]] = None,
bbox: Optional[List[float]] = None,
properties: Optional[List[Tuple[str, Any]]] = None,
cql: Optional[AstType] = None,
cql: Optional[Expr] = None,
geom: Optional[str] = None,
dt: Optional[str] = None,
tile: Optional[Tile] = None,
Expand Down Expand Up @@ -590,7 +595,7 @@ def _where( # noqa: C901

# `CQL` filter
if cql is not None:
wheres.append(to_filter(cql, [p.name for p in self.properties]))
wheres.append(cql.to_sql())

if tile and tms and geometry_column:
# Get tile bounds in the TMS coordinate system
Expand Down Expand Up @@ -694,7 +699,7 @@ async def _features_query(
bbox_filter: Optional[List[float]] = None,
datetime_filter: Optional[List[str]] = None,
properties_filter: Optional[List[Tuple[str, str]]] = None,
cql_filter: Optional[AstType] = None,
cql_filter: Optional[Expr] = None,
sortby: Optional[str] = None,
properties: Optional[List[str]] = None,
geom: Optional[str] = None,
Expand Down Expand Up @@ -749,7 +754,7 @@ async def _features_count_query(
bbox_filter: Optional[List[float]] = None,
datetime_filter: Optional[List[str]] = None,
properties_filter: Optional[List[Tuple[str, str]]] = None,
cql_filter: Optional[AstType] = None,
cql_filter: Optional[Expr] = None,
geom: Optional[str] = None,
dt: Optional[str] = None,
function_parameters: Optional[Dict[str, str]],
Expand Down Expand Up @@ -781,7 +786,7 @@ async def features(
bbox_filter: Optional[List[float]] = None,
datetime_filter: Optional[List[str]] = None,
properties_filter: Optional[List[Tuple[str, str]]] = None,
cql_filter: Optional[AstType] = None,
cql_filter: Optional[Expr] = None,
sortby: Optional[str] = None,
properties: Optional[List[str]] = None,
geom: Optional[str] = None,
Expand Down Expand Up @@ -860,7 +865,7 @@ async def get_tile(
datetime_filter: Optional[List[str]] = None,
properties_filter: Optional[List[Tuple[str, str]]] = None,
function_parameters: Optional[Dict[str, str]] = None,
cql_filter: Optional[AstType] = None,
cql_filter: Optional[Expr] = None,
sortby: Optional[str] = None,
properties: Optional[List[str]] = None,
geom: Optional[str] = None,
Expand Down
11 changes: 5 additions & 6 deletions tipg/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import re
from typing import Annotated, Dict, List, Literal, Optional, Tuple, get_args

import orjson
from ciso8601 import parse_rfc3339
from cql2 import Expr
from morecantile import Tile
from morecantile import tms as default_tms
from pygeofilter.ast import AstType
from pygeofilter.parsers.cql2_json import parse as cql2_json_parser
from pygeofilter.parsers.cql2_text import parse as cql2_text_parser

from tipg.collections import Catalog, Collection, CollectionList
from tipg.errors import InvalidBBox, MissingCollectionCatalog, MissingFunctionParameter
Expand Down Expand Up @@ -289,14 +288,14 @@ def filter_query(
alias="filter-lang",
),
] = None,
) -> Optional[AstType]:
) -> Optional[Dict]:
"""Parse Filter Query."""
if query is not None:
if filter_lang == "cql2-json":
return cql2_json_parser(query)
return Expr(orjson.loads(query))

# default to cql2-text
return cql2_text_parser(query)
return Expr(query)

return None

Expand Down
Loading