Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions requirements-internal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --cert=None --client-cert=None --index-url=None --pip-args=None requirements-internal.in
#
blinker==1.9.0
# via
# flask
# opengeodeweb-microservice
click==8.3.0
# via
# flask
# opengeodeweb-microservice
fastjsonschema==2.21.1
# via opengeodeweb-microservice
flask==3.1.2
# via
# flask-sqlalchemy
# opengeodeweb-microservice
flask-sqlalchemy==3.1.1
# via opengeodeweb-microservice
greenlet==3.2.4
# via
# opengeodeweb-microservice
# sqlalchemy
itsdangerous==2.2.0
# via
# flask
# opengeodeweb-microservice
jinja2==3.1.6
# via
# flask
# opengeodeweb-microservice
markupsafe==3.0.3
# via
# flask
# jinja2
# opengeodeweb-microservice
# werkzeug
opengeodeweb-microservice==1.0.3
# via -r requirements-internal.in
sqlalchemy==2.0.43
# via
# flask-sqlalchemy
# opengeodeweb-microservice
typing-extensions==4.15.0
# via
# opengeodeweb-microservice
# sqlalchemy
werkzeug==3.1.3
# via
# flask
# opengeodeweb-microservice
2 changes: 1 addition & 1 deletion requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ geode-viewables==3.3.0
flask[async]==3.1.2
flask-cors==6.0.1
werkzeug==3.1.2
flask-sqlalchemy==3.1.1
flask-sqlalchemy==3.1.1
41 changes: 9 additions & 32 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,39 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=./requirements.txt --pre ./requirements-internal.in ./requirements.in
# pip-compile --output-file=./requirements.txt --pre ./requirements.in
#
asgiref~=3.10
# via flask
blinker~=1.9
# via
# flask
# opengeodeweb-microservice
# via flask
click~=8.3
# via
# flask
# opengeodeweb-microservice
fastjsonschema~=2.21
# via opengeodeweb-microservice
# via flask
flask[async]~=3.1
# via
# -r requirements.in
# flask-cors
# flask-sqlalchemy
# opengeodeweb-microservice
flask-cors==6.0.1
# via -r requirements.in
flask-sqlalchemy==3.1.1
# via
# -r requirements.in
# opengeodeweb-microservice
# via -r requirements.in
geode-common==33.11.0
# via
# -r requirements.in
# geode-viewables
geode-viewables==3.3.0
# via -r requirements.in
greenlet~=3.2
# via
# opengeodeweb-microservice
# sqlalchemy
# via sqlalchemy
itsdangerous~=2.2
# via
# flask
# opengeodeweb-microservice
# via flask
jinja2~=3.1
# via
# flask
# opengeodeweb-microservice
# via flask
markupsafe~=3.0
# via
# flask
# jinja2
# opengeodeweb-microservice
# werkzeug
opengeode-core==15.27.4
# via
Expand All @@ -75,19 +59,12 @@ opengeode-io==7.4.0
# -r requirements.in
# geode-viewables
# opengeode-geosciencesio
opengeodeweb-microservice~=1.0,>=1.0.3
# via -r requirements-internal.in
sqlalchemy~=2.0
# via
# flask-sqlalchemy
# opengeodeweb-microservice
# via flask-sqlalchemy
typing-extensions~=4.15
# via
# opengeodeweb-microservice
# sqlalchemy
# via sqlalchemy
werkzeug==3.1.2
# via
# -r requirements.in
# flask
# flask-cors
# opengeodeweb-microservice
7 changes: 7 additions & 0 deletions src/opengeodeweb_back/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from opengeodeweb_back import utils_functions, app_config
from opengeodeweb_back.routes import blueprint_routes
from opengeodeweb_back.routes.models import blueprint_models
from opengeodeweb_back.routes.create import blueprint_create
from opengeodeweb_microservice.database.connection import init_database


Expand Down Expand Up @@ -51,6 +52,12 @@
name="opengeodeweb_models",
)

app.register_blueprint(
blueprint_create.routes,
url_prefix="/opengeodeweb_back/create",
name="opengeodeweb_create",
)

if FLASK_DEBUG == False:
utils_functions.set_interval(
utils_functions.kill_task, SECONDS_BETWEEN_SHUTDOWNS, app
Expand Down
28 changes: 2 additions & 26 deletions src/opengeodeweb_back/routes/blueprint_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

# Local application imports
from .. import geode_functions, utils_functions

from opengeodeweb_microservice.database.data import Data
from opengeodeweb_microservice.database.connection import get_session
from .models import blueprint_models

routes = flask.Blueprint("routes", __name__, url_prefix="/opengeodeweb_back")
Expand All @@ -36,7 +37,6 @@ def teardown_request(exception):
name=blueprint_models.routes.name,
)


schemas = os.path.join(os.path.dirname(__file__), "schemas")

with open(
Expand Down Expand Up @@ -258,30 +258,6 @@ 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)
title = flask.request.get_json()["title"]
x = flask.request.get_json()["x"]
y = flask.request.get_json()["y"]
z = flask.request.get_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]))
builder.set_name(title)
return flask.make_response(
utils_functions.generate_native_viewable_and_light_viewable_from_object(
"PointSet3D", PointSet3D
),
200,
)


with open(os.path.join(schemas, "texture_coordinates.json"), "r") as file:
texture_coordinates_json = json.load(file)

Expand Down
129 changes: 129 additions & 0 deletions src/opengeodeweb_back/routes/create/blueprint_create.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Standard library imports
import json
import os
import uuid

# Third party imports
import flask
import opengeode
import werkzeug

# Local application imports
from opengeodeweb_back import geode_functions, utils_functions
from opengeodeweb_microservice.database.data import Data
from opengeodeweb_microservice.database.connection import get_session
from opengeodeweb_back.utils_functions import save_all_viewables_and_return_info

routes = flask.Blueprint("create", __name__, url_prefix="/opengeodeweb_back/create")

schemas = os.path.join(os.path.dirname(__file__), "schemas")

# Load schema for point creation
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():
"""Endpoint to create a single point in 3D space."""
print(f"create_point : {flask.request=}", flush=True)

utils_functions.validate_request(flask.request, create_point_json)

# Extract data from request
title = flask.request.json["title"]
x = flask.request.json["x"]
y = flask.request.json["y"]
z = flask.request.json["z"]

# Create the point set
class_ = geode_functions.geode_object_class("PointSet3D")
point_set = class_.create()
builder = geode_functions.create_builder("PointSet3D", point_set)
builder.create_point(opengeode.Point3D([x, y, z]))
builder.set_name(title)

# Save and get info
result = save_all_viewables_and_return_info(
geode_object="PointSet3D", data=point_set, input_file=None, additional_files=[]
)

# Prepare response with the title
response = {
"viewable_file_name": result["viewable_file_name"],
"id": result["id"],
"name": title,
"native_file_name": result["native_file_name"],
"object_type": result["object_type"],
"geode_object": result["geode_object"],
}

# Add binary_light_viewable if it exists
if "binary_light_viewable" in result:
response["binary_light_viewable"] = result["binary_light_viewable"]

return flask.make_response(response, 200)


# Load schema for AOI creation
with open(os.path.join(schemas, "create_aoi.json"), "r") as file:
create_aoi_json = json.load(file)


@routes.route(create_aoi_json["route"], methods=create_aoi_json["methods"])
def create_aoi():
"""Endpoint to create an Area of Interest (AOI) as an EdgedCurve3D."""
print(f"create_aoi : {flask.request=}", flush=True)

utils_functions.validate_request(flask.request, create_aoi_json)

# Extract data from request
name = flask.request.json["name"]
points = flask.request.json["points"]
z = flask.request.json["z"]

# Create the edged curve
class_ = geode_functions.geode_object_class("EdgedCurve3D")
edged_curve = class_.create()
builder = geode_functions.create_builder("EdgedCurve3D", edged_curve)
builder.set_name(name)

# Create vertices first
vertex_indices = []
for point in points:
vertex_id = builder.create_point(opengeode.Point3D([point["x"], point["y"], z]))
vertex_indices.append(vertex_id)

# Create edges between consecutive vertices and close the loop
num_vertices = len(vertex_indices)
for i in range(num_vertices):
edge_id = builder.create_edge()
next_i = (i + 1) % num_vertices # Wrap around to close the loop
builder.set_edge_vertex(opengeode.EdgeVertex(edge_id, 0), vertex_indices[i])
builder.set_edge_vertex(
opengeode.EdgeVertex(edge_id, 1), vertex_indices[next_i]
)

# Save and get info
result = save_all_viewables_and_return_info(
geode_object="EdgedCurve3D",
data=edged_curve,
input_file=None,
additional_files=[],
)

# Prepare response
response = {
"viewable_file_name": result["viewable_file_name"],
"id": result["id"],
"name": name,
"native_file_name": result["native_file_name"],
"object_type": result["object_type"],
"geode_object": result["geode_object"],
}

# Add binary_light_viewable if it exists
if "binary_light_viewable" in result:
response["binary_light_viewable"] = result["binary_light_viewable"]

return flask.make_response(response, 200)
46 changes: 46 additions & 0 deletions src/opengeodeweb_back/routes/create/schemas/create_aoi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"route": "/create_aoi",
"methods": [
"POST"
],
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the AOI"
},
"points": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": [
"x",
"y"
],
"additionalProperties": false
},
"minItems": 4,
"maxItems": 4
},
"z": {
"type": "number"
},
"id": {
"type": "string"
}
},
"required": [
"name",
"points",
"z"
],
"additionalProperties": false
}
Loading
Loading