2

I have 2 ee.FeatureCollections in GEE. The first is a square grid polygon layer. The second is a polygon layer made up of multiple irregular rectangles that overlap with one another. I want to count the number of times each grid square intersects with the rectangles and export this result as a Shapefile. I am used to performing spatial joins in QGIS, ArcGIS and R but would like to do it in GEE. However, I am facing some problems related to understanding the function of several code segments.

Here is a graphic demonstrating what I intend to achieve.

enter image description here

I was trying to work this out by following closely with the GEE tutorial on Spatial Joins but I am running into some errors which I am unsure how to solve. Primarily, I am unsure what to define in the code lines 31 (on 'matchesKey') and 44 (on 'grid.get') as I haven't yet understood their functions. After several failed attempts, I am wondering if I should be using another approach instead, for e.g. via ee.Geometry.Polygon.intersection().

Here is the link to my code (with the assets shared publicly) and the code appended in this thread too.

/*
Purpose of script:

For each grid square, count the number of times it intersects with another Feature Collection,
and return the count value as a new property

*/

//  Load square grid layer
var grid = ee.FeatureCollection('users/jjohanness1992/SpatialJoin/grid');
print('1st grid square',grid.first());

//  Load polygon layer
var rectangles = ee.FeatureCollection('users/jjohanness1992/SpatialJoin/rectangles');
print('1st rectangle',rectangles.first());

//  Inspect in map
Map.addLayer(grid,{},'grid');
Map.addLayer(rectangles,{},'rectangles');
Map.centerObject(rectangles,15);

//  Define spatial filter that controls the intersection of geometries
var spatialFilter = ee.Filter.intersects({
  leftField: '.geo',
  rightField: '.geo',
  maxError: 0.01
});

//  Define a save all join
var saveAllJoin = ee.Join.saveAll({
    matchesKey: 'id', // I'm not sure what I should put here in matchesKey: 'XXX'
});
// **********
/* Here I get the following error message:
Error: Invalid property type: Property id has type List<Object>. (Error code: 3)
*/
// **********

//  Apply the join
var intersectJoined = saveAllJoin.apply(grid, rectangles, spatialFilter);

//  Count number of firepix in a grid and set as a property
intersectJoined = intersectJoined.map(function(grid) {
  var nRectangles = ee.List(grid.get('id')).size(); // I'm not sure what to put in grid.get('XXX')
  return grid.set('nCount',nRectangles);
});


//  Export
Export.table.toDrive({
  collection: intersectJoined,
  description:'intersectJoined',
  folder: '00_pilot',
  fileFormat: 'SHP'
});

1 Answer 1

1

You didn't say the reason of your affirmation related to "after several failed attempts". So, I supossed that it was in the impossibility of exporting intersectJoined Feature Collection as shapefile. This collection has the unusual field (Property) id whose content is a List type Object; producing an error code 3 when it is trying to export as shapefile.

This error can be avoided removing that Property. By using the answer in this question, I modified your code as follows (link here):

/*
Purpose of script:

For each grid square, count the number of times it intersects with another Feature Collection,
and return the count value as a new property

*/

//  Load square grid layer
var grid = ee.FeatureCollection('users/jjohanness1992/SpatialJoin/grid');
//print('1st grid square',grid.first());

//  Load polygon layer
var rectangles = ee.FeatureCollection('users/jjohanness1992/SpatialJoin/rectangles');
//print('1st rectangle',rectangles.first());

//  Inspect in map
//Map.addLayer(grid,{},'grid');
//Map.addLayer(rectangles,{},'rectangles');
Map.centerObject(rectangles,15);

//  Define spatial filter that controls the intersection of geometries
var spatialFilter = ee.Filter.intersects({
  leftField: '.geo',
  rightField: '.geo',
  maxError: 0.01
});

//  Define a save all join
var saveAllJoin = ee.Join.saveAll({
    matchesKey: 'id', // I'm not sure what I should put here in matchesKey: 'XXX'
});
// **********
/* Here I get the following error message:
Error: Invalid property type: Property id has type List<Object>. (Error code: 3)
*/
// **********

//  Apply the join
var intersectJoined = saveAllJoin.apply(grid, rectangles, spatialFilter);

//  Count number of firepix in a grid and set as a property
intersectJoined = intersectJoined.map(function(grid) {
  var nRectangles = ee.List(grid.get('id')).size(); // I'm not sure what to put in grid.get('XXX')
  return grid.set('nCount',nRectangles);
});

print("intersectJoined", intersectJoined.limit(10));

// Generic Function to remove a property from a feature
var removeProperty = function(feat, property) {
  var properties = feat.propertyNames();
  var selectProperties = properties.filter(ee.Filter.neq('item', property));
  return feat.select(selectProperties);
};

// remove property id in each feature
var intersectJoined = intersectJoined.map(function(feat) {
  return removeProperty(feat, 'id');
});

print(intersectJoined.limit(10));


//  Export
Export.table.toDrive({
  collection: intersectJoined,
  description:'intersectJoined',
  folder: '00_pilot',
  fileFormat: 'SHP'
});

After running above code and its associated task in GEE code editor, I got the shapefile without any error. I downloaded it to my disk drive and it looks as follows in QGIS. It has 82,834 records in its attributes table with nCount between 1 and 38. I hope this helps.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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