翼度科技»论坛 编程开发 .net 查看内容

C#使用GDAL读取TIF文件

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
GDAL官网
C#使用GDAL库需安装以下两个Nuget包:GDAL和GDAL.Native

也可以安装这几个包:

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

使用GDAL库的功能之前,必须先注册
  1. // 注册
  2. GdalConfiguration.ConfigureGdal();
  3. Gdal.AllRegister();
  4. // 设置utf-8编码
  5. Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
复制代码
若安装的是第二种程序包,即MaxRev.Gdal.Core等,则注册语句为:
  1. // 注册
  2. GdalBase.ConfigureAll();
  3. // 设置编码
  4. Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
复制代码
需注意的是,有时会报"PROJ: proj_create_from_database: Cannot find proj.db"这样的异常,解决这个异常,可以在注册之后加上这行代码,手动设置PROJ_DB环境变量的查找路径:
  1. Osr.SetPROJSearchPath(Environment.GetEnvironmentVariable("PROJ_LIB"));
复制代码
或者在文件资源管理器中找到proj.db文件,再设置它的查找路径


最后手动设置查找路径:
  1. Osr.SetPROJSearchPath("C:\\xxx\\xxx\\.nuget\\packages\\gdal.native\\3.5.3\\build\\gdal\\share");
复制代码
MaxRev.Gdal的查找路径为:
  1. Osr.SetPROJSearchPath("C:\\xxx\\xxx\\.nuget\\packages\\maxrev.gdal.windowsruntime.minimal\\3.6.1.110\\runtimes\\win-x64\\native\\maxrev.gdal.core.libshared");
复制代码
读取信息
  1. // 使用只读方式打开tif文件
  2. Dataset ds = Gdal.Open("C:\\xxx.tif", Access.GA_ReadOnly);
  3. if (ds == null)
  4. {
  5.     Console.WriteLine("文件打开失败...");
  6.     return;
  7. }
  8. // 获取驱动器名称,这里输出的是:GeoTIFF
  9. var driverName = ds.GetDriver().LongName;
  10. // 投影坐标系信息
  11. var projection = ds.GetProjection();
  12. var projection = ds.GetProjectionRef();
复制代码
这里的波段表示单个栅格波段/通道/图层,它不一定代表整个图像,例如,24 位 RGB 图像通常表示为具有三个波段的数据集,一个用于红色,一个用于绿色,一个用于蓝色。
  1. // 波段数
  2. var rasterCount = ds.RasterCount;
  3. // 获取tif的第一个波段,波段索引从1开始
  4. var band = ds.GetRasterBand(1);
  5. // 波段数据类型
  6. var bandDataType = band.DataType;
  7. Console.WriteLine("DataType: " + Gdal.GetDataTypeName(bandDataType));
  8. // 波段颜色解释
  9. var interpretation = band.GetRasterColorInterpretation();
  10. Console.WriteLine("PaletteInterp: " + interpretation.ToString());
复制代码
读取像素值
  1. var band = ds.GetRasterBand(1);
  2. // 计算最大值和最小值
  3. double[] rasterMinMax = new double[2];
  4. int approx_ok = 0;
  5. band.ComputeRasterMinMax(rasterMinMax, approx_ok);
  6. Console.WriteLine("rasterMinMax = " + rasterMinMax[0] + ", " + rasterMinMax[1]);
  7. // 获取最大值和最小值,这里获取的不一定是真实的最值
  8. band.GetMaximum(out double mval, out int mhasval);
  9. band.GetMinimum(out double min, out int minval);
  10. // 获取无效值
  11. band.GetNoDataValue(out var val, out var hasval);
  12. // 读取像素值
  13. int Xsize = band.XSize;
  14. int Ysize = band.YSize;
  15. var buff = new double[Xsize * Ysize];
  16. band.ReadRaster(0, 0, Xsize, Ysize, buff, Xsize, Ysize, 0, 0);
  17. for (int i = 0; i < Xsize; i++)
  18. {
  19.     for (int j = 0; j < Ysize; j++)
  20.     {
  21.         var value = buff[i + j * Xsize];
  22.         Console.Write(value + "  ");
  23.     }
  24. }
复制代码
计算经纬度
  1. // 获取仿射变换矩阵
  2. /*
  3.         地理坐标和影像数据行列的转换关系:
  4.         Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2)
  5.         Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5)
  6. */
  7. double[] geoTrans = new double[6];
  8. ds.GetGeoTransform(geoTrans);
  9. // 转换地理坐标系
  10. SpatialReference spatial = ds.GetSpatialRef();
  11. var geors = new SpatialReference("");
  12. geors.ImportFromEPSG(4326);
  13. var transformation = new CoordinateTransformation(spatial, geors);
  14. //计算经纬度
  15. for (int i = 0; i < Ysize; i++)
  16. {
  17.     for (int j = 0; j < Xsize; j++)
  18.     {
  19.         // 计算投影坐标
  20.         var x = geoTrans[0] + i * geoTrans[1] + j * geoTrans[2];
  21.         var y = geoTrans[3] + i * geoTrans[4] + j * geoTrans[5];
  22.         // 计算经纬度
  23.         double[] longiAndLat = new double[2];
  24.         transformation.TransformPoint(longiAndLat, x, y, 0);
  25.                 // 1是经度,2是纬度
  26.         Console.Write("(" + longiAndLat[1] + "," + longiAndLat[0] + ") , ");
  27.     }
  28. }
复制代码
来源:https://www.cnblogs.com/rockrose/archive/2023/02/27/17159458.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具