Skip to content

Commit b9c145d

Browse files
authored
Fix PostgreSQL bbox query (#2051)
* Add test for PostgreSQL bbox * Fix PostgreSQL bbox query Prefer using `ST_Intersects` and specify the storage_crs when creating a SQL envelope
1 parent 350aec1 commit b9c145d

2 files changed

Lines changed: 18 additions & 4 deletions

File tree

pygeoapi/provider/sql.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
from typing import Optional
6161

6262
from geoalchemy2 import Geometry # noqa - this isn't used explicitly but is needed to process Geometry columns
63-
from geoalchemy2.functions import ST_MakeEnvelope
63+
from geoalchemy2.functions import ST_MakeEnvelope, ST_Intersects
6464
from geoalchemy2.shape import to_shape, from_shape
6565
from pygeofilter.backends.sqlalchemy.evaluate import to_filter
6666
import pyproj
@@ -91,7 +91,7 @@
9191
ProviderQueryError,
9292
ProviderItemNotFoundError
9393
)
94-
from pygeoapi.util import get_transform_from_crs
94+
from pygeoapi.util import get_transform_from_crs, get_crs_from_uri
9595

9696

9797
LOGGER = logging.getLogger(__name__)
@@ -720,9 +720,11 @@ def _get_bbox_filter(self, bbox: list[float]):
720720
return True # Let everything through if no bbox
721721

722722
# Since this provider uses postgis, we can use ST_MakeEnvelope
723-
envelope = ST_MakeEnvelope(*bbox)
723+
storage_srid = get_crs_from_uri(self.storage_crs).to_epsg()
724+
envelope = ST_MakeEnvelope(*bbox, storage_srid or 4326)
725+
724726
geom_column = getattr(self.table_model, self.geom)
725-
bbox_filter = geom_column.intersects(envelope)
727+
bbox_filter = ST_Intersects(envelope, geom_column)
726728

727729
return bbox_filter
728730

tests/test_postgresql_provider.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,18 @@ def test_query_cql_properties_bbox_filters(config):
381381
assert ids == expected_ids
382382

383383

384+
def test_bbox_is_same_as_cql(config):
385+
provider = PostgreSQLProvider(config)
386+
387+
bbox = [30.560389, -3.134991, 30.604849, -3.061970]
388+
fc_bbox = provider.query(bbox=bbox)
389+
390+
bbox_cql = parse('BBOX(foo_geom, {}, {}, {}, {})'.format(*bbox))
391+
fc_bbox_cql = provider.query(filterq=bbox_cql)
392+
393+
assert fc_bbox == fc_bbox_cql
394+
395+
384396
def test_get_fields_types(config_types):
385397
provider = PostgreSQLProvider(config_types)
386398

0 commit comments

Comments
 (0)