Spaces:
Sleeping
Sleeping
# -*- coding: utf-8 -*- | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
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 | |
def extract_geom(gdf, cog): | |
x = (rioxarray. | |
open_rasterio('/vsicurl/'+cog, masked=True). | |
rio.clip(gdf.geometry.values, gdf.crs, from_disk=True) | |
) | |
return x | |
def read_polygon(polygon): | |
geojson_str = json.dumps(polygon) | |
gdf = gpd.read_file(geojson_str, driver='GeoJSON') | |
gdf.set_crs('epsg:4326') | |
return gdf | |
def area_hectares(gdf): | |
area = gdf.to_crs("EPSG:9822").area / 10000. | |
return area | |
# + | |
st.set_page_config(layout="wide", page_title="Paradise Valley", page_icon="⚡") | |
st.title("Land Use change in Paradise Valley") | |
DESCRIPTION=''' | |
Pan and zoom to the desired location on the map. Then, use the map tools to draw a polygon (pentagon tool), bounding box (square tool) or other shape anywhere on the map. | |
(use esc key to exit drawing mode). Map will display acres of land converted. | |
''' | |
built = "https://huggingface.co/datasets/boettiger-lab/yellowstone/resolve/main/diffs_cog.tif" | |
m = leafmap.Map(center=[35, -100], zoom=3) | |
## Map controls sidebar | |
with st.sidebar: | |
st.markdown(DESCRIPTION) | |
cog_layers = { | |
"Expanded Built Land, 2017-2023": built, | |
} | |
selection = st.radio("Data", cog_layers) | |
cog = cog_layers[selection] | |
m.add_cog_layer(cog, palette="reds", name=selection, | |
transparent_bg=True, opacity = 0.8, | |
zoom_to_layer=False) | |
"### python code for map layer:" | |
"adjust options or add additional layers using leafmap" | |
code = st.text_area( | |
label = "code:", | |
value = code_ex, | |
height = 400) | |
# run whatever python code is in the python box, just for fun | |
eval(compile(code, "<string>", "exec")) | |
st_data = m.to_streamlit(height=400, bidirectional=True) | |
polygon = st_data["last_active_drawing"] | |
# Here we actually compute the total carbon in the requested polygon | |
if polygon is not None: | |
gdf = read_polygon(polygon) | |
x = extract_geom(gdf, cog).fillna(0) | |
count = x.count() | |
area = round(float(area_hectares(gdf))) | |
carbon_total = round(float(x.mean()) * area) # no, mean does not include zeros | |
col2, col3 = st.columns(3) | |
col2.metric(label=f"Area", value=f"{area:,} Hectares") | |
col3.metric(label=f"pixels", value=f"{count:,}") | |
# pixel sums instead of means | |
# value = round(float(x.sum())) | |
# if(selection in ["Vulnerable Carbon (2018)", | |
# "Manageable Carbon (2018)", | |
# "Irrecoverable Carbon (2018)"]): | |
# value = value * 9 # 300m pixels, each pixel is 9 hectres | |
st.divider() | |
''' | |
Note: this is just a proof-of-principle demonstration of these tools, and these calculations have not been validated. | |
## Credits | |
### Data sources | |
- <https://planetarycomputer.microsoft.com/dataset/io-lulc-annual-v02> | |
### Software stack | |
- Streamlit (python) app hosted on free-tier HuggingFace spaces ([source code](https://huggingface.co/spaces/boettiger-lab/leafmap/blob/main/app.py)). | |
- Cloud-optimized geotifs hosted on [Source.Coop](https://source.coop) | |
- Mapping with Leafmap, calculations with rasterio | |
''' | |