SlopeAspectGraphTip.sml

  Download

More scripts: Enhanced Data Tip

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
### SlopeAspectGraphTip.sml
### Display Control Script that computes slope and aspect for
### the cursor position from an elevation raster (first layer in 
### the group) and plots them graphically in the GraphTip.
### Dimensions of the GraphTip are computed dynamically based on
### the dimensions of the slope triangle and aspect pointer graphics.
### Drawing area coordinates for GraphTip are in screen pixels with
### 0,0 at upper left corner, x positive to right, y positive down.
class GRDEVICE_MEM_RGB24 imagedev;	## color rendering device in memory for drawing GraphTip
class GRDEVICE_MEM_BINARY maskdev;	## transparency mask in memory for GraphTip
class GC gc;								## graphics context for GraphTip
### variables for DEM raster
class GRE_LAYER_RASTER DEM_layer;
class RASTER DEM;		
class TRANSPARM trans;	## coordinate transformation parameters 
class POINT2D ptLayer;	## class for layer coordinates of cursor position
numeric lin, col;			## current line and column position
numeric w, h;				## cell size (width and height)
numeric nullDEM;			## null value for DEM
numeric dzX, dzY;			## derivatives of Z in X and Y directions
numeric slope, aspect;
### variables for GraphTip
numeric height, width;	# dimensions of drawing area
class POINT2D offset;	# offset of GraphTip from cursor
string aspect$;			# aspect value string
numeric aspectDrawAngle;	# angle used for drawing aspect arrow
class POINT2D center;		# position of the center of rotation of the aspect arrow
array numeric x_points[3];		## arrays to hold x and y coordinates of the vertices of
array numeric y_points[3];		## the triangle graphic that depicts the slope
class POINT2D arrowEnd;			## position used to draw arrow head for aspect pointer
numeric tribaseY;					##	y-position of base of slope triangle graphic 
numeric baseline, triHeight; 	## width and height of triangle (in screen pixels)
numeric aspHeight;				## height needed for aspect pointer (in screen pixels)
### procedure called when group or layout is initialized 
proc OnInitialize () {
	offset.x = 15;		## set offset of GraphTip from cursor position
	offset.y = 15;		## (down and to the right)
	}
### procedure called when View is created for group
proc OnGroupCreateView (
   class GRE_GROUP group		## predefined class variable
   ) {
   DEM_layer = group.FirstLayer;					## get first layer in group
	DispGetRasterFromLayer(DEM, DEM_layer);	## get raster variable for DEM
	w = ColScale(DEM);								## get line and column cell size
	h = LinScale(DEM);
	nullDEM = NullValue(DEM);						## get null value for DEM
   }
### function called when datatip event is triggered
func OnViewDataTipShowRequest (
   class GRE_VIEW view,			## predefined class variables
   class POINT2D point,
   class TOOLTIP datatip
   ) {
   numeric retval = 1;		## in GraphTip use only what is created by script
	trans = view.GetTransLayerToScreen(DEM_layer, 1);	## transform from screen to layer
	ptLayer = trans.ConvertPoint2DFwd(point);				## cursor position in layer coordinates
	lin = floor(ptLayer.y);				## line and column position of DEM cell under cursor
	col = floor(ptLayer.x);
	if ( DEM[lin,col] <> nullDEM ) {		## if cursor is not over a null cell
		### compute x and y derivatives and slope
		dzX = ( DEM[lin, col + 1] - DEM[lin, col - 1] ) / (2 * w);
		dzY = ( DEM[lin - 1, col] - DEM[lin + 1, col] ) / (2 * h);
		slope = atand( sqrt( sqr(dzX) + sqr(dzY) ) );
		### compute dimensions of slope triangle graphic
		baseline = 40 * cosd(slope);
		triHeight = baseline * tand(slope);
		tribaseY = 17 + round(triHeight);
		### compute aspect
		if (slope == 0) {		## aspect is undefined for flat areas; no pointer needed
			aspect$ = "Undefined";
			aspHeight = 5;			## set drawing height for area where arrow would otherwise be drawn
			}
		else {
			if (dzY != 0)	{	## check for division by zero
				aspect = deg * atan2(-dzX, -dzY);
				if (aspect < 0 ) then
					aspect += 360;
				}
			else
				aspect = 90;	## when dzY = 0
			aspect$ = sprintf("%.1f deg", aspect);		## create aspect label string
			aspectDrawAngle = (aspect - 90);				## drawing angle for aspect pointer
			aspHeight = round( abs( 18 * sind(aspectDrawAngle) ) );	## height of area pointer will be drawn in
			if (aspHeight < 5) then
				aspHeight = 5;						## minimum drawing height for pointer area
			}
		### compute dimensions of GraphTip drawing area based on
		### triangle graphic and aspect pointer dimensions
		width = 54;										## width of drawing area
		center.x = width / 2;						## position of center for rotating pointer
		center.y = tribaseY + 35 + aspHeight;
		height = center.y + aspHeight + 18;		## height of drawing area
		### create GraphTip drawing area with specified dimensions
		imagedev.Create(height,width);
		maskdev.Create(height,width);
		### begin drawing GraphTip elements
		gc = imagedev.CreateGC();			### create graphics context for GraphTip
		gc.SetColorRGB(100,100,67,100);
		gc.FillRect(0, 0, width, height);	## yellow background rectangle for GraphTip
		gc.SetColorName("black");
		gc.DrawRect(0, 0, width - 1, height - 1);	## draw black frame around GraphTip
		gc.DrawTextSetFont("ARIAL.TTF");
		gc.DrawTextSetHeightPixels(10);
		gc.TextStyle.RoundWidth = 1;
		### draw Slope and Aspect titles
		gc.DrawTextSimple("Slope:", 12, 12);
		gc.DrawTextSimple("Aspect:", 10, tribaseY + 30);
		### draw slope graphic (right triangle) and value label
		### compute coordinates for ends of baseline and store in arrays
		x_points[1] = center.x - baseline / 2;
		x_points[2] = center.x + baseline / 2;
		y_points[1] = tribaseY;
		y_points[2] = tribaseY;
		if (slope < 5) {		# draw horizontal line instead of triangle
			gc.MoveTo(x_points[1], y_points[1]);
			gc.DrawTo(x_points[2], y_points[2]);
			} 
		else {
			x_points[3] = center.x + baseline / 2;		## x-coord of top vertex of triangle
 
			y_points[3] = tribaseY - triHeight;			# y-coordinate of top vertex of triangle
			### draw light blue slope triangle
			gc.SetColorRGB(70, 85, 100, 100);
			gc.DrawPolyLine(x_points, y_points, 3);
			gc.FillPolyLine(x_points, y_points, 3);
			### draw black line along slope (hypotenuse of right triangle)
			gc.MoveTo(x_points[1], y_points[1]);		## move to lower left triangle vertex
			gc.SetColorRGB(0, 0, 0, 100);
			gc.DrawTo(x_points[3], y_points[3]);		## draw line to top vertex
			}
		### draw text for slope value below triangle
		gc.DrawTextSimple( sprintf("%.1f deg", slope), 7, tribaseY + 12);
		### draw the aspect pointer (line with arrowhead added) and label
		if (slope > 0) {
			### find and store coordinates of end of pointer line
			arrowEnd.x = center.x + 18 * cosd(aspectDrawAngle);
			arrowEnd.y = center.y + 18 * sind(aspectDrawAngle);
			### move to start of pointer line and draw to end
			gc.MoveTo( center.x - 16 * cosd(aspectDrawAngle), center.y - 16 * sind(aspectDrawAngle) );
			gc.SetColorRGB(100,0,0,100);
			gc.DrawTo(arrowEnd.x, arrowEnd.y );
			### draw arrowhead
			gc.DrawArrow(arrowEnd.x, arrowEnd.y, aspectDrawAngle, 6, 30, "Open");
			### draw small red circle at center of rotation of pointer
			gc.SetColorRGB(0,0,0,100);
			gc.FillCircle(center.x, center.y, 2);
			}
		### draw text with aspect value under pointer
		gc.DrawTextSimple(aspect$, 5, center.y + aspHeight + 12);
		### set the rendered image and mask as source for the GraphTip
		datatip.SetImageTip(imagedev, maskdev, offset);
		}
	else								## if outside DEM or on null cell then
		retval = -1;				## don't show any datatip
	return (retval);
   }