Skip to content

Commit ee76362

Browse files
committed
add options for returning geometry
1 parent 4dec594 commit ee76362

File tree

3 files changed

+62
-18
lines changed

3 files changed

+62
-18
lines changed

tifeatures/dbmodel.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ def datetime_column(self, dtcol: Optional[str] = None):
7070

7171
def geometry_column(self, gcol: Optional[str] = None) -> Optional[GeometryColumn]:
7272
"""Return the name of the first geometry column."""
73-
if self.geometry_columns is not None and len(self.geometry_columns) > 0:
73+
if (
74+
self.geometry_columns is not None
75+
and len(self.geometry_columns) > 0
76+
and gcol != "none"
77+
):
7478
for c in self.geometry_columns:
7579
if gcol is None or c.name == gcol:
7680
return c

tifeatures/factory.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,10 @@ def collections(
346346
],
347347
}
348348
)
349-
for collection in [*tables, *list(function_catalog.values())]
349+
for collection in [
350+
*tables,
351+
*list(function_catalog.values()),
352+
]
350353
],
351354
)
352355

@@ -507,6 +510,13 @@ async def items(
507510
description="Starts the response at an offset.",
508511
),
509512
output_type: Optional[ResponseType] = Depends(OutputType),
513+
bbox_only: Optional[bool] = Query(
514+
None,
515+
description="Only return the bounding box of the feature.",
516+
),
517+
simplify: Optional[float] = Query(
518+
None, description="Simplify the output geometry."
519+
),
510520
):
511521
offset = offset or 0
512522

@@ -523,6 +533,8 @@ async def items(
523533
"datetime-column",
524534
"limit",
525535
"offset",
536+
"bbox_only",
537+
"simplify",
526538
]
527539
properties_filter = [
528540
(key, value)
@@ -542,6 +554,8 @@ async def items(
542554
offset=offset,
543555
geom=geom_column,
544556
dt=datetime_column,
557+
bbox_only=bbox_only,
558+
simplify=simplify,
545559
)
546560

547561
qs = "?" + str(request.query_params) if request.query_params else ""

tifeatures/layer.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212
from pydantic import BaseModel, root_validator
1313
from pygeofilter.ast import AstType
1414

15+
from tifeatures.dbmodel import GeometryColumn
1516
from tifeatures.dbmodel import Table as DBTable
1617
from tifeatures.errors import (
1718
InvalidDatetime,
1819
InvalidDatetimeColumnName,
19-
InvalidGeometryColumnName,
2020
InvalidPropertyName,
2121
MissingDatetimeColumn,
22-
MissingGeometryColumn,
2322
)
2423
from tifeatures.filter.evaluate import to_filter
2524
from tifeatures.filter.filters import bbox_to_wkt
@@ -121,6 +120,36 @@ def _select_count(self):
121120
def _from(self):
122121
return clauses.From(self.id)
123122

123+
def _geom(
124+
self,
125+
geometry_column: Optional[GeometryColumn],
126+
bbox_only: Optional[bool],
127+
simplify: Optional[float],
128+
):
129+
if geometry_column is None:
130+
return pg_funcs.cast(None, "json")
131+
132+
g = logic.V(geometry_column.name)
133+
134+
if bbox_only:
135+
g = logic.Func("ST_Envelope", g)
136+
elif simplify:
137+
g = logic.Func(
138+
"ST_SnapToGrid",
139+
logic.Func("ST_Simplify", g, simplify),
140+
simplify,
141+
)
142+
143+
if geometry_column.srid == 4326:
144+
g = logic.Func("ST_AsGeoJson", g)
145+
else:
146+
g = logic.Func(
147+
"ST_Transform",
148+
logic.Func("ST_AsGeoJson", g),
149+
4326,
150+
)
151+
return g
152+
124153
def _where(
125154
self,
126155
ids: Optional[List[str]] = None,
@@ -304,14 +333,12 @@ async def query(
304333
dt: str = None,
305334
limit: Optional[int] = None,
306335
offset: Optional[int] = None,
336+
bbox_only: Optional[bool] = None,
337+
simplify: Optional[float] = None,
307338
) -> Tuple[FeatureCollection, int]:
308339
"""Build and run Pg query."""
309-
if not self.geometry_columns:
310-
raise MissingGeometryColumn("Must have geometry column for geojson output.")
311340

312341
geometry_column = self.geometry_column(geom)
313-
if not geometry_column:
314-
raise InvalidGeometryColumnName(f"Invalid Geometry Column: {geom}.")
315342

316343
sql_query = """
317344
WITH
@@ -327,13 +354,8 @@ async def query(
327354
json_build_object(
328355
'type', 'Feature',
329356
'id', :id_column,
330-
'geometry', ST_AsGeoJSON(
331-
CASE
332-
WHEN :srid = 4326 THEN :geometry_column
333-
ELSE ST_Transform(:geometry_column, 4326)
334-
END
335-
)::json,
336-
'properties', to_jsonb( features.* ) - :geom_columns
357+
'geometry', :geometry_q,
358+
'properties', to_jsonb( features.* ) - :geom_columns::text[]
337359
)
338360
),
339361
'total_count', total_count.count
@@ -365,10 +387,14 @@ async def query(
365387
dt=dt,
366388
),
367389
id_column=logic.V(self.id_column),
368-
srid=geometry_column.srid,
369-
geometry_column=logic.V(geometry_column.name),
370-
geom_columns=geometry_column.name,
390+
geometry_q=self._geom(
391+
geometry_column=geometry_column,
392+
bbox_only=bbox_only,
393+
simplify=simplify,
394+
),
395+
geom_columns=[g.name for g in self.geometry_columns],
371396
)
397+
print(q, p)
372398
async with pool.acquire() as conn:
373399
items = await conn.fetchval(q, *p)
374400

0 commit comments

Comments
 (0)