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 |
+
"""
|