cboettig commited on
Commit
266b108
·
1 Parent(s): bfc9dae
Files changed (2) hide show
  1. app.py +86 -41
  2. requirements.txt +1 -1
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import streamlit as st
 
2
  import pandas as pd
3
  import pydeck as pdk
4
  import numpy as np
@@ -7,13 +8,16 @@ from matplotlib import cm
7
  from PIL import Image
8
  import ibis
9
  from ibis import _
 
10
 
11
- con = ibis.duckdb.connect(extensions=["spatial"])
 
12
  con.raw_sql('''
13
  INSTALL h3 FROM community;
14
  LOAD h3;
15
  ''')
16
 
 
17
  @ibis.udf.scalar.builtin
18
  def h3_latlng_to_cell(lat: float, lng: float, zoom: int) -> int:
19
  ...
@@ -32,17 +36,25 @@ st.set_page_config(page_title="GBIF Observations Explorer", page_icon=image, lay
32
  st.header("GBIF Observations Explorer", divider="rainbow")
33
  # st.set_page_config(page_title="H3 in Streamlit", layout="wide")
34
 
35
- h3_parquet = "https://data.source.coop/cboettig/gbif/gbif_us_h3.parquet"
36
-
37
-
38
- con = ibis.duckdb.connect(extensions=["spatial", "h3"])
 
 
 
39
  gbif_h3 = con.read_parquet(h3_parquet)
40
 
 
 
 
 
 
41
  # ------ Visualisation 1 ---------
42
 
43
 
44
  # @st.cache_resource(ttl="2d")
45
- def filter_gbif(_df, species="Canis lupus", bbox = [-130., 0., -90., 40.]):
46
  return (_df
47
  .filter(_.decimallongitude >= bbox[0],
48
  _.decimallongitude < bbox[2],
@@ -59,7 +71,7 @@ def get_h3point_df(_df, resolution: float) -> pd.DataFrame:
59
  .rename(hex = column)
60
  .group_by(_.hex)
61
  .agg(n = _.count())
62
- .mutate(wkt = h3_cell_to_boundary_wkt(_.hex))
63
  .mutate(v = _.n.log())
64
  .mutate(normalized_values = _.v / _.v.max())
65
  .to_pandas()
@@ -67,31 +79,74 @@ def get_h3point_df(_df, resolution: float) -> pd.DataFrame:
67
  rgb = cm.viridis(df.normalized_values)
68
  rgb_array = np.round( rgb * 255 ).astype(int).clip(0,255).tolist()
69
  df['rgb'] = rgb_array
70
- #df['viridis_hex'] = colors.to_hex(rgb)
71
  df['viridis_hex'] = [f"#{int(c[0] * 255):02x}{int(c[1] * 255):02x}{int(c[2] * 255):02x}" for c in rgb]
72
  return df
73
 
 
 
 
 
 
 
 
74
 
75
- def get_coverage_layer(df: pd.DataFrame, v_scale = 0) -> pdk.Layer:
76
- return pdk.Layer(
77
- "H3HexagonLayer",
78
- df,
79
- get_hexagon="hex",
80
- filled=True,
81
- auto_highlight=True,
82
- get_fill_color="rgb",
83
- get_elevation="normalized_values",
84
- elevation_scale=5000 * 10 ** v_scale,
85
- elevation_range=[0,1],
86
- pickable=True,
87
- extruded=True,
88
- line_width_min_pixels=1,
89
- )
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  col1, col2, col3 = st.columns(3)
93
  with col1:
94
- h3_resolut_1 = st.slider("H3 resolution", min_value=0, max_value=12, value=5)
95
  v_scale = st.slider("vertical scale", min_value=-1, max_value=3, value=1)
96
 
97
  with col2:
@@ -99,13 +154,13 @@ with col2:
99
  "Select longitude range",
100
  min_value=-130.0,
101
  max_value=-65.0,
102
- value=(-120.0, -115.0), # Default selected range
103
  step=0.1)
104
  min_lat, max_lat = st.slider(
105
  "Select latitude range",
106
- min_value=0.0,
107
- max_value=50.0,
108
- value=(36., 39.0), # Default selected range
109
  step=0.1)
110
 
111
  with col3:
@@ -115,22 +170,12 @@ bbox = [min_lng, min_lat, max_lng, max_lat]
115
  center_lat = (bbox[1] + bbox[3]) / 2
116
  center_lng = (bbox[0] + bbox[2]) / 2
117
 
 
118
  df = filter_gbif(gbif_h3, species, bbox)
119
  df = get_h3point_df(df, h3_resolut_1)
120
- layer_coverage_1 = get_coverage_layer(df, v_scale)
121
- visible_layers_coverage_1 = [layer_coverage_1]
122
-
123
- st.pydeck_chart(
124
- pdk.Deck(map_provider='carto',
125
- map_style='light',
126
- initial_view_state=pdk.ViewState(
127
- latitude=center_lat, longitude=center_lng, zoom=h3_resolut_1, height=600
128
- ),
129
- tooltip={"html": "<b>Count:</b> {n}", "style": {"color": "white"}},
130
- layers=visible_layers_coverage_1,
131
- )
132
- )
133
 
 
134
 
 
135
 
136
 
 
1
  import streamlit as st
2
+ import leafmap.maplibregl as leafmap
3
  import pandas as pd
4
  import pydeck as pdk
5
  import numpy as np
 
8
  from PIL import Image
9
  import ibis
10
  from ibis import _
11
+ from huggingface_hub import HfApi, login
12
 
13
+
14
+ con = ibis.duckdb.connect(extensions=["spatial", "httpfs"])
15
  con.raw_sql('''
16
  INSTALL h3 FROM community;
17
  LOAD h3;
18
  ''')
19
 
20
+
21
  @ibis.udf.scalar.builtin
22
  def h3_latlng_to_cell(lat: float, lng: float, zoom: int) -> int:
23
  ...
 
36
  st.header("GBIF Observations Explorer", divider="rainbow")
37
  # st.set_page_config(page_title="H3 in Streamlit", layout="wide")
38
 
39
+ # h3_parquet = "https://data.source.coop/cboettig/gbif/gbif_us_h3.parquet"
40
+ # h3_parquet = "/home/rstudio/source.coop/cboettig/gbif/gbif_us_h3.parquet"
41
+ # h3_parquet = "hf://datasets/boettiger-lab/gbif/usa_h3/*/*.parquet"
42
+ # h3_parquet = "hf://datasets/boettiger-lab/gbif/gbif_ca_h3.parquet"
43
+ h3_parquet = "https://data.source.coop/cboettig/gbif/gbif_ca.geoparquet"
44
+ #h3_parquet = "https://huggingface.co/datasets/boettiger-lab/gbif/resolve/main/gbif_ca.geoparquet"
45
+ #h3_parquet = "gbif_ca.geoparquet"
46
  gbif_h3 = con.read_parquet(h3_parquet)
47
 
48
+ # +
49
+ # ibis doesn't know that duckdb can access hf://
50
+ #con.raw_sql(f"CREATE OR REPLACE VIEW gbif AS SELECT * FROM read_parquet('{h3_parquet}')")
51
+ #gbif_h3 = con.table("gbif")
52
+ # -
53
  # ------ Visualisation 1 ---------
54
 
55
 
56
  # @st.cache_resource(ttl="2d")
57
+ def filter_gbif(_df, species="Canis lupus", bbox = [-130., 30., -90., 60.]):
58
  return (_df
59
  .filter(_.decimallongitude >= bbox[0],
60
  _.decimallongitude < bbox[2],
 
71
  .rename(hex = column)
72
  .group_by(_.hex)
73
  .agg(n = _.count())
74
+ # .mutate(wkt = h3_cell_to_boundary_wkt(_.hex))
75
  .mutate(v = _.n.log())
76
  .mutate(normalized_values = _.v / _.v.max())
77
  .to_pandas()
 
79
  rgb = cm.viridis(df.normalized_values)
80
  rgb_array = np.round( rgb * 255 ).astype(int).clip(0,255).tolist()
81
  df['rgb'] = rgb_array
82
+ #df['viridis_hex'] = colors.to_hex(rgb) # not robust?
83
  df['viridis_hex'] = [f"#{int(c[0] * 255):02x}{int(c[1] * 255):02x}{int(c[2] * 255):02x}" for c in rgb]
84
  return df
85
 
86
+ # +
87
+ # #%%time
88
+ #df = filter_gbif(gbif_h3, species = "Canis lupus")
89
+ #df = get_h3point_df(df, 6)
90
+ #df.head(10)
91
+
92
+ # +
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
+ def host_df(df, filename = "live.json", repo_id="boettiger-lab/gbif"):
96
+ df.to_json(".static/"+filename, orient='records', indent=2)
97
+ from huggingface_hub import HfApi, login
98
+ api = HfApi()
99
+ info = api.upload_file(
100
+ path_or_fileobj=".static/"+filename,
101
+ path_in_repo="live/" + filename,
102
+ repo_id=repo_id,
103
+ repo_type="dataset",
104
+ )
105
+ commit_hash = info.oid
106
+ return f"https://huggingface.co/datasets/{repo_id}/resolve/{commit_hash}/live/{filename}"
107
+
108
+ #from minio import Minio
109
+ #key = st.secrets["MINIO_KEY"]
110
+ #secret = st.secrets["MINIO_SECRET"]
111
+ #client = Minio("minio.carlboettiger.info", key, secret)
112
+ #client.fput_object("public-biodiversity", name, name)
113
+ return info
114
+
115
+ def hex_layer(m, df: pd.DataFrame, v_scale = 1):
116
+ url = host_df(df)
117
+
118
+ deck_grid_layer = {
119
+ "@@type": "H3HexagonLayer",
120
+ "id": "my-layer",
121
+ "data": url,
122
+ "getHexagon": "@@=hex",
123
+ "getFillColor": "@@=rgb",
124
+ "getElevation": "@@=normalized_values",
125
+ "elevationScale": 5000 * 10 ** v_scale,
126
+ "elevationRange": [0,1],
127
+ }
128
+ return m.add_deck_layers([deck_grid_layer])
129
+
130
+
131
+ # +
132
+ # #%%time
133
+ def local_test():
134
+ bbox = [-120, 37, -118, 39]
135
+ df = filter_gbif(gbif_h3, species = "Canis lupus", bbox = bbox)
136
+ df = get_h3point_df(df, 6)
137
+ m = leafmap.Map(style="positron", center=(-121.4, 37.74), zoom=7,)
138
+ hex_layer(m, df)
139
+ return m
140
+
141
+
142
+ #local_test()
143
+ # -
144
+
145
+ m = leafmap.Map(style="positron", center=(-121.4, 37.74), zoom=7,)
146
 
147
  col1, col2, col3 = st.columns(3)
148
  with col1:
149
+ h3_resolut_1 = st.slider("H3 resolution", min_value=2, max_value=11, value=5)
150
  v_scale = st.slider("vertical scale", min_value=-1, max_value=3, value=1)
151
 
152
  with col2:
 
154
  "Select longitude range",
155
  min_value=-130.0,
156
  max_value=-65.0,
157
+ value=(-128.0, -115.0), # Default selected range
158
  step=0.1)
159
  min_lat, max_lat = st.slider(
160
  "Select latitude range",
161
+ min_value=20.0,
162
+ max_value=70.0,
163
+ value=(30.0, 42.0), # Default selected range
164
  step=0.1)
165
 
166
  with col3:
 
170
  center_lat = (bbox[1] + bbox[3]) / 2
171
  center_lng = (bbox[0] + bbox[2]) / 2
172
 
173
+ # +
174
  df = filter_gbif(gbif_h3, species, bbox)
175
  df = get_h3point_df(df, h3_resolut_1)
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
+ hex_layer(m, df)
178
 
179
+ m.to_streamlit()
180
 
181
 
requirements.txt CHANGED
@@ -9,4 +9,4 @@ referencing==0.35.1
9
  rasterio==1.3.10
10
  shapely==2.0.4
11
  shiny==0.10.2
12
- requests
 
9
  rasterio==1.3.10
10
  shapely==2.0.4
11
  shiny==0.10.2
12
+ huggingface_hub