diff --git a/include/plateau/dataset/standard_map_grid.h b/include/plateau/dataset/standard_map_grid.h index 79895230..a6ec0228 100644 --- a/include/plateau/dataset/standard_map_grid.h +++ b/include/plateau/dataset/standard_map_grid.h @@ -7,6 +7,17 @@ #include "plateau/dataset/grid_code.h" namespace plateau::dataset { + + enum class StandardMapGridLevel + { + Invalid = -1, + Level50000 = 0, + Level5000 = 1, + Level2500 = 2, + Level1000 = 3, + Level500 = 4, + }; + /** * \brief 国土基本図図郭を表します。 * @@ -14,7 +25,7 @@ namespace plateau::dataset { */ class LIBPLATEAU_EXPORT StandardMapGrid : public GridCode { public: - explicit StandardMapGrid(std::string code); + explicit StandardMapGrid(std::string code); StandardMapGrid() = default; /** @@ -53,8 +64,23 @@ namespace plateau::dataset { bool operator==(const StandardMapGrid& other) const; bool operator<(const StandardMapGrid& other) const; + /** + * \brief 図郭コードから平面直角座標系での範囲を計算します。 + * \return 平面直角座標系での範囲(min, max) + */ + std::pair calculateGridExtent() const; + private: std::string code_; // 図郭コード bool is_valid_ = false; // コードが有効かどうか + StandardMapGridLevel level_; + + int coordinate_origin_; // 原点 + char first_row_; // 1文字目はrow座標(東西, A-H) + char first_column_; // 2文字目はcolumn座標(南北, A-T) + int second_row_; + int second_column_; + int third_row_; + int third_column_; }; -} \ No newline at end of file +} diff --git a/src/dataset/standard_map_grid.cpp b/src/dataset/standard_map_grid.cpp index 5cfa2544..bb0e15d0 100644 --- a/src/dataset/standard_map_grid.cpp +++ b/src/dataset/standard_map_grid.cpp @@ -1,28 +1,265 @@ #include "plateau/dataset/standard_map_grid.h" +#include #include "plateau/geometry/geo_coordinate.h" #include #include +#include +#include +#include namespace plateau::dataset { - StandardMapGrid::StandardMapGrid(std::string code) : code_(std::move(code)), is_valid_(false) { - // コードの形式を検証 - // TODO - is_valid_ = true; + namespace { + constexpr int level5000_division_count = 10; + constexpr int level2500_division_count = 2; + constexpr int level1000_division_count = 5; + constexpr int level500_division_count = 10; + + // 1セルのサイズ + constexpr double level50000_cell_column = 30000.0; // 南北30km + constexpr double level50000_cell_row = 40000.0; // 東西40km + + constexpr double level5000_cell_column = level50000_cell_column / level5000_division_count; // 南北4km + constexpr double level5000_cell_row = level50000_cell_row / level5000_division_count; // 東西3km + + constexpr double level2500_cell_column = level5000_cell_column / level2500_division_count; // 南北2km + constexpr double level2500_cell_row = level5000_cell_row / level2500_division_count; // 東西1.5km + + constexpr double level1000_cell_column = level5000_cell_column / level1000_division_count; // 南北800m + constexpr double level1000_cell_row = level5000_cell_row / level1000_division_count; // 東西600m + + constexpr double level500_cell_column = level5000_cell_column / level500_division_count; // 南北400m + constexpr double level500_cell_row = level5000_cell_row / level500_division_count; // 東西300m + + /** + * 図郭コードの文字列からレベル(詳細度)を返します。 + */ + StandardMapGridLevel parseLevel(const std::string& code) { + if (code.size() == 4) { + return StandardMapGridLevel::Level50000; + } + if (code.size() == 6) { + return StandardMapGridLevel::Level5000; + } + if (code.size() == 7) { + return StandardMapGridLevel::Level2500; + } + if (code.size() == 8) { + // 末尾がアルファベットであれば1000 + if (std::isalpha(code.back())) { + return StandardMapGridLevel::Level1000; + } + // 末尾が数字であれば500 + else { + return StandardMapGridLevel::Level500; + } + } + + // サポート対象外 + return StandardMapGridLevel::Invalid; + } + + /** + * 計算された平面直角座標をTVec3dのペアに変換します。 + */ + std::pair createExtentPair( + double min_column, double min_row, + double max_column, double max_row) { + // column: 南北方向(緯度):Y軸 + // row: 東西方向(経度):X軸 + return {TVec3d(min_row, 0, min_column), TVec3d(max_row, 0, max_column)}; + } + + void calculateSubGridExtent( + double& min_column, double& min_row, + double& max_column, double& max_row, + int column_index, int row_index, + double cell_column, double cell_row) { + + // column座標(南北)の計算 + min_column = min_column + (column_index * cell_column); + max_column = min_column + cell_column; + + // row座標(東西)の計算 + min_row = min_row + (row_index * cell_row); + max_row = min_row + cell_row; + } + } + + StandardMapGrid::StandardMapGrid(std::string code) : code_(std::move(code)) { + try { + is_valid_ = true; + + // 図郭コードの文字列が数字とアルファベットからなることをチェックします。 + if (!std::all_of(code_.begin(), code_.end(), [](char c) + { + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'); + })) { + is_valid_ = false; + return; + } + + // 図郭コードのレベル(詳細度)をチェックします。 + level_ = parseLevel(code_); + if (level_ == StandardMapGridLevel::Invalid) { + is_valid_ = false; + return; + } + + // 原点設定 + coordinate_origin_ = std::stoi(code_.substr(0, 2)); + + // 図郭コードのcolumn, row座標を取得します。 + first_column_ = code_[2]; // 1文字目はcolumn座標(南北) + first_row_ = code_[3]; // 2文字目はrow座標(東西) + + // 文字の範囲チェック + if (first_column_ < 'A' || first_column_ > 'T' || + first_row_ < 'A' || first_row_ > 'H') { + is_valid_ = false; + return; + } + + if (level_ == StandardMapGridLevel::Level50000) { + return; + } + + // 基点は左下(90) + second_column_ = 9 - std::stoi(code_.substr(4, 1)); + second_row_ = std::stoi(code_.substr(5, 1)); + + if (level_ == StandardMapGridLevel::Level5000) { + return; + } + + if (level_ == StandardMapGridLevel::Level2500) { + // 基点は左下 + int third = std::stoi(code_.substr(6, 1)); // 1-4 + switch (third) { + case 1: // 左上 + third_column_ = 1; + third_row_ = 0; + break; + case 2: // 右上 + third_column_ = 1; + third_row_ = 1; + break; + case 3: // 左下 + third_column_ = 0; + third_row_ = 0; + break; + case 4: // 右下 + third_column_ = 0; + third_row_ = 1; + break; + default: + is_valid_ = false; + break; + } + return; + } + + if (level_ == StandardMapGridLevel::Level1000) { + // 基点は左下(4A) + third_column_ = 4 - std::stoi(code_.substr(6, 1)); // 0-4 + third_row_ = code_.substr(7, 1)[0] - 'A'; // 0-4 (A-E) + + // Level1000の範囲チェック + if (third_column_ < 0 || third_column_ > 4 || + third_row_ < 0 || third_row_ > 4) { + is_valid_ = false; + } + return; + } + + // Level500 + // 基点は左下(9A) + third_column_ = 9 - std::stoi(code_.substr(6, 1)); // 0-9 + third_row_ = std::stoi(code_.substr(7, 1)); // 0-9 + + } catch (const std::exception& e) { + is_valid_ = false; + std::cerr << "Failed to parse grid code " << code_ << ": " << e.what() << std::endl; + } } std::string StandardMapGrid::get() const { return code_; } + std::pair StandardMapGrid::calculateGridExtent() const { + // 東西方向のインデックスを計算(東がプラス、西がマイナス) + int row_index = first_row_ - 'E'; + + // 南北方向のインデックスを計算(北がプラス、南がマイナス) + int column_index = 'J' - first_column_; + + // Level50000の計算 + // column座標(南北)の計算 + double min_column = column_index * level50000_cell_column; + double max_column = min_column + level50000_cell_column; + + // row座標(東西)の計算 + double min_row = row_index * level50000_cell_row; + double max_row = min_row + level50000_cell_row; + + if (level_ == StandardMapGridLevel::Level50000) { + return createExtentPair(min_column, min_row, max_column, max_row); + } + + // Level5000の計算 + calculateSubGridExtent( + min_column, min_row, max_column, max_row, + second_column_, second_row_, + level5000_cell_column, level5000_cell_row); + + if (level_ == StandardMapGridLevel::Level5000) { + return createExtentPair(min_column, min_row, max_column, max_row); + } + + if (level_ == StandardMapGridLevel::Level2500) { + + calculateSubGridExtent( + min_column, min_row, max_column, max_row, + third_column_, third_row_, + level2500_cell_column, level2500_cell_row); + return createExtentPair(min_column, min_row, max_column, max_row); + + } else if (level_ == StandardMapGridLevel::Level1000) { + + calculateSubGridExtent( + min_column, min_row, max_column, max_row, + third_column_, third_row_, + level1000_cell_column, level1000_cell_row); + return createExtentPair(min_column, min_row, max_column, max_row); + + } else { // Level500 + + calculateSubGridExtent( + min_column, min_row, max_column, max_row, + third_column_, third_row_, + level500_cell_column, level500_cell_row); + return createExtentPair(min_column, min_row, max_column, max_row); + } + } + geometry::Extent StandardMapGrid::getExtent() const { if (!isValid()) { throw std::runtime_error("Invalid standard map grid code."); } - - // TODO: 図郭コードから緯度経度範囲を計算する実装を追加 - // この実装は図郭コードの仕様に基づいて行う必要があります - return {geometry::GeoCoordinate(0, 0, 0), geometry::GeoCoordinate(0, 0, 0)}; + + const auto [planeMin, planeMax] = calculateGridExtent(); + + // GeoReferenceを取得 + plateau::polygonMesh::MeshExtractOptions options; + options.coordinate_zone_id = coordinate_origin_; + const auto geo_reference = geometry::GeoReference(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); + + // 平面直角座標系から緯度経度に変換 + const auto min_coordinate = geo_reference.unproject(planeMin); + const auto max_coordinate = geo_reference.unproject(planeMax); + + return geometry::Extent(min_coordinate, max_coordinate); } bool StandardMapGrid::isValid() const { @@ -30,33 +267,38 @@ namespace plateau::dataset { } std::shared_ptr StandardMapGrid::upper() const { - // 仮実装: 自分自身のコピーを返す - return std::shared_ptr(upperRaw()); + // 1段階上のレベルの図郭コードに変換 + auto new_grid_code = std::shared_ptr(upperRaw()); + return new_grid_code; } GridCode* StandardMapGrid::upperRaw() const { - // 仮実装: 自分自身のコピーを返す - return new StandardMapGrid(code_); + if (level_ == StandardMapGridLevel::Level50000) { + auto* new_grid = new StandardMapGrid(code_); + new_grid->is_valid_ = false; + return new_grid; + } + + const std::string upper_code = level_ > StandardMapGridLevel::Level5000 + ? code_.substr(0, 6) + : code_.substr(0, 4); + return new StandardMapGrid(upper_code); } int StandardMapGrid::getLevel() const { - // 仮実装: 常に1を返す - return 1; + return (int)level_; } bool StandardMapGrid::isLargestLevel() const { - // 仮実装: 常にtrueを返す - return true; + return level_ == StandardMapGridLevel::Level50000; } bool StandardMapGrid::isSmallerThanNormalGml() const { - // 仮実装 - return false; + return level_ < StandardMapGridLevel::Level2500; } bool StandardMapGrid::isNormalGmlLevel() const { - // 仮実装: 常にtrueを返す - return true; + return level_ == StandardMapGridLevel::Level2500; } bool StandardMapGrid::operator==(const StandardMapGrid& other) const { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2b7eee80..4ca91885 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,7 +30,6 @@ add_executable(plateau_test "test_mesh_extractor.cpp" "test_grid_merger.cpp" "test_mesh_code.cpp" - "test_dataset.cpp" "test_vector_tile.cpp" "test_obj_writer.cpp" "test_gltf_writer.cpp" @@ -49,6 +48,7 @@ add_executable(plateau_test "test_map_zoom_level_searcher.cpp" "test_height_map_aligner.cpp" "test_heightmap_mesh_generator.cpp" + "test_standard_map_grid.cpp" "test_geo_reference.cpp" ) diff --git a/test/test_standard_map_grid.cpp b/test/test_standard_map_grid.cpp new file mode 100644 index 00000000..9bf9fd42 --- /dev/null +++ b/test/test_standard_map_grid.cpp @@ -0,0 +1,326 @@ +#include + +#include + +#include +#include + +using namespace citygml; +using namespace plateau::dataset; +using namespace plateau::geometry; + +TEST(StandardMapGrid, Level50000_WithinBounds) { + const auto extent = StandardMapGrid("08JE").getExtent(); + const auto expected = GeoCoordinate(36.0935, 138.8013, 0); + + const auto extent2 = StandardMapGrid("08KD").getExtent(); + const auto expected2 = GeoCoordinate(35.7532, 138.0981, 0); + + const auto extent3 = StandardMapGrid("08KC").getExtent(); + const auto expected3 = GeoCoordinate(35.7978, 137.8043, 0); + + std::stringstream ss; + ss << "Extent bounds: (" << extent.min.latitude << ", " << extent.min.longitude << ") - (" + << extent.max.latitude << ", " << extent.max.longitude << ")\n" + << "Expected point: (" << expected.latitude << ", " << expected.longitude << ")"; + SCOPED_TRACE(ss.str()); + ASSERT_TRUE( + extent.max.latitude >= expected.latitude && + extent.max.longitude >= expected.longitude && + extent.min.latitude <= expected.latitude && + extent.min.longitude <= expected.longitude + ); + + std::stringstream ss2; + ss2 << "Extent2 bounds: (" << extent2.min.latitude << ", " << extent2.min.longitude << ") - (" + << extent2.max.latitude << ", " << extent2.max.longitude << ")\n" + << "Expected point2: (" << expected2.latitude << ", " << expected2.longitude << ")"; + SCOPED_TRACE(ss2.str()); + ASSERT_TRUE( + extent2.max.latitude >= expected2.latitude && + extent2.max.longitude >= expected2.longitude && + extent2.min.latitude <= expected2.latitude && + extent2.min.longitude <= expected2.longitude + ); + + std::stringstream ss3; + ss3 << "Extent3 bounds: (" << extent3.min.latitude << ", " << extent3.min.longitude << ") - (" + << extent3.max.latitude << ", " << extent3.max.longitude << ")\n" + << "Expected point3: (" << expected3.latitude << ", " << expected3.longitude << ")"; + SCOPED_TRACE(ss3.str()); + ASSERT_TRUE( + extent3.max.latitude >= expected3.latitude && + extent3.max.longitude >= expected3.longitude && + extent3.min.latitude <= expected3.latitude && + extent3.min.longitude <= expected3.longitude + ); +} + +TEST(StandardMapGrid, Level5000_WithinBounds) { + const auto extent = StandardMapGrid("08JE54").getExtent(); // Level5000 + const auto expected = GeoCoordinate(36.1125, 138.6911, 0); + + std::stringstream ss; + ss << "Extent bounds: (" << extent.min.latitude << ", " << extent.min.longitude << ") - (" + << extent.max.latitude << ", " << extent.max.longitude << ")\n" + << "Expected point: (" << expected.latitude << ", " << expected.longitude << ")"; + SCOPED_TRACE(ss.str()); + ASSERT_TRUE( + extent.max.latitude >= expected.latitude && + extent.max.longitude >= expected.longitude && + extent.min.latitude <= expected.latitude && + extent.min.longitude <= expected.longitude + ); +} + +TEST(StandardMapGrid, Level2500_WithinBounds) { + const auto extent = StandardMapGrid("08EE554").getExtent(); + const auto expected = GeoCoordinate(37.4669, 138.7544, 0); + + std::stringstream ss; + ss << "Extent bounds: (" << extent.min.latitude << ", " << extent.min.longitude << ") - (" + << extent.max.latitude << ", " << extent.max.longitude << ")\n" + << "Expected point: (" << expected.latitude << ", " << expected.longitude << ")"; + SCOPED_TRACE(ss.str()); + ASSERT_TRUE( + extent.max.latitude >= expected.latitude && + extent.max.longitude >= expected.longitude && + extent.min.latitude <= expected.latitude && + extent.min.longitude <= expected.longitude + ); +} + +TEST(StandardMapGrid, Level1000_WithinBounds) { + const auto extent = StandardMapGrid("08JE640E").getExtent(); + const auto expected = GeoCoordinate(36.1053, 138.7151, 0); + + std::stringstream ss; + ss << "Extent bounds: (" << extent.min.latitude << ", " << extent.min.longitude << ") - (" + << extent.max.latitude << ", " << extent.max.longitude << ")\n" + << "Expected point: (" << expected.latitude << ", " << expected.longitude << ")"; + SCOPED_TRACE(ss.str()); + ASSERT_TRUE( + extent.max.latitude >= expected.latitude && + extent.max.longitude >= expected.longitude && + extent.min.latitude <= expected.latitude && + extent.min.longitude <= expected.longitude + ); +} + +TEST(StandardMapGrid, invalidGridCode) { + // 無効な図郭コードのテスト + ASSERT_FALSE(StandardMapGrid("invalid").isValid()); + ASSERT_FALSE(StandardMapGrid("09").isValid()); // 短すぎる + ASSERT_FALSE(StandardMapGrid("09AE09111").isValid()); // 長すぎる + ASSERT_FALSE(StandardMapGrid("09ZZ09").isValid()); // 無効な文字 +} + +TEST(StandardMapGrid, levelCheck) { + // 各レベルの判定テスト + ASSERT_EQ(StandardMapGrid("09AE").getLevel(), 0); // Level50000 + ASSERT_EQ(StandardMapGrid("09AE09").getLevel(), 1); // Level5000 + ASSERT_EQ(StandardMapGrid("09AE091").getLevel(), 2); // Level2500 + ASSERT_EQ(StandardMapGrid("09AE091A").getLevel(), 3); // Level1000 + ASSERT_EQ(StandardMapGrid("09AE0911").getLevel(), 4); // Level500 +} + +TEST(StandardMapGrid, upperMethodTest) { + // Level500からLevel50000までの変換をテスト + auto grid = StandardMapGrid("09AE0911"); // Level500 + ASSERT_EQ(grid.upper()->get(), "09AE09"); // Level5000 + + grid = StandardMapGrid("09AE091A"); // Level1000 + ASSERT_EQ(grid.upper()->get(), "09AE09"); // Level5000 + + grid = StandardMapGrid("09AE091"); // Level2500 + ASSERT_EQ(grid.upper()->get(), "09AE09"); // Level5000 + + grid = StandardMapGrid("09AE09"); // Level5000 + ASSERT_EQ(grid.upper()->get(), "09AE"); // Level50000 + + // Level50000からの変換は無効になるはず + grid = StandardMapGrid("09AE"); // Level50000 + auto upper_grid = grid.upper(); + ASSERT_FALSE(upper_grid->isValid()); +} + +TEST(StandardMapGrid, levelCheckMethods) { + // isLargestLevelのテスト + ASSERT_TRUE(StandardMapGrid("09AE").isLargestLevel()); // Level50000 + ASSERT_FALSE(StandardMapGrid("09AE09").isLargestLevel()); // Level5000 + + // isSmallerThanNormalGmlのテスト + ASSERT_TRUE(StandardMapGrid("09AE").isSmallerThanNormalGml()); // Level50000 + ASSERT_TRUE(StandardMapGrid("09AE09").isSmallerThanNormalGml()); // Level5000 + ASSERT_FALSE(StandardMapGrid("09AE091").isSmallerThanNormalGml()); // Level2500 + ASSERT_FALSE(StandardMapGrid("09AE091A").isSmallerThanNormalGml()); // Level1000 + + // isNormalGmlLevelのテスト + ASSERT_FALSE(StandardMapGrid("09AE").isNormalGmlLevel()); // Level50000 + ASSERT_FALSE(StandardMapGrid("09AE09").isNormalGmlLevel()); // Level5000 + ASSERT_TRUE(StandardMapGrid("09AE091").isNormalGmlLevel()); // Level2500 + ASSERT_FALSE(StandardMapGrid("09AE091A").isNormalGmlLevel()); // Level1000 +} + +TEST(StandardMapGrid, calculateGridExtent_Level50000) { + // 基準点のテスト + { + const auto grid = StandardMapGrid("08JE"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, 0, 0.1); + EXPECT_NEAR(min.z, 0, 0.1); + EXPECT_NEAR(max.x, 40000, 0.1); + EXPECT_NEAR(max.z, 30000, 0.1); + + std::cout << "Grid 08JE: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } + + { + const auto grid = StandardMapGrid("08NA"); // N(南), A(東西) + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, -160000, 0.1); + EXPECT_NEAR(min.z, -120000, 0.1); + EXPECT_NEAR(max.x, -120000, 0.1); + EXPECT_NEAR(max.z, -90000, 0.1); + + std::cout << "Grid 08NA: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } + + { + const auto grid = StandardMapGrid("08FA"); // F(北), A(東西) + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, -160000, 0.1); + EXPECT_NEAR(min.z, 120000, 0.1); + EXPECT_NEAR(max.x, -120000, 0.1); + EXPECT_NEAR(max.z, 150000, 0.1); + + std::cout << "Grid 08FA: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } +} + +TEST(StandardMapGrid, calculateGridExtent_Level5000) { + // Level5000表面直角座標計算テスト + { + const auto grid = StandardMapGrid("08JE54"); // Level5000 + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, 16000.0, 0.1); + EXPECT_NEAR(min.z, 12000.0, 0.1); + EXPECT_NEAR(max.x, 20000.0, 0.1); + EXPECT_NEAR(max.z, 15000.0, 0.1); + + std::cout << "\n08JE54:" << std::endl + << "(" << min.x << ", " << min.z << ") - (" << max.x << ", " << max.z << ")" << std::endl; + } + + // Level5000表面直角座標計算テスト(別のケース) + { + const auto grid = StandardMapGrid("08NA54"); // Level5000 + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, -144000.0, 0.1); + EXPECT_NEAR(min.z, -108000.0, 0.1); + EXPECT_NEAR(max.x, -140000.0, 0.1); + EXPECT_NEAR(max.z, -105000.0, 0.1); + + std::cout << "\n08NA54: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } +} + +TEST(StandardMapGrid, calculateGridExtent_Level2500) { + { + const auto grid = StandardMapGrid("08JE541"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, 16000.0, 0.1); + EXPECT_NEAR(min.z, 13500.0, 0.1); + EXPECT_NEAR(max.x, 18000.0, 0.1); + EXPECT_NEAR(max.z, 15000.0, 0.1); + + std::cout << "\n08JE54:" << std::endl + << "(" << min.x << ", " << min.z << ") - (" << max.x << ", " << max.z << ")" << std::endl; + } + + { + const auto grid = StandardMapGrid("08NA542"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, -142000.0, 0.1); + EXPECT_NEAR(min.z, -106500.0, 0.1); + EXPECT_NEAR(max.x, -140000.0, 0.1); + EXPECT_NEAR(max.z, -105000.0, 0.1); + + std::cout << "\n08NA54: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } +} + +TEST(StandardMapGrid, calculateGridExtent_Level1000) { + { + const auto grid = StandardMapGrid("08JE640E"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, 19200.0, 0.1); + EXPECT_NEAR(min.z, 11400.0, 0.1); + EXPECT_NEAR(max.x, 20000.0, 0.1); + EXPECT_NEAR(max.z, 12000.0, 0.1); + + std::cout << "\n08JE54:" << std::endl + << "(" << min.x << ", " << min.z << ") - (" << max.x << ", " << max.z << ")" << std::endl; + } + + { + const auto grid = StandardMapGrid("08NA542B"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, -143200.0, 0.1); + EXPECT_NEAR(min.z, -106800.0, 0.1); + EXPECT_NEAR(max.x, -142400.0, 0.1); + EXPECT_NEAR(max.z, -106200.0, 0.1); + + std::cout << "\n08NA54: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } +} + +TEST(StandardMapGrid, calculateGridExtent_Level500) { + { + const auto grid = StandardMapGrid("08JE6421"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, 16400.0, 0.1); + EXPECT_NEAR(min.z, 11100.0, 0.1); + EXPECT_NEAR(max.x, 16800.0, 0.1); + EXPECT_NEAR(max.z, 11400.0, 0.1); + + std::cout << "\n08JE54:" << std::endl + << "(" << min.x << ", " << min.z << ") - (" << max.x << ", " << max.z << ")" << std::endl; + } + + { + const auto grid = StandardMapGrid("08NA5476"); + const auto [min, max] = grid.calculateGridExtent(); + + EXPECT_NEAR(min.x, -141600.0, 0.1); + EXPECT_NEAR(min.z, -107400.0, 0.1); + EXPECT_NEAR(max.x, -141200.0, 0.1); + EXPECT_NEAR(max.z, -107100.0, 0.1); + + std::cout << "\n08NA54: " + << "(" << min.x << ", " << min.z << ") - (" + << max.x << ", " << max.z << ")" << std::endl; + } +} \ No newline at end of file diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/DatasetAccessorTest.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/DatasetAccessorTest.cs index d2eefb96..6765f875 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/DatasetAccessorTest.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/DatasetAccessorTest.cs @@ -165,8 +165,8 @@ private static void TestCenterPoint(DatasetSource source) // テスト用のデータは、基準点からおおむね南に50km, 西に5km の地点にあります。 // ここでいう基準点とは、下のWebサイトにおける 9番の地点です。 // https://www.gsi.go.jp/sokuchikijun/jpc.html - Assert.IsTrue(Math.Abs(center.Z - /*(-51000)*/(-369082/*国土基本図の図郭を実装するまでの一時的な値*/)) < 2000, "南に51km"); // Local と Server で値がちょっと違うので2kmの誤差猶予を持たせます。 - Assert.IsTrue(Math.Abs(center.X - /*(-9000))*/(-5132542)/*国土基本図の図郭を実装するまでの一時的な値*/) < 5000, "西に9km"); + Assert.IsTrue(Math.Abs(center.Z - 18000) < 2000, "北に18km"); // Local と Server で値がちょっと違うので2kmの誤差猶予を持たせます。 + Assert.IsTrue(Math.Abs(center.X - (-37000)) < 5000, "西に37km"); }