irie 0.0.42__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.
- irie/apps/inventory/archive/CESMD.py +0 -0
- irie/apps/inventory/models.py +27 -0
- irie/apps/inventory/services/render.py +0 -0
- irie/apps/inventory/urls.py +3 -0
- irie/apps/inventory/views.py +57 -0
- irie/apps/prediction/forms.py +2 -1
- irie/apps/prediction/models.py +24 -0
- irie/apps/prediction/urls.py +5 -3
- irie/apps/prediction/views.py +101 -8
- irie/apps/static/assets/css/brace.css +0 -32
- irie/apps/static/assets/css/brace.css.map +1 -1
- irie/apps/static/assets/css/brace.min.css +1 -1
- irie/apps/templates/inventory/asset-on-map.html +457 -0
- irie/apps/templates/inventory/asset-profile.html +1 -2
- irie/apps/templates/inventory/map-inventory.html +136 -0
- irie/apps/templates/inventory/map-inventory2.html +143 -0
- irie/apps/templates/inventory/map-single-asset.html +0 -0
- irie/apps/templates/inventory/map-single-asset2.html +618 -0
- irie/apps/templates/inventory/map-terrain.html +214 -0
- irie/apps/templates/inventory/sensor-upload.html +1 -0
- irie/apps/templates/inventory/three-maps.html +229 -0
- irie/apps/templates/layouts/base.html +1 -0
- irie/apps/templates/prediction/predictor-upload.html +68 -22
- irie/apps/templates/site/index.html +36 -27
- irie/apps/templates/site/page-400-sidebar.html +31 -0
- irie/apps/templates/site/page-400.html +29 -0
- irie/apps/templates/site/page-404-sidebar.html +1 -1
- irie/apps/templates/site/page-404.html +1 -1
- irie/fhwa/__init__.py +132 -0
- irie/fhwa/__main__.py +79 -0
- irie/fhwa/fields/nbi001.py +61 -0
- irie/fhwa/fields/nbi001b.py +1 -0
- irie/fhwa/fields/nbi002.py +0 -0
- irie/fhwa/fields.py +32 -0
- irie/init/__main__.py +0 -4
- irie/init/calid.py +86 -3
- irie/init/getNBIData.py +1 -1
- irie/init/management/commands/init_assets.py +11 -11
- irie/init/management/commands/init_predictors.py +1 -1
- irie/init/management/commands/make_asset.py +0 -0
- {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/METADATA +1 -1
- {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/RECORD +46 -31
- {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/WHEEL +1 -1
- irie/apps/inventory/CESMD.py +0 -81
- irie/apps/inventory/archive/arcGIS.py +0 -1175
- irie/apps/inventory/traffic.py +0 -175052
- /irie/apps/inventory/{calid.py → archive/calid.py} +0 -0
- {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/entry_points.txt +0 -0
- {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<title>Adding 3D models using three.js on terrain</title>
|
|
6
|
+
<meta property="og:description" content="Use a custom style layer with three.js to add 3D models to a map with 3d terrain." />
|
|
7
|
+
<meta charset='utf-8'>
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
9
|
+
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.2.0/dist/maplibre-gl.css' />
|
|
10
|
+
<script src='https://unpkg.com/maplibre-gl@5.2.0/dist/maplibre-gl.js'></script>
|
|
11
|
+
<style>
|
|
12
|
+
body {
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
html,
|
|
18
|
+
body,
|
|
19
|
+
#map {
|
|
20
|
+
height: 100%;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
23
|
+
<script type="importmap">
|
|
24
|
+
{
|
|
25
|
+
"imports": {
|
|
26
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js",
|
|
27
|
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
</head>
|
|
32
|
+
<body>
|
|
33
|
+
<div id="map"></div>
|
|
34
|
+
|
|
35
|
+
<script type="module">
|
|
36
|
+
import * as THREE from 'three';
|
|
37
|
+
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Objective:
|
|
41
|
+
* Given two known world-locations `model1Location` and `model2Location`,
|
|
42
|
+
* place two three.js objects on those locations at the appropriate height of
|
|
43
|
+
* the terrain.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
async function main() {
|
|
47
|
+
|
|
48
|
+
const map = new maplibregl.Map({
|
|
49
|
+
container: 'map',
|
|
50
|
+
center: [11.5257, 47.668],
|
|
51
|
+
zoom: 16.27,
|
|
52
|
+
pitch: 60,
|
|
53
|
+
bearing: -28.5,
|
|
54
|
+
canvasContextAttributes: {antialias: true},
|
|
55
|
+
style: {
|
|
56
|
+
version: 8,
|
|
57
|
+
layers: [
|
|
58
|
+
{
|
|
59
|
+
id: 'baseColor', // Hides edges of terrain tiles, which have 'walls' going down to 0.
|
|
60
|
+
type: 'background',
|
|
61
|
+
paint: {
|
|
62
|
+
'background-color': '#fff',
|
|
63
|
+
'background-opacity': 1.0,
|
|
64
|
+
},
|
|
65
|
+
}, {
|
|
66
|
+
id: 'hills',
|
|
67
|
+
type: 'hillshade',
|
|
68
|
+
source: 'hillshadeSource',
|
|
69
|
+
layout: {visibility: 'visible'},
|
|
70
|
+
paint: {'hillshade-shadow-color': '#473B24'}
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
terrain: {
|
|
74
|
+
source: 'terrainSource',
|
|
75
|
+
exaggeration: 1,
|
|
76
|
+
},
|
|
77
|
+
sources: {
|
|
78
|
+
terrainSource: {
|
|
79
|
+
type: 'raster-dem',
|
|
80
|
+
url: 'https://demotiles.maplibre.org/terrain-tiles/tiles.json',
|
|
81
|
+
tileSize: 256
|
|
82
|
+
},
|
|
83
|
+
hillshadeSource: {
|
|
84
|
+
type: 'raster-dem',
|
|
85
|
+
url: 'https://demotiles.maplibre.org/terrain-tiles/tiles.json',
|
|
86
|
+
tileSize: 256
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
* Helper function used to get threejs-scene-coordinates from mercator coordinates.
|
|
94
|
+
* This is just a quick and dirty solution - it won't work if points are far away from each other
|
|
95
|
+
* because a meter near the north-pole covers more mercator-units
|
|
96
|
+
* than a meter near the equator.
|
|
97
|
+
*/
|
|
98
|
+
function calculateDistanceMercatorToMeters(from, to) {
|
|
99
|
+
const mercatorPerMeter = from.meterInMercatorCoordinateUnits();
|
|
100
|
+
// mercator x: 0=west, 1=east
|
|
101
|
+
const dEast = to.x - from.x;
|
|
102
|
+
const dEastMeter = dEast / mercatorPerMeter;
|
|
103
|
+
// mercator y: 0=north, 1=south
|
|
104
|
+
const dNorth = from.y - to.y;
|
|
105
|
+
const dNorthMeter = dNorth / mercatorPerMeter;
|
|
106
|
+
return {dEastMeter, dNorthMeter};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function loadModel() {
|
|
110
|
+
const loader = new GLTFLoader();
|
|
111
|
+
const gltf = await loader.loadAsync('https://maplibre.org/maplibre-gl-js/docs/assets/34M_17/34M_17.gltf');
|
|
112
|
+
const model = gltf.scene;
|
|
113
|
+
return model;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Known locations. We'll infer the elevation of those locations once terrain is loaded.
|
|
117
|
+
const sceneOrigin = new maplibregl.LngLat(11.5255, 47.6677);
|
|
118
|
+
const model1Location = new maplibregl.LngLat(11.527, 47.6678);
|
|
119
|
+
const model2Location = new maplibregl.LngLat(11.5249, 47.6676);
|
|
120
|
+
|
|
121
|
+
// Configuration of the custom layer for a 3D model, implementing `CustomLayerInterface`.
|
|
122
|
+
const customLayer = {
|
|
123
|
+
id: '3d-model',
|
|
124
|
+
type: 'custom',
|
|
125
|
+
renderingMode: '3d',
|
|
126
|
+
|
|
127
|
+
onAdd(map, gl) {
|
|
128
|
+
/**
|
|
129
|
+
* Setting up three.js scene.
|
|
130
|
+
* We're placing model1 and model2 in such a way that the whole scene fits over the terrain.
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
this.camera = new THREE.Camera();
|
|
134
|
+
this.scene = new THREE.Scene();
|
|
135
|
+
// In threejs, y points up - we're rotating the scene such that it's y points along maplibre's up.
|
|
136
|
+
this.scene.rotateX(Math.PI / 2);
|
|
137
|
+
// In threejs, z points toward the viewer - mirroring it such that z points along maplibre's north.
|
|
138
|
+
this.scene.scale.multiply(new THREE.Vector3(1, 1, -1));
|
|
139
|
+
// We now have a scene with (x=east, y=up, z=north)
|
|
140
|
+
|
|
141
|
+
const light = new THREE.DirectionalLight(0xffffff);
|
|
142
|
+
// Making it just before noon - light coming from south-east.
|
|
143
|
+
light.position.set(50, 70, -30).normalize();
|
|
144
|
+
this.scene.add(light);
|
|
145
|
+
|
|
146
|
+
// Axes helper to show how threejs scene is oriented.
|
|
147
|
+
const axesHelper = new THREE.AxesHelper(60);
|
|
148
|
+
this.scene.add(axesHelper);
|
|
149
|
+
|
|
150
|
+
// Getting model elevations in meters above sea level
|
|
151
|
+
const sceneElevation = map.queryTerrainElevation(sceneOrigin) || 0;
|
|
152
|
+
const model1Elevation = map.queryTerrainElevation(model1Location) || 0;
|
|
153
|
+
const model2Elevation = map.queryTerrainElevation(model2Location) || 0;
|
|
154
|
+
const model1up = model1Elevation - sceneElevation;
|
|
155
|
+
const model2up = model2Elevation - sceneElevation;
|
|
156
|
+
|
|
157
|
+
// Getting model x and y (in meters) relative to scene origin.
|
|
158
|
+
const sceneOriginMercator = maplibregl.MercatorCoordinate.fromLngLat(sceneOrigin);
|
|
159
|
+
const model1Mercator = maplibregl.MercatorCoordinate.fromLngLat(model1Location);
|
|
160
|
+
const model2Mercator = maplibregl.MercatorCoordinate.fromLngLat(model2Location);
|
|
161
|
+
const {dEastMeter: model1east, dNorthMeter: model1north} = calculateDistanceMercatorToMeters(sceneOriginMercator, model1Mercator);
|
|
162
|
+
const {dEastMeter: model2east, dNorthMeter: model2north} = calculateDistanceMercatorToMeters(sceneOriginMercator, model2Mercator);
|
|
163
|
+
|
|
164
|
+
model1.position.set(model1east, model1up, model1north);
|
|
165
|
+
model2.position.set(model2east, model2up, model2north);
|
|
166
|
+
|
|
167
|
+
this.scene.add(model1);
|
|
168
|
+
this.scene.add(model2);
|
|
169
|
+
|
|
170
|
+
// Use the MapLibre GL JS map canvas for three.js.
|
|
171
|
+
this.renderer = new THREE.WebGLRenderer({
|
|
172
|
+
canvas: map.getCanvas(),
|
|
173
|
+
context: gl,
|
|
174
|
+
antialias: true
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
this.renderer.autoClear = false;
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
render(gl, args) {
|
|
181
|
+
const offsetFromCenterElevation = map.queryTerrainElevation(sceneOrigin) || 0;
|
|
182
|
+
const sceneOriginMercator = maplibregl.MercatorCoordinate.fromLngLat(sceneOrigin, offsetFromCenterElevation);
|
|
183
|
+
|
|
184
|
+
const sceneTransform = {
|
|
185
|
+
translateX: sceneOriginMercator.x,
|
|
186
|
+
translateY: sceneOriginMercator.y,
|
|
187
|
+
translateZ: sceneOriginMercator.z,
|
|
188
|
+
scale: sceneOriginMercator.meterInMercatorCoordinateUnits()
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const m = new THREE.Matrix4().fromArray(args.defaultProjectionData.mainMatrix);
|
|
192
|
+
const l = new THREE.Matrix4()
|
|
193
|
+
.makeTranslation(sceneTransform.translateX, sceneTransform.translateY, sceneTransform.translateZ)
|
|
194
|
+
.scale(new THREE.Vector3(sceneTransform.scale, -sceneTransform.scale, sceneTransform.scale));
|
|
195
|
+
|
|
196
|
+
this.camera.projectionMatrix = m.multiply(l);
|
|
197
|
+
this.renderer.resetState();
|
|
198
|
+
this.renderer.render(this.scene, this.camera);
|
|
199
|
+
map.triggerRepaint();
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const results = await Promise.all([map.once('load'), loadModel()]);
|
|
204
|
+
const model1 = results[1];
|
|
205
|
+
const model2 = model1.clone();
|
|
206
|
+
|
|
207
|
+
map.addLayer(customLayer);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
main();
|
|
211
|
+
</script>
|
|
212
|
+
</body>
|
|
213
|
+
|
|
214
|
+
</html>
|
|
@@ -0,0 +1,229 @@
|
|
|
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 three.js to add a 3D model with shadow 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
|
+
<script type="importmap">
|
|
15
|
+
{
|
|
16
|
+
"imports": {
|
|
17
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js",
|
|
18
|
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
</head>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
<div id="map"></div>
|
|
26
|
+
|
|
27
|
+
<script type="module">
|
|
28
|
+
import * as THREE from 'three';
|
|
29
|
+
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
30
|
+
|
|
31
|
+
const modelOrigin = [-124.1014, 40.50303]; // [148.9819, -35.39847];
|
|
32
|
+
// const modelSource = 'https://maplibre.org/maplibre-gl-js/docs/assets/34M_17/34M_17.gltf';
|
|
33
|
+
const modelSource = '/uploads/renderings/painter.glb';
|
|
34
|
+
const unitToMeter = 1/3.2808;
|
|
35
|
+
const MAPTILER_KEY = 'get_your_own_OpIi9ZULNHzrESv6T2vL';
|
|
36
|
+
|
|
37
|
+
//
|
|
38
|
+
// Initialize Map
|
|
39
|
+
//
|
|
40
|
+
const map = new maplibregl.Map({
|
|
41
|
+
container: 'map',
|
|
42
|
+
|
|
43
|
+
style: `https://api.maptiler.com/maps/basic-v2/style.json?key=${MAPTILER_KEY}`,
|
|
44
|
+
center: modelOrigin,
|
|
45
|
+
zoom: 18,
|
|
46
|
+
maxZoom: 30,
|
|
47
|
+
maxPitch: 85,
|
|
48
|
+
pitch: 77,
|
|
49
|
+
canvasContextAttributes: {antialias: true}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
//
|
|
53
|
+
// Add Buildings
|
|
54
|
+
//
|
|
55
|
+
|
|
56
|
+
// The 'building' layer in the streets vector source contains building-height
|
|
57
|
+
// data from OpenStreetMap.
|
|
58
|
+
map.on('load', () => {
|
|
59
|
+
// Insert the layer beneath any symbol layer.
|
|
60
|
+
const layers = map.getStyle().layers;
|
|
61
|
+
|
|
62
|
+
let labelLayerId;
|
|
63
|
+
for (let i = 0; i < layers.length; i++) {
|
|
64
|
+
if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
|
|
65
|
+
labelLayerId = layers[i].id;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
map.addSource('openmaptiles', {
|
|
71
|
+
url: `https://api.maptiler.com/tiles/v3/tiles.json?key=${MAPTILER_KEY}`,
|
|
72
|
+
type: 'vector',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
map.addLayer(
|
|
76
|
+
{
|
|
77
|
+
'id': '3d-buildings',
|
|
78
|
+
'source': 'openmaptiles',
|
|
79
|
+
'source-layer': 'building',
|
|
80
|
+
'type': 'fill-extrusion',
|
|
81
|
+
'minzoom': 15,
|
|
82
|
+
'filter': ['!=', ['get', 'hide_3d'], true],
|
|
83
|
+
'paint': {
|
|
84
|
+
'fill-extrusion-color': [
|
|
85
|
+
'interpolate',
|
|
86
|
+
['linear'],
|
|
87
|
+
['get', 'render_height'], 0, 'lightgray', 200, 'royalblue', 400, 'lightblue'
|
|
88
|
+
],
|
|
89
|
+
'fill-extrusion-height': [
|
|
90
|
+
'interpolate',
|
|
91
|
+
['linear'],
|
|
92
|
+
['zoom'],
|
|
93
|
+
15,
|
|
94
|
+
0,
|
|
95
|
+
16,
|
|
96
|
+
['get', 'render_height']
|
|
97
|
+
],
|
|
98
|
+
'fill-extrusion-base': ['case',
|
|
99
|
+
['>=', ['get', 'zoom'], 16],
|
|
100
|
+
['get', 'render_min_height'], 0
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
labelLayerId
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
//
|
|
109
|
+
// Add Asset
|
|
110
|
+
//
|
|
111
|
+
const modelAltitude = 0;
|
|
112
|
+
const modelRotate = [Math.PI / 2, 0, 0];
|
|
113
|
+
const modelCoord = maplibregl.MercatorCoordinate.fromLngLat(
|
|
114
|
+
modelOrigin,
|
|
115
|
+
modelAltitude
|
|
116
|
+
);
|
|
117
|
+
const modelScale = modelCoord.meterInMercatorCoordinateUnits()*unitToMeter;
|
|
118
|
+
const modelTransform = {
|
|
119
|
+
translateX: modelCoord.x,
|
|
120
|
+
translateY: modelCoord.y-25*modelScale,
|
|
121
|
+
translateZ: modelCoord.z+35*modelScale,
|
|
122
|
+
rotateX: modelRotate[0],
|
|
123
|
+
rotateY: modelRotate[1],
|
|
124
|
+
rotateZ: modelRotate[2],
|
|
125
|
+
scale: modelScale
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const customLayer = {
|
|
129
|
+
id: '3d-model',
|
|
130
|
+
type: 'custom',
|
|
131
|
+
renderingMode: '3d',
|
|
132
|
+
onAdd(map, gl) {
|
|
133
|
+
this.camera = new THREE.Camera();
|
|
134
|
+
this.scene = new THREE.Scene();
|
|
135
|
+
|
|
136
|
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
|
|
137
|
+
directionalLight.position.set(100, 100, 100);
|
|
138
|
+
directionalLight.castShadow = true;
|
|
139
|
+
this.scene.add(directionalLight);
|
|
140
|
+
|
|
141
|
+
directionalLight.shadow.camera.near = 0.1;
|
|
142
|
+
directionalLight.shadow.camera.far = 2000;
|
|
143
|
+
directionalLight.shadow.camera.left = -500;
|
|
144
|
+
directionalLight.shadow.camera.right = 500;
|
|
145
|
+
directionalLight.shadow.camera.top = 500;
|
|
146
|
+
directionalLight.shadow.camera.bottom = -500;
|
|
147
|
+
|
|
148
|
+
directionalLight.shadow.mapSize.width = 4096;
|
|
149
|
+
directionalLight.shadow.mapSize.height = 4096;
|
|
150
|
+
|
|
151
|
+
const groundGeometry = new THREE.PlaneGeometry(1000, 1000);
|
|
152
|
+
const groundMaterial = new THREE.ShadowMaterial({ opacity: 0.5 });
|
|
153
|
+
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
|
|
154
|
+
ground.rotation.x = -Math.PI / 2;
|
|
155
|
+
ground.position.y = modelCoord.z;
|
|
156
|
+
ground.receiveShadow = true;
|
|
157
|
+
this.scene.add(ground);
|
|
158
|
+
|
|
159
|
+
const loader = new GLTFLoader();
|
|
160
|
+
loader.load(
|
|
161
|
+
modelSource,
|
|
162
|
+
(gltf) => {
|
|
163
|
+
gltf.scene.traverse(function (node) {
|
|
164
|
+
if (node.isMesh || node.isLight) {
|
|
165
|
+
node.castShadow = true;
|
|
166
|
+
node.receiveShadow = true;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
this.scene.add(gltf.scene);
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
this.map = map;
|
|
173
|
+
|
|
174
|
+
this.renderer = new THREE.WebGLRenderer({
|
|
175
|
+
canvas: map.getCanvas(),
|
|
176
|
+
context: gl,
|
|
177
|
+
antialias: true
|
|
178
|
+
});
|
|
179
|
+
this.renderer.shadowMap.enabled = true;
|
|
180
|
+
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
181
|
+
|
|
182
|
+
this.renderer.autoClear = false;
|
|
183
|
+
},
|
|
184
|
+
render(gl, args) {
|
|
185
|
+
const rotationX = new THREE.Matrix4().makeRotationAxis(
|
|
186
|
+
new THREE.Vector3(1, 0, 0),
|
|
187
|
+
modelTransform.rotateX
|
|
188
|
+
);
|
|
189
|
+
const rotationY = new THREE.Matrix4().makeRotationAxis(
|
|
190
|
+
new THREE.Vector3(0, 1, 0),
|
|
191
|
+
modelTransform.rotateY
|
|
192
|
+
);
|
|
193
|
+
const rotationZ = new THREE.Matrix4().makeRotationAxis(
|
|
194
|
+
new THREE.Vector3(0, 0, 1),
|
|
195
|
+
modelTransform.rotateZ
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const m = new THREE.Matrix4().fromArray(args.defaultProjectionData.mainMatrix);
|
|
199
|
+
const l = new THREE.Matrix4()
|
|
200
|
+
.makeTranslation(
|
|
201
|
+
modelTransform.translateX,
|
|
202
|
+
modelTransform.translateY,
|
|
203
|
+
modelTransform.translateZ
|
|
204
|
+
)
|
|
205
|
+
.scale(
|
|
206
|
+
new THREE.Vector3(
|
|
207
|
+
modelTransform.scale,
|
|
208
|
+
-modelTransform.scale,
|
|
209
|
+
modelTransform.scale
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
.multiply(rotationX)
|
|
213
|
+
.multiply(rotationY)
|
|
214
|
+
.multiply(rotationZ);
|
|
215
|
+
|
|
216
|
+
this.camera.projectionMatrix = m.multiply(l);
|
|
217
|
+
this.renderer.resetState();
|
|
218
|
+
this.renderer.render(this.scene, this.camera);
|
|
219
|
+
this.map.triggerRepaint();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
map.on('style.load', () => {
|
|
224
|
+
map.addLayer(customLayer);
|
|
225
|
+
});
|
|
226
|
+
</script>
|
|
227
|
+
</body>
|
|
228
|
+
|
|
229
|
+
</html>
|
|
@@ -1,35 +1,81 @@
|
|
|
1
1
|
{% extends "layouts/base.html" %}
|
|
2
|
-
{# load predictor #}
|
|
3
2
|
{% block title %} {{ asset.calid }} | Upload {% endblock %}
|
|
4
|
-
{% block stylesheets %}
|
|
5
3
|
|
|
4
|
+
{% block stylesheets %}
|
|
6
5
|
{% endblock stylesheets %}
|
|
7
6
|
|
|
8
7
|
{% block content %}
|
|
9
8
|
<div class="print">
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
<div class="col-10 mb-4 d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center py-4">
|
|
10
|
+
<div class="d-block mb-4 mb-md-0">
|
|
11
|
+
<nav aria-label="breadcrumb" class="d-none d-md-inline-block">
|
|
12
|
+
<ol class="breadcrumb breadcrumb-dark breadcrumb-transparent">
|
|
13
|
+
<li class="breadcrumb-item">
|
|
14
|
+
<a href="{% url 'dashboard' %}">
|
|
15
|
+
<svg class="icon icon-xxs" 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="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path></svg>
|
|
16
|
+
</a>
|
|
17
|
+
</li>
|
|
18
|
+
<li class="breadcrumb-item text-dark" aria-current="page"><a href="{% url 'asset_table' %}">Inventory</a></li>
|
|
19
|
+
<li class="breadcrumb-item"><a href="{% url 'asset_profile' calid=asset.calid %}"><code>{{ asset.calid }}</code></a></li>
|
|
20
|
+
<li class="breadcrumb-item"><a href="/inventory/{{ asset.calid }}/predictors/">Predictors</a></li>
|
|
21
|
+
<li class="breadcrumb-item active">Upload</li>
|
|
22
|
+
</ol>
|
|
23
|
+
</nav>
|
|
24
|
+
<h1 class="h4"><samp>{{ asset.id }}</samp> / {{ asset.calid }} Predictor Upload</h1>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="btn-toolbar mb-2 mb-md-0">
|
|
27
|
+
<a role="button"
|
|
28
|
+
href="/inventory/{{ asset.calid }}/predictors/"
|
|
29
|
+
class="btn btn-sm btn-outline-primary d-inline-flex align-items-center mx-1">
|
|
30
|
+
Predictors
|
|
31
|
+
</a>
|
|
32
|
+
<a role="button"
|
|
33
|
+
href="{% url 'asset_sensors' calid=asset.calid %}"
|
|
34
|
+
class="btn btn-sm btn-outline-primary d-inline-flex align-items-center mx-1">
|
|
35
|
+
Sensors
|
|
36
|
+
</a>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="row">
|
|
40
|
+
<div class="col">
|
|
41
|
+
<form method="POST" enctype="multipart/form-data">
|
|
42
|
+
{% csrf_token %}
|
|
43
|
+
{{ form.as_p}}
|
|
44
|
+
<button id="render" type="button" class="btn btn-outline-primary" >Validate</button>
|
|
45
|
+
<button type="submit" class="btn btn-primary" name="action" value="commit">Submit</button>
|
|
46
|
+
</form>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="row">
|
|
50
|
+
<iframe
|
|
51
|
+
id="map"
|
|
52
|
+
width="100%"
|
|
53
|
+
height="400"
|
|
54
|
+
>
|
|
55
|
+
</iframe>
|
|
56
|
+
</div>
|
|
18
57
|
</div>
|
|
19
58
|
{% endblock content %}
|
|
20
59
|
|
|
21
|
-
<script>
|
|
22
|
-
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
|
23
|
-
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
|
|
24
|
-
</script>
|
|
25
60
|
{% block javascripts %}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
61
|
+
<script>
|
|
62
|
+
const button = document.getElementById('render');
|
|
63
|
+
const form = document.querySelector('form');
|
|
64
|
+
const map = document.getElementById('map');
|
|
65
|
+
button.addEventListener('click', function(event) {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
fetch('/inventory/{{ asset.calid }}/predictors/create/map/', {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
body: new FormData(form)
|
|
70
|
+
}).then(response => response.text())
|
|
71
|
+
.then(data => {
|
|
72
|
+
const blob = new Blob([data], { type: 'text/html' });
|
|
73
|
+
const url = window.URL.createObjectURL(blob);
|
|
74
|
+
map.src = url;
|
|
75
|
+
})
|
|
76
|
+
.catch(error => {
|
|
77
|
+
console.error('Error fetching map:', error);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
33
80
|
</script>
|
|
34
|
-
|
|
35
81
|
{% endblock javascripts %}
|