{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "\"Open\n", "\n", "Uncomment the following line to install [geemap](https://geemap.org) if needed." ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": {}, "outputs": [], "source": [ "# !pip install geemap" ] }, { "cell_type": "markdown", "id": "2", "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", "id": "3", "metadata": {}, "source": [ "### Using ee.Image with pydeck" ] }, { "cell_type": "code", "execution_count": null, "id": "4", "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", "id": "5", "metadata": {}, "source": [ "Adding multiple Earth Engine images" ] }, { "cell_type": "code", "execution_count": null, "id": "6", "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", "id": "7", "metadata": {}, "source": [ "### Using ee.ImageCollection with pydeck" ] }, { "cell_type": "code", "execution_count": null, "id": "8", "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", "id": "9", "metadata": {}, "source": [ "### Using ee.FeatureCollection (points) with pydeck" ] }, { "cell_type": "code", "execution_count": null, "id": "10", "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", "id": "11", "metadata": {}, "source": [ "### Using ee.FeatureCollection (lines) with pydeck" ] }, { "cell_type": "code", "execution_count": null, "id": "12", "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, "id": "13", "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 }