diff --git a/requirements.txt b/requirements.txt index 3dd352e..08d64bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -60,4 +60,3 @@ werkzeug==3.1.2 # flask # flask-cors -opengeodeweb-microservice==1.*,>=1.0.14rc1 diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 9f94eef..156f690 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -2,6 +2,7 @@ import os import time import shutil +import math from typing import Any # Third party imports @@ -267,28 +268,30 @@ def texture_coordinates() -> flask.Response: return flask.make_response({"texture_coordinates": texture_coordinates}, 200) -def attributes_metadata(manager: og.AttributeManager) -> dict[str, list[float]]: - metadata: dict[str, list[float]] = {} +def attributes_metadata(manager: og.AttributeManager) -> list[dict[str, str | float]]: + attributes: list[dict[str, str | float]] = [] + nb_elements = manager.nb_elements() for name in manager.attribute_names(): attribute = manager.find_generic_attribute(name) - if not attribute.is_genericable(): - metadata[name] = [-1.0, -1.0] - continue - min_value = None - max_value = None - nb_items = attribute.nb_items() - for i in range(nb_items): - generic_value = attribute.generic_value(i) - if min_value is None or generic_value < min_value: - min_value = generic_value - if max_value is None or generic_value > max_value: - max_value = generic_value - metadata[name] = ( - [min_value, max_value] - if min_value is not None and max_value is not None - else [-1.0, -1.0] + min_value, max_value = -1.0, -1.0 + if attribute.is_genericable(): + values = [] + nb_items = attribute.nb_items() + for index in range(nb_elements): + for item in range(nb_items): + value = attribute.generic_item_value(index, item) + values.append(value) + + valid_values = [ + value for value in values if value is not None and not math.isnan(value) + ] + if valid_values: + min_value, max_value = min(valid_values), max(valid_values) + + attributes.append( + {"attribute_name": name, "min_value": min_value, "max_value": max_value} ) - return metadata + return attributes @routes.route( @@ -305,10 +308,7 @@ def vertex_attribute_names() -> flask.Response: flask.abort(400, f"{params.id} is not a GeodeMesh") attribute_manager = geode_object.vertex_attribute_manager() return flask.make_response( - { - "vertex_attribute_names": attribute_manager.attribute_names(), - "vertex_attribute_metadata": attributes_metadata(attribute_manager), - }, + {"attributes": attributes_metadata(attribute_manager)}, 200, ) @@ -327,10 +327,7 @@ def cell_attribute_names() -> flask.Response: flask.abort(400, f"{params.id} is not a GeodeGrid") attribute_manager = geode_object.cell_attribute_manager() return flask.make_response( - { - "cell_attribute_names": attribute_manager.attribute_names(), - "cell_attribute_metadata": attributes_metadata(attribute_manager), - }, + {"attributes": attributes_metadata(attribute_manager)}, 200, ) @@ -349,10 +346,7 @@ def polygon_attribute_names() -> flask.Response: flask.abort(400, f"{params.id} is not a GeodeSurfaceMesh") attribute_manager = geode_object.polygon_attribute_manager() return flask.make_response( - { - "polygon_attribute_names": attribute_manager.attribute_names(), - "polygon_attribute_metadata": attributes_metadata(attribute_manager), - }, + {"attributes": attributes_metadata(attribute_manager)}, 200, ) @@ -371,10 +365,7 @@ def polyhedron_attribute_names() -> flask.Response: flask.abort(400, f"{params.id} is not a GeodeSolidMesh") attribute_manager = geode_object.polyhedron_attribute_manager() return flask.make_response( - { - "polyhedron_attribute_names": attribute_manager.attribute_names(), - "polyhedron_attribute_metadata": attributes_metadata(attribute_manager), - }, + {"attributes": attributes_metadata(attribute_manager)}, 200, ) @@ -393,10 +384,7 @@ def edge_attribute_names() -> flask.Response: flask.abort(400, f"{params.id} does not have edges") attribute_manager = geode_object.edge_attribute_manager() return flask.make_response( - { - "edge_attribute_names": attribute_manager.attribute_names(), - "edge_attribute_metadata": attributes_metadata(attribute_manager), - }, + {"attributes": attributes_metadata(attribute_manager)}, 200, ) diff --git a/tests/test_routes.py b/tests/test_routes.py index f669f55..4865677 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -246,13 +246,12 @@ def test_vertex_attribute_names(client: FlaskClient, test_id: str) -> None: assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) assert response.status_code == 200 - vertex_attribute_names = response.get_json()["vertex_attribute_names"] - vertex_attribute_metadata = response.get_json()["vertex_attribute_metadata"] - assert type(vertex_attribute_names) is list - assert type(vertex_attribute_metadata) is dict - for vertex_attribute_name in vertex_attribute_names: - assert type(vertex_attribute_name) is str - assert vertex_attribute_name in vertex_attribute_metadata + attributes = response.get_json()["attributes"] + assert type(attributes) is list + for attribute in attributes: + assert "attribute_name" in attribute + assert "min_value" in attribute + assert "max_value" in attribute def test_cell_attribute_names(client: FlaskClient, test_id: str) -> None: @@ -276,13 +275,12 @@ def test_cell_attribute_names(client: FlaskClient, test_id: str) -> None: assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) assert response.status_code == 200 - cell_attribute_names = response.get_json()["cell_attribute_names"] - cell_attribute_metadata = response.get_json()["cell_attribute_metadata"] - assert type(cell_attribute_names) is list - assert type(cell_attribute_metadata) is dict - for cell_attribute_name in cell_attribute_names: - assert type(cell_attribute_name) is str - assert cell_attribute_name in cell_attribute_metadata + attributes = response.get_json()["attributes"] + assert type(attributes) is list + for attribute in attributes: + assert "attribute_name" in attribute + assert "min_value" in attribute + assert "max_value" in attribute def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: @@ -306,13 +304,12 @@ def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) assert response.status_code == 200 - polygon_attribute_names = response.get_json()["polygon_attribute_names"] - polygon_attribute_metadata = response.get_json()["polygon_attribute_metadata"] - assert type(polygon_attribute_names) is list - assert type(polygon_attribute_metadata) is dict - for polygon_attribute_name in polygon_attribute_names: - assert type(polygon_attribute_name) is str - assert polygon_attribute_name in polygon_attribute_metadata + attributes = response.get_json()["attributes"] + assert type(attributes) is list + for attribute in attributes: + assert "attribute_name" in attribute + assert "min_value" in attribute + assert "max_value" in attribute def test_polyhedron_attribute_names(client: FlaskClient, test_id: str) -> None: @@ -337,16 +334,15 @@ def test_polyhedron_attribute_names(client: FlaskClient, test_id: str) -> None: response = client.post(route, json={"id": data.id}) print(response.get_json()) assert response.status_code == 200 - polyhedron_attribute_names = response.get_json()["polyhedron_attribute_names"] - polyhedron_attribute_metadata = response.get_json()["polyhedron_attribute_metadata"] - assert type(polyhedron_attribute_names) is list - assert type(polyhedron_attribute_metadata) is dict - for polyhedron_attribute_name in polyhedron_attribute_names: - assert type(polyhedron_attribute_name) is str - assert polyhedron_attribute_name in polyhedron_attribute_metadata - - if "Range" in polyhedron_attribute_metadata: - assert polyhedron_attribute_metadata["Range"] == [0.0, 579.0] + attributes = response.get_json()["attributes"] + assert type(attributes) is list + for attribute in attributes: + assert "attribute_name" in attribute + assert "min_value" in attribute + assert "max_value" in attribute + if attribute["attribute_name"] == "Range": + assert attribute["min_value"] == 0.0 + assert attribute["max_value"] == 579.0 def test_edge_attribute_names(client: FlaskClient, test_id: str) -> None: @@ -371,13 +367,12 @@ def test_edge_attribute_names(client: FlaskClient, test_id: str) -> None: response = client.post(route, json={"id": data.id}) print(response.get_json()) assert response.status_code == 200 - edge_attribute_names = response.get_json()["edge_attribute_names"] - edge_attribute_metadata = response.get_json()["edge_attribute_metadata"] - assert type(edge_attribute_names) is list - assert type(edge_attribute_metadata) is dict - for edge_attribute_name in edge_attribute_names: - assert type(edge_attribute_name) is str - assert edge_attribute_name in edge_attribute_metadata + attributes = response.get_json()["attributes"] + assert type(attributes) is list + for attribute in attributes: + assert "attribute_name" in attribute + assert "min_value" in attribute + assert "max_value" in attribute def test_database_uri_path(client: FlaskClient) -> None: