Announcement: All noncommercial projects registered to use Earth Engine before April 15, 2025 must verify noncommercial eligibility to maintain Earth Engine access.
Stay organized with collections
Save and categorize content based on your preferences.
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
power plants within 100 kilometers
of Yosemite National Park, USA. For that purpose, use a filter on the geometry
fields, with the maximum distance set to 100 kilometers using the distance
parameter:
Note that the previous example joins a FeatureCollection to another
FeatureCollection. The saveAll() join sets a property
(points) on each feature in the primary collection which
stores a list of the points within 100 km of the feature. The distance of each point to
the feature is stored in the distance property of each joined point.
Spatial joins can also be used to identify which features
in one collection intersect those in another. For example, consider two feature
collections: a primary collection containing polygons representing the
boundaries of US states, a secondary collection containing point locations
representing power plants. Suppose there is need to determine the number intersecting each
state. This can be accomplished with a spatial join as follows:
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.
Figure 1. Bar chart showing the number of power plants intersecting each US state.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-12-27 UTC."],[[["\u003cp\u003eCollections in Earth Engine can be joined based on spatial relationships like proximity or intersection using the \u003ccode\u003eee.Join\u003c/code\u003e module.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003ewithinDistance()\u003c/code\u003e filter joins features within a specified distance, while the \u003ccode\u003eintersects()\u003c/code\u003e filter joins features that overlap geographically.\u003c/p\u003e\n"],["\u003cp\u003eSpatial joins can be used for various analyses, such as finding power plants within a certain distance of a park or counting power plants within each state boundary.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003esaveAll()\u003c/code\u003e join method creates a new property containing a list of all matching features from the secondary collection, enabling further analysis and visualization.\u003c/p\u003e\n"]]],[],null,["Collections can be joined by spatial location as well as by property values. To join based\non spatial location, use a `withinDistance()` filter with `.geo` join\nfields specified. The `.geo` field indicates that the item's\ngeometry is to be used to compute the distance metric. For example, consider the task of\nfinding all\n[power plants](https://developers.google.com/earth-engine/datasets/catalog/WRI_GPPD_power_plants) within 100 kilometers\nof Yosemite National Park, USA. For that purpose, use a filter on the geometry\nfields, with the maximum distance set to 100 kilometers using the `distance`\nparameter:\n\nCode Editor (JavaScript) \n\n```javascript\n// Load a primary collection: protected areas (Yosemite National Park).\nvar primary = ee.FeatureCollection(\"WCMC/WDPA/current/polygons\")\n .filter(ee.Filter.eq('NAME', 'Yosemite National Park'));\n\n// Load a secondary collection: power plants.\nvar powerPlants = ee.FeatureCollection('WRI/GPPD/power_plants');\n\n// Define a spatial filter, with distance 100 km.\nvar distFilter = ee.Filter.withinDistance({\n distance: 100000,\n leftField: '.geo',\n rightField: '.geo',\n maxError: 10\n});\n\n// Define a saveAll join.\nvar distSaveAll = ee.Join.saveAll({\n matchesKey: 'points',\n measureKey: 'distance'\n});\n\n// Apply the join.\nvar spatialJoined = distSaveAll.apply(primary, powerPlants, distFilter);\n\n// Print the result.\nprint(spatialJoined);\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\nColab (Python) \n\n```python\n# Load a primary collection: protected areas (Yosemite National Park).\nprimary = ee.FeatureCollection('WCMC/WDPA/current/polygons').filter(\n ee.Filter.eq('NAME', 'Yosemite National Park')\n)\n\n# Load a secondary collection: power plants.\npower_plants = ee.FeatureCollection('WRI/GPPD/power_plants')\n\n# Define a spatial filter, with distance 100 km.\ndist_filter = ee.Filter.withinDistance(\n distance=100000, leftField='.geo', rightField='.geo', maxError=10\n)\n\n# Define a saveAll join.\ndist_save_all = ee.Join.saveAll(matchesKey='points', measureKey='distance')\n\n# Apply the join.\nspatial_joined = dist_save_all.apply(primary, power_plants, dist_filter)\n\n# Print the result.\ndisplay(spatial_joined)\n```\n\nNote that the previous example joins a `FeatureCollection` to another\n`FeatureCollection`. The `saveAll()` join sets a property\n(`points`) on each feature in the `primary` collection which\nstores a list of the points within 100 km of the feature. The distance of each point to\nthe feature is stored in the `distance` property of each joined point.\n\nSpatial joins can also be used to identify which features\nin one collection intersect those in another. For example, consider two feature\ncollections: a `primary` collection containing polygons representing the\nboundaries of US states, a `secondary` collection containing point locations\nrepresenting power plants. Suppose there is need to determine the number intersecting each\nstate. This can be accomplished with a spatial join as follows:\n\nCode Editor (JavaScript) \n\n```javascript\n// Load the primary collection: US state boundaries.\nvar states = ee.FeatureCollection('TIGER/2018/States');\n\n// Load the secondary collection: power plants.\nvar powerPlants = ee.FeatureCollection('WRI/GPPD/power_plants');\n\n// Define a spatial filter as geometries that intersect.\nvar spatialFilter = ee.Filter.intersects({\n leftField: '.geo',\n rightField: '.geo',\n maxError: 10\n});\n\n// Define a save all join.\nvar saveAllJoin = ee.Join.saveAll({\n matchesKey: 'power_plants',\n});\n\n// Apply the join.\nvar intersectJoined = saveAllJoin.apply(states, powerPlants, spatialFilter);\n\n// Add power plant count per state as a property.\nintersectJoined = intersectJoined.map(function(state) {\n // Get \"power_plant\" intersection list, count how many intersected this state.\n var nPowerPlants = ee.List(state.get('power_plants')).size();\n // Return the state feature with a new property: power plant count.\n return state.set('n_power_plants', nPowerPlants);\n});\n\n// Make a bar chart for the number of power plants per state.\nvar chart = ui.Chart.feature.byFeature(intersectJoined, 'NAME', 'n_power_plants')\n .setChartType('ColumnChart')\n .setSeriesNames({n_power_plants: 'Power plants'})\n .setOptions({\n title: 'Power plants per state',\n hAxis: {title: 'State'},\n vAxis: {title: 'Frequency'}});\n\n// Print the chart to the console.\nprint(chart);\n```\n\nIn the previous example, note that the `intersects()` filter doesn't store\na distance as the `withinDistance()` filter does. The output should look\nsomething like Figure 1.\nFigure 1. Bar chart showing the number of power plants intersecting each US state."]]