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();
            }
        }

效果如下:这种方法读出来的中文就不会乱码了。
在这里插入图片描述

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);

        /// <summary>
        /// 获取要素图层
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        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;
        }

        /// <summary>
        /// 创建要素图层
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="geometryType"></param>
        /// <param name="spatialReference"></param>
        /// <returns></returns>
        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;
        }

        /// <summary>
        /// 读取要素图层属性表
        /// </summary>
        /// <param name="filePath"></param>
        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();
            }
        }

        /// <summary>
        /// 插入要素
        /// </summary>
        /// <param name="filePath"></param>
        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);
        }

        /// <summary>
        /// 创建字段
        /// </summary>
        /// <param name="pLayer"></param>
        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);
        }

        /// <summary>
        /// 输出字段名称
        /// </summary>
        /// <param name="pLayer"></param>
        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());
            }
        }

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

        /// <summary>
        /// 根据字符串生成空间参考
        /// </summary>
        /// <param name="spatialReferenceString"></param>
        /// <returns></returns>
        public static OSGeo.OSR.SpatialReference CreateSpatialReference(string spatialReferenceString)
        {
            OSGeo.OSR.SpatialReference pSpatialReference = new OSGeo.OSR.SpatialReference(spatialReferenceString);
            return pSpatialReference;
        }
    }
}
要将Shapefile格式文件转换为DWG格式,你可以使用GDAL库中的OGR(OpenGIS Simple Features Reference Implementation)功能。下面是使用GDAL进行转换的基本步骤: 1. 引用GDAL和OGR库:在C#项目中,首先需要引用GDAL和OGR库。你可以在代码文件中添加以下引用: ```csharp using OSGeo.GDAL; using OSGeo.OGR; ``` 2. 初始化GDAL:在程序的入口点或初始化代码中,调用GDAL的初始化方法: ```csharp Gdal.AllRegister(); ``` 3. 打开Shapefile数据源:使用OGR打开Shapefile数据源: ```csharp DataSource sourceDS = Ogr.Open("path/to/your/shapefile", 0); ``` 4. 创建DWG文件数据源:使用OGR创建DWG文件数据源: ```csharp Driver dwgDriver = Ogr.GetDriverByName("DWG"); DataSource targetDS = dwgDriver.CreateDataSource("path/to/your/dwgfile", null); ``` 5. 复制图层:遍历Shapefile数据源中的图层,并将其复制到DWG数据源中: ```csharp for (int i = 0; i < sourceDS.GetLayerCount(); i++) { Layer sourceLayer = sourceDS.GetLayerByIndex(i); Layer targetLayer = targetDS.CreateLayer(sourceLayer.GetName(), sourceLayer.GetSpatialRef(), sourceLayer.GetGeomType(), null); FeatureDefn featureDefn = sourceLayer.GetLayerDefn(); for (int j = 0; j < featureDefn.GetFieldCount(); j++) { FieldDefn fieldDefn = featureDefn.GetFieldDefn(j); targetLayer.CreateField(fieldDefn, 1); } sourceLayer.ResetReading(); Feature feature; while ((feature = sourceLayer.GetNextFeature()) != null) { Feature targetFeature = new Feature(featureDefn); targetFeature.SetFrom(feature); targetLayer.CreateFeature(targetFeature); feature.Dispose(); targetFeature.Dispose(); } sourceLayer.Dispose(); targetLayer.Dispose(); } ``` 6. 关闭数据源:在使用完数据后,需要关闭数据源以释放资源: ```csharp sourceDS.Dispose(); targetDS.Dispose(); ``` 以上是使用GDAL库将Shapefile格式文件转换为DWG格式的基本步骤。请注意,转换过程中可能需要进行投影转换或其他额外的操作,具体取决于你的数据和需求。你可以根据需要进行进一步的处理和优化。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值