diff --git a/src/app/main.cpp b/src/app/main.cpp index ea53bab..d015735 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -507,10 +507,18 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re auto* alongLineOverlay = new BottomBarOverlay(alongLineBar, vtkWidget); QObject::connect(alongLineSlider, &QSlider::valueChanged, vtkWidget, [sceneView](int v) { sceneView->focusAlongLongAxis(v / 1000.0, 0.12); }); - // 显隐刷新:细长(长短轴比≥4,即雷达)体时显示沿线滑块。 + // 显隐刷新:仅当场景中实际渲染了雷达三维体(StoredVolume 带 linePrefix)时显示沿线滑块。 + // 旧逻辑靠数据包围盒长短轴比≥4 判定,统一自由场景下细长的非雷达数据(2D 轨迹线/反演帘面/ + // 普通体)会撑大合并包围盒→误触发。改按「已渲染体中是否存在雷达体」门控(雷达体取消勾选/移除 + // 后 onVolumeChanged 会重评并隐藏)。 auto refreshAlongLineBar = std::make_shared>( - [sceneView, alongLineBar, alongLineOverlay]() { - const bool show = sceneView->longAxisElongation() >= 4.0; + [sceneView, scene3dRepo, alongLineBar, alongLineOverlay]() { + bool show = false; + for (const auto& kv : sceneView->volumes()) + if (scene3dRepo->isRadarVolume(kv.first)) { + show = true; + break; + } alongLineBar->setVisible(show); if (show) alongLineOverlay->reposition(); }); diff --git a/src/data/api/Api3dRepository.cpp b/src/data/api/Api3dRepository.cpp index 5c4649c..e097709 100644 --- a/src/data/api/Api3dRepository.cpp +++ b/src/data/api/Api3dRepository.cpp @@ -256,6 +256,11 @@ bool Api3dRepository::volumeInfo(const std::string& dsId, VolumeInfo& out) const return true; } +bool Api3dRepository::isRadarVolume(const std::string& dsId) const { + auto it = volumes_.find(dsId); + return it != volumes_.end() && !it->second.linePrefix.empty(); +} + void Api3dRepository::appendGridPoints(const core::Grid& g, core::PointSet& pts) const { const int nx = g.nx(), ny = g.ny(); if (nx < 1 || ny < 1 || g.y.size() < static_cast(ny)) return; diff --git a/src/data/api/Api3dRepository.hpp b/src/data/api/Api3dRepository.hpp index e5df097..94a2f3a 100644 --- a/src/data/api/Api3dRepository.hpp +++ b/src/data/api/Api3dRepository.hpp @@ -78,6 +78,9 @@ public: }; // 取回三维体详情;dsId 非三维体返回 false(不弹空对话框)。 bool volumeInfo(const std::string& dsId, VolumeInfo& out) const; + // 该 dsId 是否为雷达三维体(StoredVolume 存在且 linePrefix 非空 → 走 loadVolume 雷达懒建分支)。 + // 用于「沿线位置」滑块门控:仅实际渲染了雷达体时显示,不再靠数据包围盒细长度误判。 + bool isRadarVolume(const std::string& dsId) const; // 已保存切片的列表行(ddCode="dd_slice",parentId=所属体 dsId → 树中挂父体下),供三维分析栏合并。 std::vector sliceRows() const; // 异常列表行(ddCode="dd_anomaly",parentId=remarkSourceId=归属实体[体/切片] dsId → 三级树自动挂载), diff --git a/tests/data/test_3d_repo.cpp b/tests/data/test_3d_repo.cpp index 2785fa8..9e870f1 100644 --- a/tests/data/test_3d_repo.cpp +++ b/tests/data/test_3d_repo.cpp @@ -258,6 +258,31 @@ TEST(Api3dRepo, RegisterRadarDatasetRoutesAsDdRadar3d) { std::filesystem::remove_all(dir, ec); } +// isRadarVolume:仅带 linePrefix 的体(registerRadarDataset 登记)为真;普通 IDW 体、未知 id 为假。 +// 支撑「沿线位置」滑块门控(仅雷达体在场才显示)。 +TEST(Api3dRepo, IsRadarVolumeOnlyTrueForRadarLine) { + const auto dir = std::filesystem::temp_directory_path() / "api3d_radar_isradar"; + std::error_code ec; + std::filesystem::remove_all(dir, ec); + writeSyntheticRadarLine(dir); + + StubAsyncRepo dsRepo; + auto frame = std::make_shared(22.0, 114.0); + Api3dRepository repo(dsRepo, frame); + + const std::string radarId = + repo.registerRadarDataset(dir.string(), "L", "测线L", "tm-1", /*coarse=*/1); + EXPECT_TRUE(repo.isRadarVolume(radarId)); + + VolumeBuildParams p; + p.sourceDatasetIds = {"src-a"}; + const std::string plainId = repo.createVolume(p, "普通体"); + EXPECT_FALSE(repo.isRadarVolume(plainId)); // 普通 IDW 体无 linePrefix + EXPECT_FALSE(repo.isRadarVolume("no-such")); // 未知 id + + std::filesystem::remove_all(dir, ec); +} + // loadVolume:首次勾选时懒建雷达体(无 QCoreApplication → 同步交付;全量测试中若其它用例已建 // QCoreApplication 单例则走异步,processEvents 排空队列交付)。回调收到有效 VolumeGrid。 TEST(Api3dRepo, LoadVolumeBuildsRadarLazily) {