irie 0.0.41__py3-none-any.whl → 0.0.43__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 (56) hide show
  1. irie/apps/inventory/archive/CESMD.py +0 -0
  2. irie/apps/inventory/filters.py +1 -1
  3. irie/apps/inventory/models.py +27 -0
  4. irie/apps/inventory/services/render.py +0 -0
  5. irie/apps/inventory/urls.py +3 -0
  6. irie/apps/inventory/views.py +57 -0
  7. irie/apps/prediction/forms.py +2 -1
  8. irie/apps/prediction/models.py +24 -0
  9. irie/apps/prediction/runners/hazus.py +33 -19
  10. irie/apps/prediction/urls.py +5 -3
  11. irie/apps/prediction/views.py +101 -8
  12. irie/apps/static/assets/css/brace.css +0 -33
  13. irie/apps/static/assets/css/brace.css.map +1 -1
  14. irie/apps/static/assets/css/brace.min.css +1 -1
  15. irie/apps/static/assets/js/brace.js +2 -1
  16. irie/apps/templates/includes/scripts.html +10 -1
  17. irie/apps/templates/includes/sidebar.html +19 -11
  18. irie/apps/templates/inventory/asset-on-map.html +457 -0
  19. irie/apps/templates/inventory/asset-profile.html +1 -2
  20. irie/apps/templates/inventory/map-inventory.html +136 -0
  21. irie/apps/templates/inventory/map-inventory2.html +143 -0
  22. irie/apps/templates/inventory/map-single-asset.html +0 -0
  23. irie/apps/templates/inventory/map-single-asset2.html +618 -0
  24. irie/apps/templates/inventory/map-terrain.html +214 -0
  25. irie/apps/templates/inventory/sensor-upload.html +1 -0
  26. irie/apps/templates/inventory/three-maps.html +229 -0
  27. irie/apps/templates/layouts/base.html +2 -1
  28. irie/apps/templates/prediction/predictor-upload.html +68 -22
  29. irie/apps/templates/site/index.html +36 -27
  30. irie/apps/templates/site/page-400-sidebar.html +31 -0
  31. irie/apps/templates/site/page-400.html +29 -0
  32. irie/apps/templates/site/page-404-sidebar.html +1 -1
  33. irie/apps/templates/site/page-404.html +1 -1
  34. irie/fhwa/__init__.py +132 -0
  35. irie/fhwa/__main__.py +79 -0
  36. irie/fhwa/fields/nbi001.py +61 -0
  37. irie/fhwa/fields/nbi001b.py +1 -0
  38. irie/fhwa/fields/nbi002.py +0 -0
  39. irie/fhwa/fields.py +32 -0
  40. irie/init/__main__.py +0 -4
  41. irie/init/calid.py +86 -3
  42. irie/init/getNBIData.py +1 -1
  43. irie/init/getNBIData2.py +304 -0
  44. irie/init/management/commands/init_assets.py +11 -11
  45. irie/init/management/commands/init_predictors.py +1 -1
  46. irie/init/management/commands/make_asset.py +0 -0
  47. irie/pull/nbi.py +304 -0
  48. {irie-0.0.41.dist-info → irie-0.0.43.dist-info}/METADATA +1 -1
  49. {irie-0.0.41.dist-info → irie-0.0.43.dist-info}/RECORD +53 -36
  50. {irie-0.0.41.dist-info → irie-0.0.43.dist-info}/WHEEL +1 -1
  51. irie/apps/inventory/CESMD.py +0 -81
  52. irie/apps/inventory/archive/arcGIS.py +0 -1175
  53. irie/apps/inventory/traffic.py +0 -175052
  54. /irie/apps/inventory/{calid.py → archive/calid.py} +0 -0
  55. {irie-0.0.41.dist-info → irie-0.0.43.dist-info}/entry_points.txt +0 -0
  56. {irie-0.0.41.dist-info → irie-0.0.43.dist-info}/top_level.txt +0 -0
@@ -91,7 +91,7 @@ document.addEventListener("DOMContentLoaded", function(event) {
91
91
  el.style.color = 'url(' + el.getAttribute('data-color') + ')';
92
92
  });
93
93
 
94
- //Tooltips
94
+ // Tooltips
95
95
  var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
96
96
  var tooltipList = tooltipTriggerList.map(
97
97
  function (tooltipTriggerEl) {
@@ -681,6 +681,7 @@ window.addEventListener('resize', function(event) {
681
681
 
682
682
  }
683
683
  });
684
+
684
685
  } else {
685
686
  total.forEach(function(item, i) {
686
687
  if (item.classList.contains('on-resize')) {
@@ -2,6 +2,15 @@
2
2
  <!-- Core -->
3
3
  <script src="{{ ASSETS_ROOT }}/vendor/@popperjs/core/dist/umd/popper.min.js"></script>
4
4
  <script src="{{ ASSETS_ROOT }}/vendor/bootstrap/dist/js/bootstrap.min.js"></script>
5
+ <script>
6
+ var win = navigator.platform.indexOf('Win') > -1;
7
+ if (win && document.querySelector('#sidenav-scrollbar')) {
8
+ var options = {
9
+ damping: '0.5'
10
+ }
11
+ Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
12
+ }
13
+ </script>
5
14
 
6
15
  {% comment %}
7
16
  <script src="{{ ASSETS_ROOT }}/vendor/onscreen/dist/on-screen.umd.min.js"></script>
@@ -18,7 +27,7 @@
18
27
  <script src="{{ ASSETS_ROOT }}/vendor/notyf/notyf.min.js"></script>
19
28
 
20
29
  <!-- Simplebar -->
21
- <script src="{{ ASSETS_ROOT }}/vendor/simplebar/dist/simplebar.min.js"></script>
30
+ <!-- <script src="{{ ASSETS_ROOT }}/vendor/simplebar/dist/simplebar.min.js"></script> -->
22
31
 
23
32
  <!-- Github buttons -->
24
33
  <script async defer src="https://buttons.github.io/buttons.js"></script>
@@ -1,9 +1,16 @@
1
1
 
2
- <nav class="navbar navbar-theme-primary navbar-dark px-4 col-12 d-lg-none">
2
+ <nav class="navbar navbar-theme-secondary navbar-dark px-4 col-12 d-lg-none">
3
3
  <a class="navbar-brand me-lg-5" href="/">
4
4
  <img class="navbar-brand-light" src="{{ ASSETS_ROOT }}/img/brace2-no_text.png" alt="BRACE2 logo" />
5
5
  </a>
6
6
  <div class="d-flex align-items-center">
7
+ <a href="javascript:;" class="nav-link text-body p-0" id="iconNavbarSidenav">
8
+ <div class="sidenav-toggler-inner">
9
+ <i class="sidenav-toggler-line"></i>
10
+ <i class="sidenav-toggler-line"></i>
11
+ <i class="sidenav-toggler-line"></i>
12
+ </div>
13
+ </a>
7
14
  <!-- <button class="navbar-toggler d-lg-none collapsed" type="button" -->
8
15
  <button class="navbar-toggler collapsed" type="button"
9
16
  data-bs-toggle="collapse"
@@ -15,16 +22,16 @@
15
22
  </nav>
16
23
 
17
24
  <!-- <nav id="sidebarMenu" class="sidebar d-lg-block bg-gray-800 text-white collapse" data-simplebar> -->
18
- <aside id="sidebarMenu" class="sidebar d-lg-block collapse bg-white ms-2 my-2 navbar-vertical navbar-expand-xs" data-simplebar>
19
- <div class="sidebar-inner px-4 pt-3">
25
+ <aside id="sidenav-main" style="z-index: 1;" class="sidebar navbar navbar-vertical navbar-expand-xs d-lg-block collapse bg-white ms-2 my-2 fixed-start">
26
+ <!-- <div class="sidebar-inner px-4 pt-3"> -->
27
+ <div class="collapse navbar-collapse sidebar-inner px-4 pt-3 w-auto" id="sidenav-collapse-main">
28
+ {% comment %}
20
29
  <div class="user-card d-flex d-md-none align-items-center justify-content-between justify-content-md-center pb-4">
21
30
  <div class="d-flex align-items-center">
22
- {% comment %}
23
31
  <div class="avatar-lg me-4">
24
32
  <img src="{{ ASSETS_ROOT }}/img/team/profile-picture-3.jpg" class="card-img-top rounded-circle border-white"
25
33
  alt="Profile picture">
26
34
  </div>
27
- {% endcomment %}
28
35
  <div class="d-block">
29
36
  <a href="/page-sign-in.html" class="btn btn-secondary btn-sm d-inline-flex align-items-center">
30
37
  <svg class="icon icon-xxs me-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"></path></svg>
@@ -40,9 +47,10 @@
40
47
  </a>
41
48
  </div>
42
49
  </div>
43
- <ul class="nav flex-column pt-3 pt-md-0">
50
+ {% endcomment %}
51
+ <ul class="nav navbar-nav flex-column pt-3 pt-md-0">
44
52
  <li class="nav-item">
45
- <a href="/" class="nav-link d-flex align-items-center">
53
+ <a href="/" class="nav-link d-flex align-items-center" data-bs-toggle="collapse">
46
54
  <span class="sidebar-icon">
47
55
  <img src="{{ ASSETS_ROOT }}/img/brace2-no_text.png" height="20" width="20" alt="BRACE2 Logo">
48
56
  </span>
@@ -53,7 +61,7 @@
53
61
 
54
62
  <li role="separator" class="dropdown-divider mt-2 mb-2 border-gray-700"></li>
55
63
 
56
- <li class="nav-item {% if 'dashboard' in segment %} active {% endif %}">
64
+ <li class="nav-item {% if 'dashboard' in segment %} active {% endif %}" data-bs-toggle="collapse">
57
65
  <a href="{% url 'dashboard' %}" class="nav-link">
58
66
  <span class="sidebar-icon">
59
67
  <svg class="icon icon-xs me-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2 10a8 8 0 018-8v8h8a8 8 0 11-16 0z"></path><path d="M12 2.252A8.014 8.014 0 0117.748 8H12V2.252z"></path></svg>
@@ -62,9 +70,9 @@
62
70
  </a>
63
71
  </li>
64
72
 
65
- <li class="nav-item {% if 'events' in segment %} active {% endif %}">
73
+ <li class="nav-item {% if 'events' in segment %} active {% endif %}" data-bs-toggle="collapse">
66
74
  <span
67
- class="nav-link collapsed d-flex justify-content-between align-items-center"
75
+ class="nav-link collapsed d-flex justify-content-between align-items-center"
68
76
  data-bs-toggle="collapse" data-bs-target="#submenu-events">
69
77
  <span>
70
78
  <span class="sidebar-icon">
@@ -89,7 +97,7 @@
89
97
  </div>
90
98
  </li>
91
99
 
92
- <li class="nav-item {% if 'assets' in segment %} active {% endif %}">
100
+ <li class="nav-item text-dark {% if 'assets' in segment %} active {% endif %}" data-bs-toggle="collapse">
93
101
  <a href="{% url 'asset_table' %}" class="nav-link">
94
102
  <span class="sidebar-icon">
95
103
  <svg class="icon icon-xs me-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z"></path><path fill-rule="evenodd" d="M18 9H2v5a2 2 0 002 2h12a2 2 0 002-2V9zM4 13a1 1 0 011-1h1a1 1 0 110 2H5a1 1 0 01-1-1zm5-1a1 1 0 100 2h1a1 1 0 100-2H9z" clip-rule="evenodd"></path></svg>
@@ -0,0 +1,457 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Test Maps</title>
5
+ <meta property="og:description" content="Use a custom style layer with babylon.js to add a 3D model to the map." />
6
+ <meta charset='utf-8'>
7
+ <meta name="viewport" content="width=device-width, initial-scale=1">
8
+ <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.2.0/dist/maplibre-gl.css' />
9
+ <script src='https://unpkg.com/maplibre-gl@5.2.0/dist/maplibre-gl.js'></script>
10
+ <style>
11
+ body { margin: 0; padding: 0; }
12
+ html, body, #map { height: 100%; }
13
+ </style>
14
+ {% if viewer == "three" %}
15
+ <script type="importmap">
16
+ {
17
+ "imports": {
18
+ "three": "https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js",
19
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
20
+ }
21
+ }
22
+ </script>
23
+ {% else %}
24
+ <script src="https://unpkg.com/babylonjs@5.42.2/babylon.js"></script>
25
+ <script src="https://unpkg.com/babylonjs-loaders@5.42.2/babylonjs.loaders.min.js"></script>
26
+ {% endif %}
27
+ </head>
28
+ <body>
29
+ <div id="map" data-location="{{ location }}"
30
+ {% if render_src %}
31
+ data-render-source="{{ render_src }}"
32
+ {% else %}
33
+ data-render-inline="{{ render_glb }}"
34
+ {% endif %}
35
+ >
36
+ </div>
37
+
38
+
39
+ {% if viewer == "three" %}
40
+ <script type="module">
41
+ import * as THREE from 'three';
42
+ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
43
+ {% else %}
44
+ <script>
45
+ {% endif %}
46
+ function createAssetLayerThreeJS(options) {
47
+ const {map, modelSource, modelOrigin, modelRotate, unitToMeter} = options;
48
+ const modelAltitude = 0;
49
+ const modelCoord = maplibregl.MercatorCoordinate.fromLngLat(
50
+ modelOrigin,
51
+ modelAltitude
52
+ );
53
+ const modelScale = modelCoord.meterInMercatorCoordinateUnits()*unitToMeter;
54
+ const modelTransform = {
55
+ translateX: modelCoord.x,
56
+ translateY: modelCoord.y, //-25*modelScale,
57
+ translateZ: modelCoord.z+100*modelScale, // 35
58
+ rotateX: modelRotate[0],
59
+ rotateY: modelRotate[1],
60
+ rotateZ: modelRotate[2],
61
+ scale: modelScale
62
+ };
63
+
64
+ return {
65
+ id: '3d-model',
66
+ type: 'custom',
67
+ renderingMode: '3d',
68
+ onAdd(map, gl) {
69
+ this.camera = new THREE.Camera();
70
+ this.scene = new THREE.Scene();
71
+
72
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
73
+ directionalLight.position.set(100, 100, 100);
74
+ directionalLight.castShadow = true;
75
+ this.scene.add(directionalLight);
76
+
77
+ directionalLight.shadow.camera.near = 0.1;
78
+ directionalLight.shadow.camera.far = 2000;
79
+ directionalLight.shadow.camera.left = -50000; // was 500
80
+ directionalLight.shadow.camera.right = 50000; // was 500
81
+ directionalLight.shadow.camera.top = 50000; // was 500
82
+ directionalLight.shadow.camera.bottom = -50000; // was 500
83
+
84
+ directionalLight.shadow.mapSize.width = 4096;
85
+ directionalLight.shadow.mapSize.height = 4096;
86
+
87
+ const groundGeometry = new THREE.PlaneGeometry(5000, 5000);
88
+ const groundMaterial = new THREE.ShadowMaterial({ opacity: 0.3 });
89
+ const ground = new THREE.Mesh(groundGeometry, groundMaterial);
90
+ ground.rotation.x = -Math.PI / 2;
91
+ ground.position.y = - 100; // 35;
92
+ ground.receiveShadow = true;
93
+ this.scene.add(ground);
94
+
95
+ const loader = new GLTFLoader();
96
+ loader.load(
97
+ modelSource,
98
+ (gltf) => {
99
+ gltf.scene.traverse(function (node) {
100
+ if (node.isMesh || node.isLight) {
101
+ node.castShadow = true;
102
+ node.receiveShadow = true;
103
+ }
104
+ });
105
+ this.scene.add(gltf.scene);
106
+ }
107
+ );
108
+ this.map = map;
109
+
110
+ this.renderer = new THREE.WebGLRenderer({
111
+ canvas: map.getCanvas(),
112
+ context: gl,
113
+ antialias: true
114
+ });
115
+ this.renderer.shadowMap.enabled = true;
116
+ this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
117
+
118
+ this.renderer.autoClear = false;
119
+ },
120
+ render(gl, args) {
121
+ const rotationX = new THREE.Matrix4().makeRotationAxis(
122
+ new THREE.Vector3(1, 0, 0),
123
+ modelTransform.rotateX
124
+ );
125
+ const rotationY = new THREE.Matrix4().makeRotationAxis(
126
+ new THREE.Vector3(0, 1, 0),
127
+ modelTransform.rotateY
128
+ );
129
+ const rotationZ = new THREE.Matrix4().makeRotationAxis(
130
+ new THREE.Vector3(0, 0, 1),
131
+ modelTransform.rotateZ
132
+ );
133
+
134
+ const m = new THREE.Matrix4().fromArray(args.defaultProjectionData.mainMatrix);
135
+ const l = new THREE.Matrix4()
136
+ .makeTranslation(
137
+ modelTransform.translateX,
138
+ modelTransform.translateY,
139
+ modelTransform.translateZ
140
+ )
141
+ .scale(
142
+ new THREE.Vector3(
143
+ modelTransform.scale,
144
+ -modelTransform.scale,
145
+ modelTransform.scale
146
+ )
147
+ )
148
+ .multiply(rotationX)
149
+ .multiply(rotationY)
150
+ .multiply(rotationZ);
151
+
152
+ this.camera.projectionMatrix = m.multiply(l);
153
+ this.renderer.resetState();
154
+ this.renderer.render(this.scene, this.camera);
155
+ this.map.triggerRepaint();
156
+ }
157
+ };
158
+ }
159
+
160
+ function createAssetLayerBabylon(options) {
161
+ const {map, modelSource, modelOrigin, modelRotate, unitToMeter} = options;
162
+ const worldAltitude = 0;
163
+
164
+ const BABYLON = window.BABYLON;
165
+ // +x east, +y up, +z north
166
+ // const modelRotate = [Math.PI / 2, 0, 0];
167
+ // Maplibre.js default coordinate system (no rotations)
168
+ // +x east, -y north, +z up
169
+ //var worldRotate = [0, 0, 0];
170
+
171
+ const worldOriginMercator = maplibregl.MercatorCoordinate.fromLngLat(
172
+ modelOrigin,
173
+ worldAltitude
174
+ );
175
+ const modelScale = worldOriginMercator.meterInMercatorCoordinateUnits()*unitToMeter;
176
+ const modelTransform = {
177
+ translateX: worldOriginMercator.x,
178
+ translateY: worldOriginMercator.y-25*modelScale,
179
+ translateZ: worldOriginMercator.z+35*modelScale,
180
+ rotateX: modelRotate[0],
181
+ rotateY: modelRotate[1],
182
+ rotateZ: modelRotate[2],
183
+ scale: modelScale
184
+ };
185
+
186
+ // Calculate world matrix
187
+ const worldMatrix = BABYLON.Matrix.Compose(
188
+ new BABYLON.Vector3(modelScale, modelScale, modelScale),
189
+ BABYLON.Quaternion.FromEulerAngles(
190
+ modelRotate[0],
191
+ modelRotate[1],
192
+ modelRotate[2]
193
+ ),
194
+ new BABYLON.Vector3(
195
+ worldOriginMercator.x,
196
+ worldOriginMercator.y,
197
+ worldOriginMercator.z
198
+ )
199
+ );
200
+
201
+ return {
202
+ id: '3d-model',
203
+ type: 'custom',
204
+ renderingMode: '3d',
205
+ onAdd (map, gl) {
206
+ this.engine = new BABYLON.Engine(
207
+ gl,
208
+ true,
209
+ {
210
+ useHighPrecisionMatrix: true // Important to prevent jitter at mercator scale
211
+ },
212
+ true
213
+ );
214
+ this.scene = new BABYLON.Scene(this.engine);
215
+ /**
216
+ * optionally add
217
+ * this.scene.autoClearDepthAndStencil = false
218
+ * and for renderingGroupIds set this individually via
219
+ * this.scene.setRenderingAutoClearDepthStencil(1,false)
220
+ * to allow blending with maplibre scene
221
+ * as documented in https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#reducing-calls-to-glclear
222
+ */
223
+ this.scene.autoClear = false;
224
+ /**
225
+ * use detachControl if you only want to interact with maplibre-gl and do not need pointer events of babylonjs.
226
+ * alternatively exchange this.scene.detachControl() with the following two lines, they will allow bubbling up events to maplibre-gl.
227
+ * this.scene.preventDefaultOnPointerDown = false
228
+ * this.scene.preventDefaultOnPointerUp = false
229
+ * https://doc.babylonjs.com/typedoc/classes/BABYLON.Scene#preventDefaultOnPointerDown
230
+ */
231
+ this.scene.detachControl();
232
+
233
+ this.scene.beforeRender = () => {
234
+ this.engine.wipeCaches(true);
235
+ };
236
+
237
+ // create simple camera (will have its project matrix manually calculated)
238
+ this.camera = new BABYLON.Camera(
239
+ 'Camera',
240
+ new BABYLON.Vector3(0, 0, 0),
241
+ this.scene
242
+ );
243
+
244
+ // create simple light
245
+ const light = new BABYLON.HemisphericLight(
246
+ 'light1',
247
+ new BABYLON.Vector3(0, 0, 100),
248
+ this.scene
249
+ );
250
+ light.intensity = 0.7;
251
+
252
+ // Add debug axes viewer, positioned at origin, 10 meter axis lengths
253
+ new BABYLON.AxesViewer(this.scene, 10);
254
+
255
+ // load GLTF model in to the scene
256
+ BABYLON.SceneLoader.LoadAssetContainerAsync(
257
+ modelSource, '', this.scene
258
+ ).then((modelContainer) => {
259
+ modelContainer.addAllToScene();
260
+
261
+ const rootMesh = modelContainer.createRootMesh();
262
+
263
+ // If using maplibre.js coordinate system (+z up)
264
+ // rootMesh.rotation.x = Math.PI/2
265
+
266
+ // // Create a second mesh
267
+ // const rootMesh2 = rootMesh.clone();
268
+
269
+ // // Position in babylon.js coordinate system
270
+ // rootMesh2.position.x = 25; // +east, meters
271
+ // rootMesh2.position.z = 25; // +north, meters
272
+ });
273
+
274
+ this.map = map;
275
+ },
276
+ render (gl, args) {
277
+ const cameraMatrix = BABYLON.Matrix.FromArray(args.defaultProjectionData.mainMatrix);
278
+
279
+ // world-view-projection matrix
280
+ const wvpMatrix = worldMatrix.multiply(cameraMatrix);
281
+
282
+ this.camera.freezeProjectionMatrix(wvpMatrix);
283
+
284
+ this.scene.render(false);
285
+ this.map.triggerRepaint();
286
+ }
287
+ };
288
+
289
+ }
290
+
291
+ /*
292
+ * Helper function used to get threejs-scene-coordinates from mercator coordinates.
293
+ * This is just a quick and dirty solution - it won't work if points are far away from each other
294
+ * because a meter near the north-pole covers more mercator-units
295
+ * than a meter near the equator.
296
+ */
297
+ function calculateDistanceMercatorToMeters(from, to) {
298
+ const mercatorPerMeter = from.meterInMercatorCoordinateUnits();
299
+ // mercator x: 0=west, 1=east
300
+ const dEast = to.x - from.x;
301
+ const dEastMeter = dEast / mercatorPerMeter;
302
+ // mercator y: 0=north, 1=south
303
+ const dNorth = from.y - to.y;
304
+ const dNorthMeter = dNorth / mercatorPerMeter;
305
+ return {dEastMeter, dNorthMeter};
306
+ }
307
+
308
+ const div = document.querySelector('#map');
309
+ const modelOrigin = JSON.parse(div.dataset.location); // [-124.1014, 40.50303];
310
+ var modelSource = undefined;
311
+ if (div.dataset.renderSource)
312
+ modelSource = div.dataset.renderSource;
313
+ else
314
+ modelSource = div.dataset.renderInline;
315
+
316
+ const unitToMeter = 1/3.2808;
317
+
318
+ const MAPTILER_KEY = 'get_your_own_OpIi9ZULNHzrESv6T2vL';
319
+ const mapid = 'winter'; // 'dataviz'; // 'basic-v2'; // 'aquarelle';
320
+ const map = (window.map = new maplibregl.Map({
321
+ container: 'map',
322
+ style: `https://api.maptiler.com/maps/${mapid}/style.json?key=${MAPTILER_KEY}`,
323
+ // style: {
324
+ // version: 8,
325
+ // sources: {
326
+ // osm: {
327
+ // type: 'raster',
328
+ // tiles: ['https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'],
329
+ // tileSize: 256,
330
+ // attribution: '&copy; OpenStreetMap Contributors',
331
+ // maxzoom: 19
332
+ // },
333
+ // // Use a different source for terrain and hillshade layers, to improve render quality
334
+ // terrainSource: {
335
+ // type: 'raster-dem',
336
+ // url: 'https://demotiles.maplibre.org/terrain-tiles/tiles.json',
337
+ // tileSize: 256
338
+ // },
339
+ // hillshadeSource: {
340
+ // type: 'raster-dem',
341
+ // url: 'https://demotiles.maplibre.org/terrain-tiles/tiles.json',
342
+ // tileSize: 256
343
+ // }
344
+ // },
345
+ // layers: [
346
+ // {
347
+ // id: 'osm',
348
+ // type: 'raster',
349
+ // source: 'osm'
350
+ // },
351
+ // {
352
+ // id: 'hills',
353
+ // type: 'hillshade',
354
+ // source: 'hillshadeSource',
355
+ // layout: {visibility: 'visible'},
356
+ // paint: {'hillshade-shadow-color': '#473B24'}
357
+ // }
358
+ // ],
359
+ // terrain: {
360
+ // source: 'terrainSource',
361
+ // exaggeration: 1
362
+ // }
363
+ // },
364
+ zoom: 18,
365
+ center: modelOrigin,
366
+ zoom: 18,
367
+ maxZoom: 30,
368
+ maxPitch: 85,
369
+ pitch: 77,
370
+ canvasContextAttributes: {antialias: true} // create the gl context with MSAA antialiasing, so custom layers are antialiased
371
+ }));
372
+
373
+
374
+ //
375
+ // Add Buildings
376
+ //
377
+
378
+ // The 'building' layer in the streets vector source contains building-height
379
+ // data from OpenStreetMap.
380
+ map.on('load', () => {
381
+ // Insert the layer beneath any symbol layer.
382
+ const layers = map.getStyle().layers;
383
+
384
+ let labelLayerId;
385
+ for (let i = 0; i < layers.length; i++) {
386
+ if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
387
+ labelLayerId = layers[i].id;
388
+ break;
389
+ }
390
+ }
391
+
392
+ map.addSource('openmaptiles', {
393
+ url: `https://api.maptiler.com/tiles/v3/tiles.json?key=${MAPTILER_KEY}`,
394
+ type: 'vector',
395
+ });
396
+
397
+ map.addLayer(
398
+ {
399
+ 'id': '3d-buildings',
400
+ 'source': 'openmaptiles',
401
+ 'source-layer': 'building',
402
+ 'type': 'fill-extrusion',
403
+ 'minzoom': 15,
404
+ 'filter': ['!=', ['get', 'hide_3d'], true],
405
+ 'paint': {
406
+ 'fill-extrusion-color': [
407
+ 'interpolate',
408
+ ['linear'],
409
+ ['get', 'render_height'], 0, 'lightgray', 200, 'royalblue', 400, 'lightblue'
410
+ ],
411
+ 'fill-extrusion-height': [
412
+ 'interpolate',
413
+ ['linear'],
414
+ ['zoom'],
415
+ 15,
416
+ 0,
417
+ 16,
418
+ ['get', 'render_height']
419
+ ],
420
+ 'fill-extrusion-base': ['case',
421
+ ['>=', ['get', 'zoom'], 16],
422
+ ['get', 'render_min_height'], 0
423
+ ]
424
+ }
425
+ },
426
+ labelLayerId
427
+ );
428
+ });
429
+
430
+
431
+ //
432
+ // Add Asset
433
+ //
434
+ const worldAltitude = 0;
435
+ // +x east, +y up, +z north
436
+ const modelRotate = [Math.PI / 2, 0, 0];
437
+ // Maplibre.js default coordinate system (no rotations)
438
+ // +x east, -y north, +z up
439
+ // const modelRotate = [0, 0, 0];
440
+
441
+ map.on('style.load', () => {
442
+ {% if viewer == "three" %}
443
+ map.addLayer(createAssetLayerThreeJS({
444
+ {% else %}
445
+ map.addLayer(createAssetLayerBabylon({
446
+ {% endif %}
447
+ map,
448
+ modelSource,
449
+ modelOrigin,
450
+ modelRotate,
451
+ unitToMeter
452
+ }));
453
+ });
454
+ </script>
455
+
456
+ </body>
457
+ </html>
@@ -202,8 +202,7 @@
202
202
  <model-viewer
203
203
  id="viewer"
204
204
  src="{{ asset.rendering }}"
205
- alt="3D Model"
206
- auto-rotate
205
+ alt="3D Model of {{ asset.name }}"
207
206
  camera-controls
208
207
  interaction-prompt="none"
209
208
  camera-orbit="0deg 75deg 2m"