private IRasterDataProvider CreateOutRaster(string outdir, IRasterDataProvider raster, ISpatialReference dstSpatial, PrjEnvelope envelope, double resolutionX, double resolutionY, string bandNames) { IRasterDataProvider outRaster = null; if (raster.Driver.Name == "MEM") //smart 产品数据,输出也用MEM驱动,目前数据纠正这里不存在。 { string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=MEM", "SPATIALREF=" + dstSpatial.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + envelope.MinX + "," + envelope.MaxY + "}:{" + resolutionX + "," + resolutionY + "}", string.IsNullOrWhiteSpace(bandNames)?"": "BANDNAMES=" + bandNames }; string outfilename = Path.Combine(outdir, Path.GetFileNameWithoutExtension(raster.fileName) + ".DAT"); outRaster = (raster.Driver as IRasterDataDriver).Create(outfilename, raster.Width, raster.Height, 1, enumDataType.Int16, options); } else//ldf { string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "SPATIALREF=" + dstSpatial.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + envelope.MinX + "," + envelope.MaxY + "}:{" + resolutionX + "," + resolutionY + "}", "DATETIME=" + raster.DataIdentify.OrbitDateTime, string.IsNullOrWhiteSpace(bandNames)?"": "BANDNAMES=" + bandNames }; string outfilename = Path.Combine(outdir, Path.GetFileNameWithoutExtension(raster.fileName) + ".LDF"); IRasterDataDriver driver = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver; outRaster = driver.Create(outfilename, raster.Width, raster.Height, 1, enumDataType.Int16, options); } return(outRaster); }
private string[] LdfOptions(FilePrjSettings prjSettings, ISpatialReference dstSpatial, float resolutionX, float resolutionY, DataIdentify dataIdentify) { List <string> options = new List <string>(); options.Add("INTERLEAVE=BSQ"); options.Add("VERSION=LDF"); options.Add("SPATIALREF=" + dstSpatial.ToProj4String()); options.Add("MAPINFO={" + 1 + "," + 1 + "}:{" + prjSettings.OutEnvelope.MinX + "," + prjSettings.OutEnvelope.MaxY + "}:{" + resolutionX + "," + resolutionY + "}"); options.Add("SENSOR=NOM"); if (dataIdentify != null) { string satellite = dataIdentify.Satellite; DateTime dt = dataIdentify.OrbitDateTime; bool asc = dataIdentify.IsAscOrbitDirection; if (!string.IsNullOrWhiteSpace(satellite)) { options.Add("SATELLITE=" + satellite); } if (dt != DateTime.MinValue && dt != DateTime.MaxValue) { options.Add("DATETIME=" + dt.ToString("yyyy/MM/dd HH:mm")); } } return(options.ToArray()); }
private IRasterDataProvider CreateOutFile(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, ISpatialReference dstSpatial, enumDataType dataType) { float resolutionX = prjSettings.OutResolutionX; float resolutionY = prjSettings.OutResolutionY; string[] options = null; string outformat = string.IsNullOrWhiteSpace(prjSettings.OutFormat) ? "LDF" : prjSettings.OutFormat.ToUpper(); string driver = ""; if (outformat == "TIFF") { driver = "GDAL"; options = new string[] { "DRIVERNAME=GTiff", "TFW=YES", "WKT=" + dstSpatial.ToWKTString(), "GEOTRANSFORM=" + string.Format("{0},{1},{2},{3},{4},{5}", prjSettings.OutEnvelope.MinX, resolutionX, 0, prjSettings.OutEnvelope.MaxY, 0, -resolutionY) }; } else if (outformat == "MEM") { driver = "MEM"; options = new string[] { "INTERLEAVE=BSQ", "VERSION=MEM", "WITHHDR=TRUE", "SPATIALREF=" + dstSpatial.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + prjSettings.OutEnvelope.MinX + "," + prjSettings.OutEnvelope.MaxY + "}:{" + resolutionX + "," + resolutionY + "}" }; } else { driver = "LDF"; options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "SPATIALREF=" + dstSpatial.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + prjSettings.OutEnvelope.MinX + "," + prjSettings.OutEnvelope.MaxY + "}:{" + resolutionX + "," + resolutionY + "}", "BANDNAMES=" + BandNameString(srcRaster, prjSettings.OutBandNos) }; } Size outSize = prjSettings.OutEnvelope.GetSize(resolutionX, resolutionY); int bandCount = prjSettings.OutBandNos.Length; string filename = prjSettings.OutPathAndFileName; return(CreateOutFile(driver, filename, bandCount, outSize, dataType, options)); }
private IRasterDataProvider CreateDstDataProvider(IRasterDataDriver driver, string outFile, IRasterDataProvider dataProvider) { ISpatialReference spatialRef = dataProvider.SpatialRef ?? new SpatialReference(new GeographicCoordSystem()); string spRef = "SPATIALREF=" + spatialRef.ToProj4String(); string mapInf = dataProvider.CoordEnvelope.ToMapInfoString(new Size(dataProvider.Width, dataProvider.Height)); return(driver.Create(outFile, dataProvider.Width, dataProvider.Height, 1, enumDataType.Float, spRef, mapInf, "WITHHDR=TRUE")); }
/// <summary> /// 0、先生成目标文件,以防止目标空间不足。 /// 1、计算查找表 /// 2、对所有波段执行投影 /// </summary> private void ProjectToLDF(IRasterDataProvider srcRaster, FY3_VIRR_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { string outFormat = prjSettings.OutFormat; string outfilename = prjSettings.OutPathAndFileName; string dstProj4 = dstSpatialRef.ToProj4String(); List <BandMap> bandMaps = prjSettings.BandMapTable; int dstBandCount = bandMaps.Count; Size srcSize = new Size(srcRaster.Width, srcRaster.Height); Size dstSize = prjSettings.OutSize; using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver) { PrjEnvelope dstEnvelope = prjSettings.OutEnvelope; string mapInfo = "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}"; using (IRasterDataProvider prdWriter = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount, enumDataType.UInt16, "INTERLEAVE=BSQ", "VERSION=LDF", "SPATIALREF=" + dstProj4, mapInfo, "WITHHDR=TRUE") as IRasterDataProvider) { //计算查找表 //ISpatialReference srcSpatialRef = srcRaster.SpatialRef; UInt16[] dstRowLookUpTable = new UInt16[dstSize.Width * dstSize.Height]; UInt16[] dstColLookUpTable = new UInt16[dstSize.Width * dstSize.Height]; _rasterProjector.ComputeIndexMapTable(_xs, _ys, srcSize, dstSize, dstEnvelope, _maxPrjEnvelope, out dstRowLookUpTable, out dstColLookUpTable, progressCallback); //执行投影 UInt16[] srcBandData = new UInt16[srcSize.Width * srcSize.Height]; UInt16[] dstBandData = new UInt16[dstSize.Width * dstSize.Height]; int progress = 0; for (int i = 0; i < dstBandCount; i++) //读取原始通道值,投影到目标区域 { if (progressCallback != null) { progress = (int)((i + 1) * 100 / dstBandCount); progressCallback(progress, string.Format("投影第{0}共{1}通道", i + 1, dstBandCount)); } BandMap bandMap = bandMaps[i]; ReadBandData(srcBandData, bandMap.File, bandMap.DatasetName, bandMap.BandIndex, srcSize); if (prjSettings.IsRadiation) { DoRadiation(srcBandData, srcSize, bandMap.DatasetName, bandMap.BandIndex, prjSettings.IsSolarZenith); } _rasterProjector.Project <UInt16>(srcBandData, srcSize, dstRowLookUpTable, dstColLookUpTable, dstSize, dstBandData, 0, progressCallback); using (IRasterBand band = prdWriter.GetRasterBand(i + 1)) { unsafe { fixed(UInt16 *ptr = dstBandData) { IntPtr bufferPtr = new IntPtr(ptr); band.Write(0, 0, band.Width, band.Height, bufferPtr, enumDataType.UInt16, band.Width, band.Height); } } } } } } }
private void button1_Click(object sender, EventArgs e) { ISpatialReference srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("WGS 1984.prj"); string prj4 = srcSpatialRef.ToProj4String(); ISpatialReference dstSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("WGS 1984.prj"); using (IProjectionTransform tran = ProjectionTransformFactory.GetProjectionTransform(srcSpatialRef, dstSpatialRef)) { } }
public void Test() { ISpatialReference srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("WGS 1984.prj"); srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("Mercator (sphere).prj"); string proj4 = srcSpatialRef.ToProj4String(); Assert.AreEqual(proj4, "+proj=merc +x_0=0 +y_0=0 +lon_0=0 +lat_1=0 +datum=WGS84 +a=6371000 +b=6356863.01877305+f=正无穷大 +nodefs"); srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByProj4String(proj4); }
//private void button4_Click(object sender, EventArgs e) //{ // ISpatialReference srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("WGS 1984.prj"); // srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("Mercator (sphere).prj"); // string proj4 = srcSpatialRef.ToProj4String(); // srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByProj4String(proj4); //} //private void button4_Click(object sender, EventArgs e) //{ // TestFy3AVirrProjection fyp = new TestFy3AVirrProjection(); // Action<int, string> progressCallback = new Action<int, string>(OutProgress); // fyp.DataReady(progressCallback); // Stopwatch stopwatch = new Stopwatch(); // stopwatch.Start(); // fyp.TestFy3VIRR(); // stopwatch.Stop(); // WriteLine("数据投影{0}ms", stopwatch.ElapsedMilliseconds); // stopwatch.Restart(); //} private void TestPrj4Parser_Click(object sender, EventArgs e) { ISpatialReference srcSpatialRef = null;// SpatialReferenceFactory.GetSpatialReferenceByPrjFile("WGS 1984.prj"); string prjFile = "f:\\32600.prj"; srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("Mercator (sphere).prj"); string proj4 = srcSpatialRef.ToProj4String(); ISpatialReference inverSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByProj4String(proj4); bool isSame = srcSpatialRef.IsSame(inverSpatialRef); }
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); }
public void Resample(RSS.Core.DF.IRasterDataProvider srcRaster, FileResampleSetting resSettings, Action <int, string> progressCallback) { if (srcRaster == null) { throw new ArgumentNullException("srcRaster", "待重采样数据为空"); } if (resSettings == null) { throw new ArgumentNullException("prjSettings", "重采样参数为空"); } ReadExtArgs(resSettings); string outfilename = resSettings.OutPathAndFileName; IRasterDataProvider outwriter = null; try { Size outSize = _resSettings.OutSize; string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + _dstSpatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + _resSettings.OutEnvelope.MinX + "," + _resSettings.OutEnvelope.MaxY + "}:{" + _resSettings.OutResolutionX + "," + _resSettings.OutResolutionY + "}" }; outwriter = CreateOutFile(outfilename, srcRaster.BandCount, outSize, srcRaster.DataType, options); if (File.Exists(outfilename)) { ResampleRaster(srcRaster, outwriter, progressCallback); } else { throw new FileLoadException("目标文件" + outfilename + "不存在!"); } } catch (IOException ex) { if (ex.Message == "磁盘空间不足。\r\n" && File.Exists(outfilename)) { File.Delete(outfilename); } throw ex; } finally { if (outwriter != null) { outwriter.Dispose(); outwriter = null; } } }
private string GetPrjInfo() { try { ISpatialReference prjInfo = SpatialReference.GetDefault(); PrimeMeridian centerLongitude = prjInfo.GeographicsCoordSystem.PrimeMeridian; centerLongitude.Value = 150d; return(prjInfo.ToProj4String()); } catch { return(null); } }
private string[] CreateLDFOptions(ISpatialReference spatialRef) { string bandNames = ""; string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + spatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + _env.MinX + "," + _env.MaxY + "}:{" + _resX + "," + _resY + "}", "BANDNAMES=" + bandNames }; return(options); }
public ProjectionTransform(ISpatialReference srcSpatialRef, ISpatialReference dstSpatialRef) { if (srcSpatialRef == null) { throw new ArgumentNullException("源空间参考对象为空。"); } if (dstSpatialRef == null) { throw new ArgumentNullException("目标空间参考对象为空。"); } _srcProjection = new Proj4Projection(srcSpatialRef.ToProj4String()); _dstProjection = new Proj4Projection(dstSpatialRef.ToProj4String()); _srcProjection._coordinateDomain = srcSpatialRef.CoordinateDomain; _dstProjection._coordinateDomain = dstSpatialRef.CoordinateDomain; }
private IRasterDataProvider CreateMosaicFile(IRasterDataProvider copyRaster, PrjEnvelope env, string filename) { ISpatialReference spatialRef = copyRaster.SpatialRef; string bandNames = BandNameString(copyRaster as ILdfDataProvider); Size outSize = env.GetSize(copyRaster.ResolutionX, copyRaster.ResolutionY); string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + spatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + env.MinX + "," + env.MaxY + "}:{" + copyRaster.ResolutionX + "," + copyRaster.ResolutionY + "}", "BANDNAMES=" + bandNames }; return(IdentifyOutFile(filename, copyRaster.BandCount, outSize, copyRaster.DataType, options)); }
private IRasterDataProvider CreateMosaicFile(string mosaicFilename, InputArg inArg) { ISpatialReference spatialRef = fileRaster.SpatialRef; PrjEnvelope env = inArg.MosaicInputArg.Envelope.PrjEnvelope; string bandNames = BandNameString(fileRaster as ILdfDataProvider); Size outSize = env.GetSize(fileRaster.ResolutionX, fileRaster.ResolutionY); string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + spatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + env.MinX + "," + env.MaxY + "}:{" + fileRaster.ResolutionX + "," + fileRaster.ResolutionY + "}", "BANDNAMES=" + bandNames }; return(CreateOutFile(mosaicFilename, fileRaster.BandCount, outSize, enumDataType.UInt16, options)); }
public void ParseProj4() { string proj4 = "+proj=merc +lon_0=0 +k0=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137"; Console.WriteLine("INPUT:"); Console.WriteLine(proj4); ISpatialReference spatialRef = SpatialReferenceFactory.GetSpatialReferenceByProj4String(proj4); Console.WriteLine("ESRI WKT:"); Console.WriteLine(spatialRef.ToString()); Console.WriteLine("PROJ.4:"); Console.WriteLine(spatialRef.ToProj4String()); Console.WriteLine("OGC WKT:"); Console.WriteLine(spatialRef.ToWKTString()); Console.WriteLine("ENVI Projection Info:"); Console.WriteLine(spatialRef.ToEnviProjectionInfoString()); }
private object[] GetOptions(CoordEnvelope outputEnvelope, int width, int height) { List<string> ops = new List<string>(); if (_coordEnvelope != null) ops.Add(outputEnvelope.ToMapInfoString(new Size(width, height))); if (_spatialRef != null) { try { string spref = _spatialRef.ToProj4String(); ops.Add("SPATIALREF=" + spref); } catch (Exception ex) { Console.Write(ex.Message); } } return ops.Count > 0 ? ops.ToArray() : null; }
private string[] CreateLDFOptions(IRasterDataProvider inRaster) { CoordEnvelope outEnv = inRaster.CoordEnvelope; float resX = inRaster.ResolutionX; float resY = inRaster.ResolutionY; int width = inRaster.Width; int height = inRaster.Height; ISpatialReference spatialRef = inRaster.SpatialRef; string bandNames = ""; string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + spatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + outEnv.MinX + "," + outEnv.MaxY + "}:{" + resX + "," + resY + "}", "BANDNAMES=" + bandNames }; return(options); }
private void button18_Click(object sender, EventArgs e) { string wkt = "GEOGCS[\"等经纬度投影\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]]"; wkt = "PROJCS[\"Hammer投影\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Hammer-Aitoff (world)\"]PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],PARAMETER[\"central_meridian\",105],UNIT[\"Meter\",1]]"; ISpatialReference srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByWKT(wkt, enumWKTSource.EsriPrjFile); string proj4 = srcSpatialRef.ToProj4String(); ISpatialReference inverSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByProj4String(proj4); inverSpatialRef.IsSame(srcSpatialRef); IProjectionTransform tr = ProjectionTransformFactory.GetProjectionTransform(srcSpatialRef, SpatialReference.GetDefault()); double[] x = new double[] { 1534910 }; double[] y = new double[] { 4255978 }; x = new double[] { 121.913 }; y = new double[] { 38.957 }; tr.InverTransform(x, y); tr.Transform(x, y); }
private object[] GetOptions() { List <string> ops = new List <string>(); if (_coordEnvelope != null) { ops.Add(_coordEnvelope.ToMapInfoString(new Size(vData.Width, vData.Height))); } if (_spatialRef != null) { try { string spref = _spatialRef.ToProj4String(); ops.Add("SPATIALREF=" + spref); } catch (Exception ex) { Console.Write(ex.Message); } } return(ops.Count > 0 ? ops.ToArray() : null); }
private object[] GetOptions() { List <string> ops = new List <string>(); if (_coordEnvelope != null) { ops.Add(_coordEnvelope.ToMapInfoString(_size)); } if (_spatialRef != null) { try { string spref = _spatialRef.ToProj4String(); ops.Add("SPATIALREF=" + spref); } catch (Exception ex) { Console.Write(ex.Message); } } ops.Add("ExtHeaderSize=" + _extHeaderSize.ToString()); return(ops.Count > 0 ? ops.ToArray() : null); }
private void TestProj() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Size srSize = Size.Empty; Double[] lats = null; Double[] longs = null; using (IRasterDataProvider srcPrd = GeoDataDriver.Open(@"D:\masData\FY3A_VIRRX_GBAL_L1_20110322_0525_1000M_MS.HDF") as IRasterDataProvider) { using (IBandProvider srcbandpro = srcPrd.BandProvider as IBandProvider) { srSize = new System.Drawing.Size(srcPrd.Width, srcPrd.Height); lats = new Double[srcPrd.Width * srcPrd.Height]; longs = new Double[srcPrd.Width * srcPrd.Height]; using (IRasterBand latBand = srcbandpro.GetBands("Latitude")[0]) { using (IRasterBand lonsBand = srcbandpro.GetBands("Longitude")[0]) { unsafe { fixed(Double *ptrLat = lats) { fixed(Double *ptrLong = longs) { IntPtr bufferPtrLat = new IntPtr(ptrLat); IntPtr bufferPtrLong = new IntPtr(ptrLong); latBand.Read(0, 0, srcPrd.Width, srcPrd.Height, bufferPtrLat, enumDataType.Double, srcPrd.Width, srcPrd.Height); lonsBand.Read(0, 0, srcPrd.Width, srcPrd.Height, bufferPtrLong, enumDataType.Double, srcPrd.Width, srcPrd.Height); } } } } } stopwatch.Stop(); WriteLine("读取经纬度{0}ms", stopwatch.ElapsedMilliseconds); stopwatch.Restart(); IRasterProjector raster = new RasterProjector(); PrjEnvelope destEnvelope; Action <int, string> progressCallback = new Action <int, string>(OutProgress); //progressCallback = null; //测试不用进度条的情况 ISpatialReference srcSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("WGS 1984.prj"); ISpatialReference dstSpatialRef = SpatialReferenceFactory.GetSpatialReferenceByPrjFile("ChinaBoundary.prj"); raster.ComputeDstEnvelope(srcSpatialRef, longs, lats, srSize, dstSpatialRef, out destEnvelope, progressCallback); stopwatch.Stop(); WriteLine("计算范围{0}ms", stopwatch.ElapsedMilliseconds); WriteLine("范围{0}", destEnvelope.ToString()); Size dstSize = new Size((int)(destEnvelope.Width / 0.01), (int)(destEnvelope.Height / 0.01)); UInt16[] dstRowLookUpTable = new UInt16[dstSize.Width * dstSize.Height]; UInt16[] dstColLookUpTable = new UInt16[dstSize.Width * dstSize.Height]; raster.ComputeIndexMapTable(srcSpatialRef, longs, lats, srSize, dstSpatialRef, dstSize, destEnvelope, out dstRowLookUpTable, out dstColLookUpTable, progressCallback); stopwatch.Stop(); WriteLine("计算投影查找表{0}ms", stopwatch.ElapsedMilliseconds); stopwatch.Restart(); int srcBandCount = srcPrd.BandCount; using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver) { string proj4 = dstSpatialRef.ToProj4String(); using (IRasterDataProvider prdWriter = drv.Create(@"d:\Myproj4LutX.ldf", dstSize.Width, dstSize.Height, srcBandCount, enumDataType.UInt16, "INTERLEAVE=BSQ", "VERSION=LDF", "SPATIALREF=" + proj4) as IRasterDataProvider) { UInt16[] dstData = new UInt16[dstSize.Width * dstSize.Height]; UInt16[] srcData = new UInt16[srSize.Width * srSize.Height]; //int perProgress = 0; //int curProgress = 0; for (int i = 0; i < srcBandCount; i++) { using (IRasterBand latBand = srcPrd.GetRasterBand(i + 1)) { unsafe { fixed(UInt16 *ptr = srcData) { IntPtr bufferptr = new IntPtr(ptr); latBand.Read(0, 0, srSize.Width, srSize.Height, bufferptr, enumDataType.UInt16, srSize.Width, srSize.Height); } } } //stopwatch.Stop(); //WriteLine("读取一个通道{0}ms,通道索引{1}", stopwatch.ElapsedMilliseconds, i + 1); //stopwatch.Restart(); raster.Project <UInt16>(srcData, srSize, dstRowLookUpTable, dstColLookUpTable, dstSize, dstData, 0, progressCallback); //stopwatch.Stop(); //WriteLine("投影一个通道{0}ms,通道索引{1}", stopwatch.ElapsedMilliseconds, i + 1); //stopwatch.Restart(); using (IRasterBand band = prdWriter.GetRasterBand(i + 1)) { unsafe { fixed(UInt16 *ptr = dstData) { IntPtr bufferPtr = new IntPtr(ptr); band.Write(0, 0, band.Width, band.Height, bufferPtr, enumDataType.UInt16, band.Width, band.Height); } } } //curProgress = (i+1) * 100 / srcBandCount; //if (progressCallback != null && curProgress > perProgress) //{ // progressCallback(curProgress, ""); // perProgress = curProgress; //} //stopwatch.Stop(); //WriteLine("写出一个通道{0}ms", stopwatch.ElapsedMilliseconds); //stopwatch.Restart(); } } } stopwatch.Stop(); WriteLine("投影完所有通道{0}ms", stopwatch.ElapsedMilliseconds); stopwatch.Restart(); } } }
private void ReadyArgs(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { float resolutionScale = 1f; _readyProgress = 0; if (progressCallback != null) { progressCallback(_readyProgress++, "准备相关参数"); } if (dstSpatialRef == null) { dstSpatialRef = SpatialReference.GetDefault(); } _dstSpatialRef = dstSpatialRef; _prjSettings = ArgsCheck(srcRaster, prjSettings, progressCallback); //_fileType = CheckFile(srcRaster); _locationRaster = (prjSettings as FY3L2L3FilePrjSettings).LocationFile; ReadExtArgs(prjSettings); TryCreateDefaultArg(srcRaster, _prjSettings, ref _dstSpatialRef); _left = 0; _right = 0; TrySetLeftRightInvalidPixel(_prjSettings.ExtArgs); DoSession(srcRaster, _dstSpatialRef, _prjSettings, progressCallback); if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) { _prjSettings.OutEnvelope = _maxPrjEnvelope; _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = srcRaster.Width - 1, yEnd = srcRaster.Height - 1 }; } else { GetEnvelope(_xs, _ys, _srcLocationSize.Width, _srcLocationSize.Height, _prjSettings.OutEnvelope, out _orbitBlock); if (_orbitBlock == null || _orbitBlock.Width <= 0 || _orbitBlock.Height <= 0) { throw new Exception("数据不在目标区间内"); } float invalidPresent = (_orbitBlock.Width * _orbitBlock.Height * resolutionScale) / (srcRaster.Width * srcRaster.Height); if (invalidPresent < 0.0001f) { throw new Exception("数据占轨道数据比例太小,有效率" + invalidPresent * 100 + "%"); } if (invalidPresent > 0.60f) { _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = srcRaster.Width - 1, yEnd = srcRaster.Height - 1 } } ; } _dstEnvelope = _prjSettings.OutEnvelope; if (!_dstEnvelope.IntersectsWith(_maxPrjEnvelope)) { throw new Exception("数据不在目标区间内"); } _outResolutionX = _prjSettings.OutResolutionX; _outResolutionY = _prjSettings.OutResolutionY; _outFormat = _prjSettings.OutFormat; _outfilename = _prjSettings.OutPathAndFileName; _dstProj4 = _dstSpatialRef.ToProj4String(); //_dstBandCount = _prjBands.Length; _dstBandCount = _rasterDataBands.Length; _dstSize = _prjSettings.OutSize; //_isRadiation = _prjSettings.IsRadiation; //_isSolarZenith = _prjSettings.IsSolarZenith; //_isSensorZenith = _prjSettings.IsSensorZenith; }
public override void Project(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { try { ReadyArgs(srcRaster, prjSettings, dstSpatialRef, progressCallback); IRasterDataProvider outwriter = null; try { List <string> options = new List <string>(); options.Add("INTERLEAVE=BSQ"); options.Add("VERSION=LDF"); options.Add("WITHHDR=TRUE"); options.Add("SPATIALREF=" + dstSpatialRef.ToProj4String()); options.Add("MAPINFO={" + 1 + "," + 1 + "}:{" + _prjSettings.OutEnvelope.MinX + "," + _prjSettings.OutEnvelope.MaxY + "}:{" + _outResolutionX + "," + _outResolutionY + "}"); options.Add("SENSOR=VIRR"); if (srcRaster.DataIdentify != null) { string satellite = srcRaster.DataIdentify.Satellite; DateTime dt = srcRaster.DataIdentify.OrbitDateTime; bool asc = srcRaster.DataIdentify.IsAscOrbitDirection; if (!string.IsNullOrWhiteSpace(satellite)) { options.Add("SATELLITE=" + satellite); } if (dt != DateTime.MinValue && dt != DateTime.MaxValue) { options.Add("DATETIME=" + dt.ToString("yyyy/MM/dd HH:mm")); } options.Add("ORBITDIRECTION=" + (asc ? "ASC" : "DESC")); if (srcRaster.DataIdentify.DayOrNight == enumDayOrNight.Day) { options.Add("DAYNIGHT=D"); } else if (srcRaster.DataIdentify.DayOrNight == enumDayOrNight.Night) { options.Add("DAYNIGHT=N"); } } List <string> op1 = new List <string>(options); op1.Add("BANDNAMES=" + BandNameString(_prjSettings.OutBandNos)); outwriter = CreateOutFile(_outfilename, _dstBandCount, _dstSize, op1.ToArray()); ReadyAngleFiles(_geoDataProvider, _outfilename, _prjSettings, _dstSize, options.ToArray()); ReadyExtBands(_geoDataProvider, _outfilename, _prjSettings, _dstSize, options.ToArray()); ProjectToLDF(srcRaster, outwriter, 0, progressCallback); } catch (IOException ex) { if (ex.Message == "磁盘空间不足。\r\n" && File.Exists(_outfilename)) { File.Delete(_outfilename); } throw ex; } finally { if (outwriter != null) { outwriter.Dispose(); outwriter = null; } } } catch { EndSession(); TryDeleteCurCatch(); throw; } finally { if (_curSession == null) { EndSession(); if (prjSettings.IsClearPrjCache) { TryDeleteCurCatch(); } } } }
public override IRasterDataProvider Project(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, IRasterDataProvider dstRaster, int beginBandIndex, Action <int, string> progressCallback) { if (srcRaster == null) { throw new ArgumentNullException("srcRaster"); } if (prjSettings == null) { throw new ArgumentNullException("prjSettings"); } if (dstRaster == null && prjSettings.OutPathAndFileName == null) { throw new ArgumentNullException("dstRaster"); } try { FY3_VIRR_PrjSettings fy3prjSettings = prjSettings as FY3_VIRR_PrjSettings; ISpatialReference dstSpatialRef = dstRaster.SpatialRef; TryCreateDefaultArgs(srcRaster, fy3prjSettings, ref dstSpatialRef); DoSession(srcRaster, _geoDataProvider, dstSpatialRef, fy3prjSettings, progressCallback); if (prjSettings.OutEnvelope == null || prjSettings.OutEnvelope == PrjEnvelope.Empty) { prjSettings.OutEnvelope = _maxPrjEnvelope; } if (dstSpatialRef.ProjectionCoordSystem == null && (prjSettings.OutEnvelope.MaxY > 80 || prjSettings.OutEnvelope.MaxY < -80)) { throw new Exception(string.Format("高纬度数据[>80],不适合投影为等经纬度数据[{0}]", _maxPrjEnvelope)); } if (dstRaster == null) { PrjEnvelope dstEnvelope = prjSettings.OutEnvelope; string outFormat = prjSettings.OutFormat; string outfilename = prjSettings.OutPathAndFileName; string dstProj4 = dstSpatialRef.ToProj4String(); int dstBandCount = _prjBands.Length; Size srcSize = new Size(srcRaster.Width, srcRaster.Height); Size dstSize = prjSettings.OutSize; IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver; string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + dstProj4, "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}" }; dstRaster = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount, enumDataType.UInt16, options) as IRasterDataProvider; } ProjectToLDF(srcRaster, dstRaster, 0, progressCallback); return(dstRaster); } catch { EndSession(); TryDeleteCurCatch(); throw; } finally { EndSession(); if (prjSettings.IsClearPrjCache) { TryDeleteCurCatch(); } } }
private void ReadyArgs(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { if (srcRaster == null) { throw new ArgumentNullException("srcRaster"); } if (prjSettings == null) { throw new ArgumentNullException("prjSettings"); } _readyProgress = 0; _prjSettings = prjSettings as FY3_VIRR_PrjSettings; _geoDataProvider = (prjSettings as FY3_VIRR_PrjSettings).GeoFile; _dstSpatialRef = dstSpatialRef; MemoryHelper.MemoryNeed(200, 1536);//剩余200MB,已使用1.2GB if (progressCallback != null) { progressCallback(_readyProgress++, "准备相关参数"); } TryCreateDefaultArgs(srcRaster, _prjSettings, ref dstSpatialRef); //这里去除的是读取轨道数据时候的左右像元个数。 _left = 8; _right = 8; TrySetLeftRightInvalidPixel(_prjSettings.ExtArgs); DoSession(srcRaster, _geoDataProvider, dstSpatialRef, _prjSettings, progressCallback); if (prjSettings.OutEnvelope == null || prjSettings.OutEnvelope == PrjEnvelope.Empty) { prjSettings.OutEnvelope = _maxPrjEnvelope; _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = srcRaster.Width - 1, yEnd = srcRaster.Height - 1 }; } else { GetEnvelope(_xs, _ys, srcRaster.Width, srcRaster.Height, _prjSettings.OutEnvelope, out _orbitBlock); if (_orbitBlock == null || _orbitBlock.Width <= 0 || _orbitBlock.Height <= 0) { throw new Exception("数据不在目标区间内"); } float invalidPresent = (_orbitBlock.Width * _orbitBlock.Height * 1.0F) / (srcRaster.Width * srcRaster.Height); if (invalidPresent < 0.0001f) { throw new Exception("数据占轨道数据比例太小,有效率" + invalidPresent * 100 + "%"); } if (invalidPresent > 0.60) { _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = srcRaster.Width - 1, yEnd = srcRaster.Height - 1 } } ; } //if (dstSpatialRef.ProjectionCoordSystem == null && (prjSettings.OutEnvelope.MaxY > 80 || prjSettings.OutEnvelope.MaxY < -80)) // throw new Exception(string.Format("高纬度数据,不适合投影为等经纬度数据[{0}]", _maxPrjEnvelope)); _dstSpatialRef = dstSpatialRef; _dstEnvelope = _prjSettings.OutEnvelope; if (!_dstEnvelope.IntersectsWith(_maxPrjEnvelope)) { throw new Exception("数据不在目标区间内"); } _outResolutionX = _prjSettings.OutResolutionX; _outResolutionY = _prjSettings.OutResolutionY; _outFormat = _prjSettings.OutFormat; _outfilename = _prjSettings.OutPathAndFileName; _dstProj4 = _dstSpatialRef.ToProj4String(); _dstBandCount = _prjBands.Length; _dstSize = _prjSettings.OutSize; _isRadiation = _prjSettings.IsRadiation; _isSolarZenith = _prjSettings.IsSolarZenith; _isSensorZenith = _prjSettings.IsSensorZenith; }
private void ProjectToLDF0500(IRasterDataProvider srcRaster, Size srcLocationSize, EOS_MODIS_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { if (srcRaster == null || srcRaster.Width == 0 || srcRaster.Height == 0) { throw new Exception("投影250米MERSI数据失败:无法读取源数据,或者源数据高或宽为0。"); } Size srcDataSize = new Size(srcRaster.Width, srcRaster.Height); string outFormat = prjSettings.OutFormat; string outfilename = prjSettings.OutPathAndFileName; string dstProj4 = dstSpatialRef.ToProj4String(); List <BandMap> bandMaps = prjSettings.BandMapTable; int dstBandCount = bandMaps.Count; Size dstSize = prjSettings.OutSize; using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver) { PrjEnvelope dstEnvelope = prjSettings.OutEnvelope; string mapInfo = "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}"; using (IRasterDataProvider prdWriter = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount, enumDataType.UInt16, "INTERLEAVE=BSQ", "VERSION=LDF", "SPATIALREF=" + dstProj4, mapInfo, "WITHHDR=TRUE") as IRasterDataProvider) { //考虑分块 float outResolutionX = prjSettings.OutResolutionX; float outResolutionY = prjSettings.OutResolutionY; Size outSize = dstEnvelope.GetSize(outResolutionX, outResolutionY); #region 计算分块个数、分块高宽 int blockXNum; int blockYNum; int blockWidth; int blockHeight; GetBlockNumber(outSize, out blockXNum, out blockYNum, out blockWidth, out blockHeight); #endregion Size blockSize = new Size(blockWidth, blockHeight); for (int blockYIndex = 0; blockYIndex < blockYNum; blockYIndex++) { for (int blockXIndex = 0; blockXIndex < blockXNum; blockXIndex++) { //当前块的四角范围 double blockMinX = dstEnvelope.MinX + blockWidth * outResolutionX * blockXIndex; double blockMaxX = blockMinX + blockWidth * outResolutionX; double blockMaxY = dstEnvelope.MaxY - blockHeight * outResolutionY * blockYIndex; double blockMinY = blockMaxY - blockHeight * outResolutionY; PrjEnvelope blockEnvelope = new PrjEnvelope(blockMinX, blockMaxX, blockMinY, blockMaxY); UInt16[] dstRowLookUpTable = new UInt16[blockWidth * blockHeight]; UInt16[] dstColLookUpTable = new UInt16[blockWidth * blockHeight]; _rasterProjector.ComputeIndexMapTable(_xs, _ys, srcLocationSize, srcDataSize, blockSize, blockEnvelope, out dstRowLookUpTable, out dstColLookUpTable, progressCallback); //执行投影 UInt16[] srcBandData = null; UInt16[] dstBandData = new UInt16[blockWidth * blockHeight]; for (int i = 0; i < dstBandCount; i++) //读取原始通道值,投影到目标区域 { BandMap bandMap = bandMaps[i]; ReadBandData(out srcBandData, bandMap.File, bandMap.DatasetName, bandMap.BandIndex, srcDataSize); if (prjSettings.IsRadiation) //亮温转换,这里处理的不好,如果是做了一个小块的分幅,这里花的代价太高, { DoRadiation(srcBandData, srcDataSize, srcLocationSize, bandMap.DatasetName, bandMap.BandIndex, srcRaster, prjSettings.IsRadiation, prjSettings.IsSolarZenith); } _rasterProjector.Project <UInt16>(srcBandData, srcDataSize, dstRowLookUpTable, dstColLookUpTable, blockSize, dstBandData, 0, progressCallback); using (IRasterBand band = prdWriter.GetRasterBand(i + 1)) { unsafe { fixed(UInt16 *ptr = dstBandData) { IntPtr bufferPtr = new IntPtr(ptr); int blockOffsetY = blockYIndex * blockSize.Height; int blockOffsetX = blockWidth * blockXIndex; band.Write(blockOffsetX, blockOffsetY, blockWidth, blockHeight, bufferPtr, enumDataType.UInt16, blockWidth, blockHeight); } } } } } } } } }
private void ReadyArgs(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { if (srcRaster.DataIdentify != null) { string satellite = srcRaster.DataIdentify.Satellite; //if (satellite == "FY3A")//FY3A MERSI250米数据已经经过处理,不需要再执行去条带操作 //{ // _sacnLineWidth = 0; //} } float resolutionScale = 1f; _readyProgress = 0; if (progressCallback != null) { progressCallback(_readyProgress++, "准备相关参数"); } _prjSettings = ArgsCheck(srcRaster, prjSettings); CheckIs0250(srcRaster); _dstSpatialRef = dstSpatialRef; switch (_dataType) { case "1KM": //整轨投影时候去除左右锯齿,分块投影不需要 _left = 10; _right = 10; if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) //整轨投影 { MemoryHelper.MemoryNeed(500, 1536); } else { MemoryHelper.MemoryNeed(400, 1536); //剩余900MB,已使用1.2GB } TryCreateDefaultArgs(srcRaster, _prjSettings, ref _dstSpatialRef); DoSession(srcRaster, srcRaster, _dstSpatialRef, _prjSettings, progressCallback); _angleDataProvider = srcRaster; break; case "QKM": resolutionScale = 4f; _left = 20; _right = 20; if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) { MemoryHelper.MemoryNeed(800, 1280); //整幅投影对内存做限制,系统剩余内存不低于1.5GB,应用程序已使用内存不超过600MB } else { MemoryHelper.MemoryNeed(600, 1280); //剩余900MB,已使用1.2GB } TryCreate0250DefaultArgs(srcRaster, _prjSettings, ref _dstSpatialRef); DoSession(srcRaster, _prjSettings.SecondaryOrbitRaster, _dstSpatialRef, _prjSettings, progressCallback); _angleDataProvider = _prjSettings.SecondaryOrbitRaster; break; default: break; } TrySetLeftRightInvalidPixel(_prjSettings.ExtArgs); if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) { _prjSettings.OutEnvelope = _maxPrjEnvelope; _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = _srcLocationSize.Width - 1, yEnd = _srcLocationSize.Height - 1 }; } else { GetEnvelope(_xs, _ys, _srcLocationSize.Width, _srcLocationSize.Height, _prjSettings.OutEnvelope, out _orbitBlock); if (_orbitBlock == null || _orbitBlock.Width <= 0 || _orbitBlock.Height <= 0) { throw new Exception("数据不在目标区间内"); } float invalidPresent = (_orbitBlock.Width * _orbitBlock.Height * resolutionScale) / (_srcLocationSize.Width * _srcLocationSize.Height); if (invalidPresent < 0.0001f) { throw new Exception("数据占轨道数据比例太小,有效率" + invalidPresent * 100 + "%"); } if (invalidPresent > 0.60) { _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = _srcLocationSize.Width - 1, yEnd = _srcLocationSize.Height - 1 } } ; } //地理坐标投影,下面简单的对地理坐标投影的范围作了限制,不大严谨,仅适合目前的状况。 if (_dstSpatialRef.ProjectionCoordSystem == null && (prjSettings.OutEnvelope.MaxY > 80 || prjSettings.OutEnvelope.MaxY < -80)) { throw new Exception(string.Format("高纬度数据,不适合投影为等经纬度数据[{0}]", _maxPrjEnvelope)); } //以下参数用于投影 _dstEnvelope = _prjSettings.OutEnvelope; if (!_dstEnvelope.IntersectsWith(_maxPrjEnvelope)) { throw new Exception("数据不在目标区间内"); } _outResolutionX = _prjSettings.OutResolutionX; _outResolutionY = _prjSettings.OutResolutionY; _outFormat = _prjSettings.OutFormat; _outfilename = _prjSettings.OutPathAndFileName; _dstProj4 = _dstSpatialRef.ToProj4String(); _dstBandCount = _prjBands.Length; _dstSize = _prjSettings.OutSize; _isRadiation = _prjSettings.IsRadiation; _isSolarZenith = _prjSettings.IsSolarZenith; _isSensorZenith = _prjSettings.IsSensorZenith; }
private void ReadyArgs(IRasterDataProvider srcRaster, FilePrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { float resolutionScale = 1f; _readyProgress = 0; if (progressCallback != null) { progressCallback(_readyProgress++, "准备相关参数"); } _prjSettings = ArgsCheck(srcRaster, prjSettings); _geoDataProvider = _prjSettings.GeoFile; CheckIs0250(srcRaster); _dstSpatialRef = dstSpatialRef; switch (_dataType) { case "1KM": //整轨投影时候去除左右锯齿,分块投影不需要 _left = 10; _right = 10; if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) //整轨投影时做限制 { MemoryHelper.MemoryNeed(500, 1536); } else { MemoryHelper.MemoryNeed(400, 1536); //剩余900MB,已使用1.2GB } //_angleDataProvider = srcRaster; TryCreateDefaultArgs(srcRaster, _prjSettings, ref _dstSpatialRef); TrySetLeftRightInvalidPixel(_prjSettings.ExtArgs); DoSession(srcRaster, _geoDataProvider, _dstSpatialRef, _prjSettings, progressCallback); break; case "QKM": resolutionScale = 4f; _left = 20; _right = 20; if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) { MemoryHelper.MemoryNeed(800, 1280); //整幅投影对内存做限制,系统剩余内存不低于A参数MB,应用程序已使用内存不超过B参数MB } else { MemoryHelper.MemoryNeed(600, 1280); //剩余900MB,最大已使用1.2GB } //_angleDataProvider = _prjSettings.SecondaryOrbitRaster; TryCreate0250DefaultArgs(srcRaster, _prjSettings, ref _dstSpatialRef); TrySetLeftRightInvalidPixel(_prjSettings.ExtArgs); DoSession(srcRaster, _geoDataProvider, _dstSpatialRef, _prjSettings, progressCallback); break; default: break; } if (_prjSettings.OutEnvelope == null || _prjSettings.OutEnvelope == PrjEnvelope.Empty) { _prjSettings.OutEnvelope = _maxPrjEnvelope; _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = _srcLocationSize.Width - 1, yEnd = _srcLocationSize.Height - 1 }; } else { if (_xs != null && _ys != null) { GetEnvelope(_xs, _ys, _srcLocationSize.Width, _srcLocationSize.Height, _prjSettings.OutEnvelope, out _orbitBlock); } else { int bC = 8; int tmpWidth = 0; int tmpHeight = 0; double[] tmpxs = null; double[] tmpys = null; //8024,8000 tmpWidth = _srcLocationSize.Width / bC; tmpHeight = _srcLocationSize.Height / bC; tmpxs = ReadSampleDatas(_longitudeBand, 0, 0, tmpWidth, tmpHeight); tmpys = ReadSampleDatas(_latitudeBand, 0, 0, tmpWidth, tmpHeight); _rasterProjector.Transform(SpatialReference.GetDefault(), tmpxs, tmpys, _dstSpatialRef); //计算偏移 GetEnvelope(tmpxs, tmpys, tmpWidth, tmpHeight, _prjSettings.OutEnvelope, out _orbitBlock); _orbitBlock = _orbitBlock.Zoom(bC, bC); } if (_orbitBlock == null || _orbitBlock.Width <= 0 || _orbitBlock.Height <= 0) { throw new Exception("数据不在目标区间内"); } float invalidPresent = (_orbitBlock.Width * _orbitBlock.Height * resolutionScale) / (_srcLocationSize.Width * _srcLocationSize.Height); if (invalidPresent < 0.0001f) { throw new Exception("数据占轨道数据比例太小,有效率" + invalidPresent * 100 + "%"); } if (invalidPresent > 0.60) { _orbitBlock = new Block { xOffset = 0, yBegin = 0, xEnd = _srcLocationSize.Width - 1, yEnd = _srcLocationSize.Height - 1 } } ; } //地理坐标投影,下面简单的对地理坐标投影的范围作了限制,不大严谨,仅适合目前的状况。 if (_dstSpatialRef.ProjectionCoordSystem == null && (prjSettings.OutEnvelope.MaxY > 80 || prjSettings.OutEnvelope.MaxY < -80)) { throw new Exception(string.Format("高纬度数据,不适合投影为等经纬度数据[{0}]", _maxPrjEnvelope)); } //以下参数用于投影 _dstEnvelope = _prjSettings.OutEnvelope; if (!_dstEnvelope.IntersectsWith(_maxPrjEnvelope)) { throw new Exception("数据不在目标区间内"); } _outResolutionX = _prjSettings.OutResolutionX; _outResolutionY = _prjSettings.OutResolutionY; _outFormat = _prjSettings.OutFormat; _outfilename = _prjSettings.OutPathAndFileName; _dstProj4 = _dstSpatialRef.ToProj4String(); _dstBandCount = _prjBands.Length; _dstSize = _prjSettings.OutSize; _isRadiation = _prjSettings.IsRadiation; _isSolarZenith = _prjSettings.IsSolarZenith; _isSensorZenith = _prjSettings.IsSensorZenith; }
/// <summary> /// 0、先生成目标文件,以防止目标空间不足。 /// 1、计算查找表 /// 2、读取通道数据 /// 3、计算通道数据亮温 /// 4、投影通道。 /// </summary> private void ProjectToLDF(IRasterDataProvider srcRaster, NOAA_PrjSettings prjSettings, ISpatialReference dstSpatialRef, Action <int, string> progressCallback) { string outFormat = prjSettings.OutFormat; string outfilename = prjSettings.OutPathAndFileName; string dstProj4 = dstSpatialRef.ToProj4String(); int[] outBandNos = prjSettings.OutBandNos; int dstBandCount = outBandNos.Length; Size srcSize = new Size(srcRaster.Width, srcRaster.Height); Size dstSize = prjSettings.OutSize; Size srcJdSize = srcSize; using (IRasterDataDriver drv = GeoDataDriver.GetDriverByName("LDF") as IRasterDataDriver) { PrjEnvelope dstEnvelope = prjSettings.OutEnvelope; string[] options = new string[] { "INTERLEAVE=BSQ", "VERSION=LDF", "WITHHDR=TRUE", "SPATIALREF=" + dstSpatialRef.ToProj4String(), "MAPINFO={" + 1 + "," + 1 + "}:{" + dstEnvelope.MinX + "," + dstEnvelope.MaxY + "}:{" + prjSettings.OutResolutionX + "," + prjSettings.OutResolutionY + "}" , "BANDNAMES=" + BandNameString(prjSettings.OutBandNos) }; if (progressCallback != null) { progressCallback(6, "生成输出文件"); } using (IRasterDataProvider prdWriter = drv.Create(outfilename, dstSize.Width, dstSize.Height, dstBandCount, enumDataType.UInt16, options) as IRasterDataProvider) { float outResolutionX = prjSettings.OutResolutionX; float outResolutionY = prjSettings.OutResolutionY; Size outSize = dstEnvelope.GetSize(outResolutionX, outResolutionY); int blockXNum = 0; int blockYNum = 0; int blockWidth = 0; int blockHeight = 0; GetBlockNumber(outSize, out blockXNum, out blockYNum, out blockWidth, out blockHeight); Size dstBlockSize = new Size(blockWidth, blockHeight); UInt16[] dstRowBlockLUT = new UInt16[blockWidth * blockHeight]; UInt16[] dstColBlockLUT = new UInt16[blockWidth * blockHeight]; int blockCount = blockYNum * blockXNum; int progress = 0; int percent = 0; int progressCount = blockCount * dstBandCount; for (int blockYIndex = 0; blockYIndex < blockYNum; blockYIndex++) { for (int blockXIndex = 0; blockXIndex < blockXNum; blockXIndex++) { PrjEnvelope blockEnvelope = null; Block orbitBlock = null; //经纬度数据集,计算轨道数据范围偏移 double[] blockOrbitXs = null; double[] blockOrbitYs = null; if (blockCount == 1) //没分块的情况 { orbitBlock = _orbitBlock; if (_orbitBlock.Width == srcJdSize.Width && _orbitBlock.Height == srcJdSize.Height) { blockOrbitXs = _xs; blockOrbitYs = _ys; } else //源 { GetBlockDatas(_xs, _ys, srcJdSize.Width, srcJdSize.Height, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height, out blockOrbitXs, out blockOrbitYs); } blockEnvelope = dstEnvelope; } else { //当前块的四角范围 double blockMinX = dstEnvelope.MinX + blockWidth * outResolutionX * blockXIndex; double blockMaxX = blockMinX + blockWidth * outResolutionX; double blockMaxY = dstEnvelope.MaxY - blockHeight * outResolutionY * blockYIndex; double blockMinY = blockMaxY - blockHeight * outResolutionY; blockEnvelope = new PrjEnvelope(blockMinX, blockMaxX, blockMinY, blockMaxY); //根据当前输出块,反推出对应的源数据块起始行列 GetEnvelope(_xs, _ys, srcJdSize.Width, srcJdSize.Height, blockEnvelope, out orbitBlock); if (orbitBlock.Width <= 0 || orbitBlock.Height <= 0) //当前分块不在图像内部 { progress += dstBandCount; continue; } GetBlockDatas(_xs, _ys, srcJdSize.Width, srcJdSize.Height, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height, out blockOrbitXs, out blockOrbitYs); } float[] solarZenithData = null; if (prjSettings.IsRadiation && prjSettings.IsSolarZenith) { if (File.Exists(_szDataFilename)) { ReadBandData(out solarZenithData, _solarZenithCacheRaster, 1, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height); } TryReadZenithData(orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height); } Size orbitBlockSize = new Size(orbitBlock.Width, orbitBlock.Height); _rasterProjector.ComputeIndexMapTable(blockOrbitXs, blockOrbitYs, orbitBlockSize, dstBlockSize, blockEnvelope, _maxPrjEnvelope, out dstRowBlockLUT, out dstColBlockLUT, null); //执行投影 UInt16[] srcBandData = new UInt16[orbitBlock.Width * orbitBlock.Height]; UInt16[] dstBandData = new UInt16[blockWidth * blockHeight]; for (int i = 0; i < dstBandCount; i++) //读取原始通道值,投影到目标区域 { if (progressCallback != null) { progress++; percent = progress * 100 / progressCount; progressCallback(percent, string.Format("投影第{0}/{1}块,第{2}/{3}通道", blockXIndex + blockYIndex, blockCount, i + 1, dstBandCount)); } int bandNo = outBandNos[i]; ReadBandData(srcBandData, srcRaster, bandNo, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Width, orbitBlock.Height); if (prjSettings.IsRadiation) { DoRadiation(srcBandData, orbitBlock.xOffset, orbitBlock.yBegin, orbitBlock.Size, bandNo, prjSettings.IsRadiation, prjSettings.IsSolarZenith, solarZenithData); } _rasterProjector.Project <UInt16>(srcBandData, orbitBlock.Size, dstRowBlockLUT, dstColBlockLUT, dstBlockSize, dstBandData, 0, null); IRasterBand band = prdWriter.GetRasterBand(i + 1); { unsafe { fixed(UInt16 *ptr = dstBandData) { IntPtr bufferPtr = new IntPtr(ptr); int blockOffsetY = blockYIndex * dstBlockSize.Height; int blockOffsetX = blockXIndex * dstBlockSize.Width; band.Write(blockOffsetX, blockOffsetY, blockWidth, blockHeight, bufferPtr, enumDataType.UInt16, blockWidth, blockHeight); } } } } ReleaseZenithData(); srcBandData = null; dstBandData = null; blockOrbitXs = null; blockOrbitYs = null; } } dstRowBlockLUT = null; dstColBlockLUT = null; } } }