diff --git a/include/plateau/dataset/i_dataset_accessor.h b/include/plateau/dataset/i_dataset_accessor.h index 85c2bd43..d441b2ba 100644 --- a/include/plateau/dataset/i_dataset_accessor.h +++ b/include/plateau/dataset/i_dataset_accessor.h @@ -132,7 +132,7 @@ namespace plateau::dataset { /** * \brief 都市モデルデータが存在する地域メッシュのリストを取得します。 */ - virtual std::set, GridCodeComparator>& getGridCodes() = 0; + virtual const std::set, GridCodeComparator>& getGridCodes() = 0; virtual TVec3d calculateCenterPoint(const plateau::geometry::GeoReference& geo_reference) = 0; diff --git a/src/dataset/local_dataset_accessor.cpp b/src/dataset/local_dataset_accessor.cpp index 3e8d1db4..84b8829f 100644 --- a/src/dataset/local_dataset_accessor.cpp +++ b/src/dataset/local_dataset_accessor.cpp @@ -301,7 +301,7 @@ namespace plateau::dataset { return fs::relative(fs::u8path(path).make_preferred(), fs::u8path(udx_path_)).make_preferred().string(); } - std::set, GridCodeComparator>& LocalDatasetAccessor::getGridCodes() { + const std::set, GridCodeComparator>& LocalDatasetAccessor::getGridCodes() { if (grid_codes_.empty()) { for (const auto& [_, files]: files_) { for (const auto& file: files) { diff --git a/src/dataset/local_dataset_accessor.h b/src/dataset/local_dataset_accessor.h index 6f20a03e..032e35ee 100644 --- a/src/dataset/local_dataset_accessor.h +++ b/src/dataset/local_dataset_accessor.h @@ -68,7 +68,7 @@ namespace plateau::dataset { /** * \brief 都市モデルデータが存在するGridCodeのリストを取得します。 */ - std::set, GridCodeComparator>& getGridCodes() override; + const std::set, GridCodeComparator>& getGridCodes() override; std::string getRelativePath(const std::string& path) const; std::string getU8RelativePath(const std::string& path) const; diff --git a/src/dataset/server_dataset_accessor.cpp b/src/dataset/server_dataset_accessor.cpp index fa7184f8..7dc4ce30 100644 --- a/src/dataset/server_dataset_accessor.cpp +++ b/src/dataset/server_dataset_accessor.cpp @@ -21,7 +21,7 @@ namespace plateau::dataset { grid_codes_.clear(); } - std::set, GridCodeComparator>& ServerDatasetAccessor::getGridCodes() { + const std::set, GridCodeComparator>& ServerDatasetAccessor::getGridCodes() { if (grid_codes_.empty()) { for (const auto& [_, files] : dataset_files_) { for (const auto& file : files) { diff --git a/src/dataset/server_dataset_accessor.h b/src/dataset/server_dataset_accessor.h index a0d3c467..35dce14b 100644 --- a/src/dataset/server_dataset_accessor.h +++ b/src/dataset/server_dataset_accessor.h @@ -18,7 +18,7 @@ namespace plateau::dataset { void loadFromServer(); - std::set, GridCodeComparator>& getGridCodes() override; + const std::set, GridCodeComparator>& getGridCodes() override; std::shared_ptr> getGmlFiles(PredefinedCityModelPackage package) override; void getGmlFiles(PredefinedCityModelPackage package_flags, std::vector& out_gml_files) override; diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/DatasetAccessor.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/DatasetAccessor.cs index cbd5129b..16d45e2e 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/DatasetAccessor.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/DatasetAccessor.cs @@ -41,6 +41,10 @@ public NativeVectorGmlFile GetAllGmlFiles() return GetGmlFiles((PredefinedCityModelPackage)allPackages); } + /// + /// C++側のvectorとしてのGridCodeを返します。 + /// 注意:受け取る側でusingを付けるなど、廃棄されるようにしてください。 + /// public NativeVectorGridCode GridCodes { get @@ -79,7 +83,7 @@ public DatasetAccessor FilterByGridCodes(IEnumerable gridCodes) var nativeGridCodes = NativeVectorGridCode.Create(); foreach (var gridCode in gridCodes) { - nativeGridCodes.Add(gridCode); + nativeGridCodes.AddCopyOf(gridCode); } var result = NativeMethods.plateau_i_dataset_accessor_filter_by_grid_codes( diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs index 07ee7cfb..398d4a78 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/GmlFile.cs @@ -81,6 +81,7 @@ public PredefinedCityModelPackage Package { /// GMLファイルのGridCodeを返します。 /// ただし、誤った形式のGMLファイル名である等の理由でGridCodeを読み取れなかった場合は /// 戻り値の isValid が false になります。 + /// 戻り値が解放されるようにするためにusingを付けてください。 /// public GridCode GridCode { @@ -89,6 +90,7 @@ public GridCode GridCode ThrowIfDisposed(); var gridCodePtr = DLLUtil.GetNativeValue(Handle, NativeMethods.plateau_gml_file_get_grid_code); + // gridCodePtrの寿命管理はC++側に任せるのでここでは解放しませんが、copiedはC#から解放する必要があります。 var copied = GridCode.CopyFrom(gridCodePtr); return copied; } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/MeshCode.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/MeshCode.cs index 9328a880..13bb40dc 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/MeshCode.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Dataset/MeshCode.cs @@ -21,51 +21,5 @@ public struct MeshCode public readonly int Level; [MarshalAs(UnmanagedType.U1)] private readonly bool isValid; - private static bool getHalfMeshNumber(out int num, int row, int col) - { - if (row < 0 || row > 1 || - col < 0 || col > 1) - { - num = 0; - return false; - } - - // 番号順に左下→右下→左上→右上 - num = row * 2 + col + 1; - return true; - } - - public override string ToString() - { - // ThrowIfInvalid(); - string secondString = Level2(); - if (this.Level == 2) - return secondString; - - string thirdString = secondString + $"{this.ThirdRow | 0}{this.ThirdCol | 0}"; - if (this.Level == 3) - return thirdString; - - getHalfMeshNumber(out int fourthNum, this.FourthRow, this.FourthCol); - string fourthString = thirdString + $"{fourthNum}"; - if (this.Level == 4) - return fourthString; - - getHalfMeshNumber(out int fifthNum, this.FifthRow, this.FifthCol); - string fifthString = fourthString + $"{fifthNum}"; - return fifthString; - } - - public string Level2() - { - // ThrowIfInvalid(); - return $"{this.FirstRow | 00}{this.FirstCol | 00}{this.SecondRow | 0}{this.SecondCol | 0}"; - } - - public string Level3() - { - // ThrowIfInvalid(); - return $"{Level2()}{this.ThirdRow | 0}{this.ThirdCol | 0}"; - } } } \ No newline at end of file diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Native/NativeVectorGridCode.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Native/NativeVectorGridCode.cs index d6faddf0..98850726 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Native/NativeVectorGridCode.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/Native/NativeVectorGridCode.cs @@ -7,7 +7,8 @@ namespace PLATEAU.Native { /// /// GridCodeのC++ Vectorです。 - /// 中身はVectorの廃棄時の削除するので、それまでは中身が削除されないよう注意してください。 + /// 中身はVectorの廃棄時に削除されます。 + /// ダングリングを防ぐため、vectorへの追加・参照時はコピーを渡します。 /// public class NativeVectorGridCode : NativeVectorDisposableBase { @@ -21,6 +22,9 @@ public static NativeVectorGridCode Create() return new NativeVectorGridCode(ptr); } + /// + /// インデックスでアクセスし、そのコピーを返します。 + /// public override GridCode At(int index) { ThrowIfDisposed(); @@ -40,11 +44,18 @@ public override int Length } } - public void Add(GridCode gridCode) + /// + /// 追加します。ただし、無効なGridCodeの場合は何もしません。 + /// + public void AddCopyOf(GridCode gridCode) { - gridCode.PreventAutoDispose(); + if (!gridCode.IsValid) return; + // ダングリングを防ぐためコピーを追加します。 + var copied = GridCode.CopyFrom(gridCode.Handle); + // vectorが廃棄されるまでGridCodeが廃棄されないようにします。 + copied.PreventAutoDispose(); var result = NativeMethods.plateau_vector_grid_code_push_back_value( - Handle, gridCode.Handle); + Handle, copied.Handle); DLLUtil.CheckDllError(result); }