首先创建一个Windows窗体应用程序,然后拖几个按钮和文本框,如下图所示。第一行用来显示栅格数据的路径,点击浏览找到一个栅格文件,将路径显示在文本框中,然后点击读取,将图像的基本信息显示在最下方的富文本框中;第二行的类似,显示的是矢量数据的信息。
1、添加GDALC#版本的引用,注意只添加后面是_csharp.dll的四个文件。如下图所示。
2、添加浏览按钮的事件,代码如下:
private void buttonRaster_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "打开栅格文件"; ofd.Filter = @"Erdas Imagine (*.img)|*.img| GeoTiff (*.tif *.tiff)|*.tif *.tiff| PCIDSK (*.pix)|*.pix| EarthWatch/DigitalGlobe (*.til)|*.til| HDF (*.hdf *.h5 *he5)|*.hdf *.h5 *he5| NITF (*.ntf *.nsf)|*.ntf *.nsf| Spot DIMAP (metadata.dim)|metadata.dim| 位图文件 (*.bmp)|*.bmp| Graphics Interchange Format (*.gif)|*.gif| JPEG (*.jpg *.jpeg)|*.jpg *.jpeg| Portable Network Graphics (*.png)|*.png| Web Map Servers (*.xml)|*.xml|所有文件|*.*"; ofd.ShowDialog(); textBoxRaster.Text = ofd.FileName; } private void buttonVector_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "打开矢量文件"; ofd.Filter = @"ESRI Shapefile(*.shp)|*.shp| MapInfo File(*.mid *.mif *.tab)|*.mid *.mif *tab| Arc/Info .E00 (*.e00)|*.e00| AutoCAD DXF(*.dxf)|*.dxf| Comma Separated Value (.csv)|*.csv| GML(*.gml)|*.gml| KML(*.kml)|*.kml| 所有文件|*.*"; ofd.ShowDialog(); textBoxVector.Text = ofd.FileName; }
3、添加读取栅格和矢量数据信息的代码,分别存在GDALReadFile.cs和OGRReadFile.cs文件中。具体代码见下面:
首先是GDALReadFile.cs
using OSGeo.GDAL; using OSGeo.OSR; using System; namespace GDALTest { /// <summary> /// 使用GDAL读取栅格数据信息类 /// </summary> public class GDALReadFile { public static string GetRasterInfo(string strFilePath) { string strInfomation = ""; try { /* -------------------------------------------------------------------- */ /* Register driver(s). */ /* -------------------------------------------------------------------- */ Gdal.AllRegister(); /* -------------------------------------------------------------------- */ /* Open dataset. */ /* -------------------------------------------------------------------- */ Dataset ds = Gdal.Open(strFilePath, Access.GA_ReadOnly); if (ds == null) { strInfomation = ("Can't open " + strFilePath); return strInfomation; } strInfomation += ("Raster dataset parameters:\n"); strInfomation += (" Projection: " + ds.GetProjectionRef() + "\n"); strInfomation += (" RasterCount: " + ds.RasterCount.ToString() + "\n"); strInfomation += (" RasterSize (" + ds.RasterXSize.ToString() + "," + ds.RasterYSize.ToString() + ")" + "\n"); /* -------------------------------------------------------------------- */ /* Get driver */ /* -------------------------------------------------------------------- */ Driver drv = ds.GetDriver(); if (drv == null) { strInfomation += ("Can't get driver."); return strInfomation; } strInfomation += ("Using driver " + drv.LongName); /* -------------------------------------------------------------------- */ /* Get metadata */ /* -------------------------------------------------------------------- */ string[] metadata = ds.GetMetadata(""); if (metadata.Length > 0) { strInfomation += (" Metadata:"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { strInfomation += (" " + iMeta.ToString() + ": " + metadata[iMeta] + "\n"); } strInfomation += ("\n"); } /* -------------------------------------------------------------------- */ /* Report "IMAGE_STRUCTURE" metadata. */ /* -------------------------------------------------------------------- */ metadata = ds.GetMetadata("IMAGE_STRUCTURE"); if (metadata.Length > 0) { strInfomation += (" Image Structure Metadata:" + "\n"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { strInfomation += (" " + iMeta.ToString() + ": " + metadata[iMeta] + "\n"); } strInfomation += ("\n"); } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ metadata = ds.GetMetadata("SUBDATASETS"); if (metadata.Length > 0) { strInfomation += (" Subdatasets:\n"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { strInfomation += (" " + iMeta.ToString() + ": " + metadata[iMeta] + "\n"); } strInfomation += ("\n"); } /* -------------------------------------------------------------------- */ /* Report geolocation. */ /* -------------------------------------------------------------------- */ metadata = ds.GetMetadata("GEOLOCATION"); if (metadata.Length > 0) { strInfomation += (" Geolocation:\n"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { strInfomation += (" " + iMeta.ToString() + ": " + metadata[iMeta] + "\n"); } strInfomation += ("\n"); } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ strInfomation += ("Corner Coordinates:\n"); strInfomation += (" Upper Left (" + GDALInfoGetPosition(ds, 0.0, 0.0) + ")" + "\n"); strInfomation += (" Lower Left (" + GDALInfoGetPosition(ds, 0.0, ds.RasterYSize) + ")" + "\n"); strInfomation += (" Upper Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, 0.0) + ")" + "\n"); strInfomation += (" Lower Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, ds.RasterYSize) + ")" + "\n"); strInfomation += (" Center (" + GDALInfoGetPosition(ds, ds.RasterXSize / 2, ds.RasterYSize / 2) + ")" + "\n"); strInfomation += ("\n"); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ string projection = ds.GetProjectionRef(); if (projection != null) { SpatialReference srs = new SpatialReference(null); if (srs.ImportFromWkt(ref projection) == 0) { string wkt; srs.ExportToPrettyWkt(out wkt, 0); strInfomation += ("Coordinate System is:\n"); strInfomation += (wkt); } else { strInfomation += ("Coordinate System is:\n"); strInfomation += (projection); } } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if (ds.GetGCPCount() > 0) { strInfomation += ("GCP Projection: " + ds.GetGCPProjection() + "\n"); GCP[] GCPs = ds.GetGCPs(); for (int i = 0; i < ds.GetGCPCount(); i++) { strInfomation += ("GCP[" + i.ToString() + "]: Id=" + GCPs[i].Id + ", Info=" + GCPs[i].Info + "\n"); strInfomation += (" (" + GCPs[i].GCPPixel.ToString() + "," + GCPs[i].GCPLine.ToString() + ") -> (" + GCPs[i].GCPX.ToString() + "," + GCPs[i].GCPY.ToString() + "," + GCPs[i].GCPZ.ToString() + ")" + "\n"); strInfomation += (""); } strInfomation += ("\n"); double[] transform = new double[6]; Gdal.GCPsToGeoTransform(GCPs, transform, 0); strInfomation += ("GCP Equivalent geotransformation parameters: " + ds.GetGCPProjection() + "\n"); for (int i = 0; i < 6; i++) strInfomation += ("t[" + i + "] = " + transform[i].ToString() + "\n"); strInfomation += ("\n"); } /* -------------------------------------------------------------------- */ /* Get raster band */ /* -------------------------------------------------------------------- */ for (int iBand = 1; iBand <= ds.RasterCount; iBand++) { Band band = ds.GetRasterBand(iBand); strInfomation += ("Band " + iBand.ToString() + " :\n"); strInfomation += (" DataType: " + Gdal.GetDataTypeName(band.DataType) + "\n"); strInfomation += (" ColorInterpretation: " + Gdal.GetColorInterpretationName(band.GetRasterColorInterpretation()) + "\n"); ColorTable ct = band.GetRasterColorTable(); if (ct != null) strInfomation += (" Band has a color table with " + ct.GetCount().ToString() + " entries.\n"); strInfomation += (" Description: " + band.GetDescription() + "\n"); strInfomation += (" Size (" + band.XSize.ToString() + "," + band.YSize.ToString() + ")" + "\n"); int BlockXSize, BlockYSize; band.GetBlockSize(out BlockXSize, out BlockYSize); strInfomation += (" BlockSize (" + BlockXSize.ToString() + "," + BlockYSize.ToString() + ")" + "\n"); double val; int hasval; band.GetMinimum(out val, out hasval); if (hasval != 0) strInfomation += (" Minimum: " + val.ToString()); band.GetMaximum(out val, out hasval); if (hasval != 0) strInfomation += (" Maximum: " + val.ToString()); band.GetNoDataValue(out val, out hasval); if (hasval != 0) strInfomation += (" NoDataValue: " + val.ToString()); band.GetOffset(out val, out hasval); if (hasval != 0) strInfomation += (" Offset: " + val.ToString()); band.GetScale(out val, out hasval); if (hasval != 0) strInfomation += (" Scale: " + val.ToString()); for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++) { Band over = band.GetOverview(iOver); strInfomation += (" OverView " + iOver + " :" + "\n"); strInfomation += (" DataType: " + over.DataType + "\n"); strInfomation += (" Size (" + over.XSize + "," + over.YSize + ")" + "\n"); strInfomation += (" PaletteInterp: " + over.GetRasterColorInterpretation().ToString() + "\n"); } } } catch (Exception e) { strInfomation += ("Application error: " + e.Message); } return strInfomation; } private static string GDALInfoGetPosition(Dataset ds, double x, double y) { double[] adfGeoTransform = new double[6]; double dfGeoX, dfGeoY; ds.GetGeoTransform(adfGeoTransform); dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y; dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y; return dfGeoX.ToString() + ", " + dfGeoY.ToString(); } } }
接着是OGRReadFile.cs文件:
using OSGeo.OGR; using OSGeo.OSR; using System; /// <summary> /// 使用OGR读取矢量数据信息类 /// </summary> public class OGRReadFile { public static string GetVectorInfo(string strFilePath) { string strInfomation = ""; /* -------------------------------------------------------------------- */ /* Register format(s). */ /* -------------------------------------------------------------------- */ Ogr.RegisterAll(); /* -------------------------------------------------------------------- */ /* Open data source. */ /* -------------------------------------------------------------------- */ DataSource ds = Ogr.Open(strFilePath, 0); if (ds == null) { strInfomation = ("Can't open " + strFilePath); return strInfomation; } /* -------------------------------------------------------------------- */ /* Get driver */ /* -------------------------------------------------------------------- */ Driver drv = ds.GetDriver(); if (drv == null) { strInfomation = ("Can't get driver."); return strInfomation; } // TODO: drv.name is still unsafe with lazy initialization (Bug 1339) strInfomation += ("Using driver " + drv.name); /* -------------------------------------------------------------------- */ /* Iterating through the layers */ /* -------------------------------------------------------------------- */ for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++) { Layer layer = ds.GetLayerByIndex(iLayer); if (layer == null) { strInfomation = ("FAILURE: Couldn't fetch advertised layer " + iLayer); return strInfomation; } strInfomation += ReportLayer(layer); } return strInfomation; } public static string ReportLayer(Layer layer) { string strInfomation = ""; FeatureDefn def = layer.GetLayerDefn(); strInfomation += ("Layer name: " + def.GetName()); strInfomation += ("Feature Count: " + layer.GetFeatureCount(1).ToString()); Envelope ext = new Envelope(); layer.GetExtent(ext, 1); strInfomation += ("Extent: " + ext.MinX.ToString() + "," + ext.MaxX.ToString() + "," + ext.MinY.ToString() + "," + ext.MaxY.ToString()); /* -------------------------------------------------------------------- */ /* Reading the spatial reference */ /* -------------------------------------------------------------------- */ OSGeo.OSR.SpatialReference sr = layer.GetSpatialRef(); string srs_wkt; if (sr != null) { sr.ExportToPrettyWkt(out srs_wkt, 1); } else srs_wkt = "(unknown)"; strInfomation += ("Layer SRS WKT: " + srs_wkt); /* -------------------------------------------------------------------- */ /* Reading the fields */ /* -------------------------------------------------------------------- */ strInfomation += ("Field definition:"); for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++) { FieldDefn fdef = def.GetFieldDefn(iAttr); strInfomation += (fdef.GetNameRef() + ": " + fdef.GetFieldTypeName(fdef.GetFieldType()) + " (" + fdef.GetWidth().ToString() + "." + fdef.GetPrecision().ToString() + ")"); } /* -------------------------------------------------------------------- */ /* Reading the shapes */ /* -------------------------------------------------------------------- */ strInfomation += (""); Feature feat; while ((feat = layer.GetNextFeature()) != null) { strInfomation += ReportFeature(feat, def); feat.Dispose(); } return strInfomation; } public static string ReportFeature(Feature feat, FeatureDefn def) { string strInfomation = ""; strInfomation += ("Feature(" + def.GetName() + "): " + feat.GetFID().ToString()); for (int iField = 0; iField < feat.GetFieldCount(); iField++) { FieldDefn fdef = def.GetFieldDefn(iField); strInfomation += (fdef.GetNameRef() + " (" + fdef.GetFieldTypeName(fdef.GetFieldType()) + ") = "); if (feat.IsFieldSet(iField)) { if (fdef.GetFieldType() == FieldType.OFTStringList) { string[] sList = feat.GetFieldAsStringList(iField); foreach (string s in sList) { strInfomation += ("\"" + s + "\" "); } strInfomation += ("\n"); } else if (fdef.GetFieldType() == FieldType.OFTIntegerList) { int count; int[] iList = feat.GetFieldAsIntegerList(iField, out count); for (int i = 0; i < count; i++) { strInfomation += (iList[i] + " "); } strInfomation += ("\n"); } else if (fdef.GetFieldType() == FieldType.OFTRealList) { int count; double[] iList = feat.GetFieldAsDoubleList(iField, out count); for (int i = 0; i < count; i++) { strInfomation += (iList[i].ToString() + " "); } strInfomation += ("\n"); } else strInfomation += (feat.GetFieldAsString(iField)); } else strInfomation += ("(null)"); } if (feat.GetStyleString() != null) strInfomation += (" Style = " + feat.GetStyleString()); Geometry geom = feat.GetGeometryRef(); if (geom != null) { strInfomation += (" " + geom.GetGeometryName() + "(" + geom.GetGeometryType() + ")"); Geometry sub_geom; for (int i = 0; i < geom.GetGeometryCount(); i++) { sub_geom = geom.GetGeometryRef(i); if (sub_geom != null) { strInfomation += (" subgeom" + i + ": " + sub_geom.GetGeometryName() + "(" + sub_geom.GetGeometryType() + ")"); } } Envelope env = new Envelope(); geom.GetEnvelope(env); strInfomation += (" ENVELOPE: " + env.MinX + "," + env.MaxX + "," + env.MinY + "," + env.MaxY); string geom_wkt; geom.ExportToWkt(out geom_wkt); strInfomation += (" " + geom_wkt); } strInfomation += ("\n"); return strInfomation; } }
4、写完读取代码,然后编写读取按钮的响应事件,具体代码如下:
private void buttonRasterRead_Click(object sender, EventArgs e) { string strRasterPath = textBoxRaster.Text; if (strRasterPath == "") { MessageBox.Show("请先选择文件路径", "提示"); return; } string strInfomation = GDALReadFile.GetRasterInfo(strRasterPath); richTextBoxInfo.Text = strInfomation; } private void buttonVectorRead_Click(object sender, EventArgs e) { string strVectorPath = textBoxVector.Text; if (strVectorPath == "") { MessageBox.Show("请先选择文件路径", "提示"); return; } string strInfomation = OGRReadFile.GetVectorInfo(strVectorPath); richTextBoxInfo.Text = strInfomation; }
5、做完上面的步骤,你就可以编译了,编译很顺利,直接编译过去了(如果你不能编译过去,请查看错误并修改)。然后点击运行,选择一个栅格数据,然后点击读取,期待将图像信息写入下面的富文本框中,结果很悲剧的发现,出现了一个异常。群里很多人都遇到过这个异常,这个异常就是“Application error: “OSGeo.GDAL.GdalPINVOKE”的类型初始值设定项引发异常。”,截图如下:
下面就开始解决这个异常,按照下面的步骤进行解决:
首先:确定自己引用的GDAL库是正常的,检验正常的一个很方便的就是双击GDAL库中bin文件夹里面的exe,如果一闪而过,基本上就正常的。如果提示错误信息,比如,应用程序无法正常启动啥的,就先安装编译GDAL库的VS对应版本的C++分发库(也叫C++运行库,名字叫vcredist_x86.exe或者vcredist_x64.exe,注意还有SP1之分)。
第二:假设通过安装这个运行库,GDAL库可以正常启动了,接下来把GDAL库的C#版本里面的dll全部拷贝到C#程序编译的exe所在目录,比如我的是在【F:\Work\GDALTest\bin\Debug】,然后再次启动程序,看看还抛出异常不,如果不抛出异常,那么恭喜你,下面的不用看了(我的电脑到这步结束后就正常了);如果还是抛出异常,不要着急,按照下面的步骤继续。
第三:通过上面的步骤还是不行的话,将整个工程的【配置管理器】中改成与GDAL库的版本一致,这里的版本指的是操作系统是32位还是64位,如果GDAL是32位的,那么在配置管理器中创建一个x86的平台,然后编译整个工程;如果GDAL版本是64位的,那么创建一个x64的平台进行编译。(这个步骤一般是会出现在使用32位的GDAL库在64位的系统上开发会用到)。
第四:如果你通过上面三个步骤还是没有解决的话,那我也不知道了……
最后截个图,看看输出的图像信息和矢量信息,初学者可以参考这个来读取栅格数据和矢量数据。程序的代码打包在我的CSDN资源里面,下载地址是:http://download.csdn.net/detail/liminlu0314/4653881
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");