private IRasterDataProvider CreateMosaicRaster(string filename, GeoInfo geoHeader, int bandCount, ISpatialReference spatialRef) { IRasterDataProvider outRaster = null; if (File.Exists(filename)) { outRaster = GeoDataDriver.Open(filename, enumDataProviderAccess.Update, null) as IRasterDataProvider; } else { float resX = 0.01f; float resY = 0.01f; float ltX = 65; float ltY = 60; int width = 8000; int height = 7000; if (geoHeader == null) { return(null); } resX = geoHeader.ResX; resY = geoHeader.ResY; ltX = geoHeader.LtX; ltY = geoHeader.LtY; width = geoHeader.Width; height = geoHeader.Height; if (spatialRef == null) { spatialRef = SpatialReference.GetDefault(); } string dir = Path.GetDirectoryName(filename); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } IRasterDataDriver raster = RasterDataDriver.GetDriverByName("LDF") as IRasterDataDriver; string bandNames = "";//CreateBandNames(bandcount); string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + spatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + ltX + "," + ltY + "}:{" + resX + "," + resY + "}", "BANDNAMES=" + bandNames }; outRaster = raster.Create(filename, width, height, bandCount, enumDataType.UInt16, options) as RasterDataProvider; string outSolarZenithFile = Path.ChangeExtension(filename, ".SolarZenith.ldf"); using (RasterDataProvider outSolarZenithRaster = raster.Create(outSolarZenithFile, width, height, 1, enumDataType.UInt16, options) as RasterDataProvider) { } } return(outRaster); }
/// <summary> /// 地理数据拼接:地理坐标,投影坐标 /// 拼接输出ldf /// 支持按高度角数据拼接,高度角数据为后缀为".SolarZenith.ldf"的附加文件,值为扩大了100倍的short类型的高度角值。 /// </summary> /// <param name="args"> /// "D:\20131003|*_1000M.ldf" "D:\20131002\\FY3C_VIRR_1000M_global.ldf" "1,2,3" "0.01,0.01,-180,90,36000,18000" /// </param> static void Main(string[] args) { //new ToChinaCenter().Tran(); //return; if (args == null || args.Length != 4) { Console.WriteLine("输入参数错误:"); Console.WriteLine(" 指定目录[:搜索模式] 拼接后文件名 要拼接的波段(序号从1开始) 地理坐标(x分辨率,y分辨率,左上角经度,左上角纬度,宽度,高度)"); Console.WriteLine(@" 例如:D:\20131003|*_1000M.ldf D:\20131002\FY3C_VIRR_1000M_global.ldf 1,2,3 0.01,0.01,-180,90,36000,18000"); return; } string[] paths = args[0].Split('|'); string dir = paths[0]; if (!Directory.Exists(dir)) { Console.WriteLine("指定目录不存在:" + dir); return; } string mode = ""; if (paths.Length == 2) { mode = paths[1]; } string[] files = Directory.GetFiles(dir, mode, SearchOption.AllDirectories); string outfile = args[1]; string[] bands = args[2].Split(','); string geoString = args[3]; GeoInfo geoHeader = GeoInfo.Parse(geoString); if (geoHeader == null) { Console.WriteLine("输入参数错误:" + geoString); return; } if (geoHeader.ResX == 0 || geoHeader.ResY == 0) { Console.WriteLine("输入参数错误:" + geoString + "中分辨率解析为0"); return; } MosaicProcess c = new MosaicProcess(); c.Mosaic(files, outfile, geoHeader, bands, (p, txt) => { Console.WriteLine(string.Format("{0}% {1}", p, txt)); }); }
/// <summary> /// 地理数据拼接:地理坐标,投影坐标 /// 拼接输出ldf /// 支持按高度角数据拼接,高度角数据为后缀为".SolarZenith.ldf"的附加文件,值为扩大了100倍的short类型的高度角值。 /// 本拼接程序会判断是否有高度角数据:“.SolarZenith.ldf”,如果有,则拼接时候会依据高度角的大小关系执行是否覆盖操作,如果没有,则按照有无数据执行拼接。 /// </summary> /// <param name="rasterFiles"></param> /// <param name="outRasterFile"></param> /// <param name="geoHeader"></param> /// <param name="bandMaps"></param> /// <param name="progress"></param> public void Mosaic(string[] rasterFiles, string outRasterFile, GeoInfo geoHeader, string[] bandMaps, Action <int, string> progress) { int[] bandMap = null; if (!GetBandMap(bandMaps, out bandMap)) { if (progress != null) { progress(0, "输入参数错误,参数[要拼接的波段]不正确"); } return; } if (bandMap == null || bandMap.Length == 0) { if (progress != null) { progress(0, "输入参数错误,[要拼接的波段]为空或不正确"); } return; } int bandCount = bandMap.Length; ISpatialReference spatialRef = TryFindSpatialRef(rasterFiles); using (IRasterDataProvider outraster = CreateMosaicRaster(outRasterFile, geoHeader, bandCount, spatialRef)) { string filename = null; IRasterDataProvider raster = null; string solarZenithFilename = null; IRasterDataProvider solarZenithRaster = null; RasterMaper outSolarZenithMap = null;// new RasterMaper(solarZenithRaster, new int[] { 1 }); string outSolarZenithFile = Path.ChangeExtension(outRasterFile, ".SolarZenith.ldf"); IRasterDataProvider outSolarZenithRster = null; try { for (int f = 0; f < rasterFiles.Length; f++) { filename = rasterFiles[f]; solarZenithFilename = Path.ChangeExtension(filename, ".SolarZenith.ldf"); if (progress != null) { progress((int)((f + 1) * 100f / rasterFiles.Length), string.Format("{0}/{1}", f + 1, rasterFiles.Length)); } try { raster = GeoDataDriver.Open(filename) as IRasterDataProvider; if (raster == null) { continue; } //if (raster is ILdfDataProvider) //{ // Ldf1Header header = (raster as ILdfDataProvider).Header as Ldf1Header; // if (!header.IsDay) // { // Console.WriteLine("跳过晚上数据" + Path.GetFileName(filename)); // continue; // } //} if (File.Exists(outSolarZenithFile)) { outSolarZenithRster = GeoDataDriver.Open(outSolarZenithFile, enumDataProviderAccess.Update, null) as IRasterDataProvider; outSolarZenithMap = new RasterMaper(outSolarZenithRster, new int[] { 1 }); } RasterMaper rmSz = null; if (File.Exists(solarZenithFilename)) { solarZenithRaster = GeoDataDriver.Open(solarZenithFilename) as IRasterDataProvider; rmSz = new RasterMaper(solarZenithRaster, new int[] { 1 }); } RasterMaper rmin = new RasterMaper(raster, bandMap); RasterMaper rmout = new RasterMaper(outraster, bandMap); RasterProcessModel <short, short> rp = new RasterProcessModel <short, short>(); RasterMaper[] rmIns, rmOuts; if (rmSz != null) { rmIns = new RasterMaper[] { rmin, rmSz } } ; else { rmIns = new RasterMaper[] { rmin } }; if (outSolarZenithMap != null) { rmOuts = new RasterMaper[] { rmout, outSolarZenithMap } } ; else { rmOuts = new RasterMaper[] { rmout } }; rp.SetRaster(rmIns, rmOuts); rp.RegisterCalcModel(new RasterCalcHandlerFun <short, short>((rasterVistor, target, map) => { if (rasterVistor[0] == null || rasterVistor[0].RasterBandsData.Length == 0) { return(false); } if (target[0] == null || target[0].RasterBandsData[0].Length == 0) { return(false); } if (rasterVistor[0].RasterBandsData[0] == null) { return(false); } //目标角度数据存在,源角度数据不存在,不做拼接 if (target.Length != 1 && rasterVistor.Length == 1) { return(false); } bool isUpdate = false; //不使用天顶角数据,补数据 if (target.Length == 1 || rasterVistor.Length == 1) { for (int i = 0; i < target[0].RasterBandsData[0].Length; i++) { if (rasterVistor[0].RasterBandsData[0][i] == 0)//空值 { continue; } if (target[0].RasterBandsData[0][i] == 0) { isUpdate = true; for (int b = 0; b < bandCount; b++) { target[0].RasterBandsData[b][i] = rasterVistor[0].RasterBandsData[b][i]; } } } } else { for (int i = 0; i < target[0].RasterBandsData[0].Length; i++) { if (rasterVistor[0].RasterBandsData[0][i] == 0)//空值 { continue; } /* * 太阳高度表示昼夜状态 * 在晨昏线上的各地太阳高度为0 °,表示正经历昼夜更替; * 在昼半球上的各地太阳高度大于0°,表示白昼; * 在夜半球上的各地太阳高度小于0°,表示黑夜。 * 日出、日落时,太阳高度为0 * 即: * 0°附近在日落或日出 * -90°和0°之间在晚上 * 上午太阳高度逐渐增大,最大时为太阳上中天,即是正午,午后太阳高度又逐渐缩小。 */ //(高度角 = 90 - 天顶角) //高度角有效范围: //这里读取的是SolarZenith太阳天顶,有效范围0-180。 //天顶角0-90为白天,小值为接近中午 if (rasterVistor.Length == 1 || rasterVistor[1] == null || rasterVistor[1].RasterBandsData[0] == null || target.Length == 1 || target[1] == null) { if (target[0].RasterBandsData[0][i] == 0)//如果没有角度数据,则采取补数据的方式(即不覆盖已有数据) { isUpdate = true; for (int b = 0; b < bandCount; b++)//拼接所有通道数据 { target[0].RasterBandsData[b][i] = rasterVistor[0].RasterBandsData[b][i]; } } } else if (rasterVistor[1].RasterBandsData[0][i] > 9000 || rasterVistor[1].RasterBandsData[0][i] < 0)//原高度角为夜晚或者不合理 { continue; } else if (target[1].RasterBandsData[0][i] == 0) { isUpdate = true; for (int b = 0; b < bandCount; b++) { target[0].RasterBandsData[b][i] = rasterVistor[0].RasterBandsData[b][i]; } //更新目标高度角数据 target[1].RasterBandsData[0][i] = rasterVistor[1].RasterBandsData[0][i]; } else if (rasterVistor[1].RasterBandsData[0][i] < target[1].RasterBandsData[0][i])//取高度角小的 { isUpdate = true; for (int b = 0; b < bandCount; b++) { target[0].RasterBandsData[b][i] = rasterVistor[0].RasterBandsData[b][i]; } //更新目标高度角数据 target[1].RasterBandsData[0][i] = rasterVistor[1].RasterBandsData[0][i]; } } } if (isUpdate) { return(true); } else { return(false); } } )); int rowCount = rp.CalcRowCount(); rp.Excute(0, rowCount); } finally { if (raster != null) { raster.Dispose(); raster = null; } if (outSolarZenithRster != null) { outSolarZenithRster.Dispose(); outSolarZenithRster = null; } } } } finally { if (outSolarZenithRster != null) { outSolarZenithRster.Dispose(); outSolarZenithRster = null; } } } }