Skip to content

Commit f723417

Browse files
committed
Added zonal statistics function and example
1 parent 13f62eb commit f723417

File tree

3 files changed

+180
-24
lines changed

3 files changed

+180
-24
lines changed

examples/README.md

+30-24
Original file line numberDiff line numberDiff line change
@@ -21,58 +21,64 @@ More video tutorials for geemap and Earth Engine are available on my [YouTube ch
2121

2222
## Tutorials
2323

24-
1. [Introducing the geemap Python package for interactive mapping with Google Earth Engine](#introducing-the-geemap-python-package-for-interactive-mapping-with-google-earth-engine)
25-
2. [Using basemaps in geemap and ipyleaflet for interactive mapping with Google Earth Engine](#using-basemaps-in-geemap-and-ipyleaflet-for-interactive-mapping-with-google-earth-engine)
26-
3. [Introducing the Inspector tool for Earth Engine Python API](#introducing-the-inspector-tool-for-earth-engine-python-api)
27-
4. [Creating a split-panel map for visualizing Earth Engine data](#creating-a-split-panel-map-for-visualizing-earth-engine-data)
28-
5. [Using drawing tools to interact with Earth Engine data](#using-drawing-tools-to-interact-with-earth-engine-data)
29-
6. [Creating an interactive map with a marker cluster](#creating-an-interactive-map-with-a-marker-cluster)
30-
7. [Converting data formats between GeoJSON and Earth Engine](#converting-data-formats-between-geojson-and-earth-engine)
31-
8. [Automated conversion from Earth Engine JavaScripts to Python scripts and Jupyter notebooks](#automated-conversion-from-earth-engine-javascripts-to-python-scripts-and-jupyter-notebooks)
32-
9. [Interactive plotting of Earth Engine data with minimal coding](#interactive-plotting-of-earth-engine-data-with-minimal-coding)
33-
10. [Using shapefiles with Earth Engine without having to upload data to GEE](#using-shapefiles-with-earth-engine-without-having-to-upload-data-to-gee)
34-
11. [Exporting Earth Engine Image and ImageCollection as GeoTIFF and Numpy array](#exporting-earth-engine-image-and-imagecollection-as-geotiff-and-numpy-array)
35-
36-
### Introducing the geemap Python package for interactive mapping with Google Earth Engine
24+
1. [Introducing the geemap Python package for interactive mapping with Google Earth Engine](#1-introducing-the-geemap-python-package-for-interactive-mapping-with-google-earth-engine)
25+
2. [Using basemaps in geemap and ipyleaflet for interactive mapping with Google Earth Engine](#2-using-basemaps-in-geemap-and-ipyleaflet-for-interactive-mapping-with-google-earth-engine)
26+
3. [Introducing the Inspector tool for Earth Engine Python API](#3-introducing-the-inspector-tool-for-earth-engine-python-api)
27+
4. [Creating a split-panel map for visualizing Earth Engine data](#4-creating-a-split-panel-map-for-visualizing-earth-engine-data)
28+
5. [Using drawing tools to interact with Earth Engine data](#5-using-drawing-tools-to-interact-with-earth-engine-data)
29+
6. [Creating an interactive map with a marker cluster](#6-creating-an-interactive-map-with-a-marker-cluster)
30+
7. [Converting data formats between GeoJSON and Earth Engine](#7-converting-data-formats-between-geojson-and-earth-engine)
31+
8. [Automated conversion from Earth Engine JavaScripts to Python scripts and Jupyter notebooks](#8-automated-conversion-from-earth-engine-javascripts-to-python-scripts-and-jupyter-notebooks)
32+
9. [Interactive plotting of Earth Engine data with minimal coding](#9-interactive-plotting-of-earth-engine-data-with-minimal-coding)
33+
10. [Using shapefiles with Earth Engine without having to upload data to GEE](#10-using-shapefiles-with-earth-engine-without-having-to-upload-data-to-gee)
34+
11. [Exporting Earth Engine Image and ImageCollection as GeoTIFF and Numpy array](#11-exporting-earth-engine-image-and-imagecollection-as-geotiff-and-numpy-array)
35+
12. [Zonal statistics with Earth Engine and exporting results as CSV or shapefile](#12-zonal-statistics-with-earth-engine-and-exporting-results-as-csv-or-shapefile)
36+
37+
38+
### 1. Introducing the geemap Python package for interactive mapping with Google Earth Engine
3739

3840
![Intro geemap](https://i.imgur.com/pI39k7v.gif)
3941

40-
### Using basemaps in geemap and ipyleaflet for interactive mapping with Google Earth Engine
42+
### 2. Using basemaps in geemap and ipyleaflet for interactive mapping with Google Earth Engine
4143

4244
![basemaps](https://i.imgur.com/P5B2f7p.gif)
4345

44-
### Introducing the Inspector tool for Earth Engine Python API
46+
### 3. Introducing the Inspector tool for Earth Engine Python API
4547

4648
![Inspector tool](https://i.imgur.com/8d77gtI.gif)
4749

48-
### Creating a split-panel map for visualizing Earth Engine data
50+
### 4. Creating a split-panel map for visualizing Earth Engine data
4951

5052
![Split panel](https://i.imgur.com/kql7pC3.gif)
5153

52-
### Using drawing tools to interact with Earth Engine data
54+
### 5. Using drawing tools to interact with Earth Engine data
5355

5456
![Drawing tools](https://i.imgur.com/Lm5pDUr.gif)
5557

56-
### Creating an interactive map with a marker cluster
58+
### 6. Creating an interactive map with a marker cluster
5759

5860
![Marker cluster](https://i.imgur.com/GF4cOqh.gif)
5961

60-
### Converting data formats between GeoJSON and Earth Engine
62+
### 7. Converting data formats between GeoJSON and Earth Engine
6163

6264
![GeoJSON](https://i.imgur.com/hVPmUG1.gif)
6365

64-
### Automated conversion from Earth Engine JavaScripts to Python scripts and Jupyter notebooks
66+
### 8. Automated conversion from Earth Engine JavaScripts to Python scripts and Jupyter notebooks
6567

6668
![Conversion](https://i.imgur.com/BW0zJnN.gif)
6769

68-
### Interactive plotting of Earth Engine data with minimal coding
70+
### 9. Interactive plotting of Earth Engine data with minimal coding
6971

7072
![Plotting](https://i.imgur.com/iGMRnRb.gif)
7173

72-
### Using shapefiles with Earth Engine without having to upload data to GEE
74+
### 10. Using shapefiles with Earth Engine without having to upload data to GEE
7375

7476
![shapefile](https://i.imgur.com/W3vNSdX.gif)
7577

76-
### Exporting Earth Engine Image and ImageCollection as GeoTIFF and Numpy array
78+
### 11. Exporting Earth Engine Image and ImageCollection as GeoTIFF and Numpy array
7779

78-
![exporting](https://i.imgur.com/RonLr0j.gif)
80+
![exporting](https://i.imgur.com/RonLr0j.gif)
81+
82+
### 12. Zonal statistics with Earth Engine and exporting results as CSV or shapefile
83+
84+
![zonal](https://i.imgur.com/8xmUitW.gif)
+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"import ee\n",
10+
"import geemap\n",
11+
"import os"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": null,
17+
"metadata": {},
18+
"outputs": [],
19+
"source": [
20+
"Map = geemap.Map()\n",
21+
"Map"
22+
]
23+
},
24+
{
25+
"cell_type": "code",
26+
"execution_count": null,
27+
"metadata": {},
28+
"outputs": [],
29+
"source": [
30+
"# Add Earth Engine dataset\n",
31+
"dem = ee.Image('USGS/SRTMGL1_003')\n",
32+
"\n",
33+
"# Set visualization parameters.\n",
34+
"dem_vis = {\n",
35+
" 'min': 0,\n",
36+
" 'max': 4000,\n",
37+
" 'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5']}\n",
38+
"\n",
39+
"# Add Earth Engine DEM to map\n",
40+
"Map.addLayer(dem, dem_vis, 'SRTM DEM')\n",
41+
"\n",
42+
"# Add Landsat data to map\n",
43+
"landsat = ee.Image('LE7_TOA_5YEAR/1999_2003')\n",
44+
"\n",
45+
"landsat_vis = {\n",
46+
" 'bands': ['B4', 'B3', 'B2'], \n",
47+
" 'gamma': 1.4\n",
48+
"}\n",
49+
"Map.addLayer(landsat, landsat_vis, \"LE7_TOA_5YEAR/1999_2003\")\n",
50+
"\n",
51+
"states = ee.FeatureCollection(\"TIGER/2018/States\")\n",
52+
"Map.addLayer(states, {}, 'US States')"
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": null,
58+
"metadata": {},
59+
"outputs": [],
60+
"source": [
61+
"out_dir = os.path.join(os.path.expanduser('~'), 'Downloads')\n",
62+
"out_dem_stats = os.path.join(out_dir, 'dem_stats.csv') \n",
63+
"\n",
64+
"# Allowed output formats: csv, shp, json, kml, kmz\n",
65+
"# Allowed statistics type: MEAN, MAXIMUM, MINIMUM, MEDIAN, STD, MIN_MAX, VARIANCE, SUM\n",
66+
"geemap.zonal_statistics(dem, states, out_dem_stats, statistics_type='MEAN', scale=1000)"
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": null,
72+
"metadata": {},
73+
"outputs": [],
74+
"source": [
75+
"out_landsat_stats = os.path.join(out_dir, 'landsat_stats.csv') \n",
76+
"geemap.zonal_statistics(landsat, states, out_landsat_stats, statistics_type='SUM', scale=1000)"
77+
]
78+
}
79+
],
80+
"metadata": {
81+
"kernelspec": {
82+
"display_name": "Python 3",
83+
"language": "python",
84+
"name": "python3"
85+
},
86+
"language_info": {
87+
"codemirror_mode": {
88+
"name": "ipython",
89+
"version": 3
90+
},
91+
"file_extension": ".py",
92+
"mimetype": "text/x-python",
93+
"name": "python",
94+
"nbconvert_exporter": "python",
95+
"pygments_lexer": "ipython3",
96+
"version": "3.8.2"
97+
}
98+
},
99+
"nbformat": 4,
100+
"nbformat_minor": 4
101+
}

geemap/geemap.py

+49
Original file line numberDiff line numberDiff line change
@@ -1462,3 +1462,52 @@ def ee_to_numpy(ee_object, bands=None, region=None, properties=None, default_val
14621462

14631463
except Exception as e:
14641464
print(e)
1465+
1466+
1467+
def zonal_statistics(in_value_raster, in_zone_vector, out_file_path, statistics_type='MEAN', scale=None, crs=None, tile_scale=1.0):
1468+
1469+
if not isinstance(in_value_raster, ee.Image):
1470+
print('The input raster must be an ee.Image.')
1471+
return
1472+
1473+
if not isinstance(in_zone_vector, ee.FeatureCollection):
1474+
print('The input zone data must be an ee.FeatureCollection.')
1475+
return
1476+
1477+
allowed_formats = ['csv', 'json', 'kml', 'kmz', 'shp']
1478+
filename = os.path.abspath(out_file_path)
1479+
basename = os.path.basename(filename)
1480+
name = os.path.splitext(basename)[0]
1481+
filetype = os.path.splitext(basename)[1][1:]
1482+
1483+
if not (filetype in allowed_formats):
1484+
print('The file type must be one of the following: {}'.format(
1485+
', '.join(allowed_formats)))
1486+
return
1487+
1488+
allowed_statistics = {
1489+
'MEAN': ee.Reducer.mean(),
1490+
'MAXIMUM': ee.Reducer.max(),
1491+
'MEDIAN': ee.Reducer.median(),
1492+
'MINIMUM': ee.Reducer.min(),
1493+
'STD': ee.Reducer.stdDev(),
1494+
'MIN_MAX': ee.Reducer.minMax(),
1495+
'SUM': ee.Reducer.sum(),
1496+
'VARIANCE': ee.Reducer.variance()
1497+
}
1498+
1499+
if not (statistics_type in allowed_statistics.keys()):
1500+
print('The statistics type must be one of the following: {}'.format(
1501+
', '.join(list(allowed_statistics.keys()))))
1502+
return
1503+
1504+
if scale is None:
1505+
scale = in_value_raster.projection().nominalScale().multiply(10)
1506+
1507+
try:
1508+
print('Computing statistics ...')
1509+
result = in_value_raster.reduceRegions(
1510+
collection=in_zone_vector, reducer=allowed_statistics[statistics_type], scale=scale, crs=crs, tileScale=tile_scale)
1511+
ee_export_vector(result, filename)
1512+
except Exception as e:
1513+
print(e)

0 commit comments

Comments
 (0)