Carl Boettiger commited on
Commit
f655a8e
1 Parent(s): e4937a4

more streamlined

Browse files
Files changed (2) hide show
  1. app.py +110 -76
  2. requirements.txt +1 -0
app.py CHANGED
@@ -19,48 +19,73 @@ import altair as alt
19
  import ibis
20
  from ibis import _
21
  import ibis.selectors as s
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
 
24
  # +
25
  st.set_page_config(layout="wide", page_title="Leafmap Explorer", page_icon="⚡")
26
 
27
- '''
28
- # Demo Carbon Calculator
29
 
30
- Use the map tools to draw a polygon (pentagon tool), bounding box (square tool) or other shape anywhere on the map.
31
- Click inside the box when you are done to show the coordinates.
32
- Please copy-paste those coordinates (or any geojson of your choosing) into the polygon selector.
33
- Map will zoom in on selected area and display the tons of carbon lost between 2002 - 2022 below.
34
  Data comes from Vizzuality repo on [source.coop](https://beta.source.coop/repositories/vizzuality/lg-land-carbon-data/description/).
35
  '''
36
 
 
 
37
  deforest = "https://data.source.coop/vizzuality/lg-land-carbon-data/deforest_carbon_100m_cog.tif"
 
38
  irrecoverable = "https://data.source.coop/cboettig/carbon/cogs/irrecoverable_c_total_2018.tif"
39
  vulnerable = "https://data.source.coop/cboettig/carbon/cogs/vulnerable_c_total_2018.tif"
 
40
 
41
- m = leafmap.Map(center=[35, -100], zoom=5)
42
- m.add_cog_layer("https://data.source.coop/vizzuality/lg-land-carbon-data/deforest_carbon_100m_cog.tif", palette="reds", name="deforested", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
43
- # -
 
 
 
44
 
45
 
46
- polygon_ex ='{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-124.628906,34.741612],[-124.628906,42.423457],[-117.246094,42.423457],[-117.246094,34.741612],[-124.628906,34.741612]]]}}'
47
- code_ex = '''
48
- m.add_gdf(geo, layer_name="selection")
49
- '''
50
 
 
51
 
52
  ## Map controls sidebar
53
  with st.sidebar:
54
- '''
55
- # Map controls
56
-
57
- ### Polygon selector
58
- '''
59
-
60
- polygon = st.text_area(
61
- label = "geometry",
62
- value = polygon_ex,
63
- height = 400)
 
 
 
 
64
 
65
  "### python code for map layer:"
66
  "adjust options or add additional layers using leafmap"
@@ -69,66 +94,71 @@ with st.sidebar:
69
  value = code_ex,
70
  height = 400)
71
 
 
 
 
 
 
72
 
 
73
  # Here we actually compute the total carbon in the requested polygon
74
- geo = gpd.read_file(polygon, driver='GeoJSON')
75
- geo.set_crs('epsg:4326')
76
- x = (rioxarray.
77
- open_rasterio('/vsicurl/'+deforest, masked=True).
78
- rio.clip(geo.geometry.values, geo.crs, from_disk=True).
79
- sum()
80
- )
81
- value = float(x)
82
 
 
83
 
84
- "### Tons of carbon lost:"
85
- st.write(f'{value:,}')
86
- st.divider()
87
 
88
- # run whatever python code is in the python box, just for fun
89
- eval(compile(code, "<string>", "exec"))
90
- m.to_streamlit(height=700)
91
 
92
  "## Explore further"
93
- st.write('''
94
- Try adding additional options to the map. Some suggested examples are shown below.
95
- (Of course any self-respecting streamlit app would make these into toggle buttons,
96
- but this is a demo and it's fun & flexible to be able to execute arbitrary code).
97
 
98
- To explore further, simply modify the Streamlit app.py file from the Files menu up top!
99
- '''
100
- )
101
-
102
- st.code('''
103
- # irrecoverable carbon (Conservation International):
104
- carbon = "https://data.source.coop/cboettig/carbon/cogs/irrecoverable_c_total_2018.tif"
105
- m.add_cog_layer(carbon, palette="reds", name="irrecoverable carbon", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)')
106
-
107
- # Human Impacts, Vizzuality
108
- hi="https://data.source.coop/vizzuality/hfp-100/hfp_2021_100m_v1-2_cog.tif"
109
- m.add_cog_layer(hi, palette="purples", name="human impact", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
110
-
111
- # Fire Polygons, USGS
112
- usgs = "https://data.source.coop/cboettig/fire/usgs-mtbs.pmtiles"
113
- combined_style = {
114
- "version": 8,
115
- "sources": {
116
- "source1": {
117
- "type": "vector",
118
- "url": "pmtiles://" + usgs,
119
- "attribution": "USGS"}},
120
- "layers": [{
121
- "id": "usgs",
122
- "source": "source1",
123
- "source-layer": "mtbs_perims_DD",
124
- "type": "fill",
125
- "paint": {"fill-color": "#FFA500", "fill-opacity": 0.2}}]}
126
-
127
- m.add_pmtiles(usgs, name="Fire", style=combined_style, overlay=True, show=True, zoom_to_layer=False)
128
- ''')
 
 
 
 
 
 
 
 
129
 
130
 
131
- # +
132
  st.divider()
133
 
134
  '''
@@ -137,9 +167,13 @@ st.divider()
137
  ### Data sources
138
 
139
  - Carbon-loss by Vizzuality, on https://beta.source.coop/repositories/vizzuality/lg-land-carbon-data. citation: https://doi.org/10.1101/2023.11.01.565036, License: CC-BY
140
- - 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
141
- - Fire polygons by USGS, reprocessed to PMTiles on https://beta.source.coop/cboettig/fire/, License: Public Domain.
142
  - Irrecoverable Carbon from Conservation International, reprocessed to COG on https://beta.source.coop/cboettig/carbon, citation: https://doi.org/10.1038/s41893-021-00803-6, License: CC-BY-NC
 
 
 
 
 
 
 
143
 
144
- Software stack: Streamlit (python) app hosted on free-tier HuggingFace spaces. Mapping with Leafmap.
145
  '''
 
19
  import ibis
20
  from ibis import _
21
  import ibis.selectors as s
22
+ from streamlit_folium import st_folium
23
+ import json
24
+
25
+ def extract_geom(gdf, cog):
26
+ x = (rioxarray.
27
+ open_rasterio('/vsicurl/'+cog, masked=True).
28
+ rio.clip(gdf.geometry.values, gdf.crs, from_disk=True)
29
+ )
30
+ return x
31
+
32
+ def read_polygon(polygon):
33
+ geojson_str = json.dumps(polygon)
34
+ gdf = gpd.read_file(geojson_str, driver='GeoJSON')
35
+ gdf.set_crs('epsg:4326')
36
+ return gdf
37
+
38
+ def area_hectares(gdf):
39
+ area = gdf.to_crs("EPSG:3857").area / 10000.
40
+ return area
41
 
42
 
43
  # +
44
  st.set_page_config(layout="wide", page_title="Leafmap Explorer", page_icon="⚡")
45
 
46
+ st.title("Demo Carbon Calculator")
 
47
 
48
+ DESCRIPTION='''
49
+ 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.
50
+ (use esc key to exit drawing mode). Map will display the tons of carbon lost between 2002 - 2022 below.
 
51
  Data comes from Vizzuality repo on [source.coop](https://beta.source.coop/repositories/vizzuality/lg-land-carbon-data/description/).
52
  '''
53
 
54
+ code_ex = ""
55
+
56
  deforest = "https://data.source.coop/vizzuality/lg-land-carbon-data/deforest_carbon_100m_cog.tif"
57
+ # measured in Mg / Hct (tons)
58
  irrecoverable = "https://data.source.coop/cboettig/carbon/cogs/irrecoverable_c_total_2018.tif"
59
  vulnerable = "https://data.source.coop/cboettig/carbon/cogs/vulnerable_c_total_2018.tif"
60
+ manageable = "https://data.source.coop/cboettig/carbon/cogs/manageable_c_total_2018.tif"
61
 
62
+ #rsr = "https://data.source.coop/cboettig/mobi/range-size-rarity-all/RSR_All.tif"
63
+ #richness = "https://data.source.coop/cboettig/mobi/species-richness-all/SpeciesRichness_All.tif"
64
+
65
+ # Use signed data layers
66
+ #rsr = "https://data.source.coop/cboettig/mobi/range-size-rarity-all/RSR_All.tif"
67
+ #richness = "https://data.source.coop/cboettig/mobi/species-richness-all/SpeciesRichness_All.tif"
68
 
69
 
 
 
 
 
70
 
71
+ m = leafmap.Map(center=[35, -100], zoom=2)
72
 
73
  ## Map controls sidebar
74
  with st.sidebar:
75
+ st.markdown(DESCRIPTION)
76
+
77
+ cog_layers = {
78
+ "Carbon Lost, 2002-2022": deforest,
79
+ "Vulnerable Carbon (2018)": vulnerable,
80
+ "Manageable Carbon (2018)": manageable,
81
+ "Irrecoverable Carbon (2018)": irrecoverable
82
+ }
83
+
84
+ selection = st.radio("Data", cog_layers)
85
+ cog = cog_layers[selection]
86
+ m.add_cog_layer(cog, palette="reds", name=selection,
87
+ transparent_bg=True, opacity = 0.8,
88
+ zoom_to_layer=False)
89
 
90
  "### python code for map layer:"
91
  "adjust options or add additional layers using leafmap"
 
94
  value = code_ex,
95
  height = 400)
96
 
97
+ # run whatever python code is in the python box, just for fun
98
+ eval(compile(code, "<string>", "exec"))
99
+ st_data = m.to_streamlit(height=400, bidirectional=True)
100
+
101
+ units="Tonnes"
102
 
103
+ polygon = st_data["last_active_drawing"]
104
  # Here we actually compute the total carbon in the requested polygon
105
+ if polygon is not None:
106
+ gdf = read_polygon(polygon)
107
+ x = extract_geom(gdf, cog)
108
+ value = float(x.sum())
109
+ if(selection in ["Vulnerable Carbon (2018)",
110
+ "Manageable Carbon (2018)",
111
+ "Irrecoverable Carbon (2018)"]):
112
+ value = value * 9 # 300m pixels, each pixel is 9 hectres
113
 
114
+ st.metric(label=f"{selection}", value=f"{value:,} {units}")
115
 
 
 
 
116
 
117
+ st.divider()
 
 
118
 
119
  "## Explore further"
 
 
 
 
120
 
121
+ with st.expander("code examples"):
122
+ st.write('''
123
+ Try adding additional options to the map. Some suggested examples are shown below.
124
+ (Of course any self-respecting streamlit app would make these into toggle buttons,
125
+ but this is a demo and it's fun & flexible to be able to execute arbitrary code).
126
+
127
+ To explore further, simply modify the Streamlit app.py file from the Files menu up top!
128
+ '''
129
+ )
130
+
131
+ st.code('''
132
+ # irrecoverable carbon (Conservation International):
133
+ carbon = "https://data.source.coop/cboettig/carbon/cogs/irrecoverable_c_total_2018.tif"
134
+ m.add_cog_layer(carbon, palette="reds", name="irrecoverable carbon",
135
+ transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
136
+
137
+ # Human Impacts, Vizzuality
138
+ hi="https://data.source.coop/vizzuality/hfp-100/hfp_2021_100m_v1-2_cog.tif"
139
+ m.add_cog_layer(hi, palette="purples", name="human impact",
140
+ transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
141
+
142
+ # Fire Polygons, USGS
143
+ usgs = "https://data.source.coop/cboettig/fire/usgs-mtbs.pmtiles"
144
+ combined_style = {
145
+ "version": 8,
146
+ "sources": {
147
+ "source1": {
148
+ "type": "vector",
149
+ "url": "pmtiles://" + usgs,
150
+ "attribution": "USGS"}},
151
+ "layers": [{
152
+ "id": "usgs",
153
+ "source": "source1",
154
+ "source-layer": "mtbs_perims_DD",
155
+ "type": "fill",
156
+ "paint": {"fill-color": "#FFA500", "fill-opacity": 0.2}}]}
157
+
158
+ m.add_pmtiles(usgs, name="Fire", style=combined_style, overlay=True, show=True, zoom_to_layer=False)
159
+ ''')
160
 
161
 
 
162
  st.divider()
163
 
164
  '''
 
167
  ### Data sources
168
 
169
  - Carbon-loss by Vizzuality, on https://beta.source.coop/repositories/vizzuality/lg-land-carbon-data. citation: https://doi.org/10.1101/2023.11.01.565036, License: CC-BY
 
 
170
  - Irrecoverable Carbon from Conservation International, reprocessed to COG on https://beta.source.coop/cboettig/carbon, citation: https://doi.org/10.1038/s41893-021-00803-6, License: CC-BY-NC
171
+ - Fire polygons by USGS, reprocessed to PMTiles on https://beta.source.coop/cboettig/fire/, License: Public Domain.
172
+
173
+ ### Software stack
174
+
175
+ - Streamlit (python) app hosted on free-tier HuggingFace spaces ([source code](https://huggingface.co/spaces/boettiger-lab/leafmap/blob/main/app.py)).
176
+ - Cloud-optimized geotifs hosted on [Source.Coop](https://source.coop)
177
+ - Mapping with Leafmap, calculations with rasterio
178
 
 
179
  '''
requirements.txt CHANGED
@@ -7,3 +7,4 @@ ibis-framework[duckdb]
7
  altair
8
  rioxarray
9
  geopandas
 
 
7
  altair
8
  rioxarray
9
  geopandas
10
+ streamlit-folium