{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Pydeck + Earth Engine: Points FeatureCollection\n", "\n", "This is an example of using [pydeck](https://pydeck.gl) to visualize a Google Earth Engine `FeatureCollection` of points.\n", "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/power-plants" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import required packages:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pydeck_earthengine_layers import EarthEngineLayer\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": [ "### Power plants dataset\n", "\n", "This example uses the [Global Power Plant Database][dataset], which contains location of power plants around the world, as well as metadata of which fuel source is used, and how much energy is created.\n", "\n", "[dataset]: https://developers.google.com/earth-engine/datasets/catalog/WRI_GPPD_power_plants\n", "\n", "First we'll render using EarthEngine's native capabilities, then we'll render using pydeck's rich data-driven styling capabilities." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Load the FeatureCollection\n", "table = ee.FeatureCollection(\"WRI/GPPD/power_plants\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create color palette\n", "fuel_color = ee.Dictionary({\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", "})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# List of fuels to add to the map\n", "fuels = ['Coal', 'Oil', 'Gas', 'Hydro', 'Nuclear', 'Solar', 'Waste',\n", " 'Wind', 'Geothermal', 'Biomass']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "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('styleProperty', ee.Dictionary({'pointSize': size, 'color': color}))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Make a FeatureCollection out of the power plant data table\n", "pp = ee.FeatureCollection(table).map(add_style)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 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(styleProperty='styleProperty', neighborhood=50),\n", " id=fuel,\n", " opacity=0.65,\n", " )\n", " layers.append(layer)" ] }, { "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(latitude=36, longitude=-53, zoom=3)\n", "r = pdk.Deck(\n", " layers=layers, \n", " initial_view_state=view_state\n", ")\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vector rendering\n", "\n", "To experience the full potential of pydeck, we need to explore rendering the data with vector output. Rendering the data as a vector allows for client-side data driven styling and picking objects to get information on each." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fuel_color = {\n", " 'Coal': [0, 0, 0],\n", " 'Oil': [89, 55, 4],\n", " 'Gas': [188, 128, 189],\n", " 'Hydro': [5, 101, 166],\n", " 'Nuclear': [227, 26, 28],\n", " 'Solar': [255, 127, 0],\n", " 'Waste': [106, 61, 154],\n", " 'Wind': [92, 162, 209],\n", " 'Geothermal': [253, 191, 111],\n", " 'Biomass': [34, 154, 0],\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "layers = []\n", "for fuel in fuels:\n", " layer = EarthEngineLayer(\n", " # Create each layer as consisting of a single fuel type\n", " table.filter(ee.Filter.eq('fuel1', fuel)),\n", " vis_params={},\n", " # Define a custom radius\n", " getRadius='.properties.capacitymw ** 1.35',\n", " lineWidthMinPixels=0.5,\n", " pointRadiusMinPixels=2,\n", " # Use dictionary for color mapping\n", " get_fill_color=fuel_color[fuel],\n", " # Provide a list of extra dataset properties that should be downloaded for rendering\n", " # Without this, only the geometry will be downloaded\n", " selectors=['capacitymw'],\n", " # Render as a vector, instead of as a raster generated on EE's servers\n", " as_vector=True,\n", " id=fuel,\n", " opacity=0.65,\n", " )\n", " layers.append(layer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then just as before, we define a `ViewState` and pass these layers to the `Deck` object." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "view_state = pdk.ViewState(latitude=36, longitude=-53, zoom=3)\n", "r = pdk.Deck(\n", " layers=layers, \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 }