# -*- 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, "", "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 - ### 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 '''