{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\"Open\n", "\n", "Uncomment the following line to install [geemap](https://geemap.org) if needed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# !pip install geemap" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## How to use Earth Engine with pydeck for 3D visualization\n", "\n", "### Requirements\n", "- [earthengine-api](https://github.com/google/earthengine-api): a Python client library for calling the Google Earth Engine API.\n", "- [pydeck](https://pydeck.gl/index.html): a WebGL-powered framework for visual exploratory data analysis of large datasets.\n", "- [pydeck-earthengine-layers](https://github.com/UnfoldedInc/earthengine-layers/tree/master/py): a pydeck wrapper for Google Earth Engine. For documentation please visit this [website](https://earthengine-layers.com/).\n", "- [Mapbox API key](https://pydeck.gl/installation.html#getting-a-mapbox-api-key): you will need this add basemap tiles to pydeck.\n", "\n", "### Installation\n", "\n", "- conda create -n deck python\n", "- conda activate deck\n", "- conda install mamba -c conda-forge\n", "- mamba install earthengine-api pydeck pydeck-earthengine-layers -c conda-forge\n", "- jupyter nbextension install --sys-prefix --symlink --overwrite --py pydeck\n", "- jupyter nbextension enable --sys-prefix --py pydeck" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using ee.Image with pydeck" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\n", "import pydeck as pdk\n", "import ee\n", "\n", "# Initialize Earth Engine library\n", "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()\n", "\n", "# Create an Earth Engine object\n", "image = ee.Image('CGIAR/SRTM90_V4')\n", "\n", "# Define Earth Engine visualization parameters\n", "vis_params = {\n", " \"min\": 0,\n", " \"max\": 4000,\n", " 'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5'],\n", "}\n", "\n", "# Create a pydeck EarthEngineLayer object, using the Earth Engine object and\n", "# desired visualization parameters\n", "ee_layer = EarthEngineLayer(image, vis_params)\n", "\n", "# Define the initial viewport for the map\n", "view_state = pdk.ViewState(\n", " latitude=37.7749295, longitude=-122.4194155, zoom=10, bearing=0, pitch=45\n", ")\n", "\n", "# Create a Deck instance, and display in Jupyter\n", "r = pdk.Deck(layers=[ee_layer], initial_view_state=view_state)\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding multiple Earth Engine images" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\n", "import pydeck as pdk\n", "import ee\n", "\n", "# Initialize Earth Engine library\n", "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()\n", "\n", "# Add Earth Engine dataset\n", "image = ee.Image('USGS/SRTMGL1_003')\n", "\n", "hillshade = ee.Terrain.hillshade(image)\n", "\n", "demRGB = image.visualize(\n", " **{\n", " 'min': 0,\n", " 'max': 4000,\n", " 'bands': ['elevation'],\n", " 'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5'],\n", " 'opacity': 0.5,\n", " }\n", ")\n", "\n", "hillshadeRGB = hillshade.visualize(**{'bands': ['hillshade']})\n", "\n", "blend = hillshadeRGB.blend(demRGB)\n", "\n", "ee_layer = EarthEngineLayer(blend, {})\n", "\n", "# Define the initial viewport for the map\n", "view_state = pdk.ViewState(\n", " latitude=37.7749295, longitude=-122.4194155, zoom=10, bearing=0, pitch=45\n", ")\n", "\n", "# Create a Deck instance, and display in Jupyter\n", "r = pdk.Deck(layers=[ee_layer], initial_view_state=view_state)\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using ee.ImageCollection with pydeck" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\n", "import pydeck as pdk\n", "import ee\n", "\n", "# Initialize Earth Engine library\n", "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()\n", "\n", "# Initialize an ee.ImageColllection object referencing the Global Forecast System dataset\n", "image_collection = ee.ImageCollection('NOAA/GFS0P25')\n", "\n", "# Select images from December 22, 2018\n", "image_collection = image_collection.filterDate('2018-12-22', '2018-12-23')\n", "\n", "# Choose the first 24 images in the ImageCollection\n", "image_collection = image_collection.limit(24)\n", "\n", "# Select a single band to visualize\n", "image_collection = image_collection.select('temperature_2m_above_ground')\n", "\n", "# Style temperature values between -40C and 35C,\n", "# with lower values shades of blue, purple, and cyan,\n", "# and higher values shades of green, yellow, and red\n", "vis_params = {\n", " 'min': -40.0,\n", " 'max': 35.0,\n", " 'palette': ['blue', 'purple', 'cyan', 'green', 'yellow', 'red'],\n", "}\n", "\n", "layer = EarthEngineLayer(\n", " image_collection, vis_params, animate=True, id=\"global_weather\"\n", ")\n", "\n", "view_state = pdk.ViewState(latitude=36, longitude=10, zoom=1)\n", "r = pdk.Deck(layers=[layer], initial_view_state=view_state)\n", "\n", "# layer.visible = True\n", "# layer.opacity = 0.2\n", "\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using ee.FeatureCollection (points) with pydeck" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\n", "import pydeck as pdk\n", "import ee\n", "\n", "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()\n", "\n", "# Load the FeatureCollection\n", "table = ee.FeatureCollection(\"WRI/GPPD/power_plants\")\n", "\n", "# Create color palette\n", "fuel_color = ee.Dictionary(\n", " {\n", " 'Coal': '000000',\n", " 'Oil': '593704',\n", " 'Gas': 'BC80BD',\n", " 'Hydro': '0565A6',\n", " 'Nuclear': 'E31A1C',\n", " 'Solar': 'FF7F00',\n", " 'Waste': '6A3D9A',\n", " 'Wind': '5CA2D1',\n", " 'Geothermal': 'FDBF6F',\n", " 'Biomass': '229A00',\n", " }\n", ")\n", "\n", "# List of fuels to add to the map\n", "fuels = [\n", " 'Coal',\n", " 'Oil',\n", " 'Gas',\n", " 'Hydro',\n", " 'Nuclear',\n", " 'Solar',\n", " 'Waste',\n", " 'Wind',\n", " 'Geothermal',\n", " 'Biomass',\n", "]\n", "\n", "\n", "def add_style(point):\n", " \"\"\"Computes size from capacity and color from fuel type.\n", "\n", " Args:\n", " - point: (ee.Geometry.Point) A Point\n", "\n", " Returns:\n", " (ee.Geometry.Point): Input point with added style dictionary\n", " \"\"\"\n", " size = ee.Number(point.get('capacitymw')).sqrt().divide(10).add(2)\n", " color = fuel_color.get(point.get('fuel1'))\n", " return point.set(\n", " 'styleProperty', ee.Dictionary({'pointSize': size, 'color': color})\n", " )\n", "\n", "\n", "# Make a FeatureCollection out of the power plant data table\n", "pp = ee.FeatureCollection(table).map(add_style)\n", "\n", "# Create a layer for each fuel type\n", "layers = []\n", "for fuel in fuels:\n", " layer = EarthEngineLayer(\n", " pp.filter(ee.Filter.eq('fuel1', fuel)).style(\n", " styleProperty='styleProperty', neighborhood=50\n", " ),\n", " id=fuel,\n", " opacity=0.65,\n", " )\n", " layers.append(layer)\n", "\n", "view_state = pdk.ViewState(latitude=36, longitude=-53, zoom=3)\n", "\n", "r = pdk.Deck(layers=layers, initial_view_state=view_state)\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using ee.FeatureCollection (lines) with pydeck" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\n", "import pydeck as pdk\n", "import ee\n", "\n", "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()\n", "\n", "# Hurricane tracks and points for 2017.\n", "hurricanes = ee.FeatureCollection('NOAA/NHC/HURDAT2/atlantic')\n", "\n", "year = '2017'\n", "points = hurricanes.filter(ee.Filter.date(ee.Date(year).getRange('year')))\n", "\n", "\n", "# Find all of the hurricane ids.\n", "def get_id(point):\n", " return ee.Feature(point).get('id')\n", "\n", "\n", "storm_ids = points.toList(1000).map(get_id).distinct()\n", "\n", "\n", "# Create a line for each hurricane.\n", "def create_line(storm_id):\n", " pts = points.filter(ee.Filter.eq('id', ee.String(storm_id)))\n", " pts = pts.sort('system:time_start')\n", " line = ee.Geometry.LineString(pts.geometry().coordinates())\n", " feature = ee.Feature(line)\n", " return feature.set('id', storm_id)\n", "\n", "\n", "lines = ee.FeatureCollection(storm_ids.map(create_line))\n", "\n", "\n", "lines_layer = EarthEngineLayer(\n", " lines,\n", " {'color': 'red'},\n", " id=\"tracks\",\n", ")\n", "\n", "points_layer = EarthEngineLayer(\n", " points,\n", " {'color': 'green'},\n", " id=\"points\",\n", ")\n", "\n", "\n", "view_state = pdk.ViewState(latitude=36, longitude=-53, zoom=3)\n", "r = pdk.Deck(layers=[points_layer, lines_layer], initial_view_state=view_state)\n", "r.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\n", "import pydeck as pdk\n", "import ee\n", "\n", "try:\n", " ee.Initialize()\n", "except Exception as e:\n", " ee.Authenticate()\n", " ee.Initialize()\n", "\n", "dataset = ee.FeatureCollection('FAO/GAUL/2015/level0')\n", "\n", "countries = dataset.style(fillColor='b5ffb4', color='00909F', width=3)\n", "\n", "layer = EarthEngineLayer(countries, id=\"international_boundaries\")\n", "view_state = pdk.ViewState(latitude=36, longitude=10, zoom=3)\n", "r = pdk.Deck(layers=[layer], initial_view_state=view_state)\n", "r.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }