More scripts: Vector
Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
## POLYBL.SML
## This sample script illustrates the use of some of the
## vector and database functions in SML. It is designed to operate
## on a vector object containing contiguous polygons that might
## represent countries, states, counties, census blocks, etc. The script
## selects four specific polygons by attribute, and computes
## the total length of the polygon boundary lines that are not
## shared between the selected polygons. For a block of contiguous
## polgyons, this is the perimeter of the block. If none of the
## selected polygons are contiguous, the calculated length
## is the total boundary length of the selected polygons.
## The checks for the class of adjacent polygons require explicit
## database table.field references which must be provided for the
## the particular vector object being used. This example uses the
## vector object 'states' in the UNTDSTAT.RVC Project File in the
## USA sample data collection.
## Polygons are selected by the name of the state, which is contained
## in the STATE_NAME field in the 'states' database table.
## The line list for a selected polygon is accessed, and database
## references are used to check the class assignments for the polygons
## on either side of each line. If either polygon is not among the
## selected set of states, the line length is added to a perimeter
## variable for the polygon.
## For each selected polygon, the SML script outputs the following
## data for each unshared boundary line: line element number,
## the state to the left and right sides, and the line length.
## The summed unshared boundary length is then reported for the polygon.
## When all selected polygons have been processed, the total unshared
## boundary length for the selected set is reported. The in-depth
## report facilitates checking that the polygon adjacency selection
## criteria are working correctly.
## Output information is printed to the console window, and written
## to a text file.
## AUTHOR: Randy Smith, MicroImages, Inc.
## CREATION DATE: May 13, 1997
clear();
class VECTOR V;
class FILE output;
GetInputVector(V);
# Set up PopUp Dialogs to provide names of states
string s1$, s2$, s3$, s4$;
s1$ = PopupString("Enter the name of the first state with first letter capitalized: ", "Nebraska");
s2$ = PopupString("Enter the name of the second state: ", "Kansas");
s3$ = PopupString("Enter the name of the third state: ", "Colorado");
s4$ = PopupString("Enter the name of the fourth state: ", "Wyoming");
# Set up PopUp Dialog to name an output text file for results
string defaultfile$ = "c:/DATA/boundout.txt";
$ifdef _MI_INTERNAL_AUTOTEST_MODE
defaultfile$ = CreateTempFileName();
output = fopen(defaultfile$, "w");
$else
string outfile$ = PopupString( "Enter path and filename for results text file:", defaultfile$ );
output = fopen(outfile$, "w");
$endif
# Initialize perimeter variables
numeric perim1, perim2, perim3, perim4, tperim;
perim1 = 0; # unshared perimeter of state1
perim2 = 0; # unshared perimeter of state2
perim3 = 0; # unshared perimeter of state3
perim4 = 0; # unshared perimeter of state4
tperim = 0; # total unshared perimeter of selected states
# Define array to contain list of line numbers for the selected polygon.
# Array size is arbitrary; it will be resized automatically by
# the GetVectorPolyLinelist function.
array numeric linelist[10];
# Main processing loop
numeric i;
numeric numlines, linenum;
numeric leftpoly, rightpoly;
numeric len1, len2, len3, len4;
for each poly in V begin
if (V.poly.states.STATE_NAME$ == s1$ ) then begin # processing loop for state1
printf( "\n\n--------------\n%s", s1$ ); # print separator line in console window
fprintf( output, "\n\n------------\n%s", s1$ ); # print separator line in output file
numlines = GetVectorPolyLineList(V, linelist); # get list of lines and assign number
# of lines to variable
for i = 1 to numlines begin
linenum = linelist[i];
leftpoly = V.line[linenum].Internal.LeftPoly; # get number of polygon to left
rightpoly = V.line[linenum].Internal.RightPoly; # get number of polygon to right
if ( ( V.poly[leftpoly].states.STATE_NAME$ == s1$ and
! ( V.poly[rightpoly].states.STATE_NAME$ == s2$ or # database query to select
V.poly[rightpoly].states.STATE_NAME$ == s3$ or # lines not shared with
V.poly[rightpoly].states.STATE_NAME$ == s4$ ) ) # other selected states
or
( V.poly[rightpoly].states.STATE_NAME$ == s1$ and
! ( V.poly[leftpoly].states.STATE_NAME$ == s2$ or
V.poly[leftpoly].states.STATE_NAME$ == s3$ or
V.poly[leftpoly].states.STATE_NAME$ == s4$ ) ) ) then begin
len1 = V.line[linenum].LINESTATS.Length; # get line length from LINESTATS
printf( "\n\nLine: %d\tLength: %10.3f", linenum, len1 );
fprintf( output, "\n\nLine: %d\tLength: %10.3f", linenum, len1 );
printf( "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
fprintf( output, "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
perim1 = perim1 + len1; # add length of line to perim
end
end
printf( "\n\nUnshared boundary length of %s = %10.3f meters", s1$, perim1 );
fprintf( output, "\n\nUnshared boundary length of %s = %10.3f meters", s1$, perim1 );
end
if (V.poly.states.STATE_NAME$ == s2$ ) then begin # processing loop for state2
printf( "\n\n--------------\n%s", s2$ );
fprintf( output, "\n\n----------------\n%s", s2$ );
numlines = GetVectorPolyLineList(V, linelist);
for i = 1 to numlines begin
linenum = linelist[i];
leftpoly = V.line[linenum].Internal.LeftPoly;
rightpoly = V.line[linenum].Internal.RightPoly;
if ( ( V.poly[leftpoly].states.STATE_NAME$ == s2$ and
! ( V.poly[rightpoly].states.STATE_NAME$ == s1$ or
V.poly[rightpoly].states.STATE_NAME$ == s3$ or
V.poly[rightpoly].states.STATE_NAME$ == s4$ ) )
or
( V.poly[rightpoly].states.STATE_NAME$ == s2$ and
! ( V.poly[leftpoly].states.STATE_NAME$ == s1$ or
V.poly[leftpoly].states.STATE_NAME$ == s3$ or
V.poly[leftpoly].states.STATE_NAME$ == s4$ ) ) ) then begin
len2 = V.line[linenum].LINESTATS.Length;
printf( "\n\nLine: %d\tLength: %10.3f", linenum, len2 );
fprintf( output, "\n\nLine: %d\tLength: %10.3f", linenum, len2 );
printf( "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
fprintf( output, "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
perim2 = perim2 + len2;
end
end
printf( "\n\nUnshared boundary length of %s = %10.3f meters", s2$, perim2 );
fprintf( output, "\n\nUnshared boundary length of %s = %10.3f meters", s2$, perim2 );
end
if (V.poly.states.STATE_NAME$ == s3$ ) then begin # processing loop for state3
printf( "\n\n--------------\n%s", s3$ );
fprintf( output, "\n\n--------------\n%s", s3$ );
numlines = GetVectorPolyLineList(V, linelist);
for i = 1 to numlines begin
linenum = linelist[i];
leftpoly = V.line[linenum].Internal.LeftPoly;
rightpoly = V.line[linenum].Internal.RightPoly;
if ( ( V.poly[leftpoly].states.STATE_NAME$ == s3$ and
! ( V.poly[rightpoly].states.STATE_NAME$ == s1$ or
V.poly[rightpoly].states.STATE_NAME$ == s2$ or
V.poly[rightpoly].states.STATE_NAME$ == s4$ ) )
or
( V.poly[rightpoly].states.STATE_NAME$ == s3$ and
! ( V.poly[leftpoly].states.STATE_NAME$ == s1$ or
V.poly[leftpoly].states.STATE_NAME$ == s2$ or
V.poly[leftpoly].states.STATE_NAME$ == s4$ ) ) ) then begin
len3 = V.line[linenum].LINESTATS.Length;
printf( "\n\nLine: %d\tLength: %10.3f", linenum, len3 );
fprintf( output, "\n\nLine: %d\tLength: %10.3f", linenum, len3 );
printf( "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
fprintf( output, "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
perim3 = perim3 + len3;
end
end
printf( "\n\nUnshared boundary length of %s = %10.3f meters", s3$, perim3 );
fprintf( output, "\n\nUnshared boundary length of %s = %10.3f meters", s3$, perim3 );
end
if (V.poly.states.STATE_NAME$ == s4$ ) then begin # processing loop for state4
printf( "\n\n--------------\n%s", s4$ );
fprintf( output, "\n\n-----------------\n%s", s4$ );
numlines = GetVectorPolyLineList(V, linelist);
for i = 1 to numlines begin
linenum = linelist[i];
leftpoly = V.line[linenum].Internal.LeftPoly;
rightpoly = V.line[linenum].Internal.RightPoly;
if ( ( V.poly[leftpoly].states.STATE_NAME$ == s4$ and
! ( V.poly[rightpoly].states.STATE_NAME$ == s1$ or
V.poly[rightpoly].states.STATE_NAME$ == s2$ or
V.poly[rightpoly].states.STATE_NAME$ == s3$ ) )
or
( V.poly[rightpoly].states.STATE_NAME$ == s4$ and
! ( V.poly[leftpoly].states.STATE_NAME$ == s1$ or
V.poly[leftpoly].states.STATE_NAME$ == s2$ or
V.poly[leftpoly].states.STATE_NAME$ == s3$ ) ) ) then begin
len4 = V.line[linenum].LINESTATS.Length;
printf( "\n\nLine: %d\tLength: %10.3f", linenum, len4 );
fprintf( output, "\n\nLine: %d\tLength: %10.3f", linenum, len4 );
printf( "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
fprintf( output, "\nLeftPoly = %s\t\tRightPoly = %s", V.poly[leftpoly].states.STATE_NAME$,
V.poly[rightpoly].states.STATE_NAME$ );
perim4 = perim4 + len4;
end
end
printf( "\n\nUnshared boundary length of %s = %10.3f meters", s4$, perim4 );
fprintf( output, "\n\nUnshared boundary length of %s = %10.3f meters", s4$, perim4 );
end
end
tperim = perim1 + perim2 + perim3 + perim4; # calculate total unshared perimeter
printf( "\n\n=====================\n\nTotal unshared boundary length of states = %10.5f meters", tperim );
fprintf( output, "\n\n=================\n\nTotal unshared boundary length of states = %10.5f meters", tperim );
fclose(output);