11import stacrs
22from pystac import Collection as PystacCollection
33from pystac import Extent , Item
4+ from stacrs import DuckdbClient
45
56from tistac .backends import Backend
6- from tistac .models import Collection , ItemCollection , Search
7+ from tistac .models import Collection , ItemCollection , Link , Search
78
89
910class StacGeoparquetBackend (Backend ):
1011 """A stac-geoparquet backend, using DuckDB under the hood."""
1112
12- def __init__ (self , href : str ):
13+ def __init__ (self , href : str , base_url : str ):
1314 # TODO support multiple collections
1415 # TODO store collection information in the **stac-geoparquet**
1516 items_as_dicts = stacrs .search (href )
@@ -35,6 +36,8 @@ def __init__(self, href: str):
3536 d ["stac_version" ] = "1.1.0"
3637 self .collections = [Collection .model_validate (d )]
3738 self .href = href
39+ self .base_url = base_url
40+ self .client = DuckdbClient ()
3841
3942 async def get_collections (self ) -> list [Collection ]:
4043 return self .collections
@@ -43,5 +46,27 @@ async def get_collection(self, collection_id: str) -> Collection | None:
4346 return next ((c for c in self .collections if c .id == collection_id ), None )
4447
4548 async def search (self , search : Search ) -> ItemCollection :
46- items = stacrs .search (self .href , limit = search .limit )
47- return ItemCollection (features = items )
49+ item_collection = self .client .search (self .href , ** search .model_dump ())
50+ number_returned = len (item_collection ["features" ])
51+ assert search .limit , "Search should always have a limit at this point"
52+ links = []
53+ if number_returned >= search .limit :
54+ links .append (
55+ self .next_link (
56+ search .limit ,
57+ search .offset or 0 ,
58+ number_returned ,
59+ )
60+ )
61+ item_collection ["numberReturned" ] = number_returned
62+ item_collection ["links" ] = links
63+ return ItemCollection .model_validate (item_collection )
64+
65+ def next_link (self , limit : int , offset : int , num_items : int ) -> Link :
66+ # TODO support POST
67+ return Link (
68+ rel = "next" ,
69+ type = "application/geo+json" ,
70+ href = self .base_url + f"search?limit={ limit } &offset={ offset + num_items } " ,
71+ method = "GET" ,
72+ )
0 commit comments