From 536a2da690a9fe7bd318051bdaf667126d853fa9 Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 9 Apr 2025 14:44:02 +0900 Subject: [PATCH 01/24] =?UTF-8?q?Project=E3=82=B9=E3=82=AD=E3=83=83?= =?UTF-8?q?=E3=83=97=E5=87=A6=E7=90=86=E3=81=AB=E4=BC=B4=E3=81=86=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AEc=20wrapp?= =?UTF-8?q?er=20,=20C#=E5=87=A6=E7=90=86=E3=83=BB=E3=83=A6=E3=83=8B?= =?UTF-8?q?=E3=83=83=E3=83=88=E3=83=86=E3=82=B9=E3=83=88=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/c_wrapper/geo_reference_c.cpp | 20 +++++++-- src/c_wrapper/gml_file_c.cpp | 20 ++++++--- .../CSharpPLATEAU.Test/Dataset/GmlFileTest.cs | 23 +++++++++- .../Geom/GeoReferenceTests.cs | 12 ++++++ .../CSharpPLATEAU/Dataset/GmlFile.cs | 43 ++++++++++++++++++- .../CSharpPLATEAU/Geometries/GeoReference.cs | 31 +++++++++++++ 6 files changed, 138 insertions(+), 11 deletions(-) diff --git a/src/c_wrapper/geo_reference_c.cpp b/src/c_wrapper/geo_reference_c.cpp index c4eb3d55..61d04228 100644 --- a/src/c_wrapper/geo_reference_c.cpp +++ b/src/c_wrapper/geo_reference_c.cpp @@ -22,10 +22,10 @@ extern "C" { GeoReference) DLL_VALUE_FUNC(plateau_geo_reference_project, - GeoReference, - TVec3d, - handle->project(lat_lon), - , GeoCoordinate lat_lon) + GeoReference, + TVec3d, + handle->project(lat_lon), + , GeoCoordinate lat_lon) DLL_VALUE_FUNC(plateau_geo_reference_unproject, GeoReference, @@ -33,6 +33,18 @@ extern "C" { handle->unproject(point), , TVec3d point) + DLL_VALUE_FUNC(plateau_geo_reference_project_point, + GeoReference, + TVec3d, + handle->project(point), + , TVec3d point) + + DLL_VALUE_FUNC(plateau_geo_reference_convert, + GeoReference, + TVec3d, + handle->convert(point, convert_axis, project), + , TVec3d point, bool convert_axis, bool project) + DLL_VALUE_FUNC(plateau_geo_reference_get_reference_point, GeoReference, TVec3d, diff --git a/src/c_wrapper/gml_file_c.cpp b/src/c_wrapper/gml_file_c.cpp index 62922437..85a0221b 100644 --- a/src/c_wrapper/gml_file_c.cpp +++ b/src/c_wrapper/gml_file_c.cpp @@ -40,13 +40,23 @@ extern "C" { } DLL_STRING_PTR_FUNC(plateau_gml_file_get_feature_type_str, - GmlFile, - handle->getFeatureType()) + GmlFile, + handle->getFeatureType()) DLL_VALUE_FUNC(plateau_gml_file_get_mesh_code, - GmlFile, - MeshCode, - handle->getMeshCode()) + GmlFile, + MeshCode, + handle->getMeshCode()) + + DLL_VALUE_FUNC(plateau_gml_file_get_epsg, + GmlFile, + double, + handle->getEpsg()) + + DLL_VALUE_FUNC(plateau_gml_file_is_polar_coordinate_system, + GmlFile, + bool, + handle->isPolarCoordinateSystem()) LIBPLATEAU_C_EXPORT APIResult LIBPLATEAU_C_API plateau_gml_file_fetch( const GmlFile* const gml_file_info, diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs index 50cd69e0..26e2c0b6 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs @@ -35,7 +35,28 @@ public void TestMeshCode() Assert.AreEqual("53392642", info.MeshCode.ToString()); info.Dispose(); } - + + [TestMethod] + public void TestEpsgCode() + { + string path = "data/udx/bldg/53392642_bldg_6697_op2.gml"; + var info = GmlFile.Create(path); + Assert.AreEqual(6697, info.Epsg); + Assert.IsTrue(info.isPolarCoordinateSystem); + info.Dispose(); + } + + + [TestMethod] + public void TestEpsgCodePlane() + { + string path = "data/udx/unf/08EE763_unf_10169_sewer_op.gml"; + var info = GmlFile.Create(path); + Assert.AreEqual(10169, info.Epsg); + Assert.IsFalse(info.isPolarCoordinateSystem); + info.Dispose(); + } + [TestMethod] public void DirNameToPackage_Returns_Gml_Package() { diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs index 8e44df04..8a017c95 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs @@ -121,5 +121,17 @@ private static void CheckProjectUnproject(PlateauVector3d referencePoint, float Assert.IsTrue(Math.Abs(lat.Latitude - latitude) < 0.00000001);//およそ1mm相当の誤差以内か Assert.IsTrue(Math.Abs(lat.Longitude - longitude) < 0.00000001);//およそ1mm相当の誤差以内か } + + [TestMethod] + public void Convert_returns_same_values() + { + using var geoReference = GeoReference.Create( + new PlateauVector3d(0, 0, 0), 1.0f, CoordinateSystem.EUN, 5 + ); + var xyz = new PlateauVector3d(1, 2, 3); + Assert.AreEqual(xyz, geoReference.Convert(xyz, false, false)); + Assert.AreEqual(GeoReference.ConvertAxisFromENUTo(CoordinateSystem.EUN, xyz), geoReference.Convert(xyz, true, false)); + Assert.AreEqual(geoReference.Project(xyz), geoReference.Convert(xyz, true, true)); + } } } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs index f3faab17..0a5e5b2b 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs @@ -93,6 +93,37 @@ public MeshCode MeshCode } } + /// + /// GMLファイルのEPSGコードを返します。 + /// 取得失敗時のデフォルト値はEPSG:6697です。 + /// + public double Epsg + { + get + { + ThrowIfDisposed(); + var epsg = DLLUtil.GetNativeValue(Handle, + NativeMethods.plateau_gml_file_get_epsg); + return epsg; + } + } + + /// + /// 平面直角座標系への変換が必要なGMLファイルかどうかを返します。 + /// 取得失敗時のデフォルト値はtrueです。 + /// + public bool isPolarCoordinateSystem + { + get + { + ThrowIfDisposed(); + var isPolar = DLLUtil.GetNativeValue(Handle, + NativeMethods.plateau_gml_file_is_polar_coordinate_system); + return isPolar; + } + } + + public string[] SearchAllCodelistPathsInGml() { var nativePaths = NativeVectorString.Create(); @@ -211,7 +242,17 @@ internal static extern APIResult plateau_gml_file_get_feature_type_str( internal static extern APIResult plateau_gml_file_get_mesh_code( [In] IntPtr gmlFilePtr, out MeshCode outMeshCode); - + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_gml_file_get_epsg( + [In] IntPtr gmlFilePtr, + out double outEpsg); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_gml_file_is_polar_coordinate_system( + [In] IntPtr gmlFilePtr, + out bool outBool); + [DllImport(DLLUtil.DllName, CharSet = CharSet.Ansi)] internal static extern APIResult plateau_gml_file_fetch( [In] IntPtr gmlFilePtr, diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs index 1c54f6d2..11107276 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs @@ -115,6 +115,15 @@ public PlateauVector3d Project(GeoCoordinate geoCoordinate) return outXyz; } + public PlateauVector3d Project(PlateauVector3d point) + { + var result = NativeMethods.plateau_geo_reference_project_point( + Handle, out var outXyz, + point); + DLLUtil.CheckDllError(result); + return outXyz; + } + public GeoCoordinate Unproject(PlateauVector3d point) { var result = NativeMethods.plateau_geo_reference_unproject( @@ -124,6 +133,15 @@ public GeoCoordinate Unproject(PlateauVector3d point) return outLatLon; } + public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, bool project) + { + var result = NativeMethods.plateau_geo_reference_convert( + Handle, out var outXyz, + point, convertAxis, project); + DLLUtil.CheckDllError(result); + return outXyz; + } + public static PlateauVector3d ConvertAxisToENU(CoordinateSystem axis, PlateauVector3d vertex) { var result = NativeMethods.plateau_geo_reference_convert_axis_to_enu(axis, vertex, out var outVertex); @@ -213,6 +231,19 @@ internal static extern APIResult plateau_geo_reference_unproject( out GeoCoordinate outLatLon, PlateauVector3d point); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_geo_reference_project_point( + [In] IntPtr geoReferencePtr, + out PlateauVector3d outXyz, + PlateauVector3d point); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_geo_reference_convert( + [In] IntPtr geoReferencePtr, + out PlateauVector3d outXyz, + PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, [MarshalAs(UnmanagedType.U1)] bool project); + [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_get_reference_point( [In] IntPtr handle, From b6a908716e47910a73ecc32681f64eb79ddcaeac Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 9 Apr 2025 15:06:32 +0900 Subject: [PATCH 02/24] =?UTF-8?q?UnitTest=E7=94=A8=E3=81=AB=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/c_wrapper/geo_reference_c.cpp | 6 ++++++ .../CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs | 1 + .../CSharpPLATEAU/Geometries/GeoReference.cs | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/c_wrapper/geo_reference_c.cpp b/src/c_wrapper/geo_reference_c.cpp index 61d04228..1da4c001 100644 --- a/src/c_wrapper/geo_reference_c.cpp +++ b/src/c_wrapper/geo_reference_c.cpp @@ -39,6 +39,12 @@ extern "C" { handle->project(point), , TVec3d point) + DLL_VALUE_FUNC(plateau_geo_reference_project_without_axis_convert, + GeoReference, + TVec3d, + handle->projectWithoutAxisConvert(point), + , TVec3d point) + DLL_VALUE_FUNC(plateau_geo_reference_convert, GeoReference, TVec3d, diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs index 8a017c95..78fc8a11 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs @@ -132,6 +132,7 @@ public void Convert_returns_same_values() Assert.AreEqual(xyz, geoReference.Convert(xyz, false, false)); Assert.AreEqual(GeoReference.ConvertAxisFromENUTo(CoordinateSystem.EUN, xyz), geoReference.Convert(xyz, true, false)); Assert.AreEqual(geoReference.Project(xyz), geoReference.Convert(xyz, true, true)); + Assert.AreEqual(geoReference.ProjectWithoutAxisConvert(xyz), geoReference.Convert(xyz, false, true)); } } } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs index 11107276..8dbff53a 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs @@ -124,6 +124,15 @@ public PlateauVector3d Project(PlateauVector3d point) return outXyz; } + public PlateauVector3d ProjectWithoutAxisConvert(PlateauVector3d point) + { + var result = NativeMethods.plateau_geo_reference_project_without_axis_convert( + Handle, out var outXyz, + point); + DLLUtil.CheckDllError(result); + return outXyz; + } + public GeoCoordinate Unproject(PlateauVector3d point) { var result = NativeMethods.plateau_geo_reference_unproject( @@ -231,13 +240,18 @@ internal static extern APIResult plateau_geo_reference_unproject( out GeoCoordinate outLatLon, PlateauVector3d point); - [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_project_point( [In] IntPtr geoReferencePtr, out PlateauVector3d outXyz, PlateauVector3d point); + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_geo_reference_project_without_axis_convert( + [In] IntPtr geoReferencePtr, + out PlateauVector3d outXyz, + PlateauVector3d point); + [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_convert( [In] IntPtr geoReferencePtr, From 913b8158a1c88c01132bcd6d1ba2e7ec544ae036 Mon Sep 17 00:00:00 2001 From: sevendev Date: Thu, 10 Apr 2025 12:28:07 +0900 Subject: [PATCH 03/24] =?UTF-8?q?extract=20option=E3=81=ABpolar=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E7=94=A8=E3=83=95=E3=83=A9=E3=82=B0=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=EF=BC=88=E8=87=AA=E5=89=8D=E3=81=A7gmlfile=E3=81=AE=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E3=81=97=E3=81=A6=E6=B8=A1=E3=81=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 10 ++++++---- .../plateau/polygon_mesh/mesh_extract_options.h | 8 +++++++- src/geometry/geo_coordinate.cpp | 11 ++++++++--- src/polygon_mesh/area_mesh_factory.cpp | 2 +- src/polygon_mesh/mesh_extractor.cpp | 2 +- src/polygon_mesh/mesh_factory.cpp | 16 +++++++--------- test/test_mesh_extractor.cpp | 1 + 7 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 1dc4cf7b..c061fd7f 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -70,13 +70,13 @@ namespace plateau::geometry { } bool contains(GeoCoordinate point, bool ignore_height = true) const; - bool contains(TVec3d point, bool ignore_height = true) const; + bool contains(TVec3d point, bool ignore_height = true, bool is_polar_coordinate_system = true) const; /** * 引数 city_obj の位置を推定し、その位置が Extent の範囲内に含まれるかどうかを返します。 * city_obj の位置が不明の場合は false を返します。 */ - bool contains(const citygml::CityObject& city_obj, bool ignore_height = true) const; + bool contains(const citygml::CityObject& city_obj, bool ignore_height = true, bool is_polar_coordinate_system = true) const; /** * other と交わる箇所があるかどうかを返します。 @@ -94,8 +94,10 @@ namespace plateau::geometry { static Extent all() { return { - GeoCoordinate(-9999999, -9999999, -9999), - GeoCoordinate(9999999, 9999999, 9999) + GeoCoordinate(-90, -180, -9999), + GeoCoordinate(90, 180, 9999) + //GeoCoordinate(-9999999, -9999999, -9999), + //GeoCoordinate(9999999, 9999999, 9999) }; } }; diff --git a/include/plateau/polygon_mesh/mesh_extract_options.h b/include/plateau/polygon_mesh/mesh_extract_options.h index ec72c522..a3a8e564 100644 --- a/include/plateau/polygon_mesh/mesh_extract_options.h +++ b/include/plateau/polygon_mesh/mesh_extract_options.h @@ -37,7 +37,8 @@ namespace plateau::polygonMesh { texture_packing_resolution(2048), attach_map_tile(true), map_tile_zoom_level(15), - map_tile_url("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg") + map_tile_url("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg"), + is_polar_coordinate_system(true) {} public: @@ -111,5 +112,10 @@ namespace plateau::polygonMesh { * https://ctrlshift.hatenadiary.org/entry/20080119/1200719590 */ char map_tile_url[1000]; + + /** + * 極座標系か、平面直角座標系かを指定します。 + */ + bool is_polar_coordinate_system; }; } diff --git a/src/geometry/geo_coordinate.cpp b/src/geometry/geo_coordinate.cpp index 090a92d7..ef14d296 100644 --- a/src/geometry/geo_coordinate.cpp +++ b/src/geometry/geo_coordinate.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -49,14 +50,18 @@ namespace plateau::geometry { max.height >= point.height; } - bool Extent::contains(TVec3d point, bool ignore_height) const { + bool Extent::contains(TVec3d point, bool ignore_height, bool is_polar_coordinate_system) const { + if (!is_polar_coordinate_system) { + plateau::geometry::GeoReference geo_ref(0, TVec3d(0, 0, 0), 1.0f, CoordinateSystem::ENU); + return contains(geo_ref.unproject(point), ignore_height); + } return contains(GeoCoordinate(point.x, point.y, point.z), ignore_height); } - bool Extent::contains(const CityObject& city_obj, bool ignore_height) const{ + bool Extent::contains(const CityObject& city_obj, bool ignore_height, bool is_polar_coordinate_system) const{ try{ auto pos = PolygonMeshUtils::cityObjPos(city_obj); - return contains(pos, ignore_height); + return contains(pos, ignore_height, is_polar_coordinate_system); }catch(std::invalid_argument& e){ // 位置不明は false 扱いとします。 return false; diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 46e14429..3be21041 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -19,7 +19,7 @@ namespace { return false; for (const auto& extent : extents) { - if (extent.contains(city_obj)) + if (extent.contains(city_obj, true, options.is_polar_coordinate_system)) return false; } diff --git a/src/polygon_mesh/mesh_extractor.cpp b/src/polygon_mesh/mesh_extractor.cpp index 01791659..2cba8cdb 100644 --- a/src/polygon_mesh/mesh_extractor.cpp +++ b/src/polygon_mesh/mesh_extractor.cpp @@ -27,7 +27,7 @@ namespace { return false; for (const auto& extent : extents) { - if (extent.contains(city_obj)) + if (extent.contains(city_obj, true, options.is_polar_coordinate_system)) return false; } return true; diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index f03579fd..e9b0e952 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -32,9 +32,7 @@ namespace plateau::polygonMesh { */ void cityGmlPolygonToMesh( const Polygon& polygon, const std::string& gml_path, - const GeoReference& geo_reference, Mesh& out_mesh) { - - const auto& gml = plateau::dataset::GmlFile(gml_path); + const GeoReference& geo_reference, Mesh& out_mesh, bool is_polar_coordinate_system) { // マージ対象の情報を取得します。ここでの頂点は極座標です。 const auto& vertices_lat_lon = polygon.getVertices(); @@ -56,7 +54,7 @@ namespace plateau::polygonMesh { auto& out_vertices = out_mesh.getVertices(); out_vertices.reserve(vertices_lat_lon.size()); for (const auto& lat_lon : vertices_lat_lon) { - auto xyz = geo_reference.convert(lat_lon, false, gml.isPolarCoordinateSystem()); + auto xyz = geo_reference.convert(lat_lon, false, is_polar_coordinate_system); out_vertices.push_back(xyz); } assert(out_vertices.size() == vertices_lat_lon.size()); @@ -130,12 +128,12 @@ namespace plateau::polygonMesh { void findAllPolygonsInGeometry( const Geometry& geom, std::list& polygons, const unsigned lod, long long& out_vertices_count, - const std::vector extents) { + const std::vector extents, bool is_polar_coordinate_system) { // 子のジオメトリのポリゴンをすべて取得 const unsigned int child_count = geom.getGeometriesCount(); for (unsigned int i = 0; i < child_count; i++) { - findAllPolygonsInGeometry(geom.getGeometry(i), polygons, lod, out_vertices_count, extents); + findAllPolygonsInGeometry(geom.getGeometry(i), polygons, lod, out_vertices_count, extents, is_polar_coordinate_system); } if (geom.getLOD() != lod) return; @@ -148,7 +146,7 @@ namespace plateau::polygonMesh { // TODO: 計算コストが頂点数と範囲数に比例するため高速化 for (const auto& vertex : polygon->getVertices()) { for (const auto& extent : extents) { - if (extent.contains(vertex)) { + if (extent.contains(vertex, true, is_polar_coordinate_system)) { is_in_extent = true; break; } @@ -206,7 +204,7 @@ namespace plateau::polygonMesh { return; Mesh mesh; - cityGmlPolygonToMesh(polygon, gml_path, geo_reference_, mesh); + cityGmlPolygonToMesh(polygon, gml_path, geo_reference_, mesh, options_.is_polar_coordinate_system); const auto from_axis = geometry::CoordinateSystem::ENU; const auto to_axis = options_.mesh_axes; @@ -353,7 +351,7 @@ namespace plateau::polygonMesh { for (unsigned i = 0; i < geometry_count; i++) { findAllPolygonsInGeometry( city_obj.getGeometry(i), out_polygons, lod, - out_vertices_count, extents); + out_vertices_count, extents, options_.is_polar_coordinate_system); } } diff --git a/test/test_mesh_extractor.cpp b/test/test_mesh_extractor.cpp index 2dad32aa..149227c9 100644 --- a/test/test_mesh_extractor.cpp +++ b/test/test_mesh_extractor.cpp @@ -221,6 +221,7 @@ namespace plateau::polygonMesh { mesh_extract_options.coordinate_zone_id = 8; mesh_extract_options.unit_scale = 1.0; mesh_extract_options.mesh_axes = CoordinateSystem::ENU; + mesh_extract_options.is_polar_coordinate_system = false; const std::shared_ptr city_model = load(gml_path, params); const auto& gml = plateau::dataset::GmlFile((city_model->getGmlPath())); From 9fd91c843b1a426246713fdc7fad4afc614425b0 Mon Sep 17 00:00:00 2001 From: sevendev Date: Thu, 10 Apr 2025 18:59:16 +0900 Subject: [PATCH 04/24] =?UTF-8?q?=E5=88=A4=E5=AE=9A=E5=87=A6=E7=90=86?= =?UTF-8?q?=EF=BC=88temp)=20Unit=20Test=E3=81=8C=E9=80=9A=E3=82=89?= =?UTF-8?q?=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataQualityAttribute_geometrySrcDesc.xml" | 202 ++++++++++++++++++ .../DataQualityAttribute_thematicSrcDesc.xml" | 106 +++++++++ include/plateau/geometry/geo_coordinate.h | 4 +- src/geometry/geo_coordinate.cpp | 13 +- src/polygon_mesh/area_mesh_factory.cpp | 11 +- src/polygon_mesh/mesh_factory.cpp | 21 +- 6 files changed, 343 insertions(+), 14 deletions(-) create mode 100644 "data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_geometrySrcDesc.xml" create mode 100644 "data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_thematicSrcDesc.xml" diff --git "a/data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_geometrySrcDesc.xml" "b/data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_geometrySrcDesc.xml" new file mode 100644 index 00000000..2a4e2ad6 --- /dev/null +++ "b/data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_geometrySrcDesc.xml" @@ -0,0 +1,202 @@ + + +DataQualityAttribute_geometrySrcDesc + + +公共測量成果又は基本測量成果 +000 + + + + +(公共測量又は基本測量ではない)現地測量の測量成果 +101 + + + + +(公共測量又は基本測量ではない)UAV写真測量の測量成果 +102 + + + + +(公共測量又は基本測量ではない)空中写真測量の測量成果 +103 + + + + +(公共測量又は基本測量ではない)既成図数値化の測量成果 +104 + + + + +(公共測量又は基本測量ではない)修正測量の測量成果 +105 + + + + +(公共測量又は基本測量ではない)写真地図作成の測量成果 +106 + + + + +(公共測量又は基本測量ではない)地図編集の測量成果 +107 + + + + +(公共測量又は基本測量ではない)地上レーザ測量の測量成果 +108 + + + + +(公共測量又は基本測量ではない)UAV写真点群測量の測量成果 +109 + + + + +(公共測量又は基本測量ではない)UAVレーザ測量の測量成果 +110 + + + + +(公共測量又は基本測量ではない)車載写真レーザ測量の測量成果 +111 + + + + +(公共測量又は基本測量ではない)航空レーザ測量の測量成果 +112 + + + + +(公共測量又は基本測量ではない)航空レーザ測深測量の測量成果 +113 + + + + +(公共測量又は基本測量ではない)路線測量の測量成果 +114 + + + + +(公共測量又は基本測量ではない)河川測量の測量成果 +115 + + + + +(公共測量又は基本測量ではない)用地測量の測量成果 +116 + + + + +(公共測量又は基本測量ではない)その他の応用測量の測量成果 +117 + + + + +(公共測量又は基本測量ではない)LidarSLAM計測の測量成果 +118 + + + + +(公共測量又は基本測量ではない)高密度航空レーザ測量の測量成果 +119 + + + + +(公共測量又は基本測量ではない)写真点群測量の測量成果 +120 + + + + +(公共測量又は基本測量ではない)三次元数値図化の測量成果 +121 + + + + +都市計画基礎調査 +201 + + + + +都市計画図書 +202 + + + + +台帳 +300 + + + + +道路台帳 +301 + + + + +その他のGISデータ +400 + + + + +BIMモデル、CADデータ、設計図、完成図、一般図(平面図、配置図、断面図等) +500 + + + + +その他の資料 +700 + + + + +現地調査 +801 + + + + +GISデータ演算 +803 + + + + +推定 +901 + + + + +未作成 +999 + + + diff --git "a/data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_thematicSrcDesc.xml" "b/data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_thematicSrcDesc.xml" new file mode 100644 index 00000000..4551b888 --- /dev/null +++ "b/data/\346\227\245\346\234\254\350\252\236\343\203\221\343\202\271\343\203\206\343\202\271\343\203\210/codelists/DataQualityAttribute_thematicSrcDesc.xml" @@ -0,0 +1,106 @@ + + +DataQualityAttribute_thematicSrcDesc + + +公共測量成果又は基本測量成果 +000 + + + + +基盤地図情報 +022 + + + + +数値地形図データ +023 + + + + +公共測量成果又は基本測量成果ではない測量成果 +100 + + + + +都市計画基礎調査 +201 + + + + +都市計画図書 +202 + + + + +台帳 +300 + + + + +道路台帳 +301 + + + + +その他のGISデータ +400 + + + + +BIMモデル、CADデータ、設計図、完成図、一般図(平面図、配置図、断面図等) +500 + + + + +統計データ +600 + + + + +建築計画概要書 +701 + + + + +その他の資料 +700 + + + + +現地調査 +801 + + + + +写真判読 +802 + + + + +GISデータ演算 +803 + + + + +未作成 +999 + + + diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index c061fd7f..fdd3dc66 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -70,13 +70,13 @@ namespace plateau::geometry { } bool contains(GeoCoordinate point, bool ignore_height = true) const; - bool contains(TVec3d point, bool ignore_height = true, bool is_polar_coordinate_system = true) const; + bool contains(TVec3d point, bool ignore_height = true, bool is_polar_coordinate_system = true, int zone_id = 0) const; /** * 引数 city_obj の位置を推定し、その位置が Extent の範囲内に含まれるかどうかを返します。 * city_obj の位置が不明の場合は false を返します。 */ - bool contains(const citygml::CityObject& city_obj, bool ignore_height = true, bool is_polar_coordinate_system = true) const; + bool contains(const citygml::CityObject& city_obj, bool ignore_height = true, bool is_polar_coordinate_system = true, int zone_id = 0) const; /** * other と交わる箇所があるかどうかを返します。 diff --git a/src/geometry/geo_coordinate.cpp b/src/geometry/geo_coordinate.cpp index ef14d296..0859f03e 100644 --- a/src/geometry/geo_coordinate.cpp +++ b/src/geometry/geo_coordinate.cpp @@ -50,15 +50,16 @@ namespace plateau::geometry { max.height >= point.height; } - bool Extent::contains(TVec3d point, bool ignore_height, bool is_polar_coordinate_system) const { - if (!is_polar_coordinate_system) { - plateau::geometry::GeoReference geo_ref(0, TVec3d(0, 0, 0), 1.0f, CoordinateSystem::ENU); - return contains(geo_ref.unproject(point), ignore_height); - } + bool Extent::contains(TVec3d point, bool ignore_height, bool is_polar_coordinate_system, int zone_id) const { + // if (!is_polar_coordinate_system) { + //plateau::geometry::GeoReference geo_ref(zone_id, TVec3d(0, 0, 0), 1.0f, CoordinateSystem::ENU); + // return contains(geo_ref.unproject(point), ignore_height); + // //return true; + // } return contains(GeoCoordinate(point.x, point.y, point.z), ignore_height); } - bool Extent::contains(const CityObject& city_obj, bool ignore_height, bool is_polar_coordinate_system) const{ + bool Extent::contains(const CityObject& city_obj, bool ignore_height, bool is_polar_coordinate_system, int zone_id) const{ try{ auto pos = PolygonMeshUtils::cityObjPos(city_obj); return contains(pos, ignore_height, is_polar_coordinate_system); diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 3be21041..5eced8c6 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -19,7 +19,16 @@ namespace { return false; for (const auto& extent : extents) { - if (extent.contains(city_obj, true, options.is_polar_coordinate_system)) + + if (!options.is_polar_coordinate_system) { + //plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); + //auto pos = PolygonMeshUtils::cityObjPos(city_obj); + //if (extent.contains(geo_ref.unproject(pos))) + // return false; + return false; + } + + if (extent.contains(city_obj)) return false; } diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index e9b0e952..68c9715e 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -128,12 +128,12 @@ namespace plateau::polygonMesh { void findAllPolygonsInGeometry( const Geometry& geom, std::list& polygons, const unsigned lod, long long& out_vertices_count, - const std::vector extents, bool is_polar_coordinate_system) { + const std::vector extents, const MeshExtractOptions& options) { // 子のジオメトリのポリゴンをすべて取得 const unsigned int child_count = geom.getGeometriesCount(); for (unsigned int i = 0; i < child_count; i++) { - findAllPolygonsInGeometry(geom.getGeometry(i), polygons, lod, out_vertices_count, extents, is_polar_coordinate_system); + findAllPolygonsInGeometry(geom.getGeometry(i), polygons, lod, out_vertices_count, extents, options); } if (geom.getLOD() != lod) return; @@ -146,7 +146,18 @@ namespace plateau::polygonMesh { // TODO: 計算コストが頂点数と範囲数に比例するため高速化 for (const auto& vertex : polygon->getVertices()) { for (const auto& extent : extents) { - if (extent.contains(vertex, true, is_polar_coordinate_system)) { + + if (!options.is_polar_coordinate_system) { + //plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); + //if (extent.contains(geo_ref.unproject(vertex))) { + // is_in_extent = true; + // break; + //} + is_in_extent = true; + break; + } + + if (extent.contains(vertex)) { is_in_extent = true; break; } @@ -347,11 +358,11 @@ namespace plateau::polygonMesh { std::vector extents = { Extent::all() }; if (options_.exclude_polygons_outside_extent) extents = extents_; - + for (unsigned i = 0; i < geometry_count; i++) { findAllPolygonsInGeometry( city_obj.getGeometry(i), out_polygons, lod, - out_vertices_count, extents, options_.is_polar_coordinate_system); + out_vertices_count, extents, options_); } } From 96e7d119500c71d15054f8b1627f08301adb9ab4 Mon Sep 17 00:00:00 2001 From: sevendev Date: Thu, 10 Apr 2025 19:13:16 +0900 Subject: [PATCH 05/24] =?UTF-8?q?Unit=20Test=E9=80=9A=E3=81=A3=E3=81=9F?= =?UTF-8?q?=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 4 ++-- src/geometry/geo_coordinate.cpp | 11 +++-------- src/polygon_mesh/mesh_extractor.cpp | 5 ++++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index fdd3dc66..54655582 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -70,13 +70,13 @@ namespace plateau::geometry { } bool contains(GeoCoordinate point, bool ignore_height = true) const; - bool contains(TVec3d point, bool ignore_height = true, bool is_polar_coordinate_system = true, int zone_id = 0) const; + bool contains(TVec3d point, bool ignore_height = true) const; /** * 引数 city_obj の位置を推定し、その位置が Extent の範囲内に含まれるかどうかを返します。 * city_obj の位置が不明の場合は false を返します。 */ - bool contains(const citygml::CityObject& city_obj, bool ignore_height = true, bool is_polar_coordinate_system = true, int zone_id = 0) const; + bool contains(const citygml::CityObject& city_obj, bool ignore_height = true) const; /** * other と交わる箇所があるかどうかを返します。 diff --git a/src/geometry/geo_coordinate.cpp b/src/geometry/geo_coordinate.cpp index 0859f03e..51ed9206 100644 --- a/src/geometry/geo_coordinate.cpp +++ b/src/geometry/geo_coordinate.cpp @@ -50,19 +50,14 @@ namespace plateau::geometry { max.height >= point.height; } - bool Extent::contains(TVec3d point, bool ignore_height, bool is_polar_coordinate_system, int zone_id) const { - // if (!is_polar_coordinate_system) { - //plateau::geometry::GeoReference geo_ref(zone_id, TVec3d(0, 0, 0), 1.0f, CoordinateSystem::ENU); - // return contains(geo_ref.unproject(point), ignore_height); - // //return true; - // } + bool Extent::contains(TVec3d point, bool ignore_height) const { return contains(GeoCoordinate(point.x, point.y, point.z), ignore_height); } - bool Extent::contains(const CityObject& city_obj, bool ignore_height, bool is_polar_coordinate_system, int zone_id) const{ + bool Extent::contains(const CityObject& city_obj, bool ignore_height) const{ try{ auto pos = PolygonMeshUtils::cityObjPos(city_obj); - return contains(pos, ignore_height, is_polar_coordinate_system); + return contains(pos, ignore_height); }catch(std::invalid_argument& e){ // 位置不明は false 扱いとします。 return false; diff --git a/src/polygon_mesh/mesh_extractor.cpp b/src/polygon_mesh/mesh_extractor.cpp index 2cba8cdb..40d6e78c 100644 --- a/src/polygon_mesh/mesh_extractor.cpp +++ b/src/polygon_mesh/mesh_extractor.cpp @@ -26,8 +26,11 @@ namespace { if (!options.exclude_city_object_outside_extent) return false; + if (!options.is_polar_coordinate_system) + return false; + for (const auto& extent : extents) { - if (extent.contains(city_obj, true, options.is_polar_coordinate_system)) + if (extent.contains(city_obj)) return false; } return true; From dc08d4949db3e83544665c86b84c78bca19d8a2c Mon Sep 17 00:00:00 2001 From: sevendev Date: Fri, 11 Apr 2025 09:25:11 +0900 Subject: [PATCH 06/24] C# MeshExtractOptions --- .../CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs index 796f6f97..7fc0a119 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs @@ -72,7 +72,7 @@ public static ConvertGranularity ToConvertGranularity(this MeshGranularity g) [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct MeshExtractOptions { - public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshAxes, MeshGranularity meshGranularity, uint minLOD, uint maxLOD, bool exportAppearance, int gridCountOfSide, float unitScale, int coordinateZoneID, bool excludeCityObjectOutsideExtent, bool excludePolygonsOutsideExtent, bool enableTexturePacking, uint texturePackingResolution, bool attachMapTile, int mapTileZoomLevel, string mapTileURL) + public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshAxes, MeshGranularity meshGranularity, uint minLOD, uint maxLOD, bool exportAppearance, int gridCountOfSide, float unitScale, int coordinateZoneID, bool excludeCityObjectOutsideExtent, bool excludePolygonsOutsideExtent, bool enableTexturePacking, uint texturePackingResolution, bool attachMapTile, int mapTileZoomLevel, string mapTileURL, bool isPolarCoordinateSystem) { this.ReferencePoint = referencePoint; this.MeshAxes = meshAxes; @@ -90,6 +90,7 @@ public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshA this.AttachMapTile = attachMapTile; this.MapTileZoomLevel = mapTileZoomLevel; this.mapTileURL = mapTileURL; + this.IsPolarCoordinateSystem = isPolarCoordinateSystem; // 上で全てのメンバー変数を設定できてますが、バリデーションをするため念のためメソッドやプロパティも呼びます。 SetLODRange(minLOD, maxLOD); @@ -224,6 +225,12 @@ public string MapTileURL } } + /// + /// 極座標系か、平面直角座標系かを指定します。 + /// EPSG:6697 極座標系, EPSG:10162~10174 平面直角座標系 + /// + [MarshalAs(UnmanagedType.U1)] public bool IsPolarCoordinateSystem; + /// デフォルト値の設定を返します。 internal static MeshExtractOptions DefaultValue() { From 3080821757b9d05ffc82772251d9aea5d8bc442f Mon Sep 17 00:00:00 2001 From: sevendev Date: Fri, 11 Apr 2025 11:51:55 +0900 Subject: [PATCH 07/24] =?UTF-8?q?contains=E5=88=A4=E5=AE=9A=E3=80=80?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/polygon_mesh/area_mesh_factory.cpp | 13 ++++++++----- src/polygon_mesh/mesh_extractor.cpp | 21 ++++++++++++++++----- src/polygon_mesh/mesh_factory.cpp | 21 ++++++++++----------- test/test_mesh_extractor.cpp | 2 ++ 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 5eced8c6..3f2cc887 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -7,6 +7,7 @@ namespace { using namespace plateau; using namespace polygonMesh; + using namespace geometry; /** * グリッド番号と、そのグリッドに属する CityObject のリストを対応付ける辞書です。 @@ -21,11 +22,13 @@ namespace { for (const auto& extent : extents) { if (!options.is_polar_coordinate_system) { - //plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); - //auto pos = PolygonMeshUtils::cityObjPos(city_obj); - //if (extent.contains(geo_ref.unproject(pos))) - // return false; - return false; + plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); + try { + auto pos = PolygonMeshUtils::cityObjPos(city_obj); + if (extent.contains(geo_ref.unproject(pos))) + return false; + } + catch (std::invalid_argument& e) {} } if (extent.contains(city_obj)) diff --git a/src/polygon_mesh/mesh_extractor.cpp b/src/polygon_mesh/mesh_extractor.cpp index 40d6e78c..c5a32465 100644 --- a/src/polygon_mesh/mesh_extractor.cpp +++ b/src/polygon_mesh/mesh_extractor.cpp @@ -26,12 +26,23 @@ namespace { if (!options.exclude_city_object_outside_extent) return false; - if (!options.is_polar_coordinate_system) + if (!options.is_polar_coordinate_system) { + plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); + try { + auto pos = PolygonMeshUtils::cityObjPos(city_obj); + for (const auto& extent : extents) { + if (extent.contains(geo_ref.unproject(pos))) + return false; + } + } + catch (std::invalid_argument& e) {} return false; - - for (const auto& extent : extents) { - if (extent.contains(city_obj)) - return false; + } + else { + for (const auto& extent : extents) { + if (extent.contains(city_obj)) + return false; + } } return true; } diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index 68c9715e..a75de84c 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -148,18 +148,17 @@ namespace plateau::polygonMesh { for (const auto& extent : extents) { if (!options.is_polar_coordinate_system) { - //plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); - //if (extent.contains(geo_ref.unproject(vertex))) { - // is_in_extent = true; - // break; - //} - is_in_extent = true; - break; + plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); + if (extent.contains(geo_ref.unproject(vertex))) { + is_in_extent = true; + break; + } } - - if (extent.contains(vertex)) { - is_in_extent = true; - break; + else { + if (extent.contains(vertex)) { + is_in_extent = true; + break; + } } } if (is_in_extent) diff --git a/test/test_mesh_extractor.cpp b/test/test_mesh_extractor.cpp index 149227c9..81ab9b4b 100644 --- a/test/test_mesh_extractor.cpp +++ b/test/test_mesh_extractor.cpp @@ -228,7 +228,9 @@ namespace plateau::polygonMesh { ASSERT_FALSE(gml.isPolarCoordinateSystem()); auto model = MeshExtractor::extract(*city_model, mesh_extract_options); + ASSERT_GE(1, model->getRootNodeCount()); const auto& lod_node = model->getRootNodeAt(0); + ASSERT_GE(1, lod_node.getChildCount()); const auto& first_model_node = lod_node.getChildAt(0); const auto& mesh = first_model_node.getMesh(); From 0644111323c784b63f23f823733fba5740ef59b7 Mon Sep 17 00:00:00 2001 From: sevendev Date: Fri, 11 Apr 2025 16:12:17 +0900 Subject: [PATCH 08/24] comment removed --- include/plateau/geometry/geo_coordinate.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 54655582..7f28b44f 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -96,8 +96,6 @@ namespace plateau::geometry { return { GeoCoordinate(-90, -180, -9999), GeoCoordinate(90, 180, 9999) - //GeoCoordinate(-9999999, -9999999, -9999), - //GeoCoordinate(9999999, 9999999, 9999) }; } }; From 5499628ef87f04d2fd056ba8c1976c31c2ca35d8 Mon Sep 17 00:00:00 2001 From: sevendev Date: Mon, 14 Apr 2025 09:25:55 +0900 Subject: [PATCH 09/24] =?UTF-8?q?contains=20=E5=87=A6=E7=90=86=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/polygon_mesh/area_mesh_factory.cpp | 1 + src/polygon_mesh/mesh_extractor.cpp | 6 +++--- src/polygon_mesh/mesh_factory.cpp | 1 + src/polygon_mesh/polygon_mesh_utils.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 3f2cc887..64e8a22b 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -22,6 +22,7 @@ namespace { for (const auto& extent : extents) { if (!options.is_polar_coordinate_system) { + // 平面直角座標系の判定 plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); try { auto pos = PolygonMeshUtils::cityObjPos(city_obj); diff --git a/src/polygon_mesh/mesh_extractor.cpp b/src/polygon_mesh/mesh_extractor.cpp index c5a32465..cf566d8f 100644 --- a/src/polygon_mesh/mesh_extractor.cpp +++ b/src/polygon_mesh/mesh_extractor.cpp @@ -27,16 +27,16 @@ namespace { return false; if (!options.is_polar_coordinate_system) { + // 平面直角座標系の判定 plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); try { - auto pos = PolygonMeshUtils::cityObjPos(city_obj); + auto pos = geo_ref.unproject(PolygonMeshUtils::cityObjPos(city_obj)); for (const auto& extent : extents) { - if (extent.contains(geo_ref.unproject(pos))) + if (extent.contains(pos)) return false; } } catch (std::invalid_argument& e) {} - return false; } else { for (const auto& extent : extents) { diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index a75de84c..63ed9f2a 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -148,6 +148,7 @@ namespace plateau::polygonMesh { for (const auto& extent : extents) { if (!options.is_polar_coordinate_system) { + // 平面直角座標系の判定 plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); if (extent.contains(geo_ref.unproject(vertex))) { is_in_extent = true; diff --git a/src/polygon_mesh/polygon_mesh_utils.cpp b/src/polygon_mesh/polygon_mesh_utils.cpp index 4ff9f853..1a39c4c1 100644 --- a/src/polygon_mesh/polygon_mesh_utils.cpp +++ b/src/polygon_mesh/polygon_mesh_utils.cpp @@ -60,7 +60,7 @@ namespace plateau::polygonMesh { if (!envelope.validBounds()) { return TVec3d{0, 0, 0}; } - const auto& gml = plateau::dataset::GmlFile(city_model.getGmlPath()); + const auto& gml = plateau::dataset::GmlFile(city_model.getGmlPath()); // 平面直角座標系の判定用 auto city_center = (envelope.getLowerBound() + envelope.getUpperBound()) / 2.0; return geometry::GeoReference(coordinate_zone_id).convert(city_center, true, gml.isPolarCoordinateSystem()); } From 6fdbb860123700dce6f0cc2ee5e633a602234427 Mon Sep 17 00:00:00 2001 From: sevendev Date: Thu, 17 Apr 2025 17:41:07 +0900 Subject: [PATCH 10/24] =?UTF-8?q?xy=E5=8F=8D=E8=BB=A2=20=E5=B9=B3=E9=9D=A2?= =?UTF-8?q?=E3=83=BC>=E7=B7=AF=E5=BA=A6=E7=B5=8C=E5=BA=A6->=E5=B9=B3?= =?UTF-8?q?=E9=9D=A2=E3=81=AB=E5=86=8D=E5=A4=89=E6=8F=9B=E5=87=A6=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/dataset/gml_file.h | 1 - include/plateau/geometry/geo_coordinate.h | 121 ++++++++++++++++++ include/plateau/geometry/geo_reference.h | 5 +- .../polygon_mesh/mesh_extract_options.h | 10 +- src/c_wrapper/geometry_utils_c.cpp | 13 ++ src/c_wrapper/gml_file_c.cpp | 8 +- src/dataset/gml_file.cpp | 10 -- src/geometry/geo_coordinate.cpp | 26 ++++ src/geometry/geo_reference.cpp | 35 ++++- src/polygon_mesh/area_mesh_factory.cpp | 14 +- src/polygon_mesh/mesh_extractor.cpp | 22 +--- src/polygon_mesh/mesh_factory.cpp | 23 +--- src/polygon_mesh/polygon_mesh_utils.cpp | 3 +- test/CMakeLists.txt | 1 + test/test_geo_coordinate.cpp | 40 ++++++ test/test_geo_reference.cpp | 34 +++-- test/test_gml_file.cpp | 4 +- test/test_mesh_extractor.cpp | 13 +- .../CSharpPLATEAU/Dataset/GmlFile.cs | 10 +- .../PolygonMesh/MeshExtractOptions.cs | 10 +- 20 files changed, 295 insertions(+), 108 deletions(-) create mode 100644 test/test_geo_coordinate.cpp diff --git a/include/plateau/dataset/gml_file.h b/include/plateau/dataset/gml_file.h index e9954d30..aff4559b 100644 --- a/include/plateau/dataset/gml_file.h +++ b/include/plateau/dataset/gml_file.h @@ -22,7 +22,6 @@ namespace plateau::dataset { void setPath(const std::string& path); MeshCode getMeshCode() const; double getEpsg() const; - bool isPolarCoordinateSystem() const; const std::string& getFeatureType() const; PredefinedCityModelPackage getPackage() const; std::string getAppearanceDirectoryPath() const; diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 7f28b44f..78569ed4 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -78,6 +78,12 @@ namespace plateau::geometry { */ bool contains(const citygml::CityObject& city_obj, bool ignore_height = true) const; + /** + * 平面直角座標系の判定を含む処理です + */ + bool containsInPolar(TVec3d point,const double epsg, bool ignore_height = true) const; + bool containsInPolar(const citygml::CityObject& city_obj,const double epsg, bool ignore_height = true) const; + /** * other と交わる箇所があるかどうかを返します。 * ただし other の高さは無視して緯度と経度の2次元のみで判定します。 @@ -99,4 +105,119 @@ namespace plateau::geometry { }; } }; + + /** + * 平面直角座標判定、平面直角座標の基準点取得 + */ + struct CoordinateReferenceFactory { + // EPSGごとのzone取得 + static int GetZoneId(double epsg) { + // 日本測地系2011(JGD2011)に基づく平面直角座標系 + if (epsg == 10162) { + return 1; // 1系 + } + else if (epsg == 10163) { + return 2; // 2系 + } + else if (epsg == 10164) { + return 3; // 3系 + } + else if (epsg == 10165) { + return 4; // 4系 + } + else if (epsg == 10166) { + return 5; // 5系 + } + else if (epsg == 10167) { + return 6; // 6系 + } + else if (epsg == 10168) { + return 7; // 7系 + } + else if (epsg == 10169) { + return 8; // 8系 + } + else if (epsg == 10170) { + return 9; // 9系 + } + else if (epsg == 10171) { + return 10; // 10系 + } + else if (epsg == 10172) { + return 11; // 11系 + } + else if (epsg == 10173) { + return 12; // 12系 + } + else if (epsg == 10174) { + return 13; // 13系 + } + return 0; + } + + // EPSGごとの基準点取得 + static GeoCoordinate GetReferencePoint(double epsg) { + const int zone = GetZoneId(epsg); + if (zone != 0) + return GetReferencePointByZone(zone); + return GeoCoordinate(); + } + + // Zone IDごとの基準点 + // zoneに紐づく基準点はPolarToPlaneCartesianにハードコードで持っているが値が取得できないので、ここで定義 + static GeoCoordinate GetReferencePointByZone(int zone_id) { + switch (zone_id) { + case 1: + return GeoCoordinate(33, 129.5, 0); + case 2: + return GeoCoordinate(33, 131, 0); + case 3: + return GeoCoordinate(36, 132.166667, 0); + case 4: + return GeoCoordinate(33, 133.5, 0); + case 5: + return GeoCoordinate(36, 134.333333, 0); + case 6: + return GeoCoordinate(36, 136, 0); + case 7: + return GeoCoordinate(36, 137.166667, 0); + case 8: + return GeoCoordinate(36, 138.5, 0); + case 9: + return GeoCoordinate(35, 139.833333, 0); + case 10: + return GeoCoordinate(40, 140.833333, 0); + case 11: + return GeoCoordinate(44, 140.25, 0); + case 12: + return GeoCoordinate(44, 142, 0); + case 13: + return GeoCoordinate(43, 144, 0); + case 14: + return GeoCoordinate(26, 142, 0); + case 15: + return GeoCoordinate(26, 127.5, 0); + case 16: + return GeoCoordinate(24, 124, 0); + case 17: + return GeoCoordinate(31, 131, 0); + case 18: + return GeoCoordinate(20, 136, 0); + case 19: + return GeoCoordinate(25, 154, 0); + default: + return GeoCoordinate(); + } + } + + // 極座標系・平面直角座標系判定 + static bool IsPolarCoordinateSystem(double epsg) { + // 平面直角座標系の区分についてはこちらを参照してください : + // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ + if (epsg >= 10162 && epsg <= 10174) { + return false; + } + return true; + } + }; } diff --git a/include/plateau/geometry/geo_reference.h b/include/plateau/geometry/geo_reference.h index 52ca6680..7286aa10 100644 --- a/include/plateau/geometry/geo_reference.h +++ b/include/plateau/geometry/geo_reference.h @@ -26,10 +26,13 @@ namespace plateau::geometry { /// project の座標軸変換をしない版です。座標軸は ENU → ENU であるとします。 reference_point_ は ENUに変換されます。 TVec3d projectWithoutAxisConvert(const TVec3d& lat_lon) const; TVec3d convertAxisToENU(const TVec3d& vertex) const; - TVec3d convert(const TVec3d& lat_lon, const bool convert_axis = true, const bool project = true) const; + TVec3d convert(const TVec3d& lat_lon, const bool convert_axis = true, const double epsg = 6697) const; static TVec3d convertAxisFromENUTo(CoordinateSystem axis, const TVec3d& vertex); static TVec3d convertAxisToENU(CoordinateSystem axis, const TVec3d& vertex); + static TVec3d reverseXY(const TVec3d& vertex); + static GeoCoordinate planeToPolar(const TVec3d& vertex, const int coordinate_zone_id); + GeoCoordinate unproject(const TVec3d& point) const; void setReferencePoint(TVec3d point); diff --git a/include/plateau/polygon_mesh/mesh_extract_options.h b/include/plateau/polygon_mesh/mesh_extract_options.h index a3a8e564..6390bf2d 100644 --- a/include/plateau/polygon_mesh/mesh_extract_options.h +++ b/include/plateau/polygon_mesh/mesh_extract_options.h @@ -38,7 +38,7 @@ namespace plateau::polygonMesh { attach_map_tile(true), map_tile_zoom_level(15), map_tile_url("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg"), - is_polar_coordinate_system(true) + epsg_code(6697) {} public: @@ -113,9 +113,9 @@ namespace plateau::polygonMesh { */ char map_tile_url[1000]; - /** - * 極座標系か、平面直角座標系かを指定します。 - */ - bool is_polar_coordinate_system; + /** + * 平面直角座標系は、EPSGコードに応じて基準点を取得します。 + */ + double epsg_code; }; } diff --git a/src/c_wrapper/geometry_utils_c.cpp b/src/c_wrapper/geometry_utils_c.cpp index c49f3f82..fea1f6ec 100644 --- a/src/c_wrapper/geometry_utils_c.cpp +++ b/src/c_wrapper/geometry_utils_c.cpp @@ -1,8 +1,10 @@ #include "libplateau_c.h" #include "city_model_c.h" #include +#include using namespace libplateau; using namespace plateau::polygonMesh; +using namespace plateau::geometry; extern "C" { @@ -12,4 +14,15 @@ DLL_VALUE_FUNC(plateau_geometry_utils_get_center_point, PolygonMeshUtils::getCenterPoint(*handle->getCityModelPtr(), coordinate_zone_id), ,int coordinate_zone_id) +LIBPLATEAU_C_EXPORT APIResult LIBPLATEAU_C_API plateau_geometry_utils_is_polar_coordinate_system( + double epsg, + bool* out +) { +API_TRY{ + *out = CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg); + return APIResult::Success; +} API_CATCH + return APIResult::ErrorUnknown; +} + } diff --git a/src/c_wrapper/gml_file_c.cpp b/src/c_wrapper/gml_file_c.cpp index 85a0221b..31a1bc8a 100644 --- a/src/c_wrapper/gml_file_c.cpp +++ b/src/c_wrapper/gml_file_c.cpp @@ -53,10 +53,10 @@ extern "C" { double, handle->getEpsg()) - DLL_VALUE_FUNC(plateau_gml_file_is_polar_coordinate_system, - GmlFile, - bool, - handle->isPolarCoordinateSystem()) + //DLL_VALUE_FUNC(plateau_gml_file_is_polar_coordinate_system, + // GmlFile, + // bool, + // handle->isPolarCoordinateSystem()) LIBPLATEAU_C_EXPORT APIResult LIBPLATEAU_C_API plateau_gml_file_fetch( const GmlFile* const gml_file_info, diff --git a/src/dataset/gml_file.cpp b/src/dataset/gml_file.cpp index 5549fa00..36daa49d 100644 --- a/src/dataset/gml_file.cpp +++ b/src/dataset/gml_file.cpp @@ -60,16 +60,6 @@ namespace plateau::dataset { } } - bool GmlFile::isPolarCoordinateSystem() const { - double epsg = getEpsg(); - // 平面直角座標系の区分についてはこちらを参照してください : - // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ - if (epsg >= 10162 && epsg <= 10174) { - return false; - } - return true; - } - const std::string& GmlFile::getFeatureType() const { return feature_type_; } diff --git a/src/geometry/geo_coordinate.cpp b/src/geometry/geo_coordinate.cpp index 51ed9206..52178e11 100644 --- a/src/geometry/geo_coordinate.cpp +++ b/src/geometry/geo_coordinate.cpp @@ -64,6 +64,32 @@ namespace plateau::geometry { } } + bool Extent::containsInPolar(TVec3d point, const double epsg, bool ignore_height) const { + + if (!CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg)) { + // 平面直角座標系の判定 + const auto& unprojected = GeoReference::planeToPolar(point, CoordinateReferenceFactory::GetZoneId(epsg)); + point = { unprojected.latitude, unprojected.longitude, unprojected.height }; + } + return contains(GeoCoordinate(point.x, point.y, point.z), ignore_height); + } + + bool Extent::containsInPolar(const CityObject& city_obj, const double epsg, bool ignore_height) const { + + if (!CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg)) { + // 平面直角座標系の判定 + try { + const auto pos = PolygonMeshUtils::cityObjPos(city_obj); + return containsInPolar(pos, epsg, ignore_height); + } + catch (std::invalid_argument& e) { + // 位置不明は false 扱いとします。 + return false; + } + } + return contains(city_obj, ignore_height); + } + bool Extent::intersects2D(const Extent& other) const { const auto center_1 = centerPoint(); const auto center_2 = other.centerPoint(); diff --git a/src/geometry/geo_reference.cpp b/src/geometry/geo_reference.cpp index 584c32f8..b4811962 100644 --- a/src/geometry/geo_reference.cpp +++ b/src/geometry/geo_reference.cpp @@ -24,18 +24,26 @@ namespace plateau::geometry { return converted_point; } - TVec3d GeoReference::convert(const TVec3d& lat_lon, const bool convert_axis, const bool project) const { + //平面直角座標判定を含むproject, projectWithoutAxisConvert処理と同様の処理 + TVec3d GeoReference::convert(const TVec3d& lat_lon, const bool convert_axis, const double epsg) const { //平面直角座標変換、座標軸変換をフラグに応じてスキップします。 TVec3d point = lat_lon; - // 平面直角座標系に変換 - if (project) - PolarToPlaneCartesian().project(point, zone_id_); + + // 極座標系・平面直角座標系判定 + const bool is_polar = CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg); + if (!is_polar) { + //平面直角座標の場合は緯度経度に変換 + const auto& unprojected = planeToPolar(point, CoordinateReferenceFactory::GetZoneId(epsg)); + point = { unprojected.latitude, unprojected.longitude, unprojected.height }; + } + + PolarToPlaneCartesian().project(point, zone_id_); if (!convert_axis) { - // 座標軸変換をしない場合 + // 座標軸変換をしない場合 TVec3 converted_point = point / unit_scale_ - convertAxisToENU(coordinate_system_, reference_point_); return converted_point; } - // 座標軸変換をする場合 + // 座標軸変換をする場合 TVec3 converted_point = convertAxisFromENUTo(coordinate_system_, point); converted_point = converted_point / unit_scale_ - reference_point_; return converted_point; @@ -88,6 +96,21 @@ namespace plateau::geometry { } } + //平面直角座標のGMLの座標は xyが反転しているので変換 + TVec3d GeoReference::reverseXY(const TVec3d& vertex) { + return { vertex.y, vertex.x, vertex.z }; //x,y反転 + } + + //平面直角座標から緯度経度に変換 + GeoCoordinate GeoReference::planeToPolar(const TVec3d& vertex, const int coordinate_zone_id) { + TVec3d point = vertex; + point = reverseXY(point); + plateau::geometry::GeoReference geo_ref(coordinate_zone_id); + const auto unprojected = geo_ref.unproject(point); + //point = { unprojected.latitude, unprojected.longitude, unprojected.height }; + return unprojected; + } + void GeoReference::setReferencePoint(TVec3d point) { reference_point_ = point; } diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 64e8a22b..af42f28a 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -20,19 +20,7 @@ namespace { return false; for (const auto& extent : extents) { - - if (!options.is_polar_coordinate_system) { - // 平面直角座標系の判定 - plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); - try { - auto pos = PolygonMeshUtils::cityObjPos(city_obj); - if (extent.contains(geo_ref.unproject(pos))) - return false; - } - catch (std::invalid_argument& e) {} - } - - if (extent.contains(city_obj)) + if (extent.containsInPolar(city_obj, options.epsg_code)) return false; } diff --git a/src/polygon_mesh/mesh_extractor.cpp b/src/polygon_mesh/mesh_extractor.cpp index cf566d8f..d70a9139 100644 --- a/src/polygon_mesh/mesh_extractor.cpp +++ b/src/polygon_mesh/mesh_extractor.cpp @@ -25,24 +25,10 @@ namespace { // 範囲外を省く設定ならば省きます。 if (!options.exclude_city_object_outside_extent) return false; - - if (!options.is_polar_coordinate_system) { - // 平面直角座標系の判定 - plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); - try { - auto pos = geo_ref.unproject(PolygonMeshUtils::cityObjPos(city_obj)); - for (const auto& extent : extents) { - if (extent.contains(pos)) - return false; - } - } - catch (std::invalid_argument& e) {} - } - else { - for (const auto& extent : extents) { - if (extent.contains(city_obj)) - return false; - } + + for (const auto& extent : extents) { + if (extent.containsInPolar(city_obj, options.epsg_code)) + return false; } return true; } diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index 63ed9f2a..a507ee5f 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -32,7 +32,7 @@ namespace plateau::polygonMesh { */ void cityGmlPolygonToMesh( const Polygon& polygon, const std::string& gml_path, - const GeoReference& geo_reference, Mesh& out_mesh, bool is_polar_coordinate_system) { + const GeoReference& geo_reference, Mesh& out_mesh, double epsg) { // マージ対象の情報を取得します。ここでの頂点は極座標です。 const auto& vertices_lat_lon = polygon.getVertices(); @@ -54,7 +54,7 @@ namespace plateau::polygonMesh { auto& out_vertices = out_mesh.getVertices(); out_vertices.reserve(vertices_lat_lon.size()); for (const auto& lat_lon : vertices_lat_lon) { - auto xyz = geo_reference.convert(lat_lon, false, is_polar_coordinate_system); + auto xyz = geo_reference.convert(lat_lon, false, epsg); out_vertices.push_back(xyz); } assert(out_vertices.size() == vertices_lat_lon.size()); @@ -146,20 +146,9 @@ namespace plateau::polygonMesh { // TODO: 計算コストが頂点数と範囲数に比例するため高速化 for (const auto& vertex : polygon->getVertices()) { for (const auto& extent : extents) { - - if (!options.is_polar_coordinate_system) { - // 平面直角座標系の判定 - plateau::geometry::GeoReference geo_ref(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); - if (extent.contains(geo_ref.unproject(vertex))) { - is_in_extent = true; - break; - } - } - else { - if (extent.contains(vertex)) { - is_in_extent = true; - break; - } + if (extent.containsInPolar(vertex, options.epsg_code)) { + is_in_extent = true; + break; } } if (is_in_extent) @@ -215,7 +204,7 @@ namespace plateau::polygonMesh { return; Mesh mesh; - cityGmlPolygonToMesh(polygon, gml_path, geo_reference_, mesh, options_.is_polar_coordinate_system); + cityGmlPolygonToMesh(polygon, gml_path, geo_reference_, mesh, options_.epsg_code); const auto from_axis = geometry::CoordinateSystem::ENU; const auto to_axis = options_.mesh_axes; diff --git a/src/polygon_mesh/polygon_mesh_utils.cpp b/src/polygon_mesh/polygon_mesh_utils.cpp index 1a39c4c1..e8cb6e24 100644 --- a/src/polygon_mesh/polygon_mesh_utils.cpp +++ b/src/polygon_mesh/polygon_mesh_utils.cpp @@ -1,6 +1,7 @@ #include #include "plateau/polygon_mesh/mesh.h" #include "plateau/geometry/geo_reference.h" +#include "plateau/geometry/geo_coordinate.h" #include "citygml/citymodel.h" #include @@ -62,7 +63,7 @@ namespace plateau::polygonMesh { } const auto& gml = plateau::dataset::GmlFile(city_model.getGmlPath()); // 平面直角座標系の判定用 auto city_center = (envelope.getLowerBound() + envelope.getUpperBound()) / 2.0; - return geometry::GeoReference(coordinate_zone_id).convert(city_center, true, gml.isPolarCoordinateSystem()); + return geometry::GeoReference(coordinate_zone_id).convert(city_center, true, gml.getEpsg()); } /** diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2b7eee80..e7936a5a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -50,6 +50,7 @@ add_executable(plateau_test "test_height_map_aligner.cpp" "test_heightmap_mesh_generator.cpp" "test_geo_reference.cpp" + "test_geo_coordinate.cpp" ) add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/test_granularity_convert") diff --git a/test/test_geo_coordinate.cpp b/test/test_geo_coordinate.cpp new file mode 100644 index 00000000..2d617a8f --- /dev/null +++ b/test/test_geo_coordinate.cpp @@ -0,0 +1,40 @@ +#include +#include "../src/geometry/geo_coordinate.cpp" + +namespace plateau::geometry { + class GeoCoordinateTest : public ::testing::Test { + protected: + void SetUp() override { + } + void TearDown() override { + } + }; + + TEST_F(GeoCoordinateTest, ExtentContains) { // NOLINT + + plateau::geometry::Extent ext(GeoCoordinate(-30, -90, -9999), GeoCoordinate(30, 90, 9999)); + plateau::geometry::Extent ext2(GeoCoordinate(-30, -90, -9999), GeoCoordinate(60, 180, 9999)); + + ASSERT_TRUE(ext.contains(TVec3d(0, 0, 0))); + ASSERT_TRUE(ext.contains(GeoCoordinate(1,1,0))); + ASSERT_FALSE(ext.contains(GeoCoordinate(40, 0, 0))); + ASSERT_FALSE(ext.contains(GeoCoordinate(0, -100, 0))); + + const auto& zoneRefPoint = GeoReference::planeToPolar(TVec3d(), 8);// 10169 は zone id:8 + ASSERT_FLOAT_EQ(36.0, zoneRefPoint.latitude); + ASSERT_FLOAT_EQ(138.5, zoneRefPoint.longitude); + ASSERT_FALSE(ext.containsInPolar(TVec3d(), 10169)); + ASSERT_TRUE(ext2.containsInPolar(TVec3d(), 10169)); + } + + TEST_F(GeoCoordinateTest, CoordinateReference) { // NOLINT + + ASSERT_EQ(8, CoordinateReferenceFactory::GetZoneId(10169)); + ASSERT_FALSE(CoordinateReferenceFactory::IsPolarCoordinateSystem(10169)); + ASSERT_TRUE(CoordinateReferenceFactory::IsPolarCoordinateSystem(6697)); + + const auto& refPoint = CoordinateReferenceFactory::GetReferencePoint(10169); + ASSERT_EQ(36.0, refPoint.latitude); + ASSERT_EQ(138.5, refPoint.longitude); + } +} diff --git a/test/test_geo_reference.cpp b/test/test_geo_reference.cpp index 3b1c81b6..ce00faf4 100644 --- a/test/test_geo_reference.cpp +++ b/test/test_geo_reference.cpp @@ -20,9 +20,9 @@ namespace plateau::geometry { TVec3d base_point = TVec3d(100, 100, 0); }; - TEST_F(GeoReferenceTest, ConvertAxisProject) { // NOLINT + TEST_F(GeoReferenceTest, ConvertAxisPolar) { // NOLINT // 平面直角座標変換・座標軸変換を行う - TVec3d converted = ref.convert(base_point, true, true); + TVec3d converted = ref.convert(base_point, true, 6697); TVec3d projected = ref.project(base_point); // Expected @@ -35,9 +35,9 @@ namespace plateau::geometry { ASSERT_EQ(expected_point, projected); } - TEST_F(GeoReferenceTest, ConvertProjectOnly) { // NOLINT + TEST_F(GeoReferenceTest, ConvertProjectPolar) { // NOLINT // 平面直角座標変換を行う・座標軸変換を行わない - TVec3d converted = ref.convert(base_point, false, true); + TVec3d converted = ref.convert(base_point, false, 6697); TVec3d projected = ref.projectWithoutAxisConvert(base_point); // Expected @@ -49,27 +49,33 @@ namespace plateau::geometry { ASSERT_EQ(expected_point, projected); } - TEST_F(GeoReferenceTest, ConvertAxisOnly) { // NOLINT - // 平面直角座標変換を行わない・座標軸変換を行う - TVec3d point = ref.convert(base_point, true, false); + TEST_F(GeoReferenceTest, ConvertAxisPlane) { // NOLINT + // 平面->緯度経度->平面変換・座標軸変換を行う + TVec3d point = ref.convert(base_point, true, 10169); // Expected - TVec3 expected_point = GeoReference::convertAxisFromENUTo(coordinate, base_point); + TVec3d position = base_point; + const auto& unprj = GeoReference::planeToPolar(position, CoordinateReferenceFactory::GetZoneId(10169)); + position = { unprj.latitude, unprj.longitude, unprj.height }; + PolarToPlaneCartesian().project(position, zone_id); + TVec3 expected_point = GeoReference::convertAxisFromENUTo(coordinate, position); expected_point = expected_point / unit_scale - ref_point; ASSERT_EQ(expected_point, point); } - TEST_F(GeoReferenceTest, ConvertOnly) { // NOLINT - // 平面直角座標変換・座標軸変換を行わない - TVec3d point = ref.convert(base_point, false, false); + TEST_F(GeoReferenceTest, ConvertPlane) { // NOLINT + // 平面->緯度経度->平面変換を行う・座標軸変換を行わない + TVec3d point = ref.convert(base_point, false, 10169); // Expected - TVec3 expected_point = base_point / unit_scale - GeoReference::convertAxisToENU(coordinate, ref_point); + TVec3d position = base_point; + const auto& unprj = GeoReference::planeToPolar(position, CoordinateReferenceFactory::GetZoneId(10169)); + position = { unprj.latitude, unprj.longitude, unprj.height }; + PolarToPlaneCartesian().project(position, zone_id); + TVec3 expected_point = position / unit_scale - GeoReference::convertAxisToENU(coordinate, ref_point); ASSERT_EQ(expected_point, point); } - // fetch のテストは test_dataset.cpp にあります。 - } diff --git a/test/test_gml_file.cpp b/test/test_gml_file.cpp index 1acb51a1..8302176d 100644 --- a/test/test_gml_file.cpp +++ b/test/test_gml_file.cpp @@ -16,11 +16,11 @@ namespace plateau::dataset { TEST_F(GmlFileTest, get_epsg) { // NOLINT auto info1 = GmlFile(std::string("foobar/udx/unf/08EE751_unf_10169_water_op.gml")); ASSERT_EQ(10169, info1.getEpsg()); - ASSERT_FALSE(info1.isPolarCoordinateSystem()); + ASSERT_FALSE(plateau::geometry::CoordinateReferenceFactory::IsPolarCoordinateSystem(info1.getEpsg())); auto info2 = GmlFile(std::string("foobar/udx/bldg/53392546_bldg_6697_2_op.gml")); ASSERT_EQ(6697, info2.getEpsg()); - ASSERT_TRUE(info2.isPolarCoordinateSystem()); + ASSERT_TRUE(plateau::geometry::CoordinateReferenceFactory::IsPolarCoordinateSystem(info2.getEpsg())); } // fetch のテストは test_dataset.cpp にあります。 diff --git a/test/test_mesh_extractor.cpp b/test/test_mesh_extractor.cpp index 81ab9b4b..f8c41e78 100644 --- a/test/test_mesh_extractor.cpp +++ b/test/test_mesh_extractor.cpp @@ -221,11 +221,12 @@ namespace plateau::polygonMesh { mesh_extract_options.coordinate_zone_id = 8; mesh_extract_options.unit_scale = 1.0; mesh_extract_options.mesh_axes = CoordinateSystem::ENU; - mesh_extract_options.is_polar_coordinate_system = false; + mesh_extract_options.epsg_code = 10169; + const std::shared_ptr city_model = load(gml_path, params); const auto& gml = plateau::dataset::GmlFile((city_model->getGmlPath())); - ASSERT_FALSE(gml.isPolarCoordinateSystem()); + ASSERT_FALSE(plateau::geometry::CoordinateReferenceFactory::IsPolarCoordinateSystem(gml.getEpsg())); auto model = MeshExtractor::extract(*city_model, mesh_extract_options); ASSERT_GE(1, model->getRootNodeCount()); @@ -244,11 +245,15 @@ namespace plateau::polygonMesh { const auto& city_model_polygon = root_geometry.getPolygon(0); const auto& city_model_vertices = city_model_polygon->getVertices(); - // 変換されないのでscale:1でENUであればCityModelと座標が同じになる + // scale:1でENUであればCityModelとほぼ同一座標 + // 平面直角座標は、XYZ => YXZの変換が行われる for (int i = 0; i < city_model_vertices.size(); i++) { const auto& city_model_vertex = city_model_vertices[i]; const auto& vertex = vertices[i]; - ASSERT_EQ(vertex, city_model_vertex); + + ASSERT_NEAR(vertex.y, city_model_vertex.x, 0.1); + ASSERT_NEAR(vertex.x, city_model_vertex.y, 0.1); + ASSERT_NEAR(vertex.z, city_model_vertex.z, 0.1); } } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs index 0a5e5b2b..317fed6c 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs @@ -117,8 +117,8 @@ public bool isPolarCoordinateSystem get { ThrowIfDisposed(); - var isPolar = DLLUtil.GetNativeValue(Handle, - NativeMethods.plateau_gml_file_is_polar_coordinate_system); + var result = NativeMethods.plateau_geometry_utils_is_polar_coordinate_system(Epsg, out var isPolar); + DLLUtil.CheckDllError(result); return isPolar; } } @@ -249,9 +249,9 @@ internal static extern APIResult plateau_gml_file_get_epsg( out double outEpsg); [DllImport(DLLUtil.DllName)] - internal static extern APIResult plateau_gml_file_is_polar_coordinate_system( - [In] IntPtr gmlFilePtr, - out bool outBool); + internal static extern APIResult plateau_geometry_utils_is_polar_coordinate_system( + double epsg, + [MarshalAs(UnmanagedType.U1)] out bool outBool); [DllImport(DLLUtil.DllName, CharSet = CharSet.Ansi)] internal static extern APIResult plateau_gml_file_fetch( diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs index 7fc0a119..a45aa590 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs @@ -72,7 +72,7 @@ public static ConvertGranularity ToConvertGranularity(this MeshGranularity g) [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct MeshExtractOptions { - public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshAxes, MeshGranularity meshGranularity, uint minLOD, uint maxLOD, bool exportAppearance, int gridCountOfSide, float unitScale, int coordinateZoneID, bool excludeCityObjectOutsideExtent, bool excludePolygonsOutsideExtent, bool enableTexturePacking, uint texturePackingResolution, bool attachMapTile, int mapTileZoomLevel, string mapTileURL, bool isPolarCoordinateSystem) + public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshAxes, MeshGranularity meshGranularity, uint minLOD, uint maxLOD, bool exportAppearance, int gridCountOfSide, float unitScale, int coordinateZoneID, bool excludeCityObjectOutsideExtent, bool excludePolygonsOutsideExtent, bool enableTexturePacking, uint texturePackingResolution, bool attachMapTile, int mapTileZoomLevel, string mapTileURL, double epsgCode) { this.ReferencePoint = referencePoint; this.MeshAxes = meshAxes; @@ -90,7 +90,7 @@ public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshA this.AttachMapTile = attachMapTile; this.MapTileZoomLevel = mapTileZoomLevel; this.mapTileURL = mapTileURL; - this.IsPolarCoordinateSystem = isPolarCoordinateSystem; + this.epsgCode = epsgCode; // 上で全てのメンバー変数を設定できてますが、バリデーションをするため念のためメソッドやプロパティも呼びます。 SetLODRange(minLOD, maxLOD); @@ -225,11 +225,7 @@ public string MapTileURL } } - /// - /// 極座標系か、平面直角座標系かを指定します。 - /// EPSG:6697 極座標系, EPSG:10162~10174 平面直角座標系 - /// - [MarshalAs(UnmanagedType.U1)] public bool IsPolarCoordinateSystem; + public double epsgCode; /// デフォルト値の設定を返します。 internal static MeshExtractOptions DefaultValue() From f4c45e40bd09d519d820502e2cd286072c7c6bb3 Mon Sep 17 00:00:00 2001 From: sevendev Date: Thu, 17 Apr 2025 18:22:24 +0900 Subject: [PATCH 11/24] C# lib fix --- src/c_wrapper/geo_reference_c.cpp | 4 ++-- .../CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs | 6 ++---- .../LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/c_wrapper/geo_reference_c.cpp b/src/c_wrapper/geo_reference_c.cpp index 1da4c001..3a918a24 100644 --- a/src/c_wrapper/geo_reference_c.cpp +++ b/src/c_wrapper/geo_reference_c.cpp @@ -48,8 +48,8 @@ extern "C" { DLL_VALUE_FUNC(plateau_geo_reference_convert, GeoReference, TVec3d, - handle->convert(point, convert_axis, project), - , TVec3d point, bool convert_axis, bool project) + handle->convert(point, convert_axis, epsg), + , TVec3d point, bool convert_axis, double epsg) DLL_VALUE_FUNC(plateau_geo_reference_get_reference_point, GeoReference, diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs index 78fc8a11..61879715 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Geom/GeoReferenceTests.cs @@ -129,10 +129,8 @@ public void Convert_returns_same_values() new PlateauVector3d(0, 0, 0), 1.0f, CoordinateSystem.EUN, 5 ); var xyz = new PlateauVector3d(1, 2, 3); - Assert.AreEqual(xyz, geoReference.Convert(xyz, false, false)); - Assert.AreEqual(GeoReference.ConvertAxisFromENUTo(CoordinateSystem.EUN, xyz), geoReference.Convert(xyz, true, false)); - Assert.AreEqual(geoReference.Project(xyz), geoReference.Convert(xyz, true, true)); - Assert.AreEqual(geoReference.ProjectWithoutAxisConvert(xyz), geoReference.Convert(xyz, false, true)); + Assert.AreEqual(geoReference.Project(xyz), geoReference.Convert(xyz, true, 6697)); + Assert.AreEqual(geoReference.ProjectWithoutAxisConvert(xyz), geoReference.Convert(xyz, false, 6697)); } } } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs index 8dbff53a..3e1d0b0a 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs @@ -142,11 +142,11 @@ public GeoCoordinate Unproject(PlateauVector3d point) return outLatLon; } - public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, bool project) + public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, double epsg) { var result = NativeMethods.plateau_geo_reference_convert( Handle, out var outXyz, - point, convertAxis, project); + point, convertAxis, epsg); DLLUtil.CheckDllError(result); return outXyz; } @@ -256,7 +256,7 @@ internal static extern APIResult plateau_geo_reference_project_without_axis_conv internal static extern APIResult plateau_geo_reference_convert( [In] IntPtr geoReferencePtr, out PlateauVector3d outXyz, - PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, [MarshalAs(UnmanagedType.U1)] bool project); + PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, double epsg); [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_get_reference_point( From 7dbb827db3a618a4d91520813d85d3494a9fc62c Mon Sep 17 00:00:00 2001 From: sevendev Date: Thu, 17 Apr 2025 18:28:34 +0900 Subject: [PATCH 12/24] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 1 + src/geometry/geo_reference.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 78569ed4..22eadc6b 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -80,6 +80,7 @@ namespace plateau::geometry { /** * 平面直角座標系の判定を含む処理です + * 平面直角座標の場合はunprojectして緯度経度に変換してから判定します。 */ bool containsInPolar(TVec3d point,const double epsg, bool ignore_height = true) const; bool containsInPolar(const citygml::CityObject& city_obj,const double epsg, bool ignore_height = true) const; diff --git a/src/geometry/geo_reference.cpp b/src/geometry/geo_reference.cpp index b4811962..4eda6f0f 100644 --- a/src/geometry/geo_reference.cpp +++ b/src/geometry/geo_reference.cpp @@ -107,7 +107,6 @@ namespace plateau::geometry { point = reverseXY(point); plateau::geometry::GeoReference geo_ref(coordinate_zone_id); const auto unprojected = geo_ref.unproject(point); - //point = { unprojected.latitude, unprojected.longitude, unprojected.height }; return unprojected; } From 476974fdcbe2f115c37f82dc326fcce5b0035a0e Mon Sep 17 00:00:00 2001 From: sevendev Date: Fri, 18 Apr 2025 09:21:59 +0900 Subject: [PATCH 13/24] conflict fix --- src/c_wrapper/gml_file_c.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/c_wrapper/gml_file_c.cpp b/src/c_wrapper/gml_file_c.cpp index e2eac32c..ad964847 100644 --- a/src/c_wrapper/gml_file_c.cpp +++ b/src/c_wrapper/gml_file_c.cpp @@ -43,11 +43,6 @@ extern "C" { GmlFile, handle->getFeatureType()) - DLL_VALUE_FUNC(plateau_gml_file_get_mesh_code, - GmlFile, - MeshCode, - handle->getMeshCode()) - DLL_PTR_FUNC(plateau_gml_file_get_grid_code, GmlFile, GridCode, From 34c65bad306ddba5278912e5857010a4dd81c285 Mon Sep 17 00:00:00 2001 From: sevendev Date: Fri, 18 Apr 2025 14:36:34 +0900 Subject: [PATCH 14/24] test update --- test/test_geo_coordinate.cpp | 5 +++++ test/test_geo_reference.cpp | 15 +++++++++++++++ test/test_mesh_extractor.cpp | 25 +++++++++++++++---------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/test/test_geo_coordinate.cpp b/test/test_geo_coordinate.cpp index 2d617a8f..299d3f53 100644 --- a/test/test_geo_coordinate.cpp +++ b/test/test_geo_coordinate.cpp @@ -20,6 +20,11 @@ namespace plateau::geometry { ASSERT_FALSE(ext.contains(GeoCoordinate(40, 0, 0))); ASSERT_FALSE(ext.contains(GeoCoordinate(0, -100, 0))); + // 6697の場合は同様の処理 + ASSERT_EQ(ext.contains(TVec3d(0, 0, 0)), ext.containsInPolar(TVec3d(0, 0, 0), 6697)); + ASSERT_EQ(ext.contains(TVec3d(80, 90, 0)), ext.containsInPolar(TVec3d(80, 90, 0), 6697)); + + // 平面直角座標 const auto& zoneRefPoint = GeoReference::planeToPolar(TVec3d(), 8);// 10169 は zone id:8 ASSERT_FLOAT_EQ(36.0, zoneRefPoint.latitude); ASSERT_FLOAT_EQ(138.5, zoneRefPoint.longitude); diff --git a/test/test_geo_reference.cpp b/test/test_geo_reference.cpp index ce00faf4..27e80285 100644 --- a/test/test_geo_reference.cpp +++ b/test/test_geo_reference.cpp @@ -78,4 +78,19 @@ namespace plateau::geometry { ASSERT_EQ(expected_point, point); } + // 平面直角座標のGMLの値を緯度経度に変換 + TEST_F(GeoReferenceTest, PlaneToPolarConversion) { // NOLINT + TVec3d base_position(100, -100, 1); // 経度、緯度、高さ + + const auto& polar = GeoReference::planeToPolar(base_position, 9); + TVec3d polar_vector = { polar.latitude, polar.longitude, polar.height }; + + // xy反転してunprojectした値 + TVec3d position = { base_position.y, base_position.x, base_position.z }; // xy反転 + PolarToPlaneCartesian().unproject(position, 9); + const auto& expected_point = position; + + ASSERT_EQ(expected_point, polar_vector); + } + } diff --git a/test/test_mesh_extractor.cpp b/test/test_mesh_extractor.cpp index b3a9a587..5ed63519 100644 --- a/test/test_mesh_extractor.cpp +++ b/test/test_mesh_extractor.cpp @@ -204,29 +204,34 @@ namespace plateau::polygonMesh { } } - // Epsgが6697以外(10162~10174)の場合、平面直角座標変換を行わない + // Epsgが6697以外(10162~10174)の場合、GMLの位置情報が平面直角座標 TEST_F(MeshExtractorTest, no_coordinate_transformation_during_conversion) { // NOLINT const std::string gml_path = u8"../data/日本語パステスト/udx/unf/08EE763_unf_10169_sewer_op.gml"; ParserParams params; params.tesselate = true; - MeshExtractOptions mesh_extract_options = MeshExtractOptions(); + + const std::shared_ptr city_model = load(gml_path, params); + const auto& gml = plateau::dataset::GmlFile((city_model->getGmlPath())); + const auto& epsg = gml.getEpsg(); + const auto& zone = CoordinateReferenceFactory::GetZoneId(epsg); + ASSERT_EQ(10169, epsg); + ASSERT_FALSE(plateau::geometry::CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg)); + ASSERT_EQ(8, zone); + + MeshExtractOptions mesh_extract_options = MeshExtractOptions(); mesh_extract_options.min_lod = 0; mesh_extract_options.max_lod = 2; mesh_extract_options.mesh_granularity = MeshGranularity::PerPrimaryFeatureObject; mesh_extract_options.grid_count_of_side = 5; mesh_extract_options.exclude_city_object_outside_extent = true; mesh_extract_options.exclude_polygons_outside_extent = false; - mesh_extract_options.coordinate_zone_id = 8; - mesh_extract_options.unit_scale = 1.0; + mesh_extract_options.coordinate_zone_id = zone; + mesh_extract_options.unit_scale = 1.0; mesh_extract_options.mesh_axes = CoordinateSystem::ENU; - mesh_extract_options.epsg_code = 10169; - - const std::shared_ptr city_model = load(gml_path, params); - - const auto& gml = plateau::dataset::GmlFile((city_model->getGmlPath())); - ASSERT_FALSE(plateau::geometry::CoordinateReferenceFactory::IsPolarCoordinateSystem(gml.getEpsg())); + mesh_extract_options.epsg_code = epsg; + // Extracted Model auto model = MeshExtractor::extract(*city_model, mesh_extract_options); ASSERT_GE(1, model->getRootNodeCount()); const auto& lod_node = model->getRootNodeAt(0); From 46601fd6a7c24e06ca0b141b32137253eb1c3804 Mon Sep 17 00:00:00 2001 From: sevendev Date: Mon, 21 Apr 2025 11:32:01 +0900 Subject: [PATCH 15/24] =?UTF-8?q?epsg=20double=20=3D>=20int=20=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 13 ++++--- include/plateau/geometry/geo_reference.h | 2 +- .../polygon_mesh/mesh_extract_options.h | 4 +-- src/c_wrapper/geo_reference_c.cpp | 2 +- src/c_wrapper/geometry_utils_c.cpp | 2 +- src/c_wrapper/gml_file_c.cpp | 2 +- src/geometry/geo_coordinate.cpp | 4 +-- src/geometry/geo_reference.cpp | 2 +- src/polygon_mesh/mesh_factory.cpp | 2 +- .../CSharpPLATEAU.Test/Dataset/GmlFileTest.cs | 5 +-- .../CSharpPLATEAU/Dataset/GmlFile.cs | 27 ++------------- .../Geometries/CoordinateReferenceFactory.cs | 34 +++++++++++++++++++ .../CSharpPLATEAU/Geometries/GeoReference.cs | 4 +-- .../PolygonMesh/MeshExtractOptions.cs | 4 +-- 14 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 22eadc6b..8d350e7c 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -82,8 +82,8 @@ namespace plateau::geometry { * 平面直角座標系の判定を含む処理です * 平面直角座標の場合はunprojectして緯度経度に変換してから判定します。 */ - bool containsInPolar(TVec3d point,const double epsg, bool ignore_height = true) const; - bool containsInPolar(const citygml::CityObject& city_obj,const double epsg, bool ignore_height = true) const; + bool containsInPolar(TVec3d point,const int epsg, bool ignore_height = true) const; + bool containsInPolar(const citygml::CityObject& city_obj,const int epsg, bool ignore_height = true) const; /** * other と交わる箇所があるかどうかを返します。 @@ -111,8 +111,11 @@ namespace plateau::geometry { * 平面直角座標判定、平面直角座標の基準点取得 */ struct CoordinateReferenceFactory { + + static constexpr int default_epsg_ = 6697; + // EPSGごとのzone取得 - static int GetZoneId(double epsg) { + static int GetZoneId(int epsg) { // 日本測地系2011(JGD2011)に基づく平面直角座標系 if (epsg == 10162) { return 1; // 1系 @@ -157,7 +160,7 @@ namespace plateau::geometry { } // EPSGごとの基準点取得 - static GeoCoordinate GetReferencePoint(double epsg) { + static GeoCoordinate GetReferencePoint(int epsg) { const int zone = GetZoneId(epsg); if (zone != 0) return GetReferencePointByZone(zone); @@ -212,7 +215,7 @@ namespace plateau::geometry { } // 極座標系・平面直角座標系判定 - static bool IsPolarCoordinateSystem(double epsg) { + static bool IsPolarCoordinateSystem(int epsg) { // 平面直角座標系の区分についてはこちらを参照してください : // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ if (epsg >= 10162 && epsg <= 10174) { diff --git a/include/plateau/geometry/geo_reference.h b/include/plateau/geometry/geo_reference.h index 7286aa10..551178f1 100644 --- a/include/plateau/geometry/geo_reference.h +++ b/include/plateau/geometry/geo_reference.h @@ -26,7 +26,7 @@ namespace plateau::geometry { /// project の座標軸変換をしない版です。座標軸は ENU → ENU であるとします。 reference_point_ は ENUに変換されます。 TVec3d projectWithoutAxisConvert(const TVec3d& lat_lon) const; TVec3d convertAxisToENU(const TVec3d& vertex) const; - TVec3d convert(const TVec3d& lat_lon, const bool convert_axis = true, const double epsg = 6697) const; + TVec3d convert(const TVec3d& lat_lon, const bool convert_axis = true, const int epsg = CoordinateReferenceFactory::default_epsg_) const; static TVec3d convertAxisFromENUTo(CoordinateSystem axis, const TVec3d& vertex); static TVec3d convertAxisToENU(CoordinateSystem axis, const TVec3d& vertex); diff --git a/include/plateau/polygon_mesh/mesh_extract_options.h b/include/plateau/polygon_mesh/mesh_extract_options.h index 6390bf2d..9a63e966 100644 --- a/include/plateau/polygon_mesh/mesh_extract_options.h +++ b/include/plateau/polygon_mesh/mesh_extract_options.h @@ -38,7 +38,7 @@ namespace plateau::polygonMesh { attach_map_tile(true), map_tile_zoom_level(15), map_tile_url("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg"), - epsg_code(6697) + epsg_code(plateau::geometry::CoordinateReferenceFactory::default_epsg_) {} public: @@ -116,6 +116,6 @@ namespace plateau::polygonMesh { /** * 平面直角座標系は、EPSGコードに応じて基準点を取得します。 */ - double epsg_code; + int epsg_code; }; } diff --git a/src/c_wrapper/geo_reference_c.cpp b/src/c_wrapper/geo_reference_c.cpp index 3a918a24..8a0d8033 100644 --- a/src/c_wrapper/geo_reference_c.cpp +++ b/src/c_wrapper/geo_reference_c.cpp @@ -49,7 +49,7 @@ extern "C" { GeoReference, TVec3d, handle->convert(point, convert_axis, epsg), - , TVec3d point, bool convert_axis, double epsg) + , TVec3d point, bool convert_axis, int epsg) DLL_VALUE_FUNC(plateau_geo_reference_get_reference_point, GeoReference, diff --git a/src/c_wrapper/geometry_utils_c.cpp b/src/c_wrapper/geometry_utils_c.cpp index fea1f6ec..17268706 100644 --- a/src/c_wrapper/geometry_utils_c.cpp +++ b/src/c_wrapper/geometry_utils_c.cpp @@ -15,7 +15,7 @@ DLL_VALUE_FUNC(plateau_geometry_utils_get_center_point, ,int coordinate_zone_id) LIBPLATEAU_C_EXPORT APIResult LIBPLATEAU_C_API plateau_geometry_utils_is_polar_coordinate_system( - double epsg, + int epsg, bool* out ) { API_TRY{ diff --git a/src/c_wrapper/gml_file_c.cpp b/src/c_wrapper/gml_file_c.cpp index ad964847..c5daaddb 100644 --- a/src/c_wrapper/gml_file_c.cpp +++ b/src/c_wrapper/gml_file_c.cpp @@ -50,7 +50,7 @@ extern "C" { DLL_VALUE_FUNC(plateau_gml_file_get_epsg, GmlFile, - double, + int, handle->getEpsg()) LIBPLATEAU_C_EXPORT APIResult LIBPLATEAU_C_API plateau_gml_file_fetch( diff --git a/src/geometry/geo_coordinate.cpp b/src/geometry/geo_coordinate.cpp index 52178e11..c8f5ab6c 100644 --- a/src/geometry/geo_coordinate.cpp +++ b/src/geometry/geo_coordinate.cpp @@ -64,7 +64,7 @@ namespace plateau::geometry { } } - bool Extent::containsInPolar(TVec3d point, const double epsg, bool ignore_height) const { + bool Extent::containsInPolar(TVec3d point, const int epsg, bool ignore_height) const { if (!CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg)) { // 平面直角座標系の判定 @@ -74,7 +74,7 @@ namespace plateau::geometry { return contains(GeoCoordinate(point.x, point.y, point.z), ignore_height); } - bool Extent::containsInPolar(const CityObject& city_obj, const double epsg, bool ignore_height) const { + bool Extent::containsInPolar(const CityObject& city_obj, const int epsg, bool ignore_height) const { if (!CoordinateReferenceFactory::IsPolarCoordinateSystem(epsg)) { // 平面直角座標系の判定 diff --git a/src/geometry/geo_reference.cpp b/src/geometry/geo_reference.cpp index 46e5ea54..8c04eba3 100644 --- a/src/geometry/geo_reference.cpp +++ b/src/geometry/geo_reference.cpp @@ -25,7 +25,7 @@ namespace plateau::geometry { } //平面直角座標判定を含むproject, projectWithoutAxisConvert処理と同様の処理 - TVec3d GeoReference::convert(const TVec3d& lat_lon, const bool convert_axis, const double epsg) const { + TVec3d GeoReference::convert(const TVec3d& lat_lon, const bool convert_axis, const int epsg) const { //平面直角座標変換、座標軸変換をフラグに応じてスキップします。 TVec3d point = lat_lon; diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index a507ee5f..7c39fd1a 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -32,7 +32,7 @@ namespace plateau::polygonMesh { */ void cityGmlPolygonToMesh( const Polygon& polygon, const std::string& gml_path, - const GeoReference& geo_reference, Mesh& out_mesh, double epsg) { + const GeoReference& geo_reference, Mesh& out_mesh, int epsg) { // マージ対象の情報を取得します。ここでの頂点は極座標です。 const auto& vertices_lat_lon = polygon.getVertices(); diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs index 17121948..9ed055cc 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/Dataset/GmlFileTest.cs @@ -2,6 +2,7 @@ using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; using PLATEAU.Dataset; +using PLATEAU.Geometries; using PLATEAU.Network; namespace PLATEAU.Test.Dataset @@ -42,7 +43,7 @@ public void TestEpsgCode() string path = "data/udx/bldg/53392642_bldg_6697_op2.gml"; var info = GmlFile.Create(path); Assert.AreEqual(6697, info.Epsg); - Assert.IsTrue(info.isPolarCoordinateSystem); + Assert.IsTrue(CoordinateReferenceFactory.IsPolarCoordinateSystem(info.Epsg)); info.Dispose(); } @@ -53,7 +54,7 @@ public void TestEpsgCodePlane() string path = "data/udx/unf/08EE763_unf_10169_sewer_op.gml"; var info = GmlFile.Create(path); Assert.AreEqual(10169, info.Epsg); - Assert.IsFalse(info.isPolarCoordinateSystem); + Assert.IsFalse(CoordinateReferenceFactory.IsPolarCoordinateSystem(info.Epsg)); info.Dispose(); } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs index 02c409e8..672e62f9 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs @@ -100,33 +100,17 @@ public GridCode GridCode /// GMLファイルのEPSGコードを返します。 /// 取得失敗時のデフォルト値はEPSG:6697です。 /// - public double Epsg + public int Epsg { get { ThrowIfDisposed(); - var epsg = DLLUtil.GetNativeValue(Handle, + var epsg = DLLUtil.GetNativeValue(Handle, NativeMethods.plateau_gml_file_get_epsg); return epsg; } } - /// - /// 平面直角座標系への変換が必要なGMLファイルかどうかを返します。 - /// 取得失敗時のデフォルト値はtrueです。 - /// - public bool isPolarCoordinateSystem - { - get - { - ThrowIfDisposed(); - var result = NativeMethods.plateau_geometry_utils_is_polar_coordinate_system(Epsg, out var isPolar); - DLLUtil.CheckDllError(result); - return isPolar; - } - } - - public string[] SearchAllCodelistPathsInGml() { var nativePaths = NativeVectorString.Create(); @@ -249,12 +233,7 @@ internal static extern APIResult plateau_gml_file_get_grid_code( [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_gml_file_get_epsg( [In] IntPtr gmlFilePtr, - out double outEpsg); - - [DllImport(DLLUtil.DllName)] - internal static extern APIResult plateau_geometry_utils_is_polar_coordinate_system( - double epsg, - [MarshalAs(UnmanagedType.U1)] out bool outBool); + out int outEpsg); [DllImport(DLLUtil.DllName, CharSet = CharSet.Ansi)] internal static extern APIResult plateau_gml_file_fetch( diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs new file mode 100644 index 00000000..52d9efb8 --- /dev/null +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs @@ -0,0 +1,34 @@ +using System; +using System.Runtime.InteropServices; +using PLATEAU.Dataset; +using PLATEAU.Interop; +using PLATEAU.Native; + +namespace PLATEAU.Geometries +{ + public static class CoordinateReferenceFactory + { + + public static readonly int DEFAULT_EPSG = 6697; + + /// + /// 平面直角座標系への変換が必要なGMLファイルかどうかを返します。 + /// 取得失敗時のデフォルト値はtrueです。 + /// + public static bool IsPolarCoordinateSystem(int Epsg) + { + var result = NativeMethods.plateau_geometry_utils_is_polar_coordinate_system(Epsg, out var isPolar); + DLLUtil.CheckDllError(result); + return isPolar; + } + + internal static class NativeMethods + { + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_geometry_utils_is_polar_coordinate_system( + int epsg, + [MarshalAs(UnmanagedType.U1)] out bool outBool); + } + } +} + diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs index 3e1d0b0a..a078aac4 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs @@ -142,7 +142,7 @@ public GeoCoordinate Unproject(PlateauVector3d point) return outLatLon; } - public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, double epsg) + public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, int epsg) { var result = NativeMethods.plateau_geo_reference_convert( Handle, out var outXyz, @@ -256,7 +256,7 @@ internal static extern APIResult plateau_geo_reference_project_without_axis_conv internal static extern APIResult plateau_geo_reference_convert( [In] IntPtr geoReferencePtr, out PlateauVector3d outXyz, - PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, double epsg); + PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, int epsg); [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_get_reference_point( diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs index a45aa590..27698523 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs @@ -72,7 +72,7 @@ public static ConvertGranularity ToConvertGranularity(this MeshGranularity g) [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct MeshExtractOptions { - public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshAxes, MeshGranularity meshGranularity, uint minLOD, uint maxLOD, bool exportAppearance, int gridCountOfSide, float unitScale, int coordinateZoneID, bool excludeCityObjectOutsideExtent, bool excludePolygonsOutsideExtent, bool enableTexturePacking, uint texturePackingResolution, bool attachMapTile, int mapTileZoomLevel, string mapTileURL, double epsgCode) + public MeshExtractOptions(PlateauVector3d referencePoint, CoordinateSystem meshAxes, MeshGranularity meshGranularity, uint minLOD, uint maxLOD, bool exportAppearance, int gridCountOfSide, float unitScale, int coordinateZoneID, bool excludeCityObjectOutsideExtent, bool excludePolygonsOutsideExtent, bool enableTexturePacking, uint texturePackingResolution, bool attachMapTile, int mapTileZoomLevel, string mapTileURL, int epsgCode) { this.ReferencePoint = referencePoint; this.MeshAxes = meshAxes; @@ -225,7 +225,7 @@ public string MapTileURL } } - public double epsgCode; + public int epsgCode; /// デフォルト値の設定を返します。 internal static MeshExtractOptions DefaultValue() From b40aa40634e2eb6d03471beab260123eb3f2e74e Mon Sep 17 00:00:00 2001 From: sevendev Date: Mon, 21 Apr 2025 14:40:51 +0900 Subject: [PATCH 16/24] refactoring --- include/plateau/geometry/geo_coordinate.h | 114 +++++------------- include/plateau/geometry/geo_reference.h | 2 +- .../polygon_mesh/mesh_extract_options.h | 2 +- src/dataset/gml_file.cpp | 6 +- 4 files changed, 36 insertions(+), 88 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 8d350e7c..5deed4d2 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -112,51 +112,18 @@ namespace plateau::geometry { */ struct CoordinateReferenceFactory { - static constexpr int default_epsg_ = 6697; + static constexpr int default_epsg = 6697; // EPSGごとのzone取得 static int GetZoneId(int epsg) { // 日本測地系2011(JGD2011)に基づく平面直角座標系 - if (epsg == 10162) { - return 1; // 1系 - } - else if (epsg == 10163) { - return 2; // 2系 - } - else if (epsg == 10164) { - return 3; // 3系 - } - else if (epsg == 10165) { - return 4; // 4系 - } - else if (epsg == 10166) { - return 5; // 5系 - } - else if (epsg == 10167) { - return 6; // 6系 - } - else if (epsg == 10168) { - return 7; // 7系 - } - else if (epsg == 10169) { - return 8; // 8系 - } - else if (epsg == 10170) { - return 9; // 9系 - } - else if (epsg == 10171) { - return 10; // 10系 - } - else if (epsg == 10172) { - return 11; // 11系 - } - else if (epsg == 10173) { - return 12; // 12系 - } - else if (epsg == 10174) { - return 13; // 13系 - } - return 0; + static const std::map epsg_to_zone = { + {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, + {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, + {10172, 11}, {10173, 12}, {10174, 13} + }; + auto it = epsg_to_zone.find(epsg); + return it != epsg_to_zone.end() ? it->second : 0; } // EPSGごとの基準点取得 @@ -170,48 +137,29 @@ namespace plateau::geometry { // Zone IDごとの基準点 // zoneに紐づく基準点はPolarToPlaneCartesianにハードコードで持っているが値が取得できないので、ここで定義 static GeoCoordinate GetReferencePointByZone(int zone_id) { - switch (zone_id) { - case 1: - return GeoCoordinate(33, 129.5, 0); - case 2: - return GeoCoordinate(33, 131, 0); - case 3: - return GeoCoordinate(36, 132.166667, 0); - case 4: - return GeoCoordinate(33, 133.5, 0); - case 5: - return GeoCoordinate(36, 134.333333, 0); - case 6: - return GeoCoordinate(36, 136, 0); - case 7: - return GeoCoordinate(36, 137.166667, 0); - case 8: - return GeoCoordinate(36, 138.5, 0); - case 9: - return GeoCoordinate(35, 139.833333, 0); - case 10: - return GeoCoordinate(40, 140.833333, 0); - case 11: - return GeoCoordinate(44, 140.25, 0); - case 12: - return GeoCoordinate(44, 142, 0); - case 13: - return GeoCoordinate(43, 144, 0); - case 14: - return GeoCoordinate(26, 142, 0); - case 15: - return GeoCoordinate(26, 127.5, 0); - case 16: - return GeoCoordinate(24, 124, 0); - case 17: - return GeoCoordinate(31, 131, 0); - case 18: - return GeoCoordinate(20, 136, 0); - case 19: - return GeoCoordinate(25, 154, 0); - default: - return GeoCoordinate(); - } + static const std::map zone_to_point = { + {1, GeoCoordinate(33, 129.5, 0)}, + {2, GeoCoordinate(33, 131, 0)}, + {3, GeoCoordinate(36, 132.166667, 0)}, + {4, GeoCoordinate(33, 133.5, 0)}, + {5, GeoCoordinate(36, 134.333333, 0)}, + {6, GeoCoordinate(36, 136, 0)}, + {7, GeoCoordinate(36, 137.166667, 0)}, + {8, GeoCoordinate(36, 138.5, 0)}, + {9, GeoCoordinate(35, 139.833333, 0)}, + {10, GeoCoordinate(40, 140.833333, 0)}, + {11, GeoCoordinate(44, 140.25, 0)}, + {12, GeoCoordinate(44, 142, 0)}, + {13, GeoCoordinate(43, 144, 0)}, + {14, GeoCoordinate(26, 142, 0)}, + {15, GeoCoordinate(26, 127.5, 0)}, + {16, GeoCoordinate(24, 124, 0)}, + {17, GeoCoordinate(31, 131, 0)}, + {18, GeoCoordinate(20, 136, 0)}, + {19, GeoCoordinate(25, 154, 0)} + }; + auto it = zone_to_point.find(zone_id); + return it != zone_to_point.end() ? it->second : GeoCoordinate(); } // 極座標系・平面直角座標系判定 diff --git a/include/plateau/geometry/geo_reference.h b/include/plateau/geometry/geo_reference.h index 551178f1..a527c8ab 100644 --- a/include/plateau/geometry/geo_reference.h +++ b/include/plateau/geometry/geo_reference.h @@ -26,7 +26,7 @@ namespace plateau::geometry { /// project の座標軸変換をしない版です。座標軸は ENU → ENU であるとします。 reference_point_ は ENUに変換されます。 TVec3d projectWithoutAxisConvert(const TVec3d& lat_lon) const; TVec3d convertAxisToENU(const TVec3d& vertex) const; - TVec3d convert(const TVec3d& lat_lon, const bool convert_axis = true, const int epsg = CoordinateReferenceFactory::default_epsg_) const; + TVec3d convert(const TVec3d& lat_lon, const bool convert_axis = true, const int epsg = CoordinateReferenceFactory::default_epsg) const; static TVec3d convertAxisFromENUTo(CoordinateSystem axis, const TVec3d& vertex); static TVec3d convertAxisToENU(CoordinateSystem axis, const TVec3d& vertex); diff --git a/include/plateau/polygon_mesh/mesh_extract_options.h b/include/plateau/polygon_mesh/mesh_extract_options.h index 9a63e966..2fb8e923 100644 --- a/include/plateau/polygon_mesh/mesh_extract_options.h +++ b/include/plateau/polygon_mesh/mesh_extract_options.h @@ -38,7 +38,7 @@ namespace plateau::polygonMesh { attach_map_tile(true), map_tile_zoom_level(15), map_tile_url("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg"), - epsg_code(plateau::geometry::CoordinateReferenceFactory::default_epsg_) + epsg_code(plateau::geometry::CoordinateReferenceFactory::default_epsg) {} public: diff --git a/src/dataset/gml_file.cpp b/src/dataset/gml_file.cpp index cef6aea0..b4a81176 100644 --- a/src/dataset/gml_file.cpp +++ b/src/dataset/gml_file.cpp @@ -54,12 +54,12 @@ namespace plateau::dataset { return GridCode::createRaw(grid_code_->get()); } - double GmlFile::getEpsg() const { + double GmlFile::getEpsg() const { try { - return epsg_.empty() ? 6697 : std::stod(epsg_); + return epsg_.empty() ? plateau::geometry::CoordinateReferenceFactory::default_epsg : std::stod(epsg_); } catch (const std::exception&) { - return 6697; + return plateau::geometry::CoordinateReferenceFactory::default_epsg; } } From 545f1f5e6a08b6d46435662dc902da1cbd760435 Mon Sep 17 00:00:00 2001 From: sevendev Date: Mon, 21 Apr 2025 17:24:08 +0900 Subject: [PATCH 17/24] =?UTF-8?q?AI=20=E3=81=AE=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 91 +++++++++---------- src/polygon_mesh/mesh_factory.cpp | 2 +- test/test_mesh_extractor.cpp | 4 +- .../Geometries/CoordinateReferenceFactory.cs | 2 +- .../CSharpPLATEAU/Geometries/GeoReference.cs | 2 +- 5 files changed, 46 insertions(+), 55 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 5deed4d2..2016049a 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -2,7 +2,8 @@ #include "citygml/vecs.hpp" #include "citygml/cityobject.h" - +#include +#include namespace plateau::geometry { @@ -107,69 +108,59 @@ namespace plateau::geometry { } }; - /** - * 平面直角座標判定、平面直角座標の基準点取得 - */ + /** + * 平面直角座標系の判定、平面直角座標の基準点取得 + */ struct CoordinateReferenceFactory { - static constexpr int default_epsg = 6697; + // EPSGとZone IDのマッピング + static constexpr std::array, 13> epsg_to_zone = { { + {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, + {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, + {10172, 11}, {10173, 12}, {10174, 13} + } }; + + // Zone IDごとの座標データ + static constexpr std::array>, 13> zone_to_point = { { + {1, {33.0, 129.5, 0.0}}, {2, {33.0, 131.0, 0.0}}, {3, {36.0, 132.166667, 0.0}}, + {4, {33.0, 133.5, 0.0}}, {5, {36.0, 134.333333, 0.0}}, {6, {36.0, 136.0, 0.0}}, + {7, {36.0, 137.166667, 0.0}}, {8, {36.0, 138.5, 0.0}}, {9, {35.0, 139.833333, 0.0}}, + {10, {40.0, 140.833333, 0.0}}, {11, {44.0, 140.25, 0.0}}, {12, {44.0, 142.0, 0.0}}, + {13, {43.0, 144.0, 0.0}} + } }; + // EPSGごとのzone取得 - static int GetZoneId(int epsg) { - // 日本測地系2011(JGD2011)に基づく平面直角座標系 - static const std::map epsg_to_zone = { - {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, - {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, - {10172, 11}, {10173, 12}, {10174, 13} - }; - auto it = epsg_to_zone.find(epsg); - return it != epsg_to_zone.end() ? it->second : 0; + static constexpr int GetZoneId(int epsg) { + for (const auto& pair : epsg_to_zone) { + if (pair.first == epsg) { + return pair.second; + } + } + return 0; } // EPSGごとの基準点取得 static GeoCoordinate GetReferencePoint(int epsg) { const int zone = GetZoneId(epsg); - if (zone != 0) - return GetReferencePointByZone(zone); + if (zone != 0) { + for (const auto& pair : zone_to_point) { + if (pair.first == zone) { + const auto& coords = pair.second; + return GeoCoordinate(coords[0], coords[1], coords[2]); + } + } + } return GeoCoordinate(); } - // Zone IDごとの基準点 - // zoneに紐づく基準点はPolarToPlaneCartesianにハードコードで持っているが値が取得できないので、ここで定義 - static GeoCoordinate GetReferencePointByZone(int zone_id) { - static const std::map zone_to_point = { - {1, GeoCoordinate(33, 129.5, 0)}, - {2, GeoCoordinate(33, 131, 0)}, - {3, GeoCoordinate(36, 132.166667, 0)}, - {4, GeoCoordinate(33, 133.5, 0)}, - {5, GeoCoordinate(36, 134.333333, 0)}, - {6, GeoCoordinate(36, 136, 0)}, - {7, GeoCoordinate(36, 137.166667, 0)}, - {8, GeoCoordinate(36, 138.5, 0)}, - {9, GeoCoordinate(35, 139.833333, 0)}, - {10, GeoCoordinate(40, 140.833333, 0)}, - {11, GeoCoordinate(44, 140.25, 0)}, - {12, GeoCoordinate(44, 142, 0)}, - {13, GeoCoordinate(43, 144, 0)}, - {14, GeoCoordinate(26, 142, 0)}, - {15, GeoCoordinate(26, 127.5, 0)}, - {16, GeoCoordinate(24, 124, 0)}, - {17, GeoCoordinate(31, 131, 0)}, - {18, GeoCoordinate(20, 136, 0)}, - {19, GeoCoordinate(25, 154, 0)} - }; - auto it = zone_to_point.find(zone_id); - return it != zone_to_point.end() ? it->second : GeoCoordinate(); - } - // 極座標系・平面直角座標系判定 + // 平面直角座標系の区分についてはこちらを参照してください : + // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ + // “該当範囲でなければ極座標” と単純化していますが、 + // EPSG 4301(JGD2000) 等の別 CRS を誤って極座標と判定する恐れがあります。 static bool IsPolarCoordinateSystem(int epsg) { - // 平面直角座標系の区分についてはこちらを参照してください : - // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ - if (epsg >= 10162 && epsg <= 10174) { - return false; - } - return true; + return !(epsg >= 10162 && epsg <= 10174); } }; } diff --git a/src/polygon_mesh/mesh_factory.cpp b/src/polygon_mesh/mesh_factory.cpp index 7c39fd1a..f72db6f3 100644 --- a/src/polygon_mesh/mesh_factory.cpp +++ b/src/polygon_mesh/mesh_factory.cpp @@ -128,7 +128,7 @@ namespace plateau::polygonMesh { void findAllPolygonsInGeometry( const Geometry& geom, std::list& polygons, const unsigned lod, long long& out_vertices_count, - const std::vector extents, const MeshExtractOptions& options) { + const std::vector& extents, const MeshExtractOptions& options) { // 子のジオメトリのポリゴンをすべて取得 const unsigned int child_count = geom.getGeometriesCount(); diff --git a/test/test_mesh_extractor.cpp b/test/test_mesh_extractor.cpp index 5ed63519..a9ea3905 100644 --- a/test/test_mesh_extractor.cpp +++ b/test/test_mesh_extractor.cpp @@ -233,9 +233,9 @@ namespace plateau::polygonMesh { // Extracted Model auto model = MeshExtractor::extract(*city_model, mesh_extract_options); - ASSERT_GE(1, model->getRootNodeCount()); + ASSERT_GE(model->getRootNodeCount(),1); const auto& lod_node = model->getRootNodeAt(0); - ASSERT_GE(1, lod_node.getChildCount()); + ASSERT_GE(lod_node.getChildCount(),1); const auto& first_model_node = lod_node.getChildAt(0); const auto& mesh = first_model_node.getMesh(); diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs index 52d9efb8..3d2aec12 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/CoordinateReferenceFactory.cs @@ -9,7 +9,7 @@ namespace PLATEAU.Geometries public static class CoordinateReferenceFactory { - public static readonly int DEFAULT_EPSG = 6697; + public const int DEFAULT_EPSG = 6697; /// /// 平面直角座標系への変換が必要なGMLファイルかどうかを返します。 diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs index a078aac4..2f34ebec 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs @@ -142,7 +142,7 @@ public GeoCoordinate Unproject(PlateauVector3d point) return outLatLon; } - public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, int epsg) + public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, int epsg = CoordinateReferenceFactory.DEFAULT_EPSG) { var result = NativeMethods.plateau_geo_reference_convert( Handle, out var outXyz, From dbc4a6cacb314555921f86b2064a4741850594b0 Mon Sep 17 00:00:00 2001 From: sevendev Date: Tue, 22 Apr 2025 15:13:11 +0900 Subject: [PATCH 18/24] =?UTF-8?q?cs=20=E3=81=AB=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CSharpPLATEAU/Geometries/GeoReference.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs index 2f34ebec..d90bd280 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Geometries/GeoReference.cs @@ -142,6 +142,13 @@ public GeoCoordinate Unproject(PlateauVector3d point) return outLatLon; } + /// + /// 指定されたEPSGコードを使用して座標変換を行います。 + /// + /// 変換する座標点 + /// 軸変換を行うかどうか + /// 使用するEPSGコード。デフォルトは6697(日本測地系2011) + /// 変換された座標点 public PlateauVector3d Convert(PlateauVector3d point, bool convertAxis, int epsg = CoordinateReferenceFactory.DEFAULT_EPSG) { var result = NativeMethods.plateau_geo_reference_convert( @@ -248,15 +255,15 @@ internal static extern APIResult plateau_geo_reference_project_point( [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_project_without_axis_convert( - [In] IntPtr geoReferencePtr, - out PlateauVector3d outXyz, - PlateauVector3d point); + [In] IntPtr geoReferencePtr, + out PlateauVector3d outXyz, + PlateauVector3d point); [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_convert( - [In] IntPtr geoReferencePtr, - out PlateauVector3d outXyz, - PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, int epsg); + [In] IntPtr geoReferencePtr, + out PlateauVector3d outXyz, + PlateauVector3d point, [MarshalAs(UnmanagedType.U1)] bool convertAxis, int epsg); [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_geo_reference_get_reference_point( From 8df652082c70ceb94b53f1a2134da3c536be63a2 Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 23 Apr 2025 15:08:59 +0900 Subject: [PATCH 19/24] =?UTF-8?q?std::array=20->=20std::set=E3=81=AB=20ref?= =?UTF-8?q?erence=20point=20->=20origin=20point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 35 ++++++++++++++--------- test/test_geo_coordinate.cpp | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 2016049a..177458c4 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -3,6 +3,7 @@ #include "citygml/vecs.hpp" #include "citygml/cityobject.h" #include +#include #include namespace plateau::geometry { @@ -115,23 +116,13 @@ namespace plateau::geometry { static constexpr int default_epsg = 6697; // EPSGとZone IDのマッピング - static constexpr std::array, 13> epsg_to_zone = { { - {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, - {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, - {10172, 11}, {10173, 12}, {10174, 13} - } }; + static const std::set> epsg_to_zone; // Zone IDごとの座標データ - static constexpr std::array>, 13> zone_to_point = { { - {1, {33.0, 129.5, 0.0}}, {2, {33.0, 131.0, 0.0}}, {3, {36.0, 132.166667, 0.0}}, - {4, {33.0, 133.5, 0.0}}, {5, {36.0, 134.333333, 0.0}}, {6, {36.0, 136.0, 0.0}}, - {7, {36.0, 137.166667, 0.0}}, {8, {36.0, 138.5, 0.0}}, {9, {35.0, 139.833333, 0.0}}, - {10, {40.0, 140.833333, 0.0}}, {11, {44.0, 140.25, 0.0}}, {12, {44.0, 142.0, 0.0}}, - {13, {43.0, 144.0, 0.0}} - } }; + static const std::set>> zone_to_point; // EPSGごとのzone取得 - static constexpr int GetZoneId(int epsg) { + static const int GetZoneId(int epsg) { for (const auto& pair : epsg_to_zone) { if (pair.first == epsg) { return pair.second; @@ -141,7 +132,7 @@ namespace plateau::geometry { } // EPSGごとの基準点取得 - static GeoCoordinate GetReferencePoint(int epsg) { + static GeoCoordinate GetOriginPoint(int epsg) { const int zone = GetZoneId(epsg); if (zone != 0) { for (const auto& pair : zone_to_point) { @@ -163,4 +154,20 @@ namespace plateau::geometry { return !(epsg >= 10162 && epsg <= 10174); } }; + + // EPSGとZone IDのマッピング + inline const std::set> CoordinateReferenceFactory::epsg_to_zone = { + {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, + {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, + {10172, 11}, {10173, 12}, {10174, 13} + }; + + // Zone IDごとの座標データ + inline const std::set>> CoordinateReferenceFactory::zone_to_point = { + {1, {33.0, 129.5, 0.0}}, {2, {33.0, 131.0, 0.0}}, {3, {36.0, 132.166667, 0.0}}, + {4, {33.0, 133.5, 0.0}}, {5, {36.0, 134.333333, 0.0}}, {6, {36.0, 136.0, 0.0}}, + {7, {36.0, 137.166667, 0.0}}, {8, {36.0, 138.5, 0.0}}, {9, {35.0, 139.833333, 0.0}}, + {10, {40.0, 140.833333, 0.0}}, {11, {44.0, 140.25, 0.0}}, {12, {44.0, 142.0, 0.0}}, + {13, {43.0, 144.0, 0.0}} + }; } diff --git a/test/test_geo_coordinate.cpp b/test/test_geo_coordinate.cpp index 299d3f53..76a1bb19 100644 --- a/test/test_geo_coordinate.cpp +++ b/test/test_geo_coordinate.cpp @@ -38,7 +38,7 @@ namespace plateau::geometry { ASSERT_FALSE(CoordinateReferenceFactory::IsPolarCoordinateSystem(10169)); ASSERT_TRUE(CoordinateReferenceFactory::IsPolarCoordinateSystem(6697)); - const auto& refPoint = CoordinateReferenceFactory::GetReferencePoint(10169); + const auto& refPoint = CoordinateReferenceFactory::GetOriginPoint(10169); ASSERT_EQ(36.0, refPoint.latitude); ASSERT_EQ(138.5, refPoint.longitude); } From 2f3cd4b7639651c80ab4aa5785fff314028f1e24 Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 23 Apr 2025 16:14:10 +0900 Subject: [PATCH 20/24] =?UTF-8?q?unordered=20map=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 56 +++++++++-------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 177458c4..40c0a41f 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -3,7 +3,7 @@ #include "citygml/vecs.hpp" #include "citygml/cityobject.h" #include -#include +#include #include namespace plateau::geometry { @@ -109,65 +109,53 @@ namespace plateau::geometry { } }; - /** - * 平面直角座標系の判定、平面直角座標の基準点取得 - */ + /** + * 平面直角座標系の判定、平面直角座標の基準点取得 + */ struct CoordinateReferenceFactory { static constexpr int default_epsg = 6697; - // EPSGとZone IDのマッピング - static const std::set> epsg_to_zone; - + static const std::unordered_map epsg_to_zone; // Zone IDごとの座標データ - static const std::set>> zone_to_point; - + static const std::unordered_map> zone_to_point; // EPSGごとのzone取得 - static const int GetZoneId(int epsg) { - for (const auto& pair : epsg_to_zone) { - if (pair.first == epsg) { - return pair.second; - } + static int GetZoneId(int epsg) { + auto it = epsg_to_zone.find(epsg); + if (it != epsg_to_zone.end()) { + return it->second; } return 0; } - // EPSGごとの基準点取得 static GeoCoordinate GetOriginPoint(int epsg) { const int zone = GetZoneId(epsg); if (zone != 0) { - for (const auto& pair : zone_to_point) { - if (pair.first == zone) { - const auto& coords = pair.second; - return GeoCoordinate(coords[0], coords[1], coords[2]); - } + auto it = zone_to_point.find(zone); + if (it != zone_to_point.end()) { + const auto& coords = it->second; + return GeoCoordinate(coords[0], coords[1], coords[2]); } } return GeoCoordinate(); } - // 極座標系・平面直角座標系判定 - // 平面直角座標系の区分についてはこちらを参照してください : - // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ - // “該当範囲でなければ極座標” と単純化していますが、 - // EPSG 4301(JGD2000) 等の別 CRS を誤って極座標と判定する恐れがあります。 static bool IsPolarCoordinateSystem(int epsg) { - return !(epsg >= 10162 && epsg <= 10174); + // 平面直角座標系(EPSG 10162~10174)かどうかを明示的に確認 + return epsg_to_zone.find(epsg) == epsg_to_zone.end(); } }; - // EPSGとZone IDのマッピング - inline const std::set> CoordinateReferenceFactory::epsg_to_zone = { + inline const std::unordered_map CoordinateReferenceFactory::epsg_to_zone = { {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, {10172, 11}, {10173, 12}, {10174, 13} }; - // Zone IDごとの座標データ - inline const std::set>> CoordinateReferenceFactory::zone_to_point = { - {1, {33.0, 129.5, 0.0}}, {2, {33.0, 131.0, 0.0}}, {3, {36.0, 132.166667, 0.0}}, - {4, {33.0, 133.5, 0.0}}, {5, {36.0, 134.333333, 0.0}}, {6, {36.0, 136.0, 0.0}}, - {7, {36.0, 137.166667, 0.0}}, {8, {36.0, 138.5, 0.0}}, {9, {35.0, 139.833333, 0.0}}, - {10, {40.0, 140.833333, 0.0}}, {11, {44.0, 140.25, 0.0}}, {12, {44.0, 142.0, 0.0}}, + inline const std::unordered_map> CoordinateReferenceFactory::zone_to_point = { + {1, {33.0, 129.5, 0.0}}, {2, {33.0, 131.0, 0.0}}, {3, {36.0, 132.166667, 0.0}}, + {4, {33.0, 133.5, 0.0}}, {5, {36.0, 134.333333, 0.0}}, {6, {36.0, 136.0, 0.0}}, + {7, {36.0, 137.166667, 0.0}}, {8, {36.0, 138.5, 0.0}}, {9, {35.0, 139.833333, 0.0}}, + {10, {40.0, 140.833333, 0.0}}, {11, {44.0, 140.25, 0.0}}, {12, {44.0, 142.0, 0.0}}, {13, {43.0, 144.0, 0.0}} }; } From bce75943e742e90d6e6cc773de2d57f923b3c775 Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 23 Apr 2025 16:23:39 +0900 Subject: [PATCH 21/24] =?UTF-8?q?geo=20coodinate=20test=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_geo_coordinate.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/test_geo_coordinate.cpp b/test/test_geo_coordinate.cpp index 76a1bb19..8111d1f0 100644 --- a/test/test_geo_coordinate.cpp +++ b/test/test_geo_coordinate.cpp @@ -34,12 +34,29 @@ namespace plateau::geometry { TEST_F(GeoCoordinateTest, CoordinateReference) { // NOLINT - ASSERT_EQ(8, CoordinateReferenceFactory::GetZoneId(10169)); + // 正常系テスト - EPSGから正しいゾーンIDが取得できること + ASSERT_EQ(1, CoordinateReferenceFactory::GetZoneId(10162)); // 最小値 + ASSERT_EQ(8, CoordinateReferenceFactory::GetZoneId(10169)); // 中間値 + ASSERT_EQ(13, CoordinateReferenceFactory::GetZoneId(10174)); // 最大値 + + // 異常系テスト - 範囲外のEPSGでは0が返されること + ASSERT_EQ(0, CoordinateReferenceFactory::GetZoneId(10161)); // 境界外(最小値-1) + ASSERT_EQ(0, CoordinateReferenceFactory::GetZoneId(10175)); // 境界外(最大値+1) + ASSERT_EQ(0, CoordinateReferenceFactory::GetZoneId(6697)); // 極座標系EPSG + ASSERT_FALSE(CoordinateReferenceFactory::IsPolarCoordinateSystem(10169)); ASSERT_TRUE(CoordinateReferenceFactory::IsPolarCoordinateSystem(6697)); + ASSERT_TRUE(CoordinateReferenceFactory::IsPolarCoordinateSystem(4301)); // JGD2000 + ASSERT_TRUE(CoordinateReferenceFactory::IsPolarCoordinateSystem(0)); // 不明なEPSG const auto& refPoint = CoordinateReferenceFactory::GetOriginPoint(10169); ASSERT_EQ(36.0, refPoint.latitude); ASSERT_EQ(138.5, refPoint.longitude); + + // 無効なEPSGの場合、空のGeoCoordinateが返されること + const auto & invalidRefPoint = CoordinateReferenceFactory::GetOriginPoint(0); + ASSERT_EQ(0.0, invalidRefPoint.latitude); + ASSERT_EQ(0.0, invalidRefPoint.longitude); + ASSERT_EQ(0.0, invalidRefPoint.height); } } From 7255cd2ba8c22ea1a5bc0dc504d382fdef85a8cd Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 23 Apr 2025 16:29:01 +0900 Subject: [PATCH 22/24] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/plateau/geometry/geo_coordinate.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/plateau/geometry/geo_coordinate.h b/include/plateau/geometry/geo_coordinate.h index 40c0a41f..54a41555 100644 --- a/include/plateau/geometry/geo_coordinate.h +++ b/include/plateau/geometry/geo_coordinate.h @@ -81,8 +81,14 @@ namespace plateau::geometry { bool contains(const citygml::CityObject& city_obj, bool ignore_height = true) const; /** - * 平面直角座標系の判定を含む処理です - * 平面直角座標の場合はunprojectして緯度経度に変換してから判定します。 + * 座標系のEPSGコードに応じて適切な座標変換を行い、点が範囲内に含まれるかを判定します。 + * 平面直角座標系(EPSG 10162~10174)の場合は、平面座標を緯度経度座標に変換してから判定します。 + * 極座標系(それ以外のEPSG)の場合は、通常のcontainsメソッドと同様に直接判定します。 + * + * @param point 判定対象の点 + * @param epsg 座標系を識別するEPSGコード + * @param ignore_height 高さを無視する場合はtrue + * @return 点が範囲内に含まれる場合はtrue */ bool containsInPolar(TVec3d point,const int epsg, bool ignore_height = true) const; bool containsInPolar(const citygml::CityObject& city_obj,const int epsg, bool ignore_height = true) const; From f2d058917392710b4a4a34a6921eb5b51655f20b Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 23 Apr 2025 16:50:29 +0900 Subject: [PATCH 23/24] =?UTF-8?q?test=E3=81=AB=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_geo_coordinate.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test/test_geo_coordinate.cpp b/test/test_geo_coordinate.cpp index 8111d1f0..bcbc855d 100644 --- a/test/test_geo_coordinate.cpp +++ b/test/test_geo_coordinate.cpp @@ -4,10 +4,6 @@ namespace plateau::geometry { class GeoCoordinateTest : public ::testing::Test { protected: - void SetUp() override { - } - void TearDown() override { - } }; TEST_F(GeoCoordinateTest, ExtentContains) { // NOLINT @@ -20,12 +16,13 @@ namespace plateau::geometry { ASSERT_FALSE(ext.contains(GeoCoordinate(40, 0, 0))); ASSERT_FALSE(ext.contains(GeoCoordinate(0, -100, 0))); - // 6697の場合は同様の処理 + // 極座標系EPSG:6697(日本測地系2000)の場合、containsとcontainsInPolarの結果が一致することを確認 ASSERT_EQ(ext.contains(TVec3d(0, 0, 0)), ext.containsInPolar(TVec3d(0, 0, 0), 6697)); ASSERT_EQ(ext.contains(TVec3d(80, 90, 0)), ext.containsInPolar(TVec3d(80, 90, 0), 6697)); // 平面直角座標 - const auto& zoneRefPoint = GeoReference::planeToPolar(TVec3d(), 8);// 10169 は zone id:8 + // EPSG:10169は平面直角座標系(第8系) + const auto& zoneRefPoint = GeoReference::planeToPolar(TVec3d(), 8); ASSERT_FLOAT_EQ(36.0, zoneRefPoint.latitude); ASSERT_FLOAT_EQ(138.5, zoneRefPoint.longitude); ASSERT_FALSE(ext.containsInPolar(TVec3d(), 10169)); @@ -50,8 +47,8 @@ namespace plateau::geometry { ASSERT_TRUE(CoordinateReferenceFactory::IsPolarCoordinateSystem(0)); // 不明なEPSG const auto& refPoint = CoordinateReferenceFactory::GetOriginPoint(10169); - ASSERT_EQ(36.0, refPoint.latitude); - ASSERT_EQ(138.5, refPoint.longitude); + ASSERT_FLOAT_EQ(36.0, refPoint.latitude); + ASSERT_FLOAT_EQ(138.5, refPoint.longitude); // 無効なEPSGの場合、空のGeoCoordinateが返されること const auto & invalidRefPoint = CoordinateReferenceFactory::GetOriginPoint(0); From 381aa2e6529f09622382ee45c544020b70a4cbfb Mon Sep 17 00:00:00 2001 From: sevendev Date: Wed, 23 Apr 2025 17:28:31 +0900 Subject: [PATCH 24/24] =?UTF-8?q?test=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_geo_coordinate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_geo_coordinate.cpp b/test/test_geo_coordinate.cpp index bcbc855d..395c2227 100644 --- a/test/test_geo_coordinate.cpp +++ b/test/test_geo_coordinate.cpp @@ -52,8 +52,8 @@ namespace plateau::geometry { // 無効なEPSGの場合、空のGeoCoordinateが返されること const auto & invalidRefPoint = CoordinateReferenceFactory::GetOriginPoint(0); - ASSERT_EQ(0.0, invalidRefPoint.latitude); - ASSERT_EQ(0.0, invalidRefPoint.longitude); - ASSERT_EQ(0.0, invalidRefPoint.height); + ASSERT_FLOAT_EQ(0.0, invalidRefPoint.latitude); + ASSERT_FLOAT_EQ(0.0, invalidRefPoint.longitude); + ASSERT_FLOAT_EQ(0.0, invalidRefPoint.height); } }