I noticed that I can't use map() to change the system:index of a FeatureCollection in GEE. I can change one system:index at a time. And I can use map() to edit other properties. Is there something special about 'system:index' that prevents me from using map() to edit?

var features = [
  ee.Feature(ee.Geometry.Rectangle(30.01, 59.80, 30.59, 60.15), {name: 'Voronoi'}),
  ee.Feature(ee.Geometry.Point(-73.96, 40.781), {name: 'Thiessen'}),
  ee.Feature(ee.Geometry.Point(6.4806, 50.8012), {name: 'Dirichlet'})

var fc = ee.FeatureCollection(features);

// Rename one feature
var newName = fc.first().get('name');
var renamed = fc.first().set('system:index', newName)
print('I can rename the system:index for one feature', renamed)

// Map across FC
var rename = function(f){
  var myNewName = ee.String(f.get('name'))
  return f.set('system:index', myNewName)
print('But cannot for a collection', fc.map(rename).first())

// Mapping a different function works ok
var addProperty = function(f){
  var newProperty = ee.String(f.get('name')).cat('Hello')
  return f.set('newProp', newProperty)
print('I can map set other properties', fc.map(addProperty).first())

I see this question found a workaround using ee.List. Is this the only solution for this?



Feature IDs (system:index) are special because it is guaranteed that every feature in a given collection will have a unique value of system:index.

You cannot change the ID when mapping over a collection because that would require remembering all previous IDs to make sure there are no duplicates, which is at odds with Earth Engine's goal of being able to process very large collections by going through them a few features at a time.

Transforming to an ee.List and back avoids this restriction because an ee.List is always processed as a whole — so it checking every feature against others for duplicate IDs is feasible. But, correspondingly, it is not possible to work with collections larger than available memory this way.

There are other limitations around system:index. For example, if you export a collection to an asset (table), then the system:index values will not be included — loading the asset will show newly assigned IDs. And, if you do any join or merge operations that combine two or more collections, the combined result will have modified IDs.

Therefore, I recommend that if you want specific identifiers for your features, store them in a normal user-defined property, not system:index.

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.