DotSpatial对于PostGis的快速读取

以前写了一篇关于PostGresql的读取方法,但是最近使用Ds发现版本更新了,而且不想像上次那样通过过于繁琐的方法去完成对PostGis的数据加载,所以又研究了一下思路。

  1. 通过查看FeatureSet这个类的源码,发现它有一个未使用的构造函数,其中有些思想可以用于借鉴:
    /// <summary>
            /// Initializes a new instance of the <see cref="FeatureSet"/> class.
            /// This creates a new featureset by checking each row of the table. If the WKB feature
            /// type matches the specified featureTypes, then it will copy that.
            /// </summary>
            /// <param name="wkbTable">The wkbTable.</param>
            /// <param name="wkbColumnIndex">The wkb column index. Not used.</param>
            /// <param name="indexed">Not used.</param>
            /// <param name="type">The feature type. Not used.</param>
            public FeatureSet(DataTable wkbTable, int wkbColumnIndex, bool indexed, FeatureType type)
                : this()
            {
                if (IndexMode)
                {
                    // Assume this DataTable has WKB in column[0] and the rest of the columns are attributes.
                    FeatureSetPack result = new FeatureSetPack();
                    foreach (DataRow row in wkbTable.Rows)
                    {
                        byte[] data = (byte[])row[0];
                        MemoryStream ms = new MemoryStream(data);
                        WkbFeatureReader.ReadFeature(ms, result);
                    }
    
                    // convert lists of arrays into a single vertex array for each shape type.
                    result.StopEditing();
    
                    // Make sure all the same columns exist in the same order
                    result.Polygons.CopyTableSchema(wkbTable);
    
                    // Assume that all the features happened to be polygons
                    foreach (DataRow row in wkbTable.Rows)
                    {
                        // Create a new row
                        DataRow dest = result.Polygons.DataTable.NewRow();
                        dest.ItemArray = row.ItemArray;
                    }
                }
            }

     

  2. 此处是创建了一个FeatureSetPack(内部包含了点线面三种数据集合),然后将wkb数据转换为feature插入到对应的数据集合内。
  3. 当图形要素(shape)插入完成后,再对数据集合(featureSet)的属性进行设置

 上述的三点是FeatureSet这个构造函数的思路,下面是我们的思路:

  1. 我们可以先通过sql语句在数据库中获取矢量图层的数据,其中重要的事情是获取geom字段时需要使用的函数是st_AsBinary,这样返回的包含wkb数据的datatable即可使用
  2. 创建对应类型的FeatureSet对象,遍历datatable对象,将每一行的wkb转换为shape对象,使用featureset对象的AddFeature方法将当前要素的图形数据添加。由于AddFeature方法在添加成功后会返回一个Feature对象,我们再给feature对象的datarow进行设置(设置属性信息)
  3. 遍历完成后,featureset.addfid()添加序号,利用featureset创建对应类型的IMapLayer对象(点线面),设置maplayer的legendText,投影信息;
  4. map.layers.add()将图层添加到地图中,此时用过查询会发现,每个要素的datarow数据都会存在,featureset的datatable数据也是存在的,但是使用FeatureSetPack 这个类完成的就会出现datarow数据为空。

通过这个思路实现的加载能够完美的将PG内的数据加载到地图中,图形和属性没有丢失。但是效率相对于本地的shapefile感觉确实要低一些,特别是同时加载多个图层的时候。为了解决加载效率的问题,我们就在同时加载图层的时候通过循环创建多个线程,每个线程加载指定个数的图层,这样效果会好很多。

 

 

 

 

转载自:https://blog.csdn.net/weixin_41012454/article/details/88778850

You may also like...