C#使用GDAL读取TIF文件

  • C#使用GDAL读取TIF文件已关闭评论
  • 90 次浏览
  • A+
所属分类:.NET技术
摘要

GDAL官网C#使用GDAL库需安装以下两个Nuget包:GDAL和GDAL.Native也可以安装这几个包:

GDAL官网

C#使用GDAL库需安装以下两个Nuget包:GDAL和GDAL.Native

C#使用GDAL读取TIF文件

也可以安装这几个包:

C#使用GDAL读取TIF文件

这两种方式的注册方式会不太一样,其他用法大致相同。在此选中的是第一种方式,即在此安装的是GDAL和GDAL.Native。

注册

使用GDAL库的功能之前,必须先注册

// 注册 GdalConfiguration.ConfigureGdal(); Gdal.AllRegister(); // 设置utf-8编码 Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); 

若安装的是第二种程序包,即MaxRev.Gdal.Core等,则注册语句为:

// 注册 GdalBase.ConfigureAll(); // 设置编码 Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); 

需注意的是,有时会报"PROJ: proj_create_from_database: Cannot find proj.db"这样的异常,解决这个异常,可以在注册之后加上这行代码,手动设置PROJ_DB环境变量的查找路径:

Osr.SetPROJSearchPath(Environment.GetEnvironmentVariable("PROJ_LIB")); 

或者在文件资源管理器中找到proj.db文件,再设置它的查找路径

C#使用GDAL读取TIF文件

C#使用GDAL读取TIF文件

最后手动设置查找路径:

Osr.SetPROJSearchPath("C:\xxx\xxx\.nuget\packages\gdal.native\3.5.3\build\gdal\share"); 

MaxRev.Gdal的查找路径为:

Osr.SetPROJSearchPath("C:\xxx\xxx\.nuget\packages\maxrev.gdal.windowsruntime.minimal\3.6.1.110\runtimes\win-x64\native\maxrev.gdal.core.libshared"); 

读取信息

// 使用只读方式打开tif文件 Dataset ds = Gdal.Open("C:\xxx.tif", Access.GA_ReadOnly); if (ds == null) {     Console.WriteLine("文件打开失败...");     return; }  // 获取驱动器名称,这里输出的是:GeoTIFF var driverName = ds.GetDriver().LongName;  // 投影坐标系信息 var projection = ds.GetProjection(); var projection = ds.GetProjectionRef(); 

这里的波段表示单个栅格波段/通道/图层,它不一定代表整个图像,例如,24 位 RGB 图像通常表示为具有三个波段的数据集,一个用于红色,一个用于绿色,一个用于蓝色。

// 波段数 var rasterCount = ds.RasterCount; // 获取tif的第一个波段,波段索引从1开始 var band = ds.GetRasterBand(1); // 波段数据类型 var bandDataType = band.DataType; Console.WriteLine("DataType: " + Gdal.GetDataTypeName(bandDataType)); // 波段颜色解释 var interpretation = band.GetRasterColorInterpretation(); Console.WriteLine("PaletteInterp: " + interpretation.ToString()); 

读取像素值

var band = ds.GetRasterBand(1);  // 计算最大值和最小值 double[] rasterMinMax = new double[2]; int approx_ok = 0; band.ComputeRasterMinMax(rasterMinMax, approx_ok); Console.WriteLine("rasterMinMax = " + rasterMinMax[0] + ", " + rasterMinMax[1]);  // 获取最大值和最小值,这里获取的不一定是真实的最值 band.GetMaximum(out double mval, out int mhasval); band.GetMinimum(out double min, out int minval);  // 获取无效值 band.GetNoDataValue(out var val, out var hasval);  // 读取像素值 int Xsize = band.XSize; int Ysize = band.YSize; var buff = new double[Xsize * Ysize]; band.ReadRaster(0, 0, Xsize, Ysize, buff, Xsize, Ysize, 0, 0); for (int i = 0; i < Xsize; i++) {     for (int j = 0; j < Ysize; j++)     {         var value = buff[i + j * Xsize];         Console.Write(value + "  ");     } } 

计算经纬度

// 获取仿射变换矩阵 /* 	地理坐标和影像数据行列的转换关系: 	Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2) 	Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5) */ double[] geoTrans = new double[6]; ds.GetGeoTransform(geoTrans);  // 转换地理坐标系 SpatialReference spatial = ds.GetSpatialRef(); var geors = new SpatialReference(""); geors.ImportFromEPSG(4326); var transformation = new CoordinateTransformation(spatial, geors);  //计算经纬度 for (int i = 0; i < Ysize; i++) {     for (int j = 0; j < Xsize; j++)     {         // 计算投影坐标         var x = geoTrans[0] + i * geoTrans[1] + j * geoTrans[2];         var y = geoTrans[3] + i * geoTrans[4] + j * geoTrans[5];         // 计算经纬度         double[] longiAndLat = new double[2];         transformation.TransformPoint(longiAndLat, x, y, 0); 		// 1是经度,2是纬度         Console.Write("(" + longiAndLat[1] + "," + longiAndLat[0] + ") , ");     } }