Streamlit / apps /deck.py
giswqs's picture
Add timelapse app
9ad0e2d
import os
import streamlit as st
import pydeck as pdk
import pandas as pd
def globe_view():
"""
GlobeView
=========
Over 33,000 power plants of the world plotted by their production capacity (given by height)
and fuel type (green if renewable) on an experimental deck.gl GlobeView.
"""
COUNTRIES = "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_admin_0_scale_rank.geojson"
POWER_PLANTS = "https://raw.githubusercontent.com/ajduberstein/geo_datasets/master/global_power_plant_database.csv"
df = pd.read_csv(POWER_PLANTS)
def is_green(fuel_type):
"""Return a green RGB value if a facility uses a renewable fuel type"""
if fuel_type.lower() in (
"nuclear",
"water",
"wind",
"hydro",
"biomass",
"solar",
"geothermal",
):
return [10, 230, 120]
return [230, 158, 10]
df["color"] = df["primary_fuel"].apply(is_green)
view_state = pdk.ViewState(latitude=51.47, longitude=0.45, zoom=2, min_zoom=2)
# Set height and width variables
view = pdk.View(type="_GlobeView", controller=True, width=1000, height=700)
layers = [
pdk.Layer(
"GeoJsonLayer",
id="base-map",
data=COUNTRIES,
stroked=False,
filled=True,
get_fill_color=[200, 200, 200],
),
pdk.Layer(
"ColumnLayer",
id="power-plant",
data=df,
get_elevation="capacity_mw",
get_position=["longitude", "latitude"],
elevation_scale=100,
pickable=True,
auto_highlight=True,
radius=20000,
get_fill_color="color",
),
]
r = pdk.Deck(
views=[view],
initial_view_state=view_state,
tooltip={"text": "{name}, {primary_fuel} plant, {country}"},
layers=layers,
# Note that this must be set for the globe to be opaque
parameters={"cull": True},
)
return r
def geojson_layer():
"""
GeoJsonLayer
===========
Property values in Vancouver, Canada, adapted from the deck.gl example pages. Input data is in a GeoJSON format.
"""
DATA_URL = "https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/geojson/vancouver-blocks.json"
LAND_COVER = [
[[-123.0, 49.196], [-123.0, 49.324], [-123.306, 49.324], [-123.306, 49.196]]
]
INITIAL_VIEW_STATE = pdk.ViewState(
latitude=49.254, longitude=-123.13, zoom=11, max_zoom=16, pitch=45, bearing=0
)
polygon = pdk.Layer(
"PolygonLayer",
LAND_COVER,
stroked=False,
# processes the data as a flat longitude-latitude pair
get_polygon="-",
get_fill_color=[0, 0, 0, 20],
)
geojson = pdk.Layer(
"GeoJsonLayer",
DATA_URL,
opacity=0.8,
stroked=False,
filled=True,
extruded=True,
wireframe=True,
get_elevation="properties.valuePerSqm / 20",
get_fill_color="[255, 255, properties.growth * 255]",
get_line_color=[255, 255, 255],
)
r = pdk.Deck(layers=[polygon, geojson], initial_view_state=INITIAL_VIEW_STATE)
return r
def terrain():
"""
TerrainLayer
===========
Extruded terrain using AWS Open Data Terrain Tiles and Mapbox Satellite imagery
"""
# Import Mapbox API Key from environment
MAPBOX_API_KEY = os.environ["MAPBOX_API_KEY"]
# AWS Open Data Terrain Tiles
TERRAIN_IMAGE = (
"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"
)
# Define how to parse elevation tiles
ELEVATION_DECODER = {
"rScaler": 256,
"gScaler": 1,
"bScaler": 1 / 256,
"offset": -32768,
}
SURFACE_IMAGE = f"https://api.mapbox.com/v4/mapbox.satellite/{{z}}/{{x}}/{{y}}@2x.png?access_token={MAPBOX_API_KEY}"
terrain_layer = pdk.Layer(
"TerrainLayer",
elevation_decoder=ELEVATION_DECODER,
texture=SURFACE_IMAGE,
elevation_data=TERRAIN_IMAGE,
)
view_state = pdk.ViewState(
latitude=46.24, longitude=-122.18, zoom=11.5, bearing=140, pitch=60
)
r = pdk.Deck(terrain_layer, initial_view_state=view_state)
return r
def app():
st.title("Pydeck Gallery")
options = ["GeoJsonLayer", "GlobeView", "TerrainLayer"]
option = st.selectbox("Select a pydeck layer type", options)
if option == "GeoJsonLayer":
st.header("Property values in Vancouver, Canada")
st.pydeck_chart(geojson_layer())
# elif option == "GlobeView":
# st.pydeck_chart(globe_view())
elif option == "TerrainLayer":
st.pydeck_chart(terrain())