Huseyin Kaya commited on
Commit
ad72737
·
unverified ·
2 Parent(s): c5ff66adb53611

Merge pull request #15 from o-z-e-r-e-r/branch240107_2

Browse files
Files changed (1) hide show
  1. tomorrowcities/pages/engine.py +52 -62
tomorrowcities/pages/engine.py CHANGED
@@ -27,6 +27,8 @@ from ..backend.engine import compute, compute_power_infra, compute_road_infra, c
27
  from ..backend.utils import building_preprocess, identity_preprocess
28
  from .utilities import S3FileBrowser, extension_list, extension_list_w_dots
29
  from .docs import data_import_help
 
 
30
 
31
  layers = solara.reactive({
32
  'infra': solara.reactive(["building"]),
@@ -476,21 +478,21 @@ def create_map_layer(df, name):
476
  df_limited[im_col] = df_limited[im_col] / df_limited[im_col].max()
477
  #df_limited = df.sort_values(by=im_col,ascending=False).head(500_000)
478
  locs = np.array([df_limited.geometry.y.to_list(), df_limited.geometry.x.to_list(), df_limited[im_col].to_list()]).transpose().tolist()
479
- map_layer = ipyleaflet.Heatmap(locations=locs, radius = 5, blur = 1)
480
  elif name == "landuse":
481
- map_layer = ipyleaflet.GeoJSON(data = json.loads(df.to_json()),
482
  style={'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.5, 'weight': 1},
483
  hover_style={'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5},
484
  style_callback=landuse_colors)
485
  map_layer.on_click(building_click_handler)
486
  elif name == "building":
487
- map_layer = ipyleaflet.GeoJSON(data = json.loads(df.to_json()),
488
  style={'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.5, 'weight': 1},
489
  hover_style={'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5},
490
  style_callback=building_colors)
491
  map_layer.on_click(landuse_click_handler)
492
  elif name == "road edges":
493
- map_layer = ipyleaflet.GeoJSON(data = json.loads(df.to_json()),
494
  hover_style={'color': 'orange'},
495
  style_callback=road_edge_colors)
496
  map_layer.on_click(road_edge_click_handler)
@@ -503,7 +505,7 @@ def create_map_layer(df, name):
503
  (point.x + half_side, point.y + half_side),
504
  (point.x - half_side, point.y + half_side)
505
  ]))
506
- map_layer = ipyleaflet.GeoJSON(data = json.loads(df_squares.to_json()),
507
  style={'opacity': 1, 'dashArray': '0', 'fillOpacity': 0.8, 'weight': 1},
508
  hover_style={'color': 'orange', 'dashArray': '0', 'fillOpacity': 0.5})
509
  map_layer.on_click(road_node_click_handler)
@@ -523,7 +525,7 @@ def create_map_layer(df, name):
523
  ),location=(y,x),title=f'{node["node_id"]}',draggable=False)
524
 
525
  markers.append(marker)
526
- map_layer= ipyleaflet.MarkerCluster(markers=markers,
527
  disable_clustering_at_zoom=5)
528
 
529
  else:
@@ -577,7 +579,6 @@ def read_tiff(file_bytes):
577
  dst_crs=target_crs,
578
  resampling=Resampling.nearest)
579
 
580
-
581
  lon_pos, lat_pos = np.meshgrid(range(width),range(height))
582
  print('start transform ..........')
583
  #lon, lat = rasterio.transform.xy(transform,lat_pos.flatten(),lon_pos.flatten())
@@ -590,7 +591,6 @@ def read_tiff(file_bytes):
590
  return gdf[(gdf.drop(columns='geometry')>0).any(axis=1)]
591
  #return gdf.sort_values(by='im',ascending=False).head(10000)
592
 
593
-
594
  def read_gem_xml(data: [bytes]):
595
  content_as_string = data.decode('utf-8')
596
  content_as_string = content_as_string.replace('\n','')
@@ -611,7 +611,6 @@ def read_gem_xml(data: [bytes]):
611
 
612
  d['description'] = getText(dom.getElementsByTagName('description')[0])
613
 
614
-
615
  d['vulnerabilityFunctions'] = []
616
  for node in dom.getElementsByTagName('vulnerabilityFunction'):
617
  v = dict()
@@ -626,7 +625,6 @@ def read_gem_xml(data: [bytes]):
626
 
627
  return d
628
 
629
-
630
  @solara.component
631
  def VulnerabilityFunctionDisplayer(vuln_func):
632
  vuln_func, _ = solara.use_state_or_update(vuln_func)
@@ -750,13 +748,11 @@ def MetricWidget(name, description, value, max_value, render_count):
750
  "title": {"fontSize": 12},
751
  "data": [{"value": value, "name": name}]}]}
752
  print(f'value/max_value {value}:{max_value}')
753
-
754
 
755
  with solara.Tooltip(description):
756
  with solara.Column():
757
  solara.FigureEcharts(option=options, attributes={ "style": "height: 100px; width: 100px" })
758
 
759
-
760
  def import_data(fileinfo: solara.components.file_drop.FileInfo):
761
  data_array = fileinfo['data']
762
  extension = fileinfo['name'].split('.')[-1]
@@ -782,7 +778,6 @@ def import_data(fileinfo: solara.components.file_drop.FileInfo):
782
  else:
783
  return (None, None)
784
 
785
-
786
  # in the first pass, look for exact column match
787
  name = None
788
  for layer_name, layer in layers.value['layers'].items():
@@ -809,7 +804,6 @@ def import_data(fileinfo: solara.components.file_drop.FileInfo):
809
  data[col] = val
810
  return (name, data)
811
 
812
-
813
  @solara.component
814
  def FileDropZone():
815
  total_progress, set_total_progress = solara.use_state(-1)
@@ -886,17 +880,18 @@ def LayerDisplayer():
886
  data = nonempty_layers[selected]['data'].value
887
  if isinstance(data, gpd.GeoDataFrame) or isinstance(data, pd.DataFrame):
888
  if "geometry" in data.columns:
889
- ((ymin,xmin),(ymax,xmax)) = layers.value['bounds'].value
890
- df_filtered = data.cx[xmin:xmax,ymin:ymax].drop(columns='geometry')
 
891
  #solara.CrossFilterReport(df_filtered, classes=["py-2"])
892
  #solara.CrossFilterSelect(df_filtered, df_filtered.columns[0])
893
  #solara.CrossFilterDataFrame(df=df_filtered)
894
- solara.DataFrame(df_filtered, items_per_page=5)
895
  else:
896
  #solara.CrossFilterReport(data, classes=["py-2"])
897
  #solara.CrossFilterSelect(data, data.columns[0])
898
  #solara.CrossFilterDataFrame(df=data)
899
- solara.DataFrame(data, items_per_page=5)
900
  if selected in ["building","road edges","road nodes","power nodes","power edges"] :
901
  with solara.Row():
902
  file_object = data.to_json()
@@ -904,6 +899,8 @@ def LayerDisplayer():
904
  solara.Button("Download GeoJSON", icon_name="mdi-cloud-download-outline", color="primary")
905
  with solara.FileDownload(data.to_csv(), f"{selected}_export.csv", mime_type="text/csv"):
906
  solara.Button("Download CSV", icon_name="mdi-cloud-download-outline", color="primary")
 
 
907
  if selected == 'gem_vulnerability':
908
  VulnerabiliyDisplayer(data)
909
 
@@ -925,7 +922,6 @@ def MetricPanel():
925
  layers.value['render_count'].value)
926
  with solara.Link("/docs/metrics"):
927
  solara.Button(icon_name="mdi-help-circle-outline", icon=True)
928
-
929
 
930
  @solara.component
931
  def LayerController():
@@ -934,7 +930,6 @@ def LayerController():
934
  if layer['map_layer'].value is not None:
935
  solara.Checkbox(label=layer_name,
936
  value=layer['visible'])
937
-
938
 
939
  @solara.component
940
  def MapViewer():
@@ -944,9 +939,22 @@ def MapViewer():
944
  zoom, set_zoom = solara.use_state(default_zoom)
945
  #center, set_center = solara.use_state(default_center)
946
 
947
- base_map = ipyleaflet.basemaps["OpenStreetMap"]["Mapnik"]
948
- base_layer = ipyleaflet.TileLayer.element(url=base_map.build_url())
949
- map_layers = [base_layer]
 
 
 
 
 
 
 
 
 
 
 
 
 
950
 
951
  render_order = [l['render_order'] for _, l in layers.value['layers'].items()]
952
  for _, (layer_name, layer) in sorted(zip(render_order,layers.value['layers'].items())):
@@ -957,7 +965,6 @@ def MapViewer():
957
  map_layer = create_map_layer(df, layer_name)
958
  if map_layer is not None:
959
  map_layers.append(map_layer)
960
-
961
 
962
  ipyleaflet.Map.element(
963
  zoom=zoom,
@@ -971,7 +978,9 @@ def MapViewer():
971
  touch_zoom=True,
972
  box_zoom=True,
973
  keyboard=True if random.random() > 0.5 else False,
974
- layers=map_layers
 
 
975
  )
976
 
977
  @solara.component
@@ -1029,10 +1038,8 @@ def ExecutePanel():
1029
 
1030
  return True, ''
1031
 
1032
-
1033
  def execute_engine():
1034
 
1035
-
1036
  def execute_road():
1037
  buildings = layers.value['layers']['building']['data'].value
1038
  household = layers.value['layers']['household']['data'].value
@@ -1180,7 +1187,6 @@ def ExecutePanel():
1180
  layers.value['metrics'][metric]['max_value'] = computed_metrics[metric]['max_value']
1181
  return buildings
1182
 
1183
-
1184
  if execute_counter > 0 :
1185
  is_ready, missing = is_ready_to_run(layers.value['infra'].value, layers.value['hazard'].value)
1186
  if not is_ready:
@@ -1238,8 +1244,6 @@ def ExecutePanel():
1238
 
1239
  layers.value['datetime_analysis'] = datetime.datetime.utcnow()
1240
 
1241
-
1242
-
1243
  # Execute the thread only when the depencency is changed
1244
  result = solara.use_thread(execute_engine, dependencies=[execute_counter])
1245
 
@@ -1288,16 +1292,12 @@ def ExecutePanel():
1288
  set_execute_btn_disabled(False)
1289
  solara.ProgressLinear(value=False)
1290
 
1291
-
1292
  @solara.component
1293
  def PolicyPanel():
1294
  all_policies = [f"{p['label']}/{p['description']}" for _, p in layers.value['policies'].items()]
1295
  with solara.Row():
1296
  solara.SelectMultiple("Policies", layers.value['selected_policies'].value, all_policies, on_value=layers.value['selected_policies'].set, dense=False)
1297
 
1298
-
1299
-
1300
-
1301
  @solara.component
1302
  def MapInfo():
1303
  print(f'{layers.value["bounds"].value}')
@@ -1338,7 +1338,6 @@ def MapInfo():
1338
  else:
1339
  solara.Text(f'{value}')
1340
 
1341
-
1342
  @solara.component
1343
  def ImportDataZone():
1344
  def s3_file_open(p):
@@ -1359,7 +1358,6 @@ def ImportDataZone():
1359
  size=len(fileContent),
1360
  data=fileContent)
1361
  set_fileinfo(file_info)
1362
-
1363
 
1364
  total_progress, set_total_progress = solara.use_state(-1)
1365
  fileinfo, set_fileinfo = solara.use_state(None)
@@ -1428,10 +1426,6 @@ def ImportDataZone():
1428
  # solara.FileBrowser(can_select=True, on_file_open=local_file_open,
1429
  # filter=lambda p: True if p.is_dir() or p.suffix in extension_list_w_dots else False)
1430
 
1431
-
1432
-
1433
-
1434
-
1435
  if total_progress > -1 and total_progress < 100:
1436
  solara.Text(f"Uploading {total_progress}%")
1437
  solara.ProgressLinear(value=total_progress)
@@ -1456,30 +1450,28 @@ def ImportDataZone():
1456
  def WebApp():
1457
  if storage.value is None:
1458
  storage.value = revive_storage()
1459
- with solara.Columns([20,70,10]):
1460
- with solara.Column():
1461
  with solara.lab.Tabs():
1462
  with solara.lab.Tab("SETTINGS"):
1463
  ExecutePanel()
1464
  with solara.lab.Tab("DATA IMPORT"):
1465
  ImportDataZone()
1466
-
1467
- with solara.Column():
1468
- LayerController()
1469
- MapViewer()
1470
- with solara.Row(justify="center"):
1471
- MetricPanel()
1472
- LayerDisplayer()
1473
- MapInfo()
1474
- with ConfirmationDialog(
1475
- layers.value['dialog_message_to_be_shown'].value is not None,
1476
- on_close=clear_help_topic,
1477
- ok="Close",
1478
- title="Information Box",
1479
- ):
1480
- solara.Markdown(f'{layers.value["dialog_message_to_be_shown"].value}')
1481
-
1482
-
1483
 
1484
  @solara.component
1485
  def Page(name: Optional[str] = None, page: int = 0, page_size=100):
@@ -1508,6 +1500,4 @@ def Page(name: Optional[str] = None, page: int = 0, page_size=100):
1508
  solara.Style(value=css)
1509
  solara.Title(" ")
1510
 
1511
- WebApp()
1512
-
1513
-
 
27
  from ..backend.utils import building_preprocess, identity_preprocess
28
  from .utilities import S3FileBrowser, extension_list, extension_list_w_dots
29
  from .docs import data_import_help
30
+ import ipywidgets
31
+ import ipydatagrid
32
 
33
  layers = solara.reactive({
34
  'infra': solara.reactive(["building"]),
 
478
  df_limited[im_col] = df_limited[im_col] / df_limited[im_col].max()
479
  #df_limited = df.sort_values(by=im_col,ascending=False).head(500_000)
480
  locs = np.array([df_limited.geometry.y.to_list(), df_limited.geometry.x.to_list(), df_limited[im_col].to_list()]).transpose().tolist()
481
+ map_layer = ipyleaflet.Heatmap(locations=locs, radius = 5, blur = 1, name = name)
482
  elif name == "landuse":
483
+ map_layer = ipyleaflet.GeoJSON(data = json.loads(df.to_json()), name = name,
484
  style={'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.5, 'weight': 1},
485
  hover_style={'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5},
486
  style_callback=landuse_colors)
487
  map_layer.on_click(building_click_handler)
488
  elif name == "building":
489
+ map_layer = ipyleaflet.GeoJSON(data = json.loads(df.to_json()), name = name,
490
  style={'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.5, 'weight': 1},
491
  hover_style={'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5},
492
  style_callback=building_colors)
493
  map_layer.on_click(landuse_click_handler)
494
  elif name == "road edges":
495
+ map_layer = ipyleaflet.GeoJSON(data = json.loads(df.to_json()), name = name,
496
  hover_style={'color': 'orange'},
497
  style_callback=road_edge_colors)
498
  map_layer.on_click(road_edge_click_handler)
 
505
  (point.x + half_side, point.y + half_side),
506
  (point.x - half_side, point.y + half_side)
507
  ]))
508
+ map_layer = ipyleaflet.GeoJSON(data = json.loads(df_squares.to_json()), name = name,
509
  style={'opacity': 1, 'dashArray': '0', 'fillOpacity': 0.8, 'weight': 1},
510
  hover_style={'color': 'orange', 'dashArray': '0', 'fillOpacity': 0.5})
511
  map_layer.on_click(road_node_click_handler)
 
525
  ),location=(y,x),title=f'{node["node_id"]}',draggable=False)
526
 
527
  markers.append(marker)
528
+ map_layer= ipyleaflet.MarkerCluster(markers=markers, name = name,
529
  disable_clustering_at_zoom=5)
530
 
531
  else:
 
579
  dst_crs=target_crs,
580
  resampling=Resampling.nearest)
581
 
 
582
  lon_pos, lat_pos = np.meshgrid(range(width),range(height))
583
  print('start transform ..........')
584
  #lon, lat = rasterio.transform.xy(transform,lat_pos.flatten(),lon_pos.flatten())
 
591
  return gdf[(gdf.drop(columns='geometry')>0).any(axis=1)]
592
  #return gdf.sort_values(by='im',ascending=False).head(10000)
593
 
 
594
  def read_gem_xml(data: [bytes]):
595
  content_as_string = data.decode('utf-8')
596
  content_as_string = content_as_string.replace('\n','')
 
611
 
612
  d['description'] = getText(dom.getElementsByTagName('description')[0])
613
 
 
614
  d['vulnerabilityFunctions'] = []
615
  for node in dom.getElementsByTagName('vulnerabilityFunction'):
616
  v = dict()
 
625
 
626
  return d
627
 
 
628
  @solara.component
629
  def VulnerabilityFunctionDisplayer(vuln_func):
630
  vuln_func, _ = solara.use_state_or_update(vuln_func)
 
748
  "title": {"fontSize": 12},
749
  "data": [{"value": value, "name": name}]}]}
750
  print(f'value/max_value {value}:{max_value}')
 
751
 
752
  with solara.Tooltip(description):
753
  with solara.Column():
754
  solara.FigureEcharts(option=options, attributes={ "style": "height: 100px; width: 100px" })
755
 
 
756
  def import_data(fileinfo: solara.components.file_drop.FileInfo):
757
  data_array = fileinfo['data']
758
  extension = fileinfo['name'].split('.')[-1]
 
778
  else:
779
  return (None, None)
780
 
 
781
  # in the first pass, look for exact column match
782
  name = None
783
  for layer_name, layer in layers.value['layers'].items():
 
804
  data[col] = val
805
  return (name, data)
806
 
 
807
  @solara.component
808
  def FileDropZone():
809
  total_progress, set_total_progress = solara.use_state(-1)
 
880
  data = nonempty_layers[selected]['data'].value
881
  if isinstance(data, gpd.GeoDataFrame) or isinstance(data, pd.DataFrame):
882
  if "geometry" in data.columns:
883
+ # ((ymin,xmin),(ymax,xmax)) = layers.value['bounds'].value
884
+ # df_filtered = data.cx[xmin:xmax,ymin:ymax].drop(columns='geometry')
885
+ df_filtered = data.drop(columns=['geometry'])
886
  #solara.CrossFilterReport(df_filtered, classes=["py-2"])
887
  #solara.CrossFilterSelect(df_filtered, df_filtered.columns[0])
888
  #solara.CrossFilterDataFrame(df=df_filtered)
889
+ ipydatagrid.DataGrid.element(dataframe=df_filtered, layout={"height": "445px"}, auto_fit_columns=True).key(f'datagrid-{df_filtered}')
890
  else:
891
  #solara.CrossFilterReport(data, classes=["py-2"])
892
  #solara.CrossFilterSelect(data, data.columns[0])
893
  #solara.CrossFilterDataFrame(df=data)
894
+ ipydatagrid.DataGrid.element(dataframe=data, layout={"height": "445px"}, auto_fit_columns=True).key(f'datagrid-{data}')
895
  if selected in ["building","road edges","road nodes","power nodes","power edges"] :
896
  with solara.Row():
897
  file_object = data.to_json()
 
899
  solara.Button("Download GeoJSON", icon_name="mdi-cloud-download-outline", color="primary")
900
  with solara.FileDownload(data.to_csv(), f"{selected}_export.csv", mime_type="text/csv"):
901
  solara.Button("Download CSV", icon_name="mdi-cloud-download-outline", color="primary")
902
+ with solara.Row(): #add empty line after attribute table
903
+ return
904
  if selected == 'gem_vulnerability':
905
  VulnerabiliyDisplayer(data)
906
 
 
922
  layers.value['render_count'].value)
923
  with solara.Link("/docs/metrics"):
924
  solara.Button(icon_name="mdi-help-circle-outline", icon=True)
 
925
 
926
  @solara.component
927
  def LayerController():
 
930
  if layer['map_layer'].value is not None:
931
  solara.Checkbox(label=layer_name,
932
  value=layer['visible'])
 
933
 
934
  @solara.component
935
  def MapViewer():
 
939
  zoom, set_zoom = solara.use_state(default_zoom)
940
  #center, set_center = solara.use_state(default_center)
941
 
942
+ # base_map = ipyleaflet.basemaps["OpenStreetMap"]["Mapnik"]
943
+ # base_layer = ipyleaflet.TileLayer.element(url=base_map.build_url())
944
+ # map_layers = [base_layer]
945
+ base_layer1 = ipyleaflet.TileLayer.element(url=ipyleaflet.basemaps.OpenStreetMap.Mapnik.build_url(),name="OpenStreetMap",base = True)
946
+ base_layer2 = ipyleaflet.TileLayer.element(url=ipyleaflet.basemaps.Esri.WorldStreetMap.build_url(),name="Esri WorldStreetMap",base = True)
947
+ base_layer3 = ipyleaflet.TileLayer.element(url=ipyleaflet.basemaps.OpenTopoMap.build_url(),name="OpenTopoMap",base = True)
948
+ base_layer4 = ipyleaflet.TileLayer.element(url=ipyleaflet.basemaps.Stadia.StamenTerrain.build_url(),name="StamenTerrain",base = True)
949
+ base_layer5 = ipyleaflet.TileLayer.element(url=ipyleaflet.basemaps.CartoDB.Positron.build_url(),name="CartoDB",base = True)
950
+ map_layers = [base_layer5, base_layer4, base_layer3, base_layer2, base_layer1]
951
+
952
+ layout = ipywidgets.Layout.element(width='100%', height='70vh')
953
+
954
+ tool1 = ipyleaflet.ZoomControl.element(position='topleft')
955
+ tool2 = ipyleaflet.FullScreenControl.element(position='topleft')
956
+ tool3 = ipyleaflet.LayersControl.element(position='topright')
957
+ tool4 = ipyleaflet.ScaleControl.element(position='bottomleft')
958
 
959
  render_order = [l['render_order'] for _, l in layers.value['layers'].items()]
960
  for _, (layer_name, layer) in sorted(zip(render_order,layers.value['layers'].items())):
 
965
  map_layer = create_map_layer(df, layer_name)
966
  if map_layer is not None:
967
  map_layers.append(map_layer)
 
968
 
969
  ipyleaflet.Map.element(
970
  zoom=zoom,
 
978
  touch_zoom=True,
979
  box_zoom=True,
980
  keyboard=True if random.random() > 0.5 else False,
981
+ layers=map_layers,
982
+ controls = [tool1, tool2, tool3, tool4],
983
+ layout = layout
984
  )
985
 
986
  @solara.component
 
1038
 
1039
  return True, ''
1040
 
 
1041
  def execute_engine():
1042
 
 
1043
  def execute_road():
1044
  buildings = layers.value['layers']['building']['data'].value
1045
  household = layers.value['layers']['household']['data'].value
 
1187
  layers.value['metrics'][metric]['max_value'] = computed_metrics[metric]['max_value']
1188
  return buildings
1189
 
 
1190
  if execute_counter > 0 :
1191
  is_ready, missing = is_ready_to_run(layers.value['infra'].value, layers.value['hazard'].value)
1192
  if not is_ready:
 
1244
 
1245
  layers.value['datetime_analysis'] = datetime.datetime.utcnow()
1246
 
 
 
1247
  # Execute the thread only when the depencency is changed
1248
  result = solara.use_thread(execute_engine, dependencies=[execute_counter])
1249
 
 
1292
  set_execute_btn_disabled(False)
1293
  solara.ProgressLinear(value=False)
1294
 
 
1295
  @solara.component
1296
  def PolicyPanel():
1297
  all_policies = [f"{p['label']}/{p['description']}" for _, p in layers.value['policies'].items()]
1298
  with solara.Row():
1299
  solara.SelectMultiple("Policies", layers.value['selected_policies'].value, all_policies, on_value=layers.value['selected_policies'].set, dense=False)
1300
 
 
 
 
1301
  @solara.component
1302
  def MapInfo():
1303
  print(f'{layers.value["bounds"].value}')
 
1338
  else:
1339
  solara.Text(f'{value}')
1340
 
 
1341
  @solara.component
1342
  def ImportDataZone():
1343
  def s3_file_open(p):
 
1358
  size=len(fileContent),
1359
  data=fileContent)
1360
  set_fileinfo(file_info)
 
1361
 
1362
  total_progress, set_total_progress = solara.use_state(-1)
1363
  fileinfo, set_fileinfo = solara.use_state(None)
 
1426
  # solara.FileBrowser(can_select=True, on_file_open=local_file_open,
1427
  # filter=lambda p: True if p.is_dir() or p.suffix in extension_list_w_dots else False)
1428
 
 
 
 
 
1429
  if total_progress > -1 and total_progress < 100:
1430
  solara.Text(f"Uploading {total_progress}%")
1431
  solara.ProgressLinear(value=total_progress)
 
1450
  def WebApp():
1451
  if storage.value is None:
1452
  storage.value = revive_storage()
1453
+ solara.Title("Sidebar")
1454
+ with solara.Sidebar():
1455
  with solara.lab.Tabs():
1456
  with solara.lab.Tab("SETTINGS"):
1457
  ExecutePanel()
1458
  with solara.lab.Tab("DATA IMPORT"):
1459
  ImportDataZone()
1460
+ MapInfo()
1461
+
1462
+ # LayerController()
1463
+ MapViewer()
1464
+ with solara.Row(justify="center"):
1465
+ MetricPanel()
1466
+ LayerDisplayer()
1467
+
1468
+ with ConfirmationDialog(
1469
+ layers.value['dialog_message_to_be_shown'].value is not None,
1470
+ on_close=clear_help_topic,
1471
+ ok="Close",
1472
+ title="Information Box",
1473
+ ):
1474
+ solara.Markdown(f'{layers.value["dialog_message_to_be_shown"].value}')
 
 
1475
 
1476
  @solara.component
1477
  def Page(name: Optional[str] = None, page: int = 0, page_size=100):
 
1500
  solara.Style(value=css)
1501
  solara.Title(" ")
1502
 
1503
+ WebApp()