#include #include #include #include "dto/TrajectoryDto.hpp" using namespace geopro::data::dto; using geopro::core::TableColumnKind; namespace { // 取自真实夹具 tests/fixtures/dd/ert-trajectory-rows.json 的 data(rowList 裁剪至 20 行, // gridHeaderDisplay 全量 14 列,逐字一致)。内联避免引入 fixture 路径编译定义。 const char* kTrajData = R"({ "gridHeaderDisplay": [ { "columnCode": "electrodeNo", "columnNameChn": "电极号", "columnSort": 1, "columnWidth": 10 }, { "columnCode": "horizontalDistance", "columnNameChn": "平距", "columnSort": 2, "columnWidth": 10 }, { "columnCode": "slopeDistance", "columnNameChn": "斜距", "columnSort": 3, "columnWidth": 10 }, { "columnCode": "projectX", "columnNameChn": "经度/东坐标", "columnSort": 4, "columnWidth": 10 }, { "columnCode": "projectY", "columnNameChn": "纬度/北坐标", "columnSort": 5, "columnWidth": 10 }, { "columnCode": "elevation", "columnNameChn": "高程", "columnSort": 6, "columnWidth": 10 }, { "columnCode": "lineNo", "columnNameChn": "线号", "columnSort": 7, "columnWidth": 10 }, { "columnCode": "channelNo", "columnNameChn": "道号", "columnSort": 8, "columnWidth": 10 }, { "columnCode": "measuredDistance", "columnNameChn": "里程", "columnSort": 9, "columnWidth": 10 }, { "columnCode": "depth", "columnNameChn": "深度", "columnSort": 10, "columnWidth": 10 }, { "columnCode": "depthOfWater", "columnNameChn": "水深", "columnSort": 11, "columnWidth": 10 }, { "columnCode": "date", "columnNameChn": "日期", "columnSort": 12, "columnWidth": 10 }, { "columnCode": "time", "columnNameChn": "时间", "columnSort": 13, "columnWidth": 10 }, { "columnCode": "resultStatus", "columnNameChn": "解状态", "columnSort": 14, "columnWidth": 10 } ], "__rowTotal": 40, "rowList": [ { "electrodeNo": 1, "horizontalDistance": 0, "slopeDistance": 0, "projectX": 516838.884, "projectY": 2494251.836, "elevation": 26.172, "lineNo": "ert1", "channelNo": "ERT1-1", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 2, "horizontalDistance": 1.08, "slopeDistance": 1.24, "projectX": 516840.099, "projectY": 2494252.112, "elevation": 25.551, "lineNo": "ert1", "channelNo": "ERT1-2", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 3, "horizontalDistance": 3.14, "slopeDistance": 3.31, "projectX": 516842.07, "projectY": 2494252.756, "elevation": 25.425, "lineNo": "ert1", "channelNo": "ERT1-3", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 4, "horizontalDistance": 4.94, "slopeDistance": 5.12, "projectX": 516843.874, "projectY": 2494252.792, "elevation": 25.625, "lineNo": "ert1", "channelNo": "ERT1-4", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 5, "horizontalDistance": 7.09, "slopeDistance": 7.28, "projectX": 516846.009, "projectY": 2494253.098, "elevation": 25.615, "lineNo": "ert1", "channelNo": "ERT1-5", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 6, "horizontalDistance": 8.91, "slopeDistance": 9.09, "projectX": 516847.815, "projectY": 2494253.249, "elevation": 25.627, "lineNo": "ert1", "channelNo": "ERT1-6", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 7, "horizontalDistance": 11.04, "slopeDistance": 11.22, "projectX": 516849.899, "projectY": 2494253.713, "elevation": 25.549, "lineNo": "ert1", "channelNo": "ERT1-7", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 8, "horizontalDistance": 13.09, "slopeDistance": 13.27, "projectX": 516851.911, "projectY": 2494254.1, "elevation": 25.49, "lineNo": "ert1", "channelNo": "ERT1-8", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 9, "horizontalDistance": 15.03, "slopeDistance": 15.26, "projectX": 516853.844, "projectY": 2494254.561, "elevation": 25.922, "lineNo": "ert1", "channelNo": "ERT1-9", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 10, "horizontalDistance": 16.95, "slopeDistance": 17.26, "projectX": 516855.736, "projectY": 2494255.216, "elevation": 25.363, "lineNo": "ert1", "channelNo": "ERT1-10", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 11, "horizontalDistance": 18.92, "slopeDistance": 19.24, "projectX": 516857.548, "projectY": 2494255.999, "elevation": 25.354, "lineNo": "ert1", "channelNo": "ERT1-11", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 12, "horizontalDistance": 20.97, "slopeDistance": 21.28, "projectX": 516859.35, "projectY": 2494256.96, "elevation": 25.39, "lineNo": "ert1", "channelNo": "ERT1-12", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 13, "horizontalDistance": 22.92, "slopeDistance": 23.24, "projectX": 516861.033, "projectY": 2494257.96, "elevation": 25.444, "lineNo": "ert1", "channelNo": "ERT1-13", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 14, "horizontalDistance": 24.81, "slopeDistance": 25.12, "projectX": 516862.667, "projectY": 2494258.906, "elevation": 25.48, "lineNo": "ert1", "channelNo": "ERT1-14", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 15, "horizontalDistance": 26.92, "slopeDistance": 27.24, "projectX": 516864.416, "projectY": 2494260.092, "elevation": 25.384, "lineNo": "ert1", "channelNo": "ERT1-15", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 16, "horizontalDistance": 28.68, "slopeDistance": 29.00, "projectX": 516865.639, "projectY": 2494261.366, "elevation": 25.5, "lineNo": "ert1", "channelNo": "ERT1-16", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 17, "horizontalDistance": 30.88, "slopeDistance": 31.19, "projectX": 516867.233, "projectY": 2494262.869, "elevation": 25.54, "lineNo": "ert1", "channelNo": "ERT1-17", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 18, "horizontalDistance": 32.76, "slopeDistance": 33.08, "projectX": 516868.457, "projectY": 2494264.304, "elevation": 25.505, "lineNo": "ert1", "channelNo": "ERT1-18", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 19, "horizontalDistance": 34.71, "slopeDistance": 35.03, "projectX": 516869.61, "projectY": 2494265.873, "elevation": 25.576, "lineNo": "ert1", "channelNo": "ERT1-19", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" }, { "electrodeNo": 20, "horizontalDistance": 36.64, "slopeDistance": 36.96, "projectX": 516870.684, "projectY": 2494267.48, "elevation": 25.567, "lineNo": "ert1", "channelNo": "ERT1-20", "measuredDistance": null, "depth": null, "depthOfWater": null, "date": null, "time": null, "resultStatus": "固定解" } ] })"; QJsonObject trajData() { return QJsonDocument::fromJson(kTrajData).object(); } // 取自真实夹具 tests/fixtures/dd/ert-trajectory-line.json 的 data(electrodelList 20 个电极, // 逐字一致;服务端直接返回 EPSG:4326 经纬 x=lon/y=lat)。内联避免引入 fixture 路径编译定义。 const char* kTrajLineData = R"({ "id": null, "electrodelList": [ { "electrodeNo": 1, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16370297649078, "y": 22.54583186479361, "z": 0 }] } }, { "electrodeNo": 2, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16371479128762, "y": 22.54583434513919, "z": 0 }] } }, { "electrodeNo": 3, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16373395960512, "y": 22.545840141157978, "z": 0 }] } }, { "electrodeNo": 4, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16375149792411, "y": 22.545840448398355, "z": 0 }] } }, { "electrodeNo": 5, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16377225700053, "y": 22.545843190544776, "z": 0 }] } }, { "electrodeNo": 6, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16378981598876, "y": 22.54584453624687, "z": 0 }] } }, { "electrodeNo": 7, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16381008094395, "y": 22.54584870568223, "z": 0 }] } }, { "electrodeNo": 8, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16382964511763, "y": 22.545852180493952, "z": 0 }] } }, { "electrodeNo": 9, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16384844206722, "y": 22.54585632432848, "z": 0 }] } }, { "electrodeNo": 10, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16386684249656, "y": 22.545862220446992, "z": 0 }] } }, { "electrodeNo": 11, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16388446655657, "y": 22.545869273235397, "z": 0 }] } }, { "electrodeNo": 12, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16390199529941, "y": 22.545877933516117, "z": 0 }] } }, { "electrodeNo": 13, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16391836757842, "y": 22.545886947155804, "z": 0 }] } }, { "electrodeNo": 14, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16393426292046, "y": 22.545895473642467, "z": 0 }] } }, { "electrodeNo": 15, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16395127881961, "y": 22.545906166262615, "z": 0 }] } }, { "electrodeNo": 16, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16396318204642, "y": 22.545917658760136, "z": 0 }] } }, { "electrodeNo": 17, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16397869446884, "y": 22.545931215521435, "z": 0 }] } }, { "electrodeNo": 18, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16399060913946, "y": 22.545944161886897, "z": 0 }] } }, { "electrodeNo": 19, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16400183500123, "y": 22.54595831901666, "z": 0 }] } }, { "electrodeNo": 20, "electrodeCoordinate": { "crsCode": "EPSG:4326", "closure": null, "geometryType": 1, "geometryCoordinates": [{ "x": 114.16401229325622, "y": 22.545972820080397, "z": 0 }] } } ] })"; QJsonObject trajLineData() { return QJsonDocument::fromJson(kTrajLineData).object(); } } // namespace TEST(TrajectoryDto, ParsesElevationLineSeries) { const QJsonObject data = trajData(); auto line = parseTrajectoryElevation(data); // 类目 "#1".."#20"(来自 electrodeNo)。 ASSERT_EQ(line.categories.size(), 20u); EXPECT_EQ(line.categories.front().toStdString(), "#1"); EXPECT_EQ(line.categories.back().toStdString(), "#20"); // y = elevation,首值 26.172。 ASSERT_EQ(line.y.size(), 20u); EXPECT_DOUBLE_EQ(line.y.front(), 26.172); EXPECT_DOUBLE_EQ(line.y[1], 25.551); // 轴标题 / 系列 / 色 / 平滑。 EXPECT_EQ(line.xTitle.toStdString(), std::string("电极号")); EXPECT_EQ(line.yTitle.toStdString(), std::string("高程")); EXPECT_EQ(line.seriesName.toStdString(), std::string("高程")); EXPECT_EQ(line.color.toStdString(), "#5470c6"); EXPECT_TRUE(line.smooth); } TEST(TrajectoryDto, ParsesTableFourteenColumnsOrderedBySort) { const QJsonObject data = trajData(); auto t = parseTrajectoryTable(data); // 14 列,按 columnSort 升序,title=columnNameChn,首列 电极号。 ASSERT_EQ(t.columns.size(), 14u); EXPECT_EQ(t.columns[0].title.toStdString(), std::string("电极号")); EXPECT_EQ(t.columns[0].code.toStdString(), "electrodeNo"); EXPECT_EQ(t.columns[1].title.toStdString(), std::string("平距")); EXPECT_EQ(t.columns[2].title.toStdString(), std::string("斜距")); EXPECT_EQ(t.columns[5].title.toStdString(), std::string("高程")); EXPECT_EQ(t.columns[13].title.toStdString(), std::string("解状态")); // 无 Toggle 列(trajectory 走 gridHeaderDisplay,不追加开关列)。 for (const auto& c : t.columns) EXPECT_EQ(c.kind, TableColumnKind::Text); // 20 行;row0:电极号=1 / projectX=516838.884 / elevation=26.172 / resultStatus=固定解。 ASSERT_EQ(t.rows.size(), 20u); ASSERT_EQ(t.rows[0].size(), 14u); EXPECT_EQ(t.rows[0][0].toStdString(), "1"); // electrodeNo EXPECT_EQ(t.rows[0][3].toStdString(), "516838.884"); // projectX EXPECT_EQ(t.rows[0][5].toStdString(), "26.172"); // elevation EXPECT_EQ(t.rows[0][13].toStdString(), std::string("固定解")); // resultStatus // null 单元 → 空串(里程/深度/水深/日期/时间)。 EXPECT_TRUE(t.rows[0][8].isEmpty()); // measuredDistance null EXPECT_TRUE(t.rows[0][9].isEmpty()); // depth null EXPECT_TRUE(t.rows[0][11].isEmpty()); // date null // total 取 __rowTotal=40(非本批 20)。 EXPECT_EQ(t.total, 40); } TEST(TrajectoryDto, ParsesEmptyToValidEmptyPayloads) { const QJsonObject empty; auto line = parseTrajectoryElevation(empty); EXPECT_EQ(line.categories.size(), 0u); EXPECT_EQ(line.y.size(), 0u); EXPECT_EQ(line.xTitle.toStdString(), std::string("电极号")); EXPECT_TRUE(line.smooth); auto t = parseTrajectoryTable(empty); EXPECT_EQ(t.columns.size(), 0u); EXPECT_EQ(t.rows.size(), 0u); EXPECT_EQ(t.total, 0); auto m = parseTrajectoryMap(empty); EXPECT_EQ(m.points.size(), 0u); } TEST(TrajectoryDto, ParsesMapPointsFromLineEndpoint) { const QJsonObject data = trajLineData(); auto m = parseTrajectoryMap(data); // 20 个电极点(electrodelList)。 ASSERT_EQ(m.points.size(), 20u); // point0:electrodeNo=1,lon≈114.16370,lat≈22.54583(x=lon、y=lat,EPSG:4326 直返)。 EXPECT_EQ(m.points[0].electrodeNo, 1); EXPECT_NEAR(m.points[0].lon, 114.16370297649078, 1e-9); EXPECT_NEAR(m.points[0].lat, 22.54583186479361, 1e-9); // point19:electrodeNo=20。 EXPECT_EQ(m.points[19].electrodeNo, 20); EXPECT_NEAR(m.points[19].lon, 114.16401229325622, 1e-9); EXPECT_NEAR(m.points[19].lat, 22.545972820080397, 1e-9); }