Back in August I blogged about how to subset ENVIRaster
objects before passing them into ENVITask using the desktop ENVI API.
Today I'm going to talk about how to do this for an ENVITask published on ESE.
While there is some pretty useful help documentation,
I wanted to present a couple more examples that showed how the recursive
capabilities of the ENVIRaster definition can be leveraged.
As the help docs detail, there are three flavors of JSON
objects that can describe an ENVIRaster object. In all cases the
"factory" attribute is the primary means of identifying which JSON
object is being used and what its other attributes can/must be. Careful
inspection of the JSON syntax in the help will show correlation to functions in
our desktop API: URLRaster matches ENVI::OpenRaster(),
SubsetRaster matches ENVISubsetRaster()
and ResampleRaster matches ENVIResampleRaster().
JSON Factory
|
JSON Attribute
|
API Function
|
keyword/argument
|
URLRaster
|
url
|
ENVI::OpenRaster
|
URI argument
|
URLRaster
|
format
|
ENVI::OpenRaster
|
EXTERNAL_TYPE or
CUSTOM_TYPE or none
|
URLRaster
|
dataset_index
|
ENVI::OpenRaster
|
DATASET_INDEX
|
URLRaster
|
dataset_name
|
ENVI::OpenRaster
|
DATASET_NAME
|
SubsetRaster
|
input_raster
|
ENVISubsetRaster
|
Raster argument
|
SubsetRaster
|
sub_rect
|
ENVISubsetRaster
|
SUB_RECT
|
SubsetRaster
|
spatialref
|
ENVISubsetRaster
|
SPATIALREF
|
SubsetRaster
|
bands
|
ENVISubsetRaster
|
BANDS
|
ResampleRaster
|
input_raster
|
ENVIResampleRaster
|
SourceRaster argument
|
ResampleRaster
|
dimensions
|
ENVIResampleRaster
|
DIMENSIONS
|
ResampleRaster
|
pixel_scale
|
ENVIResampleRaster
|
PIXEL_SCALE
|
ResampleRaster
|
column_mapping
|
ENVIResampleRaster
|
COLUMN_MAPPING
|
ResampleRaster
|
row_mapping
|
ENVIResampleRaster
|
ROW_MAPPING
|
As this table shows, the keywords in the desktop API
functions match the JSON attribute names exactly (with one notable exception of
"format" which was made more user friendly for ESE to handle the
native formats, ENVI Classic formats, and custom formats internally).
There is also a direct correlation between the value of
the "factory" attribute and the API function - the attribute value
strips off the "ENVI" prefix from the API function name. Again there
is the exception of URLRaster, but this is a special value to signify the end
of recursion and to represent the use of the class method on the ENVI object.
The positional arguments used by the API functions are
also standardized to a degree, for URLRaster we use the attribute name
"url" to correlate to the URI positional argument in
ENVI::OpenRaster. This discrepancy can be ascribed to the backwards
compatibility with ESE 5.1 and the original use of ESRI's GPRasterData datatype
in that version. For the other two factory modes, we use the standardized
attribute name "input_raster" since that is common to all of the
virtual rasters as a positional argument.
Armed with this insight, we can thusly convert the
following desktop API code into a JSON equivalent for use in an ESE task:
nv =
ENVI(/Headless)
oRaster = nv.OpenRaster('qb_boulder_msi')
oSubRaster = ENVISubsetRaster(oRaster,
SUB_RECT=[256, 256, 767, 767])
oResRaster = ENVIResampleRaster(oSubRaster,
DIMENSIONS=[1024, 1024])
{
"factory" : "ResampleRaster",
"dimensions" : [ 1024, 1024 ],
"input_raster" : {
"factory" : "SubsetRaster",
"sub_rect" : [ 256, 256, 767, 767 ],
"input_raster" : {
"factory" : URLRaster",
"url" : "qb_boulder_msi"
}
}
}
I replaced
the standard IDL Workbench chromacoding with individual colors for each API
function name, argument, and keyword, and then used the same color for the
corresponding JSON attribute to illustrate how easy this can be. One important
thing to notice here is that due to the recursion of the JSON, and the
depth-first way it will be traversed, the order of attributes in the JSON is
the opposite of the order of the function calls made using the API.
So the
next question you will likely be asking is "can I do this with any of the
virtual raster functions?" and the answer is most likely. While we
haven't formally tested all the permutations of virtual raster functions, we
have learned enough here to figure out how to build JSON representations for
most of the virtual raster functions by mapping their keywords to attribute
names and the positional argument source raster to the "input_raster"
attribute for recursion. An intrepid ESE user can experiment with this concept
, which should work though I will make no guarantees here. For example,
here is an example I tested to create an NDVI raster out of a spatial subset:
nv =
ENVI(/Headless)
oRaster = nv.OpenRaster('qb_boulder_msi')
oSubRaster = ENVISubsetRaster(oRaster,
SUB_RECT=[256, 256, 767, 767])
oNDVIRaster = ENVISpectralIndexRaster(oSubRaster,
INDEX='NDVI')
{
"factory" : "SpectralIndexRaster",
"index" : "NDVI",
"input_raster" : {
"factory" : "SubsetRaster",
"sub_rect" : [ 256, 256, 767, 767 ],
"input_raster" : {
"factory" : URLRaster",
"url" : "qb_boulder_msi"
}
}
}