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:
- 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.
- 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
*/
|
|