You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 10:34:53