@@ -1233,51 +1233,48 @@ def sortMany(
12331233 ) -> ee .ImageCollection :
12341234 """Sort an ImageCollection using more than 1 property.
12351235
1236+ The properties are set in the order of priority. The first property is the most important one,
1237+ in case of a tie, the second property is used to break the tie, and so on.
1238+
1239+ Warning:
1240+ This method will raise an error if the 2 parameter are not the same size.
1241+
12361242 Args:
12371243 properties: the list of properties to sort by.
12381244 ascending: the list of order. If not passed all properties will be sorted ascending
1245+
1246+ Examples:
1247+ .. jupyter-execute::
1248+
1249+ import ee, geetools
1250+ from geetools.utils import initialize_documentation
1251+
1252+ initialize_documentation()
1253+
1254+ # order the 500 first images of the NOAA forecast by forecasted date. in case of tie,
1255+ # order by creation date. We limit to 500 to not exceed GEE computation limits²
1256+ ic = ee.ImageCollection("NOAA/GFS0P25").limit(500)
1257+ icSorted = ic.geetools.sortMany(["forecast_time", "creation_time"])
1258+
1259+ # print the sorted list of images with forecast and creation time properties for the 10 first
1260+ icSorted = icSorted.limit(10)
1261+ info = icSorted.toList(icSorted.size()).map(lambda x: ee.Dictionary({
1262+ "forecast_time": ee.Date(ee.Image(x).get("forecast_time")).format(),
1263+ "creation_time": ee.Date(ee.Image(x).get("creation_time")).format()
1264+ }))
1265+ for item in info.getInfo():
1266+ print(f"Forecast Time: {item['forecast_time']}, Creation Time: {item['creation_time']}")
12391267 """
1240- properties = ee .List (properties )
1241- asc = ee .List (ascending or properties .map (lambda p : True ))
1242- order_dict = ee .Dictionary .fromLists (properties .slice (0 , asc .size ()), asc )
1243- # position order of each prop will be converted to string using this format
1244- length = self ._obj .size ().toInt ().format ().length ()
1245- format = ee .String ("%0" ).cat (length .format ()).cat ("d" )
1246- # suffix for temporal properties
1247- pos_suffix = ee .String ("_geetools_position" )
1248-
1249- def compute_position (prop , cum ):
1250- """Add the order position of the property to each image."""
1251- cum = ee .ImageCollection (cum )
1252- order = ee .Algorithms .If (order_dict .get (prop , True ), True , False )
1253- sorted_values = self ._obj .sort (prop , order ).aggregate_array (prop ).distinct ()
1254- position_name = ee .String (prop ).cat (pos_suffix )
1255-
1256- def add_position (img ):
1257- index = sorted_values .indexOf (img .get (prop ))
1258- return img .set (position_name , index .format (format ))
1259-
1260- return cum .map (add_position )
1261-
1262- with_positions = ee .ImageCollection (properties .iterate (compute_position , self ._obj ))
1263- # put temp properties in a list to further remove them
1264- position_properties = properties .map (lambda p : ee .String (p ).cat (pos_suffix ))
1265- final_order_property = "_geetools_sort_many_"
1266-
1267- def compute_final_prop (img ):
1268- """Join order position string of each property into a single number."""
1269- img = ee .Image (img )
1270- # values = img.toDictionary(position_properties).values() # this should work but doesn't
1271- values = position_properties .map (lambda p : img .get (p ))
1272- return img .set (final_order_property , values .join ("" ))
1273-
1274- with_order = with_positions .map (compute_final_prop )
1275- # add final property to properties to remove
1276- prop_to_remove = position_properties .add (final_order_property )
1277- # sort using the final property and remove temp properties
1278- sorted = with_order .sort (final_order_property )
1279- sorted = sorted .map (lambda i : ee .Image (i .copyProperties (i , exclude = prop_to_remove )))
1280- return sorted
1268+ # sanity checks
1269+ props = ee .List (properties )
1270+ asc = ee .List (ascending or props .map (lambda _ : True ))
1271+
1272+ # Compute the sort chain in reverse order so that the first key is the primary one and so on.
1273+ ic = self ._obj
1274+ propertiesIndex = ee .List .sequence (0 , props .size ().subtract (1 )).reverse ()
1275+ ic = propertiesIndex .iterate (lambda i , c : ee .ImageCollection (c ).sort (props .get (i ), asc .get (i )), ic )
1276+
1277+ return ee .ImageCollection (ic )
12811278
12821279 def datesByBands (
12831280 self ,
0 commit comments