0.概述
由于需要进行一些Shapefile文件的读取和管理,但是ArcGIS的二次开发工具又看起来过于臃肿,所以尝试学习GDAL完成上面的工作,由于刚刚接触,目前对这个库的了解还少之又少,先贴出官网,便于以后直接查看。GDAL-Java包官方文档。
至于为什么是Java包,因为官网根本没有C#的相关文档啊,如下图,因为Java跟C#确实很像,所以基本可以套用,但是有部分函数不同,用到的时候再看吧
本教程中介绍了GDAL的环境配置,OGR一些类的作用,以及用基础理论实现的一个小程序,程序功能还不完善,但是对于学习很有帮助,界面如下(中文乱码问题还未解决)。
1.环境配置
使用的开发软件是Visual Studio 2015,高版本肯定也是可以的。
- 网上的描述来看安装GDAL的方法主要有几种,一种下载官网编译好的DLL文件,一种自己编译源码,还有就是我用的最简单的在VS的NuGet中安装。
- 官网提供的方法如下(我用的就是第三种):
因为另外两种比较复杂,容易出错,所以就用最简单的方法进行下面的教程吧。
- 新建一个窗体程序或控制台程序。
- 找到NuGet工具,准备下载GDAL
- 下载GDAL和GDALNative
稍等片刻,GDAL就安装好了,之后程序里面会多出来这么几个东西,如下:
#安装之后并不能直接用,需要进行注册工作。实际上很简单,就是在使用前加几行代码,代码是这样的,如果是控制台程序,这段代码放在Main函数里面,如果是窗体程序放在构造函数里面就可以了:
GdalConfiguration.ConfigureGdal();
GdalConfiguration.ConfigureOgr();
OSGeo.GDAL.Gdal.AllRegister();
OSGeo.OGR.Ogr.RegisterAll();
另外使用之前可以可以引用这三个命名空间,用不着可以不加,
using OSGeo.OGR;
using OSGeo.OSR;
using OSGeo.GDAL;
至于上面三个命名空间的含义,相信看了下面JavaAPI的介绍就会有所了解
完成上面的步骤,就可以愉快的使用GDAL和OGR了
2.类库介绍
由于刚刚开始学,也只做了矢量数据的处理,因此下面的介绍只针对OGR,也就是矢量数据处理。
先看Java官方的介绍,标红的几个是我目前接触的:
用一个图介绍他们的含义,相信看了这个图,大多数人都会知道它的结构,实际上Layer跟C#的DataTable有点像,但是它多了几何对象Geometry。
还有一个Driver没有介绍,它是一个用来处理数据的工具,有很多种类,大概下面这些吧,目前我只接触了标黄的两个,好像都是数据格式。:
第一列 | 第二列 | 第三列 |
---|---|---|
ESRI Shapefile | GMT | GPSBabel |
MapInfo File | SQLite | SUA |
UK .NTF | ODBC | OpenAir |
SDTS | PGeo | PDS |
TIGER | MSSQLSpatial | WFS |
S57 | PostgreSQL | HTF |
DGN | MySQL | AeronavFAA |
VRT | PCIDSK | Geomedia |
REC | XPlane | EDIGEO |
Memory | AVCBin | GFT |
BNA | AVCE00 | SVG |
CSV | DXF | CouchDB |
NAS | Geoconcept | Idrisi |
GML | GeoRSS | ARCGEN |
GPX | GPSTrackMaker | SEGUKOOA |
KML | VFK | SEGY |
GeoJSON | PGDump |
3.代码实践
下面搭建一个简单的窗体程序,读取一下shpfile文件的属性表
- 在刚才搭建好的环境中使用工具箱搭建下面的界面,然后下面介绍各个函数,拼起来就是整个程序
2.文件目录读取,比较简单不再过多介绍,主要是为了获取一个路径pFullPath
try
{
OpenFileDialog pOpenFileDialog = new OpenFileDialog();
pOpenFileDialog.CheckFileExists = true;
pOpenFileDialog.Title = "打开Shape文件";
pOpenFileDialog.Filter = "Shape文件(*.shp)|*.shp";
pOpenFileDialog.ShowDialog();
pFullPath = pOpenFileDialog.FileName;
}
catch { MessageBox.Show("文件打开失败!");return; }
- 数据加载,
//输入一个文件目录,然后把数据读取到dataGridView1里面
private void loadShapfile(string filename)
{
DataSource ds = Ogr.Open(filename, 1);
textBox1.Text += "图层个数:" + ds.GetLayerCount().ToString() + "\n";
//下面这句可以看GDAL里面的Driver的名字,十分实用,不过这个程序暂时用不着
for (int i = 0; i < Ogr.GetDriverCount(); i++)
{
//textBox1.Text += Ogr.GetDriver(i).GetName()+"\n";
}
//从DataSource里面读取Layer,一般一个Shapefile只有一个Layer,但是其他数据源就不一定了
for (int i = 0; i < ds.GetLayerCount(); i++)
{
//获取各个Layer的信息
layer = ds.GetLayerByIndex(i);
textBox1.Text += "图层:" + (i + 1).ToString() + "\n";
textBox1.Text += "图层名称:" + layer.GetName() + "\n";
textBox1.Text += "图斑个数:" + layer.GetFeatureCount(1).ToString() + "\n";
FeatureDefn pFeatureDefn = layer.GetLayerDefn();
//新建一个DataTable,用来存储Layer里面的属性数据
DataTable pFeatDT = new DataTable(); //创建数据表
DataRow pDataRow = null; //数据表行变量
DataColumn pDataCol = null; //数据表列变量
//下面的for循环根据Layer来创建DataTable的·各个字段
for (int j = 0; j < pFeatureDefn.GetFieldCount(); j++)
{
pDataCol = new DataColumn();
FieldDefn fie = pFeatureDefn.GetFieldDefn(j);
pDataCol.ColumnName = chageCode(fie.GetName());
pDataCol.DataType = Type.GetType("System.Object");
pFeatDT.Columns.Add(pDataCol);
}
//读取每个字段的值,并写入
for (int j = 0; j < layer.GetFeatureCount(1); j++)
{
pDataRow = pFeatDT.NewRow();
Feature feature = layer.GetFeature(j);
for (int k = 0; k < pFeatDT.Columns.Count; k++)
{
pDataRow[k] = chageCode(feature.GetFieldAsString(k));
}
pFeatDT.Rows.Add(pDataRow);
}
//设置dataGridView的数据源
dataGridView1.DataSource = pFeatDT;
}
}
- 数据修改
//这个函数输入的是操作类型,包括更新,删除,复制三种
public void operate(string type)
{
if (type.Equals("update", StringComparison.InvariantCultureIgnoreCase))
{
Feature feature = layer.GetFeature(int.Parse(numericUpDown3.Value.ToString()));
if (feature != null)
{
//更新操作关键代码,输入列号和要修改的值
feature.SetField(int.Parse(numericUpDown5.Value.ToString()), textBox2.Text);
layer.SetFeature(feature);
}
else
Console.WriteLine("feature not found");
}
else if (type.Equals("copy", StringComparison.InvariantCultureIgnoreCase))
{
Feature feature = layer.GetFeature(int.Parse(numericUpDown3.Value.ToString()));
if (feature != null)
{
//修改一个feature的FID之后,把它重新插入进去,完成复制操作
feature.SetFID(int.Parse(numericUpDown5.Value.ToString()));
layer.SetFeature(feature);
}
else
Console.WriteLine("feature not found");
}
else if (type.Equals("delete", StringComparison.InvariantCultureIgnoreCase))
{
if (layer.TestCapability("DeleteFeature"))
{
//删除操作
layer.DeleteFeature(int.Parse(numericUpDown3.Value.ToString()));
}
else
Console.WriteLine("DeleteFeature not supported");
}
else
Console.WriteLine("invalid command ");
}
4. 总结
本程序在C#环境下使用GDAL类库完成了Shapefile的读取和属性更新的操作,这只是对于GDAL很简单的一个尝试,GDAL的功能十分强大,有待于继续学习。
本程序还存在一些问题有待完善
- 没有图形界面加载
- 汉字乱码问题有待解决