在C#中使用OGR读写矢量数据时,需要引用“using OSGeo.OGR;”。同时为了处理中文路径和中文字段,需要在开始设置下面两个属性,代码如下:
//为了支持中文路径,请添加下面这句代码(大多数情况下不需要这句) //OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //为了使属性表字段支持中文,请添加下面这句 OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING","");
1.读取矢量
读取矢量代码如下,处理的结果如图1所示。设置了按属性过滤后处理结果如图2所示。
static void ReadVectorFile() { // 为了支持中文路径,请添加下面这句代码 OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); // 为了使属性表字段支持中文,请添加下面这句 OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING",""); string strVectorFile ="E:\\Datum\\GDALCsTest\\Debug\\beijing.shp"; // 注册所有的驱动 Ogr.RegisterAll(); //打开数据 DataSource ds = Ogr.Open(strVectorFile,0); if( ds == null ) { Console.WriteLine( "打开文件【{0}】失败!", strVectorFile ); return; } Console.WriteLine( "打开文件【{0}】成功!", strVectorFile ); // 获取该数据源中的图层个数,一般shp数据图层只有一个,如果是mdb、dxf等图层就会有多个 int iLayerCount = ds.GetLayerCount(); // 获取第一个图层 Layer oLayer = ds.GetLayerByIndex( 0 ); if( oLayer == null ) { Console.WriteLine( "获取第{0}个图层失败!\n", 0 ); return; } // 对图层进行初始化,如果对图层进行了过滤操作,执行这句后,之前的过滤全部清空 oLayer.ResetReading(); // 通过属性表的SQL语句对图层中的要素进行筛选,这部分详细参考SQL查询章节内容 oLayer.SetAttributeFilter("\"NAME99\"LIKE \"北京市市辖区\""); // 通过指定的几何对象对图层中的要素进行筛选 //oLayer.SetSpatialFilter(); // 通过指定的四至范围对图层中的要素进行筛选 //oLayer.SetSpatialFilterRect(); // 获取图层中的属性表表头并输出 Console.WriteLine( "属性表结构信息:"); FeatureDefn oDefn = oLayer.GetLayerDefn(); int iFieldCount =oDefn.GetFieldCount(); for( int iAttr = 0; iAttr <iFieldCount; iAttr++ ) { FieldDefn oField =oDefn.GetFieldDefn( iAttr ); Console.WriteLine( "{0}:{1} ({2}.{3})", oField.GetNameRef(), oField.GetFieldTypeName(oField.GetFieldType()), oField.GetWidth(),oField.GetPrecision() ); } // 输出图层中的要素个数 Console.WriteLine( "要素个数 = {0}", oLayer.GetFeatureCount(0) ); Feature oFeature = null; // 下面开始遍历图层中的要素 while( (oFeature =oLayer.GetNextFeature()) != null ) { Console.WriteLine("当前处理第{0}个: \n属性值:" ,oFeature.GetFID()); // 获取要素中的属性表内容 for (int iField = 0;iField<iFieldCount; iField++) { FieldDefn oFieldDefn= oDefn.GetFieldDefn(iField); FieldType type =oFieldDefn.GetFieldType(); switch (type) { caseFieldType.OFTString: Console.WriteLine("{0}\t",oFeature.GetFieldAsString(iField)); break; caseFieldType.OFTReal: Console.WriteLine("{0}\t",oFeature.GetFieldAsDouble(iField)); break; caseFieldType.OFTInteger: Console.WriteLine("{0}\t",oFeature.GetFieldAsInteger(iField)); break; default: Console.WriteLine("{0}\t",oFeature.GetFieldAsString(iField)); break; } } // 获取要素中的几何体 Geometry oGeometry =oFeature.GetGeometryRef(); // 为了演示,只输出一个要素信息 break; } Console.WriteLine( "数据集关闭!" ); }
tu图1 OGR库使用C#读取矢量示例1
图2 OGR库使用C#读取矢量示例2
2.写入矢量
在使用C#创建矢量图形的时候,使用的WKT格式的字符串来进行创建。也可以使用其他的方式进行创建。代码如下,写出来的矢量图形和属性表如图3所示。
static void WriteVectorFile() { // 为了支持中文路径,请添加下面这句代码 OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); // 为了使属性表字段支持中文,请添加下面这句 OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING",""); string strVectorFile ="E:\\Datum\\GDALCsTest\\Debug\\TestPolygon.shp"; // 注册所有的驱动 Ogr.RegisterAll(); //创建数据,这里以创建ESRI的shp文件为例 string strDriverName = "ESRIShapefile"; Driver oDriver =Ogr.GetDriverByName(strDriverName); if (oDriver == null) { Console.WriteLine("%s 驱动不可用!\n", strVectorFile); return; } // 创建数据源 DataSource oDS =oDriver.CreateDataSource(strVectorFile, null); if (oDS == null) { Console.WriteLine("创建矢量文件【%s】失败!\n", strVectorFile); return; } // 创建图层,创建一个多边形图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定 Layer oLayer =oDS.CreateLayer("TestPolygon", null, wkbGeometryType.wkbPolygon,null); if (oLayer == null) { Console.WriteLine("图层创建失败!\n"); return; } // 下面创建属性表 // 先创建一个叫FieldID的整型属性 FieldDefn oFieldID = newFieldDefn("FieldID", FieldType.OFTInteger); oLayer.CreateField(oFieldID, 1); // 再创建一个叫FeatureName的字符型属性,字符长度为50 FieldDefn oFieldName = newFieldDefn("FieldName", FieldType.OFTString); oFieldName.SetWidth(100); oLayer.CreateField(oFieldName, 1); FeatureDefn oDefn =oLayer.GetLayerDefn(); // 创建三角形要素 Feature oFeatureTriangle = newFeature(oDefn); oFeatureTriangle.SetField(0, 0); oFeatureTriangle.SetField(1, "三角形"); Geometry geomTriangle =Geometry.CreateFromWkt("POLYGON ((0 0,20 0,10 15,0 0))"); oFeatureTriangle.SetGeometry(geomTriangle); oLayer.CreateFeature(oFeatureTriangle); // 创建矩形要素 Feature oFeatureRectangle = newFeature(oDefn); oFeatureRectangle.SetField(0, 1); oFeatureRectangle.SetField(1, "矩形"); Geometry geomRectangle =Geometry.CreateFromWkt("POLYGON ((30 0,60 0,60 30,30 30,30 0))"); oFeatureRectangle.SetGeometry(geomRectangle); oLayer.CreateFeature(oFeatureRectangle); // 创建五角形要素 Feature oFeaturePentagon = newFeature(oDefn); oFeaturePentagon.SetField(0, 2); oFeaturePentagon.SetField(1, "五角形"); Geometry geomPentagon =Geometry.CreateFromWkt("POLYGON ((70 0,85 0,90 15,80 30,65 15,700))"); oFeaturePentagon.SetGeometry(geomPentagon); oLayer.CreateFeature(oFeaturePentagon); Console.WriteLine("\n数据集创建完成!\n"); }
图3 写入的矢量图形
3.矢量数据管理
static void VectorDelete(string strVectorFile) { // 注册所有的驱动 Ogr.RegisterAll(); Driver oDriver = null; { //打开矢量 DataSource oDS =Ogr.Open(strVectorFile, 0); if (oDS == null) { File.Delete(strVectorFile); return; } oDriver = oDS.GetDriver(); if (oDriver == null) { File.Delete(strVectorFile);; return; } } if(oDriver.DeleteDataSource(strVectorFile) == Ogr.OGRERR_NONE) return; else File.Delete(strVectorFile); ; } staticvoid VectorRename(string strOldFile, string strNewFile) { // 注册所有的驱动 Ogr.RegisterAll(); Driver oDriver = null; { //打开矢量 DataSource oDS =Ogr.Open(strOldFile, 0); if (oDS == null) { File.Move(strOldFile,strNewFile); return; } oDriver = oDS.GetDriver(); if (oDriver == null) { File.Move(strOldFile,strNewFile); return; } DataSource oDDS =oDriver.CopyDataSource(oDS, strNewFile, null); if (oDDS == null) { File.Move(strOldFile,strNewFile); return; } } if (oDriver.DeleteDataSource(strOldFile)== Ogr.OGRERR_NONE) return; else File.Move(strOldFile,strNewFile); }