irie 0.0.56__py3-none-any.whl → 0.0.58__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.

@@ -0,0 +1,388 @@
1
+ //===----------------------------------------------------------------------===#
2
+ //
3
+ // STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ //
5
+ //===----------------------------------------------------------------------===#
6
+ //
7
+ //
8
+ function createAssetLayerThreeJS(options) {
9
+ const {map, modelSource, modelOrigin, modelRotate, unitToMeter} = options;
10
+ const modelAltitude = 0;
11
+ const modelCoord = maplibregl.MercatorCoordinate.fromLngLat(
12
+ modelOrigin,
13
+ modelAltitude
14
+ );
15
+ const modelScale = modelCoord.meterInMercatorCoordinateUnits()*unitToMeter;
16
+ const modelTransform = {
17
+ translateX: modelCoord.x,
18
+ translateY: modelCoord.y, //-25*modelScale,
19
+ translateZ: modelCoord.z+100*modelScale, // 35
20
+ rotateX: modelRotate[0],
21
+ rotateY: modelRotate[1],
22
+ rotateZ: modelRotate[2],
23
+ scale: modelScale
24
+ };
25
+
26
+ return {
27
+ id: '3d-model',
28
+ type: 'custom',
29
+ renderingMode: '3d',
30
+ onAdd(map, gl) {
31
+ this.camera = new THREE.Camera();
32
+ this.scene = new THREE.Scene();
33
+
34
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
35
+ directionalLight.position.set(100, 100, 100);
36
+ directionalLight.castShadow = true;
37
+ this.scene.add(directionalLight);
38
+
39
+ directionalLight.shadow.camera.near = 0.1;
40
+ directionalLight.shadow.camera.far = 2000;
41
+ directionalLight.shadow.camera.left = -50000; // was 500
42
+ directionalLight.shadow.camera.right = 50000; // was 500
43
+ directionalLight.shadow.camera.top = 50000; // was 500
44
+ directionalLight.shadow.camera.bottom = -50000; // was 500
45
+
46
+ directionalLight.shadow.mapSize.width = 4096;
47
+ directionalLight.shadow.mapSize.height = 4096;
48
+
49
+ const groundGeometry = new THREE.PlaneGeometry(5000, 5000);
50
+ const groundMaterial = new THREE.ShadowMaterial({ opacity: 0.3 });
51
+ const ground = new THREE.Mesh(groundGeometry, groundMaterial);
52
+ ground.rotation.x = -Math.PI / 2;
53
+ ground.position.y = - 100; // 35;
54
+ ground.receiveShadow = true;
55
+ this.scene.add(ground);
56
+
57
+ const loader = new GLTFLoader();
58
+ loader.load(
59
+ modelSource,
60
+ (gltf) => {
61
+ gltf.scene.traverse(function (node) {
62
+ if (node.isMesh || node.isLight) {
63
+ node.castShadow = true;
64
+ node.receiveShadow = true;
65
+ }
66
+ });
67
+ this.scene.add(gltf.scene);
68
+ }
69
+ );
70
+ this.map = map;
71
+
72
+ this.renderer = new THREE.WebGLRenderer({
73
+ canvas: map.getCanvas(),
74
+ context: gl,
75
+ antialias: true
76
+ });
77
+ this.renderer.shadowMap.enabled = true;
78
+ this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
79
+
80
+ this.renderer.autoClear = false;
81
+ },
82
+ render(gl, args) {
83
+ const rotationX = new THREE.Matrix4().makeRotationAxis(
84
+ new THREE.Vector3(1, 0, 0),
85
+ modelTransform.rotateX
86
+ );
87
+ const rotationY = new THREE.Matrix4().makeRotationAxis(
88
+ new THREE.Vector3(0, 1, 0),
89
+ modelTransform.rotateY
90
+ );
91
+ const rotationZ = new THREE.Matrix4().makeRotationAxis(
92
+ new THREE.Vector3(0, 0, 1),
93
+ modelTransform.rotateZ
94
+ );
95
+
96
+ const m = new THREE.Matrix4().fromArray(args.defaultProjectionData.mainMatrix);
97
+ const l = new THREE.Matrix4()
98
+ .makeTranslation(
99
+ modelTransform.translateX,
100
+ modelTransform.translateY,
101
+ modelTransform.translateZ
102
+ )
103
+ .scale(
104
+ new THREE.Vector3(
105
+ modelTransform.scale,
106
+ -modelTransform.scale,
107
+ modelTransform.scale
108
+ )
109
+ )
110
+ .multiply(rotationX)
111
+ .multiply(rotationY)
112
+ .multiply(rotationZ);
113
+
114
+ this.camera.projectionMatrix = m.multiply(l);
115
+ this.renderer.resetState();
116
+ this.renderer.render(this.scene, this.camera);
117
+ this.map.triggerRepaint();
118
+ }
119
+ };
120
+ }
121
+
122
+ function createAssetLayerBabylon(options) {
123
+ const {map, modelSource, modelOrigin, modelRotate, unitToMeter} = options;
124
+ const worldAltitude = 0;
125
+
126
+ const BABYLON = window.BABYLON;
127
+ // +x east, +y up, +z north
128
+ // const modelRotate = [Math.PI / 2, 0, 0];
129
+ // Maplibre.js default coordinate system (no rotations)
130
+ // +x east, -y north, +z up
131
+ //var worldRotate = [0, 0, 0];
132
+
133
+ const worldOriginMercator = maplibregl.MercatorCoordinate.fromLngLat(
134
+ modelOrigin,
135
+ worldAltitude
136
+ );
137
+ const modelScale = worldOriginMercator.meterInMercatorCoordinateUnits()*unitToMeter;
138
+ const modelTransform = {
139
+ translateX: worldOriginMercator.x,
140
+ translateY: worldOriginMercator.y-25*modelScale,
141
+ translateZ: worldOriginMercator.z+35*modelScale,
142
+ rotateX: modelRotate[0],
143
+ rotateY: modelRotate[1],
144
+ rotateZ: modelRotate[2],
145
+ scale: modelScale
146
+ };
147
+
148
+ // Calculate world matrix
149
+ const worldMatrix = BABYLON.Matrix.Compose(
150
+ new BABYLON.Vector3(modelScale, modelScale, modelScale),
151
+ BABYLON.Quaternion.FromEulerAngles(
152
+ modelRotate[0],
153
+ modelRotate[1],
154
+ modelRotate[2]
155
+ ),
156
+ new BABYLON.Vector3(
157
+ worldOriginMercator.x,
158
+ worldOriginMercator.y,
159
+ worldOriginMercator.z
160
+ )
161
+ );
162
+
163
+ return {
164
+ id: '3d-model',
165
+ type: 'custom',
166
+ renderingMode: '3d',
167
+ onAdd (map, gl) {
168
+ this.engine = new BABYLON.Engine(
169
+ gl,
170
+ true,
171
+ {
172
+ useHighPrecisionMatrix: true // Important to prevent jitter at mercator scale
173
+ },
174
+ true
175
+ );
176
+ this.scene = new BABYLON.Scene(this.engine);
177
+ /**
178
+ * optionally add
179
+ * this.scene.autoClearDepthAndStencil = false
180
+ * and for renderingGroupIds set this individually via
181
+ * this.scene.setRenderingAutoClearDepthStencil(1,false)
182
+ * to allow blending with maplibre scene
183
+ * as documented in https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#reducing-calls-to-glclear
184
+ */
185
+ this.scene.autoClear = false;
186
+ /**
187
+ * use detachControl if you only want to interact with maplibre-gl and do not need pointer events of babylonjs.
188
+ * alternatively exchange this.scene.detachControl() with the following two lines, they will allow bubbling up events to maplibre-gl.
189
+ * this.scene.preventDefaultOnPointerDown = false
190
+ * this.scene.preventDefaultOnPointerUp = false
191
+ * https://doc.babylonjs.com/typedoc/classes/BABYLON.Scene#preventDefaultOnPointerDown
192
+ */
193
+ this.scene.detachControl();
194
+
195
+ this.scene.beforeRender = () => {
196
+ this.engine.wipeCaches(true);
197
+ };
198
+
199
+ // create simple camera (will have its project matrix manually calculated)
200
+ this.camera = new BABYLON.Camera(
201
+ 'Camera',
202
+ new BABYLON.Vector3(0, 0, 0),
203
+ this.scene
204
+ );
205
+
206
+ // create simple light
207
+ const light = new BABYLON.HemisphericLight(
208
+ 'light1',
209
+ new BABYLON.Vector3(0, 0, 100),
210
+ this.scene
211
+ );
212
+ light.intensity = 0.7;
213
+
214
+ // Add debug axes viewer, positioned at origin, 10 meter axis lengths
215
+ new BABYLON.AxesViewer(this.scene, 10);
216
+
217
+ // load GLTF model in to the scene
218
+ BABYLON.SceneLoader.LoadAssetContainerAsync(
219
+ modelSource, '', this.scene
220
+ ).then((modelContainer) => {
221
+ modelContainer.addAllToScene();
222
+
223
+ const rootMesh = modelContainer.createRootMesh();
224
+
225
+ // If using maplibre.js coordinate system (+z up)
226
+ // rootMesh.rotation.x = Math.PI/2
227
+
228
+ // // Create a second mesh
229
+ // const rootMesh2 = rootMesh.clone();
230
+
231
+ // // Position in babylon.js coordinate system
232
+ // rootMesh2.position.x = 25; // +east, meters
233
+ // rootMesh2.position.z = 25; // +north, meters
234
+ });
235
+
236
+ this.map = map;
237
+ },
238
+ render (gl, args) {
239
+ const cameraMatrix = BABYLON.Matrix.FromArray(args.defaultProjectionData.mainMatrix);
240
+
241
+ // world-view-projection matrix
242
+ const wvpMatrix = worldMatrix.multiply(cameraMatrix);
243
+
244
+ this.camera.freezeProjectionMatrix(wvpMatrix);
245
+
246
+ this.scene.render(false);
247
+ this.map.triggerRepaint();
248
+ }
249
+ };
250
+
251
+ }
252
+
253
+ /*
254
+ * Helper function used to get threejs-scene-coordinates from mercator coordinates.
255
+ * This is just a quick and dirty solution - it won't work if points are far away from each other
256
+ * because a meter near the north-pole covers more mercator-units
257
+ * than a meter near the equator.
258
+ */
259
+ function calculateDistanceMercatorToMeters(from, to) {
260
+ const mercatorPerMeter = from.meterInMercatorCoordinateUnits();
261
+ // mercator x: 0=west, 1=east
262
+ const dEast = to.x - from.x;
263
+ const dEastMeter = dEast / mercatorPerMeter;
264
+ // mercator y: 0=north, 1=south
265
+ const dNorth = from.y - to.y;
266
+ const dNorthMeter = dNorth / mercatorPerMeter;
267
+ return {dEastMeter, dNorthMeter};
268
+ }
269
+
270
+ const div = document.querySelector('#map');
271
+ const modelOrigin = JSON.parse(div.dataset.location); // [-124.1014, 40.50303];
272
+ var modelSource = undefined;
273
+ if (div.dataset.renderSource)
274
+ modelSource = div.dataset.renderSource;
275
+ else
276
+ modelSource = div.dataset.renderInline;
277
+
278
+ const unitToMeter = 1/3.2808;
279
+
280
+ const MAPTILER_KEY = 'get_your_own_OpIi9ZULNHzrESv6T2vL';
281
+ const mapid = 'winter'; // 'dataviz'; // 'basic-v2'; // 'aquarelle';
282
+ const map = (window.map = new maplibregl.Map({
283
+ container: 'map',
284
+ style: `https://api.maptiler.com/maps/${mapid}/style.json?key=${MAPTILER_KEY}`,
285
+ zoom: 18,
286
+ center: modelOrigin,
287
+ zoom: 18,
288
+ maxZoom: 30,
289
+ maxPitch: 85,
290
+ pitch: 77,
291
+ // create the gl context with MSAA antialiasing, so custom layers are antialiased
292
+ canvasContextAttributes: {antialias: true}
293
+ }));
294
+
295
+ // Make interaction the same as THREE OrbitControls
296
+ map.dragPan.disable();
297
+ map.dragRotate.enable({ pitchWithRotate: true });
298
+ map.scrollZoom.enable({ around: 'pointer' });
299
+ map.dragPan.enable({
300
+ deceleration: 2000, // px/s²
301
+ linearity: 0.3, // lower = snappier stop
302
+ maxSpeed: 2000
303
+ });
304
+ map.scrollZoom.setWheelZoomRate(1/600); // slower mouse‐wheel zoom
305
+ map.keyboard.enable(); // arrow keys to pan/zoom
306
+ map.touchZoomRotate.enable(); // two-finger pinch & rotate
307
+
308
+
309
+ //
310
+ // Add Buildings
311
+ //
312
+
313
+ // The 'building' layer in the streets vector source contains building-height
314
+ // data from OpenStreetMap.
315
+ map.on('load', () => {
316
+ // Insert the layer beneath any symbol layer.
317
+ const layers = map.getStyle().layers;
318
+
319
+ let labelLayerId;
320
+ for (let i = 0; i < layers.length; i++) {
321
+ if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
322
+ labelLayerId = layers[i].id;
323
+ break;
324
+ }
325
+ }
326
+
327
+ map.addSource('openmaptiles', {
328
+ url: `https://api.maptiler.com/tiles/v3/tiles.json?key=${MAPTILER_KEY}`,
329
+ type: 'vector',
330
+ });
331
+
332
+ map.addLayer(
333
+ {
334
+ 'id': '3d-buildings',
335
+ 'source': 'openmaptiles',
336
+ 'source-layer': 'building',
337
+ 'type': 'fill-extrusion',
338
+ 'minzoom': 15,
339
+ 'filter': ['!=', ['get', 'hide_3d'], true],
340
+ 'paint': {
341
+ 'fill-extrusion-color': [
342
+ 'interpolate',
343
+ ['linear'],
344
+ ['get', 'render_height'], 0, 'lightgray', 200, 'royalblue', 400, 'lightblue'
345
+ ],
346
+ 'fill-extrusion-height': [
347
+ 'interpolate',
348
+ ['linear'],
349
+ ['zoom'],
350
+ 15,
351
+ 0,
352
+ 16,
353
+ ['get', 'render_height']
354
+ ],
355
+ 'fill-extrusion-base': ['case',
356
+ ['>=', ['get', 'zoom'], 16],
357
+ ['get', 'render_min_height'], 0
358
+ ]
359
+ }
360
+ },
361
+ labelLayerId
362
+ );
363
+ });
364
+
365
+
366
+ //
367
+ // Add Asset
368
+ //
369
+ const worldAltitude = 0;
370
+ // +x east, +y up, +z north
371
+ const modelRotate = [Math.PI / 2, 0, 0];
372
+ // Maplibre.js default coordinate system (no rotations)
373
+ // +x east, -y north, +z up
374
+ // const modelRotate = [0, 0, 0];
375
+
376
+ map.on('style.load', () => {
377
+ {% if viewer == "three" %}
378
+ map.addLayer(createAssetLayerThreeJS({
379
+ {% else %}
380
+ map.addLayer(createAssetLayerBabylon({
381
+ {% endif %}
382
+ map,
383
+ modelSource,
384
+ modelOrigin,
385
+ modelRotate,
386
+ unitToMeter
387
+ }));
388
+ });
@@ -263,6 +263,7 @@ document.addEventListener("DOMContentLoaded", () => {
263
263
  });
264
264
  });
265
265
  </script>
266
+
266
267
  <script type="module">
267
268
  {% include "sensors/render-sensors.js" %}
268
269
 
@@ -1,9 +1,13 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <!--
4
- *--------------------------------------------------------
5
- * BRACE2 - by PEER
6
- *--------------------------------------------------------
4
+ ===----------------------------------------------------------------------===
5
+
6
+ STAIRLab -- STructural Artificial Intelligence Laboratory
7
+
8
+ ===----------------------------------------------------------------------===
9
+ BRACE2 - by PEER
10
+ ===----------------------------------------------------------------------===
7
11
  -->
8
12
  <head>
9
13
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -14,7 +18,6 @@
14
18
  window.dataLayer = window.dataLayer || [];
15
19
  function gtag(){dataLayer.push(arguments);}
16
20
  gtag('js', new Date());
17
-
18
21
  gtag('config', 'G-TFW5X9DYND');
19
22
  </script>
20
23
  {% endcomment %}
@@ -43,11 +46,12 @@
43
46
  <link type="text/css" href="{{ ASSETS_ROOT }}/css/brace.css" media="screen" rel="stylesheet">
44
47
 
45
48
  {% block stylesheets %}{% endblock stylesheets %}
46
-
47
49
  </head>
50
+
48
51
  <body class="g-sidenav-show">
52
+
49
53
  {% include 'includes/sidebar.html' %}
50
-
54
+
51
55
  <main class="content">
52
56
 
53
57
  {# include 'includes/navigation.html' #}
@@ -1,4 +1,14 @@
1
1
  {% extends "layouts/base.html" %}
2
+ {% comment %}
3
+ <!--
4
+ ===----------------------------------------------------------------------===#
5
+
6
+ STAIRLab -- STructural Artificial Intelligence Laboratory
7
+
8
+ ===----------------------------------------------------------------------===#
9
+ -->
10
+ {% endcomment}
11
+
2
12
  {% block title %} {{ asset.calid }} | Upload {% endblock %}
3
13
 
4
14
  {% block stylesheets %}
@@ -42,7 +52,7 @@
42
52
  <form method="POST" enctype="multipart/form-data">
43
53
  {% csrf_token %}
44
54
  {{ form.as_p}}
45
- <button id="render" type="button" class="btn btn-outline-primary" >Validate</button>
55
+ <button id="render" type="button" class="btn btn-outline-primary" >Render</button>
46
56
  <button type="submit" class="btn btn-primary" name="action" value="commit">Submit</button>
47
57
  </form>
48
58
  </div>
irie/maps.py ADDED
@@ -0,0 +1,101 @@
1
+
2
+ import folium
3
+ import numpy as np
4
+
5
+ class AssetMap:
6
+
7
+ def __init__(self, assets, name=None, colors=None, color_name=None):
8
+ if name is None:
9
+ name = "Assets"
10
+
11
+ if colors is not None and len(assets)>0 and len(colors) > 0:
12
+ cm = folium.branca.colormap.LinearColormap(colors=["green", "yellow", "orange", "red"],
13
+ vmin=0, vmax=max(colors.values()),
14
+ caption=color_name)
15
+ colors = {
16
+ k: cm.rgb_hex_str(v) for k,v in colors.items()
17
+ }
18
+ else:
19
+ colors = None
20
+ cm = None
21
+
22
+ markers = self.add_bridges(assets, colors=colors)
23
+
24
+ if len(markers) > 0:
25
+ location = sum(np.array(m.location) for m in markers) / len(markers)
26
+ else:
27
+ location = [37.7735, -122.0993] # (self._preferences.latitude, self._preferences.longitude)
28
+
29
+ self._map = m = folium.Map(
30
+ location=location,
31
+ zoom_start=6,
32
+ tiles='cartodbpositron'
33
+ )
34
+
35
+ if cm is not None:
36
+ cm.add_to(m)
37
+
38
+ for marker in markers:
39
+ marker.add_to(m)
40
+
41
+
42
+ def get_html(self, **kwargs):
43
+ return self._map._repr_html_()
44
+
45
+
46
+ def add_bridges(self, assets, colors=None):
47
+ if colors is None:
48
+ colors = {}
49
+
50
+ markers = []
51
+ top_markers = []
52
+ for b in assets:
53
+ lat, lon = b.coordinates
54
+ if lat is None or lon is None:
55
+ continue
56
+
57
+ popup = folium.Popup(
58
+ folium.Html(
59
+ '<a style="display: inline;" target="_blank" href="/inventory/{calid}/">{label}</a>'.format(
60
+ calid=b.calid,
61
+ label=b.calid
62
+ ),
63
+ script=True
64
+ ),
65
+ min_width= 50,
66
+ max_width=100
67
+ )
68
+
69
+ marker = folium.CircleMarker(
70
+ location=[lat, lon],
71
+ popup=popup,
72
+ color = "blue" if b.is_complete else "black",
73
+ fill_color=colors.get(b.id, "blue" if b.is_complete else "gray"),
74
+ fill=True,
75
+ opacity=1,
76
+ fill_opacity=1,
77
+ radius=2,
78
+ weight=1,
79
+ z_index_offset=10 if b.is_complete else 100000
80
+ )
81
+
82
+ if b.is_complete:
83
+ marker = folium.Marker(
84
+ location=[lat, lon],
85
+ popup=popup,
86
+ icon=folium.Icon(icon="cloud", color="blue" if not b.is_complete else "beige"),
87
+ z_index_offset=1000
88
+ )
89
+ top_markers.append(marker)
90
+
91
+ elif b.calid in {"33-0526G", "33-0395L", "33-0525G", "33-0189L", "33-0523K", "33-0443", "33-0202F", "33-0202R", "33-0524F"}:
92
+ pass
93
+
94
+ else:
95
+ markers.append(marker)
96
+
97
+ markers.extend(top_markers)
98
+ return markers
99
+
100
+ # top_markers.extend(markers)
101
+ # return top_markers
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: irie
3
- Version: 0.0.56
3
+ Version: 0.0.58
4
4
  Summary: An infrastructure resilience engine
5
5
  Author-email: "Claudio M. Perez" <50180406+claudioperez@users.noreply.github.com>
6
6
  Project-URL: Repository, https://github.com/STAIRLab
7
7
  Project-URL: Documentation, https://stairlab.berkeley.edu/software/irie/
8
- Keywords: visualization,seismic,opensees,resilience,post-processing,structural-health-monitoring,finite-element-analysis,glTF
8
+ Keywords: resilience,structural-health-monitoring,finite-element-analysis,xara
9
9
  Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Intended Audience :: Science/Research
11
11
  Classifier: Intended Audience :: Developers
@@ -27,15 +27,14 @@ Classifier: Operating System :: Unix
27
27
  Classifier: Operating System :: MacOS
28
28
  Description-Content-Type: text/markdown
29
29
  Requires-Dist: tqdm
30
- Requires-Dist: opensees
30
+ Requires-Dist: opensees>=0.1.0
31
31
  Requires-Dist: quakeio
32
32
  Requires-Dist: mdof
33
- Requires-Dist: veux
33
+ Requires-Dist: veux>=0.0.35
34
34
  Requires-Dist: xara
35
- Requires-Dist: bottle
36
- Requires-Dist: openbim
37
- Requires-Dist: xsection
38
35
  Requires-Dist: xcsi
36
+ Requires-Dist: xsection>=0.0.19
37
+ Requires-Dist: openbim
39
38
  Requires-Dist: folium
40
39
  Requires-Dist: pandas
41
40
  Requires-Dist: numpy