private void StatRasterTemplate <T>(IRasterDataProvider raster, IRasterDataProvider tempRaster, Func <T, bool> func, ref SortedDictionary <string, double> statResult)//计算最大覆盖 { try { //计算待统计栅格与分类栅格的相交区域,以创建相同的虚拟栅格。 CoordEnvelope jxEnv = raster.CoordEnvelope.Intersect(tempRaster.CoordEnvelope); VirtualRasterHeader vHeader = VirtualRasterHeader.Create(jxEnv, raster.Width, raster.Height); VirtualRaster vRaster = new VirtualRaster(raster, vHeader); VirtualRaster template = new VirtualRaster(tempRaster, vHeader); //2、依据逻辑,计算初步统计结果,这一步对于大数据,可考虑分块处理 T[] vdata = vRaster.ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); int[] typeData = template.ReadData <int>(1, 0, 0, vHeader.Width, vHeader.Height); int length = typeData.Length; for (int i = 0; i < length; i++) { UpdateProgress((int)(i * 100f / length), "正在计算统计数据"); //统计满足条件的栅格,并将计数值加入字典。 if (func(vdata[i])) { int tvalue = typeData[i]; AddUpToDic(statResult, tvalue.ToString(), _perAreas); } } //3、直接返回初步统计结果,或者直接进一步处理 //SortedDictionary<int, double> newDic = ToSSXLevel(statResult); //return newDic; } finally { UpdateProgress(100, "统计数据计算完毕"); } }
/// <summary> /// 多条件面积统计,[当前区域] /// </summary> /// <typeparam name="T"></typeparam> /// <param name="raster"></param> /// <param name="multiFilter"></param> /// <returns></returns> private Dictionary <string, SortedDictionary <string, double> > StatRaster <T>(IRasterDataProvider raster, Dictionary <string, Func <T, bool> > multiFilter, bool weight, float weightZoom) where T : struct, IConvertible { try { int filterLength = multiFilter.Count; string[] filterKeys = multiFilter.Keys.ToArray(); Func <T, bool>[] filters = new Func <T, bool> [filterLength]; double[] areas = new double[filterLength]; for (int i = 0; i < filterLength; i++) { filters[i] = multiFilter[filterKeys[i]]; } //计算待统计栅格与分类栅格的相交区域,以创建相同的虚拟栅格。 CoordEnvelope jxEnv = raster.CoordEnvelope; VirtualRasterHeader vHeader = VirtualRasterHeader.Create(jxEnv, raster.Width, raster.Height); VirtualRaster vRaster = new VirtualRaster(raster, vHeader); //2、依据逻辑,计算初步统计结果,这一步对于大数据,可考虑分块处理 T[] vdata = vRaster.ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); int length = vdata.Length; for (int i = 0; i < length; i++) { UpdateProgress((int)(i * 100f / length), "正在计算统计数据"); //统计满足条件的栅格,并将计数值加入字典。 for (int f = 0; f < filterLength; f++) { if (filters[f](vdata[i])) { areas[f] += weight ? _perAreas * Convert.ToSingle(vdata[i]) / weightZoom : _perAreas; //break; } } } SortedDictionary <string, double> dic = new SortedDictionary <string, double>(); for (int i = 0; i < filterLength; i++) { dic.Add(filterKeys[i], areas[i]); } Dictionary <string, SortedDictionary <string, double> > result = new Dictionary <string, SortedDictionary <string, double> >(); result.Add("当前区域", dic); return(result); } finally { UpdateProgress(100, "统计数据计算完毕"); } }
public static void totest2() { string file = @"D:\WorkFolder\Smart二期\1.联机开发@Smart\SMART\bin\Release\SystemData\RasterTemplate\China_XjRaster.dat"; IRasterDataProvider inRaster = RasterDataDriver.Open(file) as IRasterDataProvider; VirtualRasterHeader vrh = VirtualRasterHeader.Create(new CoordEnvelope(120, 140, 10, 30), 0.005f, 0.005f); VirtualRaster vin = new VirtualRaster(inRaster, vrh); int[] data = vin.ReadData <int>(1, 10, 10, vrh.Width - 10, vrh.Height - 10); using (IRasterDataProvider raster = VirtualRaster.CreateVirtureData(vrh, @"d:\pppppp2.ldf", enumDataType.Int32)) { GCHandle buffer = VirtualRaster.GetHandles(data); IntPtr bufferPtr = buffer.AddrOfPinnedObject(); raster.GetRasterBand(1).Write(10, 10, vrh.Width - 10, vrh.Height - 10, bufferPtr, enumDataType.Int32, vrh.Width - 10, vrh.Height - 10); buffer.Free(); } }
/// <summary> /// 设置处理对象(输入和输出) /// 输入和输出文件范围可以不一致,但是必须投影方式一样,分辨率一致。 /// </summary> /// <param name="fileIn">一组创建好的输入对象,具有范围定义(每个文件的范围可以不一致,暂时要求分辨率和输出文件保持一致)</param> /// <param name="fileOut">一组创建好的输出对象,具有范围定义(每个文件的范围,大小,分辨率必须一致)</param> public void SetRaster(RasterMaper[] fileIn, RasterMaper[] fileOut) { if (fileOut == null || fileIn == null || fileIn.Length == 0 || fileOut.Length == 0)//获取为空时候使用其他逻辑,比如输入的并集,但我觉得还是放在外面好。 { return; } //1、检查所有文件投影坐标都一致(这里暂时不考虑栅格坐标) //2、检查所有输出文件范围、坐标、分辨率等都一致 //3、计算每个输入文件的偏移(相对输出文件) _fileInOffsets = new RasterOffset[fileIn.Length]; _fileOutOffsets = new RasterOffset[fileIn.Length]; for (int i = 0; i < fileIn.Length; i++) { RasterOffset fileOffset; RasterOffset fileOutOffset; CalcFileOffset(fileIn[i].Raster, fileOut[0].Raster, out fileOffset, out fileOutOffset); _fileInOffsets[i] = fileOffset; _fileOutOffsets[i] = fileOutOffset; } //4、设置通道映射表 CheckBandMap(fileIn); CheckBandMap(fileOut); _fileIn = fileIn; _fileOut = fileOut; //建立虚拟栅格 VirtualRasterHeader vHeader = VirtualRasterHeader.Create(fileOut[0].Raster); VirtualRaster[] vRasters = new VirtualRaster[fileIn.Length]; for (int i = 0; i < fileIn.Length; i++) { VirtualRaster vr = new VirtualRaster(fileIn[i].Raster, vHeader); vRasters[i] = vr; } _vRasterIn = vRasters; }
private Dictionary <string, SortedDictionary <string, double> > StatByRasterTemplate <T>(IRasterDataProvider raster, IRasterDataProvider tempRaster, Dictionary <string, Func <T, bool> > multiFilter, bool weight, float weightZoom, string vectorTemplate) where T : struct, IConvertible { try { Dictionary <string, SortedDictionary <string, double> > result = new Dictionary <string, SortedDictionary <string, double> >(); string[] filterKeys = multiFilter.Keys.ToArray(); foreach (string kye in filterKeys) { result.Add(kye, new SortedDictionary <string, double>()); } //计算待统计栅格与分类栅格的相交区域,以创建相同的虚拟栅格。 CoordEnvelope jxEnv = raster.CoordEnvelope.Intersect(tempRaster.CoordEnvelope); VirtualRasterHeader vHeader = VirtualRasterHeader.Create(jxEnv, raster.Width, raster.Height); VirtualRaster vRaster = new VirtualRaster(raster, vHeader); VirtualRaster template = new VirtualRaster(tempRaster, vHeader); //2、依据逻辑,计算初步统计结果,这一步对于大数据,可考虑分块处理 T[] vdata = vRaster.ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); int[] typeData = template.ReadData <int>(1, 0, 0, vHeader.Width, vHeader.Height); int length = typeData.Length; if (string.IsNullOrEmpty(vectorTemplate)) { for (int i = 0; i < length; i++) { UpdateProgress((int)(i * 100f / length), "正在计算统计数据"); //统计满足条件的栅格,并将计数值加入字典。 foreach (string key in filterKeys) { Func <T, bool> func = multiFilter[key]; if (func(vdata[i])) { int tvalue = typeData[i]; AddUpToDic(result[key], tvalue.ToString(), weight ? _perAreas * Convert.ToSingle(vdata[i]) / weightZoom : _perAreas); } } } } else { Size size = new Size(raster.Width, raster.Height); string[] typeNames = null; byte[] typeValue = null; string templateName; string[] featureNames = null; if (vectorTemplate.IndexOf(":") != -1) { templateName = vectorTemplate.Substring(0, vectorTemplate.IndexOf(":")); featureNames = vectorTemplate.Substring(vectorTemplate.IndexOf(":") + 1).Split(new char[] { ',' }); } else { templateName = vectorTemplate; } Action act2 = new Action(() => { typeValue = GetLanduseTypeRaster(raster, size, out typeNames, templateName); }); Parallel.Invoke(act2); for (int i = 0; i < length; i++) { UpdateProgress((int)(i * 100f / length), "正在计算统计数据"); //统计满足条件的栅格,并将计数值加入字典。 foreach (string key in filterKeys) { Func <T, bool> func = multiFilter[key]; if (func(vdata[i])) { int tvalue = typeData[i]; AddUpToDic(result[key], featureNames, tvalue.ToString(), typeNames[typeValue[i]], weight ? _perAreas * Convert.ToSingle(vdata[i]) / weightZoom : _perAreas); } } } } return(result); } finally { UpdateProgress(100, "统计数据计算完毕"); } }
private SortedDictionary <string, StatAreaItem> StatTemplate <T>(IRasterDataProvider[] rasters, IRasterDataProvider tempRaster, Func <T, bool> func) { try { //01、计算所有输入栅格的的范围并集 CoordEnvelope maxEnv = UnionEnv(rasters); //计算待统计栅格与分类栅格的相交区域,以创建相同的虚拟栅格 CoordEnvelope virtureEnv = maxEnv.Intersect(tempRaster.CoordEnvelope); VirtualRasterHeader vHeader = VirtualRasterHeader.Create(virtureEnv, rasters[0].ResolutionX, rasters[0].ResolutionX); List <VirtualRaster> vRasters = new List <VirtualRaster>(); for (int i = 0; i < rasters.Length; i++) { VirtualRaster vRaster = new VirtualRaster(rasters[i], vHeader); vRasters.Add(vRaster); } VirtualRaster template = new VirtualRaster(tempRaster, vHeader); int[] tdata = template.ReadData <int>(1, 0, 0, vHeader.Width, vHeader.Height); //2、依据逻辑,计算初步统计结果,这一步对于大数据,可考虑分块处理 int calcLength = vHeader.Width * vHeader.Height * vRasters.Count; int dataLength = vHeader.Width * vHeader.Height; byte[] valueCalced = new byte[dataLength]; SortedDictionary <string, StatAreaItem> result = new SortedDictionary <string, StatAreaItem>(); for (int i = 0; i < vRasters.Count; i++) { T[] datas = vRasters[i].ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); for (int j = 0; j < dataLength; j++) { UpdateProgress((int)((j + (i * dataLength)) * 100f / calcLength), "正在计算统计数据"); if (func(datas[j])) { string key = tdata[j].ToString(); if (result.ContainsKey(key))//累计计数 { result[key].GrandTotal += 1; } else { result.Add(key, new StatAreaItem() { GrandTotal = 1 }); } if (valueCalced[j] == 0)//覆盖计数 { valueCalced[j] = 1; result[key].Cover += 1; } } } } double perAreas = AreaCountHelper.CalcArea(vHeader.CoordEnvelope.Center.X, vHeader.CoordEnvelope.Center.Y, vHeader.ResolutionX, vHeader.ResolutionY) * Math.Pow(10, -6); foreach (string key in result.Keys) { result[key].GrandTotal *= perAreas; result[key].Cover *= perAreas; } return(result); } finally { UpdateProgress(100, "统计数据计算完毕"); } }
/// <summary> /// 覆盖面积:指的是覆盖到的面积, /// 累计面积:即累计覆盖面积,相同区域不同时次的累计计算 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rasters"></param> /// <param name="rasterTemplate"></param> /// <param name="func"></param> /// <returns></returns> private SortedDictionary <string, StatAreaItem> StatTemplate <T>(IRasterDataProvider[] rasters, IRasterDataProvider typeRaster, Func <T, bool> func, bool isCombinSameDay) { try { //01、计算所有输入栅格的的范围并集 CoordEnvelope maxEnv = UnionEnv(rasters); //计算待统计栅格与分类栅格的相交区域,以创建相同的虚拟栅格。 CoordEnvelope virtureEnv = maxEnv.Intersect(typeRaster.CoordEnvelope); VirtualRasterHeader vHeader = VirtualRasterHeader.Create(virtureEnv, rasters[0].ResolutionX, rasters[0].ResolutionX); VirtualRaster typelate = new VirtualRaster(typeRaster, vHeader); int[] tdata = typelate.ReadData <int>(1, 0, 0, vHeader.Width, vHeader.Height); //2、依据逻辑,计算初步统计结果,这一步对于大数据,可考虑分块处理 int calcLength = vHeader.Width * vHeader.Height * rasters.Length; int dataLength = vHeader.Width * vHeader.Height; byte[] valueCalced = new byte[dataLength]; SortedDictionary <string, StatAreaItem> result = new SortedDictionary <string, StatAreaItem>(); if (isCombinSameDay) { //预处理同天数据 Dictionary <DateTime, List <IRasterDataProvider> > dic = new Dictionary <DateTime, List <IRasterDataProvider> >(); foreach (IRasterDataProvider raster in rasters) { if (raster.DataIdentify.OrbitDateTime == DateTime.MinValue) { RasterIdentify identify = new RasterIdentify(raster.fileName); raster.DataIdentify.OrbitDateTime = identify.OrbitDateTime; } List <IRasterDataProvider> lst; if (dic.TryGetValue(raster.DataIdentify.OrbitDateTime, out lst)) { dic[raster.DataIdentify.OrbitDateTime].Add(raster); } else { lst = new List <IRasterDataProvider>(); lst.Add(raster); dic.Add(raster.DataIdentify.OrbitDateTime, lst); } } foreach (DateTime dateKey in dic.Keys) { IRasterDataProvider[] rastersSameDay = dic[dateKey].ToArray(); if (rastersSameDay.Length == 1 || dateKey == DateTime.MinValue) { for (int i = 0; i < rastersSameDay.Length; i++) { VirtualRaster vRaster = new VirtualRaster(rastersSameDay[i], vHeader); T[] datas = vRaster.ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); for (int j = 0; j < dataLength; j++) { UpdateProgress((int)((j + (i * dataLength)) * 100f / calcLength), "正在计算统计数据"); if (func(datas[j])) { string key = tdata[j].ToString(); if (result.ContainsKey(key))//累计计数 { result[key].GrandTotal += 1; } else { result.Add(key, new StatAreaItem() { GrandTotal = 1 }); } if (valueCalced[j] == 0)//覆盖计数 { valueCalced[j] = 1; result[key].Cover += 1; } } } } } else//同天数据处理, { byte[] sameDayCalced = new byte[vHeader.Width * vHeader.Height]; for (int i = 0; i < rasters.Length; i++) { VirtualRaster vRaster = new VirtualRaster(rasters[i], vHeader); T[] datas = vRaster.ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); for (int j = 0; j < dataLength; j++) { UpdateProgress((int)((j + (i * dataLength)) * 100f / calcLength), "正在计算统计数据"); if (func(datas[j])) { if (sameDayCalced[j] == 0)// { sameDayCalced[j] = 1; string key = tdata[j].ToString(); if (result.ContainsKey(key))//累计计数 { result[key].GrandTotal += 1; } else { result.Add(key, new StatAreaItem() { GrandTotal = 1 }); } if (valueCalced[j] == 0)//覆盖计数 { valueCalced[j] = 1; result[key].Cover += 1; } } } } } } } } else { for (int i = 0; i < rasters.Length; i++) { VirtualRaster vRaster = new VirtualRaster(rasters[i], vHeader); T[] datas = vRaster.ReadData <T>(1, 0, 0, vHeader.Width, vHeader.Height); for (int j = 0; j < dataLength; j++) { UpdateProgress((int)((j + (i * dataLength)) * 100f / calcLength), "正在计算统计数据"); if (func(datas[j])) { string key = tdata[j].ToString(); if (result.ContainsKey(key))//累计计数 { result[key].GrandTotal += 1; } else { result.Add(key, new StatAreaItem() { GrandTotal = 1 }); } if (valueCalced[j] == 0)//覆盖计数 { valueCalced[j] = 1; result[key].Cover += 1; } } } } } double perAreas = AreaCountHelper.CalcArea(vHeader.CoordEnvelope.Center.X, vHeader.CoordEnvelope.Center.Y, vHeader.ResolutionX, vHeader.ResolutionY) * Math.Pow(10, -6); foreach (string key in result.Keys) { result[key].GrandTotal *= perAreas; result[key].Cover *= perAreas; } return(result); } finally { UpdateProgress(100, "统计数据计算完毕"); } }