diff --git a/geetools/ee_image_collection.py b/geetools/ee_image_collection.py index 66ce2933..65112a16 100644 --- a/geetools/ee_image_collection.py +++ b/geetools/ee_image_collection.py @@ -881,10 +881,13 @@ def groupInterval(self, unit: str = "month", duration: int = 1) -> ee.List: split = collection.geetools.groupInterval("month", 1) print(split.getInfo()) """ + sizeName = "__geetools_generated_size__" # set generated properties name + # as everything is relyin on the "system:time_start" property # we sort the image collection in the first place. In most collection it will change nothing # so free of charge unless for plumbing ic = self._obj.sort("system:time_start") + toCopy = ic.first().propertyNames() # transform the interval into a duration in milliseconds # I can use the DateRangeAccessor as it's imported earlier in the __init__.py file @@ -896,6 +899,20 @@ def groupInterval(self, unit: str = "month", duration: int = 1) -> ee.List: lambda dr: ic.filterDate(ee.DateRange(dr).start(), ee.DateRange(dr).end()) ) + def add_size(ic): + ic = ee.ImageCollection(ic) + return ic.set({sizeName: ic.size()}) + + def delete_size_property(ic): + ic = ee.ImageCollection(ic) + return ee.ImageCollection(ic.copyProperties(ic, properties=toCopy)) + + imageCollectionList = ( + imageCollectionList.map(add_size) + .filter(ee.Filter.gt(sizeName, 0)) + .map(delete_size_property) + ) + return ee.List(imageCollectionList) def reduceInterval( @@ -943,16 +960,20 @@ def reduceInterval( red = getattr(ee.Reducer, reducer)() if isinstance(reducer, str) else reducer def reduce(ic): - timeList = ee.ImageCollection(ic).aggregate_array("system:time_start") + ic = ee.ImageCollection(ic) + timeList = ic.aggregate_array("system:time_start") start, end = timeList.get(0), timeList.get(-1) - bandNames = ee.ImageCollection(ic).first().bandNames() - image = ee.ImageCollection(ic).reduce(red).rename(bandNames) + firstImg = ic.first() + bandNames = firstImg.bandNames() + propertyNames = firstImg.propertyNames() + image = ic.reduce(red).rename(bandNames).copyProperties(firstImg, propertyNames) return image.set("system:time_start", start, "system:time_end", end) reducedImagesList = imageCollectionList.map(reduce) # set back the original properties - ic = ee.ImageCollection(reducedImagesList).copyProperties(self._obj) + propertyNames = self._obj.propertyNames() + ic = ee.ImageCollection(reducedImagesList).copyProperties(self._obj, propertyNames) return ee.ImageCollection(ic) diff --git a/tests/test_ImageCollection.py b/tests/test_ImageCollection.py index 7ddeb616..39d48e3f 100644 --- a/tests/test_ImageCollection.py +++ b/tests/test_ImageCollection.py @@ -297,6 +297,14 @@ def test_group_interval_with_interval_and_unit(self, jaxa_rainfall): assert grouped.size().getInfo() == 3 assert ee.ImageCollection(grouped.get(0)).size().getInfo() == 24 + def test_group_interval_drop_empty_collections(self, s2_sr): + ic = s2_sr.filterDate("2021-01-01", "2021-01-07") + grouped = ic.geetools.groupInterval(duration=1, unit="day") + # Each collection must not be empty + for i in range(grouped.size().getInfo()): + imgCollection = ee.ImageCollection(grouped.get(i)) + assert imgCollection.size().getInfo() != 0 + def test_deprecated_make_equal_interval(self, jaxa_rainfall): # get 3 month worth of data and group it with default parameters ic = jaxa_rainfall.filterDate("2020-01-01", "2020-03-31") @@ -340,6 +348,22 @@ def test_reduce_interval_with_non_existing_reducer_and_properties(self, jaxa_rai with pytest.raises(AttributeError): ic.geetools.reduceInterval("toto") + def test_reduce_interval_with_empty_days(self, s2_sr): + ic = s2_sr.filterDate("2021-01-01", "2021-01-07") + resultSize = ic.geetools.reduceInterval("mean", duration=1, unit="day").size().getInfo() + assert resultSize == 3 + + def test_reduce_interval_image_collection_with_system_id(self, s2_sr): + originalIc = s2_sr.filterDate("2021-01-01", "2021-01-07") + ic = originalIc.geetools.reduceInterval("mean", duration=1, unit="day") + assert "system:id" in ic.propertyNames().getInfo() + + def test_reduce_interval_image_with_system_id(self, s2_sr): + originalIc = s2_sr.filterDate("2021-01-01", "2021-01-07") + ic = originalIc.geetools.reduceInterval("mean", duration=1, unit="day") + firstImg = ic.first() + assert "system:id" in firstImg.propertyNames().getInfo() + def test_deprecated_reduce_equal_interval(self, jaxa_rainfall, amazonas, num_regression): # get 3 month worth of data and group it with default parameters ic = jaxa_rainfall.filterDate("2020-01-01", "2020-03-31")