采用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中加载效果如下:多个点可采取循环遍历的方式实现。
转载于:https://www.cnblogs.com/FSDI-Nick/p/5169197.html