采用GDAL17的C#庫進行shp圖層屬性表讀取和修改操作,C#DLL庫解壓后包含文件如下:
添加引用主要是帶csharp的gdal、ogr、osr三個DLL,程序代碼如下:
using OSGeo.OGR;
using OSGeo.OSR;
using OSGeo.GDAL;
1. 讀取shp圖層操作
public void Reforming(string shpFilePath) { Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); Gdal.SetConfigOption("SHAPE_ENCODING", ""); Ogr.RegisterAll();// 注冊所有的驅動 DataSource ds = Ogr.Open(shpFilePath, 1);//0表示只讀,1表示可修改 if (ds == null) { MessageBox.Show("打開文件【{0}】失敗!", shpFilePath); return; } // 獲取第一個圖層 int iLayerCount = ds.GetLayerCount(); Layer oLayer = ds.GetLayerByIndex(0); if (oLayer == null) { MessageBox.Show("獲取第{0}個圖層失敗! n", "0"); return; } fieldList = GetFieldList(oLayer);//獲取圖層屬性表字段列表 int featureCount = oLayer.GetFeatureCount(0); //B1.判斷字段是否存在 #region shp屬性表 { if (!fieldList.Contains("LL_YAW")) { FieldDefn oFieldYaw = new FieldDefn("LL_YAW", FieldType.OFTReal); oFieldYaw.SetWidth(10); oFieldYaw.SetPrecision(8); oLayer.CreateField(oFieldYaw, 1); } if (!fieldList.Contains("LL_ScaleX")) { FieldDefn oFieldYaw = new FieldDefn("LL_ScaleX", FieldType.OFTReal); oFieldYaw.SetWidth(10); oFieldYaw.SetPrecision(8); oLayer.CreateField(oFieldYaw, 1); } if (!fieldList.Contains("LL_ScaleY")) { FieldDefn oFieldYaw = new FieldDefn("LL_ScaleY", FieldType.OFTReal); oFieldYaw.SetWidth(10); oFieldYaw.SetPrecision(8); oLayer.CreateField(oFieldYaw, 1); } } #endregion //輸出屬性表字段的詳細信息,數據類型、寬度、精度等 FeatureDefn oDefn1 = oLayer.GetLayerDefn(); int FieldCount1 = oDefn1.GetFieldCount(); string headerInfo = string.Empty; { for (int i = 0; i < FieldCount1; i++) { FieldDefn oField = oDefn.GetFieldDefn(i); headerInfo += String.Format("{0}:{1} {2} {3}", oField.GetNameRef(), oField.GetFieldTypeName(oField.GetFieldType()), oField.GetWidth(), oField.GetPrecision()); headerInfo += Environment.NewLine; } } MessageBox.Show(headerInfo); Feature oFeature = null; while ((oFeature = oLayer.GetNextFeature()) != null) { string name = oFeature.GetFieldAsString(0); double x = oFeature.GetFieldAsDouble(1); double y = oFeature.GetFieldAsDouble(2); double z = oFeature.GetFieldAsDouble(3); //B3.給新增加的字段賦值 oFeature.SetField(7, x); oFeature.SetField(8, y); oFeature.SetField(9, z); oLayer.SetFeature(oFeature);//保存記錄 } oLayer.Dispose(); ds.Dispose();//關閉數據集 } private List<string> GetFieldList(Layer mLayer) { List<string> newFieldList = new List<string>(); FeatureDefn oDefn = mLayer.GetLayerDefn(); int FieldCount = oDefn.GetFieldCount(); for (int i = 0; i < FieldCount; i++) { FieldDefn oField = oDefn.GetFieldDefn(i); string fieldName = oField.GetNameRef(); newFieldList.Add(fieldName); } return newFieldList; } }
需要創建或獲取shp圖層的Spatial Reference空間參考坐標系WKT時,代碼如下:
OSGeo.OSR.SpatialReference siref = oLayer.GetSpatialRef();
siref.ExportToWkt(out layerCSWKT);
siref.ImportFromWkt(ref layerCSWKT);
2.創建shp圖層,並將點的坐標值寫入屬性表代碼如下:
private void button2_Click(object sender, EventArgs e) { OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); // 為了使屬性表字段支持中文,請添加下面這句 OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", ""); string strVectorFile1 = @"C:\Users\DZY\Desktop\test6"; Ogr.RegisterAll(); string strDriver = "ESRI Shapefile"; Driver oDriver = Ogr.GetDriverByName(strDriver); if (oDriver == null) { MessageBox.Show(" 驅動不可用!\n", strVectorFile1); return; } DataSource ds1 = oDriver.CreateDataSource(strVectorFile1,null); if (ds1 == null) { MessageBox.Show("創建矢量文件【%s】失敗!\n", strVectorFile1); return; } string wkt = "…";//自定義投影坐標系的WKT OSGeo.OSR.SpatialReference sr = new OSGeo.OSR.SpatialReference(wkt); Layer olayer1 = ds1.CreateLayer("PointLayer",sr,wkbGeometryType.wkbPoint,null); //接下來創建屬性表字段 // 先創建一個叫FieldID的整型屬性 FieldDefn oFieldID = new FieldDefn("FieldID", FieldType.OFTInteger); olayer1.CreateField(oFieldID, 1); // 再創建一個叫FeatureName的字符型屬性,字符長度為50 FieldDefn oFieldName = new FieldDefn("FieldName", FieldType.OFTString); oFieldName.SetWidth(50); olayer1.CreateField(oFieldName, 1); //創建x坐標字段 FieldDefn oFieldX = new FieldDefn("x", FieldType.OFTReal); oFieldX.SetWidth(10); oFieldX.SetPrecision(8); olayer1.CreateField(oFieldX, 1); //創建y坐標字段 FieldDefn oFieldY = new FieldDefn("y", FieldType.OFTReal); oFieldY.SetWidth(10); oFieldY.SetPrecision(8); olayer1.CreateField(oFieldY, 1); //創建z坐標字段 FieldDefn oFieldZ= new FieldDefn("z", FieldType.OFTReal); oFieldZ.SetWidth(10); oFieldZ.SetPrecision(8); olayer1.CreateField(oFieldZ, 1); //寫入第一條數據 FeatureDefn oDefn = olayer1.GetLayerDefn(); Feature oFeature = new Feature(oDefn); oFeature.SetField(0, 0); oFeature.SetField(1, "Point1"); oFeature.SetField(2, 489592.624); oFeature.SetField(3, 3804367.891); oFeature.SetField(4, 386.3); Geometry geoPoint = new Geometry(OSGeo.OGR.wkbGeometryType.wkbPoint); geoPoint.AddPoint(489592.624, 3804367.891, 386.3); oFeature.SetGeometry(geoPoint); olayer1.CreateFeature(oFeature); //寫入第二條數據 Feature oFeature1 = new Feature(oDefn); oFeature1.SetField(0, 1); oFeature1.SetField(1, "Point2"); oFeature1.SetField(2, 489602.624); oFeature1.SetField(3, 3804367.891); oFeature1.SetField(4, 389.3); geoPoint.AddPoint(489602.624, 3804367.891, 389.3); oFeature1.SetGeometry(geoPoint); olayer1.CreateFeature(oFeature1); oFeature1.Dispose(); olayer1.Dispose(); ds1.Dispose(); MessageBox.Show("shp圖層創建完成!"); }
ArcMap中加載效果如下:多個點可采取循環遍歷的方式實現。