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);
}