首页 > 编程语言 >C#使用GDAL读取TIF文件

C#使用GDAL读取TIF文件

时间:2023-02-27 14:26:05浏览次数:52  
标签:C# double band int var TIF ds GDAL

GDAL官网

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

image

也可以安装这几个包:

image

这两种方式的注册方式会不太一样,其他用法大致相同。在此选中的是第一种方式,即在此安装的是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文件,再设置它的查找路径

image

image

最后手动设置查找路径:

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] + ") , ");
    }
}

标签:C#,double,band,int,var,TIF,ds,GDAL
From: https://www.cnblogs.com/rockrose/p/17159458.html

相关文章

  • 【DFS】LeetCode 291. 单词规律 II
    题目链接291.单词规律II思路定义一个全局HashMap<Character,String>来存储映射关系,key为pattern的字符,value为str的子串。一开始,map中没有任何映射关系。......
  • 力扣-算法C++-简单题
    1、给定一个整数数组nums 和一个整数目标值target,请你在该数组中找出和为目标值target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答......
  • vuex中commit和dispatch的区别
    一直都没整明白commit和dispath的区别,今天总算整明白了1、commit和dispatch的区别commit和dispatch的区别在于commit是提交mutatious的同步操作,dispatch是分发actions的......
  • webpack模块化的原理
    commonjs在webpack中既可以书写commonjs模块也可以书写es模块,而且不用考虑浏览器的兼容性问题,我们来分析一下原理。首先搞清楚commonjs模块化的处理方式,简单配置一下webp......
  • webpack实战,手写loader和plugin
    序言对于webpack来说,loader和plugin可以算是需求程度最为广泛的配置项了。但是呢,单单止步于配置可能还不够。如果我们自己有时候想要diy一个需求,但是webpack又......
  • docker常用命令
    1.查询镜像dockerimages--删除镜像dockerrmiIMAGEID2.查询容器dockerps-a3.停止容器--停止容器dockerstopCONTAINERID--删除容器dockerr......
  • thinkphp6开发cms项目之安装tp框架
    1.安装thinkphp6框架:composercreate-projecttopthink/thinktp需要安装的扩展:composerrequiretopthink/think-multi-app//多应用composerrequiretopthink/th......
  • OSCP考试Hackthebox靶机推荐
    Pain:Pain是一台基于Linux的靶机,难度级别为中等,涵盖了许多常见的漏洞类型和渗透测试技术。这台靶机需要进行横向渗透,涉及到一些密码破解和提权技术。Legacy:Legacy是一......
  • Mac 配置SSH公钥
    cd/进入主目录查看.ssh文件,是否存在公私钥,参考:链接https://www.jianshu.com/p/1bdae85fcf7bhttp://events.jianshu.io/p/54f8c11aa7d9......
  • jeecg-boot点击菜单时,在新窗口打开一个新页面
    1、’首先修改router.config.js文件,在要打开的页面路径写在基础路由constantRouterMap函数中,我这里的例子是新的聊天室在新的页面窗口打开  2、修改src/components/menu/C......