Spaces:
Build error
Build error
pgzmnk
commited on
Commit
•
4c8c6b4
1
Parent(s):
84e5c53
Format.
Browse files- app.py +74 -49
- utils/js.py +1 -1
app.py
CHANGED
@@ -240,8 +240,11 @@ def create_dataframe(years, project_name):
|
|
240 |
dfs.append(df)
|
241 |
return pd.concat(dfs)
|
242 |
|
|
|
243 |
# h/t: https://community.plotly.com/t/dynamic-zoom-for-mapbox/32658/12
|
244 |
-
def get_plotting_zoom_level_and_center_coordinates_from_lonlat_tuples(
|
|
|
|
|
245 |
"""Function documentation:\n
|
246 |
Basic framework adopted from Krichardson under the following thread:
|
247 |
https://community.plotly.com/t/dynamic-zoom-for-mapbox/32658/7
|
@@ -256,19 +259,18 @@ def get_plotting_zoom_level_and_center_coordinates_from_lonlat_tuples(longitudes
|
|
256 |
|
257 |
# Check whether both latitudes and longitudes have been passed,
|
258 |
# or if the list lenghts don't match
|
259 |
-
if (
|
260 |
-
or (len(latitudes) != len(longitudes))):
|
261 |
# Otherwise, return the default values of 0 zoom and the coordinate origin as center point
|
262 |
return 0, (0, 0)
|
263 |
|
264 |
-
# Get the boundary-box
|
265 |
-
b_box = {}
|
266 |
-
b_box[
|
267 |
-
b_box[
|
268 |
-
b_box[
|
269 |
|
270 |
# get the area of the bounding box in order to calculate a zoom-level
|
271 |
-
area = b_box[
|
272 |
|
273 |
# * 1D-linear interpolation with numpy:
|
274 |
# - Pass the area as the only x-value and not as a list, in order to return a scalar as well
|
@@ -276,52 +278,70 @@ def get_plotting_zoom_level_and_center_coordinates_from_lonlat_tuples(longitudes
|
|
276 |
# - The zpom-levels are adapted to the areas, i.e. start with the smallest area possible of 0
|
277 |
# which leads to the highest possible zoom value 20, and so forth decreasing with increasing areas
|
278 |
# as these variables are antiproportional
|
279 |
-
zoom = np.interp(
|
280 |
-
|
281 |
-
|
|
|
|
|
282 |
|
283 |
# Finally, return the zoom level and the associated boundary-box center coordinates
|
284 |
-
return zoom, b_box[
|
|
|
285 |
|
286 |
def show_project_map(project_name):
|
287 |
-
prepared_statement =
|
288 |
-
|
289 |
-
|
290 |
-
features =
|
291 |
-
|
292 |
-
geometry = features[0]['geometry']
|
293 |
longitudes = np.array(geometry["coordinates"])[0, :, 0]
|
294 |
latitudes = np.array(geometry["coordinates"])[0, :, 1]
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
|
301 |
fig.update_layout(
|
302 |
-
mapbox
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
}
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
|
|
|
|
|
|
|
|
|
|
316 |
return fig
|
317 |
|
|
|
318 |
# minMax.getInfo()
|
319 |
def calculate_biodiversity_score(start_year, end_year, project_name):
|
320 |
years = []
|
321 |
for year in range(start_year, end_year):
|
322 |
-
row_exists =
|
323 |
-
|
324 |
-
|
|
|
325 |
if not row_exists:
|
326 |
years.append(year)
|
327 |
|
@@ -338,7 +358,8 @@ def calculate_biodiversity_score(start_year, end_year, project_name):
|
|
338 |
"""
|
339 |
USE climatebase;
|
340 |
CREATE TABLE IF NOT EXISTS bioindicator (year BIGINT, project_name VARCHAR(255), value DOUBLE, area DOUBLE, score DOUBLE, CONSTRAINT unique_year_project_name UNIQUE (year, project_name));
|
341 |
-
"""
|
|
|
342 |
# UPSERT project record
|
343 |
con.sql(
|
344 |
"""
|
@@ -347,14 +368,18 @@ def calculate_biodiversity_score(start_year, end_year, project_name):
|
|
347 |
"""
|
348 |
)
|
349 |
logging.info("upsert records into motherduck")
|
350 |
-
scores =
|
351 |
-
|
352 |
-
|
|
|
353 |
return scores
|
354 |
|
|
|
355 |
def motherduck_list_projects(author_id):
|
356 |
-
return
|
357 |
-
|
|
|
|
|
358 |
|
359 |
|
360 |
with gr.Blocks() as demo:
|
@@ -385,7 +410,7 @@ with gr.Blocks() as demo:
|
|
385 |
fn=show_project_map,
|
386 |
inputs=[project_name],
|
387 |
outputs=[m1],
|
388 |
-
|
389 |
|
390 |
def update_project_dropdown_list(url_params):
|
391 |
username = url_params.get("username", "default")
|
@@ -410,4 +435,4 @@ with gr.Blocks() as demo:
|
|
410 |
queue=False,
|
411 |
)
|
412 |
|
413 |
-
demo.launch()
|
|
|
240 |
dfs.append(df)
|
241 |
return pd.concat(dfs)
|
242 |
|
243 |
+
|
244 |
# h/t: https://community.plotly.com/t/dynamic-zoom-for-mapbox/32658/12
|
245 |
+
def get_plotting_zoom_level_and_center_coordinates_from_lonlat_tuples(
|
246 |
+
longitudes=None, latitudes=None
|
247 |
+
):
|
248 |
"""Function documentation:\n
|
249 |
Basic framework adopted from Krichardson under the following thread:
|
250 |
https://community.plotly.com/t/dynamic-zoom-for-mapbox/32658/7
|
|
|
259 |
|
260 |
# Check whether both latitudes and longitudes have been passed,
|
261 |
# or if the list lenghts don't match
|
262 |
+
if (latitudes is None or longitudes is None) or (len(latitudes) != len(longitudes)):
|
|
|
263 |
# Otherwise, return the default values of 0 zoom and the coordinate origin as center point
|
264 |
return 0, (0, 0)
|
265 |
|
266 |
+
# Get the boundary-box
|
267 |
+
b_box = {}
|
268 |
+
b_box["height"] = latitudes.max() - latitudes.min()
|
269 |
+
b_box["width"] = longitudes.max() - longitudes.min()
|
270 |
+
b_box["center"] = (np.mean(longitudes), np.mean(latitudes))
|
271 |
|
272 |
# get the area of the bounding box in order to calculate a zoom-level
|
273 |
+
area = b_box["height"] * b_box["width"]
|
274 |
|
275 |
# * 1D-linear interpolation with numpy:
|
276 |
# - Pass the area as the only x-value and not as a list, in order to return a scalar as well
|
|
|
278 |
# - The zpom-levels are adapted to the areas, i.e. start with the smallest area possible of 0
|
279 |
# which leads to the highest possible zoom value 20, and so forth decreasing with increasing areas
|
280 |
# as these variables are antiproportional
|
281 |
+
zoom = np.interp(
|
282 |
+
x=area,
|
283 |
+
xp=[0, 5**-10, 4**-10, 3**-10, 2**-10, 1**-10, 1**-5],
|
284 |
+
fp=[20, 15, 14, 13, 12, 7, 5],
|
285 |
+
)
|
286 |
|
287 |
# Finally, return the zoom level and the associated boundary-box center coordinates
|
288 |
+
return zoom, b_box["center"]
|
289 |
+
|
290 |
|
291 |
def show_project_map(project_name):
|
292 |
+
prepared_statement = con.execute(
|
293 |
+
"SELECT geometry FROM project WHERE name = ? LIMIT 1", [project_name]
|
294 |
+
).fetchall()
|
295 |
+
features = json.loads(prepared_statement[0][0].replace("'", '"'))["features"]
|
296 |
+
geometry = features[0]["geometry"]
|
|
|
297 |
longitudes = np.array(geometry["coordinates"])[0, :, 0]
|
298 |
latitudes = np.array(geometry["coordinates"])[0, :, 1]
|
299 |
+
(
|
300 |
+
zoom,
|
301 |
+
bbox_center,
|
302 |
+
) = get_plotting_zoom_level_and_center_coordinates_from_lonlat_tuples(
|
303 |
+
longitudes, latitudes
|
304 |
+
)
|
305 |
+
fig = go.Figure(
|
306 |
+
go.Scattermapbox(
|
307 |
+
mode="markers",
|
308 |
+
lon=[bbox_center[0]],
|
309 |
+
lat=[bbox_center[1]],
|
310 |
+
marker={"size": 20, "color": ["cyan"]},
|
311 |
+
)
|
312 |
+
)
|
313 |
|
314 |
fig.update_layout(
|
315 |
+
mapbox={
|
316 |
+
"style": "stamen-terrain",
|
317 |
+
"center": {"lon": bbox_center[0], "lat": bbox_center[1]},
|
318 |
+
"zoom": zoom,
|
319 |
+
"layers": [
|
320 |
+
{
|
321 |
+
"source": {
|
322 |
+
"type": "FeatureCollection",
|
323 |
+
"features": [{"type": "Feature", "geometry": geometry}],
|
324 |
+
},
|
325 |
+
"type": "fill",
|
326 |
+
"below": "traces",
|
327 |
+
"color": "royalblue",
|
328 |
+
}
|
329 |
+
],
|
330 |
+
},
|
331 |
+
margin={"l": 0, "r": 0, "b": 0, "t": 0},
|
332 |
+
)
|
333 |
+
|
334 |
return fig
|
335 |
|
336 |
+
|
337 |
# minMax.getInfo()
|
338 |
def calculate_biodiversity_score(start_year, end_year, project_name):
|
339 |
years = []
|
340 |
for year in range(start_year, end_year):
|
341 |
+
row_exists = con.execute(
|
342 |
+
"SELECT COUNT(1) FROM bioindicator WHERE (year = ? AND project_name = ?)",
|
343 |
+
[year, project_name],
|
344 |
+
).fetchall()[0][0]
|
345 |
if not row_exists:
|
346 |
years.append(year)
|
347 |
|
|
|
358 |
"""
|
359 |
USE climatebase;
|
360 |
CREATE TABLE IF NOT EXISTS bioindicator (year BIGINT, project_name VARCHAR(255), value DOUBLE, area DOUBLE, score DOUBLE, CONSTRAINT unique_year_project_name UNIQUE (year, project_name));
|
361 |
+
"""
|
362 |
+
)
|
363 |
# UPSERT project record
|
364 |
con.sql(
|
365 |
"""
|
|
|
368 |
"""
|
369 |
)
|
370 |
logging.info("upsert records into motherduck")
|
371 |
+
scores = con.execute(
|
372 |
+
"SELECT * FROM bioindicator WHERE (year >= ? AND year <= ? AND project_name = ?)",
|
373 |
+
[start_year, end_year, project_name],
|
374 |
+
).df()
|
375 |
return scores
|
376 |
|
377 |
+
|
378 |
def motherduck_list_projects(author_id):
|
379 |
+
return con.execute(
|
380 |
+
"SELECT DISTINCT name FROM project WHERE authorId = ? AND geometry != 'null'",
|
381 |
+
[author_id],
|
382 |
+
).df()
|
383 |
|
384 |
|
385 |
with gr.Blocks() as demo:
|
|
|
410 |
fn=show_project_map,
|
411 |
inputs=[project_name],
|
412 |
outputs=[m1],
|
413 |
+
)
|
414 |
|
415 |
def update_project_dropdown_list(url_params):
|
416 |
username = url_params.get("username", "default")
|
|
|
435 |
queue=False,
|
436 |
)
|
437 |
|
438 |
+
demo.launch()
|
utils/js.py
CHANGED
@@ -5,4 +5,4 @@ get_window_url_params = """
|
|
5 |
console.log('url_params', url_params)
|
6 |
return url_params;
|
7 |
}
|
8 |
-
"""
|
|
|
5 |
console.log('url_params', url_params)
|
6 |
return url_params;
|
7 |
}
|
8 |
+
"""
|