Skip to content

Commit 6bcafeb

Browse files
author
Tom Augspurger
authored
Merge pull request #6 from TomAugspurger/tom/fix/date-format
Handle mixed datetimes within a collection
2 parents 85efc86 + f0cca83 commit 6bcafeb

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

stac_geoparquet/stac_geoparquet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def to_geodataframe(items: Sequence[dict[str, Any]]) -> geopandas.GeoDataFrame:
6363

6464
for column in ["datetime", "start_datetime", "end_datetime"]:
6565
if column in gdf.columns:
66-
gdf[column] = pd.to_datetime(gdf[column])
66+
gdf[column] = pd.to_datetime(gdf[column], format="ISO8601")
6767

6868
columns = [
6969
"type",

tests/sentinel-2-item.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"S2B_MSIL2A_20220612T182919_R027_T24XWR_20220613T123251","bbox":[-39.00128,80.92029861,-32.006714,81.9569194],"type":"Feature","links":[{"rel":"collection","type":"application/json","href":"https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a"},{"rel":"parent","type":"application/json","href":"https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a"},{"rel":"root","type":"application/json","href":"https://planetarycomputer.microsoft.com/api/stac/v1/"},{"rel":"self","type":"application/geo+json","href":"https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2B_MSIL2A_20220612T182919_R027_T24XWR_20220613T123251"},{"rel":"license","href":"https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice"},{"rel":"preview","href":"https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=sentinel-2-l2a&item=S2B_MSIL2A_20220612T182919_R027_T24XWR_20220613T123251","title":"Map of item","type":"text/html"}],"assets":{"AOT":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_AOT_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Aerosol optical thickness (AOT)"},"B01":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R60m/T24XWR_20220612T182919_B01_60m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[1830,1830],"proj:transform":[60.0,0.0,499980.0,0.0,-60.0,9100020.0],"gsd":60.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 1 - Coastal aerosol - 60m","eo:bands":[{"name":"B01","common_name":"coastal","description":"Band 1 - Coastal aerosol","center_wavelength":0.443,"full_width_half_max":0.027}]},"B02":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_B02_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 2 - Blue - 10m","eo:bands":[{"name":"B02","common_name":"blue","description":"Band 2 - Blue","center_wavelength":0.49,"full_width_half_max":0.098}]},"B03":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_B03_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 3 - Green - 10m","eo:bands":[{"name":"B03","common_name":"green","description":"Band 3 - Green","center_wavelength":0.56,"full_width_half_max":0.045}]},"B04":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_B04_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 4 - Red - 10m","eo:bands":[{"name":"B04","common_name":"red","description":"Band 4 - Red","center_wavelength":0.665,"full_width_half_max":0.038}]},"B05":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_B05_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 5 - Vegetation red edge 1 - 20m","eo:bands":[{"name":"B05","common_name":"rededge","description":"Band 5 - Vegetation red edge 1","center_wavelength":0.704,"full_width_half_max":0.019}]},"B06":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_B06_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 6 - Vegetation red edge 2 - 20m","eo:bands":[{"name":"B06","common_name":"rededge","description":"Band 6 - Vegetation red edge 2","center_wavelength":0.74,"full_width_half_max":0.018}]},"B07":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_B07_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 7 - Vegetation red edge 3 - 20m","eo:bands":[{"name":"B07","common_name":"rededge","description":"Band 7 - Vegetation red edge 3","center_wavelength":0.783,"full_width_half_max":0.028}]},"B08":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_B08_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 8 - NIR - 10m","eo:bands":[{"name":"B08","common_name":"nir","description":"Band 8 - NIR","center_wavelength":0.842,"full_width_half_max":0.145}]},"B09":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R60m/T24XWR_20220612T182919_B09_60m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[1830,1830],"proj:transform":[60.0,0.0,499980.0,0.0,-60.0,9100020.0],"gsd":60.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 9 - Water vapor - 60m","eo:bands":[{"name":"B09","description":"Band 9 - Water vapor","center_wavelength":0.945,"full_width_half_max":0.026}]},"B11":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_B11_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 11 - SWIR (1.6) - 20m","eo:bands":[{"name":"B11","common_name":"swir16","description":"Band 11 - SWIR (1.6)","center_wavelength":1.61,"full_width_half_max":0.143}]},"B12":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_B12_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 12 - SWIR (2.2) - 20m","eo:bands":[{"name":"B12","common_name":"swir22","description":"Band 12 - SWIR (2.2)","center_wavelength":2.19,"full_width_half_max":0.242}]},"B8A":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_B8A_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Band 8A - Vegetation red edge 4 - 20m","eo:bands":[{"name":"B8A","common_name":"rededge","description":"Band 8A - Vegetation red edge 4","center_wavelength":0.865,"full_width_half_max":0.033}]},"SCL":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R20m/T24XWR_20220612T182919_SCL_20m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[5490,5490],"proj:transform":[20.0,0.0,499980.0,0.0,-20.0,9100020.0],"gsd":20.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Scene classfication map (SCL)"},"WVP":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_WVP_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"Water vapour (WVP)"},"visual":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/IMG_DATA/R10m/T24XWR_20220612T182919_TCI_10m.tif","proj:bbox":[499980.0,8990220.0,609780.0,9100020.0],"proj:shape":[10980,10980],"proj:transform":[10.0,0.0,499980.0,0.0,-10.0,9100020.0],"gsd":10.0,"type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["data"],"title":"True color image","eo:bands":[{"name":"B04","common_name":"red","description":"Band 4 - Red","center_wavelength":0.665,"full_width_half_max":0.038},{"name":"B03","common_name":"green","description":"Band 3 - Green","center_wavelength":0.56,"full_width_half_max":0.045},{"name":"B02","common_name":"blue","description":"Band 2 - Blue","center_wavelength":0.49,"full_width_half_max":0.098}]},"preview":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/QI_DATA/T24XWR_20220612T182919_PVI.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","roles":["thumbnail"],"title":"Thumbnail"},"safe-manifest":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/manifest.safe","type":"application/xml","roles":["metadata"],"title":"SAFE manifest"},"granule-metadata":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/GRANULE/L2A_T24XWR_A027509_20220612T182920/MTD_TL.xml","type":"application/xml","roles":["metadata"],"title":"Granule metadata"},"inspire-metadata":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/INSPIRE.xml","type":"application/xml","roles":["metadata"],"title":"INSPIRE metadata"},"product-metadata":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/MTD_MSIL2A.xml","type":"application/xml","roles":["metadata"],"title":"Product metadata"},"datastrip-metadata":{"href":"https://sentinel2l2a01.blob.core.windows.net/sentinel2-l2/24/X/WR/2022/06/12/S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE/DATASTRIP/DS_ESRI_20220613T123251_S20220612T182920/MTD_DS.xml","type":"application/xml","roles":["metadata"],"title":"Datastrip metadata"},"tilejson":{"title":"TileJSON with default rendering","href":"https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=sentinel-2-l2a&item=S2B_MSIL2A_20220612T182919_R027_T24XWR_20220613T123251&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0&format=png","type":"application/json","roles":["tiles"]},"rendered_preview":{"title":"Rendered preview","rel":"preview","href":"https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=sentinel-2-l2a&item=S2B_MSIL2A_20220612T182919_R027_T24XWR_20220613T123251&assets=visual&asset_bidx=visual%7C1%2C2%2C3&nodata=0&format=png","roles":["overview"],"type":"image/png"}},"geometry":{"type":"Polygon","coordinates":[[[-39.00128,81.9569194],[-32.006714,81.8974237],[-32.75702,80.9202986],[-39.00113,80.9732637],[-39.00128,81.9569194]]]},"collection":"sentinel-2-l2a","properties":{"datetime":"2022-06-12T18:29:19.024000Z","platform":"Sentinel-2B","proj:epsg":32624,"instruments":["msi"],"s2:mgrs_tile":"24XWR","constellation":"Sentinel 2","s2:granule_id":"S2B_OPER_MSI_L2A_TL_ESRI_20220613T123251_A027509_T24XWR_N04.00","eo:cloud_cover":30.529344,"s2:datatake_id":"GS2B_20220612T182919_027509_N04.00","s2:product_uri":"S2B_MSIL2A_20220612T182919_N0400_R027_T24XWR_20220613T123251.SAFE","s2:datastrip_id":"S2B_OPER_MSI_L2A_DS_ESRI_20220613T123251_S20220612T182920_N04.00","s2:product_type":"S2MSI2A","sat:orbit_state":"ascending","s2:datatake_type":"INS-NOBS","s2:generation_time":"2022-06-13T12:32:51.87450Z","sat:relative_orbit":27,"s2:water_percentage":0.3641,"s2:mean_solar_zenith":63.0036756665255,"s2:mean_solar_azimuth":245.346023617542,"s2:processing_baseline":"04.00","s2:snow_ice_percentage":65.965366,"s2:vegetation_percentage":0.0,"s2:thin_cirrus_percentage":27.739277,"s2:cloud_shadow_percentage":0.452198,"s2:nodata_pixel_percentage":3e-6,"s2:unclassified_percentage":0.002581,"s2:dark_features_percentage":0.17497,"s2:not_vegetated_percentage":2.511432,"s2:degraded_msi_data_percentage":0.0,"s2:high_proba_clouds_percentage":1.210932,"s2:reflectance_conversion_factor":0.9705201543305,"s2:medium_proba_clouds_percentage":1.579135,"s2:saturated_defective_pixel_percentage":0.0},"stac_extensions":["https://stac-extensions.github.io/eo/v1.0.0/schema.json","https://stac-extensions.github.io/sat/v1.0.0/schema.json","https://stac-extensions.github.io/projection/v1.0.0/schema.json"],"stac_version":"1.0.0"}

tests/test_stac_geoparquet.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import json
2+
import pathlib
3+
14
import stac_geoparquet
25
import shapely.geometry
36
import pandas as pd
@@ -10,6 +13,8 @@
1013
from stac_geoparquet.stac_geoparquet import to_item_collection
1114
from stac_geoparquet.utils import assert_equal, fix_empty_multipolygon
1215

16+
HERE = pathlib.Path(__file__).parent
17+
1318

1419
def test_assert_equal():
1520
a = pystac.read_file(
@@ -334,3 +339,20 @@ def test_smoke(collection_id):
334339
result = to_item_collection(df)
335340
expected = pystac.ItemCollection(items)
336341
assert_equal(result, expected)
342+
343+
344+
def test_mixed_date_format():
345+
a = json.loads((HERE / "sentinel-2-item.json").read_text())
346+
b = json.loads((HERE / "sentinel-2-item.json").read_text())
347+
a["properties"]["datetime"] = "2000-12-10T22:04:58Z"
348+
b["properties"]["datetime"] = "2000-12-10T22:04:57.998000Z"
349+
a["geometry"] = {"type": "Point", "coordinates": [0, 0]}
350+
b["geometry"] = {"type": "Point", "coordinates": [0, 0]}
351+
352+
result = stac_geoparquet.to_geodataframe([a, b])
353+
expected = [
354+
pd.Timestamp("2000-12-10 22:04:58+0000", tz="UTC"),
355+
pd.Timestamp("2000-12-10 22:04:57.998000+0000", tz="UTC"),
356+
]
357+
358+
assert result["datetime"].tolist() == expected

0 commit comments

Comments
 (0)