10
10
import requests
11
11
from requests import Session , Response
12
12
13
- from isamples_export_client .duckdb_utilities import GeoFeaturesResult , read_geo_features_from_jsonl
13
+ from isamples_export_client .duckdb_utilities import (
14
+ GeoFeaturesResult ,
15
+ TemporalExtent ,
16
+ read_geo_features_from_jsonl ,
17
+ get_temporal_extent_from_jsonl
18
+ )
14
19
from isamples_export_client .geoparquet_utilities import write_geoparquet_from_json_lines
15
20
16
21
GEOPARQUET = "geoparquet"
26
31
27
32
STAC_COLLECTION_TYPE = "Collection"
28
33
STAC_VERSION = "1.0.0"
34
+ STAC_DEFAULT_LICENSE = "CC-BY-4.0" # https://spdx.org/licenses/CC-BY-4.0.html
29
35
COLLECTION_ID = "isamples-stac-collection-"
30
36
COLLECTION_DESCRIPTION = """The Internet of Samples (iSamples) is a multi-disciplinary and multi-institutional
31
37
project funded by the National Science Foundation to design, develop, and promote service infrastructure to uniquely,
@@ -41,6 +47,13 @@ def datetime_to_solr_format(dt):
41
47
return dt .strftime (SOLR_TIME_FORMAT )
42
48
43
49
50
+ class JsonDateTimeEncoder (json .JSONEncoder ):
51
+ def default (self , o ):
52
+ if isinstance (o , datetime .datetime ):
53
+ return o .isoformat (timespec = "seconds" )
54
+ return json .JSONEncoder .default (self , o )
55
+
56
+
44
57
class ExportJobStatus (Enum ):
45
58
CREATED = "created"
46
59
STARTED = "started"
@@ -185,7 +198,15 @@ def write_manifest(self, query: str, uuid: str, tstarted: datetime.datetime, num
185
198
f .write (json .dumps (manifests , indent = 4 ))
186
199
return manifest_path
187
200
188
- def write_stac (self , uuid : str , tstarted : datetime .datetime , geo_result : GeoFeaturesResult , solr_query : str , json_file_path : str , parquet_file_path : str ) -> str :
201
+ def write_stac (
202
+ self ,
203
+ uuid : str ,
204
+ tstarted : datetime .datetime ,
205
+ geo_result : GeoFeaturesResult ,
206
+ temporal_result : TemporalExtent ,
207
+ solr_query : str ,
208
+ json_file_path : str ,
209
+ parquet_file_path : str ) -> str :
189
210
assets_dict = {
190
211
}
191
212
description_string = (
@@ -210,8 +231,17 @@ def write_stac(self, uuid: str, tstarted: datetime.datetime, geo_result: GeoFeat
210
231
"type" : STAC_COLLECTION_TYPE ,
211
232
"id" : f"iSamples Export Service result { uuid } " ,
212
233
"collection" : f"{ COLLECTION_TITLE } { uuid } " ,
213
- "geometry" : geo_result .geo_json_dict ,
214
- "bbox" : geo_result .bbox ,
234
+ "license" : STAC_DEFAULT_LICENSE ,
235
+ "extent" : {
236
+ "spatial" : {
237
+ "bbox" : [geo_result .bbox ,]
238
+ },
239
+ "temporal" : {
240
+ "interval" : [
241
+ temporal_result
242
+ ]
243
+ }
244
+ },
215
245
"properties" : {
216
246
"datetime" : datetime_to_solr_format (tstarted )
217
247
},
@@ -305,8 +335,8 @@ def write_stac(self, uuid: str, tstarted: datetime.datetime, geo_result: GeoFeat
305
335
"assets" : assets_dict
306
336
}
307
337
stac_path = ExportClient ._stac_file_path (self ._destination_directory )
308
- with open (stac_path , "w" ) as f :
309
- f . write ( json .dumps (stac_item , indent = 4 ) )
338
+ with open (stac_path , "w" , encoding = "UTF-8" ) as f :
339
+ json .dump (stac_item , f , indent = 4 , ensure_ascii = False , cls = JsonDateTimeEncoder )
310
340
return stac_path
311
341
312
342
def perform_full_download (self ):
@@ -334,13 +364,14 @@ def perform_full_download(self):
334
364
manifest_path = self .write_manifest (self ._query , uuid , tstarted , num_results )
335
365
logging .info (f"Successfully wrote manifest file to { manifest_path } " )
336
366
geo_result = read_geo_features_from_jsonl (filename )
367
+ temporal_result = get_temporal_extent_from_jsonl (filename )
337
368
parquet_filename = None
338
369
if self .is_geoparquet :
339
370
parquet_filename = write_geoparquet_from_json_lines (filename )
340
371
query_string = status_json .get ("query" ).replace ("'" , "\" " )
341
372
solr_query_dict = json .loads (query_string )
342
373
query = solr_query_dict .pop ("q" )
343
- stac_path = self .write_stac (uuid , tstarted , geo_result , query , filename , parquet_filename )
374
+ stac_path = self .write_stac (uuid , tstarted , geo_result , temporal_result , query , filename , parquet_filename )
344
375
logging .info (f"Successfully wrote stac item to { stac_path } " )
345
376
break
346
377
except Exception as e :
0 commit comments