/// <summary> /// Sets the environment for raster analysis. /// </summary> /// <param name="pWS"></param> /// <param name="pEnv"></param> /// <param name="pSR"></param> /// <param name="dCellSize"></param> /// <param name="pMask"></param> private void SetRasterAnalysisEnvironment(IWorkspace pWS, IEnvelope pEnv, ISpatialReference pSR, Double dCellSize, IGeoDataset pMask) { IRasterAnalysisEnvironment pRAE = new RasterAnalysisClass(); object oEnv = pEnv; object oCellSize = dCellSize; object oBool = true; try { if (pWS != null) { pRAE.OutWorkspace = pWS; } if (pEnv != null) { pRAE.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref oEnv, ref oBool); } if (pSR != null) { pRAE.OutSpatialReference = pSR; } if (dCellSize > 0) { pRAE.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref oCellSize); } if (pMask != null) { pRAE.Mask = pMask; } pRAE.VerifyType = esriRasterVerifyEnum.esriRasterVerifyOff; //TIM: we need to make sure this gets set back at some point pRAE.SetAsNewDefaultEnvironment(); } catch (Exception ex) { clsStatic.ShowErrorMessage(ex.ToString()); } }
internal static RasterExtractionResult SummariseRaster(IGeoDataset pClippingPolygon, ExtractionLayerConfig pExtractionLayerConfig) { // set the analysis extent to be that of the polygon ServerLogger logger = new ServerLogger(); logger.LogMessage(ServerLogger.msgType.debug, "SummariseCategoricalRaster", 99, "Categorical raster clip beginning.."); IEnvelope tAnalysisExtent = pClippingPolygon.Extent; bool pCategoricalSummary = pExtractionLayerConfig.ExtractionType == ExtractionTypes.CategoricalRaster; IGeoDataset pRasterToClip = pExtractionLayerConfig.LayerDataset; IRasterAnalysisEnvironment tRasterAnalysisEnvironment = new RasterAnalysisClass(); object tAnalysisEnvelopeCastToObject = (System.Object)tAnalysisExtent; // object tAnotherBizarreMissingObject = Type.Missing; object tSnapObject = (System.Object)pRasterToClip; tRasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref tAnalysisEnvelopeCastToObject, ref tSnapObject); tRasterAnalysisEnvironment.SetAsNewDefaultEnvironment(); // extract the subset of the raster IExtractionOp2 tExtractionOp = new RasterExtractionOpClass(); // note we want to base the extraction on a raster (in an IGeoDataset) rather than an IPolygon. // That's because the catchment polygon may be multipart, and the operation doesn't work with multipart. // Also the polygon has a max of 1000 vertices. // And raster mask extraction is probably faster since the // polygon is converted internally to a grid anyway. IGeoDataset tClipped; if (pRasterToClip as IRaster != null) { logger.LogMessage(ServerLogger.msgType.debug, "SummariseRaster", 99, "Input was in raster form, using directly to clip..."); tClipped = tExtractionOp.Raster(pRasterToClip, pClippingPolygon); } else { // POLYGON VERSION: tExtractionOp.Polygon(pClipRaster,pPolygon,true) // sometimes we need to be able to pass in a polygon but rather than using the polygon // method we'll manually convert to a mask raster to avoid the issues above // It would save work to do this once for each request rather than repeat the conversion // for each layer - but we might want a different environment (snap extent etc) for each. logger.LogMessage(ServerLogger.msgType.debug, "SummariseCategoricalRaster", 99, "Converting input polygon to mask raster for clip..."); IRasterConvertHelper tConvertPolygonToRaster = new RasterConvertHelperClass(); // convert it to a raster with the same cell size as the input IRasterProps tRst = pRasterToClip as IRasterProps; IPnt tRstCellSize = tRst.MeanCellSize(); double x = tRstCellSize.X; double y = tRstCellSize.Y; double cellSize = Math.Round(Math.Min(x, y), 0); object tCellSizeAsObjectForNoGoodReason = (System.Object)cellSize; tRasterAnalysisEnvironment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref tCellSizeAsObjectForNoGoodReason); IGeoDataset tPolyAsRast = tConvertPolygonToRaster.ToRaster1(pRasterToClip, "GRID", tRasterAnalysisEnvironment) as IGeoDataset; logger.LogMessage(ServerLogger.msgType.debug, "SummariseCategoricalRaster", 99, "...done, proceeding with clip"); tClipped = tExtractionOp.Raster(pRasterToClip, tPolyAsRast); } // now we have the clipped raster we need to summarise it differently depending on whether // we want a summary by category/value (for categorical rasters) or by stats (for float rasters) Dictionary <string, double> tResults; if (pCategoricalSummary) { tResults = WatershedDetailExtraction.SummariseRasterCategorically(tClipped); if (tResults.Count > 100) { // sanity check: don't sum up more than 100 different values tResults = WatershedDetailExtraction.SummariseRasterStatistically(tClipped); pCategoricalSummary = false; } } else { tResults = WatershedDetailExtraction.SummariseRasterStatistically(tClipped); } tRasterAnalysisEnvironment.RestoreToPreviousDefaultEnvironment(); return(new RasterExtractionResult(pExtractionLayerConfig.ParamName, pCategoricalSummary, tResults)); //return tResults; }
internal static RasterExtractionResult SummariseRaster(IGeoDataset pClippingPolygon, ExtractionLayerConfig pExtractionLayerConfig) { // set the analysis extent to be that of the polygon ServerLogger logger = new ServerLogger(); logger.LogMessage(ServerLogger.msgType.debug, "SummariseCategoricalRaster", 99, "Categorical raster clip beginning.."); IEnvelope tAnalysisExtent = pClippingPolygon.Extent; bool pCategoricalSummary = pExtractionLayerConfig.ExtractionType==ExtractionTypes.CategoricalRaster; IGeoDataset pRasterToClip = pExtractionLayerConfig.LayerDataset; IRasterAnalysisEnvironment tRasterAnalysisEnvironment = new RasterAnalysisClass(); object tAnalysisEnvelopeCastToObject = (System.Object)tAnalysisExtent; // object tAnotherBizarreMissingObject = Type.Missing; object tSnapObject = (System.Object)pRasterToClip; tRasterAnalysisEnvironment.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref tAnalysisEnvelopeCastToObject, ref tSnapObject); tRasterAnalysisEnvironment.SetAsNewDefaultEnvironment(); // extract the subset of the raster IExtractionOp2 tExtractionOp = new RasterExtractionOpClass(); // note we want to base the extraction on a raster (in an IGeoDataset) rather than an IPolygon. // That's because the catchment polygon may be multipart, and the operation doesn't work with multipart. // Also the polygon has a max of 1000 vertices. // And raster mask extraction is probably faster since the // polygon is converted internally to a grid anyway. IGeoDataset tClipped; if (pRasterToClip as IRaster != null) { logger.LogMessage(ServerLogger.msgType.debug, "SummariseRaster", 99, "Input was in raster form, using directly to clip..."); tClipped = tExtractionOp.Raster(pRasterToClip, pClippingPolygon); } else { // POLYGON VERSION: tExtractionOp.Polygon(pClipRaster,pPolygon,true) // sometimes we need to be able to pass in a polygon but rather than using the polygon // method we'll manually convert to a mask raster to avoid the issues above // It would save work to do this once for each request rather than repeat the conversion // for each layer - but we might want a different environment (snap extent etc) for each. logger.LogMessage(ServerLogger.msgType.debug, "SummariseCategoricalRaster", 99, "Converting input polygon to mask raster for clip..."); IRasterConvertHelper tConvertPolygonToRaster = new RasterConvertHelperClass(); // convert it to a raster with the same cell size as the input IRasterProps tRst = pRasterToClip as IRasterProps; IPnt tRstCellSize = tRst.MeanCellSize(); double x = tRstCellSize.X; double y = tRstCellSize.Y; double cellSize = Math.Round(Math.Min(x, y), 0); object tCellSizeAsObjectForNoGoodReason = (System.Object)cellSize; tRasterAnalysisEnvironment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref tCellSizeAsObjectForNoGoodReason); IGeoDataset tPolyAsRast = tConvertPolygonToRaster.ToRaster1(pRasterToClip, "GRID", tRasterAnalysisEnvironment) as IGeoDataset; logger.LogMessage(ServerLogger.msgType.debug, "SummariseCategoricalRaster", 99, "...done, proceeding with clip"); tClipped = tExtractionOp.Raster(pRasterToClip, tPolyAsRast); } // now we have the clipped raster we need to summarise it differently depending on whether // we want a summary by category/value (for categorical rasters) or by stats (for float rasters) Dictionary<string, double> tResults; if (pCategoricalSummary) { tResults = WatershedDetailExtraction.SummariseRasterCategorically(tClipped); if (tResults.Count > 100) { // sanity check: don't sum up more than 100 different values tResults = WatershedDetailExtraction.SummariseRasterStatistically(tClipped); pCategoricalSummary = false; } } else { tResults = WatershedDetailExtraction.SummariseRasterStatistically(tClipped); } tRasterAnalysisEnvironment.RestoreToPreviousDefaultEnvironment(); return new RasterExtractionResult(pExtractionLayerConfig.ParamName, pCategoricalSummary, tResults); //return tResults; }