feat(vtk): 类目描述符目录 categoryCatalog(classify谓词+扩展契约)取代 categoryConfigs
splitByCategory 改遍历 catalog 用 classify 路由(首个 classify==true 入段);新增 5 段含 trajectory。旧 CategoryConfig/categoryConfigs 暂保留供 CategoryAnalysisTab/CategorySection。同步修正 test_dataset_category 旧断言(段数随 catalog=5)。
This commit is contained in:
parent
7d9f34d3ec
commit
8f7da3657a
|
|
@ -1,21 +1,15 @@
|
||||||
#include "DatasetCategory.hpp"
|
#include "DatasetCategory.hpp"
|
||||||
|
#include "repo/CategoryDescriptor.hpp"
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
||||||
CategoryBuckets splitByCategory(const std::vector<geopro::data::DsRow>& rows) {
|
CategoryBuckets splitByCategory(const std::vector<geopro::data::DsRow>& rows) {
|
||||||
const auto& cfg = categoryConfigs();
|
const auto& cat = geopro::data::categoryCatalog();
|
||||||
CategoryBuckets b;
|
CategoryBuckets b;
|
||||||
b.segments.resize(cfg.size());
|
b.segments.resize(cat.size());
|
||||||
for (const auto& r : rows) {
|
for (const auto& r : rows)
|
||||||
int hit = -1;
|
for (std::size_t i = 0; i < cat.size(); ++i)
|
||||||
// 先按 ddCode(三维体/切片)——它们无 dsTypeCode(来自 Api3dRepository mock 行)。
|
if (cat[i].classify && cat[i].classify(r)) { b.segments[i].push_back(r); break; }
|
||||||
for (std::size_t i = 0; i < cfg.size() && hit < 0; ++i)
|
|
||||||
if (!cfg[i].ddCode.empty() && r.ddCode == cfg[i].ddCode) hit = static_cast<int>(i);
|
|
||||||
// 再按 dsTypeCode。
|
|
||||||
for (std::size_t i = 0; i < cfg.size() && hit < 0; ++i)
|
|
||||||
if (!cfg[i].dsTypeCode.empty() && r.dsTypeCode == cfg[i].dsTypeCode) hit = static_cast<int>(i);
|
|
||||||
if (hit >= 0) b.segments[static_cast<std::size_t>(hit)].push_back(r);
|
|
||||||
}
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ add_library(geopro_data STATIC
|
||||||
repo/LocalSampleRepository.cpp
|
repo/LocalSampleRepository.cpp
|
||||||
repo/LocalSample3dRepository.cpp
|
repo/LocalSample3dRepository.cpp
|
||||||
repo/DatasetFieldDictionary.cpp
|
repo/DatasetFieldDictionary.cpp
|
||||||
|
repo/CategoryDescriptor.cpp
|
||||||
dto/NavDto.cpp
|
dto/NavDto.cpp
|
||||||
dto/Vtk3dRequests.cpp
|
dto/Vtk3dRequests.cpp
|
||||||
dto/DatasetChartDto.cpp
|
dto/DatasetChartDto.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "repo/CategoryDescriptor.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace geopro::data {
|
||||||
|
|
||||||
|
std::function<bool(const DsRow&)> byDdCode(std::initializer_list<std::string> codes) {
|
||||||
|
std::vector<std::string> cs(codes);
|
||||||
|
return [cs](const DsRow& r) {
|
||||||
|
for (const auto& c : cs) if (r.ddCode == c) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
std::function<bool(const DsRow&)> byDsTypeCode(std::initializer_list<std::string> codes) {
|
||||||
|
std::vector<std::string> cs(codes);
|
||||||
|
return [cs](const DsRow& r) {
|
||||||
|
for (const auto& c : cs) if (r.dsTypeCode == c) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<CategoryDescriptor>& categoryCatalog() {
|
||||||
|
static const std::vector<CategoryDescriptor> kCat = {
|
||||||
|
{"resistivity", "电阻率数据", SceneKind::Curtain3D,
|
||||||
|
byDsTypeCode({"ERT platform inversion data"}),
|
||||||
|
{FilterKind::DateRange, FilterKind::ArrayType},
|
||||||
|
{OpKind::GenerateVolume, OpKind::Filter}, "curtain"},
|
||||||
|
{"apparent", "视电阻率数据", SceneKind::Curtain3D,
|
||||||
|
byDsTypeCode({"visual resistivity data"}),
|
||||||
|
{FilterKind::DateRange, FilterKind::ArrayType},
|
||||||
|
{OpKind::GenerateVolume, OpKind::Filter}, "curtain"},
|
||||||
|
{"transient", "瞬变电磁数据", SceneKind::Curtain3D,
|
||||||
|
byDsTypeCode({"DD TRANSIENT ELECTROMAGNETIC INVERSION"}),
|
||||||
|
{FilterKind::DateRange},
|
||||||
|
{OpKind::GenerateVolume, OpKind::Filter}, "curtain"},
|
||||||
|
{"voxel", "三维体", SceneKind::Volume3D,
|
||||||
|
byDdCode({"dd_voxel"}),
|
||||||
|
{FilterKind::DateRange},
|
||||||
|
{OpKind::Filter}, "volume"},
|
||||||
|
{"trajectory", "轨迹数据", SceneKind::Plane2D,
|
||||||
|
byDdCode({"dd_trajectory_data"}),
|
||||||
|
{FilterKind::DateRange},
|
||||||
|
{OpKind::PlaneZ, OpKind::Filter, OpKind::Basemap}, "plane2d"},
|
||||||
|
};
|
||||||
|
return kCat;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace geopro::data
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
#include <functional>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "repo/RepoTypes.hpp" // DsRow
|
||||||
|
|
||||||
|
namespace geopro::data {
|
||||||
|
|
||||||
|
enum class SceneKind { Volume3D, Curtain3D, Plane2D }; // 渲染语义/共存规则
|
||||||
|
enum class FilterKind { DateRange, ArrayType }; // 筛选器契约(可扩展)
|
||||||
|
enum class OpKind { GenerateVolume, Filter, PlaneZ, Basemap }; // 段操作契约(可扩展)
|
||||||
|
|
||||||
|
struct CategoryDescriptor {
|
||||||
|
std::string id;
|
||||||
|
std::string title;
|
||||||
|
SceneKind sceneKind;
|
||||||
|
std::function<bool(const DsRow&)> classify; // 轴1 数据来源/分类
|
||||||
|
std::vector<FilterKind> filters; // 轴2 筛选器
|
||||||
|
std::vector<OpKind> operations; // 轴3 段头图标操作
|
||||||
|
std::string renderStrategyId; // 轴4 渲染策略键
|
||||||
|
};
|
||||||
|
|
||||||
|
// classify 便捷构造器(常见按 ddCode / dsTypeCode 接入)
|
||||||
|
std::function<bool(const DsRow&)> byDdCode(std::initializer_list<std::string> codes);
|
||||||
|
std::function<bool(const DsRow&)> byDsTypeCode(std::initializer_list<std::string> codes);
|
||||||
|
|
||||||
|
const std::vector<CategoryDescriptor>& categoryCatalog();
|
||||||
|
|
||||||
|
} // namespace geopro::data
|
||||||
|
|
@ -59,6 +59,8 @@ target_sources(geopro_tests PRIVATE data/test_nav_request.cpp)
|
||||||
# GprVolumeRepository:逐线 GPR int16 量化体(BuiltI16)→ app 渲染链 float 体(VolumeGrid)。
|
# GprVolumeRepository:逐线 GPR int16 量化体(BuiltI16)→ app 渲染链 float 体(VolumeGrid)。
|
||||||
# 纯适配器逐值反量化 + 全链(合成多通道 .iprb 走真 P1/P2)产出有效 VolumeGrid。
|
# 纯适配器逐值反量化 + 全链(合成多通道 .iprb 走真 P1/P2)产出有效 VolumeGrid。
|
||||||
target_sources(geopro_tests PRIVATE data/test_gpr_volume_repository.cpp)
|
target_sources(geopro_tests PRIVATE data/test_gpr_volume_repository.cpp)
|
||||||
|
# CategoryDescriptor:类目描述符目录 categoryCatalog(classify谓词+扩展契约) + splitByCategory 遍历路由。
|
||||||
|
target_sources(geopro_tests PRIVATE data/test_category_descriptor.cpp)
|
||||||
target_link_libraries(geopro_tests PRIVATE geopro_data)
|
target_link_libraries(geopro_tests PRIVATE geopro_data)
|
||||||
|
|
||||||
# store 层:ChunkedVolumeStore(GPR 三维体分块压缩落盘 round-trip + 边缘块 + 压缩生效)。
|
# store 层:ChunkedVolumeStore(GPR 三维体分块压缩落盘 round-trip + 边缘块 + 压缩生效)。
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "DatasetCategory.hpp"
|
#include "DatasetCategory.hpp"
|
||||||
|
#include "repo/CategoryDescriptor.hpp"
|
||||||
using geopro::data::DsRow;
|
using geopro::data::DsRow;
|
||||||
using namespace geopro::app;
|
using namespace geopro::app;
|
||||||
|
|
||||||
|
|
@ -23,7 +24,8 @@ TEST(SplitByCategory, RoutesByDsTypeCodeAndDdCode) {
|
||||||
row("x", "dd_ert_measurement_gr_data", "earth resistance"), // 接地电阻 → 丢弃
|
row("x", "dd_ert_measurement_gr_data", "earth resistance"), // 接地电阻 → 丢弃
|
||||||
};
|
};
|
||||||
const CategoryBuckets b = splitByCategory(rows);
|
const CategoryBuckets b = splitByCategory(rows);
|
||||||
ASSERT_EQ(b.segments.size(), categoryConfigs().size());
|
// splitByCategory 现走 categoryCatalog()(5 段,含 trajectory);旧 categoryConfigs 暂保留供 UI。
|
||||||
|
ASSERT_EQ(b.segments.size(), geopro::data::categoryCatalog().size());
|
||||||
EXPECT_EQ(b.segments[0].size(), 1u); EXPECT_EQ(b.segments[0][0].id, "a");
|
EXPECT_EQ(b.segments[0].size(), 1u); EXPECT_EQ(b.segments[0][0].id, "a");
|
||||||
EXPECT_EQ(b.segments[1].size(), 1u); EXPECT_EQ(b.segments[1][0].id, "b");
|
EXPECT_EQ(b.segments[1].size(), 1u); EXPECT_EQ(b.segments[1][0].id, "b");
|
||||||
EXPECT_EQ(b.segments[2].size(), 1u); EXPECT_EQ(b.segments[2][0].id, "c");
|
EXPECT_EQ(b.segments[2].size(), 1u); EXPECT_EQ(b.segments[2][0].id, "c");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "repo/CategoryDescriptor.hpp"
|
||||||
|
#include "DatasetCategory.hpp"
|
||||||
|
|
||||||
|
using namespace geopro::data;
|
||||||
|
|
||||||
|
TEST(CategoryCatalog, HasFiveSegmentsInOrder) {
|
||||||
|
const auto& cat = categoryCatalog();
|
||||||
|
ASSERT_EQ(cat.size(), 5u);
|
||||||
|
EXPECT_EQ(cat[0].id, "resistivity");
|
||||||
|
EXPECT_EQ(cat[3].id, "voxel");
|
||||||
|
EXPECT_EQ(cat[4].id, "trajectory");
|
||||||
|
EXPECT_EQ(cat[4].sceneKind, SceneKind::Plane2D);
|
||||||
|
EXPECT_EQ(cat[4].renderStrategyId, "plane2d");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CategoryCatalog, TrajectoryClassifiesByDdCode) {
|
||||||
|
const auto& cat = categoryCatalog();
|
||||||
|
DsRow traj; traj.id = "t1"; traj.ddCode = "dd_trajectory_data";
|
||||||
|
EXPECT_TRUE(cat[4].classify(traj));
|
||||||
|
DsRow vox; vox.ddCode = "dd_voxel";
|
||||||
|
EXPECT_FALSE(cat[4].classify(vox));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SplitByCategory, RoutesRowToFirstMatchingDescriptor) {
|
||||||
|
DsRow traj; traj.id = "t1"; traj.ddCode = "dd_trajectory_data";
|
||||||
|
DsRow ert; ert.id = "e1"; ert.dsTypeCode = "ERT platform inversion data";
|
||||||
|
auto b = geopro::app::splitByCategory({traj, ert});
|
||||||
|
const auto& cat = categoryCatalog();
|
||||||
|
ASSERT_EQ(b.segments.size(), cat.size());
|
||||||
|
EXPECT_EQ(b.segments[0].size(), 1u); // resistivity ← ert
|
||||||
|
EXPECT_EQ(b.segments[0][0].id, "e1");
|
||||||
|
EXPECT_EQ(b.segments[4].size(), 1u); // trajectory ← traj
|
||||||
|
EXPECT_EQ(b.segments[4][0].id, "t1");
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue