TNTmips

HOME

FREE PRODUCTS
  TNTlite
  TNTatlas
  TNTsim3D

DOWNLOADS
  Release Version
  Development Version
  FTP
  Language Kits
  Sample Geodata
  Reseller Resources
  Promotional

DOCUMENTATION
  Tutorials
  Technical Guides
  Quick Guides

SITE MAP


Rastprof.sml

See other examples of Tool and Macro scripts ...


#############################################################################################################
# RASTPROF.SML 
# Created by: Mark Smith
# Most recent revision: 9-2001
#
# This toolscript allows the user to draw a line using a line tool.  It accumulates
# the raster data from the active raster along the line and then creates a graph displaying
# the profile of the raster along the line.
#
# The active layer may not be a composite raster.
#
# This script requires TNTmips version 6.6.
#
# The following symbols are predefined
#    class VIEW View            {use to access the view the tool script is attached to}
#    class GROUP Group          {use to access the group being viewed if the script is run from a group view}

# Variable declarations
class XmForm form;
class LineTool tool;
class GRE_LAYER rasterLayer;
class Raster targetRaster;
class XmDrawingArea da;
class GC gc;
class GRE_GROUP activegroup;
string rasterName$;
numeric doGraph, hasNull;
array numeric value[1000000];
array numeric draw[1000000];
array numeric graphx[3], graphy[3];
numeric min, max, count, nullVal;
class POINT2D startpoint;
class POINT2D endpoint;
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 (activegroup.ActiveLayer.Type == "") {
		rasterName$ = "Group has no layers!";
		}
	else {
		if (activegroup.ActiveLayer.Type == "Raster") {
			rasterLayer = activegroup.ActiveLayer;
			DispGetRasterFromLayer(targetRaster, rasterLayer);
			# Check for null values
			if (HasNull(targetRaster)) {
				hasNull = 1;
				nullVal = NullValue(targetRaster);
				}
			else
				hasNull = 0;

			if (targetRaster.$Info.Type != "binary" and
				targetRaster.$Info.Type != "4-bit unsigned" and
				targetRaster.$Info.Type != "8-bit signed" and
				targetRaster.$Info.Type != "8-bit unsigned" and
				targetRaster.$Info.Type != "16-bit signed" and
				targetRaster.$Info.Type != "16-bit unsigned" and
				targetRaster.$Info.Type != "32-bit signed" and
				targetRaster.$Info.Type != "32-bit unsigned" and
				targetRaster.$Info.Type != "32-bit floating-point" and
				targetRaster.$Info.Type != "64-bit signed" and
				targetRaster.$Info.Type != "64-bit unsigned" and
				targetRaster.$Info.Type != "64-bit floating-point") {
				rasterName$ = "Type not supported!";
				}
			else {
				rasterName$ = rasterLayer.Name;
				valid = true;
				}
			}
		else
			rasterName$ = "Not a raster!";
		}
	return valid;
	}

# Callback for drawing area expose.  Draws text and graph.
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(sprintf("Raster: %s", rasterName$), 0, 10);

	if (doGraph == 0) return;

	local string min$, max$;
	local numeric size;
	local class POINT2D graph1, graph2, graph3;

	# Draw graph axes
	min$ = sprintf("%d", min);
	max$ = sprintf("%d", max);

	size = strlen(max$);

	graphx[1] = size*6.5+5;
	graphy[1] = 20;
	graphx[2] = graphx[1];
	graphy[2] = da.height - 15;
	graphx[3] = da.width - 5;
	graphy[3] = graphy[2];
	DrawPolyLine(graphx, graphy, 3);

	DrawTextSetFont("stork");
	DrawTextSetHeight(10);

	DrawTextSimple(max$, 0, graphy[1]+10);
	DrawTextSimple(min$, (size - strlen(min$))*6.5, graphy[2]);
	DrawTextSimple(sprintf("%d, %d", startpoint.x, startpoint.y), graphx[1], da.height-3);
	local string str$ = sprintf("%d, %d", endpoint.x, endpoint.y);
	DrawTextSimple(str$, graphx[3] - strlen(str$)*6.5, da.height-3);

	SetColorName("magenta");

	local numeric xscale, yscale, prevnull;
	xscale = (graphx[3] - graphx[2] + 1) / (count - 1);
	yscale = (graphy[2] - graphy[1]) / (max - min);

	# Draw profile
	if (value[1] < 0 || value[1] >= 0) {
		if (max - min == 0) {
			DrawPoint(graphx[2], graphy[1] + (graphy[2]-graphy[1])*.5);
			}
		else
			DrawPoint(graphx[2], graphy[2]-(value[1]-min)*yscale);
		}
	local numeric i;
	for i = 2 to count {
		if (value[i] < 0 || value[i] >= 0) {
			if (!(value[i-1] < 0 || value[i-1] >= 0)) {
				if (max - min == 0) {
					DrawPoint(graphx[2]+(i-1)*xscale, graphy[1] + (graphy[2]-graphy[1])*.5);
					}
				else
					DrawPoint(graphx[2]+(i-1)*xscale, graphy[2]-(value[i]-min)*yscale);
				}
			else {
				if (max - min == 0) {
					DrawTo(graphx[2]+(i-1)*xscale, graphy[1] + (graphy[2]-graphy[1])*.5);
					}
				else
					DrawTo(graphx[2]+(i-1)*xscale, graphy[2]-(value[i]-min)*yscale);
				}
			}
		}
	}

# Callback for when the active layer changes.
proc cbLayer() {
	checkLayer();
	cbRedraw();
	}

# Callback for when the active group changes.
proc cbGroup() {
	activegroup = Layout.ActiveGroup;
	WidgetAddCallback(activegroup.LayerSelectedCallback, cbLayer);
	cbLayer();
	}

# Callback for when user clicks the right mouse button on the polygon tool
# (or clicks apply).
proc cbToolApply() {
	# If the selected layer is not valid, don't do anything.
	if (checkLayer()) {
		startpoint = tool.start;
		endpoint = tool.end;
		startpoint = TransPoint2D(startpoint, ViewGetTransLayerToScreen(View, rasterLayer, 1));
		endpoint = TransPoint2D(endpoint, ViewGetTransLayerToScreen(View, rasterLayer, 1));

		# Get x and y step values
		local numeric ystep, xstep;
		local class POINT2D cursor;
		cursor = startpoint;
		count = 0;
		ystep = endpoint.y - startpoint.y;
		xstep = endpoint.x - startpoint.x;
		if (xstep == 0 && ystep == 0)
			return;
		if (abs(xstep) > abs(ystep)) {
			ystep = ystep / abs(xstep);
			xstep = xstep / abs(xstep);
			if (ystep == 0) {
				count = abs(endpoint.x - startpoint.x);
				}
			else
				count = abs((endpoint.y - startpoint.y) / ystep);
			}
		else {
			xstep = xstep / abs(ystep);
			ystep = ystep / abs(ystep);
			if (xstep == 0) {
				count = abs(endpoint.y - startpoint.y);
				}
			else 
				count = abs((endpoint.x - startpoint.x) / xstep);
			}
		count = count + 1;

		doGraph = 1;

		max = -1000000;
		min = 1000000;

		# Loop on line to generate point list.
		local numeric i;
		for i = 1 to count {
			value[i] = targetRaster[round(cursor.y), round(cursor.x)];
			# If the raster value was retrieved from a null cell or a coordinate
			# outside the raster extents, value[i] will be 'not a number'.
			# Therefore testing if it is < 0 or >= 0 determines whether it is 
			# a valid value
			if (value[i] < 0 || value[i] >= 0) {
				if (value[i] > max)
					max = value[i];
				if (value[i] < min)
					min = value[i];
				}
			cursor.x = cursor.x + xstep;
			cursor.y = cursor.y + ystep;
			}
		if (max == -1000000 && min == 1000000) {
			max = 0;
			min = 0;
			}
		cbRedraw();
		}
	}

# 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) {
		WidgetAddCallback(Layout.GroupSelectedCallback, cbGroup);
		activegroup = Layout.ActiveGroup;
		}
	else
		activegroup = Group;
	WidgetAddCallback(activegroup.LayerSelectedCallback, cbLayer);

	# Set up tool dialog.
	form = CreateFormDialog("Raster profile");
	form.marginHeight = 2;
	form.marginWidth = 2;
	WidgetAddCallback(form.Shell.PopdownCallback, cbClose);

	# Drawing area for displaying text.
	da = CreateDrawingArea(form, 173, 301);
	da.topWidget = form;
	da.bottomWidget = form;
	da.leftWidget = form;
	da.rightWidget = form;
	WidgetAddCallback(da.ExposeCallback, cbRedraw);

	# Add sketch tool.
	tool = ViewCreateLineTool(View);
	ToolAddCallback(tool.ApplyCallback, cbToolApply);

	doGraph = 0;
	}  # 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();
	DialogOpen(form);

	tool.Managed = 1;
	tool.HasPosition = 0;

	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

 


Back Home ©MicroImages, Inc. 2008 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010   USA
Business & Sales: (402)477-9554  Support: (402)477-9562  Fax: (402)477-9559
Business info@microimages.com  Support support@microimages.com  Web webmaster@microimages.com

9 May 2008

page update: 10 Aug 07