Uncomment the following line to install geemap if needed.
# !pip install geemap
How to use Earth Engine with pydeck for 3D terrain visualization¶
Pydeck + Earth Engine: Terrain Visualization
Requirements
- earthengine-api: a Python client library for calling the Google Earth Engine API.
- pydeck: a WebGL-powered framework for visual exploratory data analysis of large datasets.
- pydeck-earthengine-layers: a pydekc wrapper for Google Earth Engine. For documentation please visit this website.
- Mapbox API key: you will need this add basemap tiles to pydeck.
Installation
- conda create -n deck python
- conda activate deck
- conda install mamba -c conda-forge
- mamba install earthengine-api pydeck pydeck-earthengine-layers -c conda-forge
- jupyter nbextension install --sys-prefix --symlink --overwrite --py pydeck
- jupyter nbextension enable --sys-prefix --py pydeck
This example is adopted from here. Credits to the developers of the pydeck-earthengine-layers package.
2D Visualization¶
import ee
import geemap
Map = geemap.Map()
Map
image = ee.Image('USGS/NED').select('elevation')
vis_params = {
"min": 0,
"max": 4000,
"palette": ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5'],
}
Map.addLayer(image, vis_params, 'NED')
First, import required packages. Note that here we import the EarthEngineTerrainLayer
instead of the EarthEngineLayer
.
import ee
import pydeck as pdk
from pydeck_earthengine_layers import EarthEngineTerrainLayer
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) Input In [5], in <cell line: 3>() 1 import ee 2 import pydeck as pdk ----> 3 from pydeck_earthengine_layers import EarthEngineTerrainLayer ModuleNotFoundError: No module named 'pydeck_earthengine_layers'
Authenticate with Earth Engine¶
Using Earth Engine requires authentication. If you don't have a Google account approved for use with Earth Engine, you'll need to request access. For more information and to sign up, go to https://signup.earthengine.google.com/.
try:
ee.Initialize()
except Exception as e:
ee.Authenticate()
ee.Initialize()
Terrain Example¶
In contrast to the EarthEngineLayer
, where you need to supply one Earth Engine object to render, with the EarthEngineTerrainLayer
you must supply two Earth Engine objects. The first is used to render the image in the same way as the EarthEngineLayer
; the second supplies elevation values used to extrude terrain in 3D. Hence the former can be any Image
object; the latter must be an Image
object whose values represents terrain heights.
It's important for the terrain source to have relatively high spatial resolution. In previous examples, we used SRTM90 as an elevation source, but that only has a resolution of 90 meters. When used as an elevation source, it looks very blocky/pixelated at high zoom levels. In this example we'll use SRTM30 (30-meter resolution) as the Image
source and the USGS's National Elevation Dataset (10-meter resolution, U.S. only) as the terrain source. SRTM30 is generally the best-resolution worldwide data source available.
# image = ee.Image('USGS/SRTMGL1_003')
image = ee.Image('USGS/NED').select('elevation')
terrain = ee.Image('USGS/NED').select('elevation')
Here vis_params
consists of parameters that will be passed to the Earth Engine visParams
argument. Any parameters that you could pass directly to Earth Engine in the code editor, you can also pass here to the EarthEngineLayer
.
vis_params = {
"min": 0,
"max": 4000,
"palette": ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5'],
}
Now we're ready to create the Pydeck layer. The EarthEngineLayer
makes this simple. Just pass the Earth Engine object to the class.
Including the id
argument isn't necessary when you only have one pydeck layer, but it is necessary to distinguish multiple layers, so it's good to get into the habit of including an id
parameter.
ee_layer = EarthEngineTerrainLayer(image, terrain, vis_params, id="EETerrainLayer")
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Input In [9], in <cell line: 1>() ----> 1 ee_layer = EarthEngineTerrainLayer(image, terrain, vis_params, id="EETerrainLayer") NameError: name 'EarthEngineTerrainLayer' is not defined
Then just pass this layer to a pydeck.Deck
instance, and call .show()
to create a map:
view_state = pdk.ViewState(
latitude=36.15, longitude=-111.96, zoom=10.5, bearing=-66.16, pitch=60
)
r = pdk.Deck(layers=[ee_layer], initial_view_state=view_state)
r.show()
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Input In [10], in <cell line: 5>() 1 view_state = pdk.ViewState( 2 latitude=36.15, longitude=-111.96, zoom=10.5, bearing=-66.16, pitch=60 3 ) ----> 5 r = pdk.Deck(layers=[ee_layer], initial_view_state=view_state) 7 r.show() NameError: name 'ee_layer' is not defined