Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
############################################################################
# Fragtool.sml
# Created by: Mark Smith
# Most recent revision: 5-2001
# This toolscript allows the user to draw a region using a region tool. It
# then uses the region to mask the active layer (provided it is an integer-
# value raster) to extract a raster usable by fragstats. It writes the
# output raster to a text file and calls fragstats using a set of default
# parameters after querying the user for the edge distance value.
#
# The active layer must be an integer-value, single raster with square cells.
# Later versions may support more formats.
#
# This script requires the fragstats executable which is installed in the TNT
# mips win32 directory and that the temporary folder path specified by mips
# have folder names no greater than 8 characters long or have spaces in them.
# Variable declarations
class XmForm form, buttonRow;
class PushButtonItem closeButton;
class MdispRegionTool tool;
class Raster targetRaster;
class GRE_LAYER rasterLayer;
string rasterName$, frag$;
class XmDrawingArea da;
class GC gc;
class GRE_GROUP group;
class FILE outFile;
numeric setDefaultWhenClose = false;
# Checks layer to see if it is valid.
func checkLayer() {
local numeric valid = false;
# Get name of active layer if it is usable. If not output an error message.
if (group.ActiveLayer.Type == "") {
rasterName$ = "Group has no layers!";
}
else {
if (group.ActiveLayer.Type == "Raster") {
rasterLayer = group.ActiveLayer;
DispGetRasterFromLayer(targetRaster, rasterLayer);
if (targetRaster.$Info.Type == "32-bit floating-point" or targetRaster.$Info.Type == "64-bit floating-point") {
rasterName$ = "Raster type not supported!";
}
else {
rasterName$ = rasterLayer.Name;
valid = true;
}
}
else
rasterName$ = "Not a raster!";
}
return valid;
}
# Callback for drawing area expose. Draws text.
proc cbRedraw() {
if (gc == 0) return;
ActivateGC(gc);
# Clear the drawing area and redraw text.
SetColorName("gray75");
FillRect(0, 0, da.width, da.height);
SetColorName("black");
DrawInterfaceText(rasterName$, 0, 12);
}
# Callback for when the active layer changes.
proc cbLayer() {
checkLayer();
cbRedraw();
}
# Callback for when the active group changes.
proc cbGroup() {
group = Layout.ActiveGroup;
WidgetAddCallback(group.LayerSelectedCallback, cbLayer);
cbLayer();
}
# Callback for when user clicks the right mouse button on the polygon tool
# (or clicks apply).
proc cbToolApply(class RegionTool tool) {
# If the selected layer is not valid, don't do anything.
if (checkLayer()) {
# Set local variables
local region MyRgn;
local class StatusHandle status;
local class StatusContext context;
local numeric lins, cols, csize, edist, value;
string type$, tempFile$, fragout$, realout$;
# Create a status bar so user knows the script is doing something.
status = StatusDialogCreate(form);
context = StatusContextCreate(status);
StatusSetMessage(context, "Running fragstats...");
# Get region.
MyRgn = tool.Region;
MyRgn = RegionTrans(MyRgn, ViewGetTransViewToScreen(View, 1));
MyRgn = RegionTrans(MyRgn, ViewGetTransLayerToView(View, rasterLayer, 1));
lins = NumLins(targetRaster);
cols = NumCols(targetRaster);
tempFile$ = CreateTempFileName();
realout$ = "";
fragout$ = GetToken(GetOutputFileName(_context.ScriptDir, "Where would you like the results?", ""), ".", 0);
local numeric i;
local string temp$;
for i = 1 to NumberTokens(fragout$, "\") {
temp$ = GetToken(fragout$, "\", i);
if (strlen(temp$)>8 or NumberTokens(temp$, " ")>1) {
realout$ = fragout$;
fragout$ = FileNameGetPath(tempFile$)+"\"+FileNameGetName(tempFile$);
break;
}
}
if (FileNameGetName(fragout$)=="")
goto cleanup;
csize = (LinScale(targetRaster) + ColScale(targetRaster)) / 2;
edist = PopupNum("Enter the edge distance in meters:");
# Write to text file
outFile = fopen(tempFile$);
# Apply the region for fragstats' use
IgnoreNull(targetRaster);
value = 32071; # Fragstats won't use anything larger than this value
local numeric row, column;
for row = 1 to lins step 1 {
for column = 1 to cols step 1 {
if (PointInRegion(column, row, MyRgn)) {
fprintf(outFile, "%d ", targetRaster[row, column]);
}
else
fprintf(outFile, "%d ", -value);
}
if (row != lins)
fprintf(outFile, "\n");
}
# Close output file
fclose(outFile);
# Run fragstats
run(sprintf("%s %s %s %d %d 2 %d %d %d $ $ $ $ $ y y y y y", frag$, tempFile$, fragout$, csize, edist, lins, cols, value), 1);
if (realout$ != "") {
CopyFile(fragout$+".cla", realout$+".cla");
DeleteFile(fragout$+".cla");
CopyFile(fragout$+".ful", realout$+".ful");
DeleteFile(fragout$+".ful");
CopyFile(fragout$+".lnd", realout$+".lnd");
DeleteFile(fragout$+".lnd");
CopyFile(fragout$+".pat", realout$+".pat");
DeleteFile(fragout$+".pat");
}
cleanup:
# Cleanup
#DeleteFile(Rout.$Info.Filename);
DeleteFile(tempFile$);
# Destroy the status bar
StatusContextDestroy(context);
StatusDialogDestroy(status);
}
else PopupMessage(rasterName$);
}
# Called when the close button is pressed. Closes the dialogs.
proc cbClose() {
tool.Managed = 0;
DialogClose(form);
if (setDefaultWhenClose) {
setDefaultWhenClose = false;
View.SetDefaultTool();
}
}
# Called the first time the tool is activated.
# If the tool implements a dialog it should be created (but not displayed) here.
func OnInitialize () {
if (Layout!=null) {
WidgetAddCallback(Layout.GroupSelectedCallback, cbGroup);
group = Layout.ActiveGroup;
}
else
group = Group;
WidgetAddCallback(group.LayerSelectedCallback, cbLayer);
# Set up tool dialog.
form = CreateFormDialog("Fragstat");
form.marginHeight = 2;
form.marginWidth = 2;
WidgetAddCallback(form.Shell.PopdownCallback, cbClose);
# Drawing area for displaying text.
da = CreateDrawingArea(form, 15, 400);
da.topWidget = form;
da.leftWidget = form;
da.rightWidget = form;
WidgetAddCallback(da.ExposeCallback, cbRedraw);
# Separator between drawing area and close button.
class XmSeparator line;
line = CreateHorizontalSeparator(form);
line.topWidget = da;
line.leftWidget = form;
line.rightWidget = form;
line.topOffset = 2;
# Closes the dialog.
closeButton = CreatePushButtonItem("Close", cbClose);
# Row of buttons.
buttonRow = CreateButtonRow(form, closeButton);
buttonRow.topWidget = line;
buttonRow.leftWidget = form;
buttonRow.rightWidget = form;
buttonRow.bottomWidget = form;
# Add create polygon tool.
tool = ViewCreatePolygonTool(View);
ToolAddCallback(tool.ActivateCallback, cbToolApply);
frag$ = GetInputFileName("c:/tnt/win32/fragstat.exe", "Please locate the fragstat executable.", "exe");
} # end of OnInitialize
# Called when tool is to be destroyed, will not be called if tool was never activated.
func OnDestroy () {
tool.Managed = 0;
DestroyGC(gc);
DestroyWidget(form);
} # end of OnDestroy
# Called when tool is activated.
func OnActivate () {
checkLayer();
tool.Managed = 1;
tool.HasPosition = 0;
DialogOpen(form);
if (gc == 0)
gc = CreateGCForDrawingArea(da);
cbRedraw();
setDefaultWhenClose = true;
} # end of OnActivate
# Called when tool is deactivated (usually when switching to another tool).
func OnDeactivate () {
setDefaultWhenClose = false;
cbClose();
} # end of OnDeactivate