cave-utils 3.4.0b2__tar.gz → 3.4.2__tar.gz
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.
- {cave_utils-3.4.0b2/cave_utils.egg-info → cave_utils-3.4.2}/PKG-INFO +1 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/__init__.py +0 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/appBar.py +17 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api_utils/validator_utils.py +4 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/custom_coordinates.py +14 -146
- {cave_utils-3.4.0b2 → cave_utils-3.4.2/cave_utils.egg-info}/PKG-INFO +1 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/pyproject.toml +1 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/setup.cfg +1 -1
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/LICENSE +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/NOTICE.md +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/README.md +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/__init__.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/extraKwargs.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/globalOutputs.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/groupedOutputs.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/mapFeatures.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/maps.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/pages.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/panes.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api/settings.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api_utils/__init__.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api_utils/general.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/api_utils/validator.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/arguments.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/builders/__init__.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/builders/groups.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/geo_utils.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/log.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils/socket.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils.egg-info/SOURCES.txt +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils.egg-info/dependency_links.txt +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils.egg-info/requires.txt +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/cave_utils.egg-info/top_level.txt +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_arguments.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_builders_groups.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_custom_coordinates.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_geo_utils.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_log.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_socket.py +0 -0
- {cave_utils-3.4.0b2 → cave_utils-3.4.2}/test/test_validator.py +0 -0
|
@@ -66,7 +66,9 @@ class appBar_data_star(ApiValidator):
|
|
|
66
66
|
* **`type`**: `[str]` → The type of object displayed when the action is triggered.
|
|
67
67
|
* **Accepted Values**:
|
|
68
68
|
* `"session"`: The Session Pane
|
|
69
|
+
* If you use this type, your field id must be `"session"`.
|
|
69
70
|
* `"settings"`: The Application Settings Pane
|
|
71
|
+
* If you use this type, your field id must be `"settings"`.
|
|
70
72
|
* `"button"`: A button that allows you to send a command to the CAVE API
|
|
71
73
|
* `"pane"`: A [custom pane][]
|
|
72
74
|
* `"page"`: A [page][]
|
|
@@ -76,6 +78,8 @@ class appBar_data_star(ApiValidator):
|
|
|
76
78
|
* `"lowerLeft"`: Lower section of the left-side bar
|
|
77
79
|
* `"upperRight"`: Upper section of the right-side bar
|
|
78
80
|
* `"lowerRight"`: Lower section of the right-side bar
|
|
81
|
+
* `"none"`: Do not display the action element in the app bar
|
|
82
|
+
- This is useful to hide predefined appBar buttions like the `session` or `settings` panes.
|
|
79
83
|
* **`variant`**: `[str]` = `None` → The variant of the button.
|
|
80
84
|
* **Accepted Values**:
|
|
81
85
|
* When **`type`** == `"pane"`:
|
|
@@ -105,7 +109,7 @@ class appBar_data_star(ApiValidator):
|
|
|
105
109
|
"accepted_values": {
|
|
106
110
|
"type": ["session", "settings", "button", "pane", "page"],
|
|
107
111
|
"variant": ["modal", "wall"] if type == "pane" else [],
|
|
108
|
-
"bar": ["upperLeft", "lowerLeft", "upperRight", "lowerRight"],
|
|
112
|
+
"bar": ["upperLeft", "lowerLeft", "upperRight", "lowerRight", "none"],
|
|
109
113
|
},
|
|
110
114
|
}
|
|
111
115
|
|
|
@@ -127,3 +131,15 @@ class appBar_data_star(ApiValidator):
|
|
|
127
131
|
valid_values=kwargs.get("pane_validPaneIds", []),
|
|
128
132
|
prepend_path=[],
|
|
129
133
|
)
|
|
134
|
+
if bar_type == "session":
|
|
135
|
+
if kwargs.get("CustomKeyValidatorFieldId") != "session":
|
|
136
|
+
self.__error__(
|
|
137
|
+
msg=f"When `type` is 'session', the only valid id for this `appBar.data` item is 'session'. Received: '{kwargs.get('CustomKeyValidatorFieldId')}'",
|
|
138
|
+
path=[],
|
|
139
|
+
)
|
|
140
|
+
if bar_type == "settings":
|
|
141
|
+
if kwargs.get("CustomKeyValidatorFieldId") != "settings":
|
|
142
|
+
self.__error__(
|
|
143
|
+
msg=f"When `type` is 'settings', the only valid id for this `appBar.data` item is 'settings'. Received: '{kwargs.get('CustomKeyValidatorFieldId')}'",
|
|
144
|
+
path=[],
|
|
145
|
+
)
|
|
@@ -80,6 +80,9 @@ class ApiValidator:
|
|
|
80
80
|
def __genericKeyValidation__(self, **kwargs):
|
|
81
81
|
# Remove `timeValues` out prior to each level validation
|
|
82
82
|
data_timeValues = self.data.pop("timeValues", None)
|
|
83
|
+
# Remove 'ignore_keys' from data to avoid validation issues
|
|
84
|
+
for key in self.ignore_keys:
|
|
85
|
+
self.data.pop(key, None)
|
|
83
86
|
# Remove `order` out prior to each level validation
|
|
84
87
|
data_order = self.data.pop("order", None)
|
|
85
88
|
if data_timeValues is not None:
|
|
@@ -155,7 +158,7 @@ class ApiValidator:
|
|
|
155
158
|
# Error and Warning Helpers
|
|
156
159
|
def __error__(self, msg: str, path: list[str] = list()):
|
|
157
160
|
"""
|
|
158
|
-
Raise an error for the log
|
|
161
|
+
Raise an error for the log
|
|
159
162
|
"""
|
|
160
163
|
self.log.add(path=path, msg=msg)
|
|
161
164
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type_enforced, math,
|
|
1
|
+
import type_enforced, math, json
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
@type_enforced.Enforcer
|
|
@@ -208,164 +208,32 @@ class CustomCoordinateSystem:
|
|
|
208
208
|
"path": converted_path,
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
def convert_geojson(self,
|
|
211
|
+
def convert_geojson(self, geojson_filepath: str, output_filepath: str):
|
|
212
212
|
"""
|
|
213
213
|
Converts the coordinates of the given GeoJSON object using this coordinate system to a longitude-latitdue-altitude system and writes the new object to a file.
|
|
214
214
|
|
|
215
215
|
Arguments:
|
|
216
216
|
|
|
217
|
-
* **`
|
|
218
|
-
* **`
|
|
217
|
+
* **`geojson_filepath`**: `[str]` → The file path to the GeoJSON object.
|
|
218
|
+
* **`output_filepath`**: `[str]` → The file path to write the converted GeoJSON object to.
|
|
219
219
|
|
|
220
220
|
Returns:
|
|
221
221
|
|
|
222
222
|
* `[None]`
|
|
223
223
|
"""
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
geojson_object = requests.get(geojson_object).json()
|
|
227
|
-
else:
|
|
228
|
-
with open(geojson_object, "r") as f:
|
|
229
|
-
geojson_object = json.load(f)
|
|
224
|
+
with open(geojson_filepath, "r") as f:
|
|
225
|
+
geojson_filepath = json.load(f)
|
|
230
226
|
|
|
231
|
-
if
|
|
232
|
-
for feature in
|
|
227
|
+
if geojson_filepath["type"] == "FeatureCollection":
|
|
228
|
+
for feature in geojson_filepath["features"]:
|
|
233
229
|
self.convert_coordinates(feature["geometry"]["coordinates"])
|
|
234
|
-
elif
|
|
235
|
-
self.convert_coordinates(
|
|
230
|
+
elif geojson_filepath["type"] == "Feature":
|
|
231
|
+
self.convert_coordinates(geojson_filepath["geometry"]["coordinates"])
|
|
236
232
|
else:
|
|
237
|
-
self.convert_coordinates(
|
|
238
|
-
with open(
|
|
239
|
-
json.dump(
|
|
240
|
-
print(f"GeoJSON converted and saved to {
|
|
241
|
-
|
|
242
|
-
def __serialize_geojson__(self, geoJsonLayer: str, geoJsonProp: str, geoJsonValue: list[str]):
|
|
243
|
-
"""
|
|
244
|
-
Serializes the given GeoJSON object in this coordinate system to a dictionary of the proper format to be used under `mapFeatures.data.*.data.location`.
|
|
245
|
-
|
|
246
|
-
Arguments:
|
|
247
|
-
|
|
248
|
-
* **`geoJsonLayer`**: `[str]` → The URL of the GeoJSON layer to use.
|
|
249
|
-
* ** Note **: Must be a FeatureCollection
|
|
250
|
-
* **`geoJsonProp`**: `[str]` →
|
|
251
|
-
* The `properties` key (from the object fetched from the `geoJsonLayer` URL) to match with `geoJsonValue`.
|
|
252
|
-
* **`geoJsonValue`**: `[list[str]]` → A list of geoJsonValue keys that correspond to `geoJsonProp`.
|
|
253
|
-
* ** Note **: All corresponding geometries must be of similar type:
|
|
254
|
-
* `Point` and `MultiPoint`
|
|
255
|
-
* `LineString` and `MultiLineString`
|
|
256
|
-
* `Polygon` and `MultiPolygon`
|
|
257
|
-
|
|
258
|
-
Returns:
|
|
259
|
-
|
|
260
|
-
* `[dict]` → The serialized location structure.
|
|
261
|
-
"""
|
|
262
|
-
geojson_object = requests.get(geoJsonLayer).json()
|
|
263
|
-
if geojson_object["type"] != "FeatureCollection":
|
|
264
|
-
raise ValueError("geoJsonLayer must be a FeatureCollection.")
|
|
265
|
-
|
|
266
|
-
requested_geometries = []
|
|
267
|
-
for feature in geojson_object["features"]:
|
|
268
|
-
if (
|
|
269
|
-
geoJsonProp in feature["properties"]
|
|
270
|
-
and feature["properties"][geoJsonProp] in geoJsonValue
|
|
271
|
-
):
|
|
272
|
-
requested_geometries.append(feature["geometry"])
|
|
273
|
-
|
|
274
|
-
requested_geometry_types = {geometry["type"] for geometry in requested_geometries}
|
|
275
|
-
if requested_geometry_types.issubset({"Point", "MultiPoint"}):
|
|
276
|
-
return self.__serialize_geojson_points__(requested_geometries)
|
|
277
|
-
elif requested_geometry_types.issubset({"LineString", "MultiLineString"}):
|
|
278
|
-
return self.__serialize_geojson_lines__(requested_geometries)
|
|
279
|
-
elif requested_geometry_types.issubset({"Polygon", "MultiPolygon"}):
|
|
280
|
-
return self.__serialize_geojson_polygons__(requested_geometries)
|
|
281
|
-
else:
|
|
282
|
-
raise ValueError(
|
|
283
|
-
f"Requested geometries must be of similar type but got {requested_geometry_types}."
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
def __serialize_geojson_points__(
|
|
287
|
-
self, geometries: list[dict[str, str | list[float | int] | list[list[float | int]]]]
|
|
288
|
-
):
|
|
289
|
-
"""
|
|
290
|
-
Serializes the given GeoJSON-format geometries in this coordinate system to a dictionary of the proper format to be used under `mapFeatures.data.*.data.location`.
|
|
291
|
-
|
|
292
|
-
Arguments:
|
|
293
|
-
|
|
294
|
-
* **`geometries`**: `list[dict[str]]` → The GeoJSON geometries to serialize.
|
|
295
|
-
* ** Note **: Geometry types must be either `Point` or `MultiPoint`
|
|
296
|
-
|
|
297
|
-
Returns:
|
|
298
|
-
|
|
299
|
-
* `[dict]` → The serialized location structure.
|
|
300
|
-
"""
|
|
301
|
-
point_coordinates = []
|
|
302
|
-
for geometry in geometries:
|
|
303
|
-
if geometry["type"] == "Point":
|
|
304
|
-
point_coordinates.append(geometry["coordinates"])
|
|
305
|
-
elif geometry["type"] == "MultiPoint":
|
|
306
|
-
for point_coordinate in geometry["coordinates"]:
|
|
307
|
-
point_coordinates.append(point_coordinate)
|
|
308
|
-
else:
|
|
309
|
-
raise ValueError("Geometries must all have type Point or MultiPoint.")
|
|
310
|
-
return self.serialize_nodes(point_coordinates)
|
|
311
|
-
|
|
312
|
-
def __serialize_geojson_lines__(
|
|
313
|
-
self,
|
|
314
|
-
geometries: list[dict[str, str | list[list[float | int]] | list[list[list[float | int]]]]],
|
|
315
|
-
):
|
|
316
|
-
"""
|
|
317
|
-
Serializes the given GeoJSON-format geometries in this coordinate system to a dictionary of the proper format to be used under `mapFeatures.data.*.data.location`.
|
|
318
|
-
|
|
319
|
-
Arguments:
|
|
320
|
-
|
|
321
|
-
* **`geometries`**: `list[dict[str]]` → The GeoJSON geometries to serialize.
|
|
322
|
-
* ** Note **: Geometry types must be either `LineString` or `MultiLineString`
|
|
323
|
-
|
|
324
|
-
Returns:
|
|
325
|
-
|
|
326
|
-
* `[dict]` → The serialized location structure.
|
|
327
|
-
"""
|
|
328
|
-
line_coordinates = []
|
|
329
|
-
for geometry in geometries:
|
|
330
|
-
if geometry["type"] == "LineString":
|
|
331
|
-
line_coordinates.append(geometry["coordinates"])
|
|
332
|
-
elif geometry["type"] == "MultiLineString":
|
|
333
|
-
for line_coordinate in geometry["coordinates"]:
|
|
334
|
-
line_coordinates.append(line_coordinate)
|
|
335
|
-
else:
|
|
336
|
-
raise ValueError("Geometries must all have type LineString or MultiLineString.")
|
|
337
|
-
return self.serialize_arcs(line_coordinates)
|
|
338
|
-
|
|
339
|
-
def __serialize_geojson_polygons__(
|
|
340
|
-
self,
|
|
341
|
-
geometries: list[
|
|
342
|
-
dict[str, str | list[list[list[float | int]]] | list[list[list[list[float | int]]]]]
|
|
343
|
-
],
|
|
344
|
-
):
|
|
345
|
-
"""
|
|
346
|
-
Serializes the given GeoJSON-format geometries in this coordinate system to a dictionary of the proper format to be used under `mapFeatures.data.*.data.location`.
|
|
347
|
-
|
|
348
|
-
Arguments:
|
|
349
|
-
|
|
350
|
-
* **`geometries`**: `list[dict[str]]` → The GeoJSON geometries to serialize.
|
|
351
|
-
* ** Notes **:
|
|
352
|
-
* Geometry types must be either `Polygon` or `MultiPolygon`
|
|
353
|
-
* Polygon holes are not fully supported; two separate polygons will be displayed instead.
|
|
354
|
-
|
|
355
|
-
Returns:
|
|
356
|
-
|
|
357
|
-
* `[dict]` → The serialized location structure.
|
|
358
|
-
"""
|
|
359
|
-
polygon_coordinates = []
|
|
360
|
-
for geometry in geometries:
|
|
361
|
-
if geometry["type"] == "Polygon":
|
|
362
|
-
polygon_coordinates.extend(geometry["coordinates"])
|
|
363
|
-
elif geometry["type"] == "MultiPolygon":
|
|
364
|
-
for polygon_coordinate in geometry["coordinates"]:
|
|
365
|
-
polygon_coordinates.extend(polygon_coordinate)
|
|
366
|
-
else:
|
|
367
|
-
raise ValueError("Geometries must all have type Polygon or MultiPolygon.")
|
|
368
|
-
return self.serialize_arcs(polygon_coordinates)
|
|
233
|
+
self.convert_coordinates(geojson_filepath["coordinates"])
|
|
234
|
+
with open(output_filepath, "w") as f:
|
|
235
|
+
json.dump(geojson_filepath, f)
|
|
236
|
+
print(f"GeoJSON converted and saved to {output_filepath}.")
|
|
369
237
|
|
|
370
238
|
def __validate_coordinate_system__(self):
|
|
371
239
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|