1.功能简介
静止卫星是位于地球赤道上空约3.58万km处,与地面始终保持相对静止的卫星,静止卫星的特点是覆盖区域广,具有很强的机动灵活性,能够对特定区域进行分钟级高重复观测,可快速监测灾害目标的动态变化。目前风云2系列、风云4系列、葵花(Himawari)系列、高分4卫星均为静止卫星。
[静止卫星位置示意图]
[卫星运行轨迹图]
[FY2G数据成像图] [GF4数据成像图]
PIE支持静止卫星数据的显示和浏览,同时提供了针对常用静止卫星数据显示的优化方案,下面以FY4A数据为例来进行介绍。
2.功能实现说明
2.1 FY4A数据介绍
[FY4A数据成像图]
FY4A卫星是气象卫星,其数据采用HDF方式存储,包括4000、2000、1000、500四种分辨率的数据,不同分辨率数据包括不同的通道。其各通道均为默认标称投影的全圆盘的数据,其星下点和卫星姿态等信息均存储中HDF的对应数据集下。
[FY4A数据文件截图]
[HDF Explorer查看FY4A的4000分辨率数据]
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 |
示例代码 | |
//加载静止卫星数据 voidPIEMainWindow::On_OpenStaticData_Triggered(boolchecked) { QStringfilter = "HDF Files (*.hdf *.h5)"; QStringlstFile = QFileDialog::getOpenFileName(nullptr, "添加数据", "", filter); if (lstFile.isEmpty()) return;
QFileInfofileInfo(lstFile); QStringdesDir = fileInfo.absoluteDir().absolutePath(); QStringfileName = fileInfo.baseName(); QStringchannelName = "NOMChannel13"; QStringdesTif = desDir+"/"+fileName+"_"+channelName+".tiff"; QFileInfodesTifInfo(desTif); if (desTifInfo.exists()) return;
SysGeometry::SpatialReferencePtrspatialReference = newSysGeometry::ProjectedCoordinateSystem(); QStringprj4 = "+proj=geos +h=35785863 +a=6378137.0 +b=6356752.3 +lon_0=104.7 +no_defs"; spatialReference->ImportFromProj4(prj4);
SysDataSource::MultiDatasetPtrmulDataSetPtr = SysDataSource::DatasetFactory::Instance()->OpenDataset(lstFile, SysDataSource::GA_ReadOnly); if (mulDataSetPtr==nullptr) return; SysDataSource::RasterDatasetPtrchannelDataset= mulDataSetPtr->GetDataset(channelName); if (channelDataset!=nullptr) { //1、获取栅格数据集的相关参数
intnWidth = channelDataset->GetRasterXSize(); intnHeight = channelDataset->GetRasterYSize(); SysDataSource::PixelDataTypepixDataType = channelDataset->GetRasterBand(0)->GetRasterDataType(); intbandCount = channelDataset->GetBandCount(); QVector<int> bandMap; int* bandMapTarget = newint[bandCount]; for (inti=0;i<bandCount;i++) { bandMap.insert(i, i + 1); bandMapTarget[i] = i + 1; }
//2、读取数据至内存中 SysDataSource::PixelBufferPtrbufferPtr = channelDataset->Read(0, 0, nWidth, nHeight, nWidth, nHeight, bandMap);
//3、创建目标栅格数据并写入 SysDataSource::RasterDatasetPtrtargetDataSetPtr = SysDataSource::DatasetFactory::Instance()->CreateRasterDataset(desTif, nWidth, nHeight, bandCount, pixDataType, "GTiff", nullptr); boolflag= 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 = newdouble[6]; intbeginLineNum = 0; intnReslution = 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::LayerPtrchannelLayer = SysCarto::LayerFactory::Instance()->CreateDefaultRasterLayer(targetDataSetPtr); m_pCurrentControl->GetMap()->AddLayer(channelLayer); m_pCurrentControl->GetActiveView()->PartialRefresh(SysCarto::ViewAll); } } } |