private static void ProcessEachRasterBlock(double[] valueRasterValues, double[] zoneRasterValues, int band, ref Dictionary<int, StatisticsInfo>[] rasInfoDict) { for (int index = 0; index < valueRasterValues.Length; index++) { //Skip no data values as in ESRI if ((Math.Round(zoneRasterValues[index], 3) != GdalUtilConstants.NoDataValue) && (Math.Round(valueRasterValues[index], 3) != GdalUtilConstants.NoDataValue)) { int pixelValueFromZone = Convert.ToInt32(zoneRasterValues[index]); double pixelValueFromValue = valueRasterValues[index]; //process each pixel value if (rasInfoDict[band].ContainsKey(Convert.ToInt32(pixelValueFromZone))) { StatisticsInfo rastStatistics = rasInfoDict[band][Convert.ToInt32(pixelValueFromZone)]; rastStatistics.Count++; rastStatistics.Sum = rastStatistics.Sum + pixelValueFromValue; rasInfoDict[band][Convert.ToInt32(pixelValueFromZone)] = rastStatistics; } else { rasInfoDict[band][Convert.ToInt32(pixelValueFromZone)] = new StatisticsInfo() { Count = 1, Sum = pixelValueFromValue }; } } } }
public static void OpenFileRasterDataset(string inFolderName, string inRasterDatasetName, string inFeatureName, string inFieldName, double outCellSize, string outSummaryFile) { EnableEsriLiscences(); //Get feature raster from feature shp string outTempRasterName = "tempZoneRasterFromESRI.tif"; string outZoneRater = inFolderName + "\\" + outTempRasterName; int rasterBlockSize = 1024; RasterizeEsri.Rasterize(inFeatureName, outZoneRater, inFieldName, outCellSize); //Open raster file workspace IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass(); IRasterWorkspace rasterWorkspace = (IRasterWorkspace)workspaceFactory.OpenFromFile(inFolderName, 0); //Align raster string inValueRaster = inFolderName + "\\" + inRasterDatasetName; string inClipFeature = inFeatureName; string outClippedRasterName = "tempValueRasterFromESRI.tif"; string outClippedValueRaster = inFolderName + "\\" + outClippedRasterName; ClipRasterBoundaryEsri.ClipRaster(inValueRaster, inClipFeature, outClippedValueRaster); //Open zone raster dataset IRasterDataset zoneRasterDataset = rasterWorkspace.OpenRasterDataset(outTempRasterName); IRasterDataset2 zoneRasterDataset2 = zoneRasterDataset as IRasterDataset2; IRaster2 zoneRs2 = zoneRasterDataset2.CreateFullRaster() as IRaster2; //Open value raster dataset IRasterDataset valueRasterDataset = rasterWorkspace.OpenRasterDataset(outClippedRasterName); IRasterDataset2 valueRasterDataset2 = valueRasterDataset as IRasterDataset2; IRaster2 valueRs2 = valueRasterDataset2.CreateFullRaster() as IRaster2; //Extract bands from the raster IRasterBandCollection valueRasterPlanes = valueRasterDataset as IRasterBandCollection; //create raster cursor to read block by block IPnt blockSize = new PntClass(); blockSize.SetCoords(rasterBlockSize, rasterBlockSize); IRasterCursor valueRasterCursor = valueRs2.CreateCursorEx(blockSize); IRasterCursor zoneRasterCursor = zoneRs2.CreateCursorEx(blockSize); if (valueRasterPlanes != null) { Dictionary <int, StatisticsInfo>[] rasInfoDict = new Dictionary <int, StatisticsInfo> [valueRasterPlanes.Count]; int zoneRasterBandId = 0; for (int b = 0; b < valueRasterPlanes.Count; b++) { rasInfoDict[b] = new Dictionary <int, StatisticsInfo>(); } do { IPixelBlock3 valueRasterPixelBlock3 = valueRasterCursor.PixelBlock as IPixelBlock3; IPixelBlock3 zoneRasterPixelBlock3 = zoneRasterCursor.PixelBlock as IPixelBlock3; //No Idea how esri cursor fills the raster gap if zone is greater than value, so quick and fix using smallest extent int blockWidth = valueRasterPixelBlock3.Width < zoneRasterPixelBlock3.Width ? valueRasterPixelBlock3.Width : zoneRasterPixelBlock3.Width; int blockHeight = valueRasterPixelBlock3.Height < zoneRasterPixelBlock3.Height ? valueRasterPixelBlock3.Height : zoneRasterPixelBlock3.Height; //Console.WriteLine(zoneRasterPixelBlock3.Width); //Console.WriteLine(blockWidth); try { System.Array zoneRasterPixels = (System.Array)zoneRasterPixelBlock3.get_PixelData(zoneRasterBandId); for (int b = 0; b < valueRasterPlanes.Count; b++) { //Console.WriteLine(b); //Get pixel array System.Array valueRasterPixels = (System.Array)valueRasterPixelBlock3.get_PixelData(b); for (int i = 0; i < blockWidth; i++) { for (int j = 0; j < blockHeight; j++) { //Get pixel value object pixelValueFromValue = null; object pixelValueFromZone = null; try { pixelValueFromValue = valueRasterPixels.GetValue(i, j); pixelValueFromZone = zoneRasterPixels.GetValue(i, j); } catch (Exception ex) { Console.WriteLine(ex.Message); } //process each pixel value try { if (rasInfoDict[b].ContainsKey(Convert.ToInt32(pixelValueFromZone))) { StatisticsInfo rastStatistics = rasInfoDict[b][Convert.ToInt32(pixelValueFromZone)]; rastStatistics.Count++; rastStatistics.Sum = rastStatistics.Sum + Convert.ToDouble(pixelValueFromValue); rasInfoDict[b][Convert.ToInt32(pixelValueFromZone)] = rastStatistics; } else { rasInfoDict[b][Convert.ToInt32(pixelValueFromZone)] = new StatisticsInfo() { Count = 1, Sum = Convert.ToDouble(pixelValueFromValue) }; } } catch (Exception ex) { Console.WriteLine(ex.Message); } //Console.WriteLine(i +"-"+j); //Console.WriteLine(pixelValueFromValue + "-" + pixelValueFromZone); } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } while (zoneRasterCursor.Next() == true); //Export results StatisticsExport writer = new StatisticsExport(outSummaryFile); writer.ExportZonalStatistics(ref rasInfoDict, outCellSize); } else { Console.WriteLine("No band available in the Value Raster"); } }