• 基于GDAL的栅格图像空间插值预处理


    转自 基于GDAL的栅格图像空间插值预处理——C语言版

    基于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[32][6];  
          
            FILE *fp;  
            if((fp=fopen("F:\beijing_dem\site_36\information.txt","r"))== NULL)  
            {  
                printf("cannot open this file
    ");  
                exit(0);  
            }  
            for(n=0;n<32;n++) {  
                for(m=0;m<6;m++) {  
                    fscanf(fp,"%f",&site[n][m]);  
                }  
            }  
          
          
            for(n=0;n<32;n++) {  
                for(m=0;m<6;m++) {  
                    printf("%f",site[n][m]);/*注意这里*/;  
                    printf("  ");  
                }  
                printf("
    ");    //每输出一行,输出一个换行符  
            }  
            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 0;  
            }  
          
            poDatasetAspect=(GDALDataset*)GDALOpen(pszFileAspect,GA_ReadOnly);  
            if(poDatasetAspect==NULL)  
            {  
          
                printf("File: %s不能打开",pszFileAspect);  
                return 0;  
            }  
          
            /* 
            判断DEM/ASPECT文件如果存在,就把文件输入到波段第一层 
            */  
            poBandDEM=poDatasetDEM->GetRasterBand(1);  
            poBandAspect=poDatasetAspect->GetRasterBand(1);  
          
            /* 
            被处理栅格单元对象的数据框大小的提取 
            */  
            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,0,0,XsizeDEM,YsizeDEM,pmemDEM,XsizeDEM,YsizeDEM,GDT_Int16,0,0);  
          
            pmemAspect=(float*)CPLMalloc(sizeof(float)*XsizeAspect*YsizeAspect);  
            poBandAspect->RasterIO(GF_Read,0,0,XsizeAspect,YsizeAspect,pmemAspect,XsizeAspect,YsizeAspect,GDT_Float32,0,0);  
          
          
            /* 
            被处理栅格单元对象的类型提示 
            */  
            printf("Type is: %s
    ",GDALGetDataTypeName(poBandDEM->GetRasterDataType()));  
          
            //开辟新栅格内存空间  
            pmemNew=(float *)CPLMalloc(sizeof(float)*XsizeDEM*YsizeDEM);  
          
              
            for(int i=0;i<YsizeDEM;i++)  
            {  
                for(int j=0;j<XsizeDEM;j++)  
                {  
                    int flag=0;  
                    float H_value;  
                    float A_value;  
                    H_value=pmemDEM[i*XsizeDEM+j];  
                    A_value=pmemAspect[i*XsizeDEM+j];  
          
                    //单个栅格插值处理  
                    //高程没有值的特殊情况  
                    if(H_value==0)  
                    {  
                        pmemNew[i*XsizeDEM+j]=0;  
                    }  
          
                    else  
                    {  
                        //平地无坡向的情况  
                        if(A_value==-1)  
                        {  
                            //处理站点和插值单元重合的情况,插值单元的值等于站点监测值  
                            for(n=0;n<32;n++)   
                            {  
                                if(((site[n][4]-i)*(site[n][4]-i)+(site[n][5]-j)*(site[n][5]-j))==0)  
                                {  
                                    float x1=site[n][0],x2=site[n][3];  
                                    pmemNew[i*XsizeDEM+j]=site[n][3];  
                                    printf("%f   平地站点数据: ",x1);  
                                    printf("%f
    ",x2);  
                                    flag=1;  
                                }  
                            }  
          
                            if(flag==0)  
                            {  
                            pmemNew[i*XsizeDEM+j]=plain_calculate(site,H_value,i,j);  
                            //pmemNew[i*XsizeDEM+j]=3;  
                            }  
                        }   
          
                        else   
                        {  
                            //处理站点和插值单元重合的情况,插值单元的值等于站点监测值  
                            for(n=0;n<32;n++)   
                            {  
                                if(((site[n][4]-i)*(site[n][4]-i)+(site[n][5]-j)*(site[n][5]-j))==0)  
                                {  
                                    float x1=site[n][0],x2=site[n][3];  
                                    pmemNew[i*XsizeDEM+j]=site[n][3];  
                                    printf("%f   非平地站点数据: ",x1);  
                                    printf("%f
    ",x2);  
                                    flag=1;  
                                }  
                            }  
          
                            if(flag==0)  
                            {  
                                //每一个栅格单元进行插值计算  
                                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(1);  
            GDALDataset *poDstDS;  
            poDstDS=poDriver->Create("F:\beijing_dem\beijing_mix513.tiff",XsizeDEM,YsizeDEM,1,GDT_Float32,NULL);  
          
            double trans[6]={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(1);  
            poBandNew->RasterIO(GF_Write,0,0,XsizeDEM,YsizeDEM,pmemNew,XsizeDEM,YsizeDEM,GDT_Float32,0,0);  
            GDALClose((GDALDatasetH)poDatasetNew);  
          
          
          
          
            //释放数据  
            CPLFree(pmemDEM);  
            CPLFree(pmemNew);  
            printf("处理结束
    ");  
          
          
          
          
        }  

     三、插值结果

     

     

  • 相关阅读:
    vscode的插件收集
    关于vue移动端的适配
    Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null objec
    android studio 使用 aidl(三)权限验证
    Android权限级别(protectionLevel)
    android studio 使用 aidl(二)异步回调
    android studio 使用 aidl(一)基础用法
    如何获取Android唯一标识(唯一序列号)
    android studio 生成aar和引用aar
    android studio 编译NDK android studio 生成.so文件
  • 原文地址:https://www.cnblogs.com/arxive/p/8192245.html
Copyright © 2020-2023  润新知