C#利用GDAL对Shapefile进行操作

1、获取要素图层

        public static OSGeo.OGR.Layer GetLayer(string filePath)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 获取图层
            OSGeo.OGR.Driver pDriver = Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.Open(filePath, 1);
            OSGeo.OGR.Layer pLayer = pDataSource.GetLayerByName(System.IO.Path.GetFileNameWithoutExtension(filePath));
            return pLayer;
        }

2、创建要素图层

        public static OSGeo.OGR.Layer CreateLayer(string filePath, OSGeo.OGR.wkbGeometryType geometryType, OSGeo.OSR.SpatialReference spatialReference)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 数据源
            OSGeo.OGR.Driver pDriver = Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.CreateDataSource(filePath, null);
            OSGeo.OGR.Layer pLayer = null;

            // 创建图层
            if (geometryType == wkbGeometryType.wkbPoint)
            {
                pLayer = pDataSource.CreateLayer(System.IO.Path.GetFileNameWithoutExtension(filePath), spatialReference, wkbGeometryType.wkbPoint, null);
            }
            else if (geometryType == wkbGeometryType.wkbLineString)
            {
                pLayer = pDataSource.CreateLayer(System.IO.Path.GetFileNameWithoutExtension(filePath), spatialReference, wkbGeometryType.wkbLineString, null);
            }
            else
            {
                pLayer = pDataSource.CreateLayer(System.IO.Path.GetFileNameWithoutExtension(filePath), spatialReference, wkbGeometryType.wkbPolygon, null);
            }
            return pLayer;
        }

3、读取要素图层属性表
这里要注意,有很多同志在读shp文件属性表的时候,如果字段值包含中文会出现乱码的情况,我这里总结了一种方法。

        [DllImport("gdal202.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]
        public extern static System.IntPtr OGR_F_GetFieldAsString(HandleRef handle, int index);
        
        public static void ReadLayerAttributes(string filePath)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 数据源
            OSGeo.OGR.Driver pDriver = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.Open(filePath, 1);
            OSGeo.OGR.Layer pLayer = pDataSource.GetLayerByName(System.IO.Path.GetFileNameWithoutExtension(filePath));

            // 字段结构
            OSGeo.OGR.Feature pFeature = pLayer.GetNextFeature();
            OSGeo.OGR.FeatureDefn pFeatureDefn = pLayer.GetLayerDefn();
            int fieldsCount = pFeature.GetFieldCount();

            // 遍历要素
            while (pFeature != null)
            {
                for (int i = 0; i < fieldsCount; i++)
                {
                    OSGeo.OGR.FieldDefn pFieldDefn = pFeature.GetFieldDefnRef(i);
                    switch (pFieldDefn.GetFieldType())
                    {
                        case FieldType.OFTInteger:
                            {
                                Console.WriteLine(pFeature.GetFieldAsInteger(i));
                            }
                            break;
                        case FieldType.OFTInteger64:
                            {
                                Console.WriteLine(pFeature.GetFieldAsInteger64(i));
                            }
                            break;
                        case FieldType.OFTReal:
                            {
                                Console.WriteLine(pFeature.GetFieldAsDouble(i));
                            }
                            break;
                        case FieldType.OFTString:
                            {
                                string fieldName = pFieldDefn.GetName();
                                int fieldIndex = pFeatureDefn.GetFieldIndex(fieldName);
                                IntPtr pIntPtr = OGR_F_GetFieldAsString(OSGeo.OGR.Feature.getCPtr(pFeature), fieldIndex);
                                Console.WriteLine(Marshal.PtrToStringAnsi(pIntPtr));
                            }
                            break;
                    }
                }
                Console.WriteLine("----------------------------------------------");
                pFeature = pLayer.GetNextFeature();
            }
        }

效果如下:这种方法读出来的中文就不会乱码了。
C#利用GDAL对Shapefile进行操作_第1张图片
4、插入要素

        public static void InsertFeatures(string filePath)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 数据源
            OSGeo.OGR.Driver pDriver = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.Open(filePath, 1);
            OSGeo.OGR.Layer pLayer = pDataSource.GetLayerByName(System.IO.Path.GetFileNameWithoutExtension(filePath));

            // 字段索引
            OSGeo.OGR.FeatureDefn pFeatureDefn = pLayer.GetLayerDefn();
            int fieldIndex_A = pFeatureDefn.GetFieldIndex("A");
            int fieldIndex_B = pFeatureDefn.GetFieldIndex("B");
            int fieldIndex_C = pFeatureDefn.GetFieldIndex("C");

            // 插入要素
            OSGeo.OGR.Feature pFeature = new Feature(pFeatureDefn);
            OSGeo.OGR.Geometry geometry = Geometry.CreateFromWkt("POLYGON ((30 0,60 0,60 30,30 30,30 0))");
            pFeature.SetGeometry(geometry);
            pFeature.SetField(fieldIndex_A, 0);
            pFeature.SetField(fieldIndex_B, "211031");
            pFeature.SetField(fieldIndex_C, "张三");
            pLayer.CreateFeature(pFeature);

            geometry = Geometry.CreateFromWkt("POLYGON ((130 0,160 0,160 130,130 130,130 0))");
            pFeature.SetGeometry(geometry);
            pFeature.SetField(fieldIndex_A, 1);
            pFeature.SetField(fieldIndex_B, "211032");
            pFeature.SetField(fieldIndex_C, "李四");
            pLayer.CreateFeature(pFeature);
        }

5、创建字段

        public static void CreateFields(OSGeo.OGR.Layer pLayer)
        {
            // int类型字段
            OSGeo.OGR.FieldDefn pFieldDefn = new OSGeo.OGR.FieldDefn("A", OSGeo.OGR.FieldType.OFTInteger);
            pLayer.CreateField(pFieldDefn, 1);

            // double类型字段
            pFieldDefn = new OSGeo.OGR.FieldDefn("B", OSGeo.OGR.FieldType.OFTReal);
            pFieldDefn.SetPrecision(3);
            pLayer.CreateField(pFieldDefn, 1);

            // string类型字段
            pFieldDefn = new OSGeo.OGR.FieldDefn("C", OSGeo.OGR.FieldType.OFTString);
            pFieldDefn.SetWidth(200);
            pLayer.CreateField(pFieldDefn, 1);
        }

6、输出字段名称

        public static void GetFieldsName(OSGeo.OGR.Layer pLayer)
        {
            OSGeo.OGR.FeatureDefn pFeatureDefn = pLayer.GetLayerDefn();
            for (int i = 0; i < pFeatureDefn.GetFieldCount(); i++)
            {
                OSGeo.OGR.FieldDefn pFieldDefn = pFeatureDefn.GetFieldDefn(i);
                Console.WriteLine(pFieldDefn.GetNameRef());
            }
        }

7、获取空间参考字符串

        public static string GetSpatialReferenceString(OSGeo.OGR.Layer pLayer)
        {
            OSGeo.OSR.SpatialReference pSpatialReference = pLayer.GetSpatialRef();
            pSpatialReference.ExportToWkt(out string spatialReferenceString);
            return spatialReferenceString;
        }

8、根据字符串生成空间参考

        public static OSGeo.OSR.SpatialReference CreateSpatialReference(string spatialReferenceString)
        {
            OSGeo.OSR.SpatialReference pSpatialReference = new OSGeo.OSR.SpatialReference(spatialReferenceString);
            return pSpatialReference;
        }

全部代码如下

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using OSGeo.GDAL;
using OSGeo.OGR;

namespace ConsoleApp2
{
    public class GdalHelper
    {
        [DllImport("gdal202.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]
        public extern static System.IntPtr OGR_F_GetFieldAsString(HandleRef handle, int index);

        /// 
        /// 获取要素图层
        /// 
        /// 
        /// 
        public static OSGeo.OGR.Layer GetLayer(string filePath)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 获取图层
            OSGeo.OGR.Driver pDriver = Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.Open(filePath, 1);
            OSGeo.OGR.Layer pLayer = pDataSource.GetLayerByName(System.IO.Path.GetFileNameWithoutExtension(filePath));
            return pLayer;
        }

        /// 
        /// 创建要素图层
        /// 
        /// 
        /// 
        /// 
        /// 
        public static OSGeo.OGR.Layer CreateLayer(string filePath, OSGeo.OGR.wkbGeometryType geometryType, OSGeo.OSR.SpatialReference spatialReference)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 数据源
            OSGeo.OGR.Driver pDriver = Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.CreateDataSource(filePath, null);
            OSGeo.OGR.Layer pLayer = null;

            // 创建图层
            if (geometryType == wkbGeometryType.wkbPoint)
            {
                pLayer = pDataSource.CreateLayer(System.IO.Path.GetFileNameWithoutExtension(filePath), spatialReference, wkbGeometryType.wkbPoint, null);
            }
            else if (geometryType == wkbGeometryType.wkbLineString)
            {
                pLayer = pDataSource.CreateLayer(System.IO.Path.GetFileNameWithoutExtension(filePath), spatialReference, wkbGeometryType.wkbLineString, null);
            }
            else
            {
                pLayer = pDataSource.CreateLayer(System.IO.Path.GetFileNameWithoutExtension(filePath), spatialReference, wkbGeometryType.wkbPolygon, null);
            }
            return pLayer;
        }

        /// 
        /// 读取要素图层属性表
        /// 
        /// 
        public static void ReadLayerAttributes(string filePath)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 数据源
            OSGeo.OGR.Driver pDriver = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.Open(filePath, 1);
            OSGeo.OGR.Layer pLayer = pDataSource.GetLayerByName(System.IO.Path.GetFileNameWithoutExtension(filePath));

            // 字段结构
            OSGeo.OGR.Feature pFeature = pLayer.GetNextFeature();
            OSGeo.OGR.FeatureDefn pFeatureDefn = pLayer.GetLayerDefn();
            int fieldsCount = pFeature.GetFieldCount();

            // 遍历要素
            while (pFeature != null)
            {
                for (int i = 0; i < fieldsCount; i++)
                {
                    OSGeo.OGR.FieldDefn pFieldDefn = pFeature.GetFieldDefnRef(i);
                    switch (pFieldDefn.GetFieldType())
                    {
                        case FieldType.OFTInteger:
                            {
                                Console.WriteLine(pFeature.GetFieldAsInteger(i));
                            }
                            break;
                        case FieldType.OFTInteger64:
                            {
                                Console.WriteLine(pFeature.GetFieldAsInteger64(i));
                            }
                            break;
                        case FieldType.OFTReal:
                            {
                                Console.WriteLine(pFeature.GetFieldAsDouble(i));
                            }
                            break;
                        case FieldType.OFTString:
                            {
                                string fieldName = pFieldDefn.GetName();
                                int fieldIndex = pFeatureDefn.GetFieldIndex(fieldName);
                                IntPtr pIntPtr = OGR_F_GetFieldAsString(OSGeo.OGR.Feature.getCPtr(pFeature), fieldIndex);
                                Console.WriteLine(Marshal.PtrToStringAnsi(pIntPtr));
                            }
                            break;
                    }
                }
                Console.WriteLine("----------------------------------------------");
                pFeature = pLayer.GetNextFeature();
            }
        }

        /// 
        /// 插入要素
        /// 
        /// 
        public static void InsertFeatures(string filePath)
        {
            // 注册GDAL
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.OGR.Ogr.RegisterAll();

            // 数据源
            OSGeo.OGR.Driver pDriver = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource pDataSource = pDriver.Open(filePath, 1);
            OSGeo.OGR.Layer pLayer = pDataSource.GetLayerByName(System.IO.Path.GetFileNameWithoutExtension(filePath));

            // 字段索引
            OSGeo.OGR.FeatureDefn pFeatureDefn = pLayer.GetLayerDefn();
            int fieldIndex_A = pFeatureDefn.GetFieldIndex("A");
            int fieldIndex_B = pFeatureDefn.GetFieldIndex("B");
            int fieldIndex_C = pFeatureDefn.GetFieldIndex("C");

            // 插入要素
            OSGeo.OGR.Feature pFeature = new Feature(pFeatureDefn);
            OSGeo.OGR.Geometry geometry = Geometry.CreateFromWkt("POLYGON ((30 0,60 0,60 30,30 30,30 0))");
            pFeature.SetGeometry(geometry);
            pFeature.SetField(fieldIndex_A, 0);
            pFeature.SetField(fieldIndex_B, "211031");
            pFeature.SetField(fieldIndex_C, "张三");
            pLayer.CreateFeature(pFeature);

            geometry = Geometry.CreateFromWkt("POLYGON ((130 0,160 0,160 130,130 130,130 0))");
            pFeature.SetGeometry(geometry);
            pFeature.SetField(fieldIndex_A, 1);
            pFeature.SetField(fieldIndex_B, "211032");
            pFeature.SetField(fieldIndex_C, "李四");
            pLayer.CreateFeature(pFeature);
        }

        /// 
        /// 创建字段
        /// 
        /// 
        public static void CreateFields(OSGeo.OGR.Layer pLayer)
        {
            // int类型字段
            OSGeo.OGR.FieldDefn pFieldDefn = new OSGeo.OGR.FieldDefn("A", OSGeo.OGR.FieldType.OFTInteger);
            pLayer.CreateField(pFieldDefn, 1);

            // double类型字段
            pFieldDefn = new OSGeo.OGR.FieldDefn("B", OSGeo.OGR.FieldType.OFTReal);
            pFieldDefn.SetPrecision(3);
            pLayer.CreateField(pFieldDefn, 1);

            // string类型字段
            pFieldDefn = new OSGeo.OGR.FieldDefn("C", OSGeo.OGR.FieldType.OFTString);
            pFieldDefn.SetWidth(200);
            pLayer.CreateField(pFieldDefn, 1);
        }

        /// 
        /// 输出字段名称
        /// 
        /// 
        public static void GetFieldsName(OSGeo.OGR.Layer pLayer)
        {
            OSGeo.OGR.FeatureDefn pFeatureDefn = pLayer.GetLayerDefn();
            for (int i = 0; i < pFeatureDefn.GetFieldCount(); i++)
            {
                OSGeo.OGR.FieldDefn pFieldDefn = pFeatureDefn.GetFieldDefn(i);
                Console.WriteLine(pFieldDefn.GetNameRef());
            }
        }

        /// 
        /// 获取空间参考字符串
        /// 
        /// 
        /// 
        public static string GetSpatialReferenceString(OSGeo.OGR.Layer pLayer)
        {
            OSGeo.OSR.SpatialReference pSpatialReference = pLayer.GetSpatialRef();
            pSpatialReference.ExportToWkt(out string spatialReferenceString);
            return spatialReferenceString;
        }

        /// 
        /// 根据字符串生成空间参考
        /// 
        /// 
        /// 
        public static OSGeo.OSR.SpatialReference CreateSpatialReference(string spatialReferenceString)
        {
            OSGeo.OSR.SpatialReference pSpatialReference = new OSGeo.OSR.SpatialReference(spatialReferenceString);
            return pSpatialReference;
        }
    }
}

你可能感兴趣的:(C#,GDAL)