USGS - science for a changing world

Colorado Water Science Center

CREATELLHATCH.AML: A PROGRAM FOR CREATING ANNOTATED LATITUDE AND LONGITUDE HATCH MARKS

National Water-Quality Assessment (NAWQA) Program
South Platte River Basin Study

by Sharon L. Qi and Jennifer B. Sieverling 1

CREATELLHATCH is an Arc Macro Language (AML) program that generates an Arc/Info¹ coverage of annotated latitude-longitude hatch marks along a boundary polygon coverage (for example, a State or a study-area boundary); the polygon boundary coverage may include non-contiguous or interior polygons. Unlike the Arcplot commands that create reference marks as graphical objects along a neatline quadrilateral, CREATELLHATCH creates reference marks and annotation as coverage features along a polygon boundary of any shape. These features can be altered in Arcedit to meet user-specific requirements (for example, to create additional annotation subclasses). The user can specify the location of hatch marks--inside the boundary, outside the boundary, or both. This program runs completely within AML and is designed to be system independent.

*Use of trade names is for identification purposes only and does not imply endorsement by the U.S. Geological Survey.


PROBLEM

The standard Arcplot NEATLINE suite of commands (NEATLINE, NEATLINEGRID, NEATLINEHATCH, NEATLINELABELS, and NEATLINETICS) create labeled coordinate reference graticules or map grids, based on a quadrilateral map border, as temporary graphical elements within an Arcplot session. Because the products of the NEATLINE suite are graphical elements, they cannot be saved or manipulated as geographic features in Arc coverages. The NEATLINE suite of commands results in the creation of a quadrilateral border around an area of interest; this may not always be the desired configuration of the latitude-longitude graticules.

SOLUTION

Unlike the NEATLINE commands that create temporary graphical elements, this AML (see APPENDIX A for AML code) creates latitude-longitude hatch marks that appear only around the boundary polygon of interest; the boundary polygon coverage may include non-contiguous (for example, the State boundary of Hawaii) or interior polygons (for example, the State boundaries of the contiguous United States). These hatch marks and the corresponding labels are saved as an Arc coverage and, therefore, unlike a graphical Arcplot neatline, can be used multiple times, attributed, or edited. The resulting hatch-mark coverage may require additional editing depending on user preferences. For example, the user may create subclasses in addition to those created by CREATELLHATCH (ANNO.LAT and ANNO.LONG), or the user may refine annotation positions.

Additionally, the annotation created by CREATELLHATCH is designed to be displayed using the Arcplot commands and settings TEXTSET FONT.TXT and TEXTSTYLE TYPESET. Because typesetting commands are used by the AML to create the label annotation, the recommended method of editing the annotation, if needed, is through the Arcplot command ANNOEDIT. These are the commands that must be set in the Arcplot session for the annotation to display properly for editing or plotting:

                Arcplot: TEXTSET font.txt
                Arcplot: TEXTSYMBOL 1
                Arcplot: TEXTSTYLE typeset
                Arcplot: TEXTPUT 99
                Arcplot: ANNOTEXT <output_cover> lat
                Arcplot: ANNOTEXT <output_cover> long

This AML must be run in the directory where the output line coverage will be created or loaded as an ATOOL command.

USERS GUIDE

Command name: CREATELLHATCH.AML

Language: AML (ARC/INFO rev. 7.0)

Platform designed on: DG-UX 5.4R3.10

Invoke at Arc: prompt.

Usage: CREATELLHATCH <input_cover> <output_cover> <interval> {DMS | DM | D | DD} {BOTH | INSIDE | OUTSIDE} {hatch_size} {text_size} {LEFT | RIGHT | BOTH} {TOP | BOTTOM | BOTH} {NOJOIN | JOIN}

Purpose: generates an Arc/Info coverage of annotated latitude-longitude hatch marks along a boundary polygon coverage of any shape. CREATELLHATCH creates reference marks and annotation as coverage features that can be edited or attributed.

Arguments

<input_cover> the polygon coverage of the boundary polygon of interest for which the hatch marks will be created.
<output_cover> the name of the output hatch-mark coverage.
<interval> the distance between the hatch marks, in decimal degrees. The number must be between 0.000 and 45.000 decimal degrees.
{DMS | DM | D | DD} a code for specifying the format for the labels of the hatch marks. The default is DMS. (DMS=degrees, minutes, seconds; DM=degrees, minutes; D=degrees; DD=decimal degrees).
{BOTH | INSIDE | OUTSIDE} keyword indicating the position of the hatch marks relative to the study area boundary polygon arc. The default is BOTH.
{hatch_size} the size of the hatch marks, in map units, used to label the latitude and longitude hatch marks. The default hatch size is 1/100 the largest dimension of the input_cover boundary.
{text_size} the size of the label text to be created, in inches, based on an output graphic of 8 inches by 8 inches. The default is 0.09 inch.
{LEFT | RIGHT | BOTH} keyword indicating the position of the latitude labels. The default is LEFT.
{TOP | BOTTOM | BOTH} keyword indicating the position of the longitude labels. The default is TOP.
{NOJOIN | JOIN} keyword indicating whether the boundary polygon should be appended to the hatch-mark output_cover. The default is NOJOIN.

Notes:

This AML must be run in the directory where the output_cover coverage will be created or loaded as an ATOOL command.

The annotation created by CREATELLHATCH is designed to be displayed using the Arcplot commands and settings TEXTSET FONT.TXT and TEXTSTYLE TYPESET. Because typesetting commands are used by the AML to create the label annotation, the recommended method of editing the annotation, if needed, is through the Arcplot command ANNOEDIT. These are the commands that must be set in the Arcplot session for the annotation to display properly for editing or plotting.

        Arcplot: TEXTSET font.txt
        Arcplot: TEXTSYMBOL 1
        Arcplot: TEXTSTYLE typeset
        Arcplot: TEXTPUT 99
        Arcplot: ANNOTEXT <output_cover> lat
        Arcplot: ANNOTEXT <output_cover> long

PROGRAM DESCRIPTION

I. Error Checking
    A. Verify that the program is being run from the Arc: prompt.
    B. Verify that the required command-line arguments are present.
    C. Verify write-access to the current workspace.
    D. Verify that <input_cover> exists, has polygon topology, line topology, and a defined projection.
    E. Verify that <output_cover> does not already exist.
    F. Verify that <interval> is a real number between 0.000 and 45.000.
    G. If optional arguments are given, verify that the appropriate keyword is used.

II. Determine the geographic extent of <input_cover> in latitude and longitude.

III. Create a mesh of latitude and longitude lines based on the desired interval. Add additional vertices to the arcs of the mesh coverage so that the projected version will be smoothly shaped. Attribute the arcs in the mesh cover with latitude and longitude values.

IV. Project the mesh cover from geographic coordinates into a coverage whose coordinate system matches that of the <input_cover>.

V. Crop the mesh of latitude-longitude lines to an area near the boundary polygon coverage arc.

VI. Determine which hatch marks to annotate. This depends on the command-line argument for placing the latitude-longitude annotation.

VII. Create annotation for <output_cover> based on <format>.

VIII. If specified, append the boundary polygon coverage arc to the new line coverage of latitude-longitude hatch marks.

VIIII. Error Routines
    A. If command is given with problems in the arguments, usage syntax will be printed to the screen, and error tolerances will be returned to those set prior to running the AML.
    B. If the program completes running with no problems, temporary coverages and files will be removed, error tolerances will be returned to those set prior to running the AML, and the user will be informed that the program has completed.
    C. If an error occurs, the program will remove temporary coverages and files, error tolerances will be returned to those set prior to running the AML, and the user will be informed that an error has occurred.

DISCLAIMER

Although this program has been used by the U.S. Geological Survey, no warranty, expressed or implied, is made by the USGS as to the accuracy and functioning of the program and related program material, nor shall the fact of distribution constitute any such warranty, and no responsibility is assumed by the USGS in connection therewith.

 

APPENDIX A

/*----------------------------------------------------------------------
/*
/*  Command name:  CREATELLHATCH.AML
/*  Language: aml (ARC/INFO rev 7.0)
/*  Usage: CREATELLHATCH <input_cover> <output_cover> <interval> 
/*            {DMS | DM | D | DD} {BOTH | INSIDE | OUTSIDE} {hatch_size}
/*            {text_size} {LEFT | RIGHT | BOTH} {TOP | BOTTOM | BOTH}
/*            {NOJOIN | JOIN}
/*
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
/* Purpose: generates an Arc/Info coverage of annotated latitude-
/*          longitude hatch marks along a boundary polygon coverage of
/*          any shape. CREATELLHATCH creates reference marks and
/*          annotation as coverage features that can be edited or
/*          attributed.
/*          
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
/* Invoke at Arc: prompt.
/*
/* Arguments:
/*     Variable name,  Req/Opt,  Type,    Definition
/*     -----------------------------------------------------------------
/* input_cover          req      char    the boundary polygon coverage.
/*                                          The coverage may have more
/*                                          than one polygon or interior
/*                                          polygons.
/* output_cover         req      char    the new line coverage to
/*                                          create.
/* interval             req      char    the distance between hatch 
/*                                          marks in decimal degrees.
/* format               opt      char    keyword specifying the format
/*                                          of the annotation: DMS 
/*                                          (degrees, minutes, seconds),
/*                                          DM (degrees, minutes),
/*                                          D (degrees), or DD (decimal
/*                                          degrees).
/* position             opt      char    keyword specifying the posi-
/*                                          tion of the hatch marks
/*                                          relative to the boundary
/*                                          polygon coverage arc.
/* hatch_size           opt      char    the size of the hatch marks, 
/*                                          in map units, used to label
/*                                          the latitude and longitude
/*                                          hatch marks. The default
/*                                          hatch size is 1/100 the 
/*                                          largest dimension of the 
/*                                          input_cover boundary.
/* text_size            opt      char    the size of the annotation, 
/*                                          in inches, used to label
/*                                          the latitude and longitude
/*                                          hatch marks. This is based
/*                                          on an output graphic of 8
/*                                          inches by 8 inches. Because
/*                                          the annotation size is
/*                                          stored in map units, the
/*                                          text size will vary with
/*                                          differing map sizes.
/* lat_pos              opt      char    keyword specifying the location
/*                                          in which the latitude
/*                                          annotation will be placed.
/* long_pos             opt      char    keyword specifying the location
/*                                          in which the longitude
/*                                          annotation will be placed.
/* join                 opt      char    keyword specifying if boundary
/*                                          polygon coverage arc
/*                                          should be included in 
/*                                          output_cover.
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
/*  Routines: FINISHEDOK - Displays message when program completes 
/*                           successfully.
/*            BAILOUT    - Displays message if error occurs.
/*            CLEANUP    - Removes temporary files and coverages and
/*                           returns error tolerances to normal.
/*            USAGE      - Displays the usage for this command.
/*
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
/* History:
/* Author/Site               Date       Ver.  Event
/* ---------------------------------------------------------------------
/* Sharon L. Qi,             03/27/98   1.0   Initial coding.
/*   USGS, WRD, Colorado Dist.
/* Jennifer B. Sieverling,
/*   USGS, WRD, Colorado Dist.
/*
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
/* NOTES: 
/*      1. This AML must be run in the directory where the output line    
/*           coverage will be created or loaded as an ATOOL command.  
/*      2. The annotation created by CREATELLHATCH is designed to be
/*           displayed using the Arcplot commands and settings TEXTSET
/*           font.txt and TEXTSTYLE typeset. Because typesetting
/*           commands are used by the AML to create the label
/*           annotation, the recommended method of editing the
/*           annotation, if needed, is through the Arcplot command
/*           ANNOEDIT. These are the commands that must be set in the 
/*           Arcplot session for the annotation to display properly for
/*           editing or plotting.
/*             Arcplot: TEXTSET font.txt
/*             Arcplot: TEXTSYMBOL 1
/*             Arcplot: TEXTSTYLE typeset
/*             Arcplot: TEXTPUT 99
/*             Arcplot: ANNOTEXT <output_cover> lat
/*             Arcplot: ANNOTEXT <output_cover> long
/*      3. The '#' (shift-3) character can be used as a place holder
/*           for optional arguments.    
/*           
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*
/*    Although this program has been used by the U.S. Geological
/* Survey, no warranty, expressed or implied, is made by the USGS as to
/* the accuracy and functioning of the program and related program
/* material, nor shall the fact of distribution constitute any such
/* warranty, and no responsibility is assumed by the USGS in connection
/* therewith.
/*
/***********************************************************************
/*  Get arguments from the "command" line.
/*
&args input_cover output_cover interval format position hatch_size~
  text_size lat_pos long_pos join

/*  Introduce ourselves, so the user knows we are here.
&type CREATEHATCH Ver 1.0 (27 March 1998)
&type Running ...

/* Determine the current error tolerances are so they can be put back 
/*   when this program is complete.
&s OriginalSettings = [show &severity]

/*  Set error tolerance for this program.
&severity &error &routine bailout

/*
/*::::::::::STARTUP ERROR CHECKING

/* Avoid sending messages from Arc to the screen that might be
/*    confusing.
&messages &off &all

/* Verify that the program is being run from the Arc: prompt.
&if [quote [translate [show program]]] ne 'ARC' &then
  &do
    &type This program must be run from Arc.
    &call usage
  &end
  
/* Tell user how to use program if any required argument is missing.
&if [null %input_cover%] &then &call usage
&if [null %interval%] &then
  &do
    &type Too few arguments specified on command line.
    &call usage
  &end

/* Verify write-access to the current workspace.
&if ^ [access [show &work] -write] &then
  &do
    &type Warning: You do not have write access to this workspace.
    &call usage
  &end   

/* Verify that the input cover exists.
&if ^ [exists %input_cover% -coverage] &then
  &do                           
    &type Coverage %input_cover% does not exist in this workspace.
    &call usage
  &end
  
/* Verify that the output cover does not already exists from a previous
/*  run of this AML or that there is not another cover named this
/*  already.
/* If it exists, warn the user.
&if [exists %output_cover% -coverage] &then
  &do                           
    &type Coverage %output_cover% already exists in this workspace.
    &call usage
  &end

/* Verify that the input cover has polygon topology.
&if ^ [exists %input_cover% -polygon] &then
  &do                           
    &type The input_cover %input_cover% does not have polygon topology.
    &call usage 
  &end                          

/* Verify that the input cover has line topology.
&if ^ [exists %input_cover% -line] &then
  &do                           
    &type The input_cover %input_cover% does not have line topology.\~
          Please build with line topology.
    &call usage 
  &end                          

/* Verify that the input cover has a defined projection.
&describe %input_cover%
&if [null %prj$name%] &then
  &do
    &type Coverage %input_cover% does not have a defined projection.
    &call usage
  &end

/* Verify that the interval is a real number between 0.000 and 45.000. 
&if [type %interval%] > 0 &then
  &do
    &type Interval %interval% is not a real number. 
    &call usage
  &end

&if %interval% le 0 or %interval% > 45 &then
  &do
    &type Interval %interval% is not between 0.000 and 45.000. 
    &call usage
  &end

/* If the optional arguments are given, Verify that they are
/*   correct.
/*
/* Force all optional arguments to be uppercase. If an optional
/*   argument is not given, set it to the default.
 
&if [null %format%] or [quote %format%] eq '#' &then
  &s format DMS
&else 
  &s format [translate %format%]

&if [null %position%] or [quote %position%] eq '#' &then
  &s position BOTH
&else 
  &s position [translate %position%]
  
&if [null %hatch_size%] or [quote %hatch_size%] eq '#' &then
 &do
/*  The default size of the hatch is based on the extent of the
/*  boundary polygon coverage: the hatch size is 1/100 the largest
/*  dimension.
    &describe %input_cover%
    &set x_extent [abs [calc %dsc$xmax% - %dsc$xmin%]]
    &set y_extent [abs [calc %dsc$ymax% - %dsc$ymin%]]
    &s hatch_size [max %x_extent% %y_extent%] / 100
 &end

&if [null %text_size%] or [quote %text_size%] eq '#' &then
 &s text_size = .09

&if [null %lat_pos%] or [quote %lat_pos%] eq '#' &then
  &s lat_pos LEFT
&else 
  &s lat_pos [translate %lat_pos%]

&if [null %long_pos%] or [quote %long_pos%] eq '#' &then
  &s long_pos TOP
&else 
  &s long_pos [translate %long_pos%]

&if [null %join%] or [quote %join%] eq '#' &then
  &s join NOJOIN
&else 
  &s join [translate %join%]

/* Verify the validity of optional arguments.
&if [quote %format%] ^ in {'DMS','DM','D','DD'} &then
  &do
    &type Argument %format% invalid.
    &call usage
  &end

&if [quote %position%] ^ in {'BOTH','INSIDE','OUTSIDE'} &then
  &do
    &type Argument %position% invalid.
    &call usage
  &end

&if [type [quote %hatch_size%]] < 0 &then
  &do
    &type The hatch size %hatch_size% is not a real number. 
    &call usage
  &end

&if [type [quote %text_size%]] < 0 &then
  &do
    &type Text size %text_size% is not a real number. 
    &call usage
  &end

&if [quote %lat_pos%] ^ in {'LEFT','RIGHT','BOTH'} &then
  &do
    &type Argument %lat_pos% invalid.
    &call usage
  &end

&if [quote %long_pos%] ^ in {'TOP','BOTTOM','BOTH'} &then
  &do
    &type Argument %long_pos% invalid.
    &call usage
  &end

&if [quote %join%] ^ in {'NOJOIN','JOIN'} &then
  &do
    &type Argument %join% invalid.
    &call usage
  &end


/***********************************************************************
/*  We've passed all of the error tests.
/*  Now do the work.
/***********************************************************************

&type Starting calculations.
&type This will take a few minutes...


/* Determine the pathname to the current workspace.
&s original_workspace = [show workspace]

/* Determine the precision to the current ARC session.
&s original_precision = [show precision]

/* Set the precision to double to prevent truncation errors.
/*  This will be set back to the original setting in the clean-up
/*  portion of the AML.
precision double

/* For future reference, determine the full pathname of the projection
/*  file for the input cover.
&workspace %input_cover%
&if [exists prj -file] &then
  &s input_projection = [pathname prj]
  &else
    &s input_projection = [pathname prj.adf]
&workspace %original_workspace%

/* Determine the geographic extent of the input cover in latitude and
/*   longitude.

/*/* Find out descriptive information about the input cover.
&describe %input_cover%

/*/* Define a temporary projection file.
&s temp_geodd.prj [scratchname -file]
&s fileunit = [open %temp_geodd.prj% openstat -w]

/*/* Write out the input portion of the projection file to be used later
/*/*   for projecting the latitude-longitude mesh cover to the same
/*/*   projection as the input cover. Only include datum and spheroid
/*/*   if they have been defined in the input cover.
&s chk = [write %fileunit% 'projection geographic']
&s chk = [write %fileunit% 'units dd']
&if ^ [null %prj$datum%] &then 
   &s chk = [write %fileunit% [quote datum %prj$datum%]]
&if ^ [null %prj$spheroid%] &then 
   &s chk = [write %fileunit% [quote spheroid %prj$spheroid%]]
&s chk = [write %fileunit% 'parameters']

&s chk = [close %fileunit%]

/*/* Suppress the canvas window in case one is present from another
/*/*   Arc session.
display 0

/*/* Enter Arcplot to determine the latitude and longitude of the
/*/*   lower left corner and upper right corner of the input cover
/*/*   extent.
arcplot
mapprojection %input_projection% %temp_geodd.prj%
mapextent %input_cover%
&s minlong = [extract 1 [show mapextent]]
&s minlat = [extract 2 [show mapextent]]
&s maxlong = [extract 3 [show mapextent]]
&s maxlat = [extract 4 [show mapextent]]

/*/* Quit from Arcplot.
q

/*/* Truncate min and max longitude and latitude to nearest interval.

&if %minlat% > 0 &then
  &s convenient_minlat = [calc [truncate [calc %minlat% /~
 %interval%]] * %interval%]
&else
  &s convenient_minlat = [calc [calc [truncate [calc %minlat% /~
 %interval%]] * %interval%] - %interval%]
&if %maxlat% > 0 &then
  &s convenient_maxlat = [calc [calc [truncate [calc %maxlat% /~
 %interval%]] * %interval%] + %interval%]
&else
  &s convenient_maxlat = [calc [truncate [calc %maxlat% /~
 %interval%]] * %interval%]
&if %minlong% > 0 &then
  &s convenient_minlong = [calc [truncate [calc %minlong% /~
 %interval%]] * %interval%]
&else
  &s convenient_minlong = [calc [calc [truncate [calc %minlong% /~
 %interval%]] * %interval%] - %interval%]
&if %maxlong% > 0 &then
  &s convenient_maxlong = [calc [calc [truncate [calc %maxlong% /~
 %interval%]] * %interval%] + %interval%]
&else
  &s convenient_maxlong = [calc [truncate [calc %maxlong% /~
 %interval%]] * %interval%]

/* Create a mesh of latitude and longitude lines based on the desired
/*   interval.
&type Creating a mesh of latitude and longitude lines %interval%~
 degrees apart.
&s mesh_cover = [scratchname -directory]
generate %mesh_cover%
fishnet
[value convenient_minlong],[value convenient_minlat]
[value convenient_minlong],[value convenient_maxlat]
[value interval],[value interval]
0
[value convenient_maxlong],[value convenient_maxlat]
quit

/*/* Correct the topology for the mesh cover.
build %mesh_cover% line
build %mesh_cover% node

/*/* Add additional vertices to the arcs of the mesh coverage 
/*/*   so that the projected version will be smoothly shaped.
densifyarc %mesh_cover% # .1 vertex

/* Attribute the arcs in the mesh cover with the reference
/*   latitude or longitude values.

/*/* Add latitude and longitude values to the NAT of the mesh cover.
addxy %mesh_cover% node

/*/* Add latitude and longitude items to the mesh cover AAT and 
/*/*   transfer the values from the NAT.
additem %mesh_cover%.aat %mesh_cover%.aat latitude 8 18 f 5
additem %mesh_cover%.aat %mesh_cover%.aat longitude 8 18 f 5

arcplot
relate add
fromrel
%mesh_cover%.nat
INFO
FNODE#
%mesh_cover%#
linear
ro
torel
%mesh_cover%.nat
INFO
TNODE#
%mesh_cover%#
linear
ro
~

/*/* Calculate the latitude and longitude items in the mesh cover aat
/*/*   to equal the x and y coordinates of the corresponding
/*/*   nodes.
/*/* Do this for each arc.

&s selarcs = [extract 1 [show select %mesh_cover% arc]]

/*/*  Correct %selarcs% if points have not been reselected.
&if %selarcs% = 0 and [extract 2 [show select %mesh_cover% arc]] = 0 ~
&then
  &do
    asel %mesh_cover% arcs
    &s selarcs = [extract 1 [show select %mesh_cover% arcs]]
  &end

/*/* Set up cursor environment.
cursor arcstep declare %mesh_cover% arcs ro
cursor arcstep open

/*/* Compare FROM and TO node locations to identify horizontal versus
/*/*    vertical lines. 
/*/* For horizontal lines, latitude will be the same for both nodes.
/*/*    Set value of item LATITUDE from the y value of the nodes. Set
/*/*    value of item LONGITUDE to be a flag value (999).
/*/* For vertical lines, longitude will be the same for both nodes.
/*/*    Set value of item LONGITUDE from the y value of the nodes. Set
/*/*    value of item LATITUDE to be a flag value (999).

&do x = 1 &to %selarcs% &by 1
 &if [round [calc [show select %mesh_cover% line 1 item~
   fromrel//x-coord] * 10000000]]~
   = [round [calc [show select %mesh_cover% line 1 item~
   torel//x-coord] * 10000000]] &then
   &do
     calc %mesh_cover% arc longitude = fromrel//x-coord
     calc %mesh_cover% arc latitude = 999
   &end
   &else
     &do
       &if [round [calc [show select %mesh_cover% line 1 item~
         fromrel//y-coord] * 10000000]]~
         = [round [calc [show select %mesh_cover% line 1 item~
         torel//y-coord] * 10000000]] &then
         &do
           calc %mesh_cover% arc latitude = fromrel//y-coord
           calc %mesh_cover% arc longitude = 999
         &end
      &else &type Oops, record %x% did not get coded correctly.
    &end
cursor arcstep next
&end
cursor arcstep close

/*/* Quit out of arcplot.
q

/* Create a projection file using projection information from
/*   mesh_cover and input_cover.
/* Project mesh from geographic coordinates to match projection
/*   of input_cover.

/*/* Open the input_cover projection file for reading
&s in_file = [OPEN %input_projection% ok -READ]

/*/* Check to make sure file opened properly.
&if %ok% NE 0 &then
    &return &warning cannot open %input_projection%
    
/*/* Open the output projection file for writing.
&s dd2outprj [scratchname -file]
&s outfile = [OPEN %dd2outprj% ok -write]

/*/* Check to make sure file opened properly.
&if %ok% NE 0 &then
    &return &warning cannot open dd2outprj
&s filestat = 0

&dv out_string*
&s count = 0

/*/* Begin loop for reading input_cover projection file.
&do &until [CALC %filestat% > 0]

/*/* Read one value from the input projection file into the
/*/*   variable.
  &s strng = [unquote [READ %in_file% filestat]]
   &if %filestat% = 0 &then
     &do

/*/*   This is the inside of the loop
/*/*    where a command, using a seeded
/*/*    variable, is executed multiple times.
/*/*    An ASCII file (or qfile) holding a list
/*/*    of values for the variable will be used in this
/*/*    loop. 
    
     &s count = %count% + 1
     &s out_string%count% = %strng%
     &if [index [locase [quote %strng%]] datum] > 0 &then &s~
      datum = [extract 2 %strng%]
     &if [index [locase [quote %strng%]] spheroid] > 0 &then &s~
      spheroid = [extract 2 %strng%]

     &END
&END

/*/* Write out the input portion of the projection file to be used
/*/*   for projecting the mesh cover to the same projection as the
/*/*   input cover.
&s chk = [write %outfile% 'input']
&s chk = [write %outfile% 'projection geographic']
&s chk = [write %outfile% 'units dd']
&if [variable datum] &then 
   &s chk = [write %outfile% [quote datum %datum%]]
&if [variable spheroid] &then 
   &s chk = [write %outfile% [quote spheroid %spheroid%]]
&s chk = [write %outfile% 'parameters']
&s chk = [write %outfile% 'output']

/*/* Write out the output portion of the projection file to be used
/*/*   for projecting the mesh cover to the same projection as the
/*/*   input cover.
&do loop = 1 &to %count%
     &s chk = [write %outfile% [quote [value out_string%loop%]]]
&end
&s chk = [write %outfile% 'end']

&s chk = [close %outfile%]
&s chk = [close %in_file%]

&s mesh_projected_cover [scratchname -directory]

/*/* Project the mesh cover into the same projection as the input cover.
project cover %mesh_cover% %mesh_projected_cover% %dd2outprj%

/*/* Correct the topology of projected mesh coverage.
build %mesh_projected_cover% line

/*....................................................................

/* Crop the mesh of latitude-longitude lines to an area near the
/*   boundary polygon coverage arc(s).
&type Cropping the mesh to an area close to the~
 outermost arc(s) of the input cover.

/*/* Limit work to only the outermost arc(s) of the boundary polygon 
/*/*   coverage.
&s outer_arc_input_cover [scratchname -directory]
reselect %input_cover%  %outer_arc_input_cover% line
res lpoly# = 1 or rpoly# = 1
~
n
n
~

/*/* Correct topology for the newly created coverage of the outermost
/*/*   arc(s) of the boundary polygon coverage.
build %outer_arc_input_cover% poly

/* For use in locating new nodes, add text items to the nat of the
/*   projected mesh and give the new text items the values from x-coord
/*   and y-coord. When new nodes are created AFTER addxy has been run,
/*   the new nodes will have 0 as both the x-coord and y-coord (which
/*   is a POSSIBLE real location); however, the text items will be blank
/*   for the new nodes.
additem %mesh_projected_cover%.nat %mesh_projected_cover%.nat~
 x-text 10 10 c
additem %mesh_projected_cover%.nat %mesh_projected_cover%.nat~
 y-text 10 10 c
 
arcplot
/* Make sure all records from the projected mesh cover are all selected.
reselect %mesh_projected_cover%.nat INFO %mesh_projected_cover%# ge 0~
 or %mesh_projected_cover%# le 0
 
/* Set up environment for stepping through the file one at a time.
&s selnodes = [extract 1 [show select %mesh_projected_cover%.nat INFO]]

/*/* Set up cursor environment.
cursor nodestep declare %mesh_projected_cover% nodes ro
cursor nodestep open

&do x = 1 &to %selnodes% &by 1
calc %mesh_projected_cover% node x-text = [quote [show select~
 %mesh_projected_cover%.nat INFO %x% item x-coord]]
calc %mesh_projected_cover% node y-text = [quote [show select~
 %mesh_projected_cover%.nat INFO %x% item y-coord]]
cursor nodestep next
&end

cursor nodestep close
quit

/* Add nodes to the mesh arcs at the location of the intersection with
/*   the study area outline.
&s ident_cover = [scratchname -directory]
identity %mesh_projected_cover% %outer_arc_input_cover% %ident_cover%~
 line .001
build %ident_cover% line
build %ident_cover% node

/* Convert the intersection nodes to points.
&s ident_cover_points = [scratchname -directory]
nodepoint %ident_cover% %ident_cover_points%

/* Identify the nodes that are the intersections between the mesh and
/*   the outer arc from the intersection of latitude and longitude
/*   lines.
&s latlong_intersect_pts = [scratchname -directory]
reselect %ident_cover_points% %latlong_intersect_pts% points
resel x-text cn '          ' and y-text cn '          '
~
n
n
~
build %latlong_intersect_pts% point

/* Buffer the points based on the hatch size provided on the command
/*   line. 
&s latlong_pts_buffered [scratchname -directory]
buffer %latlong_intersect_pts% %latlong_pts_buffered% # # %hatch_size%~
 .001 point
build %latlong_pts_buffered% poly

/* Confine the projected latitude-longitude mesh to an area very near
/*   the outer polygon boundary.
&s mesh_clipped = [scratchname -directory] 
clip %mesh_projected_cover% %latlong_pts_buffered% %mesh_clipped% line~
 .001

/* If specified, confine the lat/long marks to areas inside or outside
/*   of the boundary polygon coverage arc.
&if [quote %position%] = 'OUTSIDE' &then
  erase %mesh_clipped% %outer_arc_input_cover% %output_cover% line .001
&else
  &if [quote %position%] = 'INSIDE' &then
    clip %mesh_clipped% %outer_arc_input_cover% %output_cover% line~
    .001
  &else
    copy %mesh_clipped% %output_cover%

/* Determine which hatch marks to annotate. This depends on the
/*  command-line arguments {lat_pos} and {long_pos}.
&type Annotating appropriate hatch marks...

/*/*Add the x and y coordinate values to the nat of the output
/*/*  hatch-mark cover.
addxy %output_cover% node

/*/* Add an item to the output cover aat to flag arcs to be annotated.
additem %output_cover%.aat %output_cover%.aat annotate_me 1 1 c
additem %output_cover%.aat %output_cover%.aat annotate_just 2 2 c
additem %output_cover%.aat %output_cover%.aat annotate_node 4 4 c

arcplot
/*/* Set up the link between the nat and aat of the output cover. 
relate add
fromrel
%output_cover%.nat
INFO
FNODE#
%output_cover%#
linear
ro
torel
%output_cover%.nat
INFO
TNODE#
%output_cover%#
linear
ro
~

/*/*/* Work on latitude hatch marks.
&if [quote %lat_pos%] = 'LEFT' or [quote %lat_pos%] = 'BOTH' &then
  &DO
/*/*/* Select latitude arcs.
    reselect %output_cover% arcs latitude < 998 or latitude > 1000 

/*/*/* Determine sets of arcs that are the same latitude.
    &s maxpossible_latloop = [token [listunique %output_cover% -arc~
     latitude] -count]

/*/*/* Loop through the unique latitude values to identify the hatch
/*/*/*  with the minimum longitude.
    &do x = 1 &to %maxpossible_latloop% &by 1

      &s selected_latitude = [extract %x% [listunique %output_cover%~
       -arc latitude]]
      resel %output_cover% arcs latitude > [calc~
       %selected_latitude% - .000001] and latitude < [calc~
       %selected_latitude% + .000001]

/*/*/* Use a related item to select arcs from output cover based on
/*/*/*    values in the nat.
      &s x-min = [extract 1 [listunique %output_cover% -arc~
       fromrel//x-coord]]
      resel %output_cover% arcs fromrel//x-coord > [calc~
       %x-min% - .00001] and fromrel//x-coord < [calc %x-min% + .00001]

/*/*/* Set flag value for use in choosing arcs to annotate.
      calculate %output_cover% arcs annotate_me = 'Y'
      calculate %output_cover% arcs annotate_just = 'CR'
      calculate %output_cover% arcs annotate_node = 'FROM'
      clearsel
    &end

  &END

&if [quote %lat_pos%] = 'RIGHT' or [quote %lat_pos%] = 'BOTH' &then
  &DO
/*/*/* Select latitude arcs.
    reselect %output_cover% arcs latitude < 998 or latitude > 1000 

/*/*/* Determine sets of arcs that are the same latitude.
    &s maxpossible_latloop = [token [listunique %output_cover% -arc~
     latitude] -count]

/*/*/* Loop through the unique latitude values to identify the hatch
/*/*/*  with the maximum longitude.
    &do x = 1 &to %maxpossible_latloop% &by 1

      &s selected_latitude = [extract %x% [listunique %output_cover%~
       -arc latitude]]
      resel %output_cover% arcs latitude > [calc~
       %selected_latitude% - .000001] and latitude < [calc~
       %selected_latitude% + .000001]

/*/*/* Use a related item to select arcs from output cover based on
/*/*/*   values in the nat.
      &s x-count = [token [listunique %output_cover% -arc~
       fromrel//x-coord] -count]
      &s x-max = [extract %x-count% [listunique %output_cover% -arc~
       fromrel//x-coord]]
      resel %output_cover% arcs fromrel//x-coord > [calc~
       %x-max% - .00001] and fromrel//x-coord < [calc %x-max% + .00001]

/*/*/ Set flag value for use in choosing arcs to annotate.
      calculate %output_cover% arcs annotate_me = 'Y'
      calculate %output_cover% arcs annotate_just = 'CL'
      calculate %output_cover% arcs annotate_node = 'TO'
      clearsel
    &end

  &END

/*/*/* Work on latitude hatch marks.
clearsel
&if [quote %long_pos%] = 'TOP' or [quote %long_pos%] = 'BOTH' &then
  &DO

/*/*/* Select longitude arcs.
    reselect %output_cover% arcs longitude < 998 or longitude > 1000 

/*/*/* Determine sets of arcs that are the same longitude.
    &s maxpossible_longloop = [token [listunique %output_cover% -arc~
     longitude] -count]

/*/*/* Loop through the unique longitude values to identify the hatch
/*/*/*  with the maximum latitude.
    &do x = 1 &to %maxpossible_longloop% &by 1

      &s selected_longitude = [extract %x% [listunique %output_cover%~
       -arc longitude]]
      resel %output_cover% arcs longitude > [calc~
       %selected_longitude% - .00001] and longitude < [calc~
       %selected_longitude% + .00001]

/*/*/* Use a related item to select arcs from output cover based on
/*/*/*   values in the nat.
      &s y-count = [token [listunique %output_cover% -arc~
       torel//y-coord] -count]
      &s y-max = [extract %y-count% [listunique %output_cover% -arc~
       torel//y-coord]]
      resel %output_cover% arcs torel//y-coord > [calc~
       %y-max% - .00001] and torel//y-coord < [calc %y-max% + .00001]

/*/*/ Set flag value for use in choosing arcs to annotate.
      calculate %output_cover% arcs annotate_me = 'Y'
      calculate %output_cover% arcs annotate_just = 'LC'
      calculate %output_cover% arcs annotate_node = 'TO'
      clearsel
    &end

  &END
  
&if [quote %long_pos%] = 'BOTTOM' or [quote %long_pos%] = 'BOTH' &then
  &DO
    reselect %output_cover% arcs longitude < 998 or longitude > 1000 

/*/*/* Determine sets of arcs that are the same longitude.
    &s maxpossible_longloop = [token [listunique %output_cover% -arc~
     longitude] -count]

/*/*/* Loop through the unique longitude values to identify the hatch
/*/*/*  with the minimum latitude.
    &do x = 1 &to %maxpossible_longloop% &by 1

      &s selected_longitude = [extract %x% [listunique %output_cover%~
       -arc longitude]]
      resel %output_cover% arcs longitude > [calc~
       %selected_longitude% - .00001] and longitude < [calc~
       %selected_longitude% + .00001]

/*/*/* Use a related item to select arcs from output cover based on
/*/*/*   values in the nat.
      &s y-min = [extract 1 [listunique %output_cover% -arc~
       torel//y-coord]]
      resel %output_cover% arcs torel//y-coord > [calc~
       %y-min% - .00001] and torel//y-coord < [calc %y-min% + .00001]

/*/*/* Set flag value for use in choosing arcs to annotate.
      calculate %output_cover% arcs annotate_me = 'Y'
      calculate %output_cover% arcs annotate_just = 'UC'
      calculate %output_cover% arcs annotate_node = 'FROM'
      clearsel
    &end

  &END

/*/*/* Quit out of arcplot.
q

/* Create annotation for the output cover.
&s tempgra = [scratchname -suffix .gra -file]
arcplot
display 1040
%tempgra%
mape %mesh_projected_cover%
pagesize 8 8
textset font.txt
textsymbol 1
textstyle typeset
textput 99
textsymbol 99
textsize %text_size%

/*/* Determine the format of the annotext to be placed in the
/*/*  coverage based on the format entered on the command line.

/*/*/* Work on latitude lines.
annocoverage %output_cover% lat

/*/*/* Do not look at the flagged values; use range to deal with
/*/*/*     floating-point inexact number definitions.
reselect %output_cover% arcs latitude < 998 or latitude > 1000 and~
 annotate_me cn 'Y' 
&s selarcs_latanno = [extract 1 [show select %output_cover% arcs]]
&if %selarcs_latanno% = 0 &then
  &do
    &type Something went wrong. There are no latitude lines to annotate.
    &call bailout
  &end
cursor latannostep declare %output_cover% arcs ro
cursor latannostep open
  &do x = 1 &to %selarcs_latanno% &by 1
/*/*/*/* Find out what the latitude value is.
    &s templat = [show select %output_cover% line 1 item latitude]
     &if [quote %format%] = 'DD' &then
       &do
         &s ddegree_anno = [truncate [calc %templat% * 1000000]] /~
          1000000
         &s annostring = [format '%1%!pat1857;' [quote %ddegree_anno%]]
       &end
       &else   /* Therefore, must be D, DM, or DMS.
         &do
           &if [quote %format%] = 'D' &then
             &do
               &s degree_anno = [round %templat%]
               &s annostring = [format '%1%!pat1857;' [quote~
                %degree_anno%]]
             &end
           &else   /* Therefore, must be DM or DMS.
               &do
                 &s degree_anno = [truncate %templat%] 
                 &if [quote %format%] = 'DM' &then
                   &do
                     &s minute_anno = [round [calc [abs [calc [calc~
                      %templat% - %degree_anno%] * 60]]]]
                     &s annostring = [format '%1%!pat1857;~
 %2%!pat1727;' [quote %degree_anno%] [quote %minute_anno%]]
                   &end
                 &else   /* Therefore, must be DMS.
                   &do
                     &s minute_anno = [truncate [calc [abs [calc [calc~
                      %templat% - %degree_anno%] * 60]]]]
                     &s minute_temp = [abs [calc [calc~
                      %templat% - %degree_anno%] * 60]]
                     &s second_anno = [round [calc [abs [calc [calc~
                      %minute_temp% - %minute_anno%] * 60]]]]
                     &s annostring = [format '%1%!pat1857; %2%!pat1727;~
 %3%!pat1728;' [quote %degree_anno%] [quote %minute_anno%]~
 [quote %second_anno%]]
                   &end
               &end
         &end

/* Now, place the location text at the end of the hatch mark.
&s anno_position = [show select %output_cover% line 1 item~
 annotate_just]
&s anno_node = [show select %output_cover% line 1 item~
 annotate_node]
 
&if [quote %anno_position%] cn 'CR' &then
  textoffset -.05 0
&if [quote %anno_position%] cn 'CL' &then
  textoffset .05 0
&if [quote %anno_position%] cn 'UC' &then
  textoffset 0 -.05
&if [quote %anno_position%] cn 'LC' &then
  textoffset 0 .05 

  arcendtext %output_cover% [quote %annostring%] # point1 #~
 %anno_position% %anno_node%
   
  cursor latannostep next
  &end
cursor latannostep close
clearselect

/*/*/* Work on longitude lines.
annocoverage %output_cover% long

reselect %output_cover% arcs longitude < 998 or longitude > 1000 and~
 annotate_me cn 'Y' 
&s selarcs_longanno = [extract 1 [show select %output_cover% arcs]]
&if %selarcs_longanno% = 0 &then
  &do
    &type Something went wrong. There are no longitude lines to~
 annotate.
    &call bailout
  &end
cursor longannostep declare %output_cover% arcs ro
cursor longannostep open
  &do x = 1 &to %selarcs_longanno% &by 1
    &s templong = [show select %output_cover% line 1 item longitude]
     &if [quote %format%] = 'DD' &then
       &do
         &s ddegree_anno = [truncate [calc %templong% * 1000000]] /~
          1000000
         &s annostring = [format '%1%!pat1857;' [quote %ddegree_anno%]]
       &end
       &else   /* Therefore, must be D, DM, or DMS.
         &do
           &if [quote %format%] = 'D' &then
             &do
               &s degree_anno = [round %templong%]
               &s annostring = [format '%1%!pat1857;' [quote~
                %degree_anno%]]
             &end
           &else   /* Therefore, must be DM or DMS.
               &do
                 &s degree_anno = [truncate %templong%] 
                 &if [quote %format%] = 'DM' &then
                   &do
                     &s minute_anno = [round [calc [abs [calc [calc~
                      %templong% -~
                     %degree_anno%] * 60]]]]
                     &s annostring = [format '%1%!pat1857;~
 %2%!pat1727;' [quote %degree_anno%] [quote %minute_anno%]]
                   &end
                 &else   /* Therefore, must be DMS.
                   &do
                     &s minute_anno = [truncate [calc [abs [calc [calc~
                      %templong% -~
                     %degree_anno%] * 60]]]]
                     &s minute_temp = [abs [calc [calc~
                      %templong% - %degree_anno%] * 60]]
                     &s second_anno = [round [calc [abs [calc [calc~
                      %minute_temp% - %minute_anno%] * 60]]]]
                     &s annostring = [format '%1%!pat1857; %2%!pat1727;~
 %3%!pat1728;' [quote %degree_anno%] [quote %minute_anno%]~
 [quote %second_anno%]]
                   &end
               &end
         &end

/* Now, place the location text at the end of the hatch mark.
&s anno_position = [show select %output_cover% line 1 item~
 annotate_just]
&if [quote %anno_position%] cn 'CR' &then
  textoffset -.05 0
&if [quote %anno_position%] cn 'CL' &then
  textoffset .05 0
&if [quote %anno_position%] cn 'UC' &then
  textoffset 0 -.05
&if [quote %anno_position%] cn 'LC' &then
  textoffset 0 .05 
 &s anno_node = [show select %output_cover% line 1 item~
 annotate_node]
 
  arcendtext %output_cover% [quote %annostring%] # point1 #~
  %anno_position% %anno_node%
   
  cursor longannostep next
  &end
cursor longannostep close

/*/* Stop writing annotation to the output cover.
annocoverage none

/*/* Quit out of Arcplot.
q      

/* If specified, join the boundary polygon coverage arc to the new
/*   line coverage of latitude-longitude hatch marks.
&if [quote %join%] = 'JOIN' &then
  &do
    arcedit
    editfeature arc
    intersectarcs all
    get %outer_arc_input_cover%
/* Quit out of Arcedit.
    quit yes

  &end

/* Everything finished with no problems.
&call finishedok

/***********************************************************************

/*  If everything finished with no problems, temporary coverages and
/*     files will be removed, error tolerances will be returned to those
/*     set prior to running the AML, and the user will be informed that
/*     the program has completed.
/*
&routine finishedok
&call cleanup

/*  Write an entry into the log file to keep track of use of 
/*     this command.
log * add 
CREATELLHATCH %input_cover% %output_cover% %interval% %format%~
 %position% %hatch_size% %text_size% %lat_pos% %long_pos% %join%

&return; &return &inform CREATEHATCH completed. Coverage %output_cover%~
 has been created.

/*::::::::::::
/*  If an error occurs, temporary coverages and files will be removed,
/*    error tolerances will be returned to those set prior to running
/*    the AML, and the user will be informed that an error has occurred.
/*     
&routine bailout
&call cleanup

&return; &return &inform An error has occurred in CREATELLHATCH.

/*::::::::::::
/* Clean-up after ourselves by removing temporary coverages and files  
/*     and returning error tolerances to normal.
/*
&routine cleanup
&if [quote [translate [show program]]] = 'ARCEDIT' &then
  quit no
&if [quote [translate [show program]]] = 'ARCPLOT' &then
  quit
&if [variable mesh_cover] &then
  &do
    &if [exists %mesh_cover% -cover] &then
      kill %mesh_cover% all
  &end
&if [variable outer_arc_input_cover] &then
  &do
    &if [exists %outer_arc_input_cover% -cover] &then
      kill %outer_arc_input_cover% all
  &end
&if [variable buffer_input_cover] &then
  &do
    &if [exists %buffer_input_cover% -cover] &then
      kill %buffer_input_cover% all
  &end
&if [variable temp_geodd.prj] &then
  &do
    &if [exists %temp_geodd.prj% -file] &then
      &s chk = [delete %temp_geodd.prj% -file]
  &end
&if [variable ident_cover] &then
  &do
    &if [exists %ident_cover% -cover] &then
      kill %ident_cover% all
  &end
&if [variable ident_cover_points] &then
  &do
    &if [exists %ident_cover_points% -cover] &then
      kill %ident_cover_points% all
  &end
&if [variable latlong_intersect_pts] &then
  &do
    &if [exists %latlong_intersect_pts% -cover] &then
      kill %latlong_intersect_pts% all
  &end
&if [variable latlong_pts_buffered] &then
  &do
    &if [exists %latlong_pts_buffered% -cover] &then
      kill %latlong_pts_buffered% all
  &end
&if [variable mesh_clipped] &then
  &do
    &if [exists %mesh_clipped% -cover] &then
      kill %mesh_clipped% all
  &end
&if [variable dd2outprj] &then
  &do
    &if [exists %dd2outprj% -file] &then
        &s chk = [delete %dd2outprj% -file]
  &end
&if [variable mesh_projected_cover] &then
  &do
    &if [exists %mesh_projected_cover% -cover] &then
      kill %mesh_projected_cover% all
  &end
&if [variable tempgra] &then
  &do
    &if [exists %tempgra% -file] &then
     &s chk = [delete %tempgra% -file]
  &end

&if [exists %output_cover% -cover] &then 
  &do
    &severity &warning &ignore
    dropitem %output_cover%.aat %output_cover%.aat annotate_me
    dropitem %output_cover%.aat %output_cover%.aat annotate_just
    dropitem %output_cover%.aat %output_cover%.aat annotate_node
  &end
  

&severity &warning [extract 1 %OriginalSettings%]
&severity &error [extract 2  %OriginalSettings%]
&messages &on
/* Go back to the routine that called the cleanup.
&return

/***********************************************************************
/* If command is given with problems in arguments, a usage example will
/*    be printed to the screen, and error tolerances will be returned
/*    to those set prior to running the AML.
/*
&routine usage

&severity &warning [extract 1 %OriginalSettings%]
&severity &error [extract 2  %OriginalSettings%]

&messages &on

&return &inform Usage: CREATELLHATCH <input_cover> <output_cover>\~
<interval> {DMS | DM | D | DD} {BOTH | INSIDE | OUTSIDE} {hatch_size}\~
{text_size} {LEFT | RIGHT | BOTH} {TOP | BOTTOM | BOTH} {NOJOIN | JOIN}

1 U.S. Geological Survey, Box 25046, MS 415, Denver Federal Center, Lakewood, CO 80225

Accessibility FOIA Privacy Policies and Notices

U.S. Department of the Interior | U.S. Geological Survey
URL: https://co.water.usgs.gov/nawqa/splt/meetings/P296.html
Page Contact Information: gs-w-codist_webmaster
Page Last Modified: Friday, 16-Dec-2016 19:04:05 EST