This chapter describes the raster algebra language (PL/SQL and algebraic expressions) and related raster operations, including conditional queries, cell value-based updates or edits, mathematical operations, classify, on-the-fly statistical analysis, and their applications in cartographic modeling.
This chapter contains the following major sections:
Raster algebra is commonly used in raster data analysis and GIS modeling. In GeoRaster, raster algebra is supported by the GeoRaster raster algebra language.
The GeoRaster raster algebra language is an extension to the Oracle PL/SQL language. PL/SQL provides declarations of variables and constants, general mathematical expressions, basic functions, statements, and programming capabilities. GeoRaster provides a raster algebra expression language and a set of raster algebra functions for raster layer operations. The raster algebra expression language includes general arithmetic, casting, logical, and relational operators and allows any combination of them. The raster algebra functions enable the usage of the expressions and support cell value-based conditional queries, mathematical modeling, classify operations, and cell value-based updates or edits over one or many raster layers from one or many GeoRaster objects.
This combination of the PL/SQL language and GeoRaster algebraic expressions and functions provides an easy-to-use, powerful way to define raster analyses as algebraic expressions, so that users can easily apply algebraic functions on raster data to derive new results. For example, a simple raster operation can use two or more raster layers with the same dimension sizes to produce a new raster layer by using algebraic operations (addition, subtraction, and so on), or a sophisticated raster operation to generate a Normalized Difference Vegetation Index (NDVI) from multiple bands of satellite imagery.
GeoRaster supports raster algebra local operations, so the raster algebra operations work on individual raster cells, or pixels.
The following is the GeoRaster raster algebra expression language definition:
arithmeticExpr: unaryArithmeticExpr | binaryArithmeticExpr | functionArithmeticExpr | booleanExpr | castingExpr | constantNumber | identifier | (arithmeticExpr) booleanExpr: unaryBooleanExpr | binaryBooleanExpr | arithmeticExpr comparisonOp arithmeticExpr | (booleanExpr) unaryArithmeticExpr: (arithmeticUnaryOp arithmeticExpr) binaryArithmeticExpr: arithmeticExpr arithmeticBinaryOp arithmeticExpr functionArithmeticExpr: numericFunction (arithmeticExpr) castingExpr: rangeType(arithmeticExpr) unaryBooleanExpr: booleanUnaryOp booleanExpr binaryBooleanExpr: booleanExpr booleanBinaryOp booleanExpr arithmeticBinaryOp: + | - | * | / comparisonOp: = | < | > | >= | <= | != arithmeticUnaryOp: + | - booleanBinaryOp: & | | booleanUnaryOp: ! rangeType: castint | castonebit | casttwobit | castfourbit | casteightbit numericFunction: abs | sqrt | exp | log | ln | sin | cos | tan | sinh | cosh | tanh | arcsin | arccos | arctan | ceil | floor constantNumber: double number identifier: {ID,band} | {band} ID: integer number band: integer number
The precedence of the algebraic operators (+, -, *, /, and so on) in the expression language complies with general conventions. However, in any case where the expression might be misinterpreted, you should use parentheses to clarify which interpretation is intended.
The booleanExpr
can be used as arithmeticExpr
, as defined in the GeoRaster raster algebra expression language. In this case, the TRUE
and FALSE
evaluation results of booleanExpr
are cast to numeric values 1 and 0, respectively.
The identifier
in the expression refers to a raster layer of a GeoRaster object. It is either a single band
number if there is only one GeoRaster object involved, or a pair of (ID
, band
) where ID
refers to one of GeoRaster objects in the expression and band refers to a specific layer of that GeoRaster object. The band
number in this language refers to the ordinate number of a layer along the band dimension in the cell space, so it always starts with zero.
The following procedures provide the main support for raster algebra operations:
SDO_GEOR_RA.rasterMathOp takes arithmeticExpr
and performs mathematical operations or modeling.
SDO_GEOR_RA.findCells searches/masks cells based on a booleanExpr
condition.
SDO_GEOR_RA.classify applies arithmeticExpr
to cells and then segments the raster.
SDO_GEOR_RA.rasterUpdate updates cell values of a raster based on different booleanExpr
conditions.
These raster algebra functions take many layers from one or many GeoRaster objects, apply booleanExpr
and/or arithmeticExpr
expressions over those layers, do the specific algebraic computation or modeling, and output a new GeoRaster object. The expressions can be defined in any way based on the syntax described earlier in this section.
All raster algebra functions require that the raster layers overlap each other and have the same dimension sizes and resolution if they are georeferenced, or have the same dimension sizes if they are not georeferenced. Before you apply raster algebra operations over two or more GeoRaster objects, you can use the SDO_GEOR_RA.isOverlap function to determine if the GeoRaster objects are of the same size and cover the same ground area.
Raster and image databases are generally very large. Querying and manipulating such databases are computationally intensive operations. To improve performance, all GeoRaster raster algebra functions are parallelized. You should always consider applying parallel processing when using multi-CPU or multicore servers.
This section contains examples showing how to define raster algebra expressions.
Example 4-1 finds all pixels that meet the condition defined by algebra expression '{1}>200'
, because there is only one GeoRaster object involved in the procedure, so {1}
refers to the cell value of second layer ({0}
would be for the first layer), and '{1}>200'
means any pixels whose second layer value is greater than 200. The example assumes that the source GeoRaster object has at least two layers.
Example 4-1 Finding Pixels Based on a Comparison (>)
DECLARE geor MDSYS.SDO_GEORASTER; geor1 MDSYS.SDO_GEORASTER; BEGIN select georaster into geor from georaster_table where georid = 1; select georaster into geor1 from georaster_table where georid = 5 for update; sdo_geor_ra.findcells(geor, '{1}>200','blocking=true, blocksize=(256,256,3)',geor1); update georaster_table set georaster = geor1 where georid = 5; commit; END; /
Example 4-2 generates a new GeoRaster object geor2
from two input GeoRaster objects geor
and geor1
based on the algebra expressions array SDO_STRING2_ARRAY('{0,0}-0.5*{1,0}','{0,1}-0.5*{1,1}','{0,2}-0.5*{1,2}')
. The example assumes that both of the source GeoRaster objects are images with three bands.
Example 4-2 Generating a GeoRaster Object Based on an Expressions Array
DECLARE
geor MDSYS.SDO_GEORASTER;
geor1 MDSYS.SDO_GEORASTER;
geor2 MDSYS.SDO_GEORASTER;
geo_array MDSYS.SDO_GEORASTER_ARRAY;
BEGIN
select georaster into geor from georaster_table where georid = 1;
select georaster into geor1 from georaster_table where georid = 2;
insert into georaster_table values (17, sdo_geor.init('rdt_1', 17)) returning georaster into geor2;
geo_array:=MDSYS.SDO_GEORASTER_ARRAY(geor,geor1);
sdo_geor_ra.rasterMathOp(geo_array,SDO_STRING2_ARRAY('{0,0}-0.5*{1,0}','{0,1}-0.5*{1,1}','{0,2}-0.5*{1,2}'),null,geor2);
update georaster_table set georaster = geor2 where georid = 17;
commit;
END;
/
In the algebra expressions array in Example 4-2:
{0,0}
refers to the cell value of band 0 of the first input GeoRaster object geor
.
{0,1}
refers to the cell value of band 1 of the first input GeoRaster object geor
.
{0,2}
refers to the cell value of band 2 of the first input GeoRaster object geor
.
{1,0}
refers to the cell value of band 0 of the second input GeoRaster object geor1
.
{1,1}
refers to the cell value of band 1 of the second input GeoRaster object geor1
.
{1,2}
refers to the cell value of band 2 of the second input GeoRaster object geor1
.
In Example 4-2, then, the target GeoRaster object geor2
will have three bands, and:
The cell value of band 0 of target GeoRaster object geor2
is: {0,0}-0.5*{1,0}
The cell value of band 1 of target GeoRaster object geor2
is: {0,1}-0.5*{1,1}
The cell value of band 2 of target GeoRaster object geor2
is: {0,2}-0.5*{1,2}
Example 4-3 updates cell values of the input GeoRaster object based on the algebra expression array SDO_STRING2_ARRAY('(abs({0}-{1})=48)&({2}-{1}=-101)','2*{0}-{1}/3=108')
. The example assumes that the source GeoRaster object has three layers.
Example 4-3 Updating a GeoRaster Object Based on an Expressions Array
DECLARE
geor MDSYS.SDO_GEORASTER;
geor1 MDSYS.SDO_GEORASTER;
begin
select georaster into geor from georaster_table where georid = 1;
sdo_geor_ra.rasterUpdate(geor,0,SDO_STRING2_ARRAY('(abs({0}-{1})=48)&({2}-{1}=-101)','2*{0}-{1}/3=108'),SDO_STRING2_ARRAYSET(SDO_STRING2_ARRAY('123','54','89'),SDO_STRING2_ARRAY('98','56','123')));
END;
/
In Example 4-3, for each pixel:
If (abs({0}-{1})=48)&({2}-{1}=-101)
is true, then the cell values of the three layers will be updated to ('123','54','89')
.
If 2*{0}-{1}/3=108
is true, then the cell values of the three layers will be updated to ('98','56','123')
.
In addition to their use in space-based queries on rasters (such as with SDO_GEOR.getRasterSubset), cell value-based queries are particularly useful in analytics and application modeling. To perform cell value based conditional queries and generate a new GeoRaster object based on the specified condition, you can use the SDO_GEOR_RA.findCells procedure and specify an appropriate condition
parameter.
The condition
parameter must specify a valid booleanExpr
value (explained in Section 4.1). The procedure computes the booleanExpr
against each cell in the source GeoRaster object. If the result is TRUE
, the original cell values are kept in the output GeoRaster object; if the result is FALSE
, the bgValues
are used to fill cell values in the output GeoRaster object. This can also be considered as a masking operation.
Example 4-4 calls the SDO_GEOR_RA.findCells procedure to find all pixels where the value of the second band is greater than 200. Because the bgValues parameter is not specified, the value 0 is used as the background value to fill all pixels that make the condition false. The example assumes that the source GeoRaster object is an image with more than two bands.
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; BEGIN SELECT georaster INTO geor FROM georaster_table WHERE georid = 1; INSERT into georaster_table values (5, sdo_geor.init('rdt_1', 5)) returning georaster into geor1; sdo_geor_ra.findcells(geor, '{ 1 }>200', 'blocking=true, blocksize=(256,256,3)', geor1); UPDATE georaster_table set georaster = geor1 WHERE georid = 5; COMMIT; END; / -- This pixel is set to (0,0,0) because the cell value of the -- second band is 136, which is not greater than 200. SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1 OR georid=5 ORDER BY georid; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) SDO_NUMBER_ARRAY(0, 0, 0) 2 rows selected. -- This pixel keeps the original values because the cell value -- of the second band is greater than 200. SELECT sdo_geor.getcellvalue(georaster,0,132,116,'') FROM georaster_table WHERE georid =1 OR georid=5 ORDER BY georid; SDO_GEOR.GETCELLVALUE(GEORASTER,0,132,116,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(242, 225, 233) SDO_NUMBER_ARRAY(242, 225, 233) 2 rows selected. -- This pixel keeps the original values because the cell value -- of the second band is greater than 200. SELECT sdo_geor.getcellvalue(georaster,0,261,185,'') FROM georaster_table WHERE georid =1 OR georid=5 ORDER BY georid; SDO_GEOR.GETCELLVALUE(GEORASTER,0,261,185,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(255, 214, 2) SDO_NUMBER_ARRAY(255, 214, 2)
Example 4-5 is basically the same as Example 4-4, except that the nodata
parameter value is set to 'TRUE'
, so that all NODATA pixels keep their original values from the input GeoRaster object in the output GeoRaster object.
Example 4-5 Conditional Query with nodata Parameter
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; BEGIN SELECT georaster INTO geor FROM georaster_table WHERE georid = 1; INSERT into georaster_table values (5, sdo_geor.init('rdt_1', 5)) returning georaster into geor1; sdo_geor_ra.findcells(geor, '{ 1 }>200', null, geor1, null, 'TRUE'); UPDATE georaster_table set georaster = geor1 WHERE georid = 5; COMMIT; END; / SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) 1 row selected. -- This pixel keeps its original cell values because it is nodata, even though -- the cell value of the second band is not greater than 200. SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid=5; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) 1 row selected.
Example 4-6 finds all pixels that meet all of the following conditions:
The cell value of the first band is between (100,200).
The cell value of the second band is between [50,250].
The cell value of the third band is greater than 100.
In addition, because parallelParam
is specified as 'parallel=4'
, the procedure in Example 4-6 will run in parallel with four processes.
Example 4-6 Conditional Query with parallelParam
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; BEGIN SELECT georaster INTO geor FROM georaster_table WHERE georid = 2; INSERT into georaster_table values (10, sdo_geor.init('rdt_1', 10)) returning georaster into geor1; sdo_geor_ra.findcells(geor,'({1}>=50)&({1}<=250)&({0}>100)&({0}<200)&{2}>100) ',null,geor1,null,'false','parallel=4'); UPDATE georaster_table SET georaster = geor1 WHERE georid = 10; COMMIT; END; /
This section pertains to cell value-based raster updates and not space-based raster updates, both of which types of update are described in Section 3.13, "Querying and Updating GeoRaster Cell Data".
To update raster cell values based on conditions, you can use the SDO_GEOR_RA.rasterUpdate procedure and specify appropriate condition
and vals
parameters.
The condition
parameter specifies an array of Boolean expressions, and the vals
parameter specifies an array of arrays of math expressions. (See the raster algebra operation explanations in Section 4.1). For each cell, if condition
is TRUE
, its cell value is updated to the result of the corresponding math expression in the vals
array.
Example 4-7 assumes that the GeoRaster object to be updated is an image with three bands, and it calls the SDO_GEOR_RA.rasterUpdate procedure to do the following:
For any pixels if abs(first_band_value - second_band_value)=48 and (third_band_value - second_band_value=-101), then the three band values will be updated to (123,54,89), respectively.
For any pixels if (2*first_band_value - second_band_value/3)=108, then the three band values will be updated to (98,56,123), respectively.
Example 4-7 also includes several calls to the SDO_GEOR.getCellValue function to show "before" and "after" values.
Example 4-7 Cell Value-Based Update
SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) 1 row selected. SELECT sdo_geor.getcellvalue(georaster,0,130,130,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,130,130,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(64, 60, 48) 1 row selected. SELECT sdo_geor.getcellvalue(georaster,0,230,230,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,230,230,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(11,11, 11) 1 row selected. DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; BEGIN SELECT georaster into geor FROM georaster_table WHERE georid = 1; sdo_geor_ra.rasterUpdate(geor,0,SDO_STRING2_ARRAY('(abs({0}-{1})=48)&({2}-{1}=-101)','2*{0}-{1}/3=108'),SDO_STRING2_ARRAYSET(SDO_STRING2_ARRAY('123','54','89'),SDO_STRING2_ARRAY('98','56','123'))); END; / PL/SQL procedure successfully completed. show errors; No errors. -- This pixel gets updated because it meets the first condition. SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(123, 54, 89) 1 row selected. --This pixel gets updated because it meets the second condition. SELECT sdo_geor.getcellvalue(georaster,0,130,130,'') FROM georaster_table WHERE georid=1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,130,130,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(98, 56, 123) 1 row selected. -- This pixel keeps its original values because it does not meet any condition -- in the "condition" array. SELECT sdo_geor.getcellvalue(georaster,0,230,230,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,230,230,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(11,11, 11) 1 row selected.
Example 4-8 is basically the same as Example 4-7, except that the nodata
parameter value is set to 'TRUE'
, so that all NODATA pixels keep their original values from the input GeoRaster object in the output GeoRaster object.
Example 4-8 Cell Value-Based Update with nodata Parameter
SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) 1 row selected. SELECT sdo_geor.getcellvalue(georaster,0,130,130,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,130,130,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(64, 60, 48) 1 row selected. SELECT sdo_geor.getcellvalue(georaster,0,230,230,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,230,230,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(11,11, 11) 1 row selected. DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; BEGIN SELECT georaster into geor FROM georaster_table WHERE georid = 1; sdo_geor.addNODATA(geor, 1,88); sdo_geor_ra.rasterUpdate(geor,0,SDO_STRING2_ARRAY('(abs({0}-{1})=48)&({2}-{1}=-101)','2*{0}-{1}/3=108'),SDO_STRING2_ARRAYSET(SDO_STRING2_ARRAY('123','54','89'),SDO_STRING2_ARRAY('98','56','123')),null,'true'); END; / PL/SQL procedure successfully completed. -- This pixel keeps its original values because it is a NODATA pixel. SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) 1 row selected. --This pixel gets updated because it meets the second condition. SELECT sdo_geor.getcellvalue(georaster,0,130,130,'') FROM georaster_table WHERE georid=1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,130,130,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(98, 56, 123) 1 row selected.
A major use of raster algebra is to apply mathematical models to raster layers from different sources. To apply mathematical operations on one or multiple layers, which could be from one or more GeoRaster objects, to generate a new GeoRaster object, you can use the SDO_GEOR_RA.rasterMathOp procedure.
For most formats of this procedure, the operation
parameter specifies an array of arithmeticExpr
strings used to calculate raster cell values in the output GeoRaster object. Each element of the array corresponds to a layer in the output GeoRaster object.
Example 4-9 calls the SDO_GEOR_RA.rasterMathOp procedure to generate a new 6-layer GeoRaster object from a 3-layer source GeoRaster object, and follows these rules to calculate cell values of the target GeoRaster object:
The cell value of the first three layers of target GeoRaster object is equal to the value of the corresponding layer of source GeoRaster object, minus 10.
The cell value of the last three layers of target GeoRaster object is equal to the value of the first three layers of the source GeoRaster object, respectively.
Example 4-9 Mathematical Operations (1)
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; geor2 SDO_GEORASTER; BEGIN SELECT georaster INTO geor FROM georaster_table WHERE georid = 1; INSERT into georaster_table values (16, sdo_geor.init('rdt_1', 16)) returning georaster into geor1; sdo_geor_ra.rasterMathOp(geor,SDO_STRING2_ARRAY('{0,0}-10','{0,1}-10','{0,2}-10','{0,0}','{0,1}','{0,2}'),null,geor1); UPDATE georaster_table SET georaster = geor1 WHERE georid = 16; COMMIT; END; / PL/SQL procedure successfully completed. SELECT sdo_geor.getcellvalue(georaster,0,100,100,'') FROM georaster_table WHERE georid=1; SDO_GEOR.GETCELLVALUE(GEORASTER,0,100,100,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(181, 163, 159) 1 row selected. -- In the results of the next SELECT statement, note: -- 171=181-10 -- 153=163-10 -- 149=159-10 -- 181=181 -- 163=163 -- 159=159 SELECT sdo_geor.getcellvalue(georaster,0,100,100,'') FROM georaster_table WHERE georid =16; SDO_GEOR.GETCELLVALUE(GEORASTER,0,100,100,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(171, 153, 149, 181, 163, 159) 1 row selected.
Example 4-10 applies an operation on a 2-element GeoRaster array (containing two 3-layer source GeoRaster objects) to generate a new 3-layer GeoRaster object.
Example 4-10 Mathematical Operations (2)
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; geor2 SDO_GEORASTER; geo_array SDO_GEORASTER_ARRAY; BEGIN SELECT georaster INTO geor FROM georaster_table WHERE georid = 1; SELECT georaster INTO geor2 FROM georaster_table WHERE georid = 2; INSERT into georaster_table values (17, sdo_geor.init('rdt_1', 17)) returning georaster into geor1; geo_array:=SDO_GEORASTER_ARRAY(geor,geor2); sdo_geor_ra.rasterMathOp(geo_array,SDO_STRING2_ARRAY('{0,0}-0.5*{1,0}','{0,1}-0.5*{1,1}','{0,2}-0.5*{1,2}'),null,geor1,'false',null,'parallel=4'); UPDATE georaster_table SET georaster = geor1 WHERE georid = 17; COMMIT; END; / PL/SQL procedure successfully completed. SELECT sdo_geor.getcellvalue(georaster,0,100,100,'') FROM georaster_table WHERE georid=1 or georid=2; SDO_GEOR.GETCELLVALUE(GEORASTER,0,100,100,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(181, 163, 159) SDO_NUMBER_ARRAY(60, 80, 90) 2 rows selected. -- In the results of the next SELECT statement, note: -- 151=181-0.5*60 -- 123=163-0.5*80 -- 114=159-0.5*90 SELECT sdo_geor.getcellvalue(georaster,0,100,100,'') FROM georaster_table WHERE georid =17; SDO_GEOR.GETCELLVALUE(GEORASTER,0,100,100,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(151, 123 114) 1 row selected.
Example 4-11 applies a subtraction operation on two 3-layer input GeoRaster objects to generate a new GeoRaster object. The example also includes several calls to the SDO_GEOR.getCellValue function to show "before" and "after" values.
Example 4-11 Mathematical Operations (3)
SELECT sdo_geor.getcellvalue(georaster,0,10,10,'0-2') FROM georaster_table WHERE georid=1 OR georid=5 ORDER BY georid;
SDO_GEOR.GETCELLVALUE(GEORASTER,0,10,10,'0-2')
--------------------------------------------------------------------------------
SDO_NUMBER_ARRAY(88, 137, 32)
SDO_NUMBER_ARRAY(98, 147, 42)
2 rows selected.
SELECT sdo_geor.getcellvalue(georaster,0,100,100,'0-2') FROM georaster_table WHERE georid=1 OR georid=5 ORDER BY georid;
SDO_GEOR.GETCELLVALUE(GEORASTER,0,100,100,'0-2')
--------------------------------------------------------------------------------
SDO_NUMBER_ARRAY(181, 163, 159)
SDO_NUMBER_ARRAY(191, 173, 169)
2 rows selected.
DECLARE
geor0 SDO_GEORASTER;
geor SDO_GEORASTER;
geor1 SDO_GEORASTER;
BEGIN
SELECT georaster INTO geor FROM georaster_table WHERE georid = 1;
SELECT georaster INTO geor0 FROM georaster_table WHERE georid = 5;
INSERT into georaster_table values (6, sdo_geor.init('rdt_1', 6)) returning georaster into geor1;
sdo_geor_ra.rasterMathOp(geor0,geor,null,sdo_geor_ra.OPERATOR_SUBTRACT,null,geor1);
UPDATE georaster_table SET georaster = geor1 WHERE georid = 6;
COMMIT;
END;
/
PL/SQL procedure successfully completed.
SELECT sdo_geor.getcellvalue(georaster,0,10,10,'0-2') FROM georaster_table WHERE georid=6;
SDO_GEOR.GETCELLVALUE(GEORASTER,0,10,10,'0-2')
--------------------------------------------------------------------------------
SDO_NUMBER_ARRAY(10, 10, 10)
1 row selected.
SELECT sdo_geor.getcellvalue(georaster,0,100,100,'0-2') FROM georaster_table WHERE georid=6;
SDO_GEOR.GETCELLVALUE(GEORASTER,0,100,100,'0-2')
--------------------------------------------------------------------------------
SDO_NUMBER_ARRAY(10, 10, 10)
1 row selected.
Note that booleanExpr
can be also used as arithmeticExpr
, as is done in Example 4-8, "Cell Value-Based Update with nodata Parameter".
To apply simple classification operations on source GeoRaster objects and generate new GeoRaster objects based on your specifications, you can use the SDO_GEOR_RA.classify procedure and specify the expression
, rangeArray
, and valueArray
parameters. This classification procedure is also called segmentation.
The expression
parameter is used to compute values that are used to map into the value ranges defined in the rangeArray
parameter. The rangeArray
parameter specifies a number array that defines ranges for classifying cell values, and this array must have at least one element. The valueArray
parameter is a number array that defines the target cell value for each range, and its length must be the length of rangeArray
plus one.
Example 4-12 calls the SDO_GEOR_RA.classify procedure to apply a segmentation operation on the value of the first band of the input GeoRaster object. The example assumes that the GeoRaster object is an image.
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; rangeArray SDO_NUMBER_ARRAY; valueArray SDO_NUMBER_ARRAY; BEGIN rangeArray:=sdo_number_array(70,80,90,100,110,120,130,140,150,160,170,180); valueArray:=sdo_number_array(70,80,90,100,110,120,130,140,150,160,170,180,190); SELECT georaster INTO geor FROM georaster_table WHERE georid = 1; INSERT into georaster_table values (5, sdo_geor.init('rdt_1', 5)) returning georaster into geor1; sdo_geor_ra.classify(geor,'{0}',rangeArray,valueArray,null,geor1); UPDATE georaster_table SET georaster = geor1 WHERE georid = 5; COMMIT; END; / PL/SQL procedure successfully completed. -- In the next statement, the target value is 90 because the value of the -- first band of source GeoRaster object is 88, which is between 80 and 90. SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1 OR georid =5 ORDER BY georid; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) SDO_NUMBER_ARRAY(90) 2 rows selected. -- In the next statement, the target value is 190 because the value of the -- first band of source GeoRaster object is 242, which is greater than 180. SELECT sdo_geor.getcellvalue(georaster,0,132,116,'') FROM georaster_table WHERE georid =1 OR georid =5 ORDER BY georid; SDO_GEOR.GETCELLVALUE(GEORASTER,0,132,116,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(242, 225, 233) SDO_NUMBER_ARRAY(190) 2 rows selected.
Example 4-13 calls the SDO_GEOR_RA.classify procedure to apply a segmentation operation on the value of the first layer of the source GeoRaster object, and to set the nodata
parameter to 'TRUE'
and the nodataValue
parameter to 5, so that all NODATA pixels will be set with a NODATA value of 5 in the target GeoRaster object.
Example 4-13 Classification with nodata and nodataValue Parameters
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; rangeArray SDO_NUMEBR_ARRAY; valueArray SDO_NUMEBR_ARRAY; BEGIN rangeArray:=sdo_number_array(70,80,90,100,110,120,130,140,150,160,170,180); valueArray:=sdo_number_array(70,80,90,100,110,120,130,140,150,160,170,180,190); SELECT georaster INTO geor FROM georaster_table WHERE georid = 1; sdo_geor.addNODATA(geor, 2,136); INSERT into georaster_table values (5, sdo_geor.init('rdt_1', 5)) returning georaster into geor1; sdo_geor_ra.classify(geor,'{0}',rangeArray,valueArray,null,geor1,'true',5); UPDATE georaster_table SET georaster = geor1 WHERE georid = 5; END; / PL/SQL procedure successfully completed. -- In the next statement, the target value of the cell is 5 because the value -- of the second layer of the input GeoRaster object is 136, which is nodata. SELECT sdo_geor.getcellvalue(georaster,0,30,30,'') FROM georaster_table WHERE georid =1 OR georid =5 ORDER BY georid; SDO_GEOR.GETCELLVALUE(GEORASTER,0,30,30,'') -------------------------------------------------------------------------------- SDO_NUMBER_ARRAY(88, 136, 35) SDO_NUMBER_ARRAY(5) 2 rows selected.
Many applications require statistical analysis. GeoRaster provides statistical analysis functions that dynamically ("on the fly") compute complete statistical values for a GeoRaster object or the following individual statistical values: minimum, maximum, mean, median, mode, and standard deviation. You can do this without generating a histogram and updating the GeoRaster object metadata.
These subprograms support pyramids, band by band and the aggregation of specified band numbers. Each subprogram returns an SDO_NUMBER_ARRAY object or a number.
See the reference information for explanations and examples of these on-the-fly statistics computation subprograms:
These subprograms do not modify the metadata in the GeoRaster object, except for some formats of SDO_GEOR.generateStatistics that set statistical data in the GeoRaster object metadata and return a string value of TRUE
or FALSE
instead of an SDO_NUMBER_ARRAY object.
For an application using dynamically generated statistical data, see Example 5-11, "Image Stretching Using Dynamically Generated Min and Max Cell Values" in Section 5.6, "Image Stretching".
Raster algebra has many applications, such as cartographic modeling (see Section 4.9), linear image stretching (see Section 5.6), vegetation index computing (see Section 5.10), and tasseled cap transformation (see Section 5.11). Sections in this chapter and in Chapter 5, "Image Processing and Virtual Mosaic" describe a few sample applications of the GeoRaster raster algebra.
The cell value of a GeoRaster object may represent a quantitative attribute of spatial objects, which could be in a specific unit. For example, the elevation data in a DEM GeoRaster object could be in the unit of feet. An application may require you to convert the elevations into another unit, such as meters, for georectification and other operations. You can use the raster algebra to scale the DEM data from feet into meters (that is, unit conversion), as shown in Example 4-14.
Example 4-14 Converting DEM Data from Feet to Meters
DECLARE geor1 SDO_GEORASTER; geor2 SDO_GEORASTER; BEGIN --Source GeoRaster object with a single DEM layer select georaster into geor1 from georaster_table where georid = 1; --To store the output DEM layer select georaster into geor2 from georaster_table where georid = 2 for update; --Scale elevation from feet to meters using the unit factor sdo_geor_ra.rasterMathOp(geor1,SDO_STRING2_ARRAY('{0} * 0.3048'),null,geor2); --Commit changes to the output georaster object update georaster_table set georaster = geor2 where georid = 2; commit; END; /
The cell data of a GeoRaster object may need to be offset by a constant for further processing. For example, a DEM layer may represent orthometric elevation instead of ellipsoidal elevation. To orthorectify a raw image georeferenced by an RPC model requires ellipsoidal elevation. Example 4-15 offsets the orthometric DEM by the geoid height, resulting in an ellipsoidal DEM.
Example 4-15 Offsetting DEM by Geoid Height
DECLARE geor1 SDO_GEORASTER; geor2 SDO_GEORASTER; BEGIN --Source GeoRaster object with a single orthometric DEM layer select georaster into geor1 from georaster_table where georid = 1; --To store the output DEM layer select georaster into geor2 from georaster_table where georid = 2 for update; --Offset elevation by geoid height to get ellipsoidal elevation sdo_geor_ra.rasterMathOp(geor1,SDO_STRING2_ARRAY('{0} - 28.8'),null,geor2); --Commit changes to the output GeoRaster object update georaster_table set georaster = geor2 where georid = 2; commit; END; /
You can combine the operations of Example 4-15 and Example 4-15 into a single simple step, as shown in Example 4-16.
Example 4-16 Converting (Scaling) and Offsetting
DECLARE geor1 SDO_GEORASTER; geor2 SDO_GEORASTER; BEGIN --Source GeoRaster object with a single DEM layer select georaster into geor1 from georaster_table where georid = 1; --To store the output DEM layer select georaster into geor2 from georaster_table where georid = 2 for update; --Scale elevation from feet to meters and offset elevation by geoid height sdo_geor_ra.rasterMathOp(geor1,SDO_STRING2_ARRAY('{0} * 0.3048 - 28.8'),null,geor2); --Commit changes to the output georaster object update georaster_table set georaster = geor2 where georid = 2; commit; END; /
Raster data casting maps cell values from one data type to another. In GeoRaster, there are two types of casting operations: one uses the cellDepth
keyword in the storageParam
parameter of operations, and the other uses the castingExpr
operation in the GeoRaster raster algebra. (castingExpr
is one of the arithmeticExpr
operations, as described in Section 4.1, "Raster Algebra Language".)
Whenever you apply an operation which stores the raster data result into a new GeoRaster object, you can use the cellDepth
keyword in the storageParam
parameter of that operation. (The cellDepth
keyword and its values are described in Table 1-1, "storageParam Keywords for Raster Data".) If the cellDepth
is specified, the target GeoRaster object will be created using that cellDepth
value, and the raster cell data will be automatically cast to that cellDepth
value for storage. You can directly use cellDepth
in the storageParam
parameter to do the casting if the source data is in lower cell depth and the resulting data is in higher cell depth. In this case, the casting is transparent and fast.
However, if you specify a lower cell depth for data in higher cell depth, changing the cell depth using the cellDepth
keyword in the storageParam
parameter can cause loss or change of data and reduced precision or quality. To have better control of the precision and accuracy, you can use the Raster Algebra casting operator, castingExpr
.
For example, assume you have a raster with a cell depth of 32BIT_REAL
and a value range in [0.0, 100.0). You can use Example 4-17 to perform linear segmentation of the raster into 10 different classes, each of which has a cell value that is a multiple of 10 (0, 10, 20, …, 90), using the castint
operator. This operation casts all cell values to their closest lower multiple of 10; for example, all numbers from 60 to 69 are cast to 60.
Example 4-17 Linear Segmentation of a Raster
DECLARE geor1 SDO_GEORASTER; geor2 SDO_GEORASTER; BEGIN --Source georaster object with cell value range [0.0,100.0) select georaster into geor1 from georaster_table where georid = 1; --Target georaster object to store the output layer select georaster into geor2 from georaster_table where georid = 2 for update; --Linearly segment the source raster into 10 classes and store in 8BIT cell depth sdo_geor_ra.rasterMathOp(geor1, SDO_STRING2_ARRAY('(castint({0}/10)*10'), 'celldepth=8BIT', geor2); --Commit changes to the output georaster object update georaster_table set georaster = geor2 where georid = 2; commit; END; /
As shown in Example 4-17, you can combine the usage of the cellDepth
keyword in the storageParam
parameter with the raster algebra casting operator, so that the result can be calculated correctly as well as stored in an appropriate and concise way. In Example 4-17, the output cell values are integers equal to or less than 90, so the resulting raster can be stored using 8BIT
cell depth (instead of 32BIT_REAL
), which saves storage space.
Raster algebra is widely used in cartographic modeling and is considered an essential component of GIS systems. Using the PL/SQL and the raster algebra expressions and functions, you can conduct cartographic modeling over a large number of rasters and images of virtually unlimited size.
For example, a cartographic modeling process for wildfire evaluation might retrieve the elevation, slope, aspect, temperature, wetness, and other information from a series of raster layers and then evaluate the cells one-by-one to create a resulting raster map, which can be further classified to create a thematic map. Change analysis, site selection, suitability analysis, climate modeling, and oil field evaluation using the raster layer overlay technique are other typical cartographic modeling processes. In those cases, arithmetic, relational, and logical operations may need to be combined.
Assume that a hypothetical cartographic model involves seven different raster layers and has an expression as follows. and that the modeling result is a raster map with 0 and 1 as cell values:
output = 1 if ( (100 < layer1 <= 500) & (layer2 == 3 or layer2 == 10) & ( (layer3+layer4) * log(Layer5) / sqrt(layer5) ) >= layer6) || (layer7 != 1) ) is TRUE and 0 if otherwise
Example 4-18 shows how to run the preceding cartographic model in GeoRaster and store the result as a bitmap.
Example 4-18 Cartographic Modeling
DECLARE geor SDO_GEORASTER; geor1 SDO_GEORASTER; mycursor sys_refcursor; expr varchar2(1024); BEGIN --7 source GeoRaster objects, each of which contains one source layer in the order of 1 to 7 OPEN mycursor FOR select georaster from georaster_table where georid >0 and georid <=7 order by georid; --Output GeoRaster object to contain the result insert into georaster_table (georid, georaster) values (8, sdo_geor.init('RDT_1',8)) returning georaster into geor1; --Modeling using arithmeticExpr, booleanExpr, and rasterMathOp expr := '((100<{0,0})&({0,0}<=500))&(({1,0}=3)|({1,0}=10))&(((({2,0}+{3,0})*log({4,0})/sqrt({4,0}))>={5,0})|({6,0}!=1))'; sdo_geor_ra.rasterMathOp(mycursor, sdo_string2_array(expr), 'celldepth=1BIT', geor1, 'true', 0, 'parallel=4'); update georaster_table set georaster = geor1 where georid = 8; commit; END; /
The process in Example 4-18 considers NODATA and will assign 0 (zero) to any cell that is a NODATA cell in one or more source layers. It is also parallelized into four processes to leverage multiple CPUs of the database server to improve performance.