# PipelineResampleToMatchMulti.sml # Sample standalone script to demonstrate a simple image pipeline application: # resampling/reprojecting a series of georeferenced source rasters to match the extents, # cell size, and projection of a georeferenced reference raster. # Script shows how to incorporate an image processing pipeline into a user-defined # function that is iteratively called to process a series of grayscale rasters # through the same processing steps, with each each iteration producing a single # output raster. # 21 February 2008 # Randy Smith, MicroImages, Inc. # Requires Version 2007:73 or later of the TNT products. numeric err; # error code returned numeric i; # loop counter ################################################################################## ####################### Procedures and Functions ############################### # error checking procedure proc ReportError(numeric linenum, numeric err) { printf("FAILED -line: %d, error: %d\n", linenum, err); PopupError(err); } # function to process input rasters through the resampling pipeline func rsmpPipe( class RVC_OBJITEM inObjItem, class RVC_OBJITEM outObjItem, class IMAGE_PIPELINE_BASE refImg, numeric refCellArea, numeric count, class STRINGLIST list) { local class STRING imgName$ = list.GetString(count-1); printf("Processing source image %s\n", imgName$ ); # PIPELINE SOURCE # set input raster as source local class IMAGE_PIPELINE_SOURCE_RVC source_In( inObjItem ); err = source_In.Initialize(); if (err < 0) return -1; else printf("Pipeline source for %s initialized\n", imgName$); # CHECK THAT SOURCE HAS VALID COORDINATE REFERENCE SYSTEM local class IMAGE_PIPELINE_GEOREFERENCE sourceGeoref; sourceGeoref = source_In.GetGeoreference(); # get coordinate reference system from the source georeference local class SR_COORDREFSYS crs; # input raster's coordinate reference system crs = sourceGeoref.GetCRS(); if (crs.IsDefined() == 0 or crs.IsLocal() ) { return 0; } else { printf("Coordinate reference system for source %s: %s\n", imgName$, crs.Name ); # get line and column cell sizes from source's georeference local class POINT2D scaleIn; # line and column cell sizes as x and y values of POINT2D local class POINT2D locIn; # column and line location for which to obtain cell size locIn.x = source_In.GetTotalColumns() / 2; # location at center of image locIn.y = source_In.GetTotalRows() / 2; sourceGeoref.ComputeScale(locIn, scaleIn, 1); # cell sizes in meters scaleIn.x = abs(scaleIn.x); scaleIn.y = abs(scaleIn.y); # cell scale can be negative, so get absolute value printf("Source %s image cell sizes: line = %.2f m, col = %.2f m\n", imgName$, scaleIn.y, scaleIn.x); # DETERMINE APPROPRIATE RESAMPLING METHOD # compare cell sizes (in meters) of input and reference image local numeric inCellArea; # compute area of input cell inCellArea = scaleIn.x * scaleIn.y; local string rsmpMethod$; if (refCellArea > 2 * inCellArea) then rsmpMethod$ = "Average"; else rsmpMethod$ = "CubicConvolution"; printf("Resampling method for source %s: %s\n", imgName$, rsmpMethod$); # PIPELINE FILTER to resample source image class IMAGE_PIPELINE_FILTER_RESAMPLE filter_rsmp(source_In, refImg, rsmpMethod$); err = filter_rsmp.Initialize(); if (err < 0) return -1; else printf("Resample filter for source %s initialized.\n", imgName$); # PIPELINE TARGET: set up the target for the pipeline class IMAGE_PIPELINE_TARGET_RVC target_rvc(filter_rsmp, outObjItem); target_rvc.SetCompression("DPCM", 0); err = target_rvc.Initialize(); if (err < 0) return -1; else printf("Pipeline target for image %s initialized.\n", imgName$); # EXECUTE pipeline process print("Processing..."); target_rvc.Process(); printf("Completed processing for image %s.\n\n", imgName$); return 1; } } #################################################################################### ##################################### Main program ############################### clear(); # set context so script does not exit on error, allowing manual # handling of errors. _context.AbortOnError = 0; # CHOOSE REFERENCE RASTER TO RESAMPLE TO class RVC_OBJITEM refObjItem; DlgGetObject("Select reference raster:", "Raster", refObjItem, "ExistingOnly"); # SET PIPELINE SOURCE FOR REFERENCE IMAGE class IMAGE_PIPELINE_SOURCE_RVC source_Ref( refObjItem ); err = source_Ref.Initialize(); if (err < 0) ReportError(_context.CurrentLineNum, err); else print("Reference source initialized."); printf("Reference image has %d lines and %d columns.\n", source_Ref.GetTotalRows(), source_Ref.GetTotalColumns() ); # CHECK THAT REFERENCE IMAGE HAS VALID COORDINATE REFERENCE SYSTEM class IMAGE_PIPELINE_GEOREFERENCE refGeoref; refGeoref = source_Ref.GetGeoreference(); # get coordinate reference system from the source georeference class SR_COORDREFSYS crsRef; # reference raster's coordinate reference system crsRef = refGeoref.GetCRS(); if (crsRef.IsDefined() == 0 or crsRef.IsLocal() ) { PopupMessage("Reference coordinate reference system is undefined or local; exiting script."); Exit(); } else printf("Reference coordinate reference system: %s\n", crsRef.Name ); # GET CELL SIZE (IN METERS) OF REFERENCE IMAGE (used to determine resampling method) class POINT2D scaleRef; # column and line cell size of reference image as x and y values class POINT2D locRef; # column and line location for which to obtain cell size locRef.x = source_Ref.GetTotalColumns() / 2; # location at center of reference image locRef.y = source_Ref.GetTotalRows() / 2; refGeoref.ComputeScale(locRef, scaleRef, 1); # cell sizes of reference image in meters scaleRef.x = abs(scaleRef.x); scaleRef.y = abs(scaleRef.y); printf("Reference image cell sizes: line = %.2f m, col = %.2f m\n", scaleRef.y, scaleRef.x); # compute cell area of reference image to pass to user-defined resampling function numeric refCellArea = scaleRef.x * scaleRef.y; # CHOOSE GEOREFERENCED INPUT RASTERS to be resampled. class RVC_OBJITEM inObjItemList[]; # HASH of RVC_OBJITEMS for unknown number of input rasters to resample numeric numInputs; # DlgGetObjects populates an RVC_OBJITEM hash with the RVC_OBJITEM of each selected raster DlgGetObjects("Choose georeferenced rasters to resample:", "Raster", inObjItemList, "ExistingOnly", 2); numInputs = inObjItemList.GetNumItems(); printf("Processing %d input rasters.\n\n", numInputs); # MAKE STRINGLIST OF LABELS FOR DIALOG PROMPTING FOR OUTPUT RASTERS class STRINGLIST labelList; for i = 1 to numInputs { labelList.AddToEnd( inObjItemList[i].GetDescriptor().GetShortName() ); } # CHOOSE OUTPUT RASTERS # DlgGetObjectSet populates a hash of ObjItems 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 process. class RVC_OBJITEM outObjItemList[]; DlgGetObjectSet("Choose rasters for resampled output", "Raster", labelList, outObjItemList, "NewOnly"); # LOOP THROUGH LISTS OF INPUT AND OUTPUT RVC_OBJITEMS TO RESAMPLE IMAGES for i = 1 to numInputs { # CALL USER-DEFINED FUNCTION TO RESAMPLE AN IMAGE err = rsmpPipe(inObjItemList[i], outObjItemList[i], source_Ref, refCellArea, i, labelList); if (err == 0) # invalid coordinate reference system for input printf("Source image %d has undefined or local coordinater reference system; \n no resampled raster was made.\n\n", i); else if (err < 0) ReportError(_context.CurrentLineNum, err); } print("Done.");