0

I wrote this code using the Earth Engine JavaScript API. The code clips the image collection using variable "table," which is a feature collection of about 12,000 points. I get the length of the image collection and use that number to create a a variable "sequence." I use this variable to create a nested map loop of sorts. I grab a single image and get a list of coordinates from that image. Then for each set of coordinates in the list, I store a bunch of information from that point into a dictionary and create a feature out of it. I need to convert this code to Python, but I am not sure how to convert the lines of code that use the map() function twice ("var getImgCoords and var getMetadata"). The variable "sequence2" changes for each loop, so I thought I could use the iterate() function instead of map().

var TerraClimate = ee.ImageCollection("IDAHO_EPSCOR/TERRACLIMATE"),
var table = ee.FeatureCollection("users/adrianom/CAN_AK_Coordinates")

var SearchArea = table;
var SearchAreaGeom = SearchArea.geometry();
var terraclimate_bounds = TerraClimate.filterBounds(SearchAreaGeom);

  // Clip collection to search area, more precisely than filterBounds above.
  var icClip = terraclimate_bounds.map(function(img){
    var i = img.clip(SearchAreaGeom);
    return(i);
  });

  var icClip_len = icClip.size();
  var col_list = icClip.toList(icClip_len);


  var sequence = ee.List.sequence(0, icClip_len.subtract(1));


  var getImgCoords = sequence.map(function(i){
    var img = ee.Image(col_list.get(i));
    var coords = img.geometry().coordinates();
    var coords_len = coords.size();
    var sequence2 = ee.List.sequence(0, coords_len.subtract(1));

    var getMetadata = sequence2.map(function(j){
        var coor = coords.get(j);
        var geom = ee.Geometry.Point(coor);
        var reduce = img.reduceRegion(ee.Reducer.mean(), geom, 4638.312116386398);

        var dictionary = ee.Dictionary({
          x: ee.List(coor).get(0),
          y: ee.List(coor).get(1),
          Start_Date: ee.Date(img.get('system:time_start')),
          End_Date: ee.Date(img.get('system:time_end'))
        });

        var combine_dict = reduce.combine(dictionary);
        var feature = ee.Feature(geom, combine_dict);
        return(feature);
    });


    return(getMetadata);

  });
0

This is an interesting question, since you shouldn't need to change anything to migrate from JS to Python, but in this case where you have a nested loop you have to do some workaround. No need to change the logic, just the structure.

import ee
ee.Initialize()

TerraClimate = ee.ImageCollection("IDAHO_EPSCOR/TERRACLIMATE")
table = ee.FeatureCollection("users/adrianom/CAN_AK_Coordinates")

SearchArea = table
SearchAreaGeom = SearchArea.geometry()
terraclimate_bounds = TerraClimate.filterBounds(SearchAreaGeom)

# Clip collection to search area, more precisely than filterBounds above.
icClip = terraclimate_bounds.map(lambda img: img.clip(SearchAreaGeom))

icClip_len = icClip.size()
col_list = icClip.toList(icClip_len)
sequence = ee.List.sequence(0, icClip_len.subtract(1))

# make a function that takes coords and img and return a function
def getMetadata(coords, img):
    # I changed coords because did not work as you have it in JS
    coords = ee.List(ee.List(coords).get(0))
    img = ee.Image(img)
    def wrap(j):
        coor = ee.List(coords.get(j))
        geom = ee.Geometry.Point(coor)
        reduce = img.reduceRegion(ee.Reducer.mean(), geom, 4638.312116386398)

        dictionary = ee.Dictionary({
          'x': ee.List(coor).get(0),
          'y': ee.List(coor).get(1),
          'Start_Date': ee.Date(img.get('system:time_start')),
          'End_Date': ee.Date(img.get('system:time_end'))
        })

        combine_dict = reduce.combine(dictionary)
        feature = ee.Feature(geom, combine_dict)
        return feature
        return coor
    return wrap

# function to loop over image indexes
def getImgCoords(i):
    img = ee.Image(col_list.get(i))
    coords = img.geometry().coordinates()
    coords_len = coords.size()
    sequence2 = ee.List.sequence(0, coords_len.subtract(1))
    # the function getMetadata returns a function, so map it
    return sequence2.map(getMetadata(coords, img))

# final result
imgCoords = sequence.map(getImgCoords)

By the way, you don't need to map over a list of indexes and get the elements from the list with the given index.. the map function goes over each element of the list, so you should just use it that way. In getImgCoords just map over coords and instead o mapping over sequence you could just map over col_list. But I translated the code as it was.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.