diff --git a/opengeodeweb_viewer_schemas.json b/opengeodeweb_viewer_schemas.json index 0c3aa9b3..47ffb9db 100644 --- a/opengeodeweb_viewer_schemas.json +++ b/opengeodeweb_viewer_schemas.json @@ -234,6 +234,38 @@ "name" ], "additionalProperties": false + }, + "color_map": { + "$id": "opengeodeweb_viewer.mesh.edges.attribute.edge.color_map", + "rpc": "color_map", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "points": { + "type": "array", + "description": "Flat array of [value, r, g, b, ...]", + "items": { + "type": "number" + }, + "minItems": 8 + }, + "minimum": { + "type": "number" + }, + "maximum": { + "type": "number" + } + }, + "required": [ + "id", + "points", + "minimum", + "maximum" + ], + "additionalProperties": false } }, "vertex": { diff --git a/requirements.txt b/requirements.txt index 5750c624..13efd779 100644 --- a/requirements.txt +++ b/requirements.txt @@ -61,4 +61,3 @@ wslink==1.12.4 yarl>=1 # via aiohttp -opengeodeweb-microservice==1.*,>=1.1.1 diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/edges_attribute_edge_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/edges_attribute_edge_protocols.py index 30c3ccfc..f95eb994 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/edges_attribute_edge_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/edges_attribute_edge_protocols.py @@ -35,3 +35,16 @@ def setMeshEdgesEdgeName(self, rpc_params: RpcParams) -> None: ) params = schemas.Name.from_dict(rpc_params) self.displayAttributeOnCells(params.id, params.name) + + @exportRpc( + mesh_edges_attribute_edge_prefix + + mesh_edges_attribute_edge_schemas_dict["color_map"]["rpc"] + ) + def setMeshEdgesEdgeColorMap(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, + self.mesh_edges_attribute_edge_schemas_dict["color_map"], + self.mesh_edges_attribute_edge_prefix, + ) + params = schemas.ColorMap.from_dict(rpc_params) + self.setupColorMap(params.id, params.points, params.minimum, params.maximum) diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/__init__.py index 1faac9b8..ef745855 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/__init__.py @@ -1 +1,2 @@ from .name import * +from .color_map import * diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/color_map.json b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/color_map.json new file mode 100644 index 00000000..95737cc6 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/color_map.json @@ -0,0 +1,26 @@ +{ + "rpc": "color_map", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "points": { + "type": "array", + "description": "Flat array of [value, r, g, b, ...]", + "items": { + "type": "number" + }, + "minItems": 8 + }, + "minimum": { + "type": "number" + }, + "maximum": { + "type": "number" + } + }, + "required": ["id", "points", "minimum", "maximum"], + "additionalProperties": false +} diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/color_map.py b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/color_map.py new file mode 100644 index 00000000..7fbb9d2a --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/attribute/edge/schemas/color_map.py @@ -0,0 +1,15 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class ColorMap(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + id: str + maximum: float + minimum: float + points: List[float] + """Flat array of [value, r, g, b, ...]""" diff --git a/tests/data/123456789/edged_curve3D.vtp b/tests/data/123456789/edged_curve3D.vtp new file mode 100644 index 00000000..d3f78ce0 --- /dev/null +++ b/tests/data/123456789/edged_curve3D.vtp @@ -0,0 +1,21 @@ + + + + + + 0.10942 0.532085 1 0.0989554 0.440531 1 0.127689 0.326914 1 -0.0570336 0.453631 1 -0.0440269 0.283532 1 0.0785397 0.338299 1 -0.014577 0.077456 1 0.155983 0.163299 1 0.0333169 0.16082 1 0.321452 0.0802363 1 0.355327 0.212219 1 0.252025 0.158717 1 0.428656 0.359 1 0.299515 0.365925 1 0.316268 0.303525 1 0.318692 0.624577 1 0.210924 0.577468 1 0.314173 0.57517 1 -0.0731802 0.632736 1 -0.0996019 0.598172 1 -0.162041 0.600724 1 -0.147729 0.444528 1 -0.0853436 0.517832 1 -0.0996019 0.598172 1 0.0963617 0.532762 1 0.10407 0.544358 1 -0.195351 0.421707 1 -0.105346 0.266847 1 -0.0987086 0.302912 1 -0.105346 0.266847 1 -0.115428 0.266928 1 -0.118175 0.257315 1 -0.0859438 0.0429719 1 -0.0351803 0.0175902 1 -0.0351803 0.0175902 1 -0.106668 0.248327 1 -0.118175 0.257315 1 + + + 0.109419576823711 0.53208464384079 1 0.0989554226398468 0.440531343221664 1 0.127689048647881 0.326913595199585 1 -0.0570335872471333 0.453630566596985 1 -0.0440268628299236 0.283532381057739 1 0.0785397067666054 0.338299185037613 1 -0.0145769733935595 0.0774560123682022 1 0.155983060598373 0.163299322128296 1 0.0333169139921665 0.160820126533508 1 0.32145157456398 0.0802362933754921 1 0.35532745718956 0.212218835949898 1 0.252025336027145 0.158717021346092 1 0.428656339645386 0.358999729156494 1 0.29951485991478 0.365925401449203 1 0.316268235445023 0.303525328636169 1 0.31869176030159 0.624576926231384 1 0.210924133658409 0.577467858791351 1 0.314173072576523 0.57517009973526 1 -0.0731801614165306 0.632735967636108 1 -0.0996019020676613 0.598172128200531 1 -0.162041246891022 0.600724041461945 1 -0.147729307413101 0.444528311491013 1 -0.0853436291217804 0.517831742763519 1 -0.0996019020676613 0.598172128200531 1 0.0963616594672203 0.532761991024017 1 0.104069948196411 0.544358432292938 1 -0.195351168513298 0.42170724272728 1 -0.105345673859119 0.266847312450409 1 -0.0987086147069931 0.302912443876266 1 -0.105345673859119 0.266847312450409 1 -0.115427635610104 0.266927510499954 1 -0.118174657225609 0.257315069437027 1 -0.0859437808394432 0.0429718904197216 1 -0.0351803153753281 0.017590157687664 1 -0.0351803153753281 0.017590157687664 1 -0.106668494641781 0.248327031731606 1 -0.118174657225609 0.257315069437027 1 + + + 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 6 6 6 6 6 7 7 7 8 8 8 8 8 8 8 8 + 0 1 1 2 0 2 3 4 4 5 3 5 6 7 7 8 6 8 9 10 10 11 9 11 12 13 13 14 12 14 15 16 16 17 15 17 18 19 19 20 20 21 21 22 22 23 23 24 24 25 18 25 26 27 27 28 26 28 29 30 30 31 31 32 32 33 33 34 34 35 35 36 29 36 + + + 0 1 1 2 0 2 3 4 4 5 3 5 6 7 7 8 6 8 9 10 10 11 9 11 12 13 13 14 12 14 15 16 16 17 15 17 18 19 19 20 20 21 21 22 22 23 23 24 24 25 18 25 26 27 27 28 26 28 29 30 30 31 31 32 32 33 33 34 34 35 35 36 29 36 + 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 + + + + diff --git a/tests/data/edged_curve3D.vtp b/tests/data/edged_curve3D.vtp new file mode 100644 index 00000000..d3f78ce0 --- /dev/null +++ b/tests/data/edged_curve3D.vtp @@ -0,0 +1,21 @@ + + + + + + 0.10942 0.532085 1 0.0989554 0.440531 1 0.127689 0.326914 1 -0.0570336 0.453631 1 -0.0440269 0.283532 1 0.0785397 0.338299 1 -0.014577 0.077456 1 0.155983 0.163299 1 0.0333169 0.16082 1 0.321452 0.0802363 1 0.355327 0.212219 1 0.252025 0.158717 1 0.428656 0.359 1 0.299515 0.365925 1 0.316268 0.303525 1 0.318692 0.624577 1 0.210924 0.577468 1 0.314173 0.57517 1 -0.0731802 0.632736 1 -0.0996019 0.598172 1 -0.162041 0.600724 1 -0.147729 0.444528 1 -0.0853436 0.517832 1 -0.0996019 0.598172 1 0.0963617 0.532762 1 0.10407 0.544358 1 -0.195351 0.421707 1 -0.105346 0.266847 1 -0.0987086 0.302912 1 -0.105346 0.266847 1 -0.115428 0.266928 1 -0.118175 0.257315 1 -0.0859438 0.0429719 1 -0.0351803 0.0175902 1 -0.0351803 0.0175902 1 -0.106668 0.248327 1 -0.118175 0.257315 1 + + + 0.109419576823711 0.53208464384079 1 0.0989554226398468 0.440531343221664 1 0.127689048647881 0.326913595199585 1 -0.0570335872471333 0.453630566596985 1 -0.0440268628299236 0.283532381057739 1 0.0785397067666054 0.338299185037613 1 -0.0145769733935595 0.0774560123682022 1 0.155983060598373 0.163299322128296 1 0.0333169139921665 0.160820126533508 1 0.32145157456398 0.0802362933754921 1 0.35532745718956 0.212218835949898 1 0.252025336027145 0.158717021346092 1 0.428656339645386 0.358999729156494 1 0.29951485991478 0.365925401449203 1 0.316268235445023 0.303525328636169 1 0.31869176030159 0.624576926231384 1 0.210924133658409 0.577467858791351 1 0.314173072576523 0.57517009973526 1 -0.0731801614165306 0.632735967636108 1 -0.0996019020676613 0.598172128200531 1 -0.162041246891022 0.600724041461945 1 -0.147729307413101 0.444528311491013 1 -0.0853436291217804 0.517831742763519 1 -0.0996019020676613 0.598172128200531 1 0.0963616594672203 0.532761991024017 1 0.104069948196411 0.544358432292938 1 -0.195351168513298 0.42170724272728 1 -0.105345673859119 0.266847312450409 1 -0.0987086147069931 0.302912443876266 1 -0.105345673859119 0.266847312450409 1 -0.115427635610104 0.266927510499954 1 -0.118174657225609 0.257315069437027 1 -0.0859437808394432 0.0429718904197216 1 -0.0351803153753281 0.017590157687664 1 -0.0351803153753281 0.017590157687664 1 -0.106668494641781 0.248327031731606 1 -0.118174657225609 0.257315069437027 1 + + + 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 6 6 6 6 6 7 7 7 8 8 8 8 8 8 8 8 + 0 1 1 2 0 2 3 4 4 5 3 5 6 7 7 8 6 8 9 10 10 11 9 11 12 13 13 14 12 14 15 16 16 17 15 17 18 19 19 20 20 21 21 22 22 23 23 24 24 25 18 25 26 27 27 28 26 28 29 30 30 31 31 32 32 33 33 34 34 35 35 36 29 36 + + + 0 1 1 2 0 2 3 4 4 5 3 5 6 7 7 8 6 8 9 10 10 11 9 11 12 13 13 14 12 14 15 16 16 17 15 17 18 19 19 20 20 21 21 22 22 23 23 24 24 25 18 25 26 27 27 28 26 28 29 30 30 31 31 32 32 33 33 34 34 35 35 36 29 36 + 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 + + + + diff --git a/tests/data/images/mesh/edges/edge_color_map.jpeg b/tests/data/images/mesh/edges/edge_color_map.jpeg new file mode 100644 index 00000000..96d4388f Binary files /dev/null and b/tests/data/images/mesh/edges/edge_color_map.jpeg differ diff --git a/tests/data/images/mesh/edges/edge_color_map_rainbow.jpeg b/tests/data/images/mesh/edges/edge_color_map_rainbow.jpeg new file mode 100644 index 00000000..5c3ad58e Binary files /dev/null and b/tests/data/images/mesh/edges/edge_color_map_rainbow.jpeg differ diff --git a/tests/data/images/mesh/edges/edge_color_map_rainbow_initial.jpeg b/tests/data/images/mesh/edges/edge_color_map_rainbow_initial.jpeg new file mode 100644 index 00000000..3d4e5cf4 Binary files /dev/null and b/tests/data/images/mesh/edges/edge_color_map_rainbow_initial.jpeg differ diff --git a/tests/data/images/mesh/edges/edge_color_map_range_update.jpeg b/tests/data/images/mesh/edges/edge_color_map_range_update.jpeg new file mode 100644 index 00000000..13bbff62 Binary files /dev/null and b/tests/data/images/mesh/edges/edge_color_map_range_update.jpeg differ diff --git a/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py b/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py index 6fd6c973..54bf313d 100644 --- a/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py +++ b/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py @@ -18,7 +18,7 @@ def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> dataset_factory( id=mesh_id, - viewable_file="attributed_edged_curve.vtp", + viewable_file="edged_curve3D.vtp", viewer_elements_type="edges", ) @@ -26,3 +26,236 @@ def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["register"]["rpc"], [{"id": mesh_id}], ) + + +def test_edges_edge_color_map( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register(server, dataset_factory) + + # Set active attribute (cycle_id) + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict["name"][ + "rpc" + ], + [{"id": mesh_id, "name": "cycle_id"}], + ) + + # Set color map: Blue to Red + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict[ + "color_map" + ]["rpc"], + [ + { + "id": mesh_id, + "points": [ + 0.0, + 0, + 0, + 1.0, + 8.0, + 1.0, + 0, + 0, + ], + "minimum": 0.0, + "maximum": 8.0, + } + ], + ) + + assert server.compare_image("mesh/edges/edge_color_map.jpeg") == True + + +def test_edges_edge_color_map_range_update( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register(server, dataset_factory) + + # Set active attribute + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict["name"][ + "rpc" + ], + [{"id": mesh_id, "name": "cycle_id"}], + ) + + # Set Blue to Red Map + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict[ + "color_map" + ]["rpc"], + [ + { + "id": mesh_id, + "points": [ + 0.0, + 0, + 0, + 1.0, + 8.0, + 1.0, + 0, + 0, + ], + "minimum": 0.0, + "maximum": 8.0, + } + ], + ) + + assert server.compare_image("mesh/edges/edge_color_map.jpeg") == True + + # Update range via color map + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict[ + "color_map" + ]["rpc"], + [ + { + "id": mesh_id, + "points": [ + 4.0, + 0, + 0, + 1.0, + 8.0, + 1.0, + 0, + 0, + ], + "minimum": 4.0, + "maximum": 8.0, + } + ], + ) + + assert server.compare_image("mesh/edges/edge_color_map_range_update.jpeg") == True + + +def test_edges_edge_color_map_rainbow( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register(server, dataset_factory) + + # Set active attribute + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict["name"][ + "rpc" + ], + [{"id": mesh_id, "name": "cycle_id"}], + ) + + # Rainbow Desaturated Map + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict[ + "color_map" + ]["rpc"], + [ + { + "id": mesh_id, + "points": [ + 0.0, + 71 / 255, + 71 / 255, + 219 / 255, + 0.143 * 8, + 0, + 0, + 92 / 255, + 0.285 * 8, + 0, + 255 / 255, + 255 / 255, + 0.429 * 8, + 0, + 128 / 255, + 0, + 0.571 * 8, + 255 / 255, + 255 / 255, + 0, + 0.714 * 8, + 255 / 255, + 97 / 255, + 0, + 0.857 * 8, + 107 / 255, + 0, + 0, + 8.0, + 224 / 255, + 77 / 255, + 77 / 255, + ], + "minimum": 0.0, + "maximum": 8.0, + } + ], + ) + + assert ( + server.compare_image("mesh/edges/edge_color_map_rainbow_initial.jpeg") == True + ) + + # Update rainbow range via color map + server.call( + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_prefix + + VtkMeshEdgesAttributeEdgeView.mesh_edges_attribute_edge_schemas_dict[ + "color_map" + ]["rpc"], + [ + { + "id": mesh_id, + "points": [ + 2.0, + 71 / 255, + 71 / 255, + 219 / 255, + 2.0 + 0.143 * 4, + 0, + 0, + 92 / 255, + 2.0 + 0.285 * 4, + 0, + 255 / 255, + 255 / 255, + 2.0 + 0.429 * 4, + 0, + 128 / 255, + 0, + 2.0 + 0.571 * 4, + 255 / 255, + 255 / 255, + 0, + 2.0 + 0.714 * 4, + 255 / 255, + 97 / 255, + 0, + 2.0 + 0.857 * 4, + 107 / 255, + 0, + 0, + 6.0, + 224 / 255, + 77 / 255, + 77 / 255, + ], + "minimum": 2.0, + "maximum": 6.0, + } + ], + ) + + assert server.compare_image("mesh/edges/edge_color_map_rainbow.jpeg") == True