cboettig commited on
Commit
d827042
·
1 Parent(s): e436758
Files changed (2) hide show
  1. app.py +217 -165
  2. chatmap.py +2 -1
app.py CHANGED
@@ -27,9 +27,9 @@ public_color = "#3388ff" # blue
27
 
28
  low = 2
29
  high = 3
 
30
 
31
  # +
32
-
33
  st.set_page_config(layout="wide", page_title="Protected Areas Explorer", page_icon=":globe:")
34
 
35
  '''
@@ -51,205 +51,257 @@ Alternative color rules can be applied, for instance, to distinguish between eas
51
  charts summarize the total protected area and mean richness and mean RSR within each group.
52
 
53
  '''
 
54
 
55
- # +
56
- ## Map controls sidebar
57
-
58
- sample_style = '''{
59
- "fill-color": "blue",
60
- "fill-opacity": 0.5
61
- }
62
- '''
63
-
64
- with st.sidebar:
65
-
66
- "## Map controls"
67
-
68
- style_choice = st.radio(
69
- "Color areas by",
70
- ["management type",
71
- "Fee/Easement",
72
- "species richness (thresholds)",
73
- "species richness (continuous)",
74
- "custom"]
75
- )
76
-
77
- "### Management Types Color selector"
78
-
79
- public_color = st.color_picker('Color for Public Protected (Gap 1 & 2) lands', public_color)
80
- mixed_color = st.color_picker('Color for Public Mixed Use lands', mixed_color)
81
- tribal_color = st.color_picker('Color for Tribal managed lands', tribal_color)
82
- private_color = st.color_picker('Color for privately managed land', private_color)
83
-
84
- "### Threshold selector"
85
-
86
- low = st.slider("Red when richness is less than", 0, 30, low)
87
- high = st.slider("Green for richness larger than", 0, 30, high)
88
- "missing data in grey. in-between values in blue"
89
-
90
-
91
- "### Custom styles"
92
- custom = st.text_area(
93
- label = "Define a custom mapbox fill-color rule",
94
- value = sample_style,
95
- height = 100)
96
-
97
-
98
 
99
  # +
 
 
100
 
101
- bucket = {
102
- "fill-color":
103
- ['case',
104
- ['==', ['get', 'bucket'], 'public'],
105
- public_color,
106
- ['==', ['get', 'bucket'], 'private'],
107
- private_color,
108
- ['==', ['get', 'bucket'], 'tribal'],
109
- tribal_color,
110
- mixed_color # default (bucket == mixed)
111
- ],
112
- "fill-opacity": 0.5
113
- }
114
-
115
 
116
- easement = {
117
- "fill-color":
118
- ['case',
119
- ['==', ['get', 'FeatClass'], 'Fee'],
120
- public_color,
121
- ['==', ['get', 'FeatClass'], 'Easement'],
122
- private_color,
123
- ['==', ['get', 'FeatClass'], 'Proclamation'],
124
- tribal_color,
125
- mixed_color # default (bucket == mixed)
126
- ],
127
- "fill-opacity": 0.5
128
- }
129
-
130
-
131
- thresholds = {
132
- "fill-color":
133
- ['case',
134
- ['<', ['get', 'richness'], low],
135
- private_color,
136
- ['>=', ['get', 'richness'], high],
137
- mixed_color,
138
- public_color # default
139
- ],
140
- "fill-opacity": 0.5
141
- }
142
-
143
-
144
- richness = {
145
- "fill-color": [
146
- "interpolate",
147
- ["linear"],
148
- ["get", "richness"],
149
- 0,
150
- # ["min", ["number", ["get", "richness"]]],
151
- "rgb(252, 226, 220)",
152
- #["max", ["get", "richness"]],
153
- 6,
154
- "rgb(102, 16, 66)"
155
- ],
156
- "fill-opacity": 0.9
157
- }
158
-
159
- rsr = {
160
- "fill-color": [
161
- "interpolate",
162
- ["linear"],
163
- ["get", "rsr"],
164
- 0,
165
- # ["min", ["number", ["get", "richness"]]],
166
- "rgb(252, 226, 220)",
167
- #["max", ["get", "richness"]],
168
- 6,
169
- "rgb(102, 16, 66)"
170
- ],
171
- "fill-opacity": 0.9
172
- }
173
 
174
 
175
  # +
176
- if style_choice == "management type":
177
- paint_fill = bucket
178
- if style_choice == "Fee/Easement":
179
- paint_fill = easement
180
- if style_choice == "species richness (thresholds)":
181
- paint_fill = thresholds
182
- if style_choice == "species richness (continuous)":
183
- paint_fill = richness
184
- if style_choice == "custom":
185
- paint_fill = eval(custom)
186
-
187
-
188
- r = {
189
- "fill-color": [
190
- "rgb",
191
- # red is higher when richness is higher
192
- ["get", "richness"],
193
- # green is always zero
194
- 0,
195
- # blue is higher when richness is lower
196
- ["-", 100, ["get", "richness"]]],
197
- "fill-opacity": 0.8
198
- }
199
 
 
200
 
 
 
201
 
202
  # +
203
- import leafmap.foliumap as leafmap
 
 
204
 
205
- url = "https://data.source.coop/cboettig/pad-us-3/pad-mobi.pmtiles"
206
 
207
- style = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  "version": 8,
209
  "sources": {
210
  "pad": {
211
  "type": "vector",
212
- "url": "pmtiles://" + url,
213
  "attribution": "US PAD v3"}},
214
  "layers": [{
215
  "id": "public",
216
  "source": "pad",
217
  "source-layer": "pad-mobi",
218
  "type": "fill",
219
- "paint": paint_fill
 
 
 
220
  }]}
221
- m = leafmap.Map(center=[35, -100],
222
- zoom=4,
223
- layers_control=True,
224
- draw_control=False,
225
- measure_control=False,
226
- fullscreen_control=True)
227
- #m.add_basemap("CartoDB.DarkMatter")
228
-
229
- m.add_basemap("Esri.WorldShadedRelief")
230
-
231
- m.add_tile_layer(
232
- url="https://minio.carlboettiger.info/shared-data/mobi-tiles/red/{z}/{x}/{y}.png",
233
- name="MOBI Species Richness",
234
- attribution="NatureServe",
235
- opacity=0.9
236
- )
237
 
238
 
239
- m.add_pmtiles(url, name="Protected Areas (PAD-US-3)", style=style, overlay=True, show=True, zoom_to_layer=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
 
242
- m.to_streamlit(height=900)
243
 
244
  # -
245
 
246
 
247
 
 
 
 
248
  # +
249
- #parquet = "https://data.source.coop/cboettig/pad-us-3/pad-mobi.parquet"
250
- parquet = "https://minio.carlboettiger.info/public-biodiversity/pad-us-3/pad-mobi.parquet"
251
 
252
- pad_data = ibis.read_parquet(parquet)
 
 
 
 
 
 
 
 
 
 
253
 
254
 
255
  # +
@@ -331,7 +383,7 @@ with col2:
331
 
332
 
333
  with col3:
334
- "#### Mean Range-Size Rarirty"
335
  st.altair_chart(rsr_chart, use_container_width=True)
336
 
337
  # +
 
27
 
28
  low = 2
29
  high = 3
30
+ alpha = .5
31
 
32
  # +
 
33
  st.set_page_config(layout="wide", page_title="Protected Areas Explorer", page_icon=":globe:")
34
 
35
  '''
 
51
  charts summarize the total protected area and mean richness and mean RSR within each group.
52
 
53
  '''
54
+ # -
55
 
56
+ pad_pmtiles = "https://data.source.coop/cboettig/pad-us-3/pad-mobi.pmtiles"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  # +
59
+ #parquet = "https://data.source.coop/cboettig/pad-us-3/pad-mobi.parquet"
60
+ parquet = "https://minio.carlboettiger.info/public-biodiversity/pad-us-3/pad-mobi.parquet"
61
 
62
+ @st.cache_resource
63
+ def ibis_connection(parquet):
64
+ return ibis.read_parquet(parquet)
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ pad_data = ibis_connection(parquet)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
 
69
  # +
70
+ @st.cache_data
71
+ def pad_stats(_pad_data):
72
+ return (_pad_data
73
+ .aggregate(min_richness = _.richness.min(),
74
+ max_richness = _.richness.max(),
75
+ mean_richness = _.richness.mean(),
76
+ sd_richness = _.richness.std(),
77
+ min_rsr = _.rsr.min(),
78
+ max_rsr = _.rsr.max(),
79
+ mean_rsr = _.rsr.mean(),
80
+ sd_rsr = _.rsr.std())
81
+ .to_pandas()
82
+ )
83
+
84
+ stats = pad_stats(pad_data)
85
+ upper_rsr = stats["mean_rsr"][0] + stats["sd_rsr"][0]
86
+ upper_richness = stats["mean_richness"][0] + stats["sd_richness"][0]
87
+ # -
 
 
 
 
 
88
 
89
+ m = leafmap.Map(center=[35, -100], zoom=4, layers_control=True, fullscreen_control=True)
90
 
91
+ metadata = leafmap.pmtiles_metadata(pad_pmtiles)
92
+ #print(f"layer names: {metadata['layer_names']}")
93
 
94
  # +
95
+ custom_style = '''
96
+ "blue"
97
+ '''
98
 
 
99
 
100
+ manager = {
101
+ 'property': 'bucket',
102
+ 'type': 'categorical',
103
+ 'stops': [
104
+ ['public', public_color],
105
+ ['private', private_color],
106
+ ['mixed', mixed_color],
107
+ ['tribal', tribal_color]
108
+ ]
109
+ }
110
+ easement = {
111
+ 'property': 'FeatClass',
112
+ 'type': 'categorical',
113
+ 'stops': [
114
+ ['Fee', public_color],
115
+ ['Easement', private_color],
116
+ ['Proclamation', tribal_color]
117
+ ]
118
+ }
119
+
120
+ gap = {
121
+ 'property': 'GAP_Sts',
122
+ 'type': 'categorical',
123
+ 'stops': [
124
+ ['1', "#26633d"],
125
+ ['2', "#879647"],
126
+ ['3', "#BBBBBB"],
127
+ ['4', "#00000000"]
128
+ ]
129
+ }
130
+
131
+ IUCN = {
132
+ 'property': 'IUCN_Cat',
133
+ 'type': 'categorical',
134
+ 'stops': [
135
+ ["Ia", "#4B0082"],
136
+ ["Ib", "#663399"],
137
+ ["II", "#7B68EE"],
138
+ ["III", "#9370DB"],
139
+ ["IV", "#8A2BE2"],
140
+ ["V", "#9932CC"],
141
+ ["VI", "#9400D3"],
142
+ ["Other Conservation Area", "#DDA0DD"],
143
+ ["Unassigned", "#00000000"]
144
+ ]
145
+ }
146
+
147
+
148
+
149
+
150
+ thresholds = ['case',
151
+ ['<', ['get', 'richness'], low],
152
+ private_color,
153
+ ['>=', ['get', 'richness'], high],
154
+ mixed_color,
155
+ public_color # default
156
+ ]
157
+
158
+ richness = ["interpolate",
159
+ ["linear"],
160
+ ["get", "richness"],
161
+ 0, "#FFE6EE",
162
+ 4.8, "#850101"
163
+ ]
164
+
165
+ rsr = ["interpolate",
166
+ ["linear"],
167
+ ["get", "rsr"],
168
+ 0, "#FFE6EE",
169
+ 0.006, "#850101"
170
+ ]
171
+
172
+
173
+ def pad_style(paint, alpha):
174
+ return {
175
  "version": 8,
176
  "sources": {
177
  "pad": {
178
  "type": "vector",
179
+ "url": "pmtiles://" + pad_pmtiles,
180
  "attribution": "US PAD v3"}},
181
  "layers": [{
182
  "id": "public",
183
  "source": "pad",
184
  "source-layer": "pad-mobi",
185
  "type": "fill",
186
+ "paint": {
187
+ "fill-color": paint,
188
+ "fill-opacity": alpha
189
+ }
190
  }]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
 
193
+
194
+ # +
195
+ ## Map controls sidebar
196
+
197
+ with st.sidebar:
198
+ "## Basemaps"
199
+ if st.toggle("Shaded Relief Topo"):
200
+ m.add_basemap("Esri.WorldShadedRelief")
201
+
202
+
203
+ boundaries = st.radio("Boundaries:",
204
+ ["None",
205
+ "State Boundaries",
206
+ "County Boundaries",
207
+ "Congressional District",
208
+ "custom"]
209
+ )
210
+
211
+ "## Raster layers"
212
+
213
+ if st.toggle("Species Richness"):
214
+ m.add_tile_layer(url="https://data.source.coop/cboettig/mobi/tiles/red/species-richness-all/{z}/{x}/{y}.png",
215
+ name="MOBI Species Richness",
216
+ attribution="NatureServe",
217
+ opacity=0.9
218
+ )
219
+
220
+ if st.toggle("Range-Size Rarity"):
221
+ m.add_tile_layer(url="https://data.source.coop/cboettig/mobi/tiles/green/range-size-rarity-all/{z}/{x}/{y}.png",
222
+ name="MOBI Range-Size Rarity",
223
+ attribution="NatureServe",
224
+ opacity=0.9
225
+ )
226
+ #m.add_cog_layer("https://data.source.coop/cboettig/mobi/range-size-rarity-all/RSR_All.tif",
227
+ # palette="greens", name="Range-Size Rarity", transparent_bg=True, opacity = 0.9, zoom_to_layer=False)
228
+
229
+ if st.toggle("Carbon Lost (2002-2022)"):
230
+ m.add_cog_layer("https://data.source.coop/vizzuality/lg-land-carbon-data/deforest_carbon_100m_cog.tif",
231
+ palette="reds", name="Carbon Lost (2002-2022)", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
232
+
233
+
234
+ if st.toggle("Irrecoverable Carbon"):
235
+ m.add_cog_layer("https://data.source.coop/cboettig/carbon/cogs/irrecoverable_c_total_2018.tif",
236
+ palette="purples", name="Irrecoverable Carbon", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
237
+
238
+ if st.toggle("Managable Carbon"):
239
+ m.add_cog_layer("https://data.source.coop/cboettig/carbon/cogs/managable_c_total_2018.tif",
240
+ palette="greens", name="Managable Carbon", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
241
+
242
+ if st.toggle("Human Impact"):
243
+ hi="https://data.source.coop/vizzuality/hfp-100/hfp_2021_100m_v1-2_cog.tif"
244
+ m.add_cog_layer(hi, palette="purples", name="Human Impact", transparent_bg=True, opacity = 0.8, zoom_to_layer=False)
245
+
246
+ "## Protected Areas"
247
+
248
+ style_dict = {"Manager Type": manager,
249
+ "Fee/Easement": easement,
250
+ "GAP Status Code": gap,
251
+ "IUCN Status Code": IUCN,
252
+ "Mean Richness": richness,
253
+ "Mean RSR": rsr,
254
+ "custom": eval(custom_style)}
255
+
256
+ if st.toggle("PAD US-3", True):
257
+ alpha = st.slider("transparency", 0.0, 1.1, 0.5)
258
+ style_choice = st.radio("Color protected Areas by", style_dict)
259
+
260
+ style=pad_style(style_dict[style_choice], alpha)
261
+ m.add_pmtiles(pad_pmtiles, name="Protected Areas (PAD-US-3)", style=style, overlay=True, show=True, zoom_to_layer=False)
262
+
263
+
264
+
265
+ # Fire Polygons, USGS
266
+ if st.toggle("Fire boundaries"):
267
+ usgs = "https://data.source.coop/cboettig/fire/usgs-mtbs.pmtiles"
268
+ combined_style = {
269
+ "version": 8,
270
+ "sources": {
271
+ "source1": {
272
+ "type": "vector",
273
+ "url": "pmtiles://" + usgs,
274
+ "attribution": "USGS"}},
275
+ "layers": [{
276
+ "id": "usgs",
277
+ "source": "source1",
278
+ "source-layer": "mtbs_perims_DD",
279
+ "type": "fill",
280
+ "paint": {"fill-color": "#FFA500", "fill-opacity": 0.2}}]}
281
+ m.add_pmtiles(usgs, name="Fire", style=combined_style, overlay=True, show=True, zoom_to_layer=False)
282
 
283
 
 
284
 
285
  # -
286
 
287
 
288
 
289
+
290
+
291
+
292
  # +
 
 
293
 
294
+
295
+ # paint_fill
296
+
297
+ # +
298
+
299
+ # m.add_legend(legend_dict=legend_dict)
300
+
301
+ m.to_streamlit(height=900)
302
+ # -
303
+
304
+ st.divider()
305
 
306
 
307
  # +
 
383
 
384
 
385
  with col3:
386
+ "#### Mean Range-Size Rarity"
387
  st.altair_chart(rsr_chart, use_container_width=True)
388
 
389
  # +
chatmap.py CHANGED
@@ -38,4 +38,5 @@ if prompt := st.chat_input("What is up?"):
38
  stream=True,
39
  )
40
  response = st.write_stream(stream)
41
- st.session_state.messages.append({"role": "assistant", "content": response})
 
 
38
  stream=True,
39
  )
40
  response = st.write_stream(stream)
41
+ st.session_state.messages.append({"role": "assistant", "content": response})
42
+