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.

Files changed (49) hide show
  1. irie/apps/inventory/archive/CESMD.py +0 -0
  2. irie/apps/inventory/models.py +27 -0
  3. irie/apps/inventory/services/render.py +0 -0
  4. irie/apps/inventory/urls.py +3 -0
  5. irie/apps/inventory/views.py +57 -0
  6. irie/apps/prediction/forms.py +2 -1
  7. irie/apps/prediction/models.py +24 -0
  8. irie/apps/prediction/urls.py +5 -3
  9. irie/apps/prediction/views.py +101 -8
  10. irie/apps/static/assets/css/brace.css +0 -32
  11. irie/apps/static/assets/css/brace.css.map +1 -1
  12. irie/apps/static/assets/css/brace.min.css +1 -1
  13. irie/apps/templates/inventory/asset-on-map.html +457 -0
  14. irie/apps/templates/inventory/asset-profile.html +1 -2
  15. irie/apps/templates/inventory/map-inventory.html +136 -0
  16. irie/apps/templates/inventory/map-inventory2.html +143 -0
  17. irie/apps/templates/inventory/map-single-asset.html +0 -0
  18. irie/apps/templates/inventory/map-single-asset2.html +618 -0
  19. irie/apps/templates/inventory/map-terrain.html +214 -0
  20. irie/apps/templates/inventory/sensor-upload.html +1 -0
  21. irie/apps/templates/inventory/three-maps.html +229 -0
  22. irie/apps/templates/layouts/base.html +1 -0
  23. irie/apps/templates/prediction/predictor-upload.html +68 -22
  24. irie/apps/templates/site/index.html +36 -27
  25. irie/apps/templates/site/page-400-sidebar.html +31 -0
  26. irie/apps/templates/site/page-400.html +29 -0
  27. irie/apps/templates/site/page-404-sidebar.html +1 -1
  28. irie/apps/templates/site/page-404.html +1 -1
  29. irie/fhwa/__init__.py +132 -0
  30. irie/fhwa/__main__.py +79 -0
  31. irie/fhwa/fields/nbi001.py +61 -0
  32. irie/fhwa/fields/nbi001b.py +1 -0
  33. irie/fhwa/fields/nbi002.py +0 -0
  34. irie/fhwa/fields.py +32 -0
  35. irie/init/__main__.py +0 -4
  36. irie/init/calid.py +86 -3
  37. irie/init/getNBIData.py +1 -1
  38. irie/init/management/commands/init_assets.py +11 -11
  39. irie/init/management/commands/init_predictors.py +1 -1
  40. irie/init/management/commands/make_asset.py +0 -0
  41. {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/METADATA +1 -1
  42. {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/RECORD +46 -31
  43. {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/WHEEL +1 -1
  44. irie/apps/inventory/CESMD.py +0 -81
  45. irie/apps/inventory/archive/arcGIS.py +0 -1175
  46. irie/apps/inventory/traffic.py +0 -175052
  47. /irie/apps/inventory/{calid.py → archive/calid.py} +0 -0
  48. {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/entry_points.txt +0 -0
  49. {irie-0.0.42.dist-info → irie-0.0.43.dist-info}/top_level.txt +0 -0
File without changes
@@ -142,3 +142,30 @@ class Sensor(models.Model):
142
142
 
143
143
  def __str__(self):
144
144
  return f"{self.name} ({self.group.name})"
145
+
146
+
147
+
148
+ # class Rendering:
149
+ # def __init__(self, url=None, units, datum):
150
+ # self._url = url
151
+
152
+
153
+ # def url(self):
154
+ # return self._url
155
+
156
+ # def url_or_data(self):
157
+ # pass
158
+
159
+ # def scale_meter(self):
160
+ # pass
161
+
162
+ # class PersistentRendering(models.Model):
163
+ # asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
164
+ # datum = models.ForeignKey(Datum, on_delete=models.CASCADE)
165
+ # units = models.CharField(max_length=3)
166
+
167
+ # class TemporaryRendering(Rendering):
168
+ # def __init__(self, data, units, datum, asset):
169
+ # self._data = data
170
+ # self._units = units
171
+ # self._datum = datum
File without changes
@@ -27,4 +27,7 @@ urlpatterns = [
27
27
  re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/$", views.asset_profile, name="asset_profile"),
28
28
  re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/sensors/$", views.asset_sensors, name="asset_sensors"),
29
29
  re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/sensor_upload", views.sensor_upload, name="sensor_upload"),
30
+
31
+ path("inventory/map2/", views.map_inventory),
32
+ path("california.json", views.california_json),
30
33
  ]
@@ -221,6 +221,62 @@ def asset_evals(request, calid):
221
221
  return HttpResponse(html_template.render(context, request))
222
222
 
223
223
 
224
+ def california_json(request):
225
+ with open("ca.json") as f:
226
+ return HttpResponse(f.read(), content_type="application/json")
227
+ with open("us_states.json") as f:
228
+ cal = [s for s in json.load(f)["features"] if s["id"] == "CA"][0]
229
+ return HttpResponse(json.dumps({"type": "FeatureCollection", "features": [cal]}), content_type="application/json")
230
+
231
+ def map_inventory(request):
232
+
233
+ import json
234
+ from irie.apps.inventory.models import Asset
235
+
236
+ consumed = {
237
+ "Partial": set(),
238
+ "Complete": set(),
239
+ "Instrumented": set()
240
+ }
241
+
242
+ data = {
243
+ "Partial": [],
244
+ "Complete": [],
245
+ "Instrumented": []
246
+ }
247
+
248
+ for asset in Asset.objects.all():
249
+ if asset.is_complete:
250
+ consumed["Complete"].add(asset.calid)
251
+ lat, lon = asset.coordinates
252
+ data["Complete"].append({
253
+ "lat": lat, "lon": lon
254
+ })
255
+
256
+ from irie.init.calid import CESMD, CESMD_LONG_LAT
257
+ for calid in CESMD:
258
+ if calid not in consumed["Complete"]:
259
+ consumed["Instrumented"].add(asset.calid)
260
+ try:
261
+ lat, lon = CESMD_LONG_LAT[CESMD[calid][0][2:]]
262
+ except:
263
+ continue
264
+ data["Instrumented"].append({
265
+ # "lat": lat, "lon": -lon
266
+ "lat": lat, "lon": lon
267
+ })
268
+
269
+ for asset in Asset.objects.all():
270
+ if asset.calid not in consumed["Instrumented"] and asset.calid not in consumed["Complete"]:
271
+ lat, lon = asset.coordinates
272
+ data["Partial"].append({
273
+ "lat": lat, "lon": lon
274
+ })
275
+
276
+
277
+ html_template = loader.get_template("inventory/map-inventory.html")
278
+ return HttpResponse(html_template.render({"data": json.dumps(data)}, request))
279
+
224
280
  # @login_required(login_url="/login/")
225
281
  def asset_profile(request, calid):
226
282
 
@@ -548,6 +604,7 @@ class AssetMap:
548
604
  weight=1,
549
605
  z_index_offset=10 if b.is_complete else 100000
550
606
  )
607
+
551
608
  if b.is_complete:
552
609
  marker = folium.Marker(
553
610
  location=[lat, lon],
@@ -14,7 +14,8 @@ class PredictorForm(forms.ModelForm):
14
14
  "render_file",
15
15
  "asset",
16
16
  "metrics",
17
- "active",
17
+ "active",
18
+ "description",
18
19
  "entry_point",
19
20
  "config",
20
21
  "protocol"
@@ -35,3 +35,27 @@ class PredictorModel(models.Model):
35
35
  def __str__(self):
36
36
  return f"{self.asset.calid} - {self.name} : {self.description}"
37
37
 
38
+
39
+ # class PhysicsPredictor(models.Model):
40
+ # class Units(models.TextChoices):
41
+ # iks = "IKS"
42
+ # ips = "IPS"
43
+ # fps = "FPS"
44
+ # mks = "MKS"
45
+ # cgs = "CGS"
46
+
47
+ # id = models.BigAutoField(primary_key=True)
48
+ # name = models.CharField(max_length=35)
49
+ # active = models.BooleanField()
50
+ # asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
51
+ # description = models.TextField(default="")
52
+
53
+ # config_file = models.FileField(upload_to="predictor_configs/", null=True, blank=True)
54
+ # render_file = models.FileField(upload_to="renderings/", null=True, blank=True)
55
+ # metrics = models.JSONField(default=list)
56
+
57
+ # units = models.CharField(max_length=3, choices=Units.choices)
58
+
59
+
60
+ # def __str__(self):
61
+ # return f"{self.name} : {self.asset.calid}"
@@ -8,11 +8,13 @@
8
8
  #
9
9
  #----------------------------------------------------------------------------#
10
10
  from django.urls import re_path
11
- from .views import new_prediction, asset_predictors, predictor_profile, predictor_upload
11
+ from .views import new_prediction, asset_predictors, predictor_profile, predictor_upload, asset_map
12
12
 
13
13
  urlpatterns = [
14
14
  re_path("^inventory/[0-9 A-Z-]*/predictors/new", new_prediction),
15
15
  re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/(?P<preid>[0-9 A-Z-]{1,})", predictor_profile),
16
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/create", predictor_upload),
17
- re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/", asset_predictors, name="asset_predictors")
16
+ re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/create/map/$", asset_map),
17
+ re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/map/$", asset_map),
18
+ re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/create/$", predictor_upload),
19
+ re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/predictors/", asset_predictors, name="asset_predictors")
18
20
  ]
@@ -11,11 +11,15 @@
11
11
  #----------------------------------------------------------------------------#
12
12
  import os
13
13
  import json
14
+ import veux
15
+ import uuid
16
+ import base64
14
17
 
15
18
  from django.shortcuts import HttpResponse
16
19
  from django.template import loader, TemplateDoesNotExist
17
20
  from django.contrib.auth.decorators import login_required
18
21
  from django.core.exceptions import ObjectDoesNotExist
22
+ from django.core.files.base import ContentFile
19
23
 
20
24
  from django.shortcuts import render
21
25
 
@@ -97,27 +101,116 @@ def predictor_profile(request, calid, preid):
97
101
  return HttpResponse(html_template.render(context, request))
98
102
 
99
103
 
104
+ @login_required(login_url="/login/")
105
+ def asset_map(request, calid):
106
+
107
+
108
+ r200 = loader.get_template("inventory/asset-on-map.html")
109
+ r400 = loader.get_template("site/page-400.html")
110
+ asset = Asset.objects.get(calid=calid)
111
+ context = {
112
+ "asset": asset,
113
+ "viewer": "three",
114
+ "location": json.dumps(list(reversed(list(asset.coordinates)))),
115
+ }
116
+
117
+ if request.method == "GET":
118
+ context["render_src"] = asset.rendering
119
+
120
+ elif request.method == "POST":
121
+ from openbim.csi import load, create_model, collect_outlines
122
+ # context["offset"] = json.dumps(list(reversed(list(asset.coordinates))))
123
+ context["rotate"] = "[0, 0, 0]"
124
+ context["scale"] = 1/3.2808 # TODO
125
+
126
+ uploaded_file = request.FILES.get('config_file')
127
+
128
+ try:
129
+ csi = load((str(line.decode()).replace("\r\n","\n") for line in uploaded_file.readlines()))
130
+ except Exception as e:
131
+ return HttpResponse(r400.render({"message": json.dumps({"error": str(e)})}), status=400)
132
+
133
+ try:
134
+ model = create_model(csi, verbose=True)
135
+ except Exception as e:
136
+ return HttpResponse(r400.render({"message": json.dumps({"error": str(e)})}), status=400)
137
+
138
+
139
+ outlines = collect_outlines(csi, model.frame_tags)
140
+ artist = veux.render(model, canvas="gltf", vertical=3,
141
+ reference={"frame.surface", "frame.axes"},
142
+ model_config={"frame_outlines": outlines})
143
+
144
+ glb = artist.canvas.to_glb()
145
+ glb64 = base64.b64encode(glb).decode("utf-8")
146
+ context["render_glb"] = f"data:application/octet-stream;base64,{glb64}"
147
+
148
+
149
+ try:
150
+ return HttpResponse(r200.render(context, request))
151
+
152
+ except Exception as e:
153
+ r500 = loader.get_template("site/page-500.html")
154
+ return HttpResponse(r500.render({"message": str(e)}, request), status=500)
155
+
156
+
157
+
158
+
100
159
  @login_required(login_url="/login/")
101
160
  def predictor_upload(request, calid):
102
161
 
162
+ asset = Asset.objects.get(calid=calid)
103
163
  html_template = loader.get_template("prediction/predictor-upload.html")
164
+ r400 = loader.get_template("site/page-400.html")
165
+ context = {
166
+ "asset": asset,
167
+ "segment": "inventory",
168
+ "viewer": "babylon",
169
+ "offset": json.dumps(list(reversed(list(asset.coordinates)))),
170
+ }
104
171
 
105
172
  if request.method == "POST":
173
+ from openbim.csi import load, create_model, collect_outlines
106
174
  form = PredictorForm(request.POST, request.FILES)
107
- asset = Asset.objects.get(calid=calid)
108
175
 
109
- # Save the predictor
110
- predictor = PREDICTOR_TYPES[request.POST.get("runner")].create(asset, request)
111
- predictor.save()
176
+ uploaded_file = request.FILES.get('config_file')
112
177
 
113
- return HttpResponse(json.dumps({"data": {"id": predictor.id}}))
178
+ try:
179
+ csi = load((str(line.decode()).replace("\r\n","\n") for line in uploaded_file.readlines()))
180
+ except Exception as e:
181
+ return HttpResponse(r400.render({"message": json.dumps({"error": str(e)})}), status=400)
114
182
 
115
- else:
116
- form = PredictorForm()
183
+ model = create_model(csi, verbose=True)
184
+
185
+ # Generate the .glb file using veux
186
+ outlines = collect_outlines(csi, model.frame_tags)
187
+ artist = veux.create_artist(model, canvas="gltf", vertical=3,
188
+ model_config={"frame_outlines": outlines}
189
+ )
190
+ artist.draw_surfaces()
191
+ glb = artist.canvas.to_glb()
192
+
193
+ if request.POST.get("action") == "commit":
194
+ if not form.is_valid():
195
+ return HttpResponse(json.dumps({"error": "Invalid form data"}), status=400)
196
+ predictor = PredictorModel()
197
+ predictor.active = False
198
+ predictor.asset = asset
199
+ predictor.name = form.cleaned_data['name']
200
+ predictor.description = "empty"
201
+
202
+ predictor.render_file.save(f"{uuid.uuid4()}.glb", ContentFile(glb), save=True)
203
+ predictor.save()
204
+
205
+ context["form"] = form
206
+
207
+ else: # probably a GET
208
+ context["form"] = PredictorForm()
117
209
 
118
210
 
119
211
  try:
120
- return render(request, "prediction/predictor-upload.html", {"form": form})
212
+ return HttpResponse(html_template.render(context, request))
213
+ # return render(request, "prediction/predictor-upload.html", {"form": form})
121
214
 
122
215
  except Exception as e:
123
216
  if "DEBUG" in os.environ and os.environ["DEBUG"]:
@@ -22277,38 +22277,6 @@ textarea.form-control-lg {
22277
22277
  color: #3A416F;
22278
22278
  }
22279
22279
 
22280
- .breadcrumb-item {
22281
- font-size: 0.875rem;
22282
- }
22283
- .breadcrumb-item.text-white::before {
22284
- color: #ffffff;
22285
- }
22286
-
22287
- .breadcrumb-dark {
22288
- background-color: #1F2937;
22289
- }
22290
- .breadcrumb-dark .breadcrumb-item {
22291
- font-weight: 600;
22292
- }
22293
- .breadcrumb-dark .breadcrumb-item a {
22294
- color: #F2F4F6;
22295
- }
22296
- .breadcrumb-dark .breadcrumb-item a:hover {
22297
- color: #ffffff;
22298
- }
22299
- .breadcrumb-dark .breadcrumb-item + .breadcrumb-item::before {
22300
- color: #6B7280;
22301
- }
22302
- .breadcrumb-dark .breadcrumb-item.active {
22303
- color: #D1D5DB;
22304
- }
22305
-
22306
- .breadcrumb-links {
22307
- padding: 0;
22308
- margin: 0;
22309
- background: transparent;
22310
- }
22311
-
22312
22280
  .card {
22313
22281
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
22314
22282
  border: 1px solid #E5E7EB;