Working with Spatial Analyst


Summary
This topic provides a basic overview of the necessary steps to implement a Spatial Analyst operation. Details on additional features and how the system works are also provided.

In this topic


About working with Spatial Analyst

The ArcObjects components for the ArcGIS Spatial Analyst extension provide a customizable environment with a set of developer tools that allow model development. Spatial Analyst works closely with the Raster Data Objects (RDO). The RDO model is used to access, analyze, manage, convert, and visualize raster data.
RDO provides features to complement the Spatial Analyst object model, such as unified data access and interaction independent format, a high-level nonproprietary language, and an environment that is easy to extend, upgrade, and customize.

Using Spatial Analyst objects

The Spatial Analyst object model is composed of a collection of objects to perform raster analysis. There are two main types of objects: objects that support the overall Spatial Analyst environment (the analysis environment, selection, and toolbar) and objects that perform analysis operations (slope, aspect, distance analysis, and so on).
The objects that perform analysis operations are functionally grouped according to the type of analysis they perform—CostDistance, CostAllocation, EuclideanDistance, CostPath, and so on—and are methods of RasterDistanceOp (distance operator object).
There are many objects in the Spatial Analyst object model and hundreds of methods that perform spatial modeling. Even though there are many objects and methods, the following are the main factors when implementing any Spatial Analyst operation:

Checking out the Spatial Analyst extension

To access the Spatial Analyst objects, check out the Spatial Analyst extension. You can check out this extension prior to accessing each Spatial Analyst object, check it out once in a single method, or check it out once for the entire application. Check out the Spatial Analyst extension license when doing spatial analysis. Once you are done with spatial analysis, check the license back in so other users can use the same license in a floating license environment.
AOInitialize is a singleton object.
See the following code example:
[Java]
public void checkOutSpatialAnalyst(){
    try{
        new AoInitialize().checkOutExtension
            (esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst);
    }
    catch (Exception e){}
}

public void checkInSpatialAnalyst(){
    try{
        new AoInitialize().checkInExtension
            (esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst);
    }
    catch (Exception e){}
}

Setting the analysis environment

Certain operators, such as RasterDensityOp and RasterInterpolationOp, require that some properties of the analysis output be specified. Two properties of particular importance to set are the output cell size and the extent of the analysis.
The analysis environment (through the RasterAnalysis object) controls four primary properties when performing analysis: cell size, extent, mask, and spatial reference. Even though these settings do nothing to the original data, the extent and mask affect the locations where the operation occurs. The extent defines the area on which the operation is performed. The mask defines the cell locations within the extent on which to perform the operation and the specified cell size controls the resolution of the output.
Each operator object has its own analysis environment settings. You can set the environment parameters individually for each operator object. For more information, see Analysis environment in this topic.
When created, the new operator object obtains its parameters from the settings in the RasterAnalysis object. The following code example shows how to change the default analysis environment settings that subsequent new operator objects will inherit:
[Java]
// Creates a new RasterAnalysis object and sets it as a new default setting.
public IRasterAnalysisEnvironment setNewDefaultEnvironment(IEnvelope extent, double
    cellSize, IGeoDataset mask, IWorkspace workSpace, ISpatialReference spatialRef){
    RasterAnalysis env = null;
    try{
        // Create a RasterAnalysis object.
        env = new RasterAnalysis();
        // Set the new default extent.
        env.setExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, extent, null);
        // If Not pExtent Is Nothing Then pEnv.SetExtent esriRasterEnvValue,
        // pExtent.
        // Set the new default cell size.
        env.setCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, new Double
            (cellSize));
        // Set the new default mask for analysis.
        env.setMaskByRef(mask);
        // Set the new default output workspace.
        env.setOutWorkspaceByRef(workSpace);
        // Set the new default output spatial reference.
        env.setOutSpatialReferenceByRef(spatialRef);
        // Set it as the default settings.
        env.setAsNewDefaultEnvironment();
        // Return reference to the default environment setting.
    }
    catch (Exception e){
        e.printStackTrace();
    }
    return env;
}
To reset the global analysis environment to the defaults, run the following code example; in this example, env is the new default settings that are set by the previous code example.
[Java]
env.reset();

Accessing the input data

When you have a license and have optionally set the analysis environment, identify the input data on which to apply the Spatial Analyst operation. There are four acceptable raster object inputs into a Spatial Analyst operation that calls for raster input: RasterDataset, RasterBand, Raster, or RasterDescriptor.
RasterDataset represents an existing dataset stored on disk or in a database in a particular raster format, for example, TIFF. RasterBand is an individual band of a RasterDataset. Some RasterDatasets have multiple bands, such as a satellite image, while others contain a single band such as an ESRI grid. You cannot alter the values or projection of a RasterDataset or the RasterBands. A raster is a virtual representation of raster data derived from a data source on disk. A raster can be a subset of the original RasterDataset, can be projected into a different projection, and can be composed of bands from different RasterDatasets.
A RasterDescriptor is used to present a subset of the original Raster, for example, through an attribute selection or to use an alternative value for each cell defined in a field in the data's attribute table. For more information about the raster data object model, see the DataSourcesRaster library.
In addition, two feature data objects are valid inputs; FeatureClass and FeatureClassDescriptor. The features are converted to rasters using the existing environment settings. A FeatureClass is converted directly, while a subset of the original FeatureClass is converted in a FeatureClassDescriptor.
As previously mentioned, a Spatial Analyst operation can be performed on a RasterDataset, RasterBand, Raster, RasterDescriptor, FeatureClass, or FeatureClassDescriptor. When accessing a RasterDataset, the RasterWorkspaceFactory must be used. The following code example accesses a raster on disk:
[Java]
/**
 * 
 * @param path, path of the input raster dataset
 * @param fileName, name of the input raster dataset
 * @return raster dataset
 */
public IRasterDataset openRasterDataset(String path, String fileName){
    IRasterDataset dataSet = null;
    try{
        RasterWorkspaceFactory factory = new RasterWorkspaceFactory();
        if (factory.isWorkspace(path)){
            IRasterWorkspace workSpace = (IRasterWorkspace)factory .openFromFile
                (path, 0);
            dataSet = workSpace.openRasterDataset(fileName);
        }
        else{
            System.out.println("Not a Valid WorkSpace");
        }
    }
    catch (Exception e){}
    return dataSet;
}
When a raster object exists, it can be used in an operation. To access a raster layer from a map, shapefile, or coverage from disk, see Using other ArcGIS objects with Spatial Analyst in this topic.
You may not want to perform a Spatial Analyst operation on the entire input dataset, but rather on a subset of the data—or you may want an operation to use values defined in a certain field in the data's attribute table.
An attribute subset can be created from the input dataset identifying the cells or features on which to perform the operation. To create an attribute selection or subset of the cells of an input RasterDataset, create a raster object from the RasterDataset and create a RasterDescriptor from the raster. The RasterDescriptor identifies the qualifying selection.
The following code example uses a RasterDescriptor to create an attribute subset and calls the OpenRasterDataset method. Alternatively, the same procedure can be done with feature data inputs by creating a FeatureClassDescriptor from a FeatureClass.
[Java]
/**
 * 
 * @param path, path of the raster dataset
 * @param fileName, name of the raster dataset
 * @param whereClause, where clause for the QueryFilter
 * @param subField, a list of field names. "" will use all fields
 * @param inField, a field name
 * @return
 */
public RasterDescriptor createRasterDescriptor(String path, String fileName, String
    whereClause, String subField, String inField){
    RasterDescriptor descriptor = null;
    try{
        QueryFilter filter = new QueryFilter();
        filter.setWhereClause(whereClause);
        filter.setSubFields(subField);
        // Create a raster from the dataset.
        IRaster raster = openRasterDataset(path, fileName).createDefaultRaster();
        // Create the raster descriptor.
        descriptor = new RasterDescriptor();
        descriptor.create(raster, filter, inField);
    }
    catch (Exception e){}
    return descriptor;
}
You can also create a RasterDescriptor or FeatureClassDescriptor using any desired field. For more information, see Fields in this topic.

Performing an operation

The majority of the objects in the Spatial Analyst object model are operator objects that contain the methods for spatial analysis. The methods are grouped functionally into objects based on the analysis performed. The following are the two main steps for applying a Spatial Analyst operation once the data has been identified:
The following code example queries RasterSurfaceOp and invokes the Slope method on an input elevation raster:
[Java]
// Gets an elevation raster from disk.
IRasterDataset elevation = openRasterDataset("D://SpatialTest", "elevation");
// Queries the RasterSurfaceOp.
RasterSurfaceOp surfaceOp = new RasterSurfaceOp();
// Creates a geodataset to store the results and runs the operation.
IGeoDataset slope = surfaceOp.slope((IGeoDataset)elevation,
    esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopeDegrees, null);
Even though there are many operator objects with hundreds of methods, to implement any of them, the pattern of use is the same. The only things that change from this example is the operator queried, method called, and specified parameters.

Using the output

If raster data is produced as the output from an operator, it's temporary. The data on disk is deleted as soon as it is not referenced by any objects. This temporary output can be used as input to another operator, be saved as a permanent raster dataset, or displayed in the map using the MapControl. For more information about how to make the output permanent, see Temporary outputs in this topic.
The following code example shows how to display the temporary output in a MapBean:
[Java]
/**
 * Add an IRaster to the map.
 * @param mapBean
 * @param raster
 */
public void addRasterLayer(MapBean mapBean, IRaster raster){
    try{
        RasterLayer rasterLayer = new RasterLayer();
        rasterLayer.createFromRaster(raster);
        mapBean.addLayer(rasterLayer, 0);
    }
    catch (Exception e){
        e.printStackTrace();
    }
}
Even though there are many ways to qualify the input data, perform operations, and use the output and many possible sequences to perform the desired analysis, the pattern of use for implementing any of the Spatial Analyst operators follows the same steps previously identified. The criteria that changes in any analysis are the input datasets and qualifiers, operator, method (and its parameters), and how the output is used.

Features of the ArcGIS Spatial Analyst object model

In this section, additional details are given about how the overall Spatial Analyst object model works and how the individual objects interact. The issues to consider when using the objects in conjunction with one another to perform a desired analysis are also discussed.
In addition to the standard operator objects in ArcGIS Spatial Analyst, another way to apply raster operations is through RasterMapAlgebraOp and RasterModel. These two objects allow you to submit Grid Map Algebra syntax command strings for execution on your data.
The properties of the output from an ArcGIS Spatial Analyst operator can be specified using the raster analysis environment. You can control the analysis extent, cell size, and mask properties; but with ArcGIS Spatial Analyst, you also have control of the spatial reference system in which the output dataset will be created and the workspace in which the output will be placed.

Referencing the Spatial Analyst objects and libraries

The Spatial Analyst objects are divided among three object libraries, each of which contains some, but not all, of the coclasses and interfaces used in the Spatial Analyst extension. The Spatial Analyst objects are divided in this manner because of different licensing schemes. Some of the objects are available with the core ArcGIS product, some are available with the 3D Analyst or Spatial Analyst extension, and others are available only with Spatial Analyst.

Analysis environment

The analysis environment controls the properties of the analysis performed by almost every Spatial Analyst operation. It contains the cell size, extent, and mask properties and provides a way to control the output spatial reference, the output workspace into which temporary results are placed, the verify environment used when over-writing previous results, and the prefix of the output dataset name.
The session default analysis environment controls the analysis environment that is assigned to each operator object when it's created. When you begin a new session of ArcGIS or your application using the Spatial Analyst objects, it contains the initial default settings shown in the following table:
Cellsize
Maximum of input dataset cell sizes (ArcGrid MAXOF setting)
Extent
Intersection of input dataset extents (ArcGrid MINOF setting)
Mask
None
Verify
Returns error message if output exists and terminates process (ArcGrid ERROR setting)
DefaultOutputRasterPrefix
Raster
DefaultOutputVectorPrefix
Shape
OutSpatialReference
OutWorkspace
Uses the %TEMP% system variable
The session default analysis environment can be overridden so each new operator object begins with a different set of analysis environment properties. This can be helpful if you're performing an analysis that requires multiple operator objects and needs an analysis environment setting that is not the same as the default. To change the session default analysis environment, cocreate either the RasterAnalysis object or any Op object, then query for the IRasterAnalysisEnvironment interface. Change the settings of the analysis environment to those you want to make the default, then invoke the setAsNewDefaultEnvironment method. The setAsNewDefaultEnvironment method will not change the analysis environment associated with any existing operator objects, but each new operator object will contain the settings that have been set as the default. For more information, see Setting the analysis environment in this topic for a code example on how to set the default parameters.
Each operator object has its own analysis environment. This environment can be accessed for any operator object through the IRasterAnalysisEnvironment interface. The methods on this interface allow direct control of the analysis environment on that object. When an operator object is created, the initial analysis environment properties are taken from the session default analysis environment.
The following code example sets the desired analysis environment properties for a new operator object. The example gives an explicit workspace path, cell size, and extent and uses the MakeConstant method from RasterMakerOp. You can change these parameters and methods to your required analysis.
[Java]
RasterMakerOp rasterMakerOp = new RasterMakerOp();
RasterWorkspaceFactory factory = new RasterWorkspaceFactory();
IWorkspace workSpace = factory.openFromFile("C:/tmp", 0);
rasterMakerOp.setOutWorkspaceByRef(workSpace);
rasterMakerOp.setCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, new Double(30)
    );
Envelope ext = new Envelope();
ext.setXMax(3000);
ext.setXMin(0);
ext.setYMax(3000);
ext.setYMin(0);
rasterMakerOp.setExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ext, null);
IRaster outRaster = (IRaster)rasterMakerOp.makeConstant(10, true);

Data integration

While virtually all the methods in Spatial Analyst perform their analysis on raster data, inputs can be specified in many vector formats and any raster format supported in ArcGIS. This data conversion is implicitly performed by the Spatial Analyst operator objects using properties specified in the analysis environment and is transparent to the user. If multiband raster data is input into a Spatial Analyst operation, most methods use the first band of the dataset for analysis. There are some exceptions to this rule, for example, ILocalOp.combine and ILocalOp.localStatistics. If more control over data conversion properties is required, RasterConversionOp can be used.
Only geographic data types are acceptable as inputs and to provide compiler type checking, and an interface supported by all appropriate input types must be used. The IGeoDataset interface is supported by the widest range of geographic data types. Objects that support this interface, and that are acceptable inputs to most Spatial Analyst operations, include the Raster, RasterDataset, RasterBand, RasterDescriptor, FeatureClass, and FeatureClassDescriptor objects. However, many other data types that cannot be used as inputs to spatial operations also support this interface. These data types include any layer type, such as RasterLayer and FeatureLayer, as well as triangulated irregular network (TIN) objects. If a dataset of a type not supported by Spatial Analyst is input to an operation, Error During Conversion or Could not reference the Grid dataset error messages appear. These errors can also occur if a vector dataset is input to a method with no cell size set or when there are other problems with the input data.
The Grid engine that provides most of the functionality present in Spatial Analyst can only accept raster input in ArcGrid format, while a few methods that use feature data as inputs can accept only shapefiles or coverages—for example, inverse distance weighted (IDW) and density.
The Spatial Analyst objects allow as input all supported raster formats and many vector formats into these methods. This is accomplished by converting these datasets to the correct input format prior to performing the operation. Consequently, it is not recommended to perform analysis on large, highly compressed rasters, such as CCITT Group 4, JPEG, or MrSID format. The conversion can be slow and consume significant system resources. To perform analysis on a dataset repeatedly and minimize processing time, convert the data into ArcGrid or shapefile format to prevent this implicit conversion from occurring for each operation.

Method defaults

In ArcGrid, most method arguments have default values. No input is needed if the default value is to be used for a specific argument. In Spatial Analyst, there are no default values, so these parameters are optional. These optional arguments are not strongly typed, and the optional arguments are specified as null. Sometimes methods return objects that can be any data type and the compiler cannot verify if the input argument type is correct. However, an operator expects a specific data type for the argument, and errors can occur if the wrong primitive type is used. To obtain the desired results, care must be given to the arguments of the methods.

Fields

Any numeric field in your input data can be specified as the analysis field for most operations and many operations also support analysis on fields containing character strings. Furthermore, almost all Spatial Analyst operations allow analysis to be performed on a subset of the input data. This subset can be specified using a logical query on any numeric or string field in the input data. Examples of this include a pH field in a soil raster that was created from soil type, a string field containing land use type in a land use raster, or a string field of road type in a roads feature dataset.
The following code example shows how to create a raster descriptor. The method allows an attribute subset to be created from the original input raster based on a specified field and where clause. For example, raster is a raster object created from a land use raster dataset, fieldName is the field name for land use type, and whereClause is one of the land use types, such as forest.
[Java]
Public RasterDescriptor createRasterDescriptor(String path, String fileName, String
    whereClause, String subField, String inField){
    RasterDescriptor descriptor = null;
    try{
        QueryFilter filter = new QueryFilter();
        filter.setWhereClause(whereClause);
        filter.setSubFields(subField);
        // Create a raster from the dataset.
        IRaster raster = openRasterDataset(path, fileName).createDefaultRaster();
        // Create a raster descriptor.
        descriptor = new RasterDescriptor();
        descriptor.create(raster, filter, inField);
    }
    catch (Exception e){}
    return descriptor;
}
The resulting raster descriptor can be input into any method. Any method that is applied to the descriptor will only be applied to cells containing the forest land use type.

Temporary outputs

All raster outputs from Spatial Analyst operations are temporary. To keep an output dataset after objects referencing it go out of scope, you must explicitly make it permanent. To make the output raster permanent, get the RasterDataset associated with the raster object returned from a Spatial Analyst operation. From the RasterDataset object, the ITemporaryDataset interface can be used to make the dataset permanent. Vector outputs are always permanent.
The name of the temporary dataset created by Spatial Analyst is the prefix specified by the analysis environment followed by an integer. This integer is appended to the prefix so each raster will be uniquely named. Each time an output is created, this integer sequentially increases.
The following code example shows how to make a temporary output result raster permanent:
[Java]
Ppublic void makePermanent(IRaster result){
    try{
        IRasterBandCollection bandCollection = (IRasterBandCollection)result;
        IRasterDataset dataset = bandCollection.item(0).getRasterDataset();
        ITemporaryDataset temp = (ITemporaryDataset)dataset;
        RasterWorkspaceFactory factory = new RasterWorkspaceFactory();
        IWorkspace workSpace = factory.openFromFile("C:/tmp", 0);
        //Format can be GRID, TIFF, or IMAGINE Image; Format string is case sensitive.
        //On Unix, do not use mixed cases for the name.
        temp.makePermanentAs("Result.img", workSpace, "IMAGINE Image");
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

Multiband output

Some methods, such as Curvature, eucDistanceFull, costDistanceFull, and flowDirection, allow additional optional outputs to be returned from the operation. In these cases, the return is a raster object that is a collection of bands from the different output datasets. To separate them, use the IRasterBandCollection interface on the output raster and individually access the bands. When you have the individual bands, access the datasets to make them permanent. The first band will be the default output of the method and the bands will be placed in the same order as they appear in the method signature.
The following code example shows how to access the second band and profile curve from the results of the Curvature method:
[Java]
public IRaster getSecondRaster(IRaster resultCurvature){
    IRaster secondRaster = null;
    try{
        IRasterBandCollection bandCollection = (IRasterBandCollection)
            resultCurvature;
        if (bandCollection.getCount() > 1){
            IRasterDataset dataset = bandCollection.item(1).getRasterDataset();
            secondRaster = dataset.createDefaultRaster();
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
    return secondRaster;
}

Deferred evaluation

To increase system performance, raster outputs from Spatial Analyst methods are not computed until they are used. This deferred evaluation of output datasets can result in outputs never being calculated if they are never used. Any use of the output, including creating a layer, examining the height and width of the output, or making the dataset permanent, triggers evaluation of the expression to create the dataset.
Global methods, such as costDistance, are not deferred and are evaluated when called whether the output is referred to or not. For all other operations, the evaluation of the output is deferred until the output data set is used.
The following code example forces the evaluation of the Slope method by calling the getProperty method that queries the height of the output dataset. This code example also calls the openRasterDataset method, which is described in Accessing the input data.
[Java]
//Get the elevation raster from the disc.
IRasterDataset elevation = openRasterDataset("C:/spatialanalyst", "elevation");
//Create a RasterSurfaceOp.
RasterSurfaceOp surfaceOp = new RasterSurfaceOp();
//Create a Geodataset to store the result of the operation.
IGeoDataset output = surfaceOp.slope((IGeoDataset)elevation,
    esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopeDegrees, null);
//Force the evaluation by querying the Height property.
IRasterProps props = (IRasterProps)output;
System.out.println("Height: " + props.getHeight());

Spatial reference handling

If all your data is in the same coordinate system, it is best to perform analysis in that coordinate system. However, the output spatial reference system of any Spatial Analyst object can be specified using the analysis environment by setting the OutSpatialReference property. If the output spatial reference system is not specified, a Spatial Analyst operation will use the spatial reference of the first raster input that has a spatial reference other than Unknown.
If no raster inputs have spatial reference information, the spatial reference will be taken from the first feature input with a defined spatial reference. If no input dataset has a defined spatial reference, the output will have an unknown coordinate system. Any other input with a spatial reference different from the output will be projected on the fly into the output coordinate system before the operation begins.
For vector data, this on-the-fly projection is very accurate; however, raster data is projected using an algorithm that produces faster results than a true projection at the cost of high accuracy. For raster datasets at low latitudes (<50 north or south) and smaller than a few degrees on each side, this projection is fairly accurate but is inappropriate for larger or polar raster datasets. In these cases, use ArcGrid to project your data using a cell-based projection for highest accuracy.

Using PixelBlock for custom analysis

The DOCELL, IF, and WHILE commands of ArcGrid are not available in ArcGIS Spatial Analyst. Each of these constructs loops through all cells in a raster dataset and performs some computation on each cell. The core raster data objects provide the ability to perform direct pixel reading and writing through the PixelBlock object, allowing you to replicate these tools and create new custom tools.
PixelBlock allows you to read and write pixel data from a band of a raster dataset on disk or from a raster. The following code example shows how to access the individual cell values in an input raster dataset, perform a specified method, and write the output to a new raster using PixelBlock. The code example not only shows how to access the individual values for each cell, but also shows, using neighborhood notation, how to access the neighboring cell values around the processing cell, which is accomplished by specifying the neighboring cell address such as (-1, -1) as the bottom left diagonal cell from the processing cell.
To access the value of the processing cell (not its neighbors) in the following code example, use inputBlock.getVal(0, i, j). The code example is long, but it demonstrates a powerful capability in ArcGIS. By slightly changing this example, any number of new methods can be created or any filters specified.
[Java]
/**
 * Shows users to use the PixelBlock object to perform neighborhood notation.       
 * @param inputPath,            path of the input raster dataset
 * @param inputFileName,            name of input raster dataset
 * @param outPath,            path of the output raster dataset
 * @param outFileName,            name of the output raster dataset
 */
public void neighborhoodNotation(String inputPath, String inputFileName, String
    outPath, String outFileName){
    try{
        RasterWorkspaceFactory factory = new RasterWorkspaceFactory();
        if (!factory.isWorkspace(inputPath))
            return ;
        IRasterWorkspace workSpace = (IRasterWorkspace)factory .openFromFile
            (inputPath, 0);
        IRasterDataset inputDataset = workSpace .openRasterDataset(inputFileName);
        // Get RasterBand from the input raster.
        IRasterBandCollection inputBandColl = (IRasterBandCollection)inputDataset;
        IRasterBand inputBand = inputBandColl.item(0);
        IRasterProps inputProps = (IRasterProps)inputBand;
        // Create a default raster from the input raster dataset.
        IRaster inputRaster = inputDataset.createDefaultRaster();
        // Output raster.
        if (!factory.isWorkspace(outPath))
            return ;
        workSpace = (IRasterWorkspace)factory.openFromFile(outPath, 0);
        Point originPt = new Point();
        originPt.setX(inputProps.getExtent().getXMin());
        originPt.setY(inputProps.getExtent().getYMin());
        int inPixelType = inputProps.getPixelType();
        int outPixelType = 0;
        switch (inPixelType){
            case rstPixelType.PT_COMPLEX:
                {
                    JOptionPane.showMessageDialog(null, 
                        "Operation not supported on Complex Data");
                    return ;
                }
            case rstPixelType.PT_DCOMPLEX:
                {
                    JOptionPane.showMessageDialog(null, 
                        "Operation not supported on Complex Data");
                    return ;
                }
            case rstPixelType.PT_CHAR:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_DOUBLE:
                outPixelType = rstPixelType.PT_FLOAT;
                break;
            case rstPixelType.PT_FLOAT:
                outPixelType = rstPixelType.PT_FLOAT;
                break;
            case rstPixelType.PT_LONG:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_SHORT:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_U1:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_U2:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_U4:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_UCHAR:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_ULONG:
                outPixelType = rstPixelType.PT_LONG;
                break;
            case rstPixelType.PT_USHORT:
                outPixelType = rstPixelType.PT_LONG;
                break;
        }
        IRasterWorkspace2 rasterWorkSpace = (IRasterWorkspace2)workSpace;
        IRasterDataset outDataset = rasterWorkSpace.createRasterDataset(outFileName,
            "GRID", originPt, inputProps.getWidth(), inputProps.getHeight(),
            inputProps.meanCellSize().getX(), inputProps.meanCellSize().getY(), 1,
            outPixelType, inputProps.getSpatialReference(), true);
        //Create a default raster from the output raster dataset.
        IRaster outRaster = outDataset.createDefaultRaster();
        // Get RasterBand from the input raster.
        IRasterBandCollection outBandColl = (IRasterBandCollection)outDataset;
        IRasterBand outBand = outBandColl.item(0);

        IRawPixels inRawPixel = (IRawPixels)inputBand;

        IRawPixels outRawPixel = (IRawPixels)outBand;

        //Create a Dbl Point to hold pixelblock size.
        DblPnt pnt = new DblPnt();
        pnt.setCoords(inputProps.getWidth(), inputProps.getHeight());

        //Create pixel block of input and output with defined size:
        IPixelBlock inputBlock = inRawPixel.createPixelBlock(pnt);
        IPixelBlock outBlock = outRawPixel.createPixelBlock(pnt);

        //Read input pixel block.
        pnt.setX(0);
        pnt.setY(0);
        inRawPixel.read(pnt, inputBlock);

        //Get the safe array associated with the first band of output.
        double[][] safearray = (double[][])outBlock.getSafeArray(0);
        IRasterProps outProps = (IRasterProps)outBand;

        //Loop through the safe array and calculate each pixel value.
        for (int i = 0; i < inputProps.getWidth(); i++)
        for (int j = 0; j < inputProps.getHeight(); j++){
            if ((i - 1) >= 0 && (i + 1 <= inputProps.getWidth() - 1) && (j - 1) >= 0
                && (j + 1 <= inputProps.getHeight() - 1))
                if (!((Double)inputBlock.getVal(0, i, j)).equals((Double)
                    inputProps.getNoDataValue()) && !((Double)inputBlock.getVal(0, i
                    + 1, j + 1)).equals((Double)inputProps.getNoDataValue()) && !(
                    (Double)inputBlock.getVal(0, i - 1, j - 1)).equals((Double)
                    inputProps.getNoDataValue()))
                    safearray[i][j] = ((Double)inputBlock.getVal(0, i, j))
                        .doubleValue() + ((Double)inputBlock.getVal(0, i - 1, j - 1))
                        .doubleValue() - ((Double)inputBlock.getVal(0, i + 1, j + 1))
                        .doubleValue();
            else{
                safearray[i][j] = ((Double)outProps.getNoDataValue()).doubleValue();
            }
            else{
                safearray[i][j] = ((Double)outProps.getNoDataValue()).doubleValue();
            }
        }
        outRawPixel.write(pnt, outBlock);
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

Using other ArcGIS objects with Spatial Analyst

The Spatial Analyst objects rely on obtaining input data from the RDO model as well as other object models available in ArcGIS. In Spatial Analyst methods, a RasterDataset, RasterBand, Raster, and RasterDescriptor are valid inputs as well as FeatureClass and FeatureClassDescriptor. Any of these inputs provide acceptable output behavior.
As previously discussed in the Accessing the input data section, the steps for implementing a Spatial Analyst operation show how to obtain a raster from disk to create a RasterDataset using the RasterWorkspace object.
Besides creating a RasterDataset from data on disk, the second method of acquiring input for Spatial Analyst operators is to get a raster object from a RasterLayer.
The following code example shows how to access a RasterLayer from a map in MapBean and obtain a raster from it that can be used in a Spatial Analyst operator:
[Java]
/**
 * This method will select the top raster layer in a map document.
 * @param map, MapBean which is displaying the MapDocument
 * @return IRaster, which is the top raster.
 */
public IRaster getRasterFromMap(MapBean map){
    IRaster raster = null;
    IRasterLayer layer = null;
    try{
        for (int i = 0; i < map.getLayerCount(); i++){
            if (map.getLayer(i)instanceof IRasterLayer)
                layer = (IRasterLayer)map.getLayer(i);
            break;
        }
        raster = layer.getRaster();
    }
    catch (Exception e){
        e.printStackTrace();
    }
    return raster;
}
Another input to most operators is feature class data. In some operators, the feature class data is used directly—as in RasterInterpolationOp—and in most others, the feature class data is converted automatically to a raster using the analysis environment settings.
The following code example accesses a shapefile data set using the Geodatabase object model in ArcGIS:
[Java]
/**
 * @param path, path to the directory containing the shapefile
 * @param fileName, name fo the shapefile
 * @return, featureClass of the Shape File
 */
public IFeatureClass openFeatureClassFromShapeFile(String path, String fileName){
    IFeatureClass featureClass = null;
    try{
        ShapefileWorkspaceFactory factory = new ShapefileWorkspaceFactory();
        if (!factory.isWorkspace(path)){
            JOptionPane.showMessageDialog(null, "NOt a VALID WORKSPACE!");
            return null;
        }
        IFeatureWorkspace workSpace = (IFeatureWorkspace)factory.openFromFile(path,
            0);
        featureClass = workSpace.openFeatureClass(fileName);
    }
    catch (Exception e){
        e.printStackTrace();
    }
    return featureClass;
}
Another common non-raster input comes from ArcInfo coverages. See the following code example:
[Java]
/**
 * @param path, path to the directory containing the coverage
 * @param fileName, name fo the coverage
 * @param id, ClasssID of the feature class of interest in the coverage
 * @return, featureClass of the Shape File
 */
public IFeatureClass openFeatureClassFromCoverage(String path, String fileName, int
    id){
    IFeatureClass featureClass = null;
    try{
        ArcInfoWorkspaceFactory factory = new ArcInfoWorkspaceFactory();
        if (!factory.isWorkspace(path)){
            JOptionPane.showMessageDialog(null, "NOt a VALID WORKSPACE!");
            return null;
        }
        IFeatureWorkspace workSpace = (IFeatureWorkspace)factory.openFromFile(path,
            0);
        IFeatureDataset dataset = workSpace.openFeatureDataset(fileName);
        //Get the feature class.
        IFeatureClassContainer container = (IFeatureClassContainer)dataset;
        featureClass = container.esri_getClass(id);
    }
    catch (Exception e){
        e.printStackTrace();
    }
    return featureClass;
}