Home    |    Concepts   |   API   |   Samples
Concepts > Rasters
Data Loading

ArcSDE requires raster data to be loaded in uncompressed format. Thus, the API does not depend on any one image format. Any data that can be uncompressed can be loaded into an ArcSDE raster.

Before loading data, when a raster column is added to a business table, ArcSDE does the following:

  1. The raster column is registered by adding a record to the SDE.RASTER_COLUMNS table. The SDE.RASTER_COLUMNS table references the raster column and also stores its properties.
  2. Four supporting raster tables are created. These are collectively referred to as the raster data store and include the Raster table, the RasterBand table, the RasterAuxiliary table, and the RasterBlock table.

Data are loaded into an ArcSDE raster by either inserting a new row or updating an existing row.

For the case of the INSERT, a single insert occurs for a raster dataset, while multiple inserts are possible for raster catalogs. Note that the raster dataset is an ArcGIS object. The functionality of the ArcSDE API will not prevent you from inserting multiple rows into the raster dataset; however, ArcGIS will only recognize the first row.

There are three types of raster updates: full replacement, mosaic merge, and mosaic delete. The full replacement update is the least complicated and probably the least used since most applications do not usually completely replace an existing raster, but tend to delete and insert a new one. The mosaic merge operation is probably the most common type of raster update. Mosaic merge operations source pixel data is merged in a piece-wise fashion to an existing raster to replace the existing pixel values. In this case, only the source pixel data that overlaps the existing raster is replaced; the remainder of the raster is left unchanged. The mosaic delete is very similar to the mosaic merge with the difference that the nodata bitmaks of the source pixel data and not the pixel value is merged with the existing raster. If the source nodata value is 0, the target nodata value is set to 0, thus turning it off. On the other hand, if the source no data value is 1, the target value is not changed. In this way, the incoming nodata values will erase or set to nodata those portions of the raster for which the source nodata bitmask overlaps and for which the source nodata values are set to 0.

The following provides examples of the insert loading operation and the three types of update loading operations.
 

/**
* Create a Raster column and add the raster column to the business table.
*/
LONG rc, ras_col_id; //rc = return_code
SE_RASCOLINFO rascol_info;
CHAR raster_column[] = "raster";
SE_CONNECTION connection;
CLIENT_DATA *client_data;
int raster_width = 256, raster_height = 256, rc, maxlevel = 0;
LONG pixel_type, number_of_bands, interpolation,compression;
BOOL mosaic, scanline, empty;

rc = SE_rascolinfo_create (&rascol_info);
rc = SE_rascolinfo_set_minimum_id (rascol_info, 10);
rc = SE_rascolinfo_set_creation_keyword (rascol_info, "DEFAULTS");
rc = SE_rascolinfo_set_raster_column (rascol_info, table, "RASTER");
rc = SE_rascolinfo_set_coordref (rascol_info, coordref);
rc = SE_rascolinfo_set_description (rascol_info, "NONE");

//Create Raster Column
rc = SE_rastercolumn_create (connection, rascol_info);

//Add Raster Column to table
rc = SE_rascolinfo_set_raster_column (rascol_info, table, raster_column); 

/**
* Prepare raster attribute
*/
rc = SE_rasterattr_create(raster_attrib,TRUE);

//Add the callback function to the SE_RASTERATTR structure.
//The callback function determines how SE_stream_execute will
//enter the image pixel data into the raster column.
rc = SE_rasterattr_set_callback (*raster_attrib, (SE_RASTER_PROC) some_callback_function(), (void *)client_data);

//Use colormap if only 1 band is used
rc = SE_rasterattr_set_colormap (*raster_attrib, colormap_type, colormap_data_type, num_colormap_entries, (void *) colormap_data);

//Set the compression.
rc = SE_rasterattr_set_compression_type (*raster_attrib, compression);

//Set the image size to a single band
rc = SE_rasterattr_set_image_size (*raster_attrib,raster_width,raster_height,number_of_bands);

//Set the bit mask mode.
rc = SE_rasterattr_set_mask_mode (*raster_attrib, bitmask);

//Set the mosiac mode.
rc = SE_rasterattr_set_mosaic_mode (*raster_attrib, mosaic);

//Set the pyramid info
rc = SE_rasterattr_set_pyramid_info (*raster_attrib, max_level, FALSE, interpolation);

//Set the pixel type.
rc = SE_rasterattr_set_pixel_type (*raster_attrib,pixel_type);

//Set the tile size to 64 by 64. Since the image size is 256 by 256 pixels the . 16 tiles will cover the image
rc = SE_rasterattr_set_tile_size (*raster_attrib, 64, 64);

//Set the Extent
rc = SE_rasterattr_set_extent (*raster_attrib, &raster_env);

/**
* Create a Raster column and add the raster column to the business table.
*/
SeConnection conn = ...
SeRasterColumn rasCol = null;
SeCoordinateReference coordRef = ...;

rasCol = new SeRasterColumn(conn);

//Add raster column to table
rasCol.setTableName("RASTERTABLE");
rasCol.setDescription("DESCRIPTION");
SeObjectId minId = new SeObjectId(minValue.longValue());
rasCol.setMinID(minId);
rasCol.setCoordRef(coordRef);
rasCol.setConfigurationKeyword("DEFAULTS");

rasCol.create();

// Now, refresh rastercolumn object.
rasCol = new SeRasterColumn(conn, tableName, "RASTER");

/**
* Prepare raster attribute
*/
try
{
     int mBufImageType = image.getType();
     int mBufImageWidth = image.getWidth();
     int mBufImageHeight = image.getHeight();

     boolean inputMode = true;

     SeRasterAttr attr = new SeRasterAttr(inputMode);

     int numBands = 3;
     int bandWidth = mBufImageWidth;
     int bandHeight = mBufImageHeight;
     int tileWidth = bandWidth >> 3;
     int tileHeight = bandHeight >> 3;
     int compressType = SeRaster.SE_COMPRESSION_NONE;
     int pixelType = SeRaster.SE_PIXEL_TYPE_16BIT_U;
     int maxLevel = 0;
     boolean skipLevelOne = false;
     int interpolation = SeRaster.SE_INTERPOLATION_NONE;

     if (mBufImageType == BufferedImage.TYPE_INT_RGB)
     {
          numBands = 3;
     }
    

     // Overwrite raster attr parameters

     tileWidth = (int) Math.ceil( (double) bandWidth / 8.0);
     tileHeight = (int) Math.ceil( (double) bandHeight / 8.0);
     if (tileWidth > 128)
     {
          tileWidth = 128;
     }
     if (tileHeight > 128)
     {
          tileHeight = 128;
     }

     compressType = SeRaster.SE_COMPRESSION_LZ77;

     if (maxLevel >= 1)
     {
          interpolation = SeRaster.SE_INTERPOLATION_BICUBIC;
     }
     else
     {
          interpolation = SeRaster.SE_INTERPOLATION_NONE;
     }

     attr.setImageSize(bandWidth, bandHeight, numBands);
     attr.setTileSize(tileWidth, tileHeight);
     attr.setPixelType(pixelType);
     attr.setCompressionType(compressTyp);
     attr.setPyramidInfo(maxLevel, skipLevelOne, interpolation);
     boolean maskMode = true;
     attr.setMaskMode(maskMode);

     SeExtent extent = new SeExtent(0, 0, bandWidth, bandHeight);
     attr.setExtent(extent);

     int maskType = BufferedImageData.MASK_ALL_ON;
     if (maskMode)
     {
          maskType = BufferedImageData.MASK_TILE_BOUNDARY;
     }

     /* int numBanks = 3;
     int numEntries = 256;
     int colormapType = 1;
     int dataType = 0;

     DataBufferByte dataBuffer = new DataBufferByte(numEntries, numBanks);
     for (int elem = 0; elem < numEntries; elem++)
     {
          for (int bank = 0; bank < numBanks; bank++)
          {
               dataBuffer.setElem(bank, elem, (int) elem);
          }
     }

     attr.setColorMap(colormapType, dataBuffer);*/

     // Set callback func
     Object userContext = null;
     RasterCallBackImpl myRasCallBack = null;
     myRasCallBack = new RasterCallBackImpl(attr, maskType, image);
     attr.setRasterCallBack(myRasCallBack, userContext);
}
catch(SeException se)
{
    //exception handling
}

/**
* Prepare raster attribute
*/

feedback | privacy | legal