Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
#############################################################
#
# SML Script layer to draw a north arrow.
#
# NOTE! This script assumes that the SML layer is in some
# coordinate system other than Lat/Lon (Which is unfortunately
# what the SML layer seems to default to). You MUST change
# the coordinate system of the layer to State Plane or UTM
# or something that uses feet or meters for coordinates.
# If you try to draw this using degrees, you'll get a very
# tall and thin arrow.
#
###############################################################
# Fill in parameters here...
# Angles are in degrees from vertical. Positive is to
# the left, negative is to the right
numeric mn_angle = -7.2; # Degrees to magnetic north
numeric gn_angle;
###############################################################
# Get the angle to true north from a map group.
# This code may have to be tweaked for another layout.
# It assumes that the group you want is the one just
# before the group with this script (in drawing order).
class Group group;
group = ThisLayer.group.PrevGroup;
gn_angle = -group.AngleToNorth;
##############################################################
# Generate the strings. Would like to have this produce
# Degrees, Minutes, Seconds, but decimal degrees is ok for now
string mn_anglestr$ = sprintf("%.1f", abs(mn_angle));
string gn_anglestr$ = sprintf("%.1f", abs(gn_angle));
numeric mn_theta = mn_angle + 90; # Drawing wants angle from x-axis
numeric gn_theta = gn_angle + 90;
array numeric xs[6];
array numeric ys[6];
proc DrawStar(numeric cx, numeric cy, numeric size) {
local numeric i, th;
for i = 0 to 5 {
th = 144 * i + 90;
xs[i+1] = size * cosd(th) + cx;
ys[i+1] = size * sind(th) + cy;
}
FillPolyLine(xs, ys, 5);
# Even/Odd winding rule leaves a hole in the middle
# of our star. Fill it with a circle whose radius
# is computed to intersect with the corners of the
# pentagon shaped hole. Could do this a different
# color if we wanted. Maybe do it before the actual
# polygon fill to get a different colored hole.
FillCircle(cx, cy, size * cosd(36) / 2);
}
#============================================
# Draw a vertical line with a star above it.
numeric r;
SetColorName("black");
r = 200;
MoveTo(0,0);
DrawTo(0,r);
DrawStar(0, r+20, 20);
#============================================
# Draw arrow pointing to Magnetic north
numeric x, y;
r = r * .9;
x = r * cosd(mn_theta);
y = r * sind(mn_theta);
MoveTo(0, 0);
DrawTo(x, y);
# Draw a triangle at the top of it
FillArcWedge(x, y, 20, 20, 270 + mn_angle, 30);
SetColorName("gray");
DrawArc(0, 0, r, r, 90, mn_angle);
SetColorName("black");
DrawTextSetFont("Times.ttf");
DrawTextSetHeight(30);
MoveTo(x + 10, r/2);
DrawTextSimple(mn_anglestr$);
MoveTo(x, y + 5);
DrawTextSimple("MN");
#========================================================
# Draw Grid North
if (gn_angle) {
r = r * .9;
x = r * cosd(gn_theta);
y = r * sind(gn_theta);
MoveTo(0,0);
SetColorName("black");
DrawTo(x, y);
SetColorName("gray");
DrawArc(0, 0, r, r, 90, gn_angle);
SetColorName("black");
MoveTo(-50, y - 15);
DrawTextSimple("GN");
MoveTo(-55, r/2);
DrawTextSimple(gn_anglestr$);
}
#=========================================================
# Dump some text about what Grid north is.
numeric yh;
DrawTextSetHeight(20);
x = 100; y = r * .8; yh = 20;
MoveTo(x, y);
DrawTextSimple(group.Projection.System);
y = y - yh;
# Don't bother printing out the name if the system contains
# the name. Example: "Universal Transverse Mercator"
# contains the name "Transverse Mercator"
if (!(group.Projection.System contains group.Projection.Name)) {
MoveTo(x,y);
DrawTextSimple(group.Projection.Name);
y = y - yh;
}
if (group.Projection.Zone != "") {
MoveTo(x, y);
DrawTextSimple(sprintf("Zone: %s", group.Projection.Zone));
y = y - yh;
}
MoveTo(x, y);
DrawTextSimple(group.Projection.Datum);
y = y - yh;
MoveTo(x, y);
DrawTextSimple(sprintf("Ellipsoid: %s", group.Projection.Ellipsoid));