RadGEEToolbox 1.7.3__py3-none-any.whl → 1.7.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- RadGEEToolbox/CollectionStitch.py +16 -3
- RadGEEToolbox/Export.py +16 -0
- RadGEEToolbox/GenericCollection.py +130 -34
- RadGEEToolbox/LandsatCollection.py +249 -50
- RadGEEToolbox/Sentinel1Collection.py +179 -37
- RadGEEToolbox/Sentinel2Collection.py +202 -51
- RadGEEToolbox/__init__.py +4 -4
- {radgeetoolbox-1.7.3.dist-info → radgeetoolbox-1.7.4.dist-info}/METADATA +6 -6
- radgeetoolbox-1.7.4.dist-info/RECORD +14 -0
- radgeetoolbox-1.7.3.dist-info/RECORD +0 -14
- {radgeetoolbox-1.7.3.dist-info → radgeetoolbox-1.7.4.dist-info}/WHEEL +0 -0
- {radgeetoolbox-1.7.3.dist-info → radgeetoolbox-1.7.4.dist-info}/licenses/LICENSE.txt +0 -0
- {radgeetoolbox-1.7.3.dist-info → radgeetoolbox-1.7.4.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ee
|
|
2
|
+
import warnings
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
def CollectionStitch(img_col1, img_col2, copy_properties_from=1):
|
|
4
|
+
def collectionStitch(img_col1, img_col2, copy_properties_from=1):
|
|
5
5
|
"""
|
|
6
6
|
Function to mosaic two RadGEETools image collection objects which share image dates.
|
|
7
7
|
Mosaics are only formed for dates where both image collections have images. Server-side friendly.
|
|
@@ -42,8 +42,14 @@ def CollectionStitch(img_col1, img_col2, copy_properties_from=1):
|
|
|
42
42
|
new_col = ee.ImageCollection.fromImages(image_list)
|
|
43
43
|
return new_col
|
|
44
44
|
|
|
45
|
+
def CollectionStitch(img_col1, img_col2, copy_properties_from=1):
|
|
46
|
+
warnings.warn(
|
|
47
|
+
"CollectionStitch is deprecated. Please use collectionStitch instead.",
|
|
48
|
+
DeprecationWarning,
|
|
49
|
+
stacklevel=2)
|
|
50
|
+
return collectionStitch(img_col1, img_col2, copy_properties_from)
|
|
45
51
|
|
|
46
|
-
def
|
|
52
|
+
def mosaicByDate(img_col):
|
|
47
53
|
"""
|
|
48
54
|
Function to mosaic collection images that share the same date. Server-side friendly. Requires images to have date property of "Date_Filter"
|
|
49
55
|
|
|
@@ -80,3 +86,10 @@ def MosaicByDate(img_col):
|
|
|
80
86
|
|
|
81
87
|
# Convert the list of mosaics to an ImageCollection
|
|
82
88
|
return new_col
|
|
89
|
+
|
|
90
|
+
def MosaicByDate(img_col):
|
|
91
|
+
warnings.warn(
|
|
92
|
+
"MosaicByDate is deprecated. Please use mosaicByDate instead.",
|
|
93
|
+
DeprecationWarning,
|
|
94
|
+
stacklevel=2)
|
|
95
|
+
return mosaicByDate(img_col)
|
RadGEEToolbox/Export.py
CHANGED
|
@@ -11,6 +11,22 @@ class ExportToDrive:
|
|
|
11
11
|
`.dates` property for naming files, ensuring readable filenames (e.g., 'MyExport_2023-06-01')
|
|
12
12
|
instead of long system IDs.
|
|
13
13
|
|
|
14
|
+
IMPORTANT: After creating an instance of this class, you must call the `export()` method
|
|
15
|
+
to initiate the export process.
|
|
16
|
+
|
|
17
|
+
For example, to export a RadGEEToolbox collection:
|
|
18
|
+
```python
|
|
19
|
+
collection = LandsatCollection(...) # Assume this is a RadGEEToolbox object
|
|
20
|
+
exporter = ExportToDrive(
|
|
21
|
+
input_data=collection,
|
|
22
|
+
description="Landsat_Export",
|
|
23
|
+
folder="GEE_Exports",
|
|
24
|
+
scale=30,
|
|
25
|
+
name_pattern="{date}",
|
|
26
|
+
)
|
|
27
|
+
exporter.export()
|
|
28
|
+
```
|
|
29
|
+
|
|
14
30
|
Args:
|
|
15
31
|
input_data (ee.Image, ee.ImageCollection, or RadGEEToolbox object): The data to export.
|
|
16
32
|
Can be a single image, a collection, or a RadGEEToolbox wrapper object.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ee
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import numpy as np
|
|
4
|
+
import warnings
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class GenericCollection:
|
|
@@ -93,6 +94,14 @@ class GenericCollection:
|
|
|
93
94
|
self._PixelAreaSumCollection = None
|
|
94
95
|
self._daily_aggregate_collection = None
|
|
95
96
|
|
|
97
|
+
def __call__(self):
|
|
98
|
+
"""
|
|
99
|
+
Allows the object to be called as a function, returning itself.
|
|
100
|
+
This enables property-like methods to be accessed with or without parentheses
|
|
101
|
+
(e.g., .mosaicByDate or .mosaicByDate()).
|
|
102
|
+
"""
|
|
103
|
+
return self
|
|
104
|
+
|
|
96
105
|
@staticmethod
|
|
97
106
|
def image_dater(image):
|
|
98
107
|
"""
|
|
@@ -271,7 +280,7 @@ class GenericCollection:
|
|
|
271
280
|
return out.copyProperties(img).set('system:time_start', img.get('system:time_start'))
|
|
272
281
|
|
|
273
282
|
@staticmethod
|
|
274
|
-
def
|
|
283
|
+
def pixelAreaSum(
|
|
275
284
|
image, band_name, geometry, threshold=-1, scale=30, maxPixels=1e12
|
|
276
285
|
):
|
|
277
286
|
"""
|
|
@@ -331,7 +340,19 @@ class GenericCollection:
|
|
|
331
340
|
final_image = ee.Image(bands.iterate(calculate_and_set_area, image))
|
|
332
341
|
return final_image #.set('system:time_start', image.get('system:time_start'))
|
|
333
342
|
|
|
334
|
-
|
|
343
|
+
@staticmethod
|
|
344
|
+
def PixelAreaSum(
|
|
345
|
+
image, band_name, geometry, threshold=-1, scale=30, maxPixels=1e12
|
|
346
|
+
):
|
|
347
|
+
warnings.warn(
|
|
348
|
+
"The `PixelAreaSum` static method is deprecated and will be removed in future versions. Please use the `pixelAreaSum` static method instead.",
|
|
349
|
+
DeprecationWarning,
|
|
350
|
+
stacklevel=2)
|
|
351
|
+
return GenericCollection.pixelAreaSum(
|
|
352
|
+
image, band_name, geometry, threshold, scale, maxPixels
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
def pixelAreaSumCollection(
|
|
335
356
|
self, band_name, geometry, threshold=-1, scale=30, maxPixels=1e12, output_type='ImageCollection', area_data_export_path=None
|
|
336
357
|
):
|
|
337
358
|
"""
|
|
@@ -358,7 +379,7 @@ class GenericCollection:
|
|
|
358
379
|
collection = self.collection
|
|
359
380
|
# Area calculation for each image in the collection, using the PixelAreaSum function
|
|
360
381
|
AreaCollection = collection.map(
|
|
361
|
-
lambda image: GenericCollection.
|
|
382
|
+
lambda image: GenericCollection.pixelAreaSum(
|
|
362
383
|
image,
|
|
363
384
|
band_name=band_name,
|
|
364
385
|
geometry=geometry,
|
|
@@ -374,17 +395,28 @@ class GenericCollection:
|
|
|
374
395
|
|
|
375
396
|
# If an export path is provided, the area data will be exported to a CSV file
|
|
376
397
|
if area_data_export_path:
|
|
377
|
-
GenericCollection(collection=self._PixelAreaSumCollection).
|
|
398
|
+
GenericCollection(collection=self._PixelAreaSumCollection).exportProperties(property_names=prop_names, file_path=area_data_export_path+'.csv')
|
|
378
399
|
# Returning the result in the desired format based on output_type argument or raising an error for invalid input
|
|
379
400
|
if output_type == 'ImageCollection' or output_type == 'ee.ImageCollection':
|
|
380
401
|
return self._PixelAreaSumCollection
|
|
381
402
|
elif output_type == 'GenericCollection':
|
|
382
403
|
return GenericCollection(collection=self._PixelAreaSumCollection)
|
|
383
404
|
elif output_type == 'DataFrame' or output_type == 'Pandas' or output_type == 'pd' or output_type == 'dataframe' or output_type == 'df':
|
|
384
|
-
return GenericCollection(collection=self._PixelAreaSumCollection).
|
|
405
|
+
return GenericCollection(collection=self._PixelAreaSumCollection).exportProperties(property_names=prop_names)
|
|
385
406
|
else:
|
|
386
407
|
raise ValueError("Incorrect `output_type`. The `output_type` argument must be one of the following: 'ImageCollection', 'ee.ImageCollection', 'GenericCollection', 'DataFrame', 'Pandas', 'pd', 'dataframe', or 'df'.")
|
|
387
408
|
|
|
409
|
+
def PixelAreaSumCollection(
|
|
410
|
+
self, band_name, geometry, threshold=-1, scale=30, maxPixels=1e12, output_type='ImageCollection', area_data_export_path=None
|
|
411
|
+
):
|
|
412
|
+
warnings.warn(
|
|
413
|
+
"The `PixelAreaSumCollection` method is deprecated and will be removed in future versions. Please use the `pixelAreaSumCollection` method instead.",
|
|
414
|
+
DeprecationWarning,
|
|
415
|
+
stacklevel=2)
|
|
416
|
+
return self.pixelAreaSumCollection(
|
|
417
|
+
band_name, geometry, threshold, scale, maxPixels, output_type, area_data_export_path
|
|
418
|
+
)
|
|
419
|
+
|
|
388
420
|
@staticmethod
|
|
389
421
|
def add_month_property_fn(image):
|
|
390
422
|
"""
|
|
@@ -544,7 +576,7 @@ class GenericCollection:
|
|
|
544
576
|
|
|
545
577
|
return GenericCollection(collection=distinct_col)
|
|
546
578
|
|
|
547
|
-
def
|
|
579
|
+
def exportProperties(self, property_names, file_path=None):
|
|
548
580
|
"""
|
|
549
581
|
Fetches and returns specified properties from each image in the collection as a list, and returns a pandas DataFrame and optionally saves the results to a csv file.
|
|
550
582
|
|
|
@@ -599,6 +631,13 @@ class GenericCollection:
|
|
|
599
631
|
print(f"Properties saved to {file_path}")
|
|
600
632
|
|
|
601
633
|
return df
|
|
634
|
+
|
|
635
|
+
def ExportProperties(self, property_names, file_path=None):
|
|
636
|
+
warnings.warn(
|
|
637
|
+
"The `ExportProperties` method is deprecated and will be removed in future versions. Please use the `exportProperties` method instead.",
|
|
638
|
+
DeprecationWarning,
|
|
639
|
+
stacklevel=2)
|
|
640
|
+
return self.exportProperties(property_names, file_path)
|
|
602
641
|
|
|
603
642
|
def get_generic_collection(self):
|
|
604
643
|
"""
|
|
@@ -1983,6 +2022,8 @@ class GenericCollection:
|
|
|
1983
2022
|
rightField='Date_Filter')
|
|
1984
2023
|
else:
|
|
1985
2024
|
raise ValueError(f'The chosen `join_method`: {join_method} does not match the options of "system:time_start" or "Date_Filter".')
|
|
2025
|
+
|
|
2026
|
+
native_projection = image_collection.first().select(target_band).projection()
|
|
1986
2027
|
|
|
1987
2028
|
# for any matches during a join, set image as a property key called 'future_image'
|
|
1988
2029
|
join = ee.Join.saveAll(matchesKey='future_image')
|
|
@@ -2026,7 +2067,7 @@ class GenericCollection:
|
|
|
2026
2067
|
# convert the image collection to an image of s_statistic values per pixel
|
|
2027
2068
|
# where the s_statistic is the sum of partial s values
|
|
2028
2069
|
# renaming the band as 's_statistic' for later usage
|
|
2029
|
-
final_s_image = partial_s_col.sum().rename('s_statistic')
|
|
2070
|
+
final_s_image = partial_s_col.sum().rename('s_statistic').setDefaultProjection(native_projection)
|
|
2030
2071
|
|
|
2031
2072
|
|
|
2032
2073
|
########## PART 2 - VARIANCE and Z-SCORE ##########
|
|
@@ -2089,7 +2130,7 @@ class GenericCollection:
|
|
|
2089
2130
|
mask = ee.Image(1).clip(geometry)
|
|
2090
2131
|
final_image = final_image.updateMask(mask)
|
|
2091
2132
|
|
|
2092
|
-
return final_image
|
|
2133
|
+
return final_image.setDefaultProjection(native_projection)
|
|
2093
2134
|
|
|
2094
2135
|
def sens_slope_trend(self, target_band=None, join_method='system:time_start', geometry=None):
|
|
2095
2136
|
"""
|
|
@@ -2166,20 +2207,15 @@ class GenericCollection:
|
|
|
2166
2207
|
GenericCollection: masked GenericCollection image collection
|
|
2167
2208
|
|
|
2168
2209
|
"""
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
mask = ee.Image.constant(1).clip(polygon)
|
|
2210
|
+
# Convert the polygon to a mask
|
|
2211
|
+
mask = ee.Image.constant(1).clip(polygon)
|
|
2172
2212
|
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
# Update the internal collection state
|
|
2177
|
-
self._geometry_masked_collection = GenericCollection(
|
|
2178
|
-
collection=masked_collection
|
|
2179
|
-
)
|
|
2213
|
+
# Update the mask of each image in the collection
|
|
2214
|
+
masked_collection = self.collection.map(lambda img: img.updateMask(mask)\
|
|
2215
|
+
.copyProperties(img).set('system:time_start', img.get('system:time_start')))
|
|
2180
2216
|
|
|
2181
2217
|
# Return the updated object
|
|
2182
|
-
return
|
|
2218
|
+
return GenericCollection(collection=masked_collection)
|
|
2183
2219
|
|
|
2184
2220
|
def mask_out_polygon(self, polygon):
|
|
2185
2221
|
"""
|
|
@@ -2192,23 +2228,18 @@ class GenericCollection:
|
|
|
2192
2228
|
GenericCollection: masked GenericCollection image collection
|
|
2193
2229
|
|
|
2194
2230
|
"""
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
full_mask = ee.Image.constant(1)
|
|
2198
|
-
|
|
2199
|
-
# Use paint to set pixels inside polygon as 0
|
|
2200
|
-
area = full_mask.paint(polygon, 0)
|
|
2231
|
+
# Convert the polygon to a mask
|
|
2232
|
+
full_mask = ee.Image.constant(1)
|
|
2201
2233
|
|
|
2202
|
-
|
|
2203
|
-
|
|
2234
|
+
# Use paint to set pixels inside polygon as 0
|
|
2235
|
+
area = full_mask.paint(polygon, 0)
|
|
2204
2236
|
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
)
|
|
2237
|
+
# Update the mask of each image in the collection
|
|
2238
|
+
masked_collection = self.collection.map(lambda img: img.updateMask(area)\
|
|
2239
|
+
.copyProperties(img).set('system:time_start', img.get('system:time_start')))
|
|
2209
2240
|
|
|
2210
2241
|
# Return the updated object
|
|
2211
|
-
return
|
|
2242
|
+
return GenericCollection(collection=masked_collection)
|
|
2212
2243
|
|
|
2213
2244
|
|
|
2214
2245
|
def binary_mask(self, threshold=None, band_name=None, classify_above_threshold=True, mask_zeros=False):
|
|
@@ -2467,7 +2498,7 @@ class GenericCollection:
|
|
|
2467
2498
|
new_col = self.collection.filter(ee.Filter.eq("Date_Filter", img_date))
|
|
2468
2499
|
return new_col.first()
|
|
2469
2500
|
|
|
2470
|
-
def
|
|
2501
|
+
def collectionStitch(self, img_col2):
|
|
2471
2502
|
"""
|
|
2472
2503
|
Function to mosaic two GenericCollection objects which share image dates.
|
|
2473
2504
|
Mosaics are only formed for dates where both image collections have images.
|
|
@@ -2519,9 +2550,16 @@ class GenericCollection:
|
|
|
2519
2550
|
|
|
2520
2551
|
# Return a GenericCollection instance
|
|
2521
2552
|
return GenericCollection(collection=new_col)
|
|
2553
|
+
|
|
2554
|
+
def CollectionStitch(self, img_col2):
|
|
2555
|
+
warnings.warn(
|
|
2556
|
+
"CollectionStitch is deprecated. Please use collectionStitch instead.",
|
|
2557
|
+
DeprecationWarning,
|
|
2558
|
+
stacklevel=2)
|
|
2559
|
+
return self.collectionStitch(img_col2)
|
|
2522
2560
|
|
|
2523
2561
|
@property
|
|
2524
|
-
def
|
|
2562
|
+
def mosaicByDateDepr(self):
|
|
2525
2563
|
"""
|
|
2526
2564
|
Property attribute function to mosaic collection images that share the same date.
|
|
2527
2565
|
|
|
@@ -2577,6 +2615,64 @@ class GenericCollection:
|
|
|
2577
2615
|
|
|
2578
2616
|
# Convert the list of mosaics to an ImageCollection
|
|
2579
2617
|
return self._MosaicByDate
|
|
2618
|
+
|
|
2619
|
+
@property
|
|
2620
|
+
def mosaicByDate(self):
|
|
2621
|
+
"""
|
|
2622
|
+
Property attribute function to mosaic collection images that share the same date.
|
|
2623
|
+
|
|
2624
|
+
The property CLOUD_COVER for each image is used to calculate an overall mean,
|
|
2625
|
+
which replaces the CLOUD_COVER property for each mosaiced image.
|
|
2626
|
+
Server-side friendly.
|
|
2627
|
+
|
|
2628
|
+
NOTE: if images are removed from the collection from cloud filtering, you may have mosaics composed of only one image.
|
|
2629
|
+
|
|
2630
|
+
Returns:
|
|
2631
|
+
LandsatCollection: LandsatCollection image collection with mosaiced imagery and mean CLOUD_COVER as a property
|
|
2632
|
+
"""
|
|
2633
|
+
if self._MosaicByDate is None:
|
|
2634
|
+
distinct_dates = self.collection.distinct("Date_Filter")
|
|
2635
|
+
|
|
2636
|
+
# Define a join to link images by Date_Filter
|
|
2637
|
+
filter_date = ee.Filter.equals(leftField="Date_Filter", rightField="Date_Filter")
|
|
2638
|
+
join = ee.Join.saveAll(matchesKey="date_matches")
|
|
2639
|
+
|
|
2640
|
+
# Apply the join
|
|
2641
|
+
# Primary: Distinct dates collection
|
|
2642
|
+
# Secondary: The full original collection
|
|
2643
|
+
joined_col = ee.ImageCollection(join.apply(distinct_dates, self.collection, filter_date))
|
|
2644
|
+
|
|
2645
|
+
# Define the mosaicking function
|
|
2646
|
+
def _mosaic_day(img):
|
|
2647
|
+
# Recover the list of images for this day
|
|
2648
|
+
daily_list = ee.List(img.get("date_matches"))
|
|
2649
|
+
daily_col = ee.ImageCollection.fromImages(daily_list)
|
|
2650
|
+
|
|
2651
|
+
# Create the mosaic
|
|
2652
|
+
mosaic = daily_col.mosaic().setDefaultProjection(img.projection())
|
|
2653
|
+
|
|
2654
|
+
# Properties to preserve from the representative image
|
|
2655
|
+
props_of_interest = [
|
|
2656
|
+
"system:time_start",
|
|
2657
|
+
"Date_Filter"
|
|
2658
|
+
]
|
|
2659
|
+
|
|
2660
|
+
# Return mosaic with properties set
|
|
2661
|
+
return mosaic.copyProperties(img, props_of_interest)
|
|
2662
|
+
# 5. Map the function and wrap the result
|
|
2663
|
+
mosaiced_col = joined_col.map(_mosaic_day)
|
|
2664
|
+
self._MosaicByDate = GenericCollection(collection=mosaiced_col)
|
|
2665
|
+
|
|
2666
|
+
# Convert the list of mosaics to an ImageCollection
|
|
2667
|
+
return self._MosaicByDate
|
|
2668
|
+
|
|
2669
|
+
@property
|
|
2670
|
+
def MosaicByDate(self):
|
|
2671
|
+
warnings.warn(
|
|
2672
|
+
"MosaicByDate is deprecated. Please use mosaicByDate instead.",
|
|
2673
|
+
DeprecationWarning,
|
|
2674
|
+
stacklevel=2)
|
|
2675
|
+
return self.mosaicByDate
|
|
2580
2676
|
|
|
2581
2677
|
@staticmethod
|
|
2582
2678
|
def ee_to_df(
|