Spatial Joins

Collections can be joined by spatial location as well as by property values. To join based on spatial location, use a withinDistance() filter with .geo join fields specified. The .geo field indicates that the item's geometry is to be used to compute the distance metric. For example, consider the task of finding all FLUXNET sites within 100 kilometers of each Landsat image in a collection. For that purpose, use a filter on the geometry fields, with the maximum distance set to 100 kilometers using the distance parameter:

// Load a primary collection: Landsat imagery.
var primary = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
    .filterDate('2014-04-01', '2014-06-01')
    .filterBounds(ee.Geometry.Point(-122.09, 37.42));

// Load a secondary collection: FLUXNET points in a Fusion Table.
var fluxnet = ee.FeatureCollection('projects/google/fluxnet-sites');

// Define a spatial filter, with distance 100 km.
var distFilter = ee.Filter.withinDistance({
  distance: 100000,
  leftField: '.geo',
  rightField: '.geo',
  maxError: 10

// Define a saveAll join.
var distSaveAll = ee.Join.saveAll({
  matchesKey: 'points',
  measureKey: 'distance'

// Apply the join.
var spatialJoined = distSaveAll.apply(primary, fluxnet, distFilter);

// Print the result.

Note that the previous example joins a FeatureCollection to an ImageCollection. The saveAll() join sets a property (points) on each image in the primary collection which stores a list of the points within 100 km of the image. The distance of each point to the image is stored in the distance property of each joined point.

Spatial joins can also be applied to feature collections to find places where the features in one collection intersect those in another. For example, consider two feature collections: a primary collection containing one polygon representing the boundary of California state, a secondary collection containing polygons representing Landsat image footprints according to the Worldwide Reference System. Suppose there is need to find all the image footprints which intersect the California polygon. This can be accomplished with a spatial join as follows:

// Load the primary collection: a California polygon.
var cali = ee.FeatureCollection('TIGER/2018/States')
  .filter(ee.Filter.eq('NAME', 'California'));

// Load the secondary collection: WRS-2 polygons.
var wrs = ee.FeatureCollection('projects/google/wrs2_descending');

// Define a spatial filter as geometries that intersect.
var spatialFilter = ee.Filter.intersects({
  leftField: '.geo',
  rightField: '.geo',
  maxError: 10

// Define a save all join.
var saveAllJoin = ee.Join.saveAll({
  matchesKey: 'scenes',

// Apply the join.
var intersectJoined = saveAllJoin.apply(cali, wrs, spatialFilter);

// Get the result and display it.
var intersected = ee.FeatureCollection(ee.List(intersectJoined.first().get('scenes')));
Map.addLayer(intersected, {}, 'WRS-2 polygons');
Map.addLayer(cali, {color: 'FF0000'}, 'California polygon');

In the previous example, note that the intersects() filter doesn’t store a distance as the withinDistance() filter does. The output should look something like Figure 1.

CA WRS2 join
Figure 1. Landsat WRS-2 footprints joined to a California polygon.

Send feedback about...

Google Earth Engine