基于GDAL的栅格图像空间插值预处理
基于GDAL的栅格图像预处理
前言
栅格数据和矢量数据构成空间数据的主要来源,怎样以开源方式读取并处理这些空间数据?目前有多种开源支持包,这里只介绍GDAL包。GDAL包的优点是支持库简洁、支持栅格和矢量、与多种开发平台结合。OpenGis方式读取空间数据,有利于自己编写程序进行图像预处理和智能识别等等,比如:遥感影像的降噪、锐化;红外图像的林火识别;工厂监控视频识别等等。本文中利用GDAL包读取高程栅格DEM,并添加气象自动站点的数据,进行空间插值研究。
一、程序主要程序功能实现过程
第一步:读取栅格数据,包含坡向和DEM
第二步:读入站点信息数据
第三步:按照行列号读取栅格单元到内存,不考虑高程为0的单元
第三步:每一个坡向情况中,参考固定数目的气象站点。首先确定搜索范围,获取定量数目的监测站点。
第四步:在同一个计算窗口内,通过给各个因子赋权重,依据海拔高程回归关系与加权回归分析得到
温度递减率。
第五步:计算单个站点的温度预测值,然后计算所有站点的距离权重因子,根据因子大小确定综合
影响后的温度值
第四步:开辟新内存存储处理后的栅格数据,然后新建一个tiff格式的文件,把内存
数据导出到该文件中
二、代码示例
int _tmain(int argc, _TCHAR* argv[])
{
/*
DEM、坡向栅格数据的数据框大小
*/
int XsizeDEM;
int YsizeDEM;
int XsizeAspect;
int YsizeAspect;
//double geoTransform[6];
//double Xp,Yp; /*
DEM、坡向栅格单元对象的VALUE值
*/
short int *pmemDEM;
float *pmemAspect;
float *pmemNew; //GDAL注册
GDALAllRegister(); /*
栅格单元的底图来源文件名:DEM/ASPECT
*/
const char *pszFileDEM;
pszFileDEM="F:\\beijing_dem\\bj25_CopyRaster11.img";
const char *pszFileAspect;
pszFileAspect="F:\\beijing_dem\\aspect_bj.tif"; /*读取站点信息*/
int n,m;
float site[][]; FILE *fp;
if((fp=fopen("F:\\beijing_dem\\site_36\\information.txt","r"))== NULL)
{
printf("cannot open this file\n");
exit();
}
for(n=;n<;n++) {
for(m=;m<;m++) {
fscanf(fp,"%f",&site[n][m]);
}
} for(n=;n<;n++) {
for(m=;m<;m++) {
printf("%f",site[n][m]);/*注意这里*/;
printf(" ");
}
printf("\n"); //每输出一行,输出一个换行符
}
fclose(fp); /*
DEM/ASPECT的数据集读取器
*/ GDALDataset *poDatasetDEM;
GDALRasterBand *poBandDEM;
GDALDataset *poDatasetAspect;
GDALRasterBand *poBandAspect; /*
判断DEM/ASPECT文件是否存在,不存在错误提示
*/
poDatasetDEM=(GDALDataset*)GDALOpen(pszFileDEM,GA_ReadOnly);
if(poDatasetDEM==NULL)
{
printf("File: %s不能打开",pszFileDEM);
return ;
} poDatasetAspect=(GDALDataset*)GDALOpen(pszFileAspect,GA_ReadOnly);
if(poDatasetAspect==NULL)
{ printf("File: %s不能打开",pszFileAspect);
return ;
} /*
判断DEM/ASPECT文件如果存在,就把文件输入到波段第一层
*/
poBandDEM=poDatasetDEM->GetRasterBand();
poBandAspect=poDatasetAspect->GetRasterBand(); /*
被处理栅格单元对象的数据框大小的提取
*/
XsizeDEM=poBandDEM->GetXSize();
YsizeDEM=poBandDEM->GetYSize();
XsizeAspect=poBandAspect->GetXSize();
YsizeAspect=poBandAspect->GetYSize(); /*
被处理栅格单元对象的内存开辟
*/
pmemDEM=(short int *)CPLMalloc(sizeof(short int)*XsizeDEM*YsizeDEM);
poBandDEM->RasterIO(GF_Read,,,XsizeDEM,YsizeDEM,pmemDEM,XsizeDEM,YsizeDEM,GDT_Int16,,); pmemAspect=(float*)CPLMalloc(sizeof(float)*XsizeAspect*YsizeAspect);
poBandAspect->RasterIO(GF_Read,,,XsizeAspect,YsizeAspect,pmemAspect,XsizeAspect,YsizeAspect,GDT_Float32,,); /*
被处理栅格单元对象的类型提示
*/
printf("Type is: %s\n",GDALGetDataTypeName(poBandDEM->GetRasterDataType())); //开辟新栅格内存空间
pmemNew=(float *)CPLMalloc(sizeof(float)*XsizeDEM*YsizeDEM); for(int i=;i<YsizeDEM;i++)
{
for(int j=;j<XsizeDEM;j++)
{
int flag=;
float H_value;
float A_value;
H_value=pmemDEM[i*XsizeDEM+j];
A_value=pmemAspect[i*XsizeDEM+j]; //单个栅格插值处理
//高程没有值的特殊情况
if(H_value==)
{
pmemNew[i*XsizeDEM+j]=;
} else
{
//平地无坡向的情况
if(A_value==-)
{
//处理站点和插值单元重合的情况,插值单元的值等于站点监测值
for(n=;n<;n++)
{
if(((site[n][]-i)*(site[n][]-i)+(site[n][]-j)*(site[n][]-j))==)
{
float x1=site[n][],x2=site[n][];
pmemNew[i*XsizeDEM+j]=site[n][];
printf("%f 平地站点数据: ",x1);
printf("%f\n",x2);
flag=;
}
} if(flag==)
{
pmemNew[i*XsizeDEM+j]=plain_calculate(site,H_value,i,j);
//pmemNew[i*XsizeDEM+j]=3;
}
} else
{
//处理站点和插值单元重合的情况,插值单元的值等于站点监测值
for(n=;n<;n++)
{
if(((site[n][]-i)*(site[n][]-i)+(site[n][]-j)*(site[n][]-j))==)
{
float x1=site[n][],x2=site[n][];
pmemNew[i*XsizeDEM+j]=site[n][];
printf("%f 非平地站点数据: ",x1);
printf("%f\n",x2);
flag=;
}
} if(flag==)
{
//每一个栅格单元进行插值计算
pmemNew[i*XsizeDEM+j]=calculate(site,H_value,A_value,i,j);
//pmemNew[i*XsizeDEM+j]=1;
}
}
}
//poDatasetDEM->GetGeoTransform( geoTransform);
//Xp = geoTransform[0] +j*geoTransform[1]+i*geoTransform[2];
//Yp = geoTransform[3] + j*geoTransform[4] + i*geoTransform[5]; }
} /**
创建新的空TIFF栅格文件
*/
GDALAllRegister();
GDALDriver *poDriver;
poDriver=GetGDALDriverManager()->GetDriverByName("GTiff");//AAIGrid(Arc/Info ASCII Grid) HFA (img no lim)
if(poDriver==NULL)
exit();
GDALDataset *poDstDS;
poDstDS=poDriver->Create("F:\\beijing_dem\\beijing_mix513.tiff",XsizeDEM,YsizeDEM,,GDT_Float32,NULL); double trans[]={219323.300357,100.00,0.00,4680250.0000,0.0,-100.000};
//如果图像不含地理坐标信息,默认返回值是:(0,1,0,0,0,1)
//In a north up image,
//左上角点坐标(padfGeoTransform[0],padfGeoTransform[3]);
//padfGeoTransform[1]是像元宽度(影像在宽度上的分辨率);
//padfGeoTransform[5]是像元高度(影像在高度上的分辨率);
//如果影像是指北的,padfGeoTransform[2]和padfGeoTransform[4]这两个参数的值为0。 poDstDS->SetGeoTransform(trans);
GDALClose((GDALDatasetH)poDstDS); /*
//处理后的数据层保存
*/
GDALDataset *poDatasetNew;
poDatasetNew=(GDALDataset*)GDALOpen("F:\\beijing_dem\\beijing_mix513.tiff",GA_Update);
GDALRasterBand *poBandNew;
poBandNew=poDatasetNew->GetRasterBand();
poBandNew->RasterIO(GF_Write,,,XsizeDEM,YsizeDEM,pmemNew,XsizeDEM,YsizeDEM,GDT_Float32,,);
GDALClose((GDALDatasetH)poDatasetNew); //释放数据
CPLFree(pmemDEM);
CPLFree(pmemNew);
printf("处理结束\n"); }
三、插值结果
基于GDAL的栅格图像空间插值预处理的更多相关文章
- 基于gdal的格网插值
格网插值就是使用离散的数据点创建一个栅格图像的过程.通常情况下,有一系列研究区域的离散点,如果我们想将这些点转换为规则的网格数据来进行进一步的处理,或者和其他网格数据进行合并 等处理,就需要使用格网插 ...
- 基于ArcGIS的栅格图像平滑处理(转)
基于ArcGIS的栅格图像平滑处理 栅格数据获取的途径多种多样,造成了栅格数据质量的很大差异,一些质量较差的栅格数据存在大量“噪音”象元,即在表达同类型的地理要素时,出现个别像元值与周边像元不一致的情 ...
- 关于基于GDAL库QT软件平台下C++语言开发使用说明
背景前提 地理空间数据抽象库(GDAL)是一个用于读取和编写栅格和矢量地理空间数据格式的计算机软件库,由开源地理空间基金会在许可的X / MIT风格免费软件许可下发布. 作为一个库,它为调用应用程序提 ...
- 基于GDAL的遥感影像显示(C#版)
基于GDAL的遥感影像显示(C#版) - 菜菜的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/RSyaoxin/article/details/9220735
- Tetrahedron based light probe interpolation(基于四面体的Light Probe插值)
在当前的游戏引擎中,使用Light Probe来计算全局环境光对于动态物体的影响是一种很主流的方法.在预处理阶段生成完场景的Light Probe之后,传统的方法采用查找最近的8个相邻的Probe然后 ...
- 基于GDAL库海洋表温日平均计算工具设计与实现 C++版
技术背景 在对物理海洋数据处理过程中,表层温度是众多要素中的一种,本文书要是针对海洋表温数据批量日平均处理的一个工具设计.首先要在对当前的SST数据文件作一下简要的说明,SST全称为sea surfe ...
- GDAL读取影像并插值
影像读取 并缩放 读取大影像某一部分,并缩放到指定大小,我们有时会用如下代码: #include "gdal.h" #include "gdal_priv.h" ...
- 基于GDAL库,读取.nc文件(以海洋表温数据为例)C++版
对于做海洋数据处理的同学,会经常遇到nc格式的文件,nc文件的格式全称是NetCDF,具体的详细解释请查询官网[https://www.unidata.ucar.edu/software/netcdf ...
- 基于GDAL库,读取海洋风场数据(.nc格式)c++版
经过这一段时间的对海洋数据的处理,接触了大量的与海洋相关的数据,例如海洋地形.海洋表面温度.盐度.湿度.云场.风场等数据,除了地形数据是grd格式外,其他的都是nc格式的数据.本文将以海洋风场数据为例 ...
随机推荐
- js 输出某年某月某日的天数/判断闰年
console.log(getDays(2017,12,12)); function getDays(year,month,day){ var arr = [31,28,31,30,31,30,31, ...
- 开源代码生成器,基于mybatis-generator扩展,结合freemarker
git源码地址:https://github.com/JonSnow592622272/free-generator-code 码云gitee源码地址:https://gitee.com/a59262 ...
- ZOJ3228 Searching the String (AC自动机)
Searching the String Time Limit: 7 Seconds Memory Limit: 129872 ...
- 事物的四大特性(acid)
如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一 ...
- NOIP考纲
首先来一张图,很直观(截止到2012年数据) 下面是收集的一些,我改了一下 红色加粗表示特别重要,必须掌握绿色加粗表示最好掌握,可能性不是很大,但是某些可以提高程序效率 高精度 a.加法 b.减法 c ...
- 全新Ubentu系统没有make,gcc命令解决办法
一定要记得先update sudo apt-get update 然后输入下述命令即可 sudo apt-get install make sudo apt-get install gcc
- 【洛谷日报#75】浅谈C++指针
放入我的博客食用效果更佳(有很多oi学习资料) 1.指针基础 1.引用 C++有一个东西叫引用,引用相当于给对象(如:变量)起了另一个名字,引用必须用对象初始化,一旦初始化,引用就会和初始化其的对象绑 ...
- 使用Eclipse中的反编译插件jadClipse查看Class源码
功安装完插件jadClipse 之后便可以查看源码class文件了 但是对于自己代码的class文件,直接复制过来却看不到,需要以下操作. 将此文件以及文件夹直接拷贝到Eclipse中发现 右击项目- ...
- 树梅派 -- 通过/sys读写ADC芯片 pcf8591
通过wiringPi等library, 在user space 通过/dev/i2c来读写i2c设备的方案不在本文讨论了. 编译SENSORS_PCF8591 模块 在Default raspberr ...
- tornado框架基础10-websocket
websocket 01 长轮询 在网页,我们经常扫码登录,结合之前的学习的知识点,来思考下,前端是如何知道用户在手机上扫码登录了呢? 长轮询:客户端不断的向服务器发送请求 缺点: \1. 开销大 \ ...