{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Pydeck + Earth Engine: Terrain Visualization\n", "\n", "This is an example of using [pydeck](https://pydeck.gl) to visualize a Google Earth Engine `Image` object _over 3D terrain_. To install and run this notebook locally, refer to the [Pydeck Earth Engine documentation](https://earthengine-layers.com/docs/developer-guide/pydeck-integration).\n", "\n", "To see this example online, view the [JavaScript version][js-example].\n", "\n", "[js-example]: https://earthengine-layers.com/examples/terrain" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, import required packages. Note that here we import the `EarthEngineTerrainLayer` instead of the `EarthEngineLayer`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineTerrainLayer\n", "import pydeck as pdk\n", "import ee" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Authenticate with Earth Engine\n", "\n", "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/." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Terrain Example\n", "\n", "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.\n", "\n", "It's important for the terrain source to have relatively high spatial resolution. In previous examples, we used [SRTM90][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][srtm30] (30-meter resolution) as the `Image` source and the [USGS's National Elevation Dataset][ned] (10-meter resolution, U.S. only) as the terrain source. SRTM30 is generally the best-resolution worldwide data source available.\n", "\n", "[srtm90]: https://developers.google.com/earth-engine/datasets/catalog/CGIAR_SRTM90_V4\n", "[srtm30]: https://developers.google.com/earth-engine/datasets/catalog/USGS_SRTMGL1_003\n", "[ned]: https://developers.google.com/earth-engine/datasets/catalog/USGS_NED" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "image = ee.Image('USGS/SRTMGL1_003')\n", "terrain = ee.Image('USGS/NED').select('elevation')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here `vis_params` consists of parameters that will be passed to the Earth Engine [`visParams` argument][visparams]. Any parameters that you could pass directly to Earth Engine in the code editor, you can also pass here to the `EarthEngineLayer`.\n", "\n", "[visparams]: https://developers.google.com/earth-engine/image_visualization" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vis_params={\n", " \"min\": 0, \n", " \"max\": 4000,\n", " \"palette\": ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5']\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we're ready to create the Pydeck layer. The `EarthEngineLayer` makes this simple. Just pass the Earth Engine object to the class." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ee_layer = EarthEngineTerrainLayer(\n", " image,\n", " terrain,\n", " vis_params,\n", " id=\"EETerrainLayer\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then just pass this layer to a `pydeck.Deck` instance, and call `.show()` to create a map:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "view_state = pdk.ViewState(\n", " latitude=36.15,\n", " longitude=-111.96,\n", " zoom=10.5, \n", " bearing=-66.16,\n", " pitch=60)\n", "r = pdk.Deck(\n", " layers=[ee_layer], \n", " initial_view_state=view_state\n", ")\n", "r.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.7" } }, "nbformat": 4, "nbformat_minor": 4 }