PIE SDK開啟靜止衛星資料
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 核心介面與方法
介面/類 |
方法 |
說明 |
DataSource.DatasetFactory |
OpenDataset |
開啟資料集 |
DataSource.DatasetFactory |
CreateRasterDataset |
建立柵格資料集 |
DataSource.IRasterDataset |
Read |
將柵格資料讀取至記憶體中 |
DataSource.IRasterDataset |
Write |
將記憶體資料寫入至柵格資料中 |
2.4 示例程式碼
專案路徑 |
百度雲盤地址下/PIE示例程式/05.開啟靜止衛星資料 |
資料路徑 |
百度雲盤地址下/PIE示例資料/科學資料集\HDF資料夾下資料 |
視訊路徑 |
百度雲盤地址下/PIE視訊教程/05.開啟靜止衛星資料.avi |
示例程式碼 |
|
OpenFileDialog openFile = new OpenFileDialog(); openFile.Filter = "HDF資料|*.hdf"; if (openFile.ShowDialog() != DialogResult.OK) return; string channelName = "NOMChannel13";//波段名稱 string tempTif = System.IO.Path.GetDirectoryName(openFile.FileName) + "\\NOMChannel13.tiff";//輸出tiff路徑 ISpatialReference spatialReference = new ProjectedCoordinateSystem();//目標空間參考 spatialReference.ImportFromUserInput("+proj=geos +h=35785863 +a=6378137.0 +b=6356752.3 +lon_0=104.7 +no_defs"); IRasterLayer rasterLayer = OpenStaticData(openFile.FileName, channelName, tempTif, spatialReference);// OpenStaticData方法的定義在下面 if (rasterLayer == null) return; //新增至地圖並重新整理檢視 mapControlMain.FocusMap.AddLayer(rasterLayer as ILayer); mapControlMain.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
/// <summary> /// 開啟風雲4A、風雲2G等靜止衛星資料,讀取指定波段資料為tiff /// </summary> /// <param name="filePath">hdf路徑</param> /// <param name="channelName">波段通道名稱</param> /// <param name="tiffPath">生成tiff路徑</param> /// <param name="spatialReference">空間參考</param> /// <returns></returns> private IRasterLayer OpenStaticData(string filePath, string channelName, string tiffPath, ISpatialReference spatialReference) { IRasterLayer rasteLayer = null; try { //開啟MultiDataset IMultiDataset hdfDataset = PIE.DataSource.DatasetFactory.OpenDataset(filePath, OpenMode.ReadOnly) as IMultiDataset; if (hdfDataset != null) { //遍歷,查詢指定通道的Dataset,進行資料格式轉換 for (int i = 0; i < hdfDataset.GetDatasetCount(); i++) { IDataset pTempDataset = hdfDataset.GetDataset(i); if (pTempDataset.Name == channelName) { //將RasterDataset寫入指定tiff IRasterDataset hdfRasterDatasetBand = pTempDataset as IRasterDataset;
int nWidth = hdfRasterDatasetBand.GetRasterXSize(); int nHeight = hdfRasterDatasetBand.GetRasterYSize();
PixelDataType eDateType = hdfRasterDatasetBand.GetRasterBand(0).GetRasterDataType(); int count = hdfRasterDatasetBand.GetBandCount();
int[] bandMap = new int[count]; for (int j = 0; j < count; j++) { bandMap[j] = j + 1; } string[] tempList = null; IPixelBuffer pixBuffer = hdfRasterDatasetBand.Read(0, 0, nWidth, nHeight, nWidth, nHeight, bandMap); //建立輸出柵格資料集 IRasterDataset tifRasterDataset = DatasetFactory.CreateRasterDataset(tiffPath, nWidth, nHeight, count, eDateType, "GTiff", tempList); bool flag = tifRasterDataset.Write(0, 0, nWidth, nHeight, pixBuffer.GetData_Ref(), nWidth, nHeight, eDateType, count, bandMap); tifRasterDataset.SpatialReference = spatialReference; tifRasterDataset.GetRasterBand(0).SetNoDataValue(65535);
//六引數,根據輸入座標的不同需要進行動態設定,本示例程式碼以風雲4A-4000m的資料作為實驗資料。 int beginLineNum = 0; int nReslution = 4000; string beginlineNumStr = hdfDataset.GetMetadataItem("Begin_Line_Number", ""); if (string.IsNullOrEmpty(beginlineNumStr)) { beginlineNumStr = hdfDataset.GetMetadataItem("geospatial_lat_lon_extent_begin_line_number", ""); if (string.IsNullOrEmpty(beginlineNumStr)) beginLineNum = 183; }
if (!string.IsNullOrEmpty(beginlineNumStr)) { StringBuilder sb = new StringBuilder(); foreach (char charStr in beginlineNumStr) { if ((charStr >= '0' && charStr <= '9') || charStr == ' ' || charStr == '-') sb.Append(charStr); } bool result = int.TryParse(sb.ToString(), out beginLineNum); }
double[] geoTransform = new double[6]; geoTransform[0] = -5496000; geoTransform[1] = nReslution; geoTransform[2] = 0; geoTransform[3] = 5496000 - beginLineNum * nReslution; geoTransform[4] = 0; geoTransform[5] = -nReslution; tifRasterDataset.SetGeoTransform(geoTransform);
(tifRasterDataset as IDisposable).Dispose(); (hdfRasterDatasetBand as IDisposable).Dispose(); (pixBuffer as IDisposable).Dispose();
rasteLayer = PIE.Carto.LayerFactory.CreateDefaultLayer(tiffPath) as IRasterLayer; break; } } } } catch (Exception ex) { rasteLayer = null; } return rasteLayer; }
mapControlMain.FocusMap.AddLayer(fLayer as ILayer); mapControlMain.ActiveView.PartialRefresh(PIE.Carto.ViewDrawPhaseType.ViewAll);
|
2.5 示例截圖