在C#中将GeoPackage PolyLines加载至ThinkGeo InMemoryFeatureLayer的高效方案
将GeoPackage PolyLines加载到ThinkGeo InMemoryFeatureLayer的最优方案
我正在寻找将GeoPackage中的PolyLines几何数据加载到ThinkGeo InMemoryFeatureLayer的最优方案。目前已基于Microsoft Sqlite和NetTopologySuite组件实现了可行方案,但希望找到直接将GeoPackage数据库加载至InMemoryFeatureLayer的方法。当前实现代码如下:
using Microsoft.Data.Sqlite; using NetTopologySuite.Geometries; using NetTopologySuite.IO; using ThinkGeo.Core; using ThinkGeo.UI.WinForms; // ... 其他代码 ... GeoPackageGeoReader gpkgReader = new GeoPackageGeoReader(); // 读取GeoPackage二进制几何数据 WKBWriter wkbWriter = new WKBWriter(); // 将GeoPackage几何转换为标准WKB using (SqliteConnection SQLiteConnection = new SqliteConnection(@"Data Source=:memory:")) { using (SqliteCommand SQLiteCommand = new SqliteCommand()) { SQLiteCommand.CommandText = $@" ATTACH 'c:\temp\lines.gpkg' as lines_; CREATE TEMP TABLE IF NOT EXISTS lines AS SELECT * FROM lines_.lines; DETACH lines_; SELECT fid, _ogr_geometry_, street FROM lines; "; SQLiteCommand.Connection = SQLiteConnection; SQLiteConnection.Open(); using (SqliteDataReader SQLiteDataReader = SQLiteCommand.ExecuteReader()) { while (SQLiteDataReader.Read()) { string id = SQLiteDataReader["fid"].ToString(); byte[] geomData = (byte[])SQLiteDataReader.GetValue("_ogr_geometry_"); Geometry geometry = gpkgReader.Read(geomData); // 从GeoPackage二进制数据中读取几何 byte[] standardWkb = wkbWriter.Write(geometry); // 转换为标准WKB Feature polyLineFeature = new Feature(standardWkb, id); polyLineFeature.Id = id; for (int i = 0; i < SQLiteDataReader.FieldCount; i++) { string columnName = SQLiteDataReader.GetName(i); object value = SQLiteDataReader.GetValue(i); string valueAsString = value switch { null or DBNull => string.Empty, // 处理空值和DBNull string str => str, // 直接使用字符串 _ => value.ToString() // 其他类型转为字符串 }; polyLineFeature.ColumnValues.Add(columnName, valueAsString); // 添加属性字段 } InMemoryFeatureLayer.InternalFeatures.Add(polyLineFeature); // 将要素添加到内存图层 } InMemoryFeatureLayer.BuildIndex(); } } } // ... 其他代码 ...
更优的直接加载方案
ThinkGeo Core库原生提供了GeoPackageFeatureLayer类,可直接读取GeoPackage数据,无需手动处理Sqlite连接、几何格式转换等底层操作,能更高效地将数据导入InMemoryFeatureLayer。
实现代码
using ThinkGeo.Core; using ThinkGeo.UI.WinForms; // 定义GeoPackage路径和目标图层名 string geoPackagePath = @"c:\temp\lines.gpkg"; string targetLayerName = "lines"; // 初始化GeoPackageFeatureLayer GeoPackageFeatureLayer geoPackageLayer = new GeoPackageFeatureLayer(geoPackagePath, targetLayerName); // 打开图层以读取数据 geoPackageLayer.Open(); // 初始化InMemoryFeatureLayer,同步源图层的字段结构 InMemoryFeatureLayer inMemoryLayer = new InMemoryFeatureLayer(geoPackageLayer.FeatureSource.GetColumns()); // 批量导入所有要素 foreach (Feature feature in geoPackageLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)) { inMemoryLayer.InternalFeatures.Add(feature); } // 构建索引提升后续查询性能 inMemoryLayer.BuildIndex(); // 关闭GeoPackage图层释放资源 geoPackageLayer.Close();
方案优势
- 简化代码逻辑:省去手动Sqlite连接、WKB转换等冗余代码,降低维护成本
- 原生支持更可靠:ThinkGeo内部封装了GeoPackage的标准解析逻辑,避免自定义转换可能出现的格式兼容问题
- 性能更高效:
GeoPackageFeatureLayer的批量读取逻辑经过优化,比逐行手动转换的效率更高
内容的提问来源于stack exchange,提问作者Pepik
相关产品推荐
相关产品推荐

