TransferGeoref.sml

  Download

More scripts: Georeference

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
# TransferGeoref.sml
# Script to automate copying of georeference from original
# raster objects in TNT Project Files to rasters of the
# same dimensions that have been enhanced outside TNTmips
# and reimported.
# Assumptions:
# 1) Each georeferenced source and ungeoreferenced target consist of 
# a single raster object in a Project File.
# 2) Source and target files are in different directories but have the
# same filenames.
# 3) The source raster object name is the same as its filename root.  No
#  restriction is placed on the name of the target raster object.  
# The script processes all files with matching names in the selected
# source and target directories.  A log file is created in the source
# directory to list successful result for each file or any errors.
# Potential errors reported in the custom dialog window and log file:
# 1) missing target files listed as "No Match" to source file
# 2) source raster could not be opened (object name and file name don't match)
# 3) source raster not georeferenced
# 4) target raster could not be opened 
# Version 4 February 2011
# Modified to handle variable names for the target raster.
# Randy Smith, MicroImages, Inc.
###############   Global Variables   #################
class STRING sourceDir$, targetDir$;
class STRING logfilename$;										# name of log file
class FILE logfile;
class STRINGLIST sourceList, targetList, confirmedTargetList;
class GUI_DLG dlgwin;
class GUI_CTRL_PUSHBUTTON targetDirBtn;
class GUI_CTRL_EDIT_STRING sourceDirText, targetDirText;
class GUI_CTRL_LISTBOX sourceListbox, targetListbox, procListbox;
class GUI_CTRL_EDIT_NUMBER numSource, numTarget, numProc;
class GUI_CTRL_EDIT_STRING statustext;
class GUI_CTRL_PUSHBUTTON runBtn, cancelBtn, closeBtn;
numeric err;
class STATUSDIALOG statusD;
class STATUSCONTEXT statusC;
##############################################
### function to find target Project File with same name as source
### and return its path string
func findTargetFile(class STRINGLIST list, class STRING name$)
	{
	local numeric i;
	local numeric found = 0;
	for i = 1 to list.GetNumItems()
		{
		if (list[i - 1] == name$) then
			found = 1;
		}
	return found;
	}
############################
### procedure to get the directory containing source maps with georeference
proc GetSourceDirectory()
	{
	local numeric i;
	local numeric filecount;
	sourceDir$ = GetDirectory("", "Select directory with source map files:");
	class FILEPATH sourceDirPath(sourceDir$);
	sourceDirText.SetValueStr(sourceDir$);		# write source directory name to dialog
	# clear dialog listboxes if they are still populated from a previous run
	if (sourceListbox.GetCount() > 0) then
		sourceListbox.DeleteAllItems();
	if (targetListbox.GetCount() > 0) then
		targetListbox.DeleteAllItems();
	if (procListbox.GetCount() > 0)
		{ 
		procListbox.DeleteAllItems();
		numProc.SetValueNum(0);
		}
	# clear stringlist containing matching filenames from previous run
	if (confirmedTargetList.GetNumItems() > 0) then
		confirmedTargetList.Clear();
	targetDir$ = "";
	targetDirText.SetValueStr("");		# clear target directory text field
	statustext.SetValueStr("");			# clear status message text field
	# get stringlist with names of Project Files in the source directory
	sourceList = sourceDirPath.GetFileList("*.rvc");
	sourceList.Sort();
	# loop through stringlist to add names to the source listbox in the dialog
	for i = 1 to sourceList.GetNumItems()
		{
		sourceListbox.AddItem( sourceList[i-1] );
		}
	# write number of source map files found to the editnumber in the dialog
	numSource.SetValueNum(sourceList.GetNumItems() );
	# enable Target Directory button and Cancel button
	targetDirBtn.SetEnabled(1);
	cancelBtn.SetEnabled(1);
	# open log file for this run
	logfilename$ = sprintf("%s/%s.log", sourceDir$, sourceDirPath.GetNameOnly() );
	printf("Log file is %s\n", logfilename$);
	logfile = fopen(logfilename$, "w");
	fprint(logfile, "Log for script transferring map georeference (TransferGeoref.sml.");
	fprintf(logfile, "Source directory = %s\n", sourceDir$);
	fprintf(logfile, "Number of source maps found = %d\n", sourceList.GetNumItems() );
	}
############################
### procedure to get the directory containing the target maps
proc GetTargetDirectory()
	{
	local numeric i;
	local class STRING sourceName$, targetName$;
	local numeric numFound = 0;
	targetDir$ = GetDirectory("", "Select directory with target map files:");
	class FILEPATH targetDirPath(targetDir$);
	targetDirText.SetValueStr(targetDir$);
	# get stringlist with names of Project Files in the target directory
	targetList = targetDirPath.GetFileList("*.rvc");
	# clear target listbox and target stringlist if necessary
	if (targetListbox.GetCount() > 0) then
		targetListbox.DeleteAllItems();
	if (confirmedTargetList.GetNumItems() > 0) then
		confirmedTargetList.Clear();
	# loop through source filename stringlist to identify matching files in
	# target directory and add them to the target listbox and add name to 
	# the confirmed target stringlist
	for i = 1 to sourceList.GetNumItems()
		{
		sourceName$ = sourceList[i - 1];
		if ( findTargetFile(targetList, sourceName$) == 1)
			{ 
			targetName$ = sourceName$;
			++ numFound;
			}
		else
			targetName$ = "No Match";
		# add filename or "No Match" to confirmed list and to listbox 
		confirmedTargetList.AddToEnd(targetName$);
		targetListbox.AddItem(targetName$);
		}
	# write number of target map files found to the editnumber in the dialog
	numTarget.SetValueNum(numFound);
	# enable Run button
	runBtn.SetEnabled(1);
	fprintf(logfile, "Target directory = %s\n", targetDir$);
	fprintf(logfile, "Number of matching target map files found = %d\n", numFound);
	}
############################
### procedure called by the Close button
proc onClose()
	{
	fclose(logfile);
	dlgwin.Close(0);
	Exit();
	}
############################
### procedure called by the Cancel button
proc onCancel()
	{
	fclose(logfile);
	dlgwin.Close(0);
	Exit();
	}
############################
### procedure called by the Run button
proc onRun()
	{
	local numeric i;
	class RVC_RASTER SourceRast, TargetRast;
	class RVC_OBJITEM sourceObjItem, targetObjItem;
	local class STRING filename$;		# name of Project File
	local class STRING objname$, objpath$;
	local class STRING sourcePath$, targetPath$, obj;
	local numeric transferCount = 0;
	local class STRING procListStr;
	local class STRING finalStatus$;
	local class STRINGLIST objNameList;
	statusD.Create();
	statusC = statusD.CreateContext();
	# loop through list of source files to transfer georeference
	for i = 1 to confirmedTargetList.GetNumItems()
		{
		filename$ = confirmedTargetList[i - 1];
		statusC.Message = sprintf("Processing map %d, %s", i, filename$);
		# check string returned for "No Match", indicating there is no matching target file
		if (filename$ == "No Match") then
			procListStr = "No matching target file";
		else		# target file exists
			{
			# construct filepaths for source and target rasters from filename$	 
			sourcePath$ = sourceDir$ + "/" + filename$;
			targetPath$ = targetDir$ + "/" + filename$;
			class FILEPATH sourceFilepath(sourcePath$);
			class FILEPATH targetFilepath(targetPath$);
			# construct object path for source raster
			objname$ = GetToken(filename$, ".", 1);
			objpath$ = objname$ + ".RASTER";
			# set filepath and object path for source raster
			sourceObjItem.SetFilePath(sourceFilepath);
			sourceObjItem.SetObjectPath(objpath$);
			# open the source raster for reading
			err = SourceRast.Open(sourceObjItem, "Read");
			if (err >= 0)		# source raster was successfully opened, check georeference
				{
				# check that source raster has georeference
				if ( GetLastUsedGeorefObject(SourceRast) == 0) then
					procListStr = "Source has no georeference";
				else	# source raster is georeferenced, get target raster
					{
					# get name of raster object in target file and construct object path
					objNameList = GetAllObjectNames(targetPath$, "RASTER");
					objname$ = objNameList.GetString(0);
					objpath$ = objname$ + ".RASTER";
					# set filepath and object path for target raster
					targetObjItem.SetFilePath(targetFilepath);
					targetObjItem.SetObjectPath(objpath$);
					# open the target raster for reading
					err = TargetRast.Open(targetObjItem, "Write");
					if (err >= 0)		# target raster successfully opened
						{
						# check that source and target have the same dimensions
						if (TargetRast.$Info.NumLins == SourceRast.$Info.NumLins &&
							TargetRast.$Info.NumCols == SourceRast.$Info.NumCols)
							{
							CopySubobjects(SourceRast, TargetRast, "GEOREF");
							TargetRast.Close();
							++transferCount;		# increment count of successful transfers
							procListStr = "Transferred";
							}
						else	# source and target don't have the same dimensions.
							procListStr = "Target has wrong dimensions";
						}  # end target opened
					else	# target raster could not be opened.
						procListStr = "Target could not be opened";
					}	# end get target raster
				SourceRast.Close();
				} 	# end source raster opened
			else 		# source raster could not be opened
				procListStr = "Source could not be opened";
			}  # end target file exists
		procListbox.AddItem(procListStr);
		printf("Map %d, %s, result = %s\n", i, filename$, procListStr);
		fprintf(logfile, "Map %d, %s, result = %s\n", i, filename$, procListStr); 
		}	# end loop through confirmedTargetList
	numProc.SetValueNum(transferCount);
	if (transferCount == sourceList.GetNumItems() ) then
		finalStatus$ = "Processing complete, no errors.";
	else
		finalStatus$ = "Processing complete with errors."; 
	statusD.Destroy();
	runBtn.SetEnabled(0);
	cancelBtn.SetEnabled(0);
	statustext.SetValueStr(finalStatus$);
	}  # end onRun()
##################################################
#################   Main Program   #####################
clear();
_context.AbortOnError = 0;		# let script do its own error handling
class STRING xml$='<?xml version="1.0"?>
<!DOCTYPE root SYSTEM "smlforms.dtd">
<root>
	<dialog id="dlgxtiff" Title="Transfer Georeference" Buttons="">
		<pane Orientation="Horizontal" HorizResize="Fixed">
			<pushbutton Name=" Source Directory " OnPressed="GetSourceDirectory()"/>
			<edittext id="sourceDirText" width="45" ReadOnly="true"/>
		</pane>
		<pane Orientation="Horizontal" HorizResize="Fixed">
			<pushbutton id="targetDirBtn" Name=" Target Directory " Enabled="false" OnPressed="GetTargetDirectory()"/>
			<edittext id="targetDirText" Width="45" ReadOnly="true"/>
		</pane>
		<groupbox ExtraBorder="3">
			<pane Orientation="Horizontal" HorizResize="Fixed">
				<pane Orientation="Vertical" HorizResize="Fixed" VertResize="Fixed">
					<listbox id="sourceListbox" Width="20"/>
					<pane Orientation="Horizontal" HorizResize="Fixed">
						<editnumber id="numSource" Width="2" Precision="0" BlankZero="true" ReadOnly="true"/>
						<label>  source maps   </label>
					</pane>
				</pane>
				<pane Orientation="Vertical" HorizResize="Fixed" VertResize="Fixed">
					<listbox id="targetListbox" Width="20"/>
					<pane Orientation="Horizontal" HorizResize="Fixed">
						<editnumber id="numTarget" Width="2" Precision="0" BlankZero="true" ReadOnly="true"/>
						<label>  target maps   </label>
					</pane>
				</pane>
				<pane Orientation="Vertical" HorizResize="Fixed" VertResize="Fixed">
					<listbox id="procListbox" Width="30"/>
					<pane Orientation="Horizontal" HorizResize="Fixed">
						<editnumber id="numProc" Width="2" Precision="0" BlankZero="true" ReadOnly="true"/>
						<label>  transferred</label>
					</pane>
				</pane>
			</pane>
		</groupbox>
		<pane Orientation="Horizontal" HorizAlign="left">
			<edittext id="statustext" Width="20" ReadOnly="true"/>
		</pane>
		<pane Orientation="Horizontal" HorizAlign="right">
			<pushbutton id="runBtn" Name=" Run " Enabled="false" OnPressed="onRun()"/>
			<pushbutton id="cancelBtn" Name=" Cancel " Enabled="false" OnPressed="onCancel()"/>
			<pushbutton id="closeBtn" Name=" Close " OnPressed="onClose()"/>
		</pane>
	</dialog>
</root>';
### parse XML text for the dialog into memory
class XMLDOC dlgdoc;
err = dlgdoc.Parse(xml$); 
### get the dialog element from the parsed XML document
class XMLNODE dlgnode;
dlgnode = dlgdoc.GetElementByID("dlgxtiff");
### set the dialog XML element as the source for the GUI_DLG class instance
dlgwin.SetXMLNode(dlgnode);
dlgwin.CreateModeless();
### get handles for dialog controls
sourceDirText = dlgwin.GetCtrlByID("sourceDirText");
targetDirBtn = dlgwin.GetCtrlByID("targetDirBtn");
targetDirText = dlgwin.GetCtrlByID("targetDirText");
sourceListbox = dlgwin.GetCtrlByID("sourceListbox");
targetListbox = dlgwin.GetCtrlByID("targetListbox");
procListbox = dlgwin.GetCtrlByID("procListbox");
numSource = dlgwin.GetCtrlByID("numSource");
numTarget = dlgwin.GetCtrlByID("numTarget");
numProc = dlgwin.GetCtrlByID("numProc");
statustext = dlgwin.GetCtrlByID("statustext");
runBtn = dlgwin.GetCtrlByID("runBtn");
cancelBtn = dlgwin.GetCtrlByID("cancelBtn");
closeBtn = dlgwin.GetCtrlByID("closeBtn");
# open the dialog
dlgwin.Open();
WaitForExit();