Export Raster Using ArcObjects

5405
9
02-23-2012 04:30 PM
HenryColgate
Occasional Contributor
I am trying to use IRasterLayerExport3 to export a non-standard raster, pixel width 17x13, to a standard format, 13x13 via ArcObjects.  The problem is that every attempt I make brings the data down to a value in the range 0-255 as opposed to the floating point numbers contained in the original data.

It appears that the Raster Renderer is being forced though it is unselected by default when using Data-->Export in ArcGIS --> Use Renderer.

The Developer Help page states "If you don�??t want to use the raster renderer to filter the pixel values during the export, remove the raster renderer from the raster layer before passing it to the RasterLayerExport object."

http://resources.esri.com/help/9.3/arcgisengine/ArcObjects/esriCarto/IRasterLayerExport_RasterLayer....

However it is not explained how this could be achieved.  The simples solution as I see it using the command 'rasterLayer.setRendererByRefto(null);' crashes the program with an Invalid Pointer Automation Exception.

I am using ArcGIS 10 however I could only find reference to the renderer info in the 9.3 version so that is why I have chosen that link.
0 Kudos
9 Replies
PriyankaMehta
New Contributor
What exactly are you attempting to explain when you say 'non standard raster' ?

If you want to change the pixel width, have you tried resampling(because your final raster has x=y cellsize) before exporting.

Regards,
Priyanka
0 Kudos
HenryColgate
Occasional Contributor
Yeah, bad explanation. Sorry.

Basically by non-standard I mean the input pixel width isn't a square e.g. 13x13 rather it is 17x13.  That is the only thing non-standard about it.  I think it is the resampling here that may be the problem.  But of course maybe not.  I think it forces the renderer to be used.

ArcGIS automatically resamples and outputs as 13x13 grid so that is fine though I have tried forcing to 13x13 also with the same effect.
0 Kudos
PriyankaMehta
New Contributor
So now what I understand is, that you are being able to standardize it in terms of pixel size but it becomes an 8 bit raster because it keeps forcing the renderer.

Do you want to share your code developed till now .. may b we can catch something
0 Kudos
HenryColgate
Occasional Contributor
Pretty basic code.  Straight out of help.


//Open MXD and get first dataframe then get the first layer from the data frame.  

MapDocument tempMxd = new MapDocument();
tempMxd.esri_new("E:/OutputDirectory/tempmxd.mxd");
IMap map = tempMxd.getMap(0);
ILayer layer = map.getLayer(0); 


//Create a workspace so we can work with the data

WorkspaceFactory wkspf = new RasterWorkspaceFactory();
IWorkspace wksp = wkspf.openFromFile("E:/outputDir/", 0);
IRasterLayerExport3 rle = new RasterLayerExport();
IRasterLayer rl = (IRasterLayer) layer;


//Tweak how we want to export (at least as far as possible)

rle.setRasterLayerByRef(rl);
rle.setExtent(rl.getAreaOfInterest()); 
rle.setForce2RGB(false);


//Don't compress
  
IRasterStorageDef rsd = new RasterStorageDef();
rsd.setCompressionType(esriRasterCompressionType.esriRasterCompressionUncompressed);
rle.setStorageDefByRef(rsd);
 
 
//Export.  

rle.export(wksp, "exportLayer.bil", "BIL");

//Note:  No other file types work here either but I am willing to accept any uncompressed raster type besides BIL if it works


0 Kudos
PriyankaMehta
New Contributor
Hi,

I guess this should work. You can exclude killifexistsraster function if you want, because it deletes the output raster without warning when you try it again.

Dim pMxDoc As IMxDocument
        Dim pMap As IMap
        Dim pRasterLayer As IRasterLayer
        Dim pRaster As IRaster
        Dim pGeometryProc As IRasterGeometryProc

        pMxDoc = My.ArcMap.Application.Document
        pMap = pMxDoc.FocusMap
        pRasterLayer = pMap.Layer(0)
        pRaster = pRasterLayer.Raster

       
        pGeometryProc = New RasterGeometryProc
        pGeometryProc.Resample(rstResamplingTypes.RSP_NearestNeighbor, 7, pRaster)
     

        Dim pDataset As IDataset
        pDataset = pRasterLayer
        Dim pWS As IWorkspace
        pWS = pDataset.Workspace
        Dim str As String
        str = pWS.PathName

        killifexistsRaster("try", str)
        Dim RasterDataset As IRasterDataset
        Dim pRasBandCol As IRasterBandCollection
        pRasBandCol = pRaster
        'pDS = pRasBandCol.SaveAs("try3", pWS, "GRID")
        RasterDataset = pRasBandCol.SaveAs("try", pWS, "GRID")

        '***********************************
        Dim pRasterLy As IRasterLayer
        pRasterLy = New RasterLayer
        ' pRasterLayer.CreateFromRaster(pRaster)
        pRasterLy.CreateFromDataset(RasterDataset)
        pMap.AddLayer(pRasterLy)
        pMxDoc.ActiveView.Refresh()
        '***********************************

        SaveAsWithoutBuildingPyramids(pRaster)


    End Sub

    Sub SaveAsWithoutBuildingPyramids(ByVal pRaster As IRaster) 'Or as IRasterDataset)

        killifexistsRaster("tryexp", "C:\temp")

        Dim pSaveAs2 As ISaveAs2
        pSaveAs2 = pRaster
        Dim pStorageDef As IRasterStorageDef2
        pStorageDef = New RasterStorageDef
        pStorageDef.PyramidLevel = 0
        Dim pWs As IWorkspace
        pWs = SetRasterWorkspace("c:\temp")
        pSaveAs2.SaveAs("try_exp", pWs, "GRID")
    End Sub


    Public Function SetRasterWorkspace(ByVal sPath As String) As IRasterWorkspace
        Dim pWsFact As IWorkspaceFactory
        pWsFact = New RasterWorkspaceFactory
        SetRasterWorkspace = pWsFact.OpenFromFile(sPath, 0)
    End Function



    Public Function killifexistsRaster(ByVal RasterName As String, ByVal strFolder As String)

        '''''' Delete raster from disk

        Dim pRWSF As IWorkspaceFactory
        pRWSF = New RasterWorkspaceFactory

        Dim pRWS As IRasterWorkspace
        pRWS = pRWSF.OpenFromFile(strFolder, 0)

        Dim pRasterDS As IRasterDataset
        On Error Resume Next
        pRasterDS = pRWS.OpenRasterDataset(RasterName)

        If Not pRasterDS Is Nothing Then
            Dim pDS As IDataset
            pDS = pRasterDS
            If pDS.CanDelete Then pDS.Delete()

        End If
        System.IO.Directory.Delete(strFolder & "\" & RasterName, True)
        DeleteFolder(strFolder & "\" & RasterName)
 
    End Function

Public Function DeleteFolder(ByVal strPath As String) As Boolean
        Dim objDir As New IO.DirectoryInfo(strPath)

        Try
            objDir.Delete(True)
            Return True
        Catch
            Return False
        End Try
    End Function

0 Kudos
HenryColgate
Occasional Contributor
Cheers Priyanka, that works about 95%.  Will give you an upvote because I think it should work 100%.

Unfortunately I am getting rounded values in my resampled raster.  e.g. 10.1 becomes 10 as does 10.6.

I have removed the entire resampling section.  This seems to export exactly the same data as when it was there. 

It appears that SaveAs2 is responsible for rounding the data.  I have no idea why or how to fix.
0 Kudos
PriyankaMehta
New Contributor
Hi,

   Are you by any chance decreasing the resolution of your raster i.e. increasing the pixel size from original.
I tired the code on a raster with a pixel size of 5 originally. If I resample it with cell size 7 I will definitely loose information. Even the size of the
raster on hard disk will decrease. On the other hand, if I change the size to 2, then I obviously wont loose any information and there are no round offs.

Moreover, in your case, since your pixels are not square originally, that might also be a reason for lost information somewhere. Try the same code on a standard raster and see if there is any difference.
Does it work fine when you do it manually by using 'Data' --> 'Export Data'.
0 Kudos
HenryColgate
Occasional Contributor
Ironically, exporting to GRID does not work when I use Data --> Export Data however TIFF works perfectly that is no rounding of digits.  This is due to the limitations in GRID export.  Pixel, type, number of bands or colour map.  In the GRID export it notes a 32bit value rather than 64bit for TIFF.

On the other hand when I use SaveAs, GRID is the only one I can get to work.  TIF completes okay and seems to reference a 10Mb file when I open it in ArcMap.  However there is no data and the TIF and TDW files in the file system only take up 1Kb each.  Data in TDW looks fine though.  Also, when I query using the Identify tool within the expected bounds it comes up as 'No Data' rather than not displaying because the Identify query is outside the bounds.

Likewise IMAGINE Image seems to export okay using Data --> Export Data.  Like TIFF however in ArcObjects it does not fail causing an error but completes with empty data.

Also, yes, pixel is decreasing from 13x17 to 13x13
0 Kudos
HongchaoJia
New Contributor

but how to use RasterLayerExport while keep Pixel Depth?

because I want to use RasterLayerExport to export only some area of this raster

0 Kudos