diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bad9a5e..00f98a8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,4 +8,5 @@ # add_subdirectory(view) # QtWidgets 面板 # add_subdirectory(controller) # 联动编排 # +add_subdirectory(core) add_subdirectory(app) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 0000000..64271cf --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,11 @@ +find_package(Eigen3 CONFIG REQUIRED) + +add_library(geopro_core STATIC + geo/LocalFrame.cpp +) + +target_include_directories(geopro_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(geopro_core PUBLIC Eigen3::Eigen) +target_compile_features(geopro_core PUBLIC cxx_std_17) + +# 铁律:core 为纯业务逻辑层,绝不链接 Qt / VTK。 diff --git a/src/core/geo/LocalFrame.cpp b/src/core/geo/LocalFrame.cpp new file mode 100644 index 0000000..28357f9 --- /dev/null +++ b/src/core/geo/LocalFrame.cpp @@ -0,0 +1,15 @@ +#include "geo/LocalFrame.hpp" +namespace geopro::core { + +LocalFrame::LocalFrame(double originEast, double originNorth, double zDatum) + : originEast_(originEast), originNorth_(originNorth), zDatum_(zDatum) {} + +WorldPoint LocalFrame::gisToWorld(double east, double north, double elevation) const { + return WorldPoint{east - originEast_, north - originNorth_, elevation - zDatum_}; +} + +GisPoint LocalFrame::worldToGis(const WorldPoint& w) const { + return GisPoint{w.x + originEast_, w.y + originNorth_, w.z + zDatum_}; +} + +} // namespace geopro::core diff --git a/src/core/geo/LocalFrame.hpp b/src/core/geo/LocalFrame.hpp new file mode 100644 index 0000000..7466656 --- /dev/null +++ b/src/core/geo/LocalFrame.hpp @@ -0,0 +1,21 @@ +#pragma once +namespace geopro::core { + +struct WorldPoint { double x, y, z; }; // 局部米:x=East偏移, y=North偏移, z=相对Z基准 +struct GisPoint { double east, north, elevation; }; + +// 唯一权威「项目世界系」:双精度 GIS 原点平移到局部米,规避 VTK float 大坐标抖动。 +// 轴向钉死:world.x = Easting(projectX),world.y = Northing(projectY),world.z 向上为正。 +class LocalFrame { +public: + LocalFrame(double originEast, double originNorth, double zDatum); + WorldPoint gisToWorld(double east, double north, double elevation) const; + GisPoint worldToGis(const WorldPoint& w) const; + double originEast() const { return originEast_; } + double originNorth() const { return originNorth_; } + double zDatum() const { return zDatum_; } +private: + double originEast_, originNorth_, zDatum_; +}; + +} // namespace geopro::core diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6ed3229..68bb1e5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,4 +9,7 @@ target_link_libraries(geopro_tests PRIVATE GTest::gtest GTest::gtest_main) include(GoogleTest) gtest_discover_tests(geopro_tests) +target_sources(geopro_tests PRIVATE core/test_local_frame.cpp) +target_link_libraries(geopro_tests PRIVATE geopro_core) + add_subdirectory(spike) # spike S3: banded contour 渲染验证 diff --git a/tests/core/test_local_frame.cpp b/tests/core/test_local_frame.cpp new file mode 100644 index 0000000..d772618 --- /dev/null +++ b/tests/core/test_local_frame.cpp @@ -0,0 +1,20 @@ +#include +#include "geo/LocalFrame.hpp" +using geopro::core::LocalFrame; + +TEST(LocalFrame, GisToWorldSubtractsOriginEastNorth) { + LocalFrame f(/*originEast=*/516000.0, /*originNorth=*/2494000.0, /*zDatum=*/0.0); + auto w = f.gisToWorld(516863.6350992983, 2494259.56246985, 21.0); + EXPECT_NEAR(w.x, 863.6350992983, 1e-6); + EXPECT_NEAR(w.y, 259.56246985, 1e-6); + EXPECT_NEAR(w.z, 21.0, 1e-6); +} + +TEST(LocalFrame, RoundTripWorldGis) { + LocalFrame f(516000.0, 2494000.0, 5.0); + auto w = f.gisToWorld(516500.0, 2494500.0, 30.0); + auto g = f.worldToGis(w); + EXPECT_NEAR(g.east, 516500.0, 1e-6); + EXPECT_NEAR(g.north, 2494500.0, 1e-6); + EXPECT_NEAR(g.elevation, 30.0, 1e-6); +} diff --git a/vcpkg.json b/vcpkg.json index 3767cca..22cff44 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,6 +3,7 @@ "version": "0.1.0", "description": "Geopro 3.0 desktop client (Qt6 + VTK9) - M1. 方案②-修订: Qt/VTK/ADS/QtKeychain 对接官方 MSVC Qt(不走 vcpkg); 仅非 Qt 依赖走 vcpkg, 按层递增。", "dependencies": [ + "eigen3", "gtest", "nlohmann-json" ]