一直用C++来做,现在也用C#来试一下。
1.主要是C# 版本下载,尽量最新吧!
在这里 http://www.gisinternals.com/sdk/ 下了 适合自己的版本。我下载的是\release-1600-gdal-1-10-mapserver-6-2版本,
把所需要的C#的的dll库,\release-1600-gdal-1-10-mapserver-6-2\bin\gdal\csharp在这里找到。
主要的DLL有8个DLL文件gdal_csharp,gdal_wrap,gdalconst_csharp,gdalconst_wrap,ogr_csharp,ogr_warp,osr_csharp,osr_wrap 拷贝到VS项目的程序文件夹bin中。
当然\release-1600-gdal-1-10-mapserver-6-2\bin 下面的那么多DLL也做好拷贝到你的工程的bin下,因为里面的依赖关系我也分不清。
2. 写了个简单的读取类,名称为GdalRead.cs。当然,要在工程里引用四个含有*-csharp的DLL。
来个截图:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;//using System.IO;using OSGeo.GDAL;using OSGeo.OGR;using OSGeo.OSR;using System.Collections;namespace GdalReadSHP{ ///3. 在program.cs中调用。/// 定义SHP解析类 /// public class ShpRead { /// 保存SHP属性字段 public OSGeo.OGR.Driver oDerive; public Listm_FeildList; private Layer oLayer; public string sCoordiantes; public ShpRead() { m_FeildList = new List (); oLayer = null; sCoordiantes = null; } /// /// 初始化Gdal /// public void InitinalGdal() { // 为了支持中文路径 Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 为了使属性表字段支持中文 Gdal.SetConfigOption("SHAPE_ENCODING", ""); Gdal.AllRegister(); Ogr.RegisterAll(); oDerive = Ogr.GetDriverByName("ESRI Shapefile"); if (oDerive == null) { MessageBox.Show("文件不能打开,请检查"); } } ////// 获取SHP文件的层 /// /// /// ///public bool GetShpLayer(string sfilename) { if (null == sfilename || sfilename.Length <= 3) { oLayer = null; return false; } if (oDerive == null) { MessageBox.Show("文件不能打开,请检查"); } DataSource ds = oDerive.Open(sfilename, 1); if (null == ds) { oLayer = null; return false; } int iPosition = sfilename.LastIndexOf("\\"); string sTempName = sfilename.Substring(iPosition + 1, sfilename.Length - iPosition - 4 - 1); oLayer = ds.GetLayerByName(sTempName); if (oLayer == null) { ds.Dispose(); return false; } return true; } /// /// 获取所有的属性字段 /// ///public bool GetFeilds() { if (null == oLayer) { return false; } m_FeildList.Clear(); wkbGeometryType oTempGeometryType = oLayer.GetGeomType(); List TempstringList = new List (); // FeatureDefn oDefn = oLayer.GetLayerDefn(); int iFieldCount = oDefn.GetFieldCount(); for (int iAttr = 0; iAttr < iFieldCount; iAttr++) { FieldDefn oField = oDefn.GetFieldDefn(iAttr); if (null != oField) { m_FeildList.Add(oField.GetNameRef()); } } return true; } /// /// 获取某条数据的字段内容 /// /// /// ///public bool GetFeildContent(int iIndex, out List FeildStringList) { FeildStringList = new List (); Feature oFeature = null; if ((oFeature = oLayer.GetFeature(iIndex)) != null) { FeatureDefn oDefn = oLayer.GetLayerDefn(); int iFieldCount = oDefn.GetFieldCount(); // 查找字段属性 for (int iAttr = 0; iAttr < iFieldCount; iAttr++) { FieldDefn oField = oDefn.GetFieldDefn(iAttr); string sFeildName = oField.GetNameRef(); #region 获取属性字段 FieldType Ftype = oFeature.GetFieldType(sFeildName); switch (Ftype) { case FieldType.OFTString: string sFValue = oFeature.GetFieldAsString(sFeildName); string sTempType = "string"; FeildStringList.Add(sFValue); break; case FieldType.OFTReal: double dFValue = oFeature.GetFieldAsDouble(sFeildName); sTempType = "float"; FeildStringList.Add(dFValue.ToString()); break; case FieldType.OFTInteger: int iFValue = oFeature.GetFieldAsInteger(sFeildName); sTempType = "int"; FeildStringList.Add(iFValue.ToString()); break; default: //sFValue = oFeature.GetFieldAsString(ChosenFeildIndex[iFeildIndex]); sTempType = "string"; break; } #endregion } } return true; } /// /// 获取数据 /// ///public bool GetGeometry(int iIndex) { if (null == oLayer) { return false; } int iFeatureCout = oLayer.GetFeatureCount(0); Feature oFeature = null; oFeature = oLayer.GetFeature(iIndex); // Geometry Geometry oGeometry = oFeature.GetGeometryRef(); wkbGeometryType oGeometryType = oGeometry.GetGeometryType(); switch (oGeometryType) { case wkbGeometryType.wkbPoint: oGeometry.ExportToWkt(out sCoordiantes); sCoordiantes = sCoordiantes.ToUpper().Replace("POINT (", "").Replace(")", ""); break; case wkbGeometryType.wkbLineString: case wkbGeometryType.wkbLinearRing: oGeometry.ExportToWkt(out sCoordiantes); sCoordiantes = sCoordiantes.ToUpper().Replace("LINESTRING (", "").Replace(")", ""); break; default: break; } return false; } }//END class}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Windows.Forms;using OSGeo.GDAL;using OSGeo.OGR;using OSGeo.OSR;using System.Collections;namespace GdalReadSHP{ class Program { static void Main(string[] args) { string sShpFileName = @"D:\VRMap6_Data\line92\RainMainPipe.shp"; ShpRead m_Shp = new ShpRead(); // 初始化GDAL和OGR m_Shp.InitinalGdal(); // m_Shp.GetShpLayer(sShpFileName); // 获取所有属性字段名称,存放在m_FeildList中 m_Shp.GetFeilds(); ListFeildStringList = null; m_Shp.GetFeildContent(0, out FeildStringList); // 获取某条FID的数据 m_Shp.GetGeometry(0); MessageBox.Show(m_Shp.sCoordiantes); } }}
一开始自己疏忽了,总是报错。最后才发现,自己没初始化GDAL和OGR,我类个去!!
///至于对SHP用C#写,目前咩有用到。/// 初始化Gdal /// public void InitinalGdal() { // 为了支持中文路径 Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); // 为了使属性表字段支持中文 Gdal.SetConfigOption("SHAPE_ENCODING", ""); Gdal.AllRegister(); Ogr.RegisterAll(); oDerive = Ogr.GetDriverByName("ESRI Shapefile"); if (oDerive == null) { MessageBox.Show("文件不能打开,请检查"); } }
说明:
网上好多Gdal支持中文路径说需要:
Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
我试了一下,貌似用YES才行。
// 为了支持中文路径 Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
若中文名称的SHP文件,用GetLayerByName(stirng sName); 我测试是不行的。
需要改为Layer oLayer = ds.GetLayerByIndex(0);
不足之处,多多指点!
源码地址:http://download.csdn.net/detail/cartzhang/5590957
免分下载!