RadGEEToolbox 1.6.9__py3-none-any.whl → 1.7.0__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.
@@ -346,12 +346,12 @@ class Sentinel1Collection:
346
346
  else:
347
347
  raise ValueError("output_type must be 'ImageCollection' or 'Sentinel1Collection'")
348
348
 
349
- def merge(self, other):
349
+ def combine(self, other):
350
350
  """
351
- Merges the current Sentinel1Collection with another Sentinel1Collection, where images/bands with the same date are combined to a single multiband image.
351
+ Combines the current Sentinel1Collection with another Sentinel1Collection, using the `combine` method.
352
352
 
353
353
  Args:
354
- other (Sentinel1Collection): Another Sentinel1Collection to merge with current collection.
354
+ other (Sentinel1Collection): Another Sentinel1Collection to combine with current collection.
355
355
 
356
356
  Returns:
357
357
  Sentinel1Collection: A new Sentinel1Collection containing images from both collections.
@@ -364,6 +364,73 @@ class Sentinel1Collection:
364
364
  merged_collection = self.collection.combine(other.collection)
365
365
  return Sentinel1Collection(collection=merged_collection)
366
366
 
367
+ def merge(self, collections=None, multiband_collection=None, date_key='Date_Filter'):
368
+ """
369
+ Merge many singleband Sentinel1Collection products into the parent collection,
370
+ or merge a single multiband collection with parent collection,
371
+ pairing images by exact Date_Filter and returning one multiband image per date.
372
+
373
+ NOTE: if you want to merge two multiband collections, use the `combine` method instead.
374
+
375
+ Args:
376
+ collections (list): List of singleband collections to merge with parent collection, effectively adds one band per collection to each image in parent
377
+ multiband_collection (Sentinel1Collection, optional): A multiband collection to merge with parent. Specifying a collection here will override `collections`.
378
+ date_key (str): image property key for exact pairing (default 'Date_Filter')
379
+
380
+ Returns:
381
+ Sentinel1Collection: parent with extra single bands attached (one image per date)
382
+ """
383
+
384
+ if collections is None and multiband_collection is not None:
385
+ # Exact-date inner-join merge of two collections (adds ALL bands from 'other').
386
+ join = ee.Join.inner()
387
+ flt = ee.Filter.equals(leftField=date_key, rightField=date_key)
388
+ paired = join.apply(self.collection, multiband_collection.collection, flt)
389
+
390
+ def _pair_two(f):
391
+ f = ee.Feature(f)
392
+ a = ee.Image(f.get('primary'))
393
+ b = ee.Image(f.get('secondary'))
394
+ # Overwrite on name collision
395
+ merged = a.addBands(b, None, True)
396
+ # Keep parent props + date key
397
+ merged = merged.copyProperties(a, a.propertyNames())
398
+ merged = merged.set(date_key, a.get(date_key))
399
+ return ee.Image(merged)
400
+
401
+ return Sentinel1Collection(collection=ee.ImageCollection(paired.map(_pair_two)))
402
+
403
+ # Preferred path: merge many singleband products into the parent
404
+ if not isinstance(collections, list) or len(collections) == 0:
405
+ raise ValueError("Provide a non-empty list of Sentinel1Collection objects in `collections`.")
406
+
407
+ result = self.collection
408
+ for extra in collections:
409
+ if not isinstance(extra, Sentinel1Collection):
410
+ raise ValueError("All items in `collections` must be Sentinel1Collection objects.")
411
+
412
+ join = ee.Join.inner()
413
+ flt = ee.Filter.equals(leftField=date_key, rightField=date_key)
414
+ paired = join.apply(result, extra.collection, flt)
415
+
416
+ def _attach_one(f):
417
+ f = ee.Feature(f)
418
+ parent = ee.Image(f.get('primary'))
419
+ sb = ee.Image(f.get('secondary'))
420
+ # Assume singleband product; grab its first band name server-side
421
+ bname = ee.String(sb.bandNames().get(0))
422
+ # Add the single band; overwrite if the name already exists in parent
423
+ merged = parent.addBands(sb.select([bname]).rename([bname]), None, True)
424
+ # Preserve parent props + date key
425
+ merged = merged.copyProperties(parent, parent.propertyNames())
426
+ merged = merged.set(date_key, parent.get(date_key))
427
+ return ee.Image(merged)
428
+
429
+ result = ee.ImageCollection(paired.map(_attach_one))
430
+
431
+ return Sentinel1Collection(collection=result)
432
+
433
+
367
434
  @staticmethod
368
435
  def multilook_fn(image, looks):
369
436
  if looks not in [1, 2, 3, 4]:
@@ -1795,3 +1862,59 @@ class Sentinel1Collection:
1795
1862
  print(f"Zonal stats saved to {file_path}.csv")
1796
1863
  return
1797
1864
  return pivot_df
1865
+
1866
+ def export_to_asset_collection(
1867
+ self,
1868
+ asset_collection_path,
1869
+ region,
1870
+ scale,
1871
+ dates=None,
1872
+ filename_prefix="",
1873
+ crs=None,
1874
+ max_pixels=int(1e13),
1875
+ description_prefix="export"
1876
+ ):
1877
+ """
1878
+ Exports an image collection to a Google Earth Engine asset collection. The asset collection will be created if it does not already exist,
1879
+ and each image exported will be named according to the provided filename prefix and date.
1880
+
1881
+ Args:
1882
+ asset_collection_path (str): The path to the asset collection.
1883
+ region (ee.Geometry): The region to export.
1884
+ scale (int): The scale of the export.
1885
+ dates (list, optional): The dates to export. Defaults to None.
1886
+ filename_prefix (str, optional): The filename prefix. Defaults to "", i.e. blank.
1887
+ crs (str, optional): The coordinate reference system. Defaults to None, which will use the image's CRS.
1888
+ max_pixels (int, optional): The maximum number of pixels. Defaults to int(1e13).
1889
+ description_prefix (str, optional): The description prefix. Defaults to "export".
1890
+
1891
+ Returns:
1892
+ None: (queues export tasks)
1893
+ """
1894
+ ic = self.collection
1895
+ if dates is None:
1896
+ dates = self.dates
1897
+ try:
1898
+ ee.data.createAsset({'type': 'ImageCollection'}, asset_collection_path)
1899
+ except Exception:
1900
+ pass
1901
+
1902
+ for date_str in dates:
1903
+ img = ee.Image(ic.filter(ee.Filter.eq('Date_Filter', date_str)).first())
1904
+ asset_id = asset_collection_path + "/" + filename_prefix + date_str
1905
+ desc = description_prefix + "_" + filename_prefix + date_str
1906
+
1907
+ params = {
1908
+ 'image': img,
1909
+ 'description': desc,
1910
+ 'assetId': asset_id,
1911
+ 'region': region,
1912
+ 'scale': scale,
1913
+ 'maxPixels': max_pixels
1914
+ }
1915
+ if crs:
1916
+ params['crs'] = crs
1917
+
1918
+ ee.batch.Export.image.toAsset(**params).start()
1919
+
1920
+ print("Queued", len(dates), "export tasks to", asset_collection_path)