From f00a2143a26bdd7d33858ceeda5b7ec5f9525f86 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Wed, 24 Jun 2026 17:52:33 +0800 Subject: [PATCH] feat(data): VoxelGenerateRequest/SliceGenerateRequest DTO + toJson --- src/data/CMakeLists.txt | 1 + src/data/dto/Vtk3dRequests.cpp | 42 ++++++++++++++++++++++++++++++ src/data/dto/Vtk3dRequests.hpp | 35 +++++++++++++++++++++++++ tests/CMakeLists.txt | 1 + tests/data/test_vtk3d_requests.cpp | 39 +++++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 src/data/dto/Vtk3dRequests.cpp create mode 100644 src/data/dto/Vtk3dRequests.hpp create mode 100644 tests/data/test_vtk3d_requests.cpp diff --git a/src/data/CMakeLists.txt b/src/data/CMakeLists.txt index 6d928a8..57e8a0c 100644 --- a/src/data/CMakeLists.txt +++ b/src/data/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(geopro_data STATIC repo/LocalSampleRepository.cpp repo/LocalSample3dRepository.cpp dto/NavDto.cpp + dto/Vtk3dRequests.cpp dto/DatasetChartDto.cpp dto/MeasurementDto.cpp dto/GrMeasurementDto.cpp diff --git a/src/data/dto/Vtk3dRequests.cpp b/src/data/dto/Vtk3dRequests.cpp new file mode 100644 index 0000000..e80a0be --- /dev/null +++ b/src/data/dto/Vtk3dRequests.cpp @@ -0,0 +1,42 @@ +#include "dto/Vtk3dRequests.hpp" +#include +#include + +namespace geopro::data { + +namespace { +QJsonArray vec3(const std::array& v) { + return QJsonArray{v[0], v[1], v[2]}; +} +QString qs(const std::string& s) { return QString::fromStdString(s); } +} // namespace + +QJsonObject VoxelGenerateRequest::toJson() const { + QJsonArray ids; + for (const auto& s : sourceDatasetIds) ids.append(qs(s)); + QJsonObject o{ + {"projectId", qs(projectId)}, + {"structParentId", qs(structParentId)}, + {"structParentConfType", structParentConfType}, + {"name", qs(name)}, + {"sourceDatasetIds", ids}, + {"interpModel", qs(interpModel)}, + {"cellXY", cellXY}, {"cellZ", cellZ}, {"power", power}, {"maxDist", maxDist}, + }; + if (!colorScaleId.empty()) o.insert("colorScaleId", qs(colorScaleId)); + return o; +} + +QJsonObject SliceGenerateRequest::toJson() const { + QJsonObject o{ + {"projectId", qs(projectId)}, + {"volumeDsId", qs(volumeDsId)}, + {"name", qs(name)}, + {"axis", axis}, + {"origin", vec3(origin)}, {"point1", vec3(point1)}, {"point2", vec3(point2)}, + }; + if (!colorScaleId.empty()) o.insert("colorScaleId", qs(colorScaleId)); + return o; +} + +} // namespace geopro::data diff --git a/src/data/dto/Vtk3dRequests.hpp b/src/data/dto/Vtk3dRequests.hpp new file mode 100644 index 0000000..cb0edc6 --- /dev/null +++ b/src/data/dto/Vtk3dRequests.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#include +#include + +namespace geopro::data { + +// 对齐 docs/api/vtk-3d-openapi.json VoxelGenerateRequest(spec §8 请求体组装)。 +struct VoxelGenerateRequest { + std::string projectId; + std::string structParentId; // GS/项目根容器节点 id + int structParentConfType = 1; // 1=GS/项目根 2=TM + std::string name; + std::vector sourceDatasetIds; + std::string interpModel = "Idw"; // Idw|Kriging + double cellXY = 1.0, cellZ = 0.5, power = 2.0, maxDist = 4.0; + std::string colorScaleId; // 空=取首源色阶 + QJsonObject toJson() const; +}; + +// 对齐 SliceGenerateRequest。 +struct SliceGenerateRequest { + std::string projectId; + std::string volumeDsId; // 所属三维体 dsObjectId + std::string name; + int axis = 3; // 0上下/1前后/2左右/3任意 + std::array origin{{0, 0, 0}}; + std::array point1{{0, 0, 0}}; + std::array point2{{0, 0, 0}}; + std::string colorScaleId; + QJsonObject toJson() const; +}; + +} // namespace geopro::data diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 95bddc6..d94d7f7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -42,6 +42,7 @@ target_sources(geopro_tests PRIVATE data/test_local_repo.cpp) # I3dSceneRepository/LocalSample3dRepository:dimensionOf 映射 + loadVolume/loadTerrainPaths 异步回调(需 PROJ_DATA)。 target_sources(geopro_tests PRIVATE data/test_3d_repo.cpp) target_sources(geopro_tests PRIVATE data/test_nav_dto.cpp) +target_sources(geopro_tests PRIVATE data/test_vtk3d_requests.cpp) target_sources(geopro_tests PRIVATE data/test_dataset_chart_dto.cpp) target_sources(geopro_tests PRIVATE data/test_measurement_dto.cpp) target_sources(geopro_tests PRIVATE data/test_gr_dto.cpp) diff --git a/tests/data/test_vtk3d_requests.cpp b/tests/data/test_vtk3d_requests.cpp new file mode 100644 index 0000000..9dc27f1 --- /dev/null +++ b/tests/data/test_vtk3d_requests.cpp @@ -0,0 +1,39 @@ +#include +#include +#include "dto/Vtk3dRequests.hpp" +using namespace geopro::data; + +TEST(Vtk3dRequests, VoxelToJsonMatchesContract) { + VoxelGenerateRequest q; + q.projectId = "p1"; q.structParentId = "g1"; q.structParentConfType = 1; + q.name = "体A"; q.sourceDatasetIds = {"d1", "d2"}; + const QJsonObject j = q.toJson(); + EXPECT_EQ(j["projectId"].toString(), "p1"); + EXPECT_EQ(j["structParentId"].toString(), "g1"); + EXPECT_EQ(j["structParentConfType"].toInt(), 1); + EXPECT_EQ(j["name"].toString(), "体A"); + ASSERT_TRUE(j["sourceDatasetIds"].isArray()); + EXPECT_EQ(j["sourceDatasetIds"].toArray().size(), 2); + EXPECT_EQ(j["interpModel"].toString(), "Idw"); + EXPECT_DOUBLE_EQ(j["cellXY"].toDouble(), 1.0); + // colorScaleId 为空时不应出现在请求体里。 + EXPECT_FALSE(j.contains("colorScaleId")); +} + +TEST(Vtk3dRequests, VoxelColorScaleIncludedWhenSet) { + VoxelGenerateRequest q; + q.colorScaleId = "cs1"; + EXPECT_EQ(q.toJson()["colorScaleId"].toString(), "cs1"); +} + +TEST(Vtk3dRequests, SliceToJsonMatchesContract) { + SliceGenerateRequest q; + q.projectId = "p1"; q.volumeDsId = "v1"; q.name = "切片1"; q.axis = 3; + q.origin = {0, 0, -10}; q.point1 = {100, 0, -10}; q.point2 = {0, 50, -10}; + const QJsonObject j = q.toJson(); + EXPECT_EQ(j["volumeDsId"].toString(), "v1"); + EXPECT_EQ(j["axis"].toInt(), 3); + ASSERT_TRUE(j["origin"].isArray()); + EXPECT_EQ(j["origin"].toArray().size(), 3); + EXPECT_DOUBLE_EQ(j["point1"].toArray()[0].toDouble(), 100.0); +}