zoukankan      html  css  js  c++  java
  • PIE-SDK For C++打开静止卫星数据

    1.功能简介

       静止卫星是位于地球赤道上空约3.58km处,与地面始终保持相对静止的卫星,静止卫星的特点是覆盖区域广,具有很强的机动灵活性,能够对特定区域进行分钟级高重复观测,可快速监测灾害目标的动态变化。目前风云2系列、风云4系列、葵花(Himawari)系列、高分4卫星均为静止卫星。

    [静止卫星位置示意图]

    [卫星运行轨迹图]

    [FY2G数据成像图] [GF4数据成像图]

            PIE支持静止卫星数据的显示和浏览,同时提供了针对常用静止卫星数据显示的优化方案,下面以FY4A数据为例来进行介绍。

    2.功能实现说明

    2.1 FY4A数据介绍

    [FY4A数据成像图]

             FY4A卫星是气象卫星,其数据采用HDF方式存储,包括400020001000500四种分辨率的数据,不同分辨率数据包括不同的通道。其各通道均为默认标称投影的全圆盘的数据,其星下点和卫星姿态等信息均存储中HDF的对应数据集下。

    [FY4A数据文件截图]

    [HDF Explorer查看FY4A4000分辨率数据]

             HDF数据是采用了高效率压缩的数据,实现了高效的存储、分发。但却造成了数据的显示浏览缓慢(每次数据浏览,都需要从压缩文件中解压出原始数据,再获取到要显示浏览的数据),并且整个过程会占用大量的内存资源,为了保证数据的高效浏览效率,我们建议将HDF中的各通道数据生成一份支持快速浏览查看的tiff本地缓存数据,以满足浏览查看的需求。

    下面我们以FY4A 4000m数据的NOMChannel13通道为例,来演示如何完成对FY4A数据的快速读取、浏览。

    2.2 实现思路及原理说明

       读取静止卫星的数据的思路为把静止卫星数据中的对应通道(NOMChannel13)保存为一份本地的栅格数据,再通过对栅格数据的浏览,完成对静止卫星数据的浏览。

    第一步

    打开静止卫星数据为多数据集

    第二步

    获取指定通道的栅格数据集

    第三步

    读取第二步中的数据集的数据至内存中

    第四步

    创建与静止卫星同数据类型、同宽高、同波段数的目标栅格文件

    第五步

    将数据写入目标栅格数据文件

    第六步

    对目标栅格数据赋值空间参考和六参数

    2.3 核心接口与方法

    接口/

    方法

    说明

    SysDataSource::DatasetFactory

    OpenDataset

    打开数据集

    CreateRasterDataset

    创建栅格数据集

    SysDataSource::RasterDatasetPtr

    Read

    将栅格数据读取至内存中

    Write

    将内存数据写入至栅格数据中

    2.4 示例代码

    项目路径

    百度云盘地址下/PIE示例程序/03.数据加载/05.打开静止卫星数据

    数据路径

    百度云盘地址下/PIE示例数据/栅格数据/00.FY/FY4A/**.tif

    视频路径

    百度云盘地址下/PIE视频教程/03.数据加载/05.打开静止卫星数据.avi

    示例代码

    //加载静止卫星数据

    void PIEMainWindow::On_OpenStaticData_Triggered(bool checked)

    {

        QString filter = "HDF Files (*.hdf *.h5)";

        QString lstFile = QFileDialog::getOpenFileName(nullptr, "添加数据", "", filter);

        if (lstFile.isEmpty()) return;

     

        QFileInfo fileInfo(lstFile);

        QString desDir = fileInfo.absoluteDir().absolutePath();

        QString fileName = fileInfo.baseName();

        QString channelName = "NOMChannel13";

        QString desTif = desDir + "/" + fileName+"_" +channelName+ ".tiff";

        QFileInfo desTifInfo(desTif);

        if (desTifInfo.exists()) return;

     

        SysGeometry::SpatialReferencePtr spatialReference = new SysGeometry::ProjectedCoordinateSystem();

        QString prj4 = "+proj=geos +h=35785863 +a=6378137.0 +b=6356752.3 +lon_0=104.7 +no_defs";

        spatialReference->ImportFromProj4(prj4);

     

        SysDataSource::MultiDatasetPtr mulDataSetPtr = SysDataSource::DatasetFactory::Instance()->OpenDataset(lstFile, SysDataSource::GA_ReadOnly);

        if (mulDataSetPtr == nullptr) return;

        SysDataSource::RasterDatasetPtr channelDataset= mulDataSetPtr->GetDataset(channelName);

        if (channelDataset!=nullptr)

        {

            //1、获取栅格数据集的相关参数

     

            int nWidth = channelDataset->GetRasterXSize();

            int nHeight = channelDataset->GetRasterYSize();

            SysDataSource::PixelDataType pixDataType = channelDataset->GetRasterBand(0)->GetRasterDataType();

            int bandCount = channelDataset->GetBandCount();

            QVector<int> bandMap;

            int* bandMapTarget = new int[bandCount];

            for (int i=0;i<bandCount;i++)

            {

                bandMap.insert(i, i + 1);

                bandMapTarget[i] = i + 1;

            }

            

            //2、读取数据至内存中

            SysDataSource::PixelBufferPtr bufferPtr = channelDataset->Read(0, 0, nWidth, nHeight, nWidth, nHeight, bandMap);

     

            //3、创建目标栅格数据并写入

            SysDataSource::RasterDatasetPtr targetDataSetPtr = SysDataSource::DatasetFactory::Instance()->CreateRasterDataset(desTif, nWidth, nHeight, bandCount,

                pixDataType, "GTiff", nullptr);

            bool flag= targetDataSetPtr->Write(0, 0, nWidth, nHeight, bufferPtr->GetData(), nWidth, nHeight, pixDataType, bandCount, bandMapTarget);

            if (flag)

            {

                //设置空间投影并设置无效值

                targetDataSetPtr->SetSpatialReference(spatialReference);

                targetDataSetPtr->GetRasterBand(0)->SetNoDataValue(65535);

                //设置六参数

                double* geoTransform = new double[6];

                int beginLineNum = 0;

                int nReslution = 4000;

                geoTransform[0] = -5496000;

                geoTransform[1] = nReslution;

                geoTransform[2] = 0;

                geoTransform[3] = 5496000 - beginLineNum * nReslution;

                geoTransform[4] = 0;

                geoTransform[5] = -nReslution;

                targetDataSetPtr->SetGeoTransform(geoTransform);

                targetDataSetPtr->Flush();

                SysCarto::LayerPtr channelLayer = SysCarto::LayerFactory::Instance()->CreateDefaultRasterLayer(targetDataSetPtr);

                m_pCurrentControl->GetMap()->AddLayer(channelLayer);

                m_pCurrentControl->GetActiveView()->PartialRefresh(SysCarto::ViewAll);

            }

        }

    }

    2.5示例截图

  • 相关阅读:
    算法第五章作业
    算法第四章作业
    算法第四章上机实践报告
    算法第三章作业——动态规划
    算法第三章上机实践报告
    分治法的思想与体会
    算法第二章上机实践报告
    c++代码规范及《数学之美》读后感
    bugkuctf web部分(前8题)解题报告
    第二次博客作业
  • 原文地址:https://www.cnblogs.com/PIESat/p/12367665.html
Copyright © 2011-2022 走看看