gdal操作矢量数据

                  目录

01注册驱动,设置环境变量

02 获取矢量图层

03创建矢量数据 

04获取图层、字段、要素属性信息

05不同数据源读取要素属性时中文存在不同程度乱码,需要获取重新字符串信息 


01注册驱动,设置环境变量

程序初始化时注册一次驱动和设置环境变量即可。

        public static void InitinalGdal()
        {
            try
            {
                OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");// 为了支持中文路径
                //OSGeo.GDAL.Gdal.SetConfigOption("GDAL_DATA", "gdal-data");
                OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");  // 为了使属性表字段支持中文
                OSGeo.GDAL.Gdal.AllRegister();
                Ogr.RegisterAll();
            }
            catch (System.Exception ex)
            {

            }
        }

02 获取矢量图层

 

        /// 
        /// 获取shp图层
        /// 
        /// shp路径
        /// 
        public static Layer GetSHPLayer(string shpPath)
        {
            Layer layer = null;
            try
            {
                //InitinalGdal();
                DataSource dsSHP = Ogr.Open(shpPath, 0);
                layer = dsSHP.GetLayerByIndex(0);
                string name = layer.GetName();
                SpatialReference sr = layer.GetSpatialRef();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return layer;
        }
        /// 
        /// 获取gdb数据
        /// 
        /// gdb路径
        /// 图层名
        /// 
        public static Layer GetGDBLayer(string gdbPath, string tableName)
        {
            //InitinalGdal();
            Layer layer = null;
            try
            {
                //方法一
                //String gdbDriverName = OpenFileGDB
                //Driver gdbDriver = Ogr.GetDriverByName(gdbDriverName);
                //if (gdbDriver == null)
                //{
                //    string errInfo = gdbDriverName + " 驱动不可用!\n";
                //    //return false;
                //}
                //DataSource gdbDataSource;
                获取gdb数据源
                //gdbDataSource = gdbDriver.Open(gdbPath, 0);
                //int layerCount = dsGDB.GetLayerCount();
                //for (int i = 0; i < layerCount; i++)
                //{
                //    layer = dsGDB.GetLayerByIndex(i);
                //}
                //方法二
                DataSource dsGDB = Ogr.Open(gdbPath, 0);
                layer = dsGDB.GetLayerByName(tableName);
                string name = layer.GetName();
                SpatialReference sr = layer.GetSpatialRef();

            }
            catch (Exception ex)
            {

            }
            return layer;
        }
        /// 
        /// 获取post数据库图层
        /// 
        /// 连接信息
        /// 模式名
        /// 图层名
        /// 
        public static Layer GetPostLayer(string connPost, string schema, string tableName)
        {
            //string connPost = string.Format("PG:dbname={0} host={1} port={2} user={3} password={4}", dbname,host, port, user, password);
            //InitinalGdal();
            Layer layer = null;
            try
            {
                DataSource dsPost = Ogr.Open(connPost, 0);
                layer = dsPost.GetLayerByName(schema + "." + tableName);
                SpatialReference sr = layer.GetSpatialRef();
            }
            catch (Exception ex)
            {

            }
            return layer;
        }

03创建矢量数据 

        public static void CreatSHP(string shpPath, string tableName)
        {
            try
            {
                //InitinalGdal();
                Driver drv = Ogr.GetDriverByName("ESRI Shapefile");
                DataSource ds = drv.CreateDataSource(shpPath, new string[] { });

                //设置坐标系
                SpatialReference sr = new SpatialReference("");
                sr.ImportFromEPSG(4490);

                //创建点图层
                Layer layer = ds.CreateLayer(tableName, sr, wkbGeometryType.wkbPoint, new string[] { });

                //创建字段
                FieldDefn fdefn = new FieldDefn("Name", FieldType.OFTString);
                fdefn.SetWidth(32);
                if (layer.CreateField(fdefn, 1) != 0)
                {
                    Console.WriteLine("创建字段失败");
                    System.Environment.Exit(-1);
                }
                fdefn = new FieldDefn("IntField", FieldType.OFTInteger);
                if (layer.CreateField(fdefn, 1) != 0)
                {
                    Console.WriteLine("创建字段失败");
                    System.Environment.Exit(-1);
                }

                fdefn = new FieldDefn("DubleField", FieldType.OFTReal);
                if (layer.CreateField(fdefn, 1) != 0)
                {
                    Console.WriteLine("创建字段失败");
                    System.Environment.Exit(-1);
                }

                fdefn = new FieldDefn("DateField", FieldType.OFTDate);
                if (layer.CreateField(fdefn, 1) != 0)
                {
                    Console.WriteLine("创建字段失败");
                    System.Environment.Exit(-1);
                }

                //创建要素
                Feature feature = new Feature(layer.GetLayerDefn());
                feature.SetField("Name", "value");
                feature.SetField("IntField", (int)123);
                feature.SetField("DubleField", (double)12.345);
                feature.SetField("DateField", 2007, 3, 15, 18, 24, 30, 0);

                //设置几何图形
                //POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))
                //MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),((6 3,9 2,9 4,6 3)))
                //LINESTRING(3 4,10 50,20 25)
                //MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4))
                Geometry geom = Geometry.CreateFromWkt("POINT(47.0 19.2)");
                if (feature.SetGeometry(geom) != 0)
                {
                    Console.WriteLine("feature添加图形失败");
                    System.Environment.Exit(-1);
                }

                if (layer.CreateFeature(feature) != 0)
                {
                    Console.WriteLine("shapefile创建要素失败");
                    System.Environment.Exit(-1);
                }
                feature.Dispose();
                ds.Dispose();
                drv.Dispose();
            }
            catch (System.Exception ex)
            {

            }
        }
        GDAL 2.0 对gdb和mdb的支持
        创建gdb;GDAL对gdb文件只支持读取,不支持写入
        依赖于ESRI FileGDBAPI我们可以实现对gdb数据的读取
        下载编译好的gdal后可以在bin\gdal\plugins-external目录下找到ogr_FileGDB.dll,这是以插件形式将FileGDBAPI进行了整合编译。使gdal支持gdb数据读写需要以下几个步骤: 
          1、将该dll放置在与gdal20X.dll同级目录下新建的gdalplugins文件夹下
          2、从https://github.com/Esri/file-geodatabase-api/tree/master/FileGDB_API_1.4下载得到对应该编译版本的FileGDBAPI.dll,放置在gdal20X.dll同级目录。
          3、驱动名称由OpenFileGDB改为FileGDB
        public static void CreatGDB(string gdbPath,Layer pgLayer )
        {
            //依据图层创建gdb
            InitinalGdal();
            string tableName = pgLayer.GetName();
            //获取gdb驱动
            String gdbDriverName = "FileGDB";//OpenFileGDB
            Driver gdbDriver = Ogr.GetDriverByName(gdbDriverName);
            if (gdbDriver == null)
            {
                Console.WriteLine("不支持" + gdbDriverName + "驱动");
                return;
            }
            DataSource gdbDataSource = null;
            if (!Directory.Exists(gdbPath))
                gdbDataSource = gdbDriver.CreateDataSource(gdbPath, null);
            else
                gdbDataSource = gdbDriver.Open(gdbPath, 1);

            //创建图层
            Layer gdbLayer = gdbDataSource.CreateLayer(pgLayer.GetName(), pgLayer.GetSpatialRef(), pgLayer.GetGeomType(), null);
            if (gdbLayer == null)
            {
                Console.WriteLine("GDB创建图层失败");
                return;
            }
            //字段
            List listField = new List();
            FeatureDefn pgDefn = pgLayer.GetLayerDefn();
            int iFieldCount = pgDefn.GetFieldCount();
            for (int i = 0; i < iFieldCount; i++)
            {
                FieldDefn oField = pgDefn.GetFieldDefn(i);
                string name = oField.GetName();

                listField.Add(name);
                int tt = gdbLayer.CreateField(oField, 1);
            }

            //数据记录
            gdbDataSource.StartTransaction(1);
            Feature oFeature = null;
            Feature pFeature = null;
            int iFecCount = Convert.ToInt32(pgLayer.GetFeatureCount(0));
            int index = 0;
            if (iFecCount == 0)
                return;

            while ((oFeature = pgLayer.GetNextFeature()) != null)
            {
                index++;

                pFeature = new Feature(pgDefn);
                pFeature.SetGeometry(oFeature.GetGeometryRef());
                for (int iAttr = 0; iAttr < iFieldCount; iAttr++)
                {
                    FieldDefn oField = pgDefn.GetFieldDefn(iAttr);
                    //string fieldName = oField.GetName();
                    string val = "";
                    try
                    {
                        val = oFeature.GetFieldAsString(iAttr);
                        if (!Regex.IsMatch(val, @"^[+-]?\d*[.]?\d*$"))//数字不处理
                            val = GetRightString.getRightStr(oFeature, iAttr, "GDB");//如果layer是根据SQL获取则  iAttr+1
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                    string fieldTypr = oField.GetFieldType().ToString();
                    switch (fieldTypr)
                    {
                        case "OFTString":
                        case "OFTStringList":
                        case "OFTWideString":
                        case "OFTWideStringList":
                        case "OFTBinary":
                        case "OFTDate":
                        case "OFTDateTime":
                        case "OFTTime":
                            pFeature.SetField(iAttr, val); ;
                            break;
                        case "OFTInteger":
                        case "OFTIntegerList":
                        case "OFTInteger64":
                        case "OFTInteger64List":
                            int saveIntValue = 0;
                            if (int.TryParse(val, out saveIntValue))
                            {
                                pFeature.SetField(iAttr, saveIntValue);
                            }
                            break;
                        case "OFTReal":
                        case "OFTRealList":
                            double saveDoubleValue = 0;
                            if (double.TryParse(val, out saveDoubleValue))
                            {
                                pFeature.SetField(iAttr, saveDoubleValue);
                            }
                            break;
                    }
                }
                gdbLayer.CreateFeature(pFeature);
            }

            pFeature.Dispose();
            gdbDataSource.CommitTransaction();
            //写入文件
            gdbLayer.SyncToDisk();
            gdbDataSource.SyncToDisk();

            gdbLayer.Dispose();
            gdbDataSource.Dispose();
            pgLayer.Dispose();
        }

04获取图层、字段、要素属性信息

 

        public static void ReportLayer(Layer layer)
        {
            FeatureDefn def = layer.GetLayerDefn();
            Console.WriteLine("Layer name: " + def.GetName());
            Console.WriteLine("Feature Count: " + layer.GetFeatureCount(1));
            Envelope ext = new Envelope();
            layer.GetExtent(ext, 1);
            Console.WriteLine("Extent: " + ext.MinX + "," + ext.MaxX + "," +
                    ext.MinY + "," + ext.MaxY);

            OSGeo.OSR.SpatialReference sr = layer.GetSpatialRef();
            string srs_wkt;
            if (sr != null)
            {
                sr.ExportToPrettyWkt(out srs_wkt, 1);
            }
            else
                srs_wkt = "(unknown)";

            Console.WriteLine("Layer SRS WKT: " + srs_wkt);

            //获取字段信息
            Console.WriteLine("Field definition:");
            for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++)
            {
                FieldDefn fdef = def.GetFieldDefn(iAttr);

                Console.WriteLine(fdef.GetNameRef() + ": " +
                        fdef.GetFieldTypeName(fdef.GetFieldType()) + " (" +
                        fdef.GetWidth() + "." +
                        fdef.GetPrecision() + ")");
            }

            Feature feat;
            while ((feat = layer.GetNextFeature()) != null)
            {
                ReportFeature(feat, def);
                feat.Dispose();
            }
        }

        public static void ReportFeature(Feature feat, FeatureDefn def)
        {
            //def = feat.GetDefnRef();
            //def = layer.GetLayerDefn();
            Console.WriteLine("Feature(" + def.GetName() + "): " + feat.GetFID());
            for (int iField = 0; iField < feat.GetFieldCount(); iField++)
            {
                FieldDefn fdef = def.GetFieldDefn(iField);

                Console.Write(fdef.GetNameRef() + " (" +
                        fdef.GetFieldTypeName(fdef.GetFieldType()) + ") = ");

                if (feat.IsFieldSet(iField))
                    Console.WriteLine(feat.GetFieldAsString(iField));
                else
                    Console.WriteLine("(null)");

            }

            if (feat.GetStyleString() != null)
                Console.WriteLine("  Style = " + feat.GetStyleString());

            Geometry geom = feat.GetGeometryRef();
            if (geom != null)
                Console.WriteLine("  " + geom.GetGeometryName() +
                   "(" + geom.GetGeometryType() + ")");

            Envelope env = new Envelope();
            geom.GetEnvelope(env);
            Console.WriteLine("   ENVELOPE: " + env.MinX + "," + env.MaxX + "," +
                    env.MinY + "," + env.MaxY);

            string geom_wkt;
            geom.ExportToWkt(out geom_wkt);
            Console.WriteLine("  " + geom_wkt);
        }

05不同数据源读取要素属性时中文存在不同程度乱码,需要获取重新字符串信息 

    /// 
    /// 中文字段值特殊处理类
    /// 
    public static class GetRightString
    {
        [DllImport("gdal202.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]
        public extern static System.IntPtr OGR_F_GetFieldAsString(HandleRef handle, int i);

        [DllImport("gdal202.dll", EntryPoint = "CPLStrnlen", CallingConvention = CallingConvention.Cdecl)]
        public extern static uint CPLStrnlen(IntPtr handle, uint nMaxLen);

        public static String getRightStr(Feature fe, int index, string workspaceType)
        {
            IntPtr pchar = OGR_F_GetFieldAsString(OSGeo.OGR.Feature.getCPtr(fe), index);

            //if (workspaceType == "SHP" )非UTF8编码
            //{
            //    String str = Marshal.PtrToStringAnsi(pchar);
            //    return str;
            //}
            if (workspaceType == "SHP")//UTF8编码
            {
                int length = (int)CPLStrnlen(pchar, uint.MaxValue);
                byte[] strbuf = new byte[length];
                Marshal.Copy(pchar, strbuf, 0, length);
                string utf8String = System.Text.Encoding.UTF8.GetString(strbuf);
                return utf8String;
            }
            else if (workspaceType == "GDB")
            {
                int length = (int)CPLStrnlen(pchar, uint.MaxValue);
                byte[] strbuf = new byte[length];
                Marshal.Copy(pchar, strbuf, 0, length);
                string utf8String = System.Text.Encoding.UTF8.GetString(strbuf);
                return utf8String;
            }
            else
            {
                return fe.GetFieldAsString(index);
            }
        }

        [DllImport("gdal204.dll", EntryPoint = "OGR_F_SetFieldString", CallingConvention = CallingConvention.Cdecl)]
        public extern static void OGR_F_SetFieldString(HandleRef handle, int index, string val);

        public static void setFieldString(Feature fe, int index, string val, string workspaceType)
        {
            if (workspaceType == "SHP")
            {
                OGR_F_SetFieldString(OSGeo.OGR.Feature.getCPtr(fe), index, val);
            }
            else
            {
                fe.SetField(index, val);
            }
        }
    }

 

 

 

 

 

 

 

 

你可能感兴趣的:(GDAL,gdal,矢量数据操作)