private ISimpleSurface GetRasterSurface( [NotNull] IRaster sourceRaster, [NotNull] IEnvelope box, [CanBeNull] out IDataset memoryRasterDataset) { // Remark: // surface values outside 'raster'.envelope (but within 'box') are 0 Assert.ArgumentNotNull(sourceRaster, nameof(sourceRaster)); Assert.ArgumentNotNull(box, nameof(box)); IRasterFunction rasterFunction = new ClipFunctionClass(); IClipFunctionArguments functionArguments = new ClipFunctionArgumentsClass(); functionArguments.Raster = sourceRaster; IEnvelope clipBox = GetClipBox(box, sourceRaster); functionArguments.Extent = clipBox; functionArguments.ClippingGeometry = clipBox; functionArguments.ClippingType = esriRasterClippingType.esriRasterClippingOutside; IFunctionRasterDataset functionRasterDataset = new FunctionRasterDataset(); functionRasterDataset.Init(rasterFunction, functionArguments); functionRasterDataset.RasterInfo.NoData = (float)-9999; // unsicher, wie die memory verwaltung ist // zum sicherstellen der memory-verwaltung // --> inmemory raster erstellen var save = (ISaveAs2)functionRasterDataset; IWorkspaceName wsName = WorkspaceUtils.CreateInMemoryWorkspace("raster"); var ws = (IWorkspace)((IName)wsName).Open(); save.SaveAs("clipped", ws, "MEM"); IRasterDataset rasterDataset = ((IRasterWorkspace2)ws).OpenRasterDataset("clipped"); IRaster rasterData = rasterDataset.CreateDefaultRaster(); // Problems and workarounds for raster(-mosaic) data in surfaces // ------------------------------------------------------------- // // Extent completly within footprint of mosaic dataset: -> no NoDataValues -> no problems // Extent partly within footprint of mosaic dataset : -> double.NaN returned for values outside footprint -> no problems (TODO: verifiy) // Extent completely outside footprint of mosaic dataset, but within extent of mosaic data set: // 0-values returned for Null-raster values // workaround: ((IRasterProps) rasterData).NoDataValue = (float)0; works, if ((IRasterProps) raster).NoDataValue = null and no Height == 0 // workaround to test: use CustomPixelFilter (see https://github.com/Esri/arcobjects-sdk-community-samples/tree/master/Net/Raster/CustomNodataFilter/CSharp // Extent completely outside extent of mosaic dataset // 0-values returned for Null-raster values, rasterData.Height = 1, rasterData.Width = 1 // workaround 1: use custom RasterSurface class. // workaround 2: ((IRasterProps) rasterData).NoDataValue = (float)0; works, if ((IRasterProps) raster).NoDataValue = null and no Height == 0 memoryRasterDataset = (IDataset)rasterDataset; ISimpleSurface rasterSurface = RasterReference.CreateSurface(rasterData); return(rasterSurface); }
/// <summary> /// Clips a raster to the boundary of a polygon /// </summary> /// <param name="inRaster">IRaster, IRasterDataset, or string</param> /// <param name="geo">Polygon Geometry</param> /// <param name="clipType">the type of clip either inside or outside</param> /// <returns></returns> public IFunctionRasterDataset clipRasterFunction(object inRaster, IGeometry geo, esriRasterClippingType clipType) { IFunctionRasterDataset rRst = createIdentityRaster(inRaster); IRaster2 rRst2 = (IRaster2)createRaster(rRst); string tempAr = funcDir + "\\" + FuncCnt + ".afr"; IFunctionRasterDataset frDset = new FunctionRasterDatasetClass(); IFunctionRasterDatasetName frDsetName = new FunctionRasterDatasetNameClass(); frDsetName.FullName = tempAr; frDset.FullName = (IName)frDsetName; IRasterFunction rsFunc = new ClipFunctionClass(); IEnvelope env = geo.Envelope; double hX = rRst.RasterInfo.CellSize.X / 2; double hY = rRst.RasterInfo.CellSize.Y / 2; double xMin = env.XMin; double xMax = env.XMax; double yMin = env.YMin; double yMax = env.YMax; int clm, rw; rRst2.MapToPixel(xMin, yMin,out clm,out rw); rRst2.PixelToMap(clm, rw, out xMin, out yMin); xMin = xMin - hX; yMin = yMin - hY; rRst2.MapToPixel(xMax, yMax, out clm, out rw); rRst2.PixelToMap(clm, rw, out xMax, out yMax); xMax = xMax + hX; yMax = yMax + hY; env.PutCoords(xMin, yMin, xMax, yMax); IClipFunctionArguments args = new ClipFunctionArgumentsClass(); args.Extent = env; args.ClippingGeometry = geo; args.ClippingType = clipType; args.Raster = rRst; frDset.Init(rsFunc, args); return frDset; }