diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index ca29c35c..40868a6c 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -15,6 +15,10 @@ def geode_object_value(geode_object: str): return geode_objects_dict()[geode_object] +def geode_object_class(geode_object: str): + return geode_object_value(geode_object)["class"] + + def input_factory(geode_object: str): return geode_object_value(geode_object)["input_factory"] diff --git a/src/opengeodeweb_back/geode_objects.py b/src/opengeodeweb_back/geode_objects.py index 228c42dd..dbef8a76 100644 --- a/src/opengeodeweb_back/geode_objects.py +++ b/src/opengeodeweb_back/geode_objects.py @@ -9,6 +9,7 @@ def geode_objects_dict(): return { "BRep": { + "class": og.BRep, "input_factory": og.BRepInputFactory, "output_factory": og.BRepOutputFactory, "missing_files": og.check_brep_missing_files, @@ -30,6 +31,7 @@ def geode_objects_dict(): }, "CrossSection": { "parent": "Section", + "class": og_gs.CrossSection, "input_factory": og_gs.CrossSectionInputFactory, "output_factory": og_gs.CrossSectionOutputFactory, "missing_files": og_gs.check_cross_section_missing_files, @@ -50,6 +52,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_section, }, "EdgedCurve2D": { + "class": og.EdgedCurve2D, "input_factory": og.EdgedCurveInputFactory2D, "output_factory": og.EdgedCurveOutputFactory2D, "missing_files": og.check_edged_curve_missing_files2D, @@ -70,6 +73,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_edged_curve2D, }, "EdgedCurve3D": { + "class": og.EdgedCurve3D, "input_factory": og.EdgedCurveInputFactory3D, "output_factory": og.EdgedCurveOutputFactory3D, "missing_files": og.check_edged_curve_missing_files3D, @@ -90,6 +94,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_edged_curve3D, }, "Graph": { + "class": og.Graph, "input_factory": og.GraphInputFactory, "output_factory": og.GraphOutputFactory, "missing_files": og.check_graph_missing_files, @@ -103,6 +108,7 @@ def geode_objects_dict(): "is_viewable": True, }, "HybridSolid3D": { + "class": og.HybridSolid3D, "input_factory": og.HybridSolidInputFactory3D, "output_factory": og.HybridSolidOutputFactory3D, "missing_files": og.check_hybrid_solid_missing_files3D, @@ -124,6 +130,7 @@ def geode_objects_dict(): }, "ImplicitCrossSection": { "parent": "CrossSection", + "class": og_gs.ImplicitCrossSection, "input_factory": og_gs.ImplicitCrossSectionInputFactory, "output_factory": og_gs.ImplicitCrossSectionOutputFactory, "missing_files": og_gs.check_implicit_cross_section_missing_files, @@ -145,6 +152,7 @@ def geode_objects_dict(): }, "ImplicitStructuralModel": { "parent": "StructuralModel", + "class": og_gs.ImplicitStructuralModel, "input_factory": og_gs.ImplicitStructuralModelInputFactory, "output_factory": og_gs.ImplicitStructuralModelOutputFactory, "missing_files": og_gs.check_implicit_structural_model_missing_files, @@ -165,6 +173,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_brep, }, "LightRegularGrid2D": { + "class": og.LightRegularGrid2D, "input_factory": og.LightRegularGridInputFactory2D, "output_factory": og.LightRegularGridOutputFactory2D, "missing_files": og.check_light_regular_grid_missing_files2D, @@ -178,6 +187,7 @@ def geode_objects_dict(): "save_viewable": g_v.save_viewable_light_regular_grid2D, }, "LightRegularGrid3D": { + "class": og.LightRegularGrid3D, "input_factory": og.LightRegularGridInputFactory3D, "output_factory": og.LightRegularGridOutputFactory3D, "missing_files": og.check_light_regular_grid_missing_files3D, @@ -191,6 +201,7 @@ def geode_objects_dict(): "save_viewable": g_v.save_viewable_light_regular_grid3D, }, "PointSet2D": { + "class": og.PointSet2D, "input_factory": og.PointSetInputFactory2D, "output_factory": og.PointSetOutputFactory2D, "missing_files": og.check_point_set_missing_files2D, @@ -211,6 +222,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_point_set2D, }, "PointSet3D": { + "class": og.PointSet3D, "input_factory": og.PointSetInputFactory3D, "output_factory": og.PointSetOutputFactory3D, "missing_files": og.check_point_set_missing_files3D, @@ -231,6 +243,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_point_set3D, }, "PolygonalSurface2D": { + "class": og.PolygonalSurface2D, "input_factory": og.PolygonalSurfaceInputFactory2D, "output_factory": og.PolygonalSurfaceOutputFactory2D, "missing_files": og.check_polygonal_surface_missing_files2D, @@ -251,6 +264,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_surface2D, }, "PolygonalSurface3D": { + "class": og.PolygonalSurface3D, "input_factory": og.PolygonalSurfaceInputFactory3D, "output_factory": og.PolygonalSurfaceOutputFactory3D, "missing_files": og.check_polygonal_surface_missing_files3D, @@ -271,6 +285,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_surface3D, }, "PolyhedralSolid3D": { + "class": og.PolyhedralSolid3D, "input_factory": og.PolyhedralSolidInputFactory3D, "output_factory": og.PolyhedralSolidOutputFactory3D, "missing_files": og.check_polyhedral_solid_missing_files3D, @@ -291,6 +306,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_solid3D, }, "RasterImage2D": { + "class": og.RasterImage2D, "input_factory": og.RasterImageInputFactory2D, "output_factory": og.RasterImageOutputFactory2D, "missing_files": og.check_raster_image_missing_files2D, @@ -304,6 +320,7 @@ def geode_objects_dict(): "save_viewable": g_v.save_viewable_raster_image2D, }, "RasterImage3D": { + "class": og.RasterImage3D, "input_factory": og.RasterImageInputFactory3D, "output_factory": og.RasterImageOutputFactory3D, "missing_files": og.check_raster_image_missing_files3D, @@ -317,6 +334,7 @@ def geode_objects_dict(): "save_viewable": g_v.save_viewable_raster_image3D, }, "RegularGrid2D": { + "class": og.RegularGrid2D, "input_factory": og.RegularGridInputFactory2D, "output_factory": og.RegularGridOutputFactory2D, "missing_files": og.check_regular_grid_missing_files2D, @@ -336,6 +354,7 @@ def geode_objects_dict(): "save_viewable": g_v.save_viewable_regular_grid2D, }, "RegularGrid3D": { + "class": og.RegularGrid3D, "input_factory": og.RegularGridInputFactory3D, "output_factory": og.RegularGridOutputFactory3D, "missing_files": og.check_regular_grid_missing_files3D, @@ -355,6 +374,7 @@ def geode_objects_dict(): "save_viewable": g_v.save_viewable_regular_grid3D, }, "Section": { + "class": og.Section, "input_factory": og.SectionInputFactory, "output_factory": og.SectionOutputFactory, "missing_files": og.check_section_missing_files, @@ -376,6 +396,7 @@ def geode_objects_dict(): }, "StructuralModel": { "parent": "BRep", + "class": og_gs.StructuralModel, "input_factory": og_gs.StructuralModelInputFactory, "output_factory": og_gs.StructuralModelOutputFactory, "missing_files": og_gs.check_structural_model_missing_files, @@ -396,6 +417,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_brep, }, "TetrahedralSolid3D": { + "class": og.TetrahedralSolid3D, "input_factory": og.TetrahedralSolidInputFactory3D, "output_factory": og.TetrahedralSolidOutputFactory3D, "missing_files": og.check_tetrahedral_solid_missing_files3D, @@ -416,6 +438,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_solid3D, }, "TriangulatedSurface2D": { + "class": og.TriangulatedSurface2D, "input_factory": og.TriangulatedSurfaceInputFactory2D, "output_factory": og.TriangulatedSurfaceOutputFactory2D, "missing_files": og.check_triangulated_surface_missing_files2D, @@ -436,6 +459,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_surface2D, }, "TriangulatedSurface3D": { + "class": og.TriangulatedSurface3D, "input_factory": og.TriangulatedSurfaceInputFactory3D, "output_factory": og.TriangulatedSurfaceOutputFactory3D, "missing_files": og.check_triangulated_surface_missing_files3D, @@ -456,6 +480,7 @@ def geode_objects_dict(): "inspector": og_inspector.inspect_surface3D, }, "VertexSet": { + "class": og.VertexSet, "input_factory": og.VertexSetInputFactory, "output_factory": og.VertexSetOutputFactory, "missing_files": og.check_vertex_set_missing_files, diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 5fa558e9..3d4a2c6f 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -5,9 +5,12 @@ # Third party imports import flask -from .. import geode_functions, utils_functions -import werkzeug +import opengeode import uuid +import werkzeug + +# Local application imports +from .. import geode_functions, utils_functions routes = flask.Blueprint("routes", __name__) @@ -271,6 +274,36 @@ def save_viewable_file(): ) +with open(os.path.join(schemas, "create_point.json"), "r") as file: + create_point_json = json.load(file) + + +@routes.route(create_point_json["route"], methods=create_point_json["methods"]) +def create_point(): + utils_functions.validate_request(flask.request, create_point_json) + DATA_FOLDER_PATH = flask.current_app.config["DATA_FOLDER_PATH"] + x = flask.request.json["x"] + y = flask.request.json["y"] + z = flask.request.json["z"] + class_ = geode_functions.geode_object_class("PointSet3D") + PointSet3D = class_.create() + builder = geode_functions.create_builder("PointSet3D", PointSet3D) + builder.create_point(opengeode.Point3D([x, y, z])) + + generated_id = str(uuid.uuid4()).replace("-", "") + saved_viewable_file_path = geode_functions.save_viewable( + "PointSet3D", PointSet3D, DATA_FOLDER_PATH, generated_id + ) + + return flask.make_response( + { + "viewable_file_name": os.path.basename(saved_viewable_file_path), + "id": generated_id, + }, + 200, + ) + + with open( os.path.join(schemas, "ping.json"), "r", diff --git a/src/opengeodeweb_back/routes/schemas/create_point.json b/src/opengeodeweb_back/routes/schemas/create_point.json new file mode 100644 index 00000000..6f77eebf --- /dev/null +++ b/src/opengeodeweb_back/routes/schemas/create_point.json @@ -0,0 +1,24 @@ +{ + "route": "/create_point", + "methods": [ + "POST" + ], + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "z": { + "type": "number" + } + }, + "required": [ + "x", + "y", + "z" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/tests/test_routes.py b/tests/test_routes.py index 0661f025..0320271f 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -185,3 +185,26 @@ def get_full_data(): assert response.status_code == 400 error_description = response.json["description"] assert error_description == f"Validation error: '{key}' is a required property" + + +def test_create_point(client): + route = f"/create_point" + + def get_full_data(): + return {"x": 1, "y": 2, "z": 3} + + # Normal test with all keys + response = client.post(route, json=get_full_data()) + assert response.status_code == 200 + viewable_file_name = response.json["viewable_file_name"] + assert type(viewable_file_name) is str + id = response.json["id"] + assert type(id) is str + + for key, value in get_full_data().items(): + json = get_full_data() + json.pop(key) + response = client.post(route, json=json) + assert response.status_code == 400 + error_description = response.json["description"] + assert error_description == f"Validation error: '{key}' is a required property"