2

I am attempting to extract an irregular polygon from a Mosaic Dataset using ArcObjects in C#. This sample shows how to open a mosaic dataset in ArcObjects. Referencing existing (VB) code, this snippet is from a working tool which uses IPixelOperation to reduce the raster to only the portion covered by a polygon:

Dim pRaster As IRaster = pRasLayer.Raster
Dim pPixOp As IPixelOperation = pRaster
Dim pShapeWS As IWorkspace = pShapeWSfact.OpenFromFile(pFolderPath, 0)
Dim pShapeFws As IFeatureWorkspace = pShapeWS
Dim pShapeFC As IFeatureClass = pShapeFws.OpenFeatureClass(pFileName & ".shp")
Dim pFeatCur As IFeatureCursor = pShapeFC.Search(Nothing, True)
Dim pFeat As IFeature = pFeatCur.NextFeature
Dim pClipFilter As IClipFilter = New ClipFilterClass()
Dim pGeom As IGeometry

Do Until pFeat Is Nothing
  pGeom = pFeat.ShapeCopy
  If pGeom.SpatialReference.FactoryCode <> pMap.SpatialReference.FactoryCode Then pGeom.Project(pMap.SpatialReference)
  pClipFilter.Add(pGeom)

  pFeat = pFeatCur.NextFeature
Loop
pPixOp.PixelFilter = pClipFilter

Which illustrates how an IClipFilter can be used to restrict the display of a raster... I am attempting to use IClipFilter as IPixelFilter to return the irregular portion of a raster within a polygon:

IMosaicWorkspaceExtensionHelper mosaicExtHelper = new MosaicWorkspaceExtensionHelperClass();
IMosaicWorkspaceExtension mosaicExt = mosaicExtHelper.FindExtension(gMosDSsrcWorkspace);
IMosaicDataset pMosDS = mosaicExt.OpenMosaicDataset(gMosDSname);
IRasterDataset3 pInDS = (IRasterDataset3)pMosDS;
IRaster pInRaster = pInDS.CreateFullRaster();
IPixelOperation pPixOp = (IPixelOperation)pInRaster;

IClipFilter pClipFilter = new ClipFilterClass();
// add some geometries to the clip filter, in the same spatial reference as the raster
pPixOp.PixelFilter = (IPixelFilter) pClipFilter;

// then read/write the raster
IPnt ReadBlockSize = new PntClass();
IPnt SrcUpperLeft = new PntClass();
IPnt DestUpperLeft = new PntClass();

// create the pixel block for read/write
ReadBlockSize.SetCoords(pDestCols, RowsToRead);
IPixelBlock pReadBlock = pInRaster.CreatePixelBlock(ReadBlockSize);
IRasterEdit pWriteEdit = (IRasterEdit)pWriteRaster;
for (int RowMin = 0; RowMin < pDestRows; RowMin += RowsToRead)
{
    SrcUpperLeft.SetCoords(pSrcColOffset, pSrcRowOffset + RowMin);
    DestUpperLeft.SetCoords(0, RowMin);
    pInRaster.Read(SrcUpperLeft, pReadBlock);
    //(pClipFilter as IPixelFilter).Filter(pReadBlock);// tried this too, but it still didn't work
    pWriteEdit.Write(DestUpperLeft, pReadBlock); 
}

The result: enter image description here

The image is the size of the dataset which is correct but the pixels are unfiltered. Does IPixelOperation, IClipFilter only work in ArcMap or with IRasterLayer? Do I need to supply the geometries in cell coordinates? Is there an updated/different interface required to work with an IMosaicDataset?... I've tried several different combinations of readers/writers/filterers and none of them seem to have any affect - What am I missing?

1 Answer 1

1

In ArcMap the MosaicDataset is a MosaicLayer and is essentially a CompositeLayer, and the actual raster image is one of its components. So find the raster in the MosaicLayer and treat it exactly as you did the raster in your first example...

Dim pEnumLayer As IEnumLayer = My.ArcMap.Document.FocusMap.Layers(Nothing, True)
pEnumLayer.Reset()
Dim pLayer As ILayer = pEnumLayer.Next()

Do Until pLayer Is Nothing
    If TypeOf pLayer Is IMosaicLayer Then
        Dim pCompositeLayer As ICompositeLayer = pLayer
        Dim pRasterLayer As IRasterLayer = pCompositeLayer.Layer(2)
        Dim pRaster As IRaster = pRasterLayer.Raster
        Dim pPixOp As IPixelOperation = pRaster
        Dim pShapeWSfact As IWorkspaceFactory = New ShapefileWorkspaceFactory
        Dim pShapeWS As IWorkspace = pShapeWSfact.OpenFromFile("P:\", 0)
        Dim pShapeFws As IFeatureWorkspace = pShapeWS
        Dim pShapeFC As IFeatureClass = pShapeFws.OpenFeatureClass("RasterClipTest.shp")
        Dim pFeatCur As IFeatureCursor = pShapeFC.Search(Nothing, True)
        Dim pFeat As IFeature = pFeatCur.NextFeature()
        Dim pClipFilter As IClipFilter = New ClipFilterClass()
        Dim pGeom As IGeometry
        Do Until pFeat Is Nothing
            pGeom = pFeat.ShapeCopy
            If pGeom.SpatialReference.FactoryCode <> My.ArcMap.Document.ActiveView.FocusMap.SpatialReference.FactoryCode Then
                pGeom.Project(My.ArcMap.Document.FocusMap.SpatialReference)
            End If
            pClipFilter.Add(pGeom)
            pFeat = pFeatCur.NextFeature
        Loop
        pPixOp.PixelFilter = pClipFilter
        My.ArcMap.Document.ActiveView.Refresh()
        Exit Do
    End If
    pLayer = pEnumLayer.Next()
Loop

There a few ways you could find the raster in the MosaicLayer, and the one I did above is to assume it is at index 2, though I'm not positive this always the case. Another way would be to find the layer in the MosaicLayer named "Image", but again I am not positive that it will always have that name, since I have not extensively used mosaic datasets and thoroughly tested them.

Edit 5/8/15: This is another way to get the raster of the MosaicDataset, based on the comments below. This seems to only work in ArcMap, however, and not in the standalone windows form...

Dim WSF As IWorkspaceFactory = New FileGDBWorkspaceFactory
Dim fgdbWorkspace As IWorkspace = WSF.OpenFromFile("P:\misc.gdb", 0)
Dim pMosaicHelper As IMosaicWorkspaceExtensionHelper = New MosaicWorkspaceExtensionHelperClass()
Dim pMosaicExt As IMosaicWorkspaceExtension = pMosaicHelper.FindExtension(fgdbWorkspace)
Dim pMosaicDataset As IMosaicDataset = pMosaicExt.OpenMosaicDataset("MD")
Dim pRasterLayer As IRasterLayer = New RasterLayer
pRasterLayer.CreateFromDataset(pMosaicDataset)
pRasterLayer.Name = "my raster layer"
My.ArcMap.Document.FocusMap.AddLayer(pRasterLayer)
Dim pRaster As IRaster = pRasterLayer.Raster
Dim pPixOp As IPixelOperation = pRaster
Dim pShapeWSfact As IWorkspaceFactory = New ShapefileWorkspaceFactory
Dim pShapeWS As IWorkspace = pShapeWSfact.OpenFromFile("P:\", 0)
Dim pShapeFws As IFeatureWorkspace = pShapeWS
Dim pShapeFC As IFeatureClass = pShapeFws.OpenFeatureClass("RasterClipTest.shp")
Dim pFeatCur As IFeatureCursor = pShapeFC.Search(Nothing, True)
Dim pFeat As IFeature = pFeatCur.NextFeature()
Dim pClipFilter As IClipFilter = New ClipFilterClass()
Dim pGeom As IGeometry
Do Until pFeat Is Nothing
    pGeom = pFeat.ShapeCopy
    If pGeom.SpatialReference.FactoryCode <> My.ArcMap.Document.ActiveView.FocusMap.SpatialReference.FactoryCode Then
        pGeom.Project(My.ArcMap.Document.FocusMap.SpatialReference)
    End If
    pClipFilter.Add(pGeom)
    pFeat = pFeatCur.NextFeature
Loop
pPixOp.PixelFilter = pClipFilter
3
  • This is my first foray into mosaic datasets but unfortunately it's not a layer and it's not in ArcMap.. therein I think lies a hint toward the problem. The raster is being gained from either IMosaicDataset or IFunctionRasterDataset (both seem to work the same) and the application is a windows form (standalone) using GxObjects. I'll give it a shot making it into a layer and see how that goes. Commented May 7, 2015 at 21:46
  • No such luck, I created an IRasterLayer, loaded the mosaic dataset using CreateFromDataset(pInDS as IRasterDataset); then IRaster pInRaster = pRasLayer.Raster; in the same order but it gave the same output. Either the raster derived from a mosaic dataset can't be filtered this way or it needs to be done in ArcMap - and for this application that 'aint gonna happen. Commented May 7, 2015 at 22:07
  • 1
    Just for fun I tested the method you describe above (IRasterLayer created from CreateFromDataset and then using its .Raster) in ArcMap with a simple add-in button, and it does work. So it would seem that ArcMap, or a close approximation of its display capabilities, is required for this to work. Not sure how you can emulate that in a standalone windows form... Good luck!! :) Commented May 8, 2015 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.