@@ -99,25 +99,63 @@ def get_collection(self, collection_id: str, **kwargs) -> Collection:
99
99
return self .collection_serializer .db_to_stac (collection , base_url )
100
100
101
101
def item_collection (
102
- self , collection_id : str , limit : int = 10 , token : str = None , ** kwargs
102
+ self ,
103
+ collection_id : str ,
104
+ bbox : Optional [List [NumType ]] = None ,
105
+ datetime : Optional [str ] = None ,
106
+ limit : int = 10 ,
107
+ token : str = None ,
108
+ ** kwargs ,
103
109
) -> ItemCollection :
104
110
"""Read an item collection from the database."""
105
111
base_url = str (kwargs ["request" ].base_url )
106
112
with self .session .reader .context_session () as session :
107
- collection_children = (
113
+ query = (
108
114
session .query (self .item_table )
109
115
.join (self .collection_table )
110
116
.filter (self .collection_table .id == collection_id )
111
117
.order_by (self .item_table .datetime .desc (), self .item_table .id )
112
118
)
119
+ # Spatial query
120
+ geom = None
121
+ if bbox :
122
+ if len (bbox ) == 4 :
123
+ geom = ShapelyPolygon .from_bounds (* bbox )
124
+ elif len (bbox ) == 6 :
125
+ """Shapely doesn't support 3d bounding boxes so use the 2d portion"""
126
+ bbox_2d = [bbox [0 ], bbox [1 ], bbox [3 ], bbox [4 ]]
127
+ geom = ShapelyPolygon .from_bounds (* bbox_2d )
128
+ if geom :
129
+ filter_geom = ga .shape .from_shape (geom , srid = 4326 )
130
+ query = query .filter (
131
+ ga .func .ST_Intersects (self .item_table .geometry , filter_geom )
132
+ )
133
+
134
+ # Temporal query
135
+ if datetime :
136
+ # Two tailed query (between)
137
+ dts = datetime .split ("/" )
138
+ # Non-interval date ex. "2000-02-02T00:00:00.00Z"
139
+ if len (dts ) == 1 :
140
+ query = query .filter (self .item_table .datetime == dts [0 ])
141
+ # is there a benefit to between instead of >= and <= ?
142
+ elif dts [0 ] not in ["" , ".." ] and dts [1 ] not in ["" , ".." ]:
143
+ query = query .filter (self .item_table .datetime .between (* dts ))
144
+ # All items after the start date
145
+ elif dts [0 ] not in ["" , ".." ]:
146
+ query = query .filter (self .item_table .datetime >= dts [0 ])
147
+ # All items before the end date
148
+ elif dts [1 ] not in ["" , ".." ]:
149
+ query = query .filter (self .item_table .datetime <= dts [1 ])
150
+
113
151
count = None
114
152
if self .extension_is_enabled ("ContextExtension" ):
115
- count_query = collection_children .statement .with_only_columns (
153
+ count_query = query .statement .with_only_columns (
116
154
[func .count ()]
117
155
).order_by (None )
118
- count = collection_children .session .execute (count_query ).scalar ()
156
+ count = query .session .execute (count_query ).scalar ()
119
157
token = self .get_token (token ) if token else token
120
- page = get_page (collection_children , per_page = limit , page = (token or False ))
158
+ page = get_page (query , per_page = limit , page = (token or False ))
121
159
# Create dynamic attributes for each page
122
160
page .next = (
123
161
self .insert_token (keyset = page .paging .bookmark_next )
0 commit comments