feat(io/gpr): GPR 几何-通道横偏解析与采样深度换算
新增 geopro::io::gpr 两个纯 C++17 几何函数: - parseChannelXOffsets: 解析 .ord 末列==1 的有效通道横向偏移 - depthOfSample: 按物理把采样序号换算为深度米(samples<=1 防除零) 含失败先行的单测,GprGeometry.cpp 接入 geopro_io_gpr, test 接入 geopro_tests。
This commit is contained in:
parent
379875dff0
commit
0bbed9c0c3
|
|
@ -1,4 +1,4 @@
|
||||||
add_library(geopro_io_gpr STATIC IprHeader.cpp IprbReader.cpp)
|
add_library(geopro_io_gpr STATIC IprHeader.cpp IprbReader.cpp GprGeometry.cpp)
|
||||||
target_include_directories(geopro_io_gpr PUBLIC ${CMAKE_SOURCE_DIR}/src)
|
target_include_directories(geopro_io_gpr PUBLIC ${CMAKE_SOURCE_DIR}/src)
|
||||||
target_compile_features(geopro_io_gpr PUBLIC cxx_std_17)
|
target_compile_features(geopro_io_gpr PUBLIC cxx_std_17)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "io/gpr/GprGeometry.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace geopro::io::gpr {
|
||||||
|
|
||||||
|
std::vector<double> parseChannelXOffsets(const std::string& ordText) {
|
||||||
|
std::vector<double> offsets;
|
||||||
|
std::istringstream lines(ordText);
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(lines, line)) {
|
||||||
|
std::istringstream tok(line);
|
||||||
|
std::vector<std::string> cols;
|
||||||
|
std::string col;
|
||||||
|
while (tok >> col) cols.push_back(col);
|
||||||
|
if (cols.size() < 4) continue; // 空行/列数不足,跳过
|
||||||
|
if (cols.back() != "1") continue; // 末列==1 才是有效通道
|
||||||
|
offsets.push_back(std::stod(cols[1]));
|
||||||
|
}
|
||||||
|
return offsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
double depthOfSample(int s, const IprHeader& h) {
|
||||||
|
if (h.samples <= 1) return 0.0; // 防除零
|
||||||
|
const double timeNs = static_cast<double>(s) * h.timeWindowNs /
|
||||||
|
static_cast<double>(h.samples - 1);
|
||||||
|
const double timeSec = timeNs * 1e-9;
|
||||||
|
return h.soilVelocity * timeSec / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace geopro::io::gpr
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef GEOPRO_IO_GPR_GPRGEOMETRY_HPP
|
||||||
|
#define GEOPRO_IO_GPR_GPRGEOMETRY_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "io/gpr/IprHeader.hpp"
|
||||||
|
|
||||||
|
namespace geopro::io::gpr {
|
||||||
|
|
||||||
|
// 解析 .ord 文本,返回末列==1 的有效通道的横向偏移(第 2 列),按文件顺序。
|
||||||
|
std::vector<double> parseChannelXOffsets(const std::string& ordText);
|
||||||
|
|
||||||
|
// 采样序号 s → 深度(米)。depth = soilVelocity[m/s] * (s * timeWindowNs/(samples-1) * 1e-9) / 2。
|
||||||
|
// samples<=1 时返回 0 防除零。
|
||||||
|
double depthOfSample(int s, const IprHeader& h);
|
||||||
|
|
||||||
|
} // namespace geopro::io::gpr
|
||||||
|
|
||||||
|
#endif // GEOPRO_IO_GPR_GPRGEOMETRY_HPP
|
||||||
|
|
@ -171,6 +171,7 @@ target_link_libraries(geopro_tests PRIVATE geopro_controller Qt6::Test)
|
||||||
# io/gpr 层:.iprh 头解析 + .iprb B-scan 读取(纯 C++17,零 Qt/VTK)。
|
# io/gpr 层:.iprh 头解析 + .iprb B-scan 读取(纯 C++17,零 Qt/VTK)。
|
||||||
target_sources(geopro_tests PRIVATE io/gpr/test_ipr_header.cpp)
|
target_sources(geopro_tests PRIVATE io/gpr/test_ipr_header.cpp)
|
||||||
target_sources(geopro_tests PRIVATE io/gpr/test_iprb_reader.cpp)
|
target_sources(geopro_tests PRIVATE io/gpr/test_iprb_reader.cpp)
|
||||||
|
target_sources(geopro_tests PRIVATE io/gpr/test_gpr_geometry.cpp)
|
||||||
target_link_libraries(geopro_tests PRIVATE geopro_io_gpr)
|
target_link_libraries(geopro_tests PRIVATE geopro_io_gpr)
|
||||||
|
|
||||||
add_subdirectory(spike) # spike S3: banded contour 渲染验证
|
add_subdirectory(spike) # spike S3: banded contour 渲染验证
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "io/gpr/GprGeometry.hpp"
|
||||||
|
#include "io/gpr/IprHeader.hpp"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
using namespace geopro::io::gpr;
|
||||||
|
|
||||||
|
TEST(GprGeometry, ParsesActiveChannelOffsets) {
|
||||||
|
const std::string ord = "0 -0.686000 -1.5 1\n1 -0.581000 -1.5 1\n14 0 -1.5 0\n";
|
||||||
|
auto xs = parseChannelXOffsets(ord);
|
||||||
|
ASSERT_EQ(xs.size(), 2u); // 仅 2 个有效(末列=1)
|
||||||
|
EXPECT_NEAR(xs[0], -0.686, 1e-6);
|
||||||
|
EXPECT_NEAR(xs[1], -0.581, 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GprGeometry, DepthOfLastSampleMatchesPhysics) {
|
||||||
|
IprHeader h{};
|
||||||
|
h.samples = 821;
|
||||||
|
h.timeWindowNs = 160.352;
|
||||||
|
h.soilVelocity = 1e8; // m/s
|
||||||
|
EXPECT_NEAR(depthOfSample(820, h), 8.0, 0.05); // ~8m
|
||||||
|
EXPECT_NEAR(depthOfSample(0, h), 0.0, 1e-9);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue