zoukankan      html  css  js  c++  java
  • 使用GDAL创建Erdas格式的金字塔

        在使用Erdas或者ArcGIS打开栅格图像的时候,会创建一个后缀名为rrd的金字塔文件,用于快速显示图像。那么在使用GDAL编写自己的图像算法后,像快速的在Erdas或者ArcGIS中显示,就需要自己创建rrd格式的金字塔文件,这样在打开该图像文件时,打开速度会非常快,在我的电脑上一个2G的img不到一秒钟可以全部加载进来。

        查看GDAL中,有个gdaladdo的工具,就是一个专门用于创建金字塔文件的,但是默认的创建的是一个后缀名为ovr的金字塔文件,该种格式的金字塔不能被Erdas或者ArcGIS使用,但是可以在QGIS等使用。为了能够在Erdas中使用,在创建的时候需要指定一个选项,那就是 USE_RRD=YES,使用该选项后,创建的金字塔格式是一个aux文件,虽然后缀名不是rrd,但是该文件是可以被Erdas或者ArcGIS中使用的。

        关于gdaladdo的使用帮助,可以参考网址:http://www.gdal.org/gdaladdo.html

        Erdas的金字塔是按照2的次方来采样,金字塔顶层的大小应该是小于等于64*64,创建金字塔的,于是按照gdaladdo中的说明,其命令行参数应该是:

       gdaladdo --config USE_RRD YES airphoto.img 2 4 8 16 ...

    最后的...表示采样级别,一直到最顶层的像元个数小于等于64*64结束。有了上面的知识,下面就给出我写的一个函数,用于创建金字塔。

    /**
    * @brief 创建金字塔
    * @param pszFileName        输入的栅格文件
    * @param pProgress          进度条指针
    * @return 成功返回0
    */
    int CreatePyramids(const char* pszFileName, LT_Progress *pProgress)
    {
        if (pProgress != NULL)
        {
            pProgress->SetProgressCaption("创建金字塔");
            pProgress->SetProgressTip("正在创建金字塔...");
        }
    
        GDALAllRegister();
        CPLSetConfigOption("USE_RRD","YES");    //创建Erdas格式的字塔文件
    
        /* -------------------------------------------------------------------- */
        /*      Open data file.                                                 */
        /* -------------------------------------------------------------------- */
    
        GDALDatasetH     hDataset;
        hDataset = GDALOpen( pszFileName, GA_ReadOnly );
    
        GDALDriverH hDriver = GDALGetDatasetDriver(hDataset);
        const char* pszDriver = GDALGetDriverShortName(hDriver);
        if (EQUAL(pszDriver, "HFA") || EQUAL(pszDriver, "PCIDSK"))
        {
            GDALClose(hDataset);    //如果文件是Erdas的img或者PCI的pix格式,创建内金字塔,其他的创建外金字塔
            hDataset = GDALOpen( pszFileName, GA_Update );
        }
    
        if( hDataset == NULL )
        {
            if (pProgress != NULL)
                pProgress->SetProgressTip("打开图像失败,请检查图像是否存在或文件是否是图像文件!");
            
            return RE_NOFILE;
        }
    
        /* -------------------------------------------------------------------- */
        /*      Get File basic infomation                                       */
        /* -------------------------------------------------------------------- */
        int iWidth = GDALGetRasterXSize(hDataset);
        int iHeigh = GDALGetRasterYSize(hDataset);
    
        int iPixelNum = iWidth * iHeigh;    //图像中的总像元个数
        int iTopNum = 4096;                 //顶层金字塔大小,64*64
        int iCurNum = iPixelNum / 4;
    
        int anLevels[1024] = { 0 };
        int nLevelCount = 0;                //金字塔级数
    
        do    //计算金字塔级数,从第二级到顶层
        {
            anLevels[nLevelCount] = static_cast<int>(pow(2.0, nLevelCount+2));
            nLevelCount ++;
            iCurNum /= 4;
        } while (iCurNum > iTopNum);
    
        const char      *pszResampling = "nearest"; //采样方式
        GDALProgressFunc pfnProgress = GDALProgress;//进度条
    
        /* -------------------------------------------------------------------- */
        /*      Generate overviews.                                             */
        /* -------------------------------------------------------------------- */
        if (nLevelCount > 0 &&
            GDALBuildOverviews( hDataset,pszResampling, nLevelCount, anLevels,
            0, NULL, pfnProgress, pProgress ) != CE_None )
        {
            if (pProgress != NULL)
                pProgress->SetProgressTip("创建金字塔失败!");
    
            return RE_FAILD;
        }
    
        /* -------------------------------------------------------------------- */
        /*      Cleanup                                                         */
        /* -------------------------------------------------------------------- */
        GDALClose(hDataset);
        GDALDestroyDriverManager();
    
        if (pProgress != NULL)
            pProgress->SetProgressTip("创建金字塔完成!");
    
        return RE_SUCCESS;
    }

      需要说明的是,这段代码创建img格式和pix格式的金字塔会创建内金字塔,Erdas的img格式和PCI的pix格式可以把金字塔存放在文件内部。

    PS:在给img文件创建内金字塔后,使用除ArcGIS9.2以外的软件打开后,都正常,但是使用ArcGIS9.2打开后会出现图层偏移的问题,不知道是否ArcGIS9.2的bug。ArcGIS10正常!ArcGIS9.3没有测试。

    测试代码:

    void main()
    {
        LT_ConsoleProgress *pProgress = new LT_ConsoleProgress();
    
        int f = CreatePyramids("C://Work//Data//ttttt.img", pProgress);
    
        if (f == RE_SUCCESS)
            printf("计算成功/n");
        else
            printf("计算失败/n");
    
        delete pProgress;
    }

    测试:在使用ArcGIS10打开没有金字塔的文件时,提示:

    image

    运行测试代码:

    QEOPV7%QE]%DGHG~R7C)O19

    再次打开刚才的文件,没有上面的提示对话框了,而且很快加载进来,说明已经有金字塔了,如果使用Erdas打开的话,可以看到详细的金字塔信息。不过可以试用QGIS查看金字塔信息。右侧的列表显示的是金字塔的级别,Erdas的金字塔是从第二级开始建立的,所以看到第一级的图标上有个红色的小叉叉。见下图:

    image

  • 相关阅读:
    vue项目,百度地图api高亮选取区域,高亮某个地区,行政区域等
    vue 项目, 通知子组件更新,父组件中每次点击按钮重新加载子组件,(重新生成dom 元素)
    洛谷 P1003 铺地毯
    Codeforces Round #582 (Div. 3)
    安科 OJ 1190 连接电脑 (并查集)
    2018年牛客多校寒假 第四场 F (call to your teacher) (图的连通性)
    牛客小白月赛16 A 小石的签到题 ( 博弈)
    牛客小白月赛16 E 小雨的矩阵 ( 暴搜)
    安科 OJ 1054 排队买票 (递归,排列组合)
    牛客小白月赛15 C 表单 ( map 使用)
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6314059.html
Copyright © 2011-2022 走看看