Jonathan Marokhovsky
Sending all changes and seeing what sticks
8775fbe
raw
history blame
No virus
4.92 kB
from boettiger_app import read_polygon
import leafmap.foliumap as leafmap
import rioxarray
import geopandas as gpd
import streamlit as st
import altair as alt
import ibis
from ibis import _
import ibis.selectors as s
from streamlit_folium import st_folium
import json
from leafmap import pmtiles_style
# Common Functions
def read_polygon(polygon):
"""
Take in a polygon from the app and convert it to GeoJSON
"""
geojson_str = json.dumps(polygon)
gdf = gpd.read_file(geojson_str, driver="GeoJSON")
gdf.set_crs("epsg:4326")
return gdf
# Actual Page content below
started = None
if not started:
st.set_page_config(layout="wide", page_title="Huggingface Toy", page_icon="❦")
st.title("Huggingface Streamlit Toy")
"""
This is a toy to play around with Huggingface, Leafmap, and Streamlit
I'm looking to implement at least these things:
* Visualize raster data from an S3 bucket
* Let the user (you!) draw polygons and calculate some stats (mean, median, etc.)
* Let user load pre-defined geometries (admin levels? country borders?)
* Load boundaries based on the center of the map
"""
hi = "https://data.source.coop/vizzuality/hfp-100/hfp_2021_100m_v1-2_cog.tif"
deforest = "https://data.source.coop/vizzuality/lg-land-carbon-data/deforest_carbon_100m_cog.tif"
# Euromap info
eurocrops_pmtiles = "https://s3.us-west-2.amazonaws.com/us-west-2.opendata.source.coop/cholmes/eurocrops/eurocrops-all.pmtiles"
ec_style = pmtiles_style(eurocrops_pmtiles)
m = leafmap.Map(center=[41, -69], zoom=5)
# Moved the cog layers into optional scripts to make the pmtile information easier to see.
# m.add_cog_layer(
# deforest,
# palette="reds",
# name="deforested",
# transparent_bg=True,
# opacity=0.5,
# zoom_to_layer=False,
# )
# m.add_cog_layer(
# hi,
# palette="purples",
# name="human impact",
# transparent_bg=True,
# opacity=0.5,
# zoom_to_layer=False,
# )
m.add_pmtiles(
eurocrops_pmtiles,
name="euro crops",
style=ec_style,
overlay=True,
show=True,
zoom_to_layer=False,
)
# TODO: automate getting the polygon from the figrue
# TODO: Calculate some metrics given the area.
# TODO: add a raster to the toy
# TODO: Change calculation depending on what layers are present
# TODO: Dynamically check the center of the map and change what's displayed depending on that.
polygon_ex = '{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-6.108398,40.780541],[-6.108398,54.342149],[15.908203,54.342149],[15.908203,40.780541],[-6.108398,40.780541]]]}}'
# code_ex = """
# m.add_gdf(polygon, layer_name="selection")
# """
code_ex = ""
## Map controls sidebar
with st.sidebar:
"""
# Map controls
### Polygon selector
"""
polygon = st.text_area(label="geometry", value=polygon_ex, height=400)
"""
### python code for map layer:
adjust options or add additional layers using leafmap
"""
code = st.text_area(label="code:", value=code_ex, height=400)
# Here we actually compute the total carbon in the requested polygon
# NOTE: It is not possible to access user_roi_bounds from streamlit per: https://github.com/opengeos/leafmap/discussions/152#discussioncomment-1870416
# bounds = m.user_roi_bounds()
# if bounds is not None:
# bounds.set_crs("epsg:4326")
# geo = gpd.read_file(polygon, driver="GeoJSON")
# geo.set_crs("epsg:4326")
# x = (
# rioxarray.open_rasterio("/vsicurl/" + deforest, masked=True)
# .rio.clip(geo.geometry.values, geo.crs, from_disk=True)
# .mean()
# )
# value = x
"### Average of tons of carbon lost:"
# st.write(f"{value:,}")
st.divider()
# run whatever python code is in the python box, just for fun
eval(compile(code, "<string>", "exec"))
st_data = m.to_streamlit(height=700, bidirectional=True)
polygon = st_data["last_active_drawing"]
"### Could there be a polygon here?"
st.write(f"{polygon is not None}")
if polygon is not None:
"### The Polygon is: "
gdf = read_polygon(polygon)
st.write(f"{polygon}")
started = True
"## Explore Further"
st.write("""
To modify the map, add code to the `code` section in the sidebar to the left. Some examples of code to add are below.
""")
st.code("""
# Show deforested areas:
m.add_cog_layer(
deforest,
palette="reds",
name="deforested",
transparent_bg=True,
opacity=0.5,
zoom_to_layer=False,
)
# Show human impacted areas
m.add_cog_layer(
hi,
palette="purples",
name="human impact",
transparent_bg=True,
opacity=0.5,
zoom_to_layer=False,
)
""")
"""
## Credits
This toy was inspired by boettiger-lab's Carbon Calculator Demo: https://huggingface.co/spaces/boettiger-lab/leafmap
### Data Sources
- Human Footprint by Vizzuality, on https://beta.source.coop/repositories/vizzuality/hfp-100, citation: https://doi.org/10.3389/frsen.2023.1130896, License: Public Domain
"""