# PipelineMosaicToReference.sml # Sample standalone script to demonstrate an image pipeline application # using multiple RVC sources and a single RVC target: mosaicking the source rasters. # Script input: any number of georeferenced RVC raster objects as input for the mosaic # and a georeferenced reference raster to determine the extents, coordinate reference system, # and cell size of the output mosaic # Script output: a single RVC raster mosaic # 20 December 2007 # Randy Smith, MicroImages, Inc. # Revised 14 February 2008 # Requires Version 2008:74 dated 20 February 2008 or later of the TNT products. # The MOSAIC filter can operate on any number of input stages, each associated with a separate source. # The mechanism for passing these stages is an IMAGE_PIPELINE_STAGE_ARRAY structure, which in this # example is populated directly with source stages. This example also uses a reference raster (a separate # SOURCE_RVC). # Since the number of input rasters to the mosaic is not known until they are selected, the script needs # a way to iterate through the input images and set up a source class instance for each. Each of these # image sources must still exist when the STAGE_ARRAY is passed to the MOSAIC filter; iteratively # reusing a single source instance and passing it to the STAGE_ARRAY is not valid. # The solution is to construct the image source as an array of sources using the number of inputs selected # to define the size of the array. # The script uses the DlgGetObjects() function to pop up a dialog enabling selection of the input rasters; # this function populates a hash of RVC_OBJITEMs (identifiers for the input objects). The script loops # through the hash like an array to get each input RVC_OBJITEM as needed. Each of these objitems is used to # define a new image source that is added to the source array. The source is initialized and check for # a valid coordinate reference system before being appened to the STAGE_ARRAY. Sources without a valid # CRS are not added to the STAGE_ARRAY and thus do not become part of the mosaic. Because the STAGE_ARRAY # may end up with fewer stages than the number of input images, it is constructed without specifying # the number of stages, and an Append() method that automatically enlarges the array is used to add valid # sources to it. numeric err; # error code returned # error checking procedure proc ReportError(numeric linenum, numeric err) { printf("FAILED -line: %d, error: %d\n", linenum - 1, err); PopupError(err); } ##################################### Main program ####################################################### clear(); # set context so script does not exit on error, allowing manual # handling of errors _context.AbortOnError = 0; # CHOOSE REFERENCE RASTER to control the extents and cell size of the mosaic class RVC_OBJITEM refObjItem; # ObjItem for reference raster DlgGetObject("Choose georeferenced raster to use as reference:", "Raster", refObjItem, "ExistingOnly"); # PIPELINE SOURCE for reference image class IMAGE_PIPELINE_SOURCE_RVC refSource(refObjItem); err = refSource.Initialize(); if ( err < 0 ) ReportError(_context.CurrentLineNum, err); else print("Reference image source initialized."); # CHECK THAT REFERENCE IMAGE HAS VALID COORDINATE REFERENCE SYSTEM class IMAGE_PIPELINE_GEOREFERENCE refGeoref; refGeoref = refSource.GetGeoreference(); # get coordinate reference system from the reference image georeference class SR_COORDREFSYS refCRS; # reference raster's coordinate reference system refCRS = refGeoref.GetCRS(); if (refCRS.IsDefined() == 0 or refCRS.IsLocal() ) { PopupMessage("Reference image coordinate reference system is undefined or local; exiting script."); Exit(); } else printf("Reference image coordinate reference system: %s\n", refCRS.Name ); # CHOOSE GEOREFERENCED RASTERS TO MOSAIC class RVC_OBJITEM inObjItemList[]; # HASH of RVC_OBJITEMS for unknown number of input rasters to mosaic numeric numInputs; # DlgGetObjects populates an RVC_OBJITEM hash with the RVC_OBJITEM of each selected raster DlgGetObjects("Choose georeferenced rasters to mosaic:", "Raster", inObjItemList, "ExistingOnly", 2); # set up array of RVC_SOURCE class handles with number equal to number of input rasters numInputs = inObjItemList.GetNumItems(); class IMAGE_PIPELINE_SOURCE_RVC sources[numInputs]; printf("Number of rasters to mosaic = %d\n", numInputs); # set up STAGE_ARRAY to pass to the mosaic filter using number of inputs; construct # with unspecified number of stages to allow for skipping ungeoreferenced inputs class IMAGE_PIPELINE_STAGE_ARRAY stages( ); # declare class variables to use in processing the input rasters class RVC_OBJITEM objItem; # ObjItem for the current input raster (gets reused) class IMAGE_PIPELINE_GEOREFERENCE sourceGeoref; # georeference from current source image class SR_COORDREFSYS crs; # coordinate reference system from current source image # loop through the hash of input objItems numeric i; # counter for i = 1 to numInputs { objItem = inObjItemList[i]; # get ObjItem for current source image from the hash # of RVC_OBJITEMS # PIPELINE SOURCE for each input image sources[i] = new IMAGE_PIPELINE_SOURCE_RVC(objItem); # add a new source for the current image to the array err = sources[i].Initialize(); if ( err < 0 ) ReportError(_context.CurrentLineNum, err); else printf("\nInitialized source %d of %d\n", i, numInputs); # CHECK THAT SOURCE HAS VALID COORDINATE REFERENCE SYSTEM # if defined, add source to STAGE_ARRAY, otherwise skip sourceGeoref = sources[i].GetGeoreference(); crs = sourceGeoref.GetCRS(); if (crs.IsDefined() == 0 or crs.IsLocal() ) { printf("Coordinate reference system for source %d is undefined or local.\n", i); printf("Source %d will be omitted from mosaic.\n", i); } else { printf("Source %d: CRS = %s\n", i, crs.Name ); # append source to the STAGE_ARRAY stages.Append(sources[i]); } } # CHOOSE OUTPUT RASTER: Prompt for the output raster for the mosaic. # DlgGetObject creates only an ObjItem for the output; the new raster will then be created # by the TARGET_RVC with the desired compression. The ObjectPath of the ObjItem is not # valid until the output raster is actually created by the pipeline. class RVC_OBJITEM mosObjItem; # ObjItem for the output mosaic raster DlgGetObject("Select new raster object for the mosaic:", "Raster", mosObjItem, "NewOnly"); # PIPELINE FILTER to mosaic the input rasters class IMAGE_PIPELINE_FILTER_MOSAIC mosaic(stages, refSource, "Nearest", "Last"); err = mosaic.Initialize(); if ( err < 0 ) ReportError(_context.CurrentLineNum, err); else print("Mosaic filter initialized."); # PIPELINE TARGET # set up the target for the mosaic pipeline class IMAGE_PIPELINE_TARGET_RVC target_rvc(mosaic, mosObjItem); target_rvc.SetCompression("DPCM", 100); err = target_rvc.Initialize(); if ( err < 0) ReportError(_context.CurrentLineNum, err); else print("Mosaic target initialized."); # EXECUTE the pipeline process print("Processing..."); target_rvc.Process(); print("Done.");