irie 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of irie might be problematic. Click here for more details.

Files changed (145) hide show
  1. irie/__main__.py +24 -0
  2. irie/apps/__init__.py +5 -0
  3. irie/apps/authentication/__init__.py +1 -0
  4. irie/apps/authentication/admin.py +1 -0
  5. irie/apps/authentication/config.py +6 -0
  6. irie/apps/authentication/forms.py +41 -0
  7. irie/apps/authentication/migrations/__init__.py +1 -0
  8. irie/apps/authentication/models.py +1 -0
  9. irie/apps/authentication/tests.py +1 -0
  10. irie/apps/authentication/urls.py +9 -0
  11. irie/apps/authentication/views.py +53 -0
  12. irie/apps/config.py +8 -0
  13. irie/apps/context_processors.py +5 -0
  14. irie/apps/documents/__init__.py +0 -0
  15. irie/apps/documents/apps.py +7 -0
  16. irie/apps/documents/documents.py +61 -0
  17. irie/apps/documents/migrations/__init__.py +0 -0
  18. irie/apps/documents/tests.py +3 -0
  19. irie/apps/documents/urls.py +12 -0
  20. irie/apps/documents/views.py +27 -0
  21. irie/apps/evaluation/__init__.py +0 -0
  22. irie/apps/evaluation/admin.py +43 -0
  23. irie/apps/evaluation/apps.py +18 -0
  24. irie/apps/evaluation/daemon.py +107 -0
  25. irie/apps/evaluation/identification.py +196 -0
  26. irie/apps/evaluation/migrations/0001_initial.py +25 -0
  27. irie/apps/evaluation/migrations/0002_remove_evaluation_cesmd.py +17 -0
  28. irie/apps/evaluation/migrations/0003_evaluation_asset.py +20 -0
  29. irie/apps/evaluation/migrations/__init__.py +0 -0
  30. irie/apps/evaluation/models.py +72 -0
  31. irie/apps/evaluation/urls.py +16 -0
  32. irie/apps/evaluation/views.py +68 -0
  33. irie/apps/events/__init__.py +0 -0
  34. irie/apps/events/admin.py +9 -0
  35. irie/apps/events/apps.py +12 -0
  36. irie/apps/events/migrations/0001_initial.py +27 -0
  37. irie/apps/events/migrations/0002_alter_event_id.py +18 -0
  38. irie/apps/events/migrations/0003_event_cesmd.py +19 -0
  39. irie/apps/events/migrations/0004_event_record_identifier.py +19 -0
  40. irie/apps/events/migrations/0005_event_asset.py +21 -0
  41. irie/apps/events/migrations/0006_alter_event_event_file.py +18 -0
  42. irie/apps/events/migrations/__init__.py +0 -0
  43. irie/apps/events/models.py +70 -0
  44. irie/apps/events/tests.py +1 -0
  45. irie/apps/events/tests_events.py +240 -0
  46. irie/apps/events/urls.py +29 -0
  47. irie/apps/events/views.py +55 -0
  48. irie/apps/events/views_events.py +215 -0
  49. irie/apps/inventory/CESMD.py +81 -0
  50. irie/apps/inventory/__init__.py +5 -0
  51. irie/apps/inventory/admin.py +10 -0
  52. irie/apps/inventory/apps.py +12 -0
  53. irie/apps/inventory/archive/arcGIS.py +1175 -0
  54. irie/apps/inventory/calid.py +65 -0
  55. irie/apps/inventory/fields.py +5 -0
  56. irie/apps/inventory/forms.py +12 -0
  57. irie/apps/inventory/migrations/0001_initial.py +31 -0
  58. irie/apps/inventory/migrations/0002_assetevaluationmodel_cesmd.py +19 -0
  59. irie/apps/inventory/migrations/0003_auto_20230520_2030.py +23 -0
  60. irie/apps/inventory/migrations/0004_asset.py +27 -0
  61. irie/apps/inventory/migrations/0005_auto_20230731_1802.py +23 -0
  62. irie/apps/inventory/migrations/0006_auto_20230731_1816.py +28 -0
  63. irie/apps/inventory/migrations/0007_auto_20230731_1827.py +24 -0
  64. irie/apps/inventory/migrations/0008_asset_is_complete.py +19 -0
  65. irie/apps/inventory/migrations/0009_auto_20230731_1842.py +29 -0
  66. irie/apps/inventory/migrations/0010_auto_20230801_0025.py +23 -0
  67. irie/apps/inventory/migrations/0011_alter_asset_cgs_data.py +18 -0
  68. irie/apps/inventory/migrations/0012_corridor.py +22 -0
  69. irie/apps/inventory/migrations/0013_alter_asset_cesmd.py +18 -0
  70. irie/apps/inventory/migrations/0014_alter_asset_cesmd.py +18 -0
  71. irie/apps/inventory/migrations/__init__.py +0 -0
  72. irie/apps/inventory/models.py +70 -0
  73. irie/apps/inventory/tables.py +584 -0
  74. irie/apps/inventory/traffic.py +175052 -0
  75. irie/apps/inventory/urls.py +25 -0
  76. irie/apps/inventory/views.py +515 -0
  77. irie/apps/management/__init__.py +0 -0
  78. irie/apps/management/commands/__init__.py +0 -0
  79. irie/apps/networks/__init__.py +0 -0
  80. irie/apps/networks/apps.py +5 -0
  81. irie/apps/networks/forms.py +64 -0
  82. irie/apps/networks/migrations/0001_initial.py +26 -0
  83. irie/apps/networks/migrations/__init__.py +0 -0
  84. irie/apps/networks/models.py +14 -0
  85. irie/apps/networks/networks.py +782 -0
  86. irie/apps/networks/tests.py +1 -0
  87. irie/apps/networks/urls.py +18 -0
  88. irie/apps/networks/views.py +89 -0
  89. irie/apps/prediction/__init__.py +0 -0
  90. irie/apps/prediction/admin.py +9 -0
  91. irie/apps/prediction/apps.py +12 -0
  92. irie/apps/prediction/forms.py +20 -0
  93. irie/apps/prediction/metrics.py +61 -0
  94. irie/apps/prediction/migrations/0001_initial.py +32 -0
  95. irie/apps/prediction/migrations/0002_auto_20230731_1801.py +27 -0
  96. irie/apps/prediction/migrations/0003_rename_assetevaluationmodel_evaluation.py +18 -0
  97. irie/apps/prediction/migrations/0004_delete_evaluation.py +16 -0
  98. irie/apps/prediction/migrations/0005_predictormodel_protocol.py +18 -0
  99. irie/apps/prediction/migrations/0006_alter_predictormodel_protocol.py +18 -0
  100. irie/apps/prediction/migrations/0007_predictormodel_active.py +19 -0
  101. irie/apps/prediction/migrations/0008_predictormodel_description.py +18 -0
  102. irie/apps/prediction/migrations/0009_predictormodel_entry_point.py +19 -0
  103. irie/apps/prediction/migrations/0010_alter_predictormodel_entry_point.py +18 -0
  104. irie/apps/prediction/migrations/0011_remove_predictormodel_entry_point.py +17 -0
  105. irie/apps/prediction/migrations/0012_predictormodel_entry_point.py +18 -0
  106. irie/apps/prediction/migrations/0013_predictormodel_metrics.py +18 -0
  107. irie/apps/prediction/migrations/0014_auto_20240930_0004.py +28 -0
  108. irie/apps/prediction/migrations/0015_alter_predictormodel_render_file.py +18 -0
  109. irie/apps/prediction/migrations/__init__.py +0 -0
  110. irie/apps/prediction/models.py +37 -0
  111. irie/apps/prediction/predictor.py +286 -0
  112. irie/apps/prediction/runners/__init__.py +450 -0
  113. irie/apps/prediction/runners/metrics.py +168 -0
  114. irie/apps/prediction/runners/opensees/__init__.py +0 -0
  115. irie/apps/prediction/runners/opensees/schemas/__init__.py +39 -0
  116. irie/apps/prediction/runners/utilities.py +277 -0
  117. irie/apps/prediction/runners/xmlutils.py +232 -0
  118. irie/apps/prediction/runners/zipped.py +27 -0
  119. irie/apps/prediction/templatetags/__init__.py +0 -0
  120. irie/apps/prediction/templatetags/predictor.py +20 -0
  121. irie/apps/prediction/urls.py +19 -0
  122. irie/apps/prediction/views.py +184 -0
  123. irie/apps/prediction/views_api.py +216 -0
  124. irie/apps/site/__init__.py +0 -0
  125. irie/apps/site/admin.py +1 -0
  126. irie/apps/site/config.py +6 -0
  127. irie/apps/site/migrations/__init__.py +1 -0
  128. irie/apps/site/models.py +2 -0
  129. irie/apps/site/templatetags/__init__.py +0 -0
  130. irie/apps/site/templatetags/indexing.py +7 -0
  131. irie/apps/site/tests.py +1 -0
  132. irie/apps/site/urls.py +8 -0
  133. irie/apps/site/view_sdof.py +40 -0
  134. irie/apps/site/view_utils.py +13 -0
  135. irie/apps/site/views.py +88 -0
  136. irie/core/__init__.py +5 -0
  137. irie/core/asgi.py +12 -0
  138. irie/core/settings.py +223 -0
  139. irie/core/urls.py +39 -0
  140. irie/core/wsgi.py +12 -0
  141. irie-0.0.0.dist-info/METADATA +48 -0
  142. irie-0.0.0.dist-info/RECORD +145 -0
  143. irie-0.0.0.dist-info/WHEEL +5 -0
  144. irie-0.0.0.dist-info/entry_points.txt +2 -0
  145. irie-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,782 @@
1
+ #
2
+ # (c) Soga Research Group
3
+ #
4
+ # Pengshun Li
5
+ #
6
+ from pathlib import Path
7
+ import zipfile
8
+ import pandas as pd
9
+ import numpy as np
10
+ import geopandas as gpd
11
+ from pyproj import Transformer
12
+ from shapely.geometry import Point
13
+ import folium
14
+ from folium.plugins import TagFilterButton, Search
15
+
16
+ from apps.inventory.models import Asset
17
+
18
+ cwd = Path(__file__).parent
19
+
20
+ transformer = Transformer.from_crs("epsg:4326", "epsg:3857", always_xy=True)
21
+
22
+
23
+ COLUMN_ALIASES = {
24
+ "bridge": "Bridge",
25
+ "corridor": "Corridor",
26
+ 'detour_length': 'Detour length',
27
+ "times_used_by_hospital_access": "Zone-hospital pairs",
28
+ "times_used_by_fire_access": "Zone-fire pairs",
29
+ "times_used_by_police_access": "Zone-police pairs",
30
+ "times_used_by_maintenance_access": "Zone-maintenance pairs",
31
+ "times_used_by_airport_access": "Zone-airport pairs",
32
+ "times_used_by_seaport_access": "Zone-seaport pairs",
33
+ "times_used_by_ferry_access": "Zone-seaport pairs",
34
+ "long_decimal": "Lon",
35
+ "lat_decimal": "Lat",
36
+ }
37
+
38
+ def _read_csv(arxiv, path):
39
+ return pd.read_csv(arxiv.open(path))
40
+
41
+ def _read_csv_field(arxiv, file, dicts):
42
+ return [
43
+ {
44
+ getattr(tmp, name): getattr(tmp, key)
45
+ for tmp in _read_csv(arxiv, file).itertuples()
46
+ for name, key in fields.items()
47
+ } for fields in dicts
48
+ ]
49
+
50
+ # Define style functions for default and highlighted states
51
+ def _style_function_zipcode(feature):
52
+ return {"color": "pink", "weight": 1, "opacity": 0.2} # Default color
53
+
54
+ def _style_function_network(feature):
55
+ return {"color": "gray", "weight": 1, "opacity": 1} # Default color
56
+
57
+ def _style_function(feature):
58
+ return {"color": "blue", "weight": 2, "opacity": 1} # Default color
59
+
60
+ def _style_function_strahnet(feature):
61
+ return {"color": "brown", "weight":2, "opacity":0.5} # Default color
62
+
63
+ def _highlight_function(feature):
64
+ return {"color": "red", "weight": 4, "opacity": 1} # Highlight color
65
+
66
+
67
+ class _NetworkBase:
68
+ arxiv: zipfile.ZipFile
69
+ _weights: dict
70
+ _consider_population: bool
71
+
72
+ #
73
+ # Loaded with load_data
74
+ #
75
+ _hospital_corridor : dict
76
+ _fire_corridor : dict
77
+ _police_corridor : dict
78
+ _maintenance_corridor : dict
79
+ _airport_corridor : dict
80
+ _seaport_corridor : dict
81
+ _ferry_corridor : dict
82
+
83
+
84
+ _hospital_corridor_consider_pop_dict : dict
85
+ _fire_corridor_consider_pop_dict : dict
86
+ _police_corridor_consider_pop_dict : dict
87
+ _maintenance_corridor_consider_pop_dict : dict
88
+ _airport_corridor_consider_pop_dict : dict
89
+ _seaport_corridor_consider_pop_dict : dict
90
+ _ferry_corridor_consider_pop_dict : dict
91
+
92
+ #
93
+ # Loaded with load_bridges
94
+ #
95
+ _hospital_count_dict : dict
96
+ _fire_count_dict : dict
97
+ _police_count_dict : dict
98
+ _maintenance_count_dict : dict
99
+ _airport_count_dict : dict
100
+ _seaport_count_dict : dict
101
+ _ferry_count_dict : dict
102
+
103
+ _bridge_corridor_corres_gdf : gpd.GeoDataFrame
104
+ bridge_detour_dict : dict
105
+
106
+
107
+ def __init__(self, preferences, weights, consider_population, load_bridges=False):
108
+ self._weights = weights
109
+ self._corridors = None
110
+ self._preferences = preferences
111
+ self._consider_population = consider_population
112
+
113
+ self.load_data()
114
+
115
+ if load_bridges:
116
+ self.load_bridges()
117
+
118
+ bridge_corridor_corres_df = _read_csv(self.arxiv, "data/bridge_corridor_corres.csv")
119
+ bridge_corridor_corres_df["geometry"] = bridge_corridor_corres_df.apply(
120
+ lambda row: Point(row["long_decimal"], row["lat_decimal"]), axis=1
121
+ )
122
+ self._bridge_corridor_corres_gdf = gpd.GeoDataFrame(
123
+ bridge_corridor_corres_df, geometry="geometry", crs="EPSG:4326"
124
+ )
125
+
126
+ bridge_detour_df = _read_csv(self.arxiv, "data/D4_bridges.csv")
127
+ self.bridge_detour_dict = {
128
+ getattr(tmp, 'bridge_nbi'): getattr(tmp,'detour_length_NBI19')
129
+ for tmp in bridge_detour_df.itertuples()
130
+ }
131
+
132
+
133
+ def load_data(self):
134
+ pass
135
+
136
+ def load_bridges(self):
137
+ pass
138
+
139
+ # def ranked_corridors(self):
140
+ # if self._corridors is None:
141
+ # self._corridors = gpd.read_file(self.arxiv.open("data/corridor_line.geojson"))
142
+ # corridor_weights, corridor_ranks = self.corridor_ranking(self._weights,
143
+ # self._consider_population)
144
+ # self._corridors["corridor_weighted"] = self._corridors["id"].map(corridor_weights)
145
+ # self._corridors["corridor_rank"] = self._corridors["id"].map(corridor_ranks)
146
+
147
+ # return self._corridors
148
+
149
+ def ranked_corridors(self):
150
+ if self._corridors is None:
151
+ self._corridors = gpd.read_file(self.arxiv.open("data/corridor_line.geojson"))
152
+ corridor_weights, corridor_ranks, zone_count_dict = self.corridor_ranking(self._weights,
153
+ self._consider_population)
154
+ self._corridors["corridor_weighted"] = self._corridors["id"].map(corridor_weights)
155
+ self._corridors["corridor_rank"] = self._corridors["id"].map(corridor_ranks)
156
+ self._corridors["corridor_rank_str"] = self._corridors["corridor_rank"].apply(lambda x:str(int(x)) + ' of 161')
157
+ self._corridors["zone_count"] = self._corridors["id"].map(zone_count_dict)
158
+ return self._corridors
159
+
160
+ def create_map(self, corridor=None):
161
+
162
+ if corridor is not None:
163
+ bridges, categories = self._get_bridges(corridor, self._weights)
164
+ location = sum(np.array(m.location) for m in bridges) / len(bridges)
165
+ else:
166
+ location = (self._preferences.latitude, self._preferences.longitude)
167
+
168
+ chart = folium.Map(
169
+ location=location,
170
+ tiles="cartodb positron",
171
+ show=True,
172
+ zoom_start=10,
173
+ control_scale=True,
174
+ )
175
+
176
+ if corridor is not None:
177
+ self._add_zipcodes(chart)
178
+
179
+ self._add_network(chart)
180
+
181
+ for m in reversed(bridges):
182
+ m.add_to(chart)
183
+
184
+ TagFilterButton(categories).add_to(chart)
185
+
186
+ html_text = """
187
+ <div style="position: absolute; top: 86px; left: 48px; z-index: 1000; background: white; padding: 5px; border: 1px solid black; font-size: 12px; font-weight:bold";font-family: 'Times New Roman', Times, serif;>
188
+ ← this is a filter button
189
+ </div>
190
+ """
191
+ chart.get_root().html.add_child(folium.Element(html_text))
192
+
193
+ self.add_corridor(chart, corridor=corridor)
194
+
195
+ try:
196
+ self.add_strahnet(chart)
197
+ except:
198
+ pass
199
+
200
+ folium.LayerControl().add_to(chart)
201
+ return chart
202
+
203
+ def add_strahnet(self, chart):
204
+ popup_strahnet = folium.GeoJsonPopup(
205
+ fields = ['RouteID','NHS_TYPE'],
206
+ aliases = [
207
+ "RouteID:",
208
+ "Type:"
209
+ ],
210
+ localize=True,
211
+ labels=True,
212
+ style="background-color: yellow;")
213
+
214
+ with self.arxiv.open("data/strahnet.geojson") as f:
215
+ strahnet_gdf = gpd.read_file(f)
216
+ # Load the GeoJSON from the URL
217
+ strahnet_geo = folium.GeoJson(
218
+ strahnet_gdf.to_json(),
219
+ name="Strahnet",
220
+ popup=popup_strahnet,
221
+ style_function=_style_function_strahnet,
222
+ localize=True,
223
+ show=False
224
+ ).add_to(chart)
225
+
226
+
227
+ def add_corridor(self, chart, corridor=None):
228
+ MAX_CORRIDOR = 161
229
+
230
+ popup_corridor = folium.GeoJsonPopup(
231
+ fields=["id", "name_new", "type", "zone_count", "corridor_weighted", "corridor_rank_str"],
232
+ aliases=[
233
+ "Corridor #",
234
+ "Corridor ID",
235
+ "Corridor Type",
236
+ "Zone Count",
237
+ "Corridor Value",
238
+ "Corridor Rank",
239
+ ],
240
+ localize=True,
241
+ labels=True,
242
+ )
243
+
244
+ tooltip_corridor = folium.GeoJsonTooltip(
245
+ fields=["id", "name_new"],
246
+ aliases=["Corridor #", "Corridor ID"],
247
+ localize=True,
248
+ sticky=False,
249
+ labels=True,
250
+ style="""
251
+ background-color: #F0EFEF;
252
+ border: 2px solid black;
253
+ border-radius: 3px;
254
+ box-shadow: 3px;
255
+ """,
256
+ max_width=800,
257
+ )
258
+
259
+ #
260
+ corridor_line_gdf = self.ranked_corridors().copy()
261
+
262
+ if corridor is not None:
263
+ corridor_line_gdf = corridor_line_gdf.loc[corridor_line_gdf["id"] == corridor, :]
264
+
265
+ corridor_line_gdf["name_new"] = corridor_line_gdf.apply(
266
+ lambda x: f'<a href="" onclick="handleCorridorSelection(\'corr-{x["id"]}\')">{x["name_new"]}</a>', axis=1
267
+ )
268
+
269
+ corridor_geo = folium.GeoJson(
270
+ corridor_line_gdf.to_json(),
271
+ name="corridor",
272
+ popup=popup_corridor,
273
+ tooltip=tooltip_corridor,
274
+ style_function=_style_function,
275
+ localize=True,
276
+ ).add_to(chart)
277
+
278
+ if corridor is None:
279
+
280
+ Search(
281
+ layer=corridor_geo,
282
+ geom_type="Polygon",
283
+ placeholder="Search for a corridor based on its number",
284
+ collapsed=False,
285
+ search_label="id",
286
+ color="#FF0000",
287
+ weight = 4
288
+ ).add_to(chart)
289
+
290
+ text_string = f"""
291
+ <div style="position: absolute; top: 10px; left: 50px; background-color: rgba(255, 255, 255); padding: 5px; z-index: 1000;font-size: 10px;">
292
+ <label for="min_id">Highest Rank:</label>
293
+ <input type="number" id="min_id" name="min_id" value="1">
294
+ <label for="max_id">Lowest Rank:</label>
295
+ <input type="number" id="max_id" name="max_id" value="10">
296
+ <button onclick="applyFilter()">Apply Filter</button>
297
+ <button onclick="resetFilter()">Reset Filter</button>
298
+ </div>
299
+
300
+ <script>
301
+ var highlightedIDs = []; // Array to store highlighted IDs
302
+
303
+ function applyFilter() {{
304
+ // Get the min and max ID values from input fields
305
+ var minID = document.getElementById("min_id").value;
306
+ var maxID = document.getElementById("max_id").value;
307
+
308
+ // Call the filter function with the input values
309
+ filterByIDRange(minID, maxID);
310
+ }}
311
+
312
+ function filterByIDRange(min, max) {{
313
+ // Filter through GeoJson layer and highlight matching features
314
+ var layer = {corridor_geo.get_name()}; // This is the layer name passed from Python
315
+ layer.eachLayer(function (layer) {{
316
+ var featureID = layer.feature.properties.corridor_rank;
317
+ if (featureID >= min && featureID <= max) {{
318
+ layer.setStyle({{color: 'red', weight: 4}}); // Highlight in red
319
+ if (!highlightedIDs.includes(featureID)) {{
320
+ highlightedIDs.push(featureID); // Keep track of highlighted IDs
321
+ }}
322
+ }} else {{
323
+ // Reset to default color only if not highlighted
324
+ if (!highlightedIDs.includes(featureID)) {{
325
+ layer.setStyle({{color: 'blue', weight: 2}}); // Default color
326
+ }}
327
+ }}
328
+ }});
329
+ }}
330
+
331
+ function resetFilter() {{
332
+ // Reset all styles to default and clear highlighted IDs
333
+ var layer = {corridor_geo.get_name()}; // This is the layer name passed from Python
334
+ layer.eachLayer(function (layer) {{
335
+ layer.setStyle({{color: 'blue', weight: 2}}); // Reset to default color
336
+ }});
337
+ highlightedIDs = []; // Clear highlighted IDs array
338
+ }}
339
+
340
+ </script>
341
+ """
342
+ chart.get_root().html.add_child(folium.Element(text_string))
343
+
344
+ text_string1 = f"""
345
+ <div style="position: absolute; top: 120px; left: 10px; z-index: 1000;font-size: 10px;">
346
+ <button onclick="resetFilter_corridor()">Reset Filter for corridor search</button>
347
+ </div>
348
+
349
+ <script>
350
+ function resetFilter_corridor() {{
351
+ // Reset all styles to default and clear highlighted IDs
352
+ var layer = {corridor_geo.get_name()}; // This is the layer name passed from Python
353
+ layer.eachLayer(function (layer) {{
354
+ layer.setStyle({{color: 'blue', weight: 2}}); // Reset to default color
355
+ }});
356
+ }}
357
+ </script>
358
+ """
359
+ chart.get_root().html.add_child(folium.Element(text_string1))
360
+
361
+ def corridor_ranking(self, weights, consider_population=False):
362
+ total_weight = weights.get("hospital_weight", 1) + \
363
+ weights.get("fire_weight", 1) + \
364
+ weights.get("police_weight", 1) + \
365
+ weights.get("maintenance_weight", 1) + \
366
+ weights.get("airport_weight", 1) + \
367
+ weights.get("seaport_weight", 1) + \
368
+ weights.get("ferry_weight", 1)
369
+ hospital_weight = weights.get("hospital_weight", 1) / total_weight
370
+ fire_weight = weights.get("fire_weight", 1) / total_weight
371
+ police_weight = weights.get("police_weight", 1) / total_weight
372
+ maintenance_weight = weights.get("maintenance_weight", 1) / total_weight
373
+ airport_weight = weights.get("airport_weight", 1) / total_weight
374
+ seaport_weight = weights.get("seaport_weight", 1) / total_weight
375
+ ferry_weight = weights.get("ferry_weight", 1) / total_weight
376
+
377
+ hospital_weight_tmp = 1 if hospital_weight !=0 else 0
378
+ fire_weight_tmp = 1 if fire_weight !=0 else 0
379
+ police_weight_tmp = 1 if police_weight !=0 else 0
380
+ maintenance_weight_tmp = 1 if maintenance_weight !=0 else 0
381
+ airport_weight_tmp = 1 if airport_weight !=0 else 0
382
+ seaport_weight_tmp = 1 if seaport_weight !=0 else 0
383
+ ferry_weight_tmp = 1 if ferry_weight !=0 else 0
384
+
385
+ corridor_agg_df = pd.DataFrame()
386
+ corridor_agg_df["corridor_id"] = np.arange(1, 162)
387
+
388
+ corridor_agg_df["hospital_count_weight"] = corridor_agg_df["corridor_id"].map(
389
+ self._hospital_corridor
390
+ )
391
+ corridor_agg_df["fire_count_weight"] = corridor_agg_df["corridor_id"].map(
392
+ self._fire_corridor
393
+ )
394
+ corridor_agg_df["police_count_weight"] = corridor_agg_df["corridor_id"].map(
395
+ self._police_corridor
396
+ )
397
+ corridor_agg_df["maintenance_count_weight"] = corridor_agg_df["corridor_id"].map(
398
+ self._maintenance_corridor
399
+ )
400
+ corridor_agg_df["airport_count_weight"] = corridor_agg_df["corridor_id"].map(
401
+ self._airport_corridor
402
+ )
403
+ corridor_agg_df["seaport_count_weight"] = corridor_agg_df["corridor_id"].map(
404
+ self._seaport_corridor
405
+ )
406
+ corridor_agg_df["ferry_count_weight"] = corridor_agg_df["corridor_id"].map(
407
+ self._ferry_corridor
408
+ )
409
+
410
+ corridor_agg_df["zone_count"] = corridor_agg_df.apply(
411
+ lambda x: x["hospital_count_weight"]*hospital_weight_tmp
412
+ + x["fire_count_weight"]*fire_weight_tmp
413
+ + x["police_count_weight"]*police_weight_tmp
414
+ + x["maintenance_count_weight"]*maintenance_weight_tmp
415
+ + x["airport_count_weight"]*airport_weight_tmp
416
+ + x["seaport_count_weight"]*seaport_weight_tmp
417
+ + x["ferry_count_weight"]*ferry_weight_tmp,
418
+ axis=1,
419
+ )
420
+
421
+ if consider_population:
422
+ corridor_agg_df["hospital_count_weight"] = corridor_agg_df["corridor_id"].map(
423
+ self._hospital_corridor_consider_pop_dict
424
+ )
425
+ corridor_agg_df["fire_count_weight"] = corridor_agg_df["corridor_id"].map(
426
+ self._fire_corridor_consider_pop_dict
427
+ )
428
+ corridor_agg_df["police_count_weight"] = corridor_agg_df["corridor_id"].map(
429
+ self._police_corridor_consider_pop_dict
430
+ )
431
+ corridor_agg_df["maintenance_count_weight"] = corridor_agg_df[
432
+ "corridor_id"
433
+ ].map(self._maintenance_corridor_consider_pop_dict)
434
+ corridor_agg_df["airport_count_weight"] = corridor_agg_df["corridor_id"].map(
435
+ self._airport_corridor_consider_pop_dict
436
+ )
437
+ corridor_agg_df["seaport_count_weight"] = corridor_agg_df["corridor_id"].map(
438
+ self._seaport_corridor_consider_pop_dict
439
+ )
440
+ corridor_agg_df["ferry_count_weight"] = corridor_agg_df["corridor_id"].map(
441
+ self._ferry_corridor_consider_pop_dict
442
+ )
443
+
444
+ corridor_agg_df["hospital_count_weight"] *= hospital_weight
445
+ corridor_agg_df["fire_count_weight"] *= fire_weight
446
+ corridor_agg_df["police_count_weight"] *= police_weight
447
+ corridor_agg_df["maintenance_count_weight"] *= maintenance_weight
448
+ corridor_agg_df["airport_count_weight"] *= airport_weight
449
+ corridor_agg_df["seaport_count_weight"] *= seaport_weight
450
+ corridor_agg_df["ferry_count_weight"] *= ferry_weight
451
+
452
+ corridor_agg_df["weighted_count"] = corridor_agg_df.apply(
453
+ lambda x: x["hospital_count_weight"]
454
+ + x["fire_count_weight"]
455
+ + x["police_count_weight"]
456
+ + x["maintenance_count_weight"]
457
+ + x["airport_count_weight"]
458
+ + x["seaport_count_weight"]
459
+ + x["ferry_count_weight"],
460
+ axis=1,
461
+ )
462
+ corridor_agg_df.sort_values("weighted_count", ascending=False, inplace=True)
463
+ corridor_agg_df["rank"] = corridor_agg_df["weighted_count"].rank(method='dense', ascending=False)
464
+ corridor_agg_df = corridor_agg_df[["corridor_id", "weighted_count", "rank", "zone_count"]].copy()
465
+ zone_count_dict = dict(
466
+ zip(corridor_agg_df["corridor_id"], corridor_agg_df["zone_count"])
467
+ )
468
+ corridor_weighted_value_dict = dict(
469
+ zip(corridor_agg_df["corridor_id"], corridor_agg_df["weighted_count"])
470
+ )
471
+ corridor_rank_dict = dict(
472
+ zip(corridor_agg_df["corridor_id"], corridor_agg_df["rank"])
473
+ )
474
+ return corridor_weighted_value_dict, corridor_rank_dict, zone_count_dict
475
+
476
+
477
+ def _add_network(self, chart):
478
+ road_network_geojson_data = gpd.read_file(self.arxiv.open("data/recovery_bridge_network_links.json"))
479
+ network_feature = folium.GeoJson(
480
+ road_network_geojson_data,
481
+ name="Network",
482
+ style_function=_style_function_network,
483
+ highlight_function=_highlight_function,
484
+ show=False,
485
+ )
486
+ network_feature.add_to(chart)
487
+
488
+
489
+ def _add_zipcodes(self, chart):
490
+ tooltip_zipcode = folium.GeoJsonTooltip(
491
+ fields=["po_name", "zip"], # Specify the fields you want to show
492
+ aliases=["Post Office Name", "ZIP Code"],
493
+ )
494
+ zipcode_geojson_data = gpd.read_file(self.arxiv.open("data/zipcode.geojson"))
495
+ # Create a GeoJson feature with the correct fields
496
+ zipcode_feature = folium.GeoJson(
497
+ zipcode_geojson_data,
498
+ name="Zip Code",
499
+ style_function=_style_function_zipcode,
500
+ highlight_function=_highlight_function,
501
+ tooltip=tooltip_zipcode,
502
+ show=False,
503
+ )
504
+
505
+ zipcode_feature.add_to(chart)
506
+
507
+
508
+ def _get_bridges(self, corridor, weights):
509
+
510
+ bridge_required_gdf = self.bridge_info_for_a_corridor(weights, corridor)
511
+
512
+ bridge_required_gdf['detour_length'] = bridge_required_gdf['bridge'].map(self.bridge_detour_dict)
513
+ column = bridge_required_gdf.pop('detour_length')
514
+ bridge_required_gdf.insert(4, 'detour_length', column)
515
+
516
+ categories = ['used &detour length>2km','used &detour length<=2km','unused']
517
+ bridge_required_gdf["used"] = bridge_required_gdf.iloc[:, 6:].sum(axis=1)
518
+
519
+ markers = []
520
+ for bridge in bridge_required_gdf.itertuples():
521
+
522
+ # Find the asset associated with the bridge
523
+ try:
524
+ asset = Asset.objects.get(calid=bridge.bridge.replace(" ", "-"))
525
+ except Asset.DoesNotExist:
526
+ asset = None
527
+
528
+ if (getattr(bridge, 'used') > 0) and (getattr(bridge, 'detour_length')<=2):
529
+ category = 'used &detour length<=2km'
530
+ elif (getattr(bridge, 'used')>0) and (getattr(bridge, 'detour_length')>2):
531
+ category = 'used &detour length>2km'
532
+ else:
533
+ category = 'unused'
534
+
535
+ popup_content = """
536
+ <table style="width: 200px; border-collapse: collapse; border: none;">
537
+ """
538
+
539
+ for column in bridge_required_gdf.columns.values:
540
+ if column == "bridge" and asset is not None:
541
+ popup_content += f"""
542
+ <tr>
543
+ <td>{COLUMN_ALIASES[column]}</td>
544
+ <td><a target="_blank" href="/inventory/{asset.calid}/">{bridge.bridge}</a></td>
545
+ </tr>
546
+ """
547
+ elif column not in {"long_decimal", "lat_decimal", "geometry", "detour_length", "used"}:
548
+ popup_content += f"""
549
+ <tr>
550
+ <td>{COLUMN_ALIASES[column]}</td>
551
+ <td>{getattr(bridge, column)}</td>
552
+ </tr>
553
+ """
554
+
555
+ popup_content += "</table>"
556
+
557
+ if asset is not None:
558
+ marker = folium.Marker(
559
+ location=[bridge.geometry.y, bridge.geometry.x],
560
+ popup=popup_content,
561
+ tags=[category],
562
+ tooltip=asset.name,
563
+ z_index_offset=1000,
564
+ icon=folium.Icon(color="blue"),
565
+ )
566
+ else:
567
+ marker = folium.Marker(
568
+ location=[bridge.geometry.y, bridge.geometry.x],
569
+ popup=popup_content,
570
+ tags=[category],
571
+ z_index_offset=900,
572
+ icon=folium.Icon(color="gray"),
573
+ )
574
+ markers.append(marker)
575
+
576
+ return markers, categories
577
+
578
+ def bridge_info_for_a_corridor(self, weights, corridor_input):
579
+
580
+ bridge_required_gdf = self._bridge_corridor_corres_gdf.loc[
581
+ (self._bridge_corridor_corres_gdf["one_corridor"] == corridor_input)
582
+ | (self._bridge_corridor_corres_gdf["another_corridor"] == corridor_input),
583
+ ["bridge", "lat_decimal", "long_decimal", "geometry"],
584
+ ].copy()
585
+
586
+ bridge_required_gdf["corridor"] = corridor_input
587
+ bridge_required_gdf = bridge_required_gdf[
588
+ ["bridge", "corridor", "long_decimal", "lat_decimal", "geometry"]
589
+ ]
590
+ if weights["hos_weight"] != 0:
591
+ bridge_required_gdf["times_used_by_hospital_access"] = bridge_required_gdf[
592
+ "bridge"
593
+ ].map(self._hospital_count_dict)
594
+ if weights["fire_weight"] != 0:
595
+ bridge_required_gdf["times_used_by_fire_access"] = bridge_required_gdf[
596
+ "bridge"
597
+ ].map(self._fire_count_dict)
598
+ if weights["police_weight"] != 0:
599
+ bridge_required_gdf["times_used_by_police_access"] = bridge_required_gdf[
600
+ "bridge"
601
+ ].map(self._police_count_dict)
602
+ if weights["maintenance_weight"] != 0:
603
+ bridge_required_gdf["times_used_by_maintenance_access"] = bridge_required_gdf[
604
+ "bridge"
605
+ ].map(self._maintenance_count_dict)
606
+ if weights["airport_weight"] != 0:
607
+ bridge_required_gdf["times_used_by_airport_access"] = bridge_required_gdf[
608
+ "bridge"
609
+ ].map(self._airport_count_dict)
610
+
611
+ if weights["seaport_weight"] != 0:
612
+ bridge_required_gdf["times_used_by_seaport_access"] = bridge_required_gdf[
613
+ "bridge"
614
+ ].map(self._seaport_count_dict)
615
+ if weights["ferry_weight"] != 0:
616
+ bridge_required_gdf["times_used_by_ferry_access"] = bridge_required_gdf[
617
+ "bridge"
618
+ ].map(self._ferry_count_dict)
619
+ return bridge_required_gdf
620
+
621
+
622
+ class BridgeNetworks_method_a(_NetworkBase):
623
+ def load_data(self):
624
+ arxiv = self.arxiv = zipfile.ZipFile(cwd/"data.zip")
625
+
626
+ self._hospital_corridor, self._hospital_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/hospital_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
627
+
628
+ self._fire_corridor, self._fire_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/fire_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
629
+
630
+ self._police_corridor, self._police_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/police_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
631
+
632
+ self._maintenance_corridor, self._maintenance_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/maintenance_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
633
+
634
+ self._airport_corridor, self._airport_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/airport_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
635
+
636
+ self._seaport_corridor, self._seaport_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/seaport_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
637
+
638
+ self._ferry_corridor, self._ferry_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/ferry_access_corridor_info.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
639
+
640
+ def load_bridges(self):
641
+
642
+ arxiv = self.arxiv
643
+
644
+ hospital_visualization_df = _read_csv(arxiv, "data/hospital_access_visualization.csv")
645
+ self._hospital_count_dict = dict(
646
+ zip(hospital_visualization_df["bridge"], hospital_visualization_df["bridge_count"])
647
+ )
648
+ fire_visualization_df = _read_csv(arxiv, "data/fire_access_visualization.csv")
649
+ self._fire_count_dict = dict(
650
+ zip(fire_visualization_df["bridge"], fire_visualization_df["bridge_count"])
651
+ )
652
+ police_visualization_df = _read_csv(arxiv, "data/police_access_visualization.csv")
653
+ self._police_count_dict = dict(
654
+ zip(police_visualization_df["bridge"], police_visualization_df["bridge_count"])
655
+ )
656
+ maintenance_visualization_df = _read_csv(arxiv, "data/maintenance_access_visualization.csv")
657
+ self._maintenance_count_dict = dict(
658
+ zip(
659
+ maintenance_visualization_df["bridge"], maintenance_visualization_df["bridge_count"],
660
+ )
661
+ )
662
+ airport_visualization_df = _read_csv(arxiv, "data/airport_access_visualization.csv")
663
+ self._airport_count_dict = dict(
664
+ zip(airport_visualization_df["bridge"], airport_visualization_df["bridge_count"])
665
+ )
666
+ seaport_visualization_df = _read_csv(arxiv, "data/seaport_access_visualization.csv")
667
+ self._seaport_count_dict = dict(
668
+ zip(seaport_visualization_df["bridge"], seaport_visualization_df["bridge_count"])
669
+ )
670
+ ferry_visualization_df = _read_csv(arxiv, "data/ferry_access_visualization.csv")
671
+ self._ferry_count_dict = dict(
672
+ zip(ferry_visualization_df["bridge"], ferry_visualization_df["bridge_count"])
673
+ )
674
+
675
+
676
+ class BridgeNetworks_method_b(_NetworkBase):
677
+ def load_data(self):
678
+
679
+ arxiv = self.arxiv = zipfile.ZipFile(cwd/"data.zip")
680
+
681
+ self._hospital_corridor, self._hospital_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/hospital_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
682
+
683
+ self._fire_corridor, self._fire_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/fire_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
684
+
685
+ self._police_corridor, self._police_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/police_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
686
+
687
+ self._maintenance_corridor, self._maintenance_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/maintenance_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
688
+
689
+ self._airport_corridor, self._airport_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/airport_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
690
+
691
+ self._seaport_corridor, self._seaport_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/seaport_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
692
+
693
+ self._ferry_corridor, self._ferry_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/ferry_access_corridor_info_method_b.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
694
+
695
+ def load_bridges(self):
696
+
697
+ arxiv = self.arxiv
698
+
699
+ hospital_visualization_df = _read_csv(arxiv, "data/hospital_access_visualization_method_b.csv")
700
+ self._hospital_count_dict = dict(
701
+ zip(hospital_visualization_df["bridge"], hospital_visualization_df["bridge_count"])
702
+ )
703
+ fire_visualization_df = _read_csv(arxiv, "data/fire_access_visualization_method_b.csv")
704
+ self._fire_count_dict = dict(
705
+ zip(fire_visualization_df["bridge"], fire_visualization_df["bridge_count"])
706
+ )
707
+ police_visualization_df = _read_csv(arxiv, "data/police_access_visualization_method_b.csv")
708
+ self._police_count_dict = dict(
709
+ zip(police_visualization_df["bridge"], police_visualization_df["bridge_count"])
710
+ )
711
+ maintenance_visualization_df = _read_csv(arxiv, "data/maintenance_access_visualization_method_b.csv")
712
+ self._maintenance_count_dict = dict(
713
+ zip(
714
+ maintenance_visualization_df["bridge"],
715
+ maintenance_visualization_df["bridge_count"],
716
+ )
717
+ )
718
+ airport_visualization_df = _read_csv(arxiv, "data/airport_access_visualization_method_b.csv")
719
+ self._airport_count_dict = dict(
720
+ zip(airport_visualization_df["bridge"], airport_visualization_df["bridge_count"])
721
+ )
722
+ seaport_visualization_df = _read_csv(arxiv, "data/seaport_access_visualization_method_b.csv")
723
+ self._seaport_count_dict = dict(
724
+ zip(seaport_visualization_df["bridge"], seaport_visualization_df["bridge_count"])
725
+ )
726
+ ferry_visualization_df = _read_csv(arxiv, "data/ferry_access_visualization_method_b.csv")
727
+ self._ferry_count_dict = dict(
728
+ zip(ferry_visualization_df["bridge"], ferry_visualization_df["bridge_count"])
729
+ )
730
+
731
+ class BridgeNetworks_method_b_alt(_NetworkBase):
732
+ def load_data(self):
733
+
734
+ arxiv = self.arxiv = zipfile.ZipFile(cwd/"data.zip")
735
+ self._hospital_corridor, self._hospital_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/hospital_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
736
+
737
+ self._fire_corridor, self._fire_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/fire_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
738
+
739
+ self._police_corridor, self._police_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/police_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
740
+
741
+ self._maintenance_corridor, self._maintenance_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/maintenance_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
742
+
743
+ self._airport_corridor, self._airport_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/airport_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
744
+
745
+ self._seaport_corridor, self._seaport_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/seaport_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
746
+
747
+ self._ferry_corridor, self._ferry_corridor_consider_pop_dict = _read_csv_field(arxiv, "data/ferry_access_corridor_info_method_b_alt.csv", ({"corridor_id": "count"}, {"corridor_id": "count_consider_pop"}))
748
+
749
+ def load_bridges(self):
750
+ arxiv = self.arxiv
751
+
752
+ hospital_visualization_df = _read_csv(arxiv, "data/hospital_access_visualization_method_b_alt.csv")
753
+ self._hospital_count_dict = dict(
754
+ zip(hospital_visualization_df["bridge"], hospital_visualization_df["bridge_count"])
755
+ )
756
+ fire_visualization_df = _read_csv(arxiv, "data/fire_access_visualization_method_b_alt.csv")
757
+ self._fire_count_dict = dict(
758
+ zip(fire_visualization_df["bridge"], fire_visualization_df["bridge_count"])
759
+ )
760
+ police_visualization_df = _read_csv(arxiv, "data/police_access_visualization_method_b_alt.csv")
761
+ self._police_count_dict = dict(
762
+ zip(police_visualization_df["bridge"], police_visualization_df["bridge_count"])
763
+ )
764
+ maintenance_visualization_df = _read_csv(arxiv, "data/maintenance_access_visualization_method_b_alt.csv")
765
+ self._maintenance_count_dict = dict(
766
+ zip(
767
+ maintenance_visualization_df["bridge"],
768
+ maintenance_visualization_df["bridge_count"],
769
+ )
770
+ )
771
+ airport_visualization_df = _read_csv(arxiv, "data/airport_access_visualization_method_b_alt.csv")
772
+ self._airport_count_dict = dict(
773
+ zip(airport_visualization_df["bridge"], airport_visualization_df["bridge_count"])
774
+ )
775
+ seaport_visualization_df = _read_csv(arxiv, "data/seaport_access_visualization_method_b_alt.csv")
776
+ self._seaport_count_dict = dict(
777
+ zip(seaport_visualization_df["bridge"], seaport_visualization_df["bridge_count"])
778
+ )
779
+ ferry_visualization_df = _read_csv(arxiv, "data/ferry_access_visualization_method_b_alt.csv")
780
+ self._ferry_count_dict = dict(
781
+ zip(ferry_visualization_df["bridge"], ferry_visualization_df["bridge_count"])
782
+ )