Imported Upstream version 1.1.0 upstream/1.1.0
authorBdale Garbee <bdale@gag.com>
Thu, 5 Jun 2008 23:33:45 +0000 (17:33 -0600)
committerBdale Garbee <bdale@gag.com>
Thu, 5 Jun 2008 23:33:45 +0000 (17:33 -0600)
28 files changed:
CHANGES [new file with mode: 0644]
COPYING [new file with mode: 0644]
README [new file with mode: 0644]
build [new file with mode: 0755]
clean [new file with mode: 0755]
configure [new file with mode: 0755]
docs/man/docmaker [new file with mode: 0755]
docs/man/splat.1 [new file with mode: 0644]
docs/man/splat.man [new file with mode: 0644]
docs/pdf/splat.pdf [new file with mode: 0644]
docs/postscript/splat.ps [new file with mode: 0644]
docs/text/splat.txt [new file with mode: 0644]
fontdata.h [new file with mode: 0644]
install [new file with mode: 0755]
itm.cpp [new file with mode: 0644]
sample.lrp [new file with mode: 0644]
smallfont.h [new file with mode: 0644]
splat-1.1.0.lsm [new file with mode: 0644]
splat.cpp [new file with mode: 0644]
utils/README [new file with mode: 0644]
utils/build [new file with mode: 0755]
utils/citydecoder.c [new file with mode: 0644]
utils/fips.txt [new file with mode: 0644]
utils/fontdata.c [new file with mode: 0644]
utils/install [new file with mode: 0755]
utils/postdownload [new file with mode: 0755]
utils/s.fnt.gz [new file with mode: 0644]
utils/usgs2sdf.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
new file mode 100644 (file)
index 0000000..b8060bb
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,91 @@
+Release 1.1.0:
+By John A. Magliacane <kd2bd@amsat.org> (29-Jan-2004):
+
+* Extensively modified by J. D. McDonald in January 2004 to include
+  the Longley-Rice propagation model using C++ code from NTIA/ITS.
+  In addition to analyzing line-of-sight propagation paths, SPLAT!
+  now generates multi-color maps illustrating predicted signal
+  strength (path loss), path loss graphs, path loss reports,
+  and terrain height graphs.  The default earth radius, as well
+  as the default line-of-sight and path loss analysis range used
+  by SPLAT! may also be modified using new command-line options.
+
+* splat.c was renamed to splat.cpp to reflect changes necessary
+  to merge with Longley-Rice C++ code.  A C++ compiler (gcc/g++)
+  is now required to compile SPLAT!.
+
+* The documentation was updated to reflect the new features
+  of the program.
+
+----------------------------------------------------------------------------
+
+Release 1.0.3:
+By John A. Magliacane <kd2bd@amsat.org> (10-Jun-2002):
+
+* Coverage areas are now processed four times faster than before.
+  (TNX KC6YSO)
+
+* Determination of antenna height above average terrain (HAAT) based
+  on FCC Part 73.313(d) (Prediction of coverage) has been added.
+
+* Site analysis report generation has been added when coverage mode
+  is invoked.  These reports include ground height above mean sea
+  level, antenna height above mean sea level, antenna height above
+  average terrain, and average terrain calculated at azimuths of 0,
+  45, 90, 135, 180, 225, 270, and 315 degrees.
+
+* Added site location information in degree, minute, second format,
+  as well as antenna height above average terrain to the content of
+  obstruction reports.
+
+* Elevations below sea-level are now safely handled.
+
+* Greyscale of topographic maps generated by SPLAT! is now referenced
+  between the highest and lowest elevations in the survey, instead of
+  between the highest elevation and sea-level.  This change in reference
+  permits regions below sea level to be discernible in the map, and
+  allows subtle terrain variations to be clearly evident over regions
+  having relatively flat terrain.
+
+* The documentation was updated.
+
+* Several other minor coding changes/bug fixes were made.
+
+----------------------------------------------------------------------------
+
+Release 1.0.2:
+By John A. Magliacane <kd2bd@amsat.org> (14-May-2002):
+
+* SPLAT! now buffers data while reading bzip2 compressed SPLAT
+  Data Files (SDFs).  A 100 MHz Pentium now loads compressed SDF
+  files 208% faster than before, and takes only 2 seconds longer
+  than an uncompressed file.
+
+* Configuration, compilation, and installation scripts now invoke
+  bash instead of sh.  The -ffast-math compiler option was removed.
+
+----------------------------------------------------------------------------
+
+Release 1.0.1:
+By John A. Magliacane <kd2bd@amsat.org> (22-Apr-2002):
+
+* The maximum number of transmitter/repeater sites handled
+  per analysis has been increased from two to four.
+
+* Improved the configuration, compilation, and installation scripts.
+  Now ./configure compiles and installs the program, man page, and
+  all associated utilities in one command.
+
+* Some minor coding changes were made, including the addition of an
+  #include <stdlib.h> in each of the utilities to silence a compilation
+  warning issued by gcc version 3.x.x about the use of the exit() function.
+
+* The README and documentation files were updated.
+
+----------------------------------------------------------------------------
+
+Release 1.0.0:
+by John A. Magliacane <kd2bd@amsat.org> (08-Apr-2002):
+
+* First public release of SPLAT!
+
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..916d1f0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+       Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..2f0db5d
--- /dev/null
+++ b/README
@@ -0,0 +1,90 @@
+     ===============================================================
+     * Welcome to SPLAT! -- A Terrain Analysis Tool for Unix/Linux *
+     ===============================================================
+
+Requirements
+============
+SPLAT! requires the libbzip2-1.0.1 (or later) compression library and
+header files for successful compilation.  bzip2/libbzip2 is available
+at: http://sources.redhat.com/bzip2/
+
+SPLAT! also requires the zlib general purpose compression library.
+Any recent version included with your Linux distribution should work
+fine.  Note, however, that zlib version 1.1.3 contains a security
+vulnerability that has been fixed in version 1.1.4.  The latest
+version of zlib may be found at: http://www.gzip.org/zlib/
+If you decide to build zlib, don't forget to invoke:
+
+       ./configure -s
+
+to build zlib as a shared library.
+
+If you wish to generate terrain and elevation profiles through SPLAT!,
+you will also need gnuplot.  The latest version of gnuplot is available
+at: http://www.gnuplot.info/
+
+You will also need an application for viewing large PPM graphics
+files generated by SPLAT!.  XV, ImageMagick, XPaint, and The GIMP
+all perform this task well, especially The GIMP.
+
+It goes without saying that a C++ compiler (gcc/g++) and math libraries
+are also needed to build SPLAT!
+
+
+Installation Instructions
+=========================
+Unpack the tar.gz file in a source code directory (such as /usr/src
+under Slackware):
+
+       cd /usr/src
+       tar xvfz splat-1.1.0.tar.gz
+
+This action will generate a subdirectory named splat, and probably
+requires 'root' privileges to do so.
+
+Next, cd to the splat directory:
+
+       cd splat
+
+Invoke the configure script to build SPLAT! and related utilities:
+
+       ./configure
+
+If you are 'root', SPLAT! and its related man page and utilities will
+be installed after the compilation process is complete.  If not, you
+will be prompted to su to 'root' and invoke the install script manually:
+
+       su root
+       Password:
+       ./install all
+       exit
+
+It's THAT simple!  :-)
+Before running SPLAT!, carefully read the documentation located under
+the splat-1.1.0/docs directory for information on the use of the program.
+
+Remember, topography data must be downloaded and SPLAT Data Files must
+be generated (using the postdownload or usgs2sdf utility) prior to using
+SPLAT!  Instructions for doing so are included in the documentation.
+
+It is important to realize that when analyzing coverage areas of
+transmitters, repeaters, or cell sites, SPLAT Data Files need to be
+available for the entire region surrounding the site(s) being analyzed
+so an accurate and complete topography map can be generated.  It is
+advised that you place all your SPLAT Data Files in a single directory,
+and then create a file in your home directory called .splat_path that
+contains the full path to that directory so SPLAT! can easily find them.
+
+Please read the README file under the utils directory for information
+on the utilities included with SPLAT!.
+
+The latest announcements and information regarding SPLAT! software is
+available at the SPLAT! Home Page:
+
+       http://www.qsl.net/kd2bd/splat.html
+
+--
+John A. Magliacane, KD2BD
+January 24, 2004
+
diff --git a/build b/build
new file mode 100755 (executable)
index 0000000..7866f7f
--- /dev/null
+++ b/build
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Simple shell script for building SPLAT! and associated utilities.
+# Written by John A. Magliacane, KD2BD May 2002 -- Last update: Jan 2004
+#
+
+build_splat()
+{
+       echo -n "Compiling SPLAT!... "
+       g++ -Wall -O3 -s -lm -lbz2 -fomit-frame-pointer itm.cpp splat.cpp -o splat
+       echo "Done!"
+}
+
+build_utils()
+{
+       cd utils
+       ./build all
+       cd ..
+}
+
+if [ $# == "0" ]; then
+       echo "Usage: build  { splat, utils, all }"
+else
+
+       if [ $1 == "splat" ]; then
+               build_splat
+       fi
+
+       if [ $1 == "utils" ]; then
+               build_utils
+       fi
+
+       if [ $1 == "all" ]; then
+               build_splat
+               build_utils
+       fi
+
+       if [ $1 != "splat" ] && [ $1 != "utils" ] && [ $1 != "all" ]; then
+               echo "Usage: build { splat, utils, all }"
+       fi
+fi
+
diff --git a/clean b/clean
new file mode 100755 (executable)
index 0000000..17660d2
--- /dev/null
+++ b/clean
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Simple script to create a clean distribution
+#
+rm splat utils/fontdata utils/citydecoder utils/usgs2sdf
+echo "Done!"
+
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..369430e
--- /dev/null
+++ b/configure
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Simple script to compile (and if you're 'root', install) SPLAT! and
+# associated utilities.  Written by John A. Magliacane, KD2BD May 2002
+#
+clear
+whoami=`whoami`
+echo "       ****************************************************************"
+echo "       **    Welcome to SPLAT! Terrain Analysis Software by KD2BD    **"
+echo "       ****************************************************************"
+echo -e "\n               Now building SPLAT! and associated utilities..."
+echo
+./build all
+if [ $whoami == "root" ]; then
+       echo -e "\nNow installing SPLAT! and associated utilities..."
+       echo
+       ./install all
+else
+       echo
+       echo "To install SPLAT! and its associated utilities, please"
+       echo "su to 'root' and execute the install script as follows:"
+       echo
+       echo -e "\t./install all"
+fi
+echo
+echo "Don't forget to read the documentation under the docs directory"
+echo "as well as the various README files in the splat and splat/utils"
+echo "directories.  Enjoy the program!  73, de John, KD2BD"
diff --git a/docs/man/docmaker b/docs/man/docmaker
new file mode 100755 (executable)
index 0000000..3891f0b
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+# This script builds the man page, pdf, and postscript
+# and text documentation from the groff source "splat.man".
+echo -n "Creating postscript file... "
+groff -e -T ps -man splat.man > ../postscript/splat.ps
+echo
+echo -n "Creating man page... "
+groff -e -T ascii -man splat.man > splat.1
+echo
+echo -n "Creating text file... "
+ul -t dumb splat.1 > ../text/splat.txt
+echo
+echo -n "Creating pdf file... "
+ps2pdf ../postscript/splat.ps ../pdf/splat.pdf
+echo
+echo "Done!"
diff --git a/docs/man/splat.1 b/docs/man/splat.1
new file mode 100644 (file)
index 0000000..c45eceb
--- /dev/null
@@ -0,0 +1,683 @@
+SPLAT!(1)                 KD2BD Software                SPLAT!(1)
+
+
+
+N\bNA\bAM\bME\bE
+       splat  -  A S\bSignal P\bPropagation, L\bLoss, A\bAnd T\bTerrain analysis
+       tool
+
+S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
+       splat [-t _\bt_\br_\ba_\bn_\bs_\bm_\bi_\bt_\bt_\be_\br_\b__\bs_\bi_\bt_\be_\b._\bq_\bt_\bh] [-r _\br_\be_\bc_\be_\bi_\bv_\be_\br_\b__\bs_\bi_\bt_\be_\b._\bq_\bt_\bh] [-c
+       _\br_\bx_\b__\ba_\bn_\bt_\be_\bn_\bn_\ba_\b__\bh_\be_\bi_\bg_\bh_\bt_\b__\bf_\bo_\br_\b__\bl_\bo_\bs_\b__\bc_\bo_\bv_\be_\br_\ba_\bg_\be_\b__\ba_\bn_\ba_\bl_\by_\bs_\bi_\bs         _\b(_\bf_\be_\be_\bt_\b)
+       _\b(_\bf_\bl_\bo_\ba_\bt_\b)]   [-L   _\br_\bx_\b__\ba_\bn_\bt_\be_\bn_\bn_\ba_\b__\bh_\be_\bi_\bg_\bh_\bt_\b__\bf_\bo_\br_\b__\bL_\bo_\bn_\bg_\bl_\be_\by_\b-_\bR_\bi_\bc_\be_\b__\bc_\bo_\bv_\be_\br_\b-
+       _\ba_\bg_\be_\b__\ba_\bn_\ba_\bl_\by_\bs_\bi_\bs  _\b(_\bf_\be_\be_\bt_\b) _\b(_\bf_\bl_\bo_\ba_\bt_\b)] [-p _\bt_\be_\br_\br_\ba_\bi_\bn_\b__\bp_\br_\bo_\bf_\bi_\bl_\be_\b._\be_\bx_\bt] [-e
+       _\be_\bl_\be_\bv_\ba_\bt_\bi_\bo_\bn_\b__\bp_\br_\bo_\bf_\bi_\bl_\be_\b._\be_\bx_\bt] [-h _\bh_\be_\bi_\bg_\bh_\bt_\b__\bp_\br_\bo_\bf_\bi_\bl_\be_\b._\be_\bx_\bt]  [-l  _\bL_\bo_\bn_\bg_\b-
+       _\bl_\be_\by_\b-_\bR_\bi_\bc_\be_\b__\bp_\br_\bo_\bf_\bi_\bl_\be_\b._\be_\bx_\bt]   [-o  _\bt_\bo_\bp_\bo_\bg_\br_\ba_\bp_\bh_\bi_\bc_\b__\bm_\ba_\bp_\b__\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\bp_\bp_\bm]
+       [-b        _\bc_\ba_\br_\bt_\bo_\bg_\br_\ba_\bp_\bh_\bi_\bc_\b__\bb_\bo_\bu_\bn_\bd_\ba_\br_\by_\b__\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\bd_\ba_\bt]         [-s
+       _\bs_\bi_\bt_\be_\b/_\bc_\bi_\bt_\by_\b__\bd_\ba_\bt_\ba_\bb_\ba_\bs_\be_\b._\bd_\ba_\bt]    [-d   _\bs_\bd_\bf_\b__\bd_\bi_\br_\be_\bc_\bt_\bo_\br_\by_\b__\bp_\ba_\bt_\bh]   [-m
+       _\be_\ba_\br_\bt_\bh_\b__\br_\ba_\bd_\bi_\bu_\bs_\b__\bm_\bu_\bl_\bt_\bi_\bp_\bl_\bi_\be_\br   _\b(_\bf_\bl_\bo_\ba_\bt_\b)]   [-R    _\bm_\ba_\bx_\bi_\bm_\bu_\bm_\b__\bc_\bo_\bv_\be_\br_\b-
+       _\ba_\bg_\be_\b__\br_\ba_\bn_\bg_\be _\b(_\bf_\bo_\br _\b-_\bc _\bo_\br _\b-_\bL_\b) _\b(_\bm_\bi_\bl_\be_\bs_\b) _\b(_\bf_\bl_\bo_\ba_\bt_\b)] [-n] [-N]
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+       S\bSP\bPL\bLA\bAT\bT!\b!  is  a  simple,  yet powerful terrain analysis tool
+       written for Unix and Linux-based workstations.  S\bSP\bPL\bLA\bAT\bT!\b!  is
+       free software.  Redistribution and/or modification is per-
+       mitted under the terms of the GNU General  Public  License
+       as  published by the Free Software Foundation, either ver-
+       sion 2 of the License or any later version.   Adoption  of
+       S\bSP\bPL\bLA\bAT\bT!\b!  source code in proprietary or closed-source appli-
+       cations is a violation of this license,  and  is  s\bst\btr\bri\bic\bct\btl\bly\by
+       forbidden.
+
+       S\bSP\bPL\bLA\bAT\bT!\b!  is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY, without even  the  implied  war-
+       ranty  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR-
+       POSE. See the GNU General Public License for more details.
+
+I\bIN\bNT\bTR\bRO\bOD\bDU\bUC\bCT\bTI\bIO\bON\bN
+       S\bSP\bPL\bLA\bAT\bT!\b!  is  a terrestrial RF propagation analysis tool for
+       the spectrum between 20  MHz  and  20  GHz,  and  provides
+       information  of interest to communication system designers
+       and site engineers.  S\bSP\bPL\bLA\bAT\bT!\b! determines great  circle  dis-
+       tances  and  bearings  between  sites,  antenna  elevation
+       angles (uptilt),  depression  angles  (downtilt),  antenna
+       height  above mean sea level, antenna height above average
+       terrain, bearings and  distances  to  known  obstructions,
+       Longley-Rice   path   loss,  and  minimum  antenna  height
+       requirements needed to establish line-of-sight  communica-
+       tion  paths absent of obstructions due to terrain.  S\bSP\bPL\bLA\bAT\bT!\b!
+       produces reports, graphs, and highly  detailed  and  care-
+       fully  annotated  topographic maps depicting line-of-sight
+       paths, path loss, and expected coverage areas of transmit-
+       ters  and repeater systems.  When performing line-of-sight
+       analysis  in  situations  where  multiple  transmitter  or
+       repeater  sites are employed, S\bSP\bPL\bLA\bAT\bT!\b! determines individual
+       and mutual areas of coverage within the network specified.
+
+       S\bSP\bPL\bLA\bAT\bT!\b!  operates  in  two  modes: _\bp_\bo_\bi_\bn_\bt_\b-_\bt_\bo_\b-_\bp_\bo_\bi_\bn_\bt _\bm_\bo_\bd_\be, and
+       _\ba_\br_\be_\ba _\bp_\br_\be_\bd_\bi_\bc_\bt_\bi_\bo_\bn _\bm_\bo_\bd_\be.  These modes may  be  invoked  using
+       either  line-of-sight  (LOS)  or  Irregular  Terrain (ITM)
+       propagation models.  True Earth, four-thirds Earth, or any
+       other  Earth radius may be specified by the user when per-
+       forming line-of-sight analysis.
+
+I\bIN\bNP\bPU\bUT\bT F\bFI\bIL\bLE\bES\bS
+       S\bSP\bPL\bLA\bAT\bT!\b! is a command-line  driven  application,  and  reads
+       input  data  through a number of data files.  Each has its
+       own format.  Some files are mandatory for successful  exe-
+       cution  of the program, while others are optional.  Manda-
+       tory files include SPLAT  Data  Files  (SDF  files),  site
+       location files (QTH files), and Longley-Rice model parame-
+       ter files (LRP files).  Optional files  include  city/site
+       location files, and cartographic boundary files.
+
+S\bSP\bPL\bLA\bAT\bT D\bDA\bAT\bTA\bA F\bFI\bIL\bLE\bES\bS
+       S\bSP\bPL\bLA\bAT\bT!\b!  imports topographic data in the form of SPLAT Data
+       Files (SDFs) that may be generated from a number of infor-
+       mation  sources.   In  the United States, SPLAT Data Files
+       are most often derived from U.S.  Geological Survey  Digi-
+       tal  Elevation  Models  (DEMs)  using the u\bus\bsg\bgs\bs2\b2s\bsd\bdf\bf utility
+       included with S\bSP\bPL\bLA\bAT\bT!\b!.  USGS Digital Elevation Models  com-
+       patible with this utility are available at no cost via the
+       Internet                  at:                  _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\be_\bd_\bc_\b-
+       _\bs_\bg_\bs_\b9_\b._\bc_\br_\b._\bu_\bs_\bg_\bs_\b._\bg_\bo_\bv_\b/_\bg_\bl_\bi_\bs_\b/_\bh_\by_\bp_\be_\br_\b/_\bg_\bu_\bi_\bd_\be_\b/_\b1_\b__\bd_\bg_\br_\b__\bd_\be_\bm_\b-
+       _\bf_\bi_\bg_\b/_\bi_\bn_\bd_\be_\bx_\b1_\bm_\b._\bh_\bt_\bm_\bl.
+
+       SPLAT Data Files contain  topographic  elevations  to  the
+       nearest  meter  above  mean  sea  level  for  1-degree  by
+       1-degree regions of the earth with a resolution  of  3-arc
+       seconds.   SDF files can be read in either standard format
+       (_\b._\bs_\bd_\bf) as generated by the u\bus\bsg\bgs\bs2\b2s\bsd\bdf\bf utility, or  in  bzip2
+       compressed  format  (_\b._\bs_\bd_\bf_\b._\bb_\bz_\b2).   Since uncompressed files
+       can be slightly faster  to  load  than  compressed  files,
+       S\bSP\bPL\bLA\bAT\bT!\b!  searches  for  the needed SDF data in uncompressed
+       format first.  If such data cannot  located,  then  S\bSP\bPL\bLA\bAT\bT!\b!
+       tries  to read the data in bzip2 compressed format.  If no
+       compressed  SDF  files  can  be  found  for   the   region
+       requested, S\bSP\bPL\bLA\bAT\bT!\b! assumes the region is over water or out-
+       side the United States, and will assign  an  elevation  of
+       sea-level to these areas.  This feature of S\bSP\bPL\bLA\bAT\bT!\b! makes it
+       possible to perform path analysis not only over land,  but
+       also between coastal areas not represented by USGS Digital
+       Elevation Model Data since they are  devoid  of  any  land
+       masses.   However, this behavior of S\bSP\bPL\bLA\bAT\bT!\b! underscores the
+       importance of having all the SDF files  required  for  the
+       region  being  analyzed  if  meaningful  results are to be
+       expected.
+
+S\bSI\bIT\bTE\bE L\bLO\bOC\bCA\bAT\bTI\bIO\bON\bN (\b(Q\bQT\bTH\bH)\b) F\bFI\bIL\bLE\bES\bS
+       S\bSP\bPL\bLA\bAT\bT!\b! imports site location  information  of  transmitter
+       and  receiver  sites  analyzed  by  the program from ASCII
+       files having a _\b._\bq_\bt_\bh  extension.   QTH  files  contain  the
+       site's  name,  the site's latitude (in degrees North), the
+       site's longitude (in degrees West), and the site's antenna
+       height above ground level (AGL).  A single line-feed char-
+       acter separates each field.  The antenna height is assumed
+       to be specified in feet unless followed by the letter _\bm or
+       the word _\bm_\be_\bt_\be_\br_\bs in either upper or lower  case.   Latitude
+       and longitude information may be expressed in either deci-
+       mal format (74.6889) or degree, minute, second (DMS)  for-
+       mat (74 41 20.0).
+
+       For  example,  a  site location file describing television
+       station WNJT, Trenton, NJ (_\bw_\bn_\bj_\bt_\b._\bq_\bt_\bh) might  read  as  fol-
+       lows:
+
+               WNJT
+               40.2833
+               74.6889
+               990.00
+
+       Each transmitter and receiver site analyzed by S\bSP\bPL\bLA\bAT\bT!\b! must
+       be represented by its own site location (QTH) file.
+
+L\bLO\bON\bNG\bGL\bLE\bEY\bY-\b-R\bRI\bIC\bCE\bE P\bPA\bAR\bRA\bAM\bME\bET\bTE\bER\bR (\b(L\bLR\bRP\bP)\b) F\bFI\bIL\bLE\bES\bS
+       S\bSP\bPL\bLA\bAT\bT!\b! imports  Longley-Rice  model  parameter  data  from
+       files  having  the  same base name as the transmitter site
+       QTH file, but carrying a _\b._\bl_\br_\bp  extension,  thus  providing
+       simple  and  accurate correlation between these associated
+       data sets.  The format for the Longley-Rice model  parame-
+       ter files is as follows (_\bw_\bn_\bj_\bt_\b._\bl_\br_\bp):
+
+               15.000  ; Earth Dielectric Constant (Relative per-
+       mittivity)
+               0.005   ; Earth Conductivity (Siemens per meter)
+               301.000 ; Atmospheric Bending Constant (N-units)
+               700.000 ; Frequency in MHz (20 MHz to 20 GHz)
+               5       ; Radio Climate (5 =  Continental  Temper-
+       ate)
+               0       ; Polarization (0 = Horizontal, 1 = Verti-
+       cal)
+               0.5     ; Fraction of  situations  (50%  of  loca-
+       tions)
+               0.5     ; Fraction of time (50% of the time)
+
+       If  an LRP file corresponding to the tx_site QTH file can-
+       not be found, S\bSP\bPL\bLA\bAT\bT!\b! scans the current  working  directory
+       for  the  file "splat.lrp".  If this file cannot be found,
+       then the default parameters listed above will be  assigned
+       by  S\bSP\bPL\bLA\bAT\bT!\b! and a corresponding "splat.lrp" file containing
+       this data will be written to the  current  working  direc-
+       tory.
+
+       Typical Earth dielectric constants and conductivity values
+       are as follows:
+
+                                  Dielectric Constant  Conductiv-
+       ity
+               Salt water       :        80                5.000
+               Good ground      :        25                0.020
+               Fresh water      :        80                0.010
+               Marshy land      :        12                0.007
+               Farmland, forest :        15                0.005
+               Average ground   :        15                0.005
+               Mountain, sand   :        13                0.002
+               City             :         5                0.001
+               Poor ground      :         4                0.001
+
+       Radio climate codes used by S\bSP\bPL\bLA\bAT\bT!\b! are as follows:
+
+               1: Equatorial (Congo)
+               2: Continental Subtropical (Sudan)
+               3: Maritime Subtropical (West coast of Africa)
+               4: Desert (Sahara)
+               5: Continental Temperate
+               6:  Maritime  Temperate,  over  land  (UK and west
+       coasts of US & EU)
+               7: Maritime Temperate, over sea
+
+       The Continental Temperate climate is common to large  land
+       masses  in  the temperate zone, such as the United States.
+       For paths shorter than 100 km, there is little  difference
+       between Continental and Maritime Temperate climates.
+
+       The  final  two  parameters in the _\b._\bl_\br_\bp file correspond to
+       the statistical  analysis  provided  by  the  Longley-Rice
+       model.   In  this example, S\bSP\bPL\bLA\bAT\bT!\b!  will return the maximum
+       path loss occurring 50% of the time (fraction of time)  in
+       50%   of  situations  (fraction  of  situations).   Use  a
+       fraction of time parameter of 0.97 for digital television,
+       0.50  for analog in the United States.  Isotropic antennas
+       are assumed.
+
+       For  further  information  on   these   parameters,   see:
+       _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\be_\bl_\bb_\be_\br_\bt_\b._\bi_\bt_\bs_\b._\bb_\bl_\bd_\br_\bd_\bo_\bc_\b._\bg_\bo_\bv_\b/_\bi_\bt_\bm_\b._\bh_\bt_\bm_\bl                 and
+       _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bs_\bo_\bf_\bt_\bw_\br_\bi_\bg_\bh_\bt_\b._\bc_\bo_\bm_\b/_\bf_\ba_\bq_\b/_\be_\bn_\bg_\bi_\bn_\be_\be_\br_\bi_\bn_\bg_\b/_\bp_\br_\bo_\bp_\b__\bl_\bo_\bn_\bg_\b-
+       _\bl_\be_\by_\b__\br_\bi_\bc_\be_\b._\bh_\bt_\bm_\bl
+
+C\bCI\bIT\bTY\bY L\bLO\bOC\bCA\bAT\bTI\bIO\bON\bN F\bFI\bIL\bLE\bES\bS
+       The  names  and locations of cities, tower sites, or other
+       points of interest may imported and be  plotted  on  topo-
+       graphic  maps  generated  by  S\bSP\bPL\bLA\bAT\bT!\b!.   S\bSP\bPL\bLA\bAT\bT!\b! imports the
+       names of cities and locations from ASCII files  containing
+       the  location's  name,  the  location's  latitude, and the
+       location's longitude.  Each field is separated by a comma.
+       Each  record is separated by a single line feed character.
+       As was the case with the _\b._\bq_\bt_\bh files, latitude  and  longi-
+       tude  information  may  be  entered  in  either decimal or
+       degree, minute, second (DMS) format.
+
+       For example (_\bc_\bi_\bt_\bi_\be_\bs_\b._\bd_\ba_\bt):
+
+               Teaneck, 40.891973, 74.014506
+               Tenafly, 40.919212, 73.955892
+               Teterboro, 40.859511, 74.058908
+               Tinton Falls, 40.279966, 74.093924
+               Toms River, 39.977777, 74.183580
+               Totowa, 40.906160, 74.223310
+               Trenton, 40.219922, 74.754665
+
+       A total of five separate city data files may  be  imported
+       at  a time.  There is no limit to the size of these files.
+       S\bSP\bPL\bLA\bAT\bT!\b! reads city data sequentially, and plots only  those
+       locations  whose positions do not conflict with previously
+       plotted locations when generating topographic maps.
+
+       City data files may be generated manually using  any  text
+       editor,  imported from other sources, or derived from data
+       available from the U.S. Census Bureau  using  the  c\bci\bit\bty\byd\bde\be-\b-
+       c\bco\bod\bde\ber\br  utility  included with S\bSP\bPL\bLA\bAT\bT!\b!.  Such data is avail-
+       able free of charge via the Internet  at:  _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bc_\be_\bn_\b-
+       _\bs_\bu_\bs_\b._\bg_\bo_\bv_\b/_\bg_\be_\bo_\b/_\bw_\bw_\bw_\b/_\bc_\bo_\bb_\b/_\bb_\bd_\by_\b__\bf_\bi_\bl_\be_\bs_\b._\bh_\bt_\bm_\bl,  and  must be in ASCII
+       format.
+
+C\bCA\bAR\bRT\bTO\bOG\bGR\bRA\bAP\bPH\bHI\bIC\bC B\bBO\bOU\bUN\bND\bDA\bAR\bRY\bY D\bDA\bAT\bTA\bA F\bFI\bIL\bLE\bES\bS
+       Cartographic boundary data may also be  imported  to  plot
+       the  boundaries  of  cities,  counties, or states on topo-
+       graphic maps generated by S\bSP\bPL\bLA\bAT\bT!\b!.  Such data  must  be  of
+       the  form  of  ARC/INFO Ungenerate (ASCII Format) Metadata
+       Cartographic Boundary Files, and are  available  from  the
+       U.S.   Census  Bureau via the Internet at: _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bc_\be_\bn_\b-
+       _\bs_\bu_\bs_\b._\bg_\bo_\bv_\b/_\bg_\be_\bo_\b/_\bw_\bw_\bw_\b/_\bc_\bo_\bb_\b/_\bc_\bo_\b2_\b0_\b0_\b0_\b._\bh_\bt_\bm_\bl_\b#_\ba_\bs_\bc_\bi_\bi and  _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bc_\be_\bn_\b-
+       _\bs_\bu_\bs_\b._\bg_\bo_\bv_\b/_\bg_\be_\bo_\b/_\bw_\bw_\bw_\b/_\bc_\bo_\bb_\b/_\bp_\bl_\b2_\b0_\b0_\b0_\b._\bh_\bt_\bm_\bl_\b#_\ba_\bs_\bc_\bi_\bi.   A  total  of five
+       separate cartographic boundary files may be imported at  a
+       time.   It  is not necessary to import state boundaries if
+       county boundaries have already been imported.
+
+P\bPR\bRO\bOG\bGR\bRA\bAM\bM O\bOP\bPE\bER\bRA\bAT\bTI\bIO\bON\bN
+       S\bSP\bPL\bLA\bAT\bT!\b! is invoked via the command-line using a  series  of
+       switches  and arguments.  Since S\bSP\bPL\bLA\bAT\bT!\b! is a CPU and memory
+       intensive application, this type  of  interface  minimizes
+       overhead,  and  also  lends itself well to scripted opera-
+       tions.  S\bSP\bPL\bLA\bAT\bT!\b!'s CPU and memory scheduling priority may be
+       adjusted through the use of the Unix n\bni\bic\bce\be command.
+
+       The number and type of switches passed to S\bSP\bPL\bLA\bAT\bT!\b! determine
+       its mode of operation and method of  output  data  genera-
+       tion.   Nearly all of S\bSP\bPL\bLA\bAT\bT!\b!'s switches may be cascaded in
+       any order on the command line when invoking the program to
+       include  all the features described by those switches when
+       performing an analysis.
+
+P\bPO\bOI\bIN\bNT\bT-\b-T\bTO\bO-\b-P\bPO\bOI\bIN\bNT\bT A\bAN\bNA\bAL\bLY\bYS\bSI\bIS\bS
+       S\bSP\bPL\bLA\bAT\bT!\b! may be used to perform line-of-sight terrain analy-
+       sis between two specified site locations.  For example:
+
+       splat -t tx_site.qth -r rx_site.qth
+
+       invokes  a terrain analysis between the transmitter speci-
+       fied in _\bt_\bx_\b__\bs_\bi_\bt_\be_\b._\bq_\bt_\bh and receiver specified in _\br_\bx_\b__\bs_\bi_\bt_\be_\b._\bq_\bt_\bh,
+       and  writes  a  S\bSP\bPL\bLA\bAT\bT!\b!  Obstruction  Report to the current
+       working directory.  The report  contains  details  of  the
+       transmitter  and  receiver sites, and identifies the loca-
+       tion of any obstructions detected during the analysis.  If
+       an  obstruction  can  be  cleared  by  raising the receive
+       antenna to a greater altitude, S\bSP\bPL\bLA\bAT\bT!\b!  will  indicate  the
+       minimum  antenna  height required for a line-of-sight path
+       to exist between the transmitter  and  receiver  locations
+       specified.   If  the  antenna must be raised a significant
+       amount, this determination may take some time.
+
+       are optional when invoking the program.  S\bSP\bPL\bLA\bAT\bT!\b!  automati-
+       cally  reads all SPLAT Data Files necessary to conduct the
+       terrain analysis between the sites specified.  By default,
+       the  location of SDF files is assumed to be in the current
+       working directory unless a ".splat_path" file  is  present
+       under the user's home directory.  If this file is present,
+       it must contain the full directory path to the location of
+       all the SDF files required by S\bSP\bPL\bLA\bAT\bT!\b! to perform its analy-
+       sis for the region containing the transmitter and receiver
+       sites  specified.   The  path  in this file must be of the
+       form of a single line of ASCII text:
+
+       /opt/splat/sdf/
+
+       and may be generated with any text  editor.   The  default
+       path  specified in the _\b$_\bH_\bO_\bM_\bE_\b/_\b._\bs_\bp_\bl_\ba_\bt_\b__\bp_\ba_\bt_\bh file may be over-
+       ridden at any time using the _\b-_\bd switch:
+
+       splat -t tx_site -r rx_site -d /cdrom/sdf/
+
+       A graph of the terrain profile between  the  receiver  and
+       transmitter  locations  as a function of distance from the
+       receiver can be generated by adding the _\b-_\bp switch:
+
+       splat -t tx_site -r rx_site -p terrain_profile.gif
+
+       S\bSP\bPL\bLA\bAT\bT!\b! invokes g\bgn\bnu\bup\bpl\blo\bot\bt when generating graphs.  The  file-
+       name  extension  specified to S\bSP\bPL\bLA\bAT\bT!\b! determines the format
+       of the graph produced.  _\b._\bg_\bi_\bf will produce a 640x480  color
+       GIF  graphic  file,  while _\b._\bp_\bs or _\b._\bp_\bo_\bs_\bt_\bs_\bc_\br_\bi_\bp_\bt will produce
+       postscript output.  Output in formats such as  PNG,  Adobe
+       Illustrator,  AutoCAD  dxf,  LaTeX,  and  many  others are
+       available.  Please consult g\bgn\bnu\bup\bpl\blo\bot\bt, and g\bgn\bnu\bup\bpl\blo\bot\bt's documen-
+       tation for details on all the supported output formats.
+
+       A graph of elevations subtended by the terrain between the
+       receiver and transmitter as a function  of  distance  from
+       the receiver can be generated by using the _\b-_\be switch:
+
+       splat -t tx_site -r rx_site -e elevation_profile.gif
+
+       The  graph produced using this switch illustrates the ele-
+       vation and depression angles resulting  from  the  terrain
+       between  the  receiver's location and the transmitter site
+       from the perspective of the receiver's location.  A second
+       trace  is  plotted  between  the  left  side  of the graph
+       (receiver's location) and the location of the transmitting
+       antenna  on  the right.  This trace illustrates the eleva-
+       tion angle required for  a  line-of-sight  path  to  exist
+       between  the  receiver  and transmitter locations.  If the
+       trace intersects the elevation profile at any point on the
+       graph,  then  this  is  an indication that a line-of-sight
+       path does not exist under the conditions  given,  and  the
+       obstructions can be clearly identified on the graph at the
+       point(s) of intersection.
+
+       A graph illustrating terrain height referenced to a  line-
+       of-sight  path between the transmitter and receiver may be
+       generated using the _\b-_\bh switch:
+
+       splat -t tx_site -r rx_site -h height_profile.gif
+
+       The Earth's curvature is  clearly  evident  when  plotting
+       height profiles.
+
+       A  graph  showing  Longley-Rice  path  loss may be plotted
+       using the _\b-_\bl switch:
+
+       splat -t tx_site -r rx_site -l path_loss_profile.gif
+
+       When performing path loss profiles, a  Longley-Rice  Model
+       Path  Loss  Report is generated by S\bSP\bPL\bLA\bAT\bT!\b! in the form of a
+       text file with a _\b._\bl_\br_\bo filename extension.  The report con-
+       tains  bearings  and distances between the transmitter and
+       receiver, as well as the Longley-Rice path loss for  vari-
+       ous  distances  between the transmitter and receiver loca-
+       tions.  The mode of propagation for points along the  path
+       are  given  as _\bL_\bi_\bn_\be_\b-_\bo_\bf_\b-_\bS_\bi_\bg_\bh_\bt, _\bS_\bi_\bn_\bg_\bl_\be _\bH_\bo_\br_\bi_\bz_\bo_\bn, _\bD_\bo_\bu_\bb_\bl_\be _\bH_\bo_\br_\bi_\b-
+       _\bz_\bo_\bn, _\bD_\bi_\bf_\bf_\br_\ba_\bc_\bt_\bi_\bo_\bn _\bD_\bo_\bm_\bi_\bn_\ba_\bn_\bt, and _\bT_\br_\bo_\bp_\bo_\bs_\bc_\ba_\bt_\bt_\be_\br _\bD_\bo_\bm_\bi_\bn_\ba_\bn_\bt.
+
+       To determine the signal-to-noise  (SNR)  ratio  at  remote
+       location  where random Johnson (thermal) noise is the pri-
+       mary limiting factor in reception:
+
+       _\bS_\bN_\bR=_\bT-_\bN_\bJ-_\bL+_\bG-_\bN_\bF
+
+       where T\bT is the ERP of the transmitter in dBW, N\bNJ\bJ is  John-
+       son  Noise  in dBW (-136 dBW for a 6 MHz TV channel), L\bL is
+       the path loss provided by S\bSP\bPL\bLA\bAT\bT!\b! in dB (as a _\bp_\bo_\bs_\bi_\bt_\bi_\bv_\be num-
+       ber),  G\bG is the receive antenna gain in dB over isotropic,
+       and N\bNF\bF is the receiver noise figure in dB.
+
+       T\bT may be computed as follows:
+
+       _\bT=_\bT_\bI+_\bG_\bT
+
+       where T\bTI\bI is actual amount of RF  power  delivered  to  the
+       transmitting  antenna  in  dBW,  G\bGT\bT  is  the  transmitting
+       antenna gain (over isotropic)  in  the  direction  of  the
+       receiver (or the horizon if the receiver is over the hori-
+       zon).
+
+       To compute how much more signal is available over the min-
+       imum  to  necessary  to achieve a specific signal-to-noise
+       ratio:
+
+       _\bS_\bi_\bg_\bn_\ba_\bl__\bM_\ba_\br_\bg_\bi_\bn=_\bS_\bN_\bR-_\bS
+
+       where S\bS is the minimum desired SNR ratio (15.5 dB for ATSC
+       DTV, 42 dB for analog NTSC television).
+
+       A  topographic map may be generated by S\bSP\bPL\bLA\bAT\bT!\b! to visualize
+       the path between the transmitter and receiver  sites  from
+       yet  another  perspective.   Topographic maps generated by
+       S\bSP\bPL\bLA\bAT\bT!\b! display elevations using a  logarithmic  grayscale,
+       with higher elevations represented through brighter shades
+       of gray.  The dynamic range of the image is scaled between
+       the highest and lowest elevations present in the map.  The
+       only exception to this is sea-level, which is  represented
+       in blue.
+
+       S\bSP\bPL\bLA\bAT\bT!\b!  generated  topographic  maps  are 24-bit TrueColor
+       Portable PixMap (PPM) images, and may be  viewed,  edited,
+       or  converted  to  other  graphic formats by popular image
+       viewing applications such as x\bxv\bv,  T\bTh\bhe\be  G\bGI\bIM\bMP\bP,  I\bIm\bma\bag\bge\beM\bMa\bag\bgi\bic\bck\bk,
+       and X\bXP\bPa\bai\bin\bnt\bt.  PNG format is highly recommended for lossless
+       compressed storage of S\bSP\bPL\bLA\bAT\bT!\b!  generated topographic output
+       files.   An excellent command-line utility capable of con-
+       verting S\bSP\bPL\bLA\bAT\bT!\b! PPM graphic files to PNG files is w\bwp\bpn\bng\bg, and
+       is                      available                      at:
+       _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bl_\bi_\bb_\bp_\bn_\bg_\b._\bo_\br_\bg_\b/_\bp_\bu_\bb_\b/_\bp_\bn_\bg_\b/_\bb_\bo_\bo_\bk_\b/_\bs_\bo_\bu_\br_\bc_\be_\bs_\b._\bh_\bt_\bm_\bl.    As   a
+       last  resort,  PPM files may be compressed using the bzip2
+       utility, and read directly by T\bTh\bhe\be  G\bGI\bIM\bMP\bP  in  this  format.
+       Topographic output is specified using the _\b-_\bo switch:
+
+       splat -t tx_site -r rx_site -o topo_map.ppm
+
+       The  _\b._\bp_\bp_\bm  extension  on the output filename is assumed by
+       S\bSP\bPL\bLA\bAT\bT!\b!, and is optional.
+
+       In this example, _\bt_\bo_\bp_\bo_\b__\bm_\ba_\bp_\b._\bp_\bp_\bm will  illustrate  the  loca-
+       tions of the transmitter and receiver sites specified.  In
+       addition, the great circle path between the two sites will
+       be  drawn  over  locations  for which an unobstructed path
+       exists to the transmitter at a  receiving  antenna  height
+       equal   to   that  of  the  receiver  site  (specified  in
+       _\br_\bx_\b__\bs_\bi_\bt_\be_\b._\bq_\bt_\bh).
+
+       It may desirable to  populate  the  topographic  map  with
+       names  and  locations  of  cities,  tower  sites, or other
+       important locations.  A city file may be passed to  S\bSP\bPL\bLA\bAT\bT!\b!
+       using the _\b-_\bs switch:
+
+       splat -t tx_site -r rx_site -s cities.dat -o topo_map
+
+       Up  to five separate city files may be passed to S\bSP\bPL\bLA\bAT\bT!\b! at
+       a time following the _\b-_\bs switch.
+
+       County and state boundaries may be added  to  the  map  by
+       specifying  up  to  five  U.S.  Census Bureau cartographic
+       boundary files using the _\b-_\bb switch:
+
+       splat -t tx_site -r rx_site -b co34_d00.dat -o topo_map
+
+       In situations where multiple transmitter sites are in use,
+       as  many as four site locations may be passed to S\bSP\bPL\bLA\bAT\bT!\b! at
+       a time for analysis:
+
+       splat -t tx_site1 tx_site2 tx_site3 tx_site4 -r rx_site -p
+       profile.gif
+
+       In  this  example,  four  separate  terrain  profiles  and
+       obstruction reports will be generated by S\bSP\bPL\bLA\bAT\bT!\b!.  A single
+       topographic  map can be specified using the _\b-_\bo switch, and
+       line-of-sight  paths  between  each  transmitter  and  the
+       receiver  site indicated will be produced on the map, each
+       in its own color.  The path between the first  transmitter
+       specified  to  the  receiver  will  be  in green, the path
+       between the second transmitter and the receiver will be in
+       cyan,  the  path  between  the  third  transmitter and the
+       receiver will be in  violet,  and  the  path  between  the
+       fourth transmitter and the receiver will be in sienna.
+
+D\bDE\bET\bTE\bER\bRM\bMI\bIN\bNI\bIN\bNG\bG R\bRE\bEG\bGI\bIO\bON\bNA\bAL\bL C\bCO\bOV\bVE\bER\bRA\bAG\bGE\bE
+       S\bSP\bPL\bLA\bAT\bT!\b! can analyze a transmitter or repeater site, or net-
+       work of sites, and predict the regional coverage for  each
+       site specified.  In this mode, S\bSP\bPL\bLA\bAT\bT!\b! can generate a topo-
+       graphic map displaying the geometric line-of-sight  cover-
+       age  area of the sites based on the location of each site,
+       and the height of receive antenna wishing  to  communicate
+       with the site in question.  S\bSP\bPL\bLA\bAT\bT!\b! switches from point-to-
+       point analysis mode to area prediction mode  when  the  _\b-_\bc
+       switch is invoked as follows:
+
+       splat  -t tx_site -c 30.0 -s cities.dat -b co34_d00.dat -o
+       tx_coverage
+
+       In this example, S\bSP\bPL\bLA\bAT\bT!\b! generates a topographic map called
+       _\bt_\bx_\b__\bc_\bo_\bv_\be_\br_\ba_\bg_\be_\b._\bp_\bp_\bm  that  illustrates  the predicted line-of-
+       sight regional coverage of _\bt_\bx_\b__\bs_\bi_\bt_\be to receiving  locations
+       having  antennas  30.0 feet above ground level (AGL).  The
+       contents of _\bc_\bi_\bt_\bi_\be_\bs_\b._\bd_\ba_\bt are plotted on the map, as are  the
+       cartographic    boundaries    contained    in   the   file
+       _\bc_\bo_\b3_\b4_\b__\bd_\b0_\b0_\b._\bd_\ba_\bt.
+
+       When plotting line-of-sight paths and  areas  of  regional
+       coverage,  S\bSP\bPL\bLA\bAT\bT!\b!  by  default  does  not  account for the
+       effects of atmospheric bending.   However,  this  behavior
+       may  be modified by using the Earth radius multiplier (_\b-_\bm)
+       switch:
+
+       splat -t wnjt -c 30.0 -m  1.333  -s  cities.dat  -b  coun-
+       ties.dat -o map.ppm
+
+       An  earth  radius multiplier  of 1.333 instructs S\bSP\bPL\bLA\bAT\bT!\b! to
+       use the "four-thirds earth" model for line-of-sight propa-
+       gation  analysis.  Any appropriate earth radius multiplier
+       may be selected by the user.
+
+       When invoked in area prediction mode, S\bSP\bPL\bLA\bAT\bT!\b!  generates  a
+       site  report  for  each  station  analyzed.   S\bSP\bPL\bLA\bAT\bT!\b!  site
+       reports contain details of the site's geographic location,
+       its  height  above  mean  sea  level, the antenna's height
+       above mean sea level, the antenna's height  above  average
+       terrain,  and the height of the average terrain calculated
+       in the directions of 0, 45, 90, 135, 180,  225,  270,  and
+       315 degrees azimuth.
+
+       If  the  _\b-_\bc  switch is replaced by a _\b-_\bL switch, a Longley-
+       Rice path loss map for a transmitter site  may  be  gener-
+       ated:
+
+       splat  -t tx_site -L 30.0 -s cities.dat -b co34_d00.dat -o
+       path_loss_map
+
+       In this mode, S\bSP\bPL\bLA\bAT\bT!\b! generates a  multi-color  map  illus-
+       trating  expected  signal levels (path loss) in areas sur-
+       rounding the transmitter site.  A legend at the bottom  of
+       the  map  correlates  each color with a specific path loss
+       level in decibels.  Since Longley-Rice area prediction map
+       generation  is quite CPU intensive, provision for limiting
+       the analysis range is provided  by  the  _\b-_\bR  switch.   The
+       argument  must  be  given in miles.  If a range wider than
+       the generated topographic map is  specified,  S\bSP\bPL\bLA\bAT\bT!\b!  will
+       perform  Longley-Rice  path  loss calculations between all
+       four corners of the area prediction map.
+
+D\bDE\bET\bTE\bER\bRM\bMI\bIN\bNI\bIN\bNG\bG M\bMU\bUL\bLT\bTI\bIP\bPL\bLE\bE R\bRE\bEG\bGI\bIO\bON\bNS\bS O\bOF\bF C\bCO\bOV\bVE\bER\bRA\bAG\bGE\bE
+       S\bSP\bPL\bLA\bAT\bT!\b! can also display line-of-sight coverage  areas  for
+       as  many  as  four  separate transmitter sites on a common
+       topographic map.  For example:
+
+       splat -t site1 site2 site3 site4 -c 30.0 -o network.ppm
+
+       plots the regional line-of-sight coverage of site1, site2,
+       site3,  and  site4 based on a receive antenna located 30.0
+       feet above ground level.  A topographic map is then  writ-
+       ten  to  the file _\bn_\be_\bt_\bw_\bo_\br_\bk_\b._\bp_\bp_\bm.  The line-of-sight coverage
+       area of the transmitters are plotted  as  follows  in  the
+       colors  indicated (along with their corresponding RGB val-
+       ues in decimal):
+
+           site1: Green (0,255,0)
+           site2: Cyan (0,255,255)
+           site3: Medium Violet (147,112,219)
+           site4: Sienna 1 (255,130,71)
+
+           site1 + site2: Yellow (255,255,0)
+           site1 + site3: Pink (255,192,203)
+           site1 + site4: Green Yellow (173,255,47)
+           site2 + site3: Orange (255,165,0)
+           site2 + site4: Dark Sea Green 1 (193,255,193)
+           site3 + site4: Dark Turquoise (0,206,209)
+
+           site1 + site2 + site3: Dark Green (0,100,0)
+           site1 + site2 + site4: Blanched Almond (255,235,205)
+           site1 + site3 + site4: Medium Spring Green (0,250,154)
+           site2 + site3 + site4: Tan (210,180,140)
+
+           site1 + site2 + site3 + site4: Gold2 (238,201,0)
+
+       If  separate _\b._\bq_\bt_\bh files are generated, each representing a
+       common site location but a  different  antenna  height,  a
+       single  topographic map illustrating the regional coverage
+       from as many as four separate locations on a single  tower
+       may be generated by S\bSP\bPL\bLA\bAT\bT!\b!.
+
+T\bTO\bOP\bPO\bOG\bGR\bRA\bAP\bPH\bHI\bIC\bC M\bMA\bAP\bP G\bGE\bEN\bNE\bER\bRA\bAT\bTI\bIO\bON\bN
+       In  certain  situations, it may be desirable to generate a
+       topographic map of  a  region  without  plotting  coverage
+       areas,  line-of-sight  paths,  or  generating  obstruction
+       reports.  There are several ways of doing  this.   If  one
+       wishes  to  generate  a  topographic  map illustrating the
+       location of a transmitter and receiver site along  with  a
+       brief  text  report describing the locations and distances
+       between the sites, the _\b-_\bn switch should be invoked as fol-
+       lows:
+
+       splat -t tx_site -r rx_site -n -o topo_map.ppm
+
+       If no text report is desired, then the _\b-_\bN switch is used:
+
+       splat -t tx_site -r rx_site -N -o topo_map.ppm
+
+       If  the  _\b-_\bo  switch  and  output filename are omitted when
+       using either the _\b-_\bn or _\b-_\bN switches, output is written to a
+       file  named  _\bm_\ba_\bp_\b._\bp_\bp_\bm  in  the current working directory by
+       default.
+
+D\bDE\bET\bTE\bER\bRM\bMI\bIN\bNA\bAT\bTI\bIO\bON\bN O\bOF\bF A\bAN\bNT\bTE\bEN\bNN\bNA\bA H\bHE\bEI\bIG\bGH\bHT\bT A\bAB\bBO\bOV\bVE\bE A\bAV\bVE\bER\bRA\bAG\bGE\bE T\bTE\bER\bRR\bRA\bAI\bIN\bN
+       S\bSP\bPL\bLA\bAT\bT!\b! determines antenna  height  above  average  terrain
+       (HAAT)  according to the procedure defined by Federal Com-
+       munications Commission Part 73.313(d).  According to  this
+       definition, terrain elevations along eight radials between
+       2 and 10 miles (3 and 16 kilometers) from the  site  being
+       analyzed  are  sampled and averaged for each 45 degrees of
+       azimuth starting with True North.  If one or more  radials
+       lie  entirely  over water, or over land outside the United
+       States (areas for which no USGS topography data is  avail-
+       able), then those radials are omitted from the calculation
+       of average terrain.  If part of a radial  extends  over  a
+       body of water or over land outside the United States, then
+       only that part of the radial lying over United States land
+       is used in the determination of average terrain.
+
+       When  performing  point-to-point  terrain analysis, S\bSP\bPL\bLA\bAT\bT!\b!
+       determines the antenna height above average  terrain  only
+       if  enough topographic data has already been loaded by the
+       program to perform the point-to-point analysis.   In  most
+       cases, this will be true, unless the site in question does
+       not lie within 10 miles of the boundary of the  topography
+       data in memory.
+
+       When  performing area prediction analysis, enough topogra-
+       phy data is normally loaded by S\bSP\bPL\bLA\bAT\bT!\b! to  perform  average
+       terrain  calculations.  Under such conditions, S\bSP\bPL\bLA\bAT\bT!\b! will
+       provide the antenna height above average terrain  as  well
+       as  the  average terrain above mean sea level for azimuths
+       of 0, 45, 90, 135, 180, 225, 270,  and  315  degrees,  and
+       include such information in the site report generated.  If
+       one or more of the eight radials surveyed fall over  water
+       or  land outside the United States, S\bSP\bPL\bLA\bAT\bT!\b! reports _\bN_\bo _\bT_\be_\br_\b-
+       _\br_\ba_\bi_\bn for those radial paths.
+
+S\bSE\bET\bTT\bTI\bIN\bNG\bG T\bTH\bHE\bE M\bMA\bAX\bXI\bIM\bMU\bUM\bM S\bSI\bIZ\bZE\bE O\bOF\bF A\bAN\bN A\bAN\bNA\bAL\bLY\bYS\bSI\bIS\bS R\bRE\bEG\bGI\bIO\bON\bN
+       S\bSP\bPL\bLA\bAT\bT!\b! reads SDF files into a series of memory "slots"  as
+       required within the structure of the program.  Each "slot"
+       holds one SDF file.  Each SDF file represents a one degree
+       by  one  degree  region  of  terrain.   A _\b#_\bd_\be_\bf_\bi_\bn_\be _\bM_\bA_\bX_\bS_\bL_\bO_\bT_\bS
+       statement in the first several lines of _\bs_\bp_\bl_\ba_\bt_\b._\bc_\bp_\bp sets the
+       maximum  number  of "slots" available for topography data.
+       It also sets the maximum size of the topographic maps gen-
+       erated  by  S\bSP\bPL\bLA\bAT\bT!\b!.   MAXSLOTS is set to 9 by default.  If
+       S\bSP\bPL\bLA\bAT\bT!\b! produces a segmentation fault on start-up with this
+       default,  it  is  an indication that not enough RAM and/or
+       virtual memory (swap space) are available  to  run  S\bSP\bPL\bLA\bAT\bT!\b!
+       with  this number of MAXSLOTS.  In this case, MAXSLOTS may
+       be reduced to 4, although this will greatly limit the max-
+       imum  region  S\bSP\bPL\bLA\bAT\bT!\b!  will  be  able  to  analyze.  If 118
+       megabytes or more of total memory (swap space plus RAM) is
+       available,  then  MAXSLOTS  may  be increased to 16.  This
+       will permit operation over a 4-degree by 4-degree  region,
+       which  is  sufficient for single antenna heights in excess
+       of 10,000 feet above mean  sea  level,  or  point-to-point
+       distances of over 1000 miles.
+
+A\bAD\bDD\bDI\bIT\bTI\bIO\bON\bNA\bAL\bL I\bIN\bNF\bFO\bOR\bRM\bMA\bAT\bTI\bIO\bON\bN
+       Invoking S\bSP\bPL\bLA\bAT\bT!\b! without any arguments will display all the
+       command-line options available with the program along with
+       a brief summary of each.
+
+       The  latest news and information regarding S\bSP\bPL\bLA\bAT\bT!\b! software
+       is available through the official S\bSP\bPL\bLA\bAT\bT!\b! software web page
+       located at: _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bq_\bs_\bl_\b._\bn_\be_\bt_\b/_\bk_\bd_\b2_\bb_\bd_\b/_\bs_\bp_\bl_\ba_\bt_\b._\bh_\bt_\bm_\bl.
+
+F\bFI\bIL\bLE\bES\bS
+       $HOME/.splat_path
+              User-generated  file containing the default path to
+              the directory containing the SDF data files.
+
+       splat.lrp
+              Default Longley-Rice model parameters.
+
+A\bAU\bUT\bTH\bHO\bOR\bRS\bS
+       John A. Magliacane, KD2BD <_\bk_\bd_\b2_\bb_\bd_\b@_\ba_\bm_\bs_\ba_\bt_\b._\bo_\br_\bg>
+              Creator, Lead Developer
+
+       Doug McDonald <_\bm_\bc_\bd_\bo_\bn_\ba_\bl_\bd_\b@_\bs_\bc_\bs_\b._\bu_\bi_\bu_\bc_\b._\be_\bd_\bu>
+              Longley-Rice Model integration
+
+
+
+KD2BD Software           20 January 2004                SPLAT!(1)
diff --git a/docs/man/splat.man b/docs/man/splat.man
new file mode 100644 (file)
index 0000000..b4af60b
--- /dev/null
@@ -0,0 +1,597 @@
+.TH SPLAT! 1 "20 January 2004" "KD2BD Software" "KD2BD Software"
+.SH NAME
+splat \- A \fBS\fPignal \fBP\fPropagation, \fBL\fPoss, \fBA\fPnd \fBT\fPerrain analysis tool
+.SH SYNOPSIS
+splat [-t \fItransmitter_site.qth\fP]
+[-r \fIreceiver_site.qth\fP]
+[-c \fIrx_antenna_height_for_los_coverage_analysis (feet) (float)\fP]
+[-L \fIrx_antenna_height_for_Longley-Rice_coverage_analysis (feet) (float)\fP]
+[-p \fIterrain_profile.ext\fP]
+[-e \fIelevation_profile.ext\fP]
+[-h \fIheight_profile.ext\fP]
+[-l \fILongley-Rice_profile.ext\fP]
+[-o \fItopographic_map_filename.ppm\fP]
+[-b \fIcartographic_boundary_filename.dat\fP]
+[-s \fIsite/city_database.dat\fP]
+[-d \fIsdf_directory_path\fP]
+[-m \fIearth_radius_multiplier (float)\fP]
+[-R \fImaximum_coverage_range (for -c or -L) (miles) (float)\fP] 
+[-n]
+[-N]
+.SH DESCRIPTION
+\fBSPLAT!\fP is a simple, yet powerful terrain analysis tool written
+for Unix and Linux-based workstations. \fBSPLAT!\fP is free software.
+Redistribution and/or modification is permitted under the terms of the
+GNU General Public License as published by the Free Software Foundation,
+either version 2 of the License or any later version.  Adoption of
+\fBSPLAT!\fP source code in proprietary or closed-source applications
+is a violation of this license, and is \fBstrictly\fP forbidden. 
+
+\fBSPLAT!\fP is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+.SH INTRODUCTION
+\fBSPLAT!\fP is a terrestrial RF propagation analysis tool for the
+spectrum between 20 MHz and 20 GHz, and provides information of
+interest to communication system designers and site engineers.
+\fBSPLAT!\fP determines great circle distances and bearings between
+sites, antenna elevation angles (uptilt), depression angles
+(downtilt), antenna height above mean sea level, antenna height
+above average terrain, bearings and distances to known obstructions,
+Longley-Rice path loss, and minimum antenna height requirements
+needed to establish line-of-sight communication paths absent of
+obstructions due to terrain.  \fBSPLAT!\fP produces reports, graphs,
+and highly detailed and carefully annotated topographic maps depicting
+line-of-sight paths, path loss, and expected coverage areas of
+transmitters and repeater systems.  When performing line-of-sight
+analysis in situations where multiple transmitter or repeater sites
+are employed, \fBSPLAT!\fP determines individual and mutual areas
+of coverage within the network specified.
+
+\fBSPLAT!\fP operates in two modes: \fIpoint-to-point mode\fP, and
+\fIarea prediction mode\fP.  These modes may be invoked using either
+line-of-sight (LOS) or Irregular Terrain (ITM) propagation models.
+True Earth, four-thirds Earth, or any other Earth radius may be
+specified by the user when performing line-of-sight analysis.
+.SH INPUT FILES
+\fBSPLAT!\fP is a command-line driven application, and reads input
+data through a number of data files.  Each has its own format.  Some
+files are mandatory for successful execution of the program, while
+others are optional.  Mandatory files include SPLAT Data Files (SDF
+files), site location files (QTH files), and Longley-Rice model
+parameter files (LRP files).  Optional files include city/site
+location files, and cartographic boundary files.
+.SH SPLAT DATA FILES
+\fBSPLAT!\fP imports topographic data in the form of SPLAT Data Files
+(SDFs) that may be generated from a number of information sources.  In
+the United States, SPLAT Data Files are most often derived from U.S.
+Geological Survey Digital Elevation Models (DEMs) using the \fBusgs2sdf\fP
+utility included with \fBSPLAT!\fP.  USGS Digital Elevation Models
+compatible with this utility are available at no cost via the Internet at:
+\fIhttp://edcsgs9.cr.usgs.gov/glis/hyper/guide/1_dgr_demfig/index1m.html\fP.
+
+SPLAT Data Files contain topographic elevations to the nearest meter
+above mean sea level for 1-degree by 1-degree regions of the earth with
+a resolution of 3-arc seconds.  SDF files can be read in either standard
+format (\fI.sdf\fP) as generated by the \fBusgs2sdf\fP utility, or in
+bzip2 compressed format (\fI.sdf.bz2\fP).  Since uncompressed files can
+be slightly faster to load than compressed files, \fBSPLAT!\fP searches
+for the needed SDF data in uncompressed format first.  If such data cannot
+located, then \fBSPLAT!\fP tries to read the data in bzip2 compressed
+format.  If no compressed SDF files can be found for the region requested,
+\fBSPLAT!\fP assumes the region is over water or outside the United States,
+and will assign an elevation of sea-level to these areas.  This feature
+of \fBSPLAT!\fP makes it possible to perform path analysis not only over
+land, but also between coastal areas not represented by USGS Digital
+Elevation Model Data since they are devoid of any land masses.  However,
+this behavior of \fBSPLAT!\fP underscores the importance of having all
+the SDF files required for the region being analyzed if meaningful
+results are to be expected.
+.SH SITE LOCATION (QTH) FILES
+\fBSPLAT!\fP imports site location information of transmitter and receiver
+sites analyzed by the program from ASCII files having a \fI.qth\fP extension.
+QTH files contain the site's name, the site's latitude (in degrees North),
+the site's longitude (in degrees West), and the site's antenna height
+above ground level (AGL).  A single line-feed character separates each
+field.  The antenna height is assumed to be specified in feet unless
+followed by the letter \fIm\fP or the word \fImeters\fP in either upper
+or lower case.  Latitude and longitude information may be expressed in
+either decimal format (74.6889) or degree, minute, second (DMS)
+format (74 41 20.0).
+
+For example, a site location file describing television station WNJT,
+Trenton, NJ (\fIwnjt.qth\fP) might read as follows:
+\fC
+        WNJT
+        40.2833
+        74.6889
+        990.00
+\fR
+Each transmitter and receiver site analyzed by \fBSPLAT!\fP must be
+represented by its own site location (QTH) file.
+.SH LONGLEY-RICE PARAMETER (LRP) FILES
+\fBSPLAT!\fP imports Longley-Rice model parameter data from files having
+the same base name as the transmitter site QTH file, but carrying a \fI.lrp\fP
+extension, thus providing simple and accurate correlation between these
+associated data sets.  The format for the Longley-Rice model parameter
+files is as follows (\fIwnjt.lrp\fP):
+\fC
+        15.000  ; Earth Dielectric Constant (Relative permittivity)
+        0.005   ; Earth Conductivity (Siemens per meter)
+        301.000 ; Atmospheric Bending Constant (N-units)
+        700.000 ; Frequency in MHz (20 MHz to 20 GHz)
+        5       ; Radio Climate (5 = Continental Temperate)
+        0       ; Polarization (0 = Horizontal, 1 = Vertical)
+        0.5     ; Fraction of situations (50% of locations)
+        0.5     ; Fraction of time (50% of the time)
+\fR
+If an LRP file corresponding to the tx_site QTH file cannot
+be found, \fBSPLAT!\fP scans the current working directory for
+the file "splat.lrp".  If this file cannot be found, then the default
+parameters listed above will be assigned by \fBSPLAT!\fP and a
+corresponding "splat.lrp" file containing this data will be written
+to the current working directory.
+
+Typical Earth dielectric constants and conductivity values are as
+follows:
+\fC
+                           Dielectric Constant  Conductivity
+        Salt water       :        80                5.000
+        Good ground      :        25                0.020
+        Fresh water      :        80                0.010
+        Marshy land      :        12                0.007
+        Farmland, forest :        15                0.005
+        Average ground   :        15                0.005
+        Mountain, sand   :        13                0.002
+        City             :         5                0.001
+        Poor ground      :         4                0.001
+\fR
+Radio climate codes used by \fBSPLAT!\fP are as follows:
+\fC
+        1: Equatorial (Congo)
+        2: Continental Subtropical (Sudan)
+        3: Maritime Subtropical (West coast of Africa)
+        4: Desert (Sahara)
+        5: Continental Temperate
+        6: Maritime Temperate, over land (UK and west coasts of US & EU)
+        7: Maritime Temperate, over sea
+\fR
+The Continental Temperate climate is common to large land masses in
+the temperate zone, such as the United States.  For paths shorter than
+100 km, there is little difference between Continental and Maritime
+Temperate climates.
+
+The final two parameters in the \fI.lrp\fP file correspond to the statistical
+analysis provided by the Longley-Rice model.  In this example, \fBSPLAT!\fP
+will return the maximum path loss occurring 50% of the time (fraction
+of time) in 50% of situations (fraction of situations).  Use a fraction
+of time parameter of 0.97 for digital television, 0.50 for analog in the
+United States.  Isotropic antennas are assumed.
+
+For further information on these parameters, see:
+\fIhttp://elbert.its.bldrdoc.gov/itm.html\fP and
+\fIhttp://www.softwright.com/faq/engineering/prop_longley_rice.html\fP
+.SH CITY LOCATION FILES
+The names and locations of cities, tower sites, or other points of interest
+may imported and be plotted on topographic maps generated by \fBSPLAT!\fP.
+\fBSPLAT!\fP imports the names of cities and locations from ASCII files
+containing the location's name, the location's latitude, and the location's
+longitude.  Each field is separated by a comma.  Each record is separated
+by a single line feed character.  As was the case with the \fI.qth\fP
+files, latitude and longitude information may be entered in either
+decimal or degree, minute, second (DMS) format.
+
+For example (\fIcities.dat\fP):
+\fC
+        Teaneck, 40.891973, 74.014506
+        Tenafly, 40.919212, 73.955892
+        Teterboro, 40.859511, 74.058908
+        Tinton Falls, 40.279966, 74.093924
+        Toms River, 39.977777, 74.183580
+        Totowa, 40.906160, 74.223310
+        Trenton, 40.219922, 74.754665
+\fR
+A total of five separate city data files may be imported at a time.
+There is no limit to the size of these files.  \fBSPLAT!\fP reads city
+data sequentially, and plots only those locations whose positions do
+not conflict with previously plotted locations when generating
+topographic maps.
+
+City data files may be generated manually using any text editor,
+imported from other sources, or derived from data available from the
+U.S. Census Bureau using the \fBcitydecoder\fP utility included with
+\fBSPLAT!\fP.  Such data is available free of charge via the Internet
+at: \fIhttp://www.census.gov/geo/www/cob/bdy_files.html\fP, and must
+be in ASCII format.
+.SH CARTOGRAPHIC BOUNDARY DATA FILES
+Cartographic boundary data may also be imported to plot the boundaries of
+cities, counties, or states on topographic maps generated by \fBSPLAT!\fP.
+Such data must be of the form of ARC/INFO Ungenerate (ASCII Format)
+Metadata Cartographic Boundary Files, and are available from the U.S.
+Census Bureau via the Internet at:
+\fIhttp://www.census.gov/geo/www/cob/co2000.html#ascii\fP and
+\fIhttp://www.census.gov/geo/www/cob/pl2000.html#ascii\fP.  A total of
+five separate cartographic boundary files may be imported at a time.
+It is not necessary to import state boundaries if county boundaries
+have already been imported.
+.SH PROGRAM OPERATION
+\fBSPLAT!\fP is invoked via the command-line using a series of switches
+and arguments.  Since \fBSPLAT!\fP is a CPU and memory intensive application,
+this type of interface minimizes overhead, and also lends itself well to
+scripted operations.  \fBSPLAT!\fP's CPU and memory scheduling priority
+may be adjusted through the use of the Unix \fBnice\fP command.
+
+The number and type of switches passed to \fBSPLAT!\fP determine its
+mode of operation and method of output data generation.  Nearly all
+of \fBSPLAT!\fP's switches may be cascaded in any order on the command
+line when invoking the program to include all the features described
+by those switches when performing an analysis.
+.SH POINT-TO-POINT ANALYSIS
+\fBSPLAT!\fP may be used to perform line-of-sight terrain analysis
+between two specified site locations.  For example:
+
+\fCsplat -t tx_site.qth -r rx_site.qth\fR
+
+invokes a terrain analysis between the transmitter specified
+in \fItx_site.qth\fP and receiver specified in \fIrx_site.qth\fP,
+and writes a \fBSPLAT!\fP Obstruction Report to the current working
+directory.  The report contains details of the transmitter and
+receiver sites, and identifies the location of any obstructions
+detected during the analysis.  If an obstruction can be cleared
+by raising the receive antenna to a greater altitude, \fBSPLAT!\fP
+will indicate the minimum antenna height required for a line-of-sight
+path to exist between the transmitter and receiver locations specified.
+If the antenna must be raised a significant amount, this determination
+may take some time.
+
+\fI.qth\fP extensions are assumed by \fBSPLAT!\fP for QTH files, and
+are optional when invoking the program.  \fBSPLAT!\fP automatically
+reads all SPLAT Data Files necessary to conduct the terrain analysis
+between the sites specified.  By default, the location of SDF files
+is assumed to be in the current working directory unless a
+".splat_path" file is present under the user's home directory.
+If this file is present, it must contain the full directory path to
+the location of all the SDF files required by \fBSPLAT!\fP to perform
+its analysis for the region containing the transmitter and receiver
+sites specified.  The path in this file must be of the form of a
+single line of ASCII text:
+
+\fC/opt/splat/sdf/\fR
+
+and may be generated with any text editor.  The default path specified
+in the \fI$HOME/.splat_path\fP file may be overridden at any time using
+the \fI-d\fP switch:
+
+\fCsplat -t tx_site -r rx_site -d /cdrom/sdf/\fR
+
+A graph of the terrain profile between the receiver and transmitter
+locations as a function of distance from the receiver can be generated
+by adding the \fI-p\fP switch:
+
+\fCsplat -t tx_site -r rx_site -p terrain_profile.gif\fR
+
+\fBSPLAT!\fP invokes \fBgnuplot\fP when generating graphs.  The filename
+extension specified to \fBSPLAT!\fP determines the format of the graph
+produced.  \fI.gif\fP will produce a 640x480 color GIF graphic file,
+while \fI.ps\fP or \fI.postscript\fP will produce postscript output.
+Output in formats such as PNG, Adobe Illustrator, AutoCAD dxf, LaTeX,
+and many others are available.  Please consult \fBgnuplot\fP, and
+\fBgnuplot\fP's documentation for details on all the supported
+output formats.
+
+A graph of elevations subtended by the terrain between the receiver and
+transmitter as a function of distance from the receiver can be generated
+by using the \fI-e\fP switch:
+
+\fCsplat -t tx_site -r rx_site -e elevation_profile.gif\fR
+
+The graph produced using this switch illustrates the elevation and
+depression angles resulting from the terrain between the receiver's
+location and the transmitter site from the perspective of the receiver's
+location.  A second trace is plotted between the left side of the graph
+(receiver's location) and the location of the transmitting antenna on
+the right.  This trace illustrates the elevation angle required for a
+line-of-sight path to exist between the receiver and transmitter
+locations.  If the trace intersects the elevation profile at any point
+on the graph, then this is an indication that a line-of-sight path
+does not exist under the conditions given, and the obstructions can
+be clearly identified on the graph at the point(s) of intersection.
+
+A graph illustrating terrain height referenced to a line-of-sight
+path between the transmitter and receiver may be generated using
+the \fI-h\fP switch:
+
+\fCsplat -t tx_site -r rx_site -h height_profile.gif\fR
+
+The Earth's curvature is clearly evident when plotting height profiles.
+
+A graph showing Longley-Rice path loss may be plotted using the
+\fI-l\fP switch:
+
+\fCsplat -t tx_site -r rx_site -l path_loss_profile.gif\fR
+
+When performing path loss profiles, a Longley-Rice Model Path Loss
+Report is generated by \fBSPLAT!\fP in the form of a text file with
+a \fI.lro\fP filename extension.  The report contains bearings and
+distances between the transmitter and receiver, as well as the
+Longley-Rice path loss for various distances between the transmitter
+and receiver locations.  The mode of propagation for points along the
+path are given as \fILine-of-Sight\fP, \fISingle Horizon\fP, \fIDouble
+Horizon\fP, \fIDiffraction Dominant\fP, and \fITroposcatter Dominant\fP.
+
+To determine the signal-to-noise (SNR) ratio at remote location
+where random Johnson (thermal) noise is the primary limiting
+factor in reception:
+
+.EQ
+SNR = T - NJ - L + G - NF
+.EN
+
+where \fBT\fP is the ERP of the transmitter in dBW, \fBNJ\fP is
+Johnson Noise in dBW (-136 dBW for a 6 MHz TV channel), \fBL\fP
+is the path loss provided by \fBSPLAT!\fP in dB (as a \fIpositive\fP
+number), \fBG\fP is the receive antenna gain in dB over isotropic,
+and \fBNF\fP is the receiver noise figure in dB.
+
+\fBT\fP may be computed as follows:
+
+.EQ
+T = TI + GT
+.EN
+
+where \fBTI\fP is actual amount of RF power delivered to the transmitting
+antenna in dBW, \fBGT\fP is the transmitting antenna gain (over isotropic)
+in the direction of the receiver (or the horizon if the receiver is over
+the horizon).
+
+To compute how much more signal is available over the minimum to
+necessary to achieve a specific signal-to-noise ratio:
+
+.EQ
+Signal_Margin = SNR - S
+.EN
+
+where \fBS\fP is the minimum desired SNR ratio (15.5 dB for
+ATSC DTV, 42 dB for analog NTSC television).
+
+A topographic map may be generated by \fBSPLAT!\fP to visualize the
+path between the transmitter and receiver sites from yet another
+perspective.  Topographic maps generated by \fBSPLAT!\fP display
+elevations using a logarithmic grayscale, with higher elevations
+represented through brighter shades of gray.  The dynamic range of
+the image is scaled between the highest and lowest elevations present
+in the map.  The only exception to this is sea-level, which is
+represented in blue.
+
+\fBSPLAT!\fP generated topographic maps are 24-bit TrueColor Portable
+PixMap (PPM) images, and may be viewed, edited, or converted to other
+graphic formats by popular image viewing applications such as \fBxv\fP,
+\fBThe GIMP\fP, \fBImageMagick\fP, and \fBXPaint\fP.  PNG format is
+highly recommended for lossless compressed storage of \fBSPLAT!\fP
+generated topographic output files.  An excellent command-line utility
+capable of converting \fBSPLAT!\fP PPM graphic files to PNG files is
+\fBwpng\fP, and is available
+at: \fIhttp://www.libpng.org/pub/png/book/sources.html\fP.  As a last
+resort, PPM files may be compressed using the bzip2 utility, and read
+directly by \fBThe GIMP\fP in this format.  Topographic output
+is specified using the \fI-o\fP switch:
+
+\fCsplat -t tx_site -r rx_site -o topo_map.ppm\fR
+
+The \fI.ppm\fP extension on the output filename is assumed by
+\fBSPLAT!\fP, and is optional.
+
+In this example, \fItopo_map.ppm\fP will illustrate the locations of the
+transmitter and receiver sites specified.  In addition, the great circle
+path between the two sites will be drawn over locations for which an
+unobstructed path exists to the transmitter at a receiving antenna
+height equal to that of the receiver site (specified in \fIrx_site.qth\fP).
+
+It may desirable to populate the topographic map with names and locations
+of cities, tower sites, or other important locations.  A city file may be
+passed to \fBSPLAT!\fP using the \fI-s\fP switch:
+
+\fCsplat -t tx_site -r rx_site -s cities.dat -o topo_map\fR
+
+Up to five separate city files may be passed to \fBSPLAT!\fP at a time
+following the \fI-s\fP switch.
+
+County and state boundaries may be added to the map by specifying up
+to five U.S. Census Bureau cartographic boundary files using the \fI-b\fP
+switch:
+
+\fCsplat -t tx_site -r rx_site -b co34_d00.dat -o topo_map\fR
+
+In situations where multiple transmitter sites are in use, as many as
+four site locations may be passed to \fBSPLAT!\fP at a time for analysis:
+
+\fCsplat -t tx_site1 tx_site2 tx_site3 tx_site4 -r rx_site -p profile.gif\fR
+
+In this example, four separate terrain profiles and obstruction reports
+will be generated by \fBSPLAT!\fP.  A single topographic map can be
+specified using the \fI-o\fP switch, and line-of-sight paths between
+each transmitter and the receiver site indicated will be produced on
+the map, each in its own color.  The path between the first transmitter
+specified to the receiver will be in green, the path between the
+second transmitter and the receiver will be in cyan, the path between
+the third transmitter and the receiver will be in violet, and the
+path between the fourth transmitter and the receiver will be in sienna. 
+.SH DETERMINING REGIONAL COVERAGE
+\fBSPLAT!\fP can analyze a transmitter or repeater site, or network
+of sites, and predict the regional coverage for each site specified.
+In this mode, \fBSPLAT!\fP can generate a topographic map displaying
+the geometric line-of-sight coverage area of the sites based on the
+location of each site, and the height of receive antenna wishing to
+communicate with the site in question.  \fBSPLAT!\fP switches from
+point-to-point analysis mode to area prediction mode when the \fI-c\fP
+switch is invoked as follows:
+
+\fCsplat -t tx_site -c 30.0 -s cities.dat -b co34_d00.dat -o tx_coverage\fR
+
+In this example, \fBSPLAT!\fP generates a topographic map called
+\fItx_coverage.ppm\fP that illustrates the predicted line-of-sight
+regional coverage of \fItx_site\fP to receiving locations having
+antennas 30.0 feet above ground level (AGL).  The contents of
+\fIcities.dat\fP are plotted on the map, as are the cartographic
+boundaries contained in the file \fIco34_d00.dat\fP.
+
+When plotting line-of-sight paths and areas of regional coverage,
+\fBSPLAT!\fP by default does not account for the effects of
+atmospheric bending.  However, this behavior may be modified
+by using the Earth radius multiplier (\fI-m\fP) switch:
+
+\fCsplat -t wnjt -c 30.0 -m 1.333 -s cities.dat -b counties.dat -o map.ppm\fR
+
+An earth radius multiplier  of 1.333 instructs \fBSPLAT!\fP to use
+the "four-thirds earth" model for line-of-sight propagation analysis.
+Any appropriate earth radius multiplier may be selected by the user.
+When invoked in area prediction mode, \fBSPLAT!\fP generates a
+site report for each station analyzed.  \fBSPLAT!\fP site reports
+contain details of the site's geographic location, its height above
+mean sea level, the antenna's height above mean sea level, the
+antenna's height above average terrain, and the height of the
+average terrain calculated in the directions of 0, 45, 90, 135,
+180, 225, 270, and 315 degrees azimuth.
+
+If the \fI-c\fP switch is replaced by a \fI-L\fP switch, a
+Longley-Rice path loss map for a transmitter site may be generated:
+
+\fCsplat -t tx_site -L 30.0 -s cities.dat -b co34_d00.dat -o path_loss_map\fR
+
+In this mode, \fBSPLAT!\fP generates a multi-color map illustrating
+expected signal levels (path loss) in areas surrounding the transmitter
+site.  A legend at the bottom of the map correlates each color with a
+specific path loss level in decibels.  Since Longley-Rice area
+prediction map generation is quite CPU intensive, provision for
+limiting the analysis range is provided by the \fI-R\fP switch.
+The argument must be given in miles.  If a range wider than the
+generated topographic map is specified, \fBSPLAT!\fP will perform
+Longley-Rice path loss calculations between all four corners of
+the area prediction map.
+.SH DETERMINING MULTIPLE REGIONS OF COVERAGE
+\fBSPLAT!\fP can also display line-of-sight coverage areas for as
+many as four separate transmitter sites on a common topographic map.
+For example:
+
+\fCsplat -t site1 site2 site3 site4 -c 30.0 -o network.ppm\fR
+
+plots the regional line-of-sight coverage of site1, site2, site3,
+and site4 based on a receive antenna located 30.0 feet above ground
+level.  A topographic map is then written to the file \fInetwork.ppm\fP.
+The line-of-sight coverage area of the transmitters are plotted as
+follows in the colors indicated (along with their corresponding RGB
+values in decimal):
+\fC
+    site1: Green (0,255,0)
+    site2: Cyan (0,255,255)
+    site3: Medium Violet (147,112,219)
+    site4: Sienna 1 (255,130,71)
+
+    site1 + site2: Yellow (255,255,0)
+    site1 + site3: Pink (255,192,203)
+    site1 + site4: Green Yellow (173,255,47)
+    site2 + site3: Orange (255,165,0)
+    site2 + site4: Dark Sea Green 1 (193,255,193)
+    site3 + site4: Dark Turquoise (0,206,209)
+
+    site1 + site2 + site3: Dark Green (0,100,0)
+    site1 + site2 + site4: Blanched Almond (255,235,205)
+    site1 + site3 + site4: Medium Spring Green (0,250,154)
+    site2 + site3 + site4: Tan (210,180,140)
+
+    site1 + site2 + site3 + site4: Gold2 (238,201,0)
+\fR
+If separate \fI.qth\fP files are generated, each representing a common
+site location but a different antenna height, a single topographic map
+illustrating the regional coverage from as many as four separate locations
+on a single tower may be generated by \fBSPLAT!\fP. 
+.SH TOPOGRAPHIC MAP GENERATION
+In certain situations, it may be desirable to generate a topographic map
+of a region without plotting coverage areas, line-of-sight paths, or
+generating obstruction reports.  There are several ways of doing this.
+If one wishes to generate a topographic map illustrating the location
+of a transmitter and receiver site along with a brief text report
+describing the locations and distances between the sites, the \fI-n\fP
+switch should be invoked as follows:
+
+\fCsplat -t tx_site -r rx_site -n -o topo_map.ppm\fR
+
+If no text report is desired, then the \fI-N\fP switch is used:
+
+\fCsplat -t tx_site -r rx_site -N -o topo_map.ppm\fR
+
+If the \fI-o\fP switch and output filename are omitted when using
+either the \fI-n\fP or \fI-N\fP switches, output is written to a
+file named \fImap.ppm\fP in the current working directory by default.
+.SH DETERMINATION OF ANTENNA HEIGHT ABOVE AVERAGE TERRAIN
+\fBSPLAT!\fP determines antenna height above average terrain (HAAT)
+according to the procedure defined by Federal Communications Commission
+Part 73.313(d).  According to this definition, terrain elevations along
+eight radials between 2 and 10 miles (3 and 16 kilometers) from the site
+being analyzed are sampled and averaged for each 45 degrees of azimuth
+starting with True North.  If one or more radials lie entirely over water,
+or over land outside the United States (areas for which no USGS topography
+data is available), then those radials are omitted from the calculation
+of average terrain.  If part of a radial extends over a body of water or
+over land outside the United States, then only that part of the radial
+lying over United States land is used in the determination of average
+terrain.
+
+When performing point-to-point terrain analysis, \fBSPLAT!\fP determines
+the antenna height above average terrain only if enough topographic
+data has already been loaded by the program to perform the point-to-point
+analysis.  In most cases, this will be true, unless the site in question
+does not lie within 10 miles of the boundary of the topography data in
+memory.
+
+When performing area prediction analysis, enough topography data is normally
+loaded by \fBSPLAT!\fP to perform average terrain calculations.  Under
+such conditions, \fBSPLAT!\fP will provide the antenna height above
+average terrain as well as the average terrain above mean sea level
+for azimuths of 0, 45, 90, 135, 180, 225, 270, and 315 degrees, and
+include such information in the site report generated.  If one or
+more of the eight radials surveyed fall over water or land outside
+the United States, \fBSPLAT!\fP reports \fINo Terrain\fP for those
+radial paths.
+.SH SETTING THE MAXIMUM SIZE OF AN ANALYSIS REGION
+\fBSPLAT!\fP reads SDF files into a series of memory "slots" as required
+within the structure of the program.  Each "slot" holds one SDF file.
+Each SDF file represents a one degree by one degree region of terrain.
+A \fI#define MAXSLOTS\fP statement in the first several lines of
+\fIsplat.cpp\fP sets the maximum number of "slots" available for topography
+data.  It also sets the maximum size of the topographic maps generated by
+\fBSPLAT!\fP.  MAXSLOTS is set to 9 by default.  If \fBSPLAT!\fP produces
+a segmentation fault on start-up with this default, it is an indication
+that not enough RAM and/or virtual memory (swap space) are available to
+run \fBSPLAT!\fP with this number of MAXSLOTS.  In this case, MAXSLOTS
+may be reduced to 4, although this will greatly limit the maximum region
+\fBSPLAT!\fP will be able to analyze.  If 118 megabytes or more of total
+memory (swap space plus RAM) is available, then MAXSLOTS may be increased
+to 16.  This will permit operation over a 4-degree by 4-degree region,
+which is sufficient for single antenna heights in excess of 10,000 feet
+above mean sea level, or point-to-point distances of over 1000 miles.
+.SH ADDITIONAL INFORMATION
+Invoking \fBSPLAT!\fP without any arguments will display all the
+command-line options available with the program along with a brief
+summary of each.
+
+The latest news and information regarding \fBSPLAT!\fP software is
+available through the official \fBSPLAT!\fP software web page located
+at: \fIhttp://www.qsl.net/kd2bd/splat.html\fP.
+.SH FILES
+.TP
+\fC$HOME/.splat_path\fR
+User-generated file containing the default path to the directory
+containing the SDF data files.
+.TP
+\fCsplat.lrp\fR
+Default Longley-Rice model parameters.
+.SH AUTHORS
+.TP
+John A. Magliacane, KD2BD <\fIkd2bd@amsat.org\fP>
+Creator, Lead Developer
+.TP
+Doug McDonald <\fImcdonald@scs.uiuc.edu\fP>
+Longley-Rice Model integration
diff --git a/docs/pdf/splat.pdf b/docs/pdf/splat.pdf
new file mode 100644 (file)
index 0000000..1ab6b84
Binary files /dev/null and b/docs/pdf/splat.pdf differ
diff --git a/docs/postscript/splat.ps b/docs/postscript/splat.ps
new file mode 100644 (file)
index 0000000..2dbe5de
--- /dev/null
@@ -0,0 +1,1063 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.17.2
+%%CreationDate: Sat Jan 24 16:01:55 2004
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Bold
+%%+ font Times-Italic
+%%+ font Courier
+%%+ font Symbol
+%%DocumentSuppliedResources: procset grops 1.17 2
+%%Pages: 9
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.17 2
+/setpacking where{
+pop
+currentpacking
+true setpacking
+}if
+/grops 120 dict dup begin
+/SC 32 def
+/A/show load def
+/B{0 SC 3 -1 roll widthshow}bind def
+/C{0 exch ashow}bind def
+/D{0 exch 0 SC 5 2 roll awidthshow}bind def
+/E{0 rmoveto show}bind def
+/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
+/G{0 rmoveto 0 exch ashow}bind def
+/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/I{0 exch rmoveto show}bind def
+/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
+/K{0 exch rmoveto 0 exch ashow}bind def
+/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/M{rmoveto show}bind def
+/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
+/O{rmoveto 0 exch ashow}bind def
+/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/Q{moveto show}bind def
+/R{moveto 0 SC 3 -1 roll widthshow}bind def
+/S{moveto 0 exch ashow}bind def
+/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/SF{
+findfont exch
+[exch dup 0 exch 0 exch neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/MF{
+findfont
+[5 2 roll
+0 3 1 roll
+neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+/MANUAL{
+statusdict begin/manualfeed true store end
+}bind def
+/PLG{
+gsave newpath clippath pathbbox grestore
+exch pop add exch pop
+}bind def
+/BP{
+/level0 save def
+1 setlinecap
+1 setlinejoin
+72 RES div dup scale
+LS{
+90 rotate
+}{
+0 PL translate
+}ifelse
+1 -1 scale
+}bind def
+/EP{
+level0 restore
+showpage
+}bind def
+/DA{
+newpath arcn stroke
+}bind def
+/SN{
+transform
+.25 sub exch .25 sub exch
+round .25 add exch round .25 add exch
+itransform
+}bind def
+/DL{
+SN
+moveto
+SN
+lineto stroke
+}bind def
+/DC{
+newpath 0 360 arc closepath
+}bind def
+/TM matrix def
+/DE{
+TM currentmatrix pop
+translate scale newpath 0 0 .5 0 360 arc closepath
+TM setmatrix
+}bind def
+/RC/rcurveto load def
+/RL/rlineto load def
+/ST/stroke load def
+/MT/moveto load def
+/CL/closepath load def
+/FL{
+currentgray exch setgray fill setgray
+}bind def
+/BL/fill load def
+/LW/setlinewidth load def
+/RE{
+findfont
+dup maxlength 1 index/FontName known not{1 add}if dict begin
+{
+1 index/FID ne{def}{pop pop}ifelse
+}forall
+/Encoding exch def
+dup/FontName exch def
+currentdict end definefont pop
+}bind def
+/DEFS 0 def
+/EBEGIN{
+moveto
+DEFS begin
+}bind def
+/EEND/end load def
+/CNT 0 def
+/level1 0 def
+/PBEGIN{
+/level1 save def
+translate
+div 3 1 roll div exch scale
+neg exch neg exch translate
+0 setgray
+0 setlinecap
+1 setlinewidth
+0 setlinejoin
+10 setmiterlimit
+[]0 setdash
+/setstrokeadjust where{
+pop
+false setstrokeadjust
+}if
+/setoverprint where{
+pop
+false setoverprint
+}if
+newpath
+/CNT countdictstack def
+userdict begin
+/showpage{}def
+}bind def
+/PEND{
+clear
+countdictstack CNT sub{end}repeat
+level1 restore
+}bind def
+end def
+/setpacking where{
+pop
+setpacking
+}if
+%%EndResource
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Bold
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Courier
+%%IncludeResource: font Symbol
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72
+def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron
+/scaron/zcaron/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent
+/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen
+/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon
+/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O
+/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex
+/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y
+/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft
+/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl
+/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen
+/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft
+/logicalnot/minus/registered/macron/degree/plusminus/twosuperior
+/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior
+/ordmasculine/guilsinglright/onequarter/onehalf/threequarters
+/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE
+/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
+/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn
+/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash
+/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def
+/Courier@0 ENC0/Courier RE/Times-Italic@0 ENC0/Times-Italic RE
+/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E/F1 10.95
+/Times-Bold@0 SF -.219(NA)72 84 S(ME).219 E F0(splat \255 A)108 96 Q/F2
+10/Times-Bold@0 SF(S)2.5 E F0(ignal)A F2(P)2.5 E F0(ropag)A(ation,)-.05
+E F2(L)2.5 E F0(oss,)A F2(A)2.5 E F0(nd)A F2(T)2.5 E F0
+(errain analysis tool)A F1(SYNOPSIS)72 112.8 Q F0 .675(splat [-t)108
+124.8 R/F3 10/Times-Italic@0 SF(tr)3.175 E(ansmitter_site)-.15 E(.qth)
+-.15 E F0 3.174(][)C(-r)-3.174 E F3 -.37(re)3.174 G(ceiver_site).37 E
+(.qth)-.15 E F0 3.174(][)C(-c)-3.174 E F3(rx_antenna_height_for_los_co)
+3.174 E(ver)-.1 E -.1(age)-.15 G .674(_analysis \(feet\)).1 F
+(\(\215oat\))108 136.8 Q F0 4.38(][)C(-L)-4.38 E F3
+(rx_antenna_height_for_Longle)4.38 E(y-Rice_co)-.3 E(ver)-.1 E -.1(age)
+-.15 G 1.88(_analysis \(feet\) \(\215oat\)).1 F F0 4.38(][)C(-p)-4.38 E
+F3(terr)4.38 E(ain_pr)-.15 E(o\214le)-.45 E(.e)-.15 E(xt)-.2 E F0(])A
+([-e)108 148.8 Q F3(ele)5.543 E(vation_pr)-.15 E(o\214le)-.45 E(.e)-.15
+E(xt)-.2 E F0 5.543(][)C(-h)-5.543 E F3(height_pr)5.543 E(o\214le)-.45 E
+(.e)-.15 E(xt)-.2 E F0 5.543(][)C(-l)-5.543 E F3(Longle)5.543 E
+(y-Rice_pr)-.3 E(o\214le)-.45 E(.e)-.15 E(xt)-.2 E F0 5.543(][)C(-o)
+-5.543 E F3(topo)5.542 E(gr)-.1 E(aphic_map_\214le-)-.15 E(name)108
+160.8 Q(.ppm)-.15 E F0 5.196(][)C(-b)-5.196 E F3(carto)5.196 E(gr)-.1 E
+(aphic_boundary_\214lename)-.15 E(.dat)-.15 E F0 5.197(][)C(-s)-5.197 E
+F3(site/city_database)5.197 E(.dat)-.15 E F0 5.197(][)C(-d)-5.197 E F3
+(sdf_dir)5.197 E(ectory_path)-.37 E F0(])A([-m)108 172.8 Q F3(earth_r)
+2.5 E(adius_multiplier \(\215oat\))-.15 E F0 2.5(][)C(-R)-2.5 E F3
+(maximum_co)2.5 E(ver)-.1 E -.1(age)-.15 G(_r).1 E(ang)-.15 E 2.5(e\()
+-.1 G(for -c or -L\) \(miles\) \(\215oat\))-2.5 E F0 2.5(][)C(-n] [-N])
+-2.5 E F1(DESCRIPTION)72 189.6 Q F2(SPLA)108 201.6 Q(T!)-.95 E F0 1.588
+(is a simple, yet po)4.088 F 1.588
+(werful terrain analysis tool written for Unix and Linux-based w)-.25 F
+(orkstations.)-.1 E F2(SPLA)108 213.6 Q(T!)-.95 E F0 .053(is free softw)
+2.553 F 2.553(are. Redistrib)-.1 F .053(ution and/or modi\214cation is \
+permitted under the terms of the GNU Gen-)-.2 F .906
+(eral Public License as published by the Free Softw)108 225.6 R .906
+(are F)-.1 F .906(oundation, either v)-.15 F .906
+(ersion 2 of the License or an)-.15 F(y)-.15 E .622(later v)108 237.6 R
+3.122(ersion. Adoption)-.15 F(of)3.123 E F2(SPLA)3.123 E(T!)-.95 E F0
+.623(source code in proprietary or closed-source applications is a viol\
+ation)3.123 F(of this license, and is)108 249.6 Q F2(strictly)2.5 E F0
+(forbidden.)2.5 E F2(SPLA)108 273.6 Q(T!)-.95 E F0 .531(is distrib)3.031
+F .531(uted in the hope that it will be useful, b)-.2 F .53
+(ut WITHOUT ANY W)-.2 F(ARRANTY)-1.2 E 3.03(,w)-1.29 G .53(ithout e)
+-3.03 F -.15(ve)-.25 G(n).15 E .959(the implied w)108 285.6 R .959
+(arranty of MERCHANT)-.1 F .959(ABILITY or FITNESS FOR A P)-.93 F(AR)
+-.92 E .96(TICULAR PURPOSE. See the)-.6 F
+(GNU General Public License for more details.)108 297.6 Q F1(INTR)72
+314.4 Q(ODUCTION)-.329 E F2(SPLA)108 326.4 Q(T!)-.95 E F0 .769
+(is a terrestrial RF propag)3.269 F .768
+(ation analysis tool for the spectrum between 20 MHz and 20 GHz, and)
+-.05 F(pro)108 338.4 Q 1.482(vides information of interest to communica\
+tion system designers and site engineers.)-.15 F F2(SPLA)6.483 E(T!)-.95
+E F0(deter)3.983 E(-)-.2 E .263
+(mines great circle distances and bearings between sites, antenna ele)
+108 350.4 R -.25(va)-.25 G .263
+(tion angles \(uptilt\), depression angles).25 F(\(do)108 362.4 Q 1.197
+(wntilt\), antenna height abo)-.25 F 1.497 -.15(ve m)-.15 H 1.197
+(ean sea le).15 F -.15(ve)-.25 G 1.197(l, antenna height abo).15 F 1.497
+-.15(ve a)-.15 H -.15(ve)-.05 G 1.197(rage terrain, bearings and dis-)
+.15 F .039(tances to kno)108 374.4 R .039(wn obstructions, Longle)-.25 F
+.038
+(y-Rice path loss, and minimum antenna height requirements needed to)
+-.15 F 2.721(establish line-of-sight communication paths absent of obst\
+ructions due to terrain.)108 386.4 R F2(SPLA)7.721 E(T!)-.95 E F0
+(produces)5.221 E .242(reports, graphs, and highly detailed and careful\
+ly annotated topographic maps depicting line-of-sight paths,)108 398.4 R
+.068(path loss, and e)108 410.4 R .068(xpected co)-.15 F -.15(ve)-.15 G
+.068(rage areas of transmitters and repeater systems.).15 F .069
+(When performing line-of-sight)5.069 F .794(analysis in situations wher\
+e multiple transmitter or repeater sites are emplo)108 422.4 R(yed,)-.1
+E F2(SPLA)3.294 E(T!)-.95 E F0 .793(determines indi-)3.293 F
+(vidual and mutual areas of co)108 434.4 Q -.15(ve)-.15 G
+(rage within the netw).15 E(ork speci\214ed.)-.1 E F2(SPLA)108 458.4 Q
+(T!)-.95 E F0 1.523(operates in tw)4.023 F 4.023(om)-.1 G(odes:)-4.023 E
+F3 1.523(point-to-point mode)4.023 F F0 4.024(,a)C(nd)-4.024 E F3(ar)
+4.024 E 1.524(ea pr)-.37 F 1.524(ediction mode)-.37 F F0 6.524(.T)C
+1.524(hese modes may be)-6.524 F(in)108 470.4 Q -.2(vo)-.4 G -.1(ke).2 G
+3.084(du).1 G .583(sing either line-of-sight \(LOS\) or Irre)-3.084 F
+.583(gular T)-.15 F .583(errain \(ITM\) propag)-.7 F .583(ation models.)
+-.05 F -.35(Tr)5.583 G .583(ue Earth, four).35 F(-)-.2 E .243
+(thirds Earth, or an)108 482.4 R 2.743(yo)-.15 G .243(ther Earth radius\
+ may be speci\214ed by the user when performing line-of-sight analysis.)
+-2.743 F F1(INPUT FILES)72 499.2 Q F2(SPLA)108 511.2 Q(T!)-.95 E F0 .682
+(is a command-line dri)3.182 F -.15(ve)-.25 G 3.182(na).15 G .682
+(pplication, and reads input data through a number of data \214les.)
+-3.182 F(Each)5.681 E 1.188(has its o)108 523.2 R 1.188(wn format.)-.25
+F 1.189(Some \214les are mandatory for successful e)6.188 F -.15(xe)-.15
+G 1.189(cution of the program, while others are).15 F 2.95
+(optional. Mandatory)108 535.2 R .45(\214les include SPLA)2.95 F 2.95
+(TD)-1.11 G .449(ata Files \(SDF \214les\), site location \214les \(QTH\
+ \214les\), and Long-)-2.95 F(le)108 547.2 Q .681
+(y-Rice model parameter \214les \(LRP \214les\).)-.15 F .682
+(Optional \214les include city/site location \214les, and cartographic)
+5.681 F(boundary \214les.)108 559.2 Q F1(SPLA)72 576 Q 2.738(TD)-1.04 G
+-1.644 -1.04(AT A)-3.121 H(FILES)3.778 E F2(SPLA)108 588 Q(T!)-.95 E F0
+.65(imports topographic data in the form of SPLA)3.15 F 3.15(TD)-1.11 G
+.65(ata Files \(SDFs\) that may be generated from a)-3.15 F .621
+(number of information sources.)108 600 R .622
+(In the United States, SPLA)5.622 F 3.122(TD)-1.11 G .622
+(ata Files are most often deri)-3.122 F -.15(ve)-.25 G 3.122(df).15 G
+.622(rom U.S.)-3.122 F 1.54(Geological Surv)108 612 R 1.84 -.15(ey D)
+-.15 H 1.539(igital Ele).15 F -.25(va)-.25 G 1.539
+(tion Models \(DEMs\) using the).25 F F2(usgs2sdf)4.039 E F0 1.539
+(utility included with)4.039 F F2(SPLA)4.039 E(T!)-.95 E F0(.)A 1.47
+(USGS Digital Ele)108 624 R -.25(va)-.25 G 1.47
+(tion Models compatible with this utility are a).25 F -.25(va)-.2 G
+1.471(ilable at no cost via the Internet at:).25 F F3(http://edcsgs9.cr)
+108 636 Q(.usgs.go)-1.11 E(v/glis/hyper/guide/1_dgr_dem\214g/inde)-.1 E
+(x1m.html)-.2 E F0(.)A(SPLA)108 660 Q 2.646(TD)-1.11 G .146
+(ata Files contain topographic ele)-2.646 F -.25(va)-.25 G .146
+(tions to the nearest meter abo).25 F .445 -.15(ve m)-.15 H .145
+(ean sea le).15 F -.15(ve)-.25 G 2.645(lf).15 G .145(or 1-de)-2.645 F
+.145(gree by)-.15 F(1-de)108 672 Q .812(gree re)-.15 F .812
+(gions of the earth with a resolution of 3-arc seconds.)-.15 F .813
+(SDF \214les can be read in either standard)5.812 F .579(format \()108
+684 R F3(.sdf)A F0 3.079(\)a)C 3.079(sg)-3.079 G .579(enerated by the)
+-3.079 F F2(usgs2sdf)3.079 E F0(utility)3.079 E 3.079(,o)-.65 G 3.079
+(ri)-3.079 G 3.079(nb)-3.079 G .578(zip2 compressed format \()-3.079 F
+F3(.sdf)A(.bz2)-.15 E F0 3.078(\). Since)B(uncom-)3.078 E .183
+(pressed \214les can be slightly f)108 696 R .183
+(aster to load than compressed \214les,)-.1 F F2(SPLA)2.684 E(T!)-.95 E
+F0 .184(searches for the needed SDF data)2.684 F .091
+(in uncompressed format \214rst.)108 708 R .091
+(If such data cannot located, then)5.091 F F2(SPLA)2.591 E(T!)-.95 E F0
+.09(tries to read the data in bzip2 com-)2.59 F .91(pressed format.)108
+720 R .91(If no compressed SDF \214les can be found for the re)5.91 F
+.91(gion requested,)-.15 F F2(SPLA)3.41 E(T!)-.95 E F0 .91(assumes the)
+3.41 F(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(1)
+195.95 E EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E(re)108 84 Q .937
+(gion is o)-.15 F -.15(ve)-.15 G 3.437(rw).15 G .937
+(ater or outside the United States, and will assign an ele)-3.537 F -.25
+(va)-.25 G .936(tion of sea-le).25 F -.15(ve)-.25 G 3.436(lt).15 G 3.436
+(ot)-3.436 G .936(hese areas.)-3.436 F 1.061(This feature of)108 96 R/F1
+10/Times-Bold@0 SF(SPLA)3.561 E(T!)-.95 E F0(mak)3.561 E 1.061
+(es it possible to perform path analysis not only o)-.1 F -.15(ve)-.15 G
+3.561(rl).15 G 1.062(and, b)-3.561 F 1.062(ut also between)-.2 F 1.389
+(coastal areas not represented by USGS Digital Ele)108 108 R -.25(va)
+-.25 G 1.389(tion Model Data since the).25 F 3.889(ya)-.15 G 1.388
+(re de)-3.889 F -.2(vo)-.25 G 1.388(id of an).2 F 3.888(yl)-.15 G(and)
+-3.888 E 2.501(masses. Ho)108 120 R(we)-.25 E -.15(ve)-.25 G .801 -.4
+(r, t).15 H .001(his beha).4 F .001(vior of)-.2 F F1(SPLA)2.501 E(T!)
+-.95 E F0 .001(underscores the importance of ha)2.501 F .002
+(ving all the SDF \214les required)-.2 F(for the re)108 132 Q
+(gion being analyzed if meaningful results are to be e)-.15 E(xpected.)
+-.15 E/F2 10.95/Times-Bold@0 SF(SITE LOCA)72 148.8 Q(TION \(QTH\) FILES)
+-1.04 E F1(SPLA)108 160.8 Q(T!)-.95 E F0 .839
+(imports site location information of transmitter and recei)3.339 F -.15
+(ve)-.25 G 3.338(rs).15 G .838(ites analyzed by the program from)-3.338
+F 1.963(ASCII \214les ha)108 172.8 R 1.963(ving a)-.2 F/F3 10
+/Times-Italic@0 SF(.qth)4.463 E F0 -.15(ex)4.464 G 4.464(tension. QTH)
+.15 F 1.964(\214les contain the site')4.464 F 4.464(sn)-.55 G 1.964
+(ame, the site')-4.464 F 4.464(sl)-.55 G 1.964(atitude \(in de)-4.464 F
+(grees)-.15 E .744(North\), the site')108 184.8 R 3.244(sl)-.55 G .744
+(ongitude \(in de)-3.244 F .744(grees W)-.15 F .744
+(est\), and the site')-.8 F 3.244(sa)-.55 G .744(ntenna height abo)
+-3.244 F 1.043 -.15(ve g)-.15 H .743(round le).15 F -.15(ve)-.25 G 3.243
+(l\().15 G -.4(AG)-3.243 G 3.243(L\). A).4 F .305
+(single line-feed character separates each \214eld.)108 196.8 R .305
+(The antenna height is assumed to be speci\214ed in feet unless)5.305 F
+(follo)108 208.8 Q .402(wed by the letter)-.25 F F3(m)2.902 E F0 .402
+(or the w)2.902 F(ord)-.1 E F3(meter)2.902 E(s)-.1 E F0 .402
+(in either upper or lo)2.902 F .401(wer case.)-.25 F .401
+(Latitude and longitude informa-)5.401 F .548(tion may be e)108 220.8 R
+.548(xpressed in either decimal format \(74.6889\) or de)-.15 F .548
+(gree, minute, second \(DMS\) format \(74 41)-.15 F(20.0\).)108 232.8 Q
+-.15(Fo)108 256.8 S 3.356(re).15 G .856
+(xample, a site location \214le describing tele)-3.506 F .856
+(vision station WNJT)-.25 F 3.356(,T)-.74 G .856(renton, NJ \()-3.706 F
+F3(wnjt.qth)A F0 3.356(\)m)C .856(ight read as)-3.356 F(follo)108 268.8
+Q(ws:)-.25 E/F4 10/Courier@0 SF(WNJT)156 292.8 Q(40.2833)156 304.8 Q
+(74.6889)156 316.8 Q(990.00)156 328.8 Q F0 .23
+(Each transmitter and recei)108 352.8 R -.15(ve)-.25 G 2.73(rs).15 G .23
+(ite analyzed by)-2.73 F F1(SPLA)2.73 E(T!)-.95 E F0 .23
+(must be represented by its o)2.73 F .23(wn site location \(QTH\))-.25 F
+(\214le.)108 364.8 Q F2(LONGLEY)72 381.6 Q(-RICE P)-1.007 E
+(ARAMETER \(LRP\) FILES)-.81 E F1(SPLA)108 393.6 Q(T!)-.95 E F0 .058
+(imports Longle)2.558 F .058
+(y-Rice model parameter data from \214les ha)-.15 F .057
+(ving the same base name as the transmit-)-.2 F 1.504
+(ter site QTH \214le, b)108 405.6 R 1.504(ut carrying a)-.2 F F3(.lrp)
+4.005 E F0 -.15(ex)4.005 G 1.505(tension, thus pro).15 F 1.505
+(viding simple and accurate correlation between)-.15 F
+(these associated data sets.)108 417.6 Q(The format for the Longle)5 E
+(y-Rice model parameter \214les is as follo)-.15 E(ws \()-.25 E F3
+(wnjt.lrp)A F0(\):)A F4 6(15.000 ;)156 441.6 R
+(Earth Dielectric Constant \(Relative permittivity\))6 E 12(0.005 ;)156
+453.6 R(Earth Conductivity \(Siemens per meter\))6 E
+(301.000 ; Atmospheric Bending Constant \(N-units\))156 465.6 Q
+(700.000 ; Frequency in MHz \(20 MHz to 20 GHz\))156 477.6 Q 42(5;)156
+489.6 S(Radio Climate \(5 = Continental Temperate\))-36 E 42(0;)156
+501.6 S(Polarization \(0 = Horizontal, 1 = Vertical\))-36 E 24(0.5 ;)156
+513.6 R(Fraction of situations \(50% of locations\))6 E 24(0.5 ;)156
+525.6 R(Fraction of time \(50% of the time\))6 E F0 .771(If an LRP \214\
+le corresponding to the tx_site QTH \214le cannot be found,)108 549.6 R
+F1(SPLA)3.27 E(T!)-.95 E F0 .77(scans the current w)3.27 F(orking)-.1 E
+.085(directory for the \214le "splat.lrp".)108 561.6 R .085
+(If this \214le cannot be found, then the def)5.085 F .085
+(ault parameters listed abo)-.1 F .385 -.15(ve w)-.15 H .085(ill be).15
+F .528(assigned by)108 573.6 R F1(SPLA)3.028 E(T!)-.95 E F0 .527(and a \
+corresponding "splat.lrp" \214le containing this data will be written t\
+o the current)3.028 F -.1(wo)108 585.6 S(rking directory).1 E(.)-.65 E
+-.8(Ty)108 609.6 S(pical Earth dielectric constants and conducti).8 E
+(vity v)-.25 E(alues are as follo)-.25 E(ws:)-.25 E F4
+(Dielectric Constant)270 633.6 Q(Conductivity)12 E(Salt water)156 645.6
+Q 48(:8)42 G 96(05)-48 G(.000)-96 E(Good ground)156 657.6 Q 48(:2)36 G
+96(50)-48 G(.020)-96 E(Fresh water)156 669.6 Q 48(:8)36 G 96(00)-48 G
+(.010)-96 E(Marshy land)156 681.6 Q 48(:1)36 G 96(20)-48 G(.007)-96 E
+(Farmland, forest :)156 693.6 Q 90(15 0.005)48 F(Average ground)156
+705.6 Q 48(:1)18 G 96(50)-48 G(.005)-96 E(Mountain, sand)156 717.6 Q 48
+(:1)18 G 96(30)-48 G(.002)-96 E 72(City :)156 729.6 R 96(50)54 G(.001)
+-96 E F0(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(2)
+195.95 E EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E/F1 10/Courier@0 SF
+(Poor ground)156 84 Q -18 54(:4 0)36 H(.001)-54 E F0
+(Radio climate codes used by)108 108 Q/F2 10/Times-Bold@0 SF(SPLA)2.5 E
+(T!)-.95 E F0(are as follo)2.5 E(ws:)-.25 E F1(1: Equatorial \(Congo\))
+156 132 Q(2: Continental Subtropical \(Sudan\))156 144 Q
+(3: Maritime Subtropical \(West coast of Africa\))156 156 Q
+(4: Desert \(Sahara\))156 168 Q(5: Continental Temperate)156 180 Q
+(6: Maritime Temperate, over land \(UK and west coasts of US & EU\))156
+192 Q(7: Maritime Temperate, over sea)156 204 Q F0 1.487
+(The Continental T)108 228 R 1.486(emperate climate is common to lar)-.7
+F 1.486(ge land masses in the temperate zone, such as the)-.18 F .756
+(United States.)108 240 R -.15(Fo)5.756 G 3.256(rp).15 G .756
+(aths shorter than 100 km, there is little dif)-3.256 F .756
+(ference between Continental and Maritime)-.25 F -.7(Te)108 252 S
+(mperate climates.).7 E .379(The \214nal tw)108 276 R 2.879(op)-.1 G
+.379(arameters in the)-2.879 F/F3 10/Times-Italic@0 SF(.lrp)2.879 E F0
+.379(\214le correspond to the statistical analysis pro)2.879 F .378
+(vided by the Longle)-.15 F(y-Rice)-.15 E 2.537(model. In)108 288 R .037
+(this e)2.537 F(xample,)-.15 E F2(SPLA)2.537 E(T!)-.95 E F0 .038(will r\
+eturn the maximum path loss occurring 50% of the time \(fraction of)
+5.037 F .316(time\) in 50% of situations \(fraction of situations\).)108
+300 R .315(Use a fraction of time parameter of 0.97 for digital tele-)
+5.316 F(vision, 0.50 for analog in the United States.)108 312 Q
+(Isotropic antennas are assumed.)5 E -.15(Fo)108 336 S 3.03(rf).15 G .53
+(urther information on these parameters, see:)-3.03 F F3
+(http://elbert.its.bldr)3.03 E(doc.go)-.37 E(v/itm.html)-.1 E F0(and)
+3.03 E F3(http://www)3.03 E(.soft-)-.74 E(wright.com/faq/engineering/pr)
+108 348 Q(op_longle)-.45 E(y_rice)-.3 E(.html)-.15 E/F4 10.95
+/Times-Bold@0 SF(CITY LOCA)72 364.8 Q(TION FILES)-1.04 E F0 .807
+(The names and locations of cities, to)108 376.8 R .807
+(wer sites, or other points of interest may imported and be plotted on)
+-.25 F .797(topographic maps generated by)108 388.8 R F2(SPLA)3.297 E
+(T!)-.95 E F0(.)A F2(SPLA)5.797 E(T!)-.95 E F0 .797
+(imports the names of cities and locations from ASCII)3.297 F .191
+(\214les containing the location')108 400.8 R 2.691(sn)-.55 G .191
+(ame, the location')-2.691 F 2.691(sl)-.55 G .191
+(atitude, and the location')-2.691 F 2.69(sl)-.55 G 2.69(ongitude. Each)
+-2.69 F .19(\214eld is sepa-)2.69 F .513(rated by a comma.)108 412.8 R
+.513(Each record is separated by a single line feed character)5.513 F
+5.514(.A)-.55 G 3.014(sw)-5.514 G .514(as the case with the)-3.114 F F3
+(.qth)3.014 E F0 .259(\214les, latitude and longitude information may b\
+e entered in either decimal or de)108 424.8 R .258
+(gree, minute, second \(DMS\))-.15 F(format.)108 436.8 Q -.15(Fo)108
+460.8 S 2.5(re).15 G(xample \()-2.65 E F3(cities.dat)A F0(\):)A F1
+(Teaneck, 40.891973, 74.014506)156 484.8 Q
+(Tenafly, 40.919212, 73.955892)156 496.8 Q
+(Teterboro, 40.859511, 74.058908)156 508.8 Q
+(Tinton Falls, 40.279966, 74.093924)156 520.8 Q
+(Toms River, 39.977777, 74.183580)156 532.8 Q
+(Totowa, 40.906160, 74.223310)156 544.8 Q(Trenton, 40.219922, 74.754665)
+156 556.8 Q F0 2.74(At)108 580.8 S .24(otal of \214v)-2.74 F 2.74(es)
+-.15 G .24(eparate city data \214les may be imported at a time.)-2.74 F
+.241(There is no limit to the size of these \214les.)5.241 F F2(SPLA)108
+592.8 Q(T!)-.95 E F0 1.056(reads city data sequentially)3.556 F 3.556
+(,a)-.65 G 1.055
+(nd plots only those locations whose positions do not con\215ict with)
+-3.556 F(pre)108 604.8 Q
+(viously plotted locations when generating topographic maps.)-.25 E .996
+(City data \214les may be generated manually using an)108 628.8 R 3.496
+(yt)-.15 G -.15(ex)-3.496 G 3.496(te).15 G(ditor)-3.496 E 3.496(,i)-.4 G
+.997(mported from other sources, or deri)-3.496 F -.15(ve)-.25 G(d).15 E
+1.535(from data a)108 640.8 R -.25(va)-.2 G 1.535
+(ilable from the U.S. Census Bureau using the).25 F F2(citydecoder)4.035
+E F0 1.535(utility included with)4.035 F F2(SPLA)4.035 E(T!)-.95 E F0(.)
+A .152(Such data is a)108 652.8 R -.25(va)-.2 G .153
+(ilable free of char).25 F .153(ge via the Internet at:)-.18 F F3
+(http://www)2.653 E(.census.go)-.74 E(v/g)-.1 E
+(eo/www/cob/bdy_\214les.html)-.1 E F0(,)A(and must be in ASCII format.)
+108 664.8 Q F4(CAR)72 681.6 Q -.197(TO)-.438 G(GRAPHIC BOUND).197 E(AR)
+-.383 E 2.738(YD)-.383 G -1.644 -1.04(AT A)-3.121 H(FILES)3.778 E F0
+1.17(Cartographic boundary data may also be imported to plot the bounda\
+ries of cities, counties, or states on)108 693.6 R .071
+(topographic maps generated by)108 705.6 R F2(SPLA)2.571 E(T!)-.95 E F0
+5.071(.S)C .071
+(uch data must be of the form of ARC/INFO Ungenerate \(ASCII)-5.071 F
+-.15(Fo)108 717.6 S 1.262
+(rmat\) Metadata Cartographic Boundary Files, and are a).15 F -.25(va)
+-.2 G 1.262(ilable from the U.S.).25 F 1.262(Census Bureau via the)6.262
+F 48.573(Internet at:)108 729.6 R F3(http://www)51.073 E(.census.go)-.74
+E(v/g)-.1 E(eo/www/cob/co2000.html#ascii)-.1 E F0(and)51.074 E
+(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(3)195.95 E
+EP
+%%Page: 4 4
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E/F1 10/Times-Italic@0
+SF(http://www)108 84 Q(.census.go)-.74 E(v/g)-.1 E
+(eo/www/cob/pl2000.html#ascii)-.1 E F0 5.008(.A)C .008(total of \214v)
+-2.5 F 2.507(es)-.15 G .007(eparate cartographic boundary \214les)-2.507
+F .196(may be imported at a time.)108 96 R .196
+(It is not necessary to import state boundaries if county boundaries ha)
+5.196 F .497 -.15(ve a)-.2 H(lready).15 E(been imported.)108 108 Q/F2
+10.95/Times-Bold@0 SF(PR)72 124.8 Q(OGRAM OPERA)-.329 E(TION)-1.04 E/F3
+10/Times-Bold@0 SF(SPLA)108 136.8 Q(T!)-.95 E F0 1.03(is in)3.53 F -.2
+(vo)-.4 G -.1(ke).2 G 3.53(dv).1 G 1.03
+(ia the command-line using a series of switches and ar)-3.53 F 3.53
+(guments. Since)-.18 F F3(SPLA)3.53 E(T!)-.95 E F0 1.03(is a)3.53 F .023
+(CPU and memory intensi)108 148.8 R .323 -.15(ve a)-.25 H .023
+(pplication, this type of interf).15 F .023(ace minimizes o)-.1 F -.15
+(ve)-.15 G .024(rhead, and also lends itself well).15 F .106
+(to scripted operations.)108 160.8 R F3(SPLA)5.106 E(T!)-.95 E F0 1.206
+-.55('s C)D .106
+(PU and memory scheduling priority may be adjusted through the use of)
+.55 F(the Unix)108 172.8 Q F3(nice)2.5 E F0(command.)2.5 E .225
+(The number and type of switches passed to)108 196.8 R F3(SPLA)2.725 E
+(T!)-.95 E F0 .226(determine its mode of operation and method of output)
+2.725 F .008(data generation.)108 208.8 R .008(Nearly all of)5.008 F F3
+(SPLA)2.508 E(T!)-.95 E F0 1.108 -.55('s s)D .008
+(witches may be cascaded in an).55 F 2.507(yo)-.15 G .007
+(rder on the command line when)-2.507 F(in)108 220.8 Q -.2(vo)-.4 G(kin\
+g the program to include all the features described by those switches w\
+hen performing an analysis.).2 E F2(POINT)72 237.6 Q(-T)-1.007 E
+(O-POINT AN)-.197 E(AL)-.219 E(YSIS)-1.007 E F3(SPLA)108 249.6 Q(T!)-.95
+E F0 1.224
+(may be used to perform line-of-sight terrain analysis between tw)3.724
+F 3.725(os)-.1 G 1.225(peci\214ed site locations.)-3.725 F -.15(Fo)6.225
+G(r).15 E -.15(ex)108 261.6 S(ample:).15 E/F4 10/Courier@0 SF
+(splat -t tx_site.qth -r rx_site.qth)108 285.6 Q F0(in)108 309.6 Q -.2
+(vo)-.4 G -.1(ke).2 G 5.833(sat).1 G 3.332
+(errain analysis between the transmitter speci\214ed in)-5.833 F F1
+(tx_site)5.832 E(.qth)-.15 E F0 3.332(and recei)5.832 F -.15(ve)-.25 G
+5.832(rs).15 G 3.332(peci\214ed in)-5.832 F F1(rx_site)108 321.6 Q(.qth)
+-.15 E F0 2.858(,a)C .358(nd writes a)-2.858 F F3(SPLA)2.858 E(T!)-.95 E
+F0 .359(Obstruction Report to the current w)2.858 F .359
+(orking directory)-.1 F 5.359(.T)-.65 G .359(he report contains)-5.359 F
+.767(details of the transmitter and recei)108 333.6 R -.15(ve)-.25 G
+3.267(rs).15 G .767(ites, and identi\214es the location of an)-3.267 F
+3.266(yo)-.15 G .766(bstructions detected during)-3.266 F .627
+(the analysis.)108 345.6 R .628
+(If an obstruction can be cleared by raising the recei)5.627 F .928 -.15
+(ve a)-.25 H .628(ntenna to a greater altitude,).15 F F3(SPLA)3.128 E
+(T!)-.95 E F0 .573(will indicate the minimum antenna height required fo\
+r a line-of-sight path to e)108 357.6 R .572
+(xist between the transmitter)-.15 F .201(and recei)108 369.6 R -.15(ve)
+-.25 G 2.701(rl).15 G .201(ocations speci\214ed.)-2.701 F .201(If the a\
+ntenna must be raised a signi\214cant amount, this determination may)
+5.201 F(tak)108 381.6 Q 2.5(es)-.1 G(ome time.)-2.5 E .694
+(are optional when in)108 405.6 R -.2(vo)-.4 G .694(king the program.).2
+F F3(SPLA)5.694 E(T!)-.95 E F0 .693(automatically reads all SPLA)3.194 F
+3.193(TD)-1.11 G .693(ata Files necessary to)-3.193 F .289
+(conduct the terrain analysis between the sites speci\214ed.)108 417.6 R
+.289(By def)5.289 F .29(ault, the location of SDF \214les is assumed to)
+-.1 F .307(be in the current w)108 429.6 R .307(orking directory unless\
+ a ".splat_path" \214le is present under the user')-.1 F 2.807(sh)-.55 G
+.307(ome directory)-2.807 F 5.307(.I)-.65 G(f)-5.307 E 1.087(this \214l\
+e is present, it must contain the full directory path to the location o\
+f all the SDF \214les required by)108 441.6 R F3(SPLA)108 453.6 Q(T!)
+-.95 E F0 .738(to perform its analysis for the re)3.238 F .737
+(gion containing the transmitter and recei)-.15 F -.15(ve)-.25 G 3.237
+(rs).15 G .737(ites speci\214ed.)-3.237 F(The)5.737 E
+(path in this \214le must be of the form of a single line of ASCII te)
+108 465.6 Q(xt:)-.15 E F4(/opt/splat/sdf/)108 489.6 Q F0 .622
+(and may be generated with an)108 513.6 R 3.122(yt)-.15 G -.15(ex)-3.122
+G 3.122(te).15 G(ditor)-3.122 E 5.622(.T)-.55 G .622(he def)-5.622 F
+.622(ault path speci\214ed in the)-.1 F F1($HOME/.splat_path)3.122 E F0
+.622(\214le may)3.122 F(be o)108 525.6 Q -.15(ve)-.15 G(rridden at an)
+.15 E 2.5(yt)-.15 G(ime using the)-2.5 E F1(-d)2.5 E F0(switch:)2.5 E F4
+(splat -t tx_site -r rx_site -d /cdrom/sdf/)108 549.6 Q F0 3.023(Ag)108
+573.6 S .523(raph of the terrain pro\214le between the recei)-3.023 F
+-.15(ve)-.25 G 3.023(ra).15 G .523
+(nd transmitter locations as a function of distance from)-3.023 F
+(the recei)108 585.6 Q -.15(ve)-.25 G 2.5(rc).15 G
+(an be generated by adding the)-2.5 E F1(-p)2.5 E F0(switch:)2.5 E F4
+(splat -t tx_site -r rx_site -p terrain_profile.gif)108 609.6 Q F3(SPLA)
+108 633.6 Q(T!)-.95 E F0(in)4.119 E -.2(vo)-.4 G -.1(ke).2 G(s).1 E F3
+(gnuplot)4.119 E F0 1.619(when generating graphs.)4.119 F 1.619
+(The \214lename e)6.619 F 1.619(xtension speci\214ed to)-.15 F F3(SPLA)
+4.12 E(T!)-.95 E F0(deter)4.12 E(-)-.2 E .809
+(mines the format of the graph produced.)108 645.6 R F1(.gif)5.809 E F0
+.809(will produce a 640x480 color GIF graphic \214le, while)3.309 F F1
+(.ps)3.308 E F0(or)3.308 E F1(.postscript)108 657.6 Q F0 1.211
+(will produce postscript output.)3.711 F 1.212
+(Output in formats such as PNG, Adobe Illustrator)6.211 F 3.712(,A)-.4 G
+(utoCAD)-3.712 E 1.924(dxf, LaT)108 669.6 R 1.924(eX, and man)-.7 F
+4.424(yo)-.15 G 1.924(thers are a)-4.424 F -.25(va)-.2 G 4.424
+(ilable. Please).25 F(consult)4.424 E F3(gnuplot)4.424 E F0 4.424(,a)C
+(nd)-4.424 E F3(gnuplot)4.424 E F0 3.023 -.55('s d)D 1.923
+(ocumentation for).55 F(details on all the supported output formats.)108
+681.6 Q 3.542(Ag)108 705.6 S 1.042(raph of ele)-3.542 F -.25(va)-.25 G
+1.042(tions subtended by the terrain between the recei).25 F -.15(ve)
+-.25 G 3.542(ra).15 G 1.043(nd transmitter as a function of dis-)-3.542
+F(tance from the recei)108 717.6 Q -.15(ve)-.25 G 2.5(rc).15 G
+(an be generated by using the)-2.5 E F1(-e)2.5 E F0(switch:)2.5 E
+(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(4)195.95 E
+EP
+%%Page: 5 5
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E/F1 10/Courier@0 SF
+(splat -t tx_site -r rx_site -e elevation_profile.gif)108 84 Q F0 .425
+(The graph produced using this switch illustrates the ele)108 108 R -.25
+(va)-.25 G .424(tion and depression angles resulting from the ter).25 F
+(-)-.2 E .553(rain between the recei)108 120 R -.15(ve)-.25 G(r').15 E
+3.053(sl)-.55 G .553
+(ocation and the transmitter site from the perspecti)-3.053 F .854 -.15
+(ve o)-.25 H 3.054(ft).15 G .554(he recei)-3.054 F -.15(ve)-.25 G(r').15
+E 3.054(sl)-.55 G(ocation.)-3.054 E 3.781(As)108 132 S 1.281
+(econd trace is plotted between the left side of the graph \(recei)
+-3.781 F -.15(ve)-.25 G(r').15 E 3.78(sl)-.55 G 1.28
+(ocation\) and the location of the)-3.78 F .448
+(transmitting antenna on the right.)108 144 R .449
+(This trace illustrates the ele)5.448 F -.25(va)-.25 G .449
+(tion angle required for a line-of-sight path).25 F 1.074(to e)108 156 R
+1.074(xist between the recei)-.15 F -.15(ve)-.25 G 3.574(ra).15 G 1.074
+(nd transmitter locations.)-3.574 F 1.074
+(If the trace intersects the ele)6.074 F -.25(va)-.25 G 1.073
+(tion pro\214le at an).25 F(y)-.15 E 1.031(point on the graph, then thi\
+s is an indication that a line-of-sight path does not e)108 168 R 1.032
+(xist under the conditions)-.15 F(gi)108 180 Q -.15(ve)-.25 G(n, and th\
+e obstructions can be clearly identi\214ed on the graph at the point\(s\
+\) of intersection.).15 E 3.671(Ag)108 204 S 1.171(raph illustrating te\
+rrain height referenced to a line-of-sight path between the transmitter\
+ and recei)-3.671 F -.15(ve)-.25 G(r).15 E(may be generated using the)
+108 216 Q/F2 10/Times-Italic@0 SF(-h)2.5 E F0(switch:)2.5 E F1
+(splat -t tx_site -r rx_site -h height_profile.gif)108 240 Q F0
+(The Earth')108 264 Q 2.5(sc)-.55 G(urv)-2.5 E(ature is clearly e)-.25 E
+(vident when plotting height pro\214les.)-.25 E 2.5(Ag)108 288 S
+(raph sho)-2.5 E(wing Longle)-.25 E
+(y-Rice path loss may be plotted using the)-.15 E F2(-l)2.5 E F0
+(switch:)2.5 E F1(splat -t tx_site -r rx_site -l path_loss_profile.gif)
+108 312 Q F0 .886(When performing path loss pro\214les, a Longle)108 336
+R .886(y-Rice Model P)-.15 F .886(ath Loss Report is generated by)-.15 F
+/F3 10/Times-Bold@0 SF(SPLA)3.386 E(T!)-.95 E F0(in)3.386 E .755
+(the form of a te)108 348 R .754(xt \214le with a)-.15 F F2(.lr)3.254 E
+(o)-.45 E F0 .754(\214lename e)3.254 F 3.254(xtension. The)-.15 F .754
+(report contains bearings and distances between)3.254 F .535
+(the transmitter and recei)108 360 R -.15(ve)-.25 G 1.335 -.4(r, a).15 H
+3.035(sw).4 G .536(ell as the Longle)-3.035 F .536
+(y-Rice path loss for v)-.15 F .536(arious distances between the trans-)
+-.25 F .096(mitter and recei)108 372 R -.15(ve)-.25 G 2.596(rl).15 G
+2.596(ocations. The)-2.596 F .096(mode of propag)2.596 F .095
+(ation for points along the path are gi)-.05 F -.15(ve)-.25 G 2.595(na)
+.15 G(s)-2.595 E F2(Line-of-Sight)2.595 E F0(,)A F2(Single Horizon)108
+384 Q F0(,)A F2(Double Horizon)2.5 E F0(,)A F2(Dif)2.5 E(fr)-.18 E
+(action Dominant)-.15 E F0 2.5(,a)C(nd)-2.5 E F2 -1.85 -.55(Tr o)2.5 H
+(poscatter Dominant).55 E F0(.)A 2.36 -.8(To d)108 408 T .76(etermine t\
+he signal-to-noise \(SNR\) ratio at remote location where random Johnso\
+n \(thermal\) noise is).8 F(the primary limiting f)108 420 Q
+(actor in reception:)-.1 E F2(SNR)108.33 444 Q/F4 10/Symbol SF(=)3.07 E
+F2(T)2.71 E F4(-)3.47 E F2(NJ)2.9 E F4(-)3.17 E F2(L)2.78 E F4(+)2.73 E
+F2(G)2.18 E F4(-)2.7 E F2(NF)2.9 E F0(where)108 468 Q F3(T)3.077 E F0
+.577(is the ERP of the transmitter in dBW)3.077 F(,)-.92 E F3(NJ)3.076 E
+F0 .576(is Johnson Noise in dBW \(-136 dBW for a 6 MHz TV)3.076 F
+(channel\),)108 480 Q F3(L)2.513 E F0 .013(is the path loss pro)2.513 F
+.013(vided by)-.15 F F3(SPLA)2.513 E(T!)-.95 E F0 .014(in dB \(as a)
+2.513 F F2(positive)2.514 E F0(number\),)2.514 E F3(G)2.514 E F0 .014
+(is the recei)2.514 F .314 -.15(ve a)-.25 H .014(ntenna g).15 F(ain)-.05
+E(in dB o)108 492 Q -.15(ve)-.15 G 2.5(ri).15 G(sotropic, and)-2.5 E F3
+(NF)2.5 E F0(is the recei)2.5 E -.15(ve)-.25 G 2.5(rn).15 G
+(oise \214gure in dB.)-2.5 E F3(T)108 516 Q F0(may be computed as follo)
+2.5 E(ws:)-.25 E F2(T)107.91 540 Q F4(=)4.07 E F2(TI)2.71 E F4(+)3.21 E
+F2(GT)2.18 E F0(where)108 564 Q F3(TI)3.055 E F0 .555
+(is actual amount of RF po)3.055 F .555(wer deli)-.25 F -.15(ve)-.25 G
+.555(red to the transmitting antenna in dBW).15 F(,)-.92 E F3(GT)3.055 E
+F0 .555(is the transmit-)3.055 F .669(ting antenna g)108 576 R .669
+(ain \(o)-.05 F -.15(ve)-.15 G 3.169(ri).15 G .669
+(sotropic\) in the direction of the recei)-3.169 F -.15(ve)-.25 G 3.17
+(r\().15 G .67(or the horizon if the recei)-3.17 F -.15(ve)-.25 G 3.17
+(ri).15 G 3.17(so)-3.17 G -.15(ve)-3.32 G 3.17(rt).15 G(he)-3.17 E
+(horizon\).)108 588 Q 1.802 -.8(To c)108 612 T .202(ompute ho).8 F 2.702
+(wm)-.25 G .202(uch more signal is a)-2.702 F -.25(va)-.2 G .202
+(ilable o).25 F -.15(ve)-.15 G 2.702(rt).15 G .202
+(he minimum to necessary to achie)-2.702 F .501 -.15(ve a s)-.25 H .201
+(peci\214c signal-).15 F(to-noise ratio:)108 624 Q F2(Signal)108.33 648
+Q F0(_).51 E F2(Margin).68 E F4(=)3.04 E F2(SNR)3.13 E F4(-)2.47 E F2(S)
+2.53 E F0(where)108 672 Q F3(S)2.5 E F0
+(is the minimum desired SNR ratio \(15.5 dB for A)2.5 E(TSC DTV)-1.11 E
+2.5(,4)-1.29 G 2.5(2d)-2.5 G 2.5(Bf)-2.5 G(or analog NTSC tele)-2.5 E
+(vision\).)-.25 E 2.61(At)108 696 S .11
+(opographic map may be generated by)-2.61 F F3(SPLA)2.611 E(T!)-.95 E F0
+.111(to visualize the path between the transmitter and recei)2.611 F
+-.15(ve)-.25 G(r).15 E .099(sites from yet another perspecti)108 708 R
+-.15(ve)-.25 G 5.099(.T).15 G .099(opographic maps generated by)-5.899 F
+F3(SPLA)2.598 E(T!)-.95 E F0 .098(display ele)2.598 F -.25(va)-.25 G
+.098(tions using a log-).25 F .335(arithmic grayscale, with higher ele)
+108 720 R -.25(va)-.25 G .335
+(tions represented through brighter shades of gray).25 F 5.336(.T)-.65 G
+.336(he dynamic range)-5.336 F(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F
+(January 2004)2.5 E(5)195.95 E EP
+%%Page: 6 6
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E .257
+(of the image is scaled between the highest and lo)108 84 R .257
+(west ele)-.25 F -.25(va)-.25 G .257(tions present in the map.).25 F
+.257(The only e)5.257 F .257(xception to)-.15 F(this is sea-le)108 96 Q
+-.15(ve)-.25 G(l, which is represented in blue.).15 E/F1 10/Times-Bold@0
+SF(SPLA)108 120 Q(T!)-.95 E F0 1.241
+(generated topographic maps are 24-bit T)3.74 F 1.241
+(rueColor Portable PixMap \(PPM\) images, and may be)-.35 F(vie)108 132
+Q 1.06(wed, edited, or con)-.25 F -.15(ve)-.4 G 1.06
+(rted to other graphic formats by popular image vie).15 F 1.06
+(wing applications such as)-.25 F F1(xv)3.56 E F0(,)A F1 1.66(The GIMP)
+108 144 R F0(,)A F1(ImageMagick)4.16 E F0 4.16(,a)C(nd)-4.16 E F1(XP)
+4.16 E(aint)-.1 E F0 6.66(.P)C 1.66
+(NG format is highly recommended for lossless compressed)-6.66 F .372
+(storage of)108 156 R F1(SPLA)2.872 E(T!)-.95 E F0 .372
+(generated topographic output \214les.)5.372 F .371(An e)5.372 F .371
+(xcellent command-line utility capable of con-)-.15 F -.15(ve)108 168 S
+(rting).15 E F1(SPLA)12.216 E(T!)-.95 E F0 9.717
+(PPM graphic \214les to PNG \214les is)12.217 F F1(wpng)12.217 E F0
+12.217(,a)C 9.717(nd is a)-12.217 F -.25(va)-.2 G 9.717(ilable at:).25 F
+/F2 10/Times-Italic@0 SF(http://www)108 180 Q(.libpng)-.74 E(.or)-.15 E
+(g/pub/png/book/sour)-.37 E(ces.html)-.37 E F0 5.153(.A)C 2.653(sal)
+-5.153 G .153(ast resort, PPM \214les may be compressed using the)-2.653
+F .661(bzip2 utility)108 192 R 3.161(,a)-.65 G .661(nd read directly by)
+-3.161 F F1 .662(The GIMP)3.162 F F0 .662(in this format.)3.162 F -.8
+(To)5.662 G .662(pographic output is speci\214ed using the).8 F F2(-o)
+3.162 E F0(switch:)108 204 Q/F3 10/Courier@0 SF
+(splat -t tx_site -r rx_site -o topo_map.ppm)108 228 Q F0(The)108 252 Q
+F2(.ppm)2.5 E F0 -.15(ex)2.5 G
+(tension on the output \214lename is assumed by).15 E F1(SPLA)2.5 E(T!)
+-.95 E F0 2.5(,a)C(nd is optional.)-2.5 E .007(In this e)108 276 R
+(xample,)-.15 E F2(topo_map.ppm)2.507 E F0 .007
+(will illustrate the locations of the transmitter and recei)2.507 F -.15
+(ve)-.25 G 2.506(rs).15 G .006(ites speci\214ed.)-2.506 F(In)5.006 E .22
+(addition, the great circle path between the tw)108 288 R 2.72(os)-.1 G
+.22(ites will be dra)-2.72 F .22(wn o)-.15 F -.15(ve)-.15 G 2.72(rl).15
+G .22(ocations for which an unobstructed)-2.72 F 1.209(path e)108 300 R
+1.209(xists to the transmitter at a recei)-.15 F 1.209
+(ving antenna height equal to that of the recei)-.25 F -.15(ve)-.25 G
+3.709(rs).15 G 1.208(ite \(speci\214ed in)-3.709 F F2(rx_site)108 312 Q
+(.qth)-.15 E F0(\).)A .773(It may desirable to populate the topographic\
+ map with names and locations of cities, to)108 336 R .773
+(wer sites, or other)-.25 F(important locations.)108 348 Q 2.5(Ac)5 G
+(ity \214le may be passed to)-2.5 E F1(SPLA)2.5 E(T!)-.95 E F0
+(using the)2.5 E F2(-s)2.5 E F0(switch:)2.5 E F3
+(splat -t tx_site -r rx_site -s cities.dat -o topo_map)108 372 Q F0
+(Up to \214v)108 396 Q 2.5(es)-.15 G
+(eparate city \214les may be passed to)-2.5 E F1(SPLA)2.5 E(T!)-.95 E F0
+(at a time follo)2.5 E(wing the)-.25 E F2(-s)2.5 E F0(switch.)2.5 E .555
+(County and state boundaries may be added to the map by specifying up t\
+o \214v)108 420 R 3.054(eU)-.15 G .554(.S. Census Bureau carto-)-3.054 F
+(graphic boundary \214les using the)108 432 Q F2(-b)2.5 E F0(switch:)2.5
+E F3(splat -t tx_site -r rx_site -b co34_d00.dat -o topo_map)108 456 Q
+F0 1.063
+(In situations where multiple transmitter sites are in use, as man)108
+480 R 3.563(ya)-.15 G 3.563(sf)-3.563 G 1.064
+(our site locations may be passed to)-3.563 F F1(SPLA)108 492 Q(T!)-.95
+E F0(at a time for analysis:)2.5 E F3
+(splat -t tx_site1 tx_site2 tx_site3 tx_site4 -r rx_site -p profile.gif)
+108 516 Q F0 .285(In this e)108 540 R .285(xample, four separate terrai\
+n pro\214les and obstruction reports will be generated by)-.15 F F1
+(SPLA)2.785 E(T!)-.95 E F0 5.285(.A)C(sin-)-2.5 E .508
+(gle topographic map can be speci\214ed using the)108 552 R F2(-o)3.009
+E F0 .509(switch, and line-of-sight paths between each transmitter)3.009
+F .817(and the recei)108 564 R -.15(ve)-.25 G 3.317(rs).15 G .816
+(ite indicated will be produced on the map, each in its o)-3.317 F .816
+(wn color)-.25 F 5.816(.T)-.55 G .816(he path between the)-5.816 F .766
+(\214rst transmitter speci\214ed to the recei)108 576 R -.15(ve)-.25 G
+3.266(rw).15 G .767
+(ill be in green, the path between the second transmitter and the)-3.266
+F(recei)108 588 Q -.15(ve)-.25 G 3.464(rw).15 G .964(ill be in c)-3.464
+F .964(yan, the path between the third transmitter and the recei)-.15 F
+-.15(ve)-.25 G 3.463(rw).15 G .963(ill be in violet, and the)-3.463 F
+(path between the fourth transmitter and the recei)108 600 Q -.15(ve)
+-.25 G 2.5(rw).15 G(ill be in sienna.)-2.5 E/F4 10.95/Times-Bold@0 SF
+(DETERMINING REGION)72 616.8 Q(AL CO)-.219 E(VERA)-.548 E(GE)-.602 E F1
+(SPLA)108 628.8 Q(T!)-.95 E F0 .098
+(can analyze a transmitter or repeater site, or netw)2.598 F .098
+(ork of sites, and predict the re)-.1 F .099(gional co)-.15 F -.15(ve)
+-.15 G .099(rage for).15 F .683(each site speci\214ed.)108 640.8 R .683
+(In this mode,)5.683 F F1(SPLA)3.183 E(T!)-.95 E F0 .682
+(can generate a topographic map displaying the geometric line-)3.183 F
+.031(of-sight co)108 652.8 R -.15(ve)-.15 G .031(rage area of the sites\
+ based on the location of each site, and the height of recei).15 F .331
+-.15(ve a)-.25 H .032(ntenna wish-).15 F .439
+(ing to communicate with the site in question.)108 664.8 R F1(SPLA)5.439
+E(T!)-.95 E F0 .438(switches from point-to-point analysis mode to area)
+2.939 F(prediction mode when the)108 676.8 Q F2(-c)2.5 E F0
+(switch is in)2.5 E -.2(vo)-.4 G -.1(ke).2 G 2.5(da).1 G 2.5(sf)-2.5 G
+(ollo)-2.5 E(ws:)-.25 E F3
+(splat -t tx_site -c 30.0 -s cities.dat -b co34_d00.dat -o tx_coverage)
+108 700.8 Q F0 .269(In this e)108 724.8 R(xample,)-.15 E F1(SPLA)2.769 E
+(T!)-.95 E F0 .269(generates a topographic map called)2.769 F F2(tx_co)
+2.769 E(ver)-.1 E -.1(age)-.15 G(.ppm)-.05 E F0 .27
+(that illustrates the predicted)2.769 F(KD2BD Softw)72 768 Q 126.62
+(are 20)-.1 F(January 2004)2.5 E(6)195.95 E EP
+%%Page: 7 7
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E 1.535
+(line-of-sight re)108 84 R 1.535(gional co)-.15 F -.15(ve)-.15 G 1.535
+(rage of).15 F/F1 10/Times-Italic@0 SF(tx_site)4.035 E F0 1.535
+(to recei)4.035 F 1.535(ving locations ha)-.25 F 1.534
+(ving antennas 30.0 feet abo)-.2 F 1.834 -.15(ve g)-.15 H(round).15 E
+(le)108 96 Q -.15(ve)-.25 G 2.507(l\().15 G -.4(AG)-2.507 G 2.507
+(L\). The).4 F .007(contents of)2.507 F F1(cities.dat)2.507 E F0 .008
+(are plotted on the map, as are the cartographic boundaries contained)
+2.507 F(in the \214le)108 108 Q F1(co34_d00.dat)2.5 E F0(.)A .572
+(When plotting line-of-sight paths and areas of re)108 132 R .572
+(gional co)-.15 F -.15(ve)-.15 G(rage,).15 E/F2 10/Times-Bold@0 SF(SPLA)
+3.072 E(T!)-.95 E F0 .572(by def)3.072 F .572(ault does not account for)
+-.1 F .031(the ef)108 144 R .032(fects of atmospheric bending.)-.25 F
+(Ho)5.032 E(we)-.25 E -.15(ve)-.25 G .832 -.4(r, t).15 H .032(his beha)
+.4 F .032(vior may be modi\214ed by using the Earth radius mul-)-.2 F
+(tiplier \()108 156 Q F1(-m)A F0 2.5(\)s)C(witch:)-2.5 E/F3 10/Courier@0
+SF(splat -t wnjt -c 30.0 -m 1.333 -s cities.dat -b counties.dat -o map.\
+ppm)108 180 Q F0 .428(An earth radius multiplier)108 204 R .428
+(of 1.333 instructs)5.428 F F2(SPLA)2.928 E(T!)-.95 E F0 .428
+(to use the "four)2.928 F .428(-thirds earth" model for line-of-sight)
+-.2 F(propag)108 216 Q(ation analysis.)-.05 E(An)5 E 2.5(ya)-.15 G
+(ppropriate earth radius multiplier may be selected by the user)-2.5 E
+(.)-.55 E .201(When in)108 240 R -.2(vo)-.4 G -.1(ke).2 G 2.701(di).1 G
+2.701(na)-2.701 G .201(rea prediction mode,)-2.701 F F2(SPLA)2.701 E(T!)
+-.95 E F0 .202(generates a site report for each station analyzed.)2.701
+F F2(SPLA)5.202 E(T!)-.95 E F0 .659
+(site reports contain details of the site')108 252 R 3.159(sg)-.55 G
+.659(eographic location, its height abo)-3.159 F .959 -.15(ve m)-.15 H
+.658(ean sea le).15 F -.15(ve)-.25 G .658(l, the antenna').15 F(s)-.55 E
+.612(height abo)108 264 R .912 -.15(ve m)-.15 H .612(ean sea le).15 F
+-.15(ve)-.25 G .612(l, the antenna').15 F 3.112(sh)-.55 G .612
+(eight abo)-3.112 F .912 -.15(ve a)-.15 H -.15(ve)-.05 G .613
+(rage terrain, and the height of the a).15 F -.15(ve)-.2 G .613
+(rage ter).15 F(-)-.2 E(rain calculated in the directions of 0, 45, 90,\
+ 135, 180, 225, 270, and 315 de)108 276 Q(grees azimuth.)-.15 E .345
+(If the)108 300 R F1(-c)2.845 E F0 .345(switch is replaced by a)2.845 F
+F1(-L)2.844 E F0 .344(switch, a Longle)2.844 F .344
+(y-Rice path loss map for a transmitter site may be gen-)-.15 F(erated:)
+108 312 Q F3(splat -t tx_site -L 30.0 -s cities.dat -b co34_d00.dat -o \
+path_loss_map)108 336 Q F0 .977(In this mode,)108 360 R F2(SPLA)3.477 E
+(T!)-.95 E F0 .977(generates a multi-color map illustrating e)3.477 F
+.977(xpected signal le)-.15 F -.15(ve)-.25 G .978
+(ls \(path loss\) in areas).15 F .997(surrounding the transmitter site.)
+108 372 R 3.497(Al)5.997 G -.15(eg)-3.497 G .996
+(end at the bottom of the map correlates each color with a speci\214c)
+.15 F .163(path loss le)108 384 R -.15(ve)-.25 G 2.663(li).15 G 2.663
+(nd)-2.663 G 2.663(ecibels. Since)-2.663 F(Longle)2.663 E .163
+(y-Rice area prediction map generation is quite CPU intensi)-.15 F -.15
+(ve)-.25 G 2.664(,p).15 G(ro-)-2.664 E .014
+(vision for limiting the analysis range is pro)108 396 R .014
+(vided by the)-.15 F F1(-R)2.514 E F0 2.514(switch. The)2.514 F(ar)2.514
+E .013(gument must be gi)-.18 F -.15(ve)-.25 G 2.513(ni).15 G 2.513(nm)
+-2.513 G 2.513(iles. If)-2.513 F 3.58(ar)108 408 S 1.08
+(ange wider than the generated topographic map is speci\214ed,)-3.58 F
+F2(SPLA)3.58 E(T!)-.95 E F0 1.08(will perform Longle)3.58 F 1.08
+(y-Rice path)-.15 F
+(loss calculations between all four corners of the area prediction map.)
+108 420 Q/F4 10.95/Times-Bold@0 SF(DETERMINING MUL)72 436.8 Q
+(TIPLE REGIONS OF CO)-1.007 E(VERA)-.548 E(GE)-.602 E F2(SPLA)108 448.8
+Q(T!)-.95 E F0 1.087(can also display line-of-sight co)3.587 F -.15(ve)
+-.15 G 1.086(rage areas for as man).15 F 3.586(ya)-.15 G 3.586(sf)-3.586
+G 1.086(our separate transmitter sites on a)-3.586 F
+(common topographic map.)108 460.8 Q -.15(Fo)5 G 2.5(re).15 G(xample:)
+-2.65 E F3(splat -t site1 site2 site3 site4 -c 30.0 -o network.ppm)108
+484.8 Q F0 .686(plots the re)108 508.8 R .687(gional line-of-sight co)
+-.15 F -.15(ve)-.15 G .687
+(rage of site1, site2, site3, and site4 based on a recei).15 F .987 -.15
+(ve a)-.25 H .687(ntenna located).15 F .277(30.0 feet abo)108 520.8 R
+.577 -.15(ve g)-.15 H .277(round le).15 F -.15(ve)-.25 G 2.776(l. A).15
+F .276(topographic map is then written to the \214le)2.776 F F1
+(network.ppm)2.776 E F0 5.276(.T)C .276(he line-of-sight)-5.276 F(co)108
+532.8 Q -.15(ve)-.15 G .2
+(rage area of the transmitters are plotted as follo).15 F .2
+(ws in the colors indicated \(along with their correspond-)-.25 F
+(ing RGB v)108 544.8 Q(alues in decimal\):)-.25 E F3
+(site1: Green \(0,255,0\))132 568.8 Q(site2: Cyan \(0,255,255\))132
+580.8 Q(site3: Medium Violet \(147,112,219\))132 592.8 Q
+(site4: Sienna 1 \(255,130,71\))132 604.8 Q
+(site1 + site2: Yellow \(255,255,0\))132 628.8 Q
+(site1 + site3: Pink \(255,192,203\))132 640.8 Q
+(site1 + site4: Green Yellow \(173,255,47\))132 652.8 Q
+(site2 + site3: Orange \(255,165,0\))132 664.8 Q
+(site2 + site4: Dark Sea Green 1 \(193,255,193\))132 676.8 Q
+(site3 + site4: Dark Turquoise \(0,206,209\))132 688.8 Q
+(site1 + site2 + site3: Dark Green \(0,100,0\))132 712.8 Q
+(site1 + site2 + site4: Blanched Almond \(255,235,205\))132 724.8 Q F0
+(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(7)195.95 E
+EP
+%%Page: 8 8
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E/F1 10/Courier@0 SF
+(site1 + site3 + site4: Medium Spring Green \(0,250,154\))132 84 Q
+(site2 + site3 + site4: Tan \(210,180,140\))132 96 Q
+(site1 + site2 + site3 + site4: Gold2 \(238,201,0\))132 120 Q F0 .247
+(If separate)108 144 R/F2 10/Times-Italic@0 SF(.qth)2.747 E F0 .247
+(\214les are generated, each representing a common site location b)2.747
+F .247(ut a dif)-.2 F .246(ferent antenna height,)-.25 F 3.535(as)108
+156 S 1.035(ingle topographic map illustrating the re)-3.535 F 1.036
+(gional co)-.15 F -.15(ve)-.15 G 1.036(rage from as man).15 F 3.536(ya)
+-.15 G 3.536(sf)-3.536 G 1.036(our separate locations on a)-3.536 F
+(single to)108 168 Q(wer may be generated by)-.25 E/F3 10/Times-Bold@0
+SF(SPLA)2.5 E(T!)-.95 E F0(.)A/F4 10.95/Times-Bold@0 SF -.197(TO)72
+184.8 S(POGRAPHIC MAP GENERA).197 E(TION)-1.04 E F0 .52(In certain situ\
+ations, it may be desirable to generate a topographic map of a re)108
+196.8 R .519(gion without plotting co)-.15 F -.15(ve)-.15 G -.2(r-).15 G
+1.006
+(age areas, line-of-sight paths, or generating obstruction reports.)108
+208.8 R 1.007(There are se)6.007 F -.15(ve)-.25 G 1.007(ral w).15 F
+1.007(ays of doing this.)-.1 F(If)6.007 E .814(one wishes to generate a\
+ topographic map illustrating the location of a transmitter and recei)
+108 220.8 R -.15(ve)-.25 G 3.314(rs).15 G .814(ite along)-3.314 F 1.175
+(with a brief te)108 232.8 R 1.176(xt report describing the locations a\
+nd distances between the sites, the)-.15 F F2(-n)3.676 E F0 1.176
+(switch should be)3.676 F(in)108 244.8 Q -.2(vo)-.4 G -.1(ke).2 G 2.5
+(da).1 G 2.5(sf)-2.5 G(ollo)-2.5 E(ws:)-.25 E F1
+(splat -t tx_site -r rx_site -n -o topo_map.ppm)108 268.8 Q F0(If no te)
+108 292.8 Q(xt report is desired, then the)-.15 E F2(-N)2.5 E F0
+(switch is used:)2.5 E F1
+(splat -t tx_site -r rx_site -N -o topo_map.ppm)108 316.8 Q F0 .061
+(If the)108 340.8 R F2(-o)2.561 E F0 .061
+(switch and output \214lename are omitted when using either the)2.561 F
+F2(-n)2.56 E F0(or)2.56 E F2(-N)2.56 E F0 .06
+(switches, output is written to)2.56 F 2.5<618c>108 352.8 S(le named)
+-2.5 E F2(map.ppm)2.5 E F0(in the current w)2.5 E
+(orking directory by def)-.1 E(ault.)-.1 E F4(DETERMIN)72 369.6 Q -1.04
+(AT)-.219 G(ION OF ANTENN)1.04 E 2.738(AH)-.219 G(EIGHT ABO)-2.738 E
+(VE A)-.548 E(VERA)-1.588 E(GE TERRAIN)-.602 E F3(SPLA)108 381.6 Q(T!)
+-.95 E F0 .947(determines antenna height abo)3.447 F 1.248 -.15(ve a)
+-.15 H -.15(ve)-.05 G .948(rage terrain \(HAA).15 F .948
+(T\) according to the procedure de\214ned by)-1.11 F .167
+(Federal Communications Commission P)108 393.6 R .167(art 73.313\(d\).)
+-.15 F .166(According to this de\214nition, terrain ele)5.166 F -.25(va)
+-.25 G .166(tions along).25 F .794(eight radials between 2 and 10 miles\
+ \(3 and 16 kilometers\) from the site being analyzed are sampled and)
+108 405.6 R -2.25 -.2(av e)108 417.6 T .614(raged for each 45 de).2 F
+.613(grees of azimuth starting with T)-.15 F .613(rue North.)-.35 F .613
+(If one or more radials lie entirely o)5.613 F -.15(ve)-.15 G(r).15 E
+-.1(wa)108 429.6 S(ter).1 E 2.911(,o)-.4 G 2.911(ro)-2.911 G -.15(ve)
+-3.061 G 2.911(rl).15 G .411
+(and outside the United States \(areas for which no USGS topograph)
+-2.911 F 2.911(yd)-.05 G .412(ata is a)-2.911 F -.25(va)-.2 G .412
+(ilable\), then).25 F .519
+(those radials are omitted from the calculation of a)108 441.6 R -.15
+(ve)-.2 G .519(rage terrain.).15 F .519(If part of a radial e)5.519 F
+.519(xtends o)-.15 F -.15(ve)-.15 G 3.019(rab).15 G .518(ody of)-3.019 F
+-.1(wa)108 453.6 S .012(ter or o).1 F -.15(ve)-.15 G 2.512(rl).15 G .012
+(and outside the United States, then only that part of the radial lying\
+ o)-2.512 F -.15(ve)-.15 G 2.513(rU).15 G .013(nited States land is)
+-2.513 F(used in the determination of a)108 465.6 Q -.15(ve)-.2 G
+(rage terrain.).15 E .162
+(When performing point-to-point terrain analysis,)108 489.6 R F3(SPLA)
+2.662 E(T!)-.95 E F0 .162(determines the antenna height abo)2.662 F .461
+-.15(ve a)-.15 H -.15(ve)-.05 G .161(rage ter).15 F(-)-.2 E .407(rain o\
+nly if enough topographic data has already been loaded by the program t\
+o perform the point-to-point)108 501.6 R 3.712(analysis. In)108 513.6 R
+1.211(most cases, this will be true, unless the site in question does n\
+ot lie within 10 miles of the)3.712 F(boundary of the topograph)108
+525.6 Q 2.5(yd)-.05 G(ata in memory)-2.5 E(.)-.65 E .491
+(When performing area prediction analysis, enough topograph)108 549.6 R
+2.991(yd)-.05 G .492(ata is normally loaded by)-2.991 F F3(SPLA)2.992 E
+(T!)-.95 E F0 .492(to per)2.992 F(-)-.2 E .807(form a)108 561.6 R -.15
+(ve)-.2 G .807(rage terrain calculations.).15 F .807
+(Under such conditions,)5.807 F F3(SPLA)3.307 E(T!)-.95 E F0 .807
+(will pro)3.307 F .807(vide the antenna height abo)-.15 F -.15(ve)-.15 G
+-2.25 -.2(av e)108 573.6 T .203(rage terrain as well as the a).2 F -.15
+(ve)-.2 G .203(rage terrain abo).15 F .503 -.15(ve m)-.15 H .203
+(ean sea le).15 F -.15(ve)-.25 G 2.704(lf).15 G .204
+(or azimuths of 0, 45, 90, 135, 180, 225,)-2.704 F .162(270, and 315 de)
+108 585.6 R .162
+(grees, and include such information in the site report generated.)-.15
+F .161(If one or more of the eight)5.161 F 1.259(radials surv)108 597.6
+R -.15(ey)-.15 G 1.259(ed f).15 F 1.259(all o)-.1 F -.15(ve)-.15 G 3.759
+(rw).15 G 1.259(ater or land outside the United States,)-3.859 F F3
+(SPLA)3.76 E(T!)-.95 E F0(reports)3.76 E F2 1.26(No T)3.76 F(err)-.92 E
+(ain)-.15 E F0 1.26(for those)3.76 F(radial paths.)108 609.6 Q F4
+(SETTING THE MAXIMUM SIZE OF AN AN)72 626.4 Q(AL)-.219 E(YSIS REGION)
+-1.007 E F3(SPLA)108 638.4 Q(T!)-.95 E F0 .971(reads SDF \214les into a\
+ series of memory "slots" as required within the structure of the progr\
+am.)3.471 F .508(Each "slot" holds one SDF \214le.)108 650.4 R .508
+(Each SDF \214le represents a one de)5.508 F .508(gree by one de)-.15 F
+.508(gree re)-.15 F .508(gion of terrain.)-.15 F(A)5.508 E F2 1.237
+(#de\214ne MAXSLO)108 662.4 R(TS)-.4 E F0 1.237
+(statement in the \214rst se)3.737 F -.15(ve)-.25 G 1.237(ral lines of)
+.15 F F2(splat.cpp)3.737 E F0 1.236(sets the maximum number of "slots")
+3.737 F -.2(av)108 674.4 S 2.412(ailable for topograph)-.05 F 4.912(yd)
+-.05 G 4.912(ata. It)-4.912 F 2.412
+(also sets the maximum size of the topographic maps generated by)4.912 F
+F3(SPLA)108 686.4 Q(T!)-.95 E F0 5.883(.M)C(AXSLO)-5.883 E .883
+(TS is set to 9 by def)-.4 F 3.383(ault. If)-.1 F F3(SPLA)3.382 E(T!)
+-.95 E F0 .882(produces a se)3.382 F .882(gmentation f)-.15 F .882
+(ault on start-up with)-.1 F .78(this def)108 698.4 R .78(ault, it is a\
+n indication that not enough RAM and/or virtual memory \(sw)-.1 F .78
+(ap space\) are a)-.1 F -.25(va)-.2 G .78(ilable to).25 F(run)108 710.4
+Q F3(SPLA)3.119 E(T!)-.95 E F0 .618(with this number of MAXSLO)3.119 F
+3.118(TS. In)-.4 F .618(this case, MAXSLO)3.118 F .618
+(TS may be reduced to 4, although)-.4 F .617
+(this will greatly limit the maximum re)108 722.4 R(gion)-.15 E F3(SPLA)
+3.117 E(T!)-.95 E F0 .617(will be able to analyze.)3.117 F .617
+(If 118 me)5.617 F -.05(ga)-.15 G .618(bytes or more of).05 F
+(KD2BD Softw)72 768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(8)195.95 E
+EP
+%%Page: 9 9
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(SPLA)72 48 Q 151.145(T!\(1\) KD2BD)-1.11 F
+(Softw)2.5 E 151.145(are SPLA)-.1 F(T!\(1\))-1.11 E 1.004
+(total memory \(sw)108 84 R 1.003(ap space plus RAM\) is a)-.1 F -.25
+(va)-.2 G 1.003(ilable, then MAXSLO).25 F 1.003
+(TS may be increased to 16.)-.4 F 1.003(This will)6.003 F .081
+(permit operation o)108 96 R -.15(ve)-.15 G 2.581(ra4).15 G(-de)-2.581 E
+.081(gree by 4-de)-.15 F .081(gree re)-.15 F .081(gion, which is suf)
+-.15 F .082(\214cient for single antenna heights in e)-.25 F(xcess)-.15
+E(of 10,000 feet abo)108 108 Q .3 -.15(ve m)-.15 H(ean sea le).15 E -.15
+(ve)-.25 G(l, or point-to-point distances of o).15 E -.15(ve)-.15 G 2.5
+(r1).15 G(000 miles.)-2.5 E/F1 10.95/Times-Bold@0 SF(ADDITION)72 124.8 Q
+(AL INFORMA)-.219 E(TION)-1.04 E F0(In)108 136.8 Q -.2(vo)-.4 G(king).2
+E/F2 10/Times-Bold@0 SF(SPLA)2.811 E(T!)-.95 E F0 .311(without an)2.811
+F 2.811(ya)-.15 G -.18(rg)-2.811 G .311
+(uments will display all the command-line options a).18 F -.25(va)-.2 G
+.31(ilable with the pro-).25 F(gram along with a brief summary of each.)
+108 148.8 Q .332(The latest ne)108 172.8 R .332(ws and information re)
+-.25 F -.05(ga)-.15 G(rding).05 E F2(SPLA)2.832 E(T!)-.95 E F0(softw)
+2.832 E .332(are is a)-.1 F -.25(va)-.2 G .332(ilable through the of).25
+F(\214cial)-.25 E F2(SPLA)2.833 E(T!)-.95 E F0(soft-)2.833 E -.1(wa)108
+184.8 S(re web page located at:).1 E/F3 10/Times-Italic@0 SF(http://www)
+2.5 E(.qsl.net/kd2bd/splat.html)-.74 E F0(.)A F1(FILES)72 201.6 Q/F4 10
+/Courier@0 SF($HOME/.splat_path)108 213.6 Q F0(User)144 225.6 Q
+(-generated \214le containing the def)-.2 E
+(ault path to the directory containing the SDF data \214les.)-.1 E F4
+(splat.lrp)108 242.4 Q F0(Def)144 254.4 Q(ault Longle)-.1 E
+(y-Rice model parameters.)-.15 E F1 -.548(AU)72 271.2 S(THORS).548 E F0
+(John A. Magliacane, KD2BD <)108 283.2 Q F3(kd2bd@amsat.or)A(g)-.37 E F0
+(>)A(Creator)144 295.2 Q 2.5(,L)-.4 G(ead De)-2.5 E -.15(ve)-.25 G
+(loper).15 E(Doug McDonald <)108 312 Q F3(mcdonald@scs.uiuc.edu)A F0(>)A
+(Longle)144 324 Q(y-Rice Model inte)-.15 E(gration)-.15 E(KD2BD Softw)72
+768 Q 126.62(are 20)-.1 F(January 2004)2.5 E(9)195.95 E EP
+%%Trailer
+end
+%%EOF
diff --git a/docs/text/splat.txt b/docs/text/splat.txt
new file mode 100644 (file)
index 0000000..40fc60a
--- /dev/null
@@ -0,0 +1,683 @@
+SPLAT!(1)                 KD2BD Software                SPLAT!(1)
+
+
+
+NAME
+       splat  -  A Signal Propagation, Loss, And Terrain analysis
+       tool
+
+SYNOPSIS
+       splat [-t transmitter_site.qth] [-r receiver_site.qth] [-c
+       rx_antenna_height_for_los_coverage_analysis         (feet)
+       (float)]   [-L   rx_antenna_height_for_Longley-Rice_cover-
+       age_analysis  (feet) (float)] [-p terrain_profile.ext] [-e
+       elevation_profile.ext] [-h height_profile.ext]  [-l  Long-
+       ley-Rice_profile.ext]   [-o  topographic_map_filename.ppm]
+       [-b        cartographic_boundary_filename.dat]         [-s
+       site/city_database.dat]    [-d   sdf_directory_path]   [-m
+       earth_radius_multiplier   (float)]   [-R    maximum_cover-
+       age_range (for -c or -L) (miles) (float)] [-n] [-N]
+
+DESCRIPTION
+       SPLAT!  is  a  simple,  yet powerful terrain analysis tool
+       written for Unix and Linux-based workstations.  SPLAT!  is
+       free software.  Redistribution and/or modification is per-
+       mitted under the terms of the GNU General  Public  License
+       as  published by the Free Software Foundation, either ver-
+       sion 2 of the License or any later version.   Adoption  of
+       SPLAT!  source code in proprietary or closed-source appli-
+       cations is a violation of this license,  and  is  strictly
+       forbidden.
+
+       SPLAT!  is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY, without even  the  implied  war-
+       ranty  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR-
+       POSE. See the GNU General Public License for more details.
+
+INTRODUCTION
+       SPLAT!  is  a terrestrial RF propagation analysis tool for
+       the spectrum between 20  MHz  and  20  GHz,  and  provides
+       information  of interest to communication system designers
+       and site engineers.  SPLAT! determines great  circle  dis-
+       tances  and  bearings  between  sites,  antenna  elevation
+       angles (uptilt),  depression  angles  (downtilt),  antenna
+       height  above mean sea level, antenna height above average
+       terrain, bearings and  distances  to  known  obstructions,
+       Longley-Rice   path   loss,  and  minimum  antenna  height
+       requirements needed to establish line-of-sight  communica-
+       tion  paths absent of obstructions due to terrain.  SPLAT!
+       produces reports, graphs, and highly  detailed  and  care-
+       fully  annotated  topographic maps depicting line-of-sight
+       paths, path loss, and expected coverage areas of transmit-
+       ters  and repeater systems.  When performing line-of-sight
+       analysis  in  situations  where  multiple  transmitter  or
+       repeater  sites are employed, SPLAT! determines individual
+       and mutual areas of coverage within the network specified.
+
+       SPLAT!  operates  in  two  modes: point-to-point mode, and
+       area prediction mode.  These modes may  be  invoked  using
+       either  line-of-sight  (LOS)  or  Irregular  Terrain (ITM)
+       propagation models.  True Earth, four-thirds Earth, or any
+       other  Earth radius may be specified by the user when per-
+       forming line-of-sight analysis.
+
+INPUT FILES
+       SPLAT! is a command-line  driven  application,  and  reads
+       input  data  through a number of data files.  Each has its
+       own format.  Some files are mandatory for successful  exe-
+       cution  of the program, while others are optional.  Manda-
+       tory files include SPLAT  Data  Files  (SDF  files),  site
+       location files (QTH files), and Longley-Rice model parame-
+       ter files (LRP files).  Optional files  include  city/site
+       location files, and cartographic boundary files.
+
+SPLAT DATA FILES
+       SPLAT!  imports topographic data in the form of SPLAT Data
+       Files (SDFs) that may be generated from a number of infor-
+       mation  sources.   In  the United States, SPLAT Data Files
+       are most often derived from U.S.  Geological Survey  Digi-
+       tal  Elevation  Models  (DEMs)  using the usgs2sdf utility
+       included with SPLAT!.  USGS Digital Elevation Models  com-
+       patible with this utility are available at no cost via the
+       Internet                  at:                  http://edc-
+       sgs9.cr.usgs.gov/glis/hyper/guide/1_dgr_dem-
+       fig/index1m.html.
+
+       SPLAT Data Files contain  topographic  elevations  to  the
+       nearest  meter  above  mean  sea  level  for  1-degree  by
+       1-degree regions of the earth with a resolution  of  3-arc
+       seconds.   SDF files can be read in either standard format
+       (.sdf) as generated by the usgs2sdf utility, or  in  bzip2
+       compressed  format  (.sdf.bz2).   Since uncompressed files
+       can be slightly faster  to  load  than  compressed  files,
+       SPLAT!  searches  for  the needed SDF data in uncompressed
+       format first.  If such data cannot  located,  then  SPLAT!
+       tries  to read the data in bzip2 compressed format.  If no
+       compressed  SDF  files  can  be  found  for   the   region
+       requested, SPLAT! assumes the region is over water or out-
+       side the United States, and will assign  an  elevation  of
+       sea-level to these areas.  This feature of SPLAT! makes it
+       possible to perform path analysis not only over land,  but
+       also between coastal areas not represented by USGS Digital
+       Elevation Model Data since they are  devoid  of  any  land
+       masses.   However, this behavior of SPLAT! underscores the
+       importance of having all the SDF files  required  for  the
+       region  being  analyzed  if  meaningful  results are to be
+       expected.
+
+SITE LOCATION (QTH) FILES
+       SPLAT! imports site location  information  of  transmitter
+       and  receiver  sites  analyzed  by  the program from ASCII
+       files having a .qth  extension.   QTH  files  contain  the
+       site's  name,  the site's latitude (in degrees North), the
+       site's longitude (in degrees West), and the site's antenna
+       height above ground level (AGL).  A single line-feed char-
+       acter separates each field.  The antenna height is assumed
+       to be specified in feet unless followed by the letter m or
+       the word meters in either upper or lower  case.   Latitude
+       and longitude information may be expressed in either deci-
+       mal format (74.6889) or degree, minute, second (DMS)  for-
+       mat (74 41 20.0).
+
+       For  example,  a  site location file describing television
+       station WNJT, Trenton, NJ (wnjt.qth) might  read  as  fol-
+       lows:
+
+               WNJT
+               40.2833
+               74.6889
+               990.00
+
+       Each transmitter and receiver site analyzed by SPLAT! must
+       be represented by its own site location (QTH) file.
+
+LONGLEY-RICE PARAMETER (LRP) FILES
+       SPLAT! imports  Longley-Rice  model  parameter  data  from
+       files  having  the  same base name as the transmitter site
+       QTH file, but carrying a .lrp  extension,  thus  providing
+       simple  and  accurate correlation between these associated
+       data sets.  The format for the Longley-Rice model  parame-
+       ter files is as follows (wnjt.lrp):
+
+               15.000  ; Earth Dielectric Constant (Relative per-
+       mittivity)
+               0.005   ; Earth Conductivity (Siemens per meter)
+               301.000 ; Atmospheric Bending Constant (N-units)
+               700.000 ; Frequency in MHz (20 MHz to 20 GHz)
+               5       ; Radio Climate (5 =  Continental  Temper-
+       ate)
+               0       ; Polarization (0 = Horizontal, 1 = Verti-
+       cal)
+               0.5     ; Fraction of  situations  (50%  of  loca-
+       tions)
+               0.5     ; Fraction of time (50% of the time)
+
+       If  an LRP file corresponding to the tx_site QTH file can-
+       not be found, SPLAT! scans the current  working  directory
+       for  the  file "splat.lrp".  If this file cannot be found,
+       then the default parameters listed above will be  assigned
+       by  SPLAT! and a corresponding "splat.lrp" file containing
+       this data will be written to the  current  working  direc-
+       tory.
+
+       Typical Earth dielectric constants and conductivity values
+       are as follows:
+
+                                  Dielectric Constant  Conductiv-
+       ity
+               Salt water       :        80                5.000
+               Good ground      :        25                0.020
+               Fresh water      :        80                0.010
+               Marshy land      :        12                0.007
+               Farmland, forest :        15                0.005
+               Average ground   :        15                0.005
+               Mountain, sand   :        13                0.002
+               City             :         5                0.001
+               Poor ground      :         4                0.001
+
+       Radio climate codes used by SPLAT! are as follows:
+
+               1: Equatorial (Congo)
+               2: Continental Subtropical (Sudan)
+               3: Maritime Subtropical (West coast of Africa)
+               4: Desert (Sahara)
+               5: Continental Temperate
+               6:  Maritime  Temperate,  over  land  (UK and west
+       coasts of US & EU)
+               7: Maritime Temperate, over sea
+
+       The Continental Temperate climate is common to large  land
+       masses  in  the temperate zone, such as the United States.
+       For paths shorter than 100 km, there is little  difference
+       between Continental and Maritime Temperate climates.
+
+       The  final  two  parameters in the .lrp file correspond to
+       the statistical  analysis  provided  by  the  Longley-Rice
+       model.   In  this example, SPLAT!  will return the maximum
+       path loss occurring 50% of the time (fraction of time)  in
+       50%   of  situations  (fraction  of  situations).   Use  a
+       fraction of time parameter of 0.97 for digital television,
+       0.50  for analog in the United States.  Isotropic antennas
+       are assumed.
+
+       For  further  information  on   these   parameters,   see:
+       http://elbert.its.bldrdoc.gov/itm.html                 and
+       http://www.softwright.com/faq/engineering/prop_long-
+       ley_rice.html
+
+CITY LOCATION FILES
+       The  names  and locations of cities, tower sites, or other
+       points of interest may imported and be  plotted  on  topo-
+       graphic  maps  generated  by  SPLAT!.   SPLAT! imports the
+       names of cities and locations from ASCII files  containing
+       the  location's  name,  the  location's  latitude, and the
+       location's longitude.  Each field is separated by a comma.
+       Each  record is separated by a single line feed character.
+       As was the case with the .qth files, latitude  and  longi-
+       tude  information  may  be  entered  in  either decimal or
+       degree, minute, second (DMS) format.
+
+       For example (cities.dat):
+
+               Teaneck, 40.891973, 74.014506
+               Tenafly, 40.919212, 73.955892
+               Teterboro, 40.859511, 74.058908
+               Tinton Falls, 40.279966, 74.093924
+               Toms River, 39.977777, 74.183580
+               Totowa, 40.906160, 74.223310
+               Trenton, 40.219922, 74.754665
+
+       A total of five separate city data files may  be  imported
+       at  a time.  There is no limit to the size of these files.
+       SPLAT! reads city data sequentially, and plots only  those
+       locations  whose positions do not conflict with previously
+       plotted locations when generating topographic maps.
+
+       City data files may be generated manually using  any  text
+       editor,  imported from other sources, or derived from data
+       available from the U.S. Census Bureau  using  the  cityde-
+       coder  utility  included with SPLAT!.  Such data is avail-
+       able free of charge via the Internet  at:  http://www.cen-
+       sus.gov/geo/www/cob/bdy_files.html,  and  must be in ASCII
+       format.
+
+CARTOGRAPHIC BOUNDARY DATA FILES
+       Cartographic boundary data may also be  imported  to  plot
+       the  boundaries  of  cities,  counties, or states on topo-
+       graphic maps generated by SPLAT!.  Such data  must  be  of
+       the  form  of  ARC/INFO Ungenerate (ASCII Format) Metadata
+       Cartographic Boundary Files, and are  available  from  the
+       U.S.   Census  Bureau via the Internet at: http://www.cen-
+       sus.gov/geo/www/cob/co2000.html#ascii and  http://www.cen-
+       sus.gov/geo/www/cob/pl2000.html#ascii.   A  total  of five
+       separate cartographic boundary files may be imported at  a
+       time.   It  is not necessary to import state boundaries if
+       county boundaries have already been imported.
+
+PROGRAM OPERATION
+       SPLAT! is invoked via the command-line using a  series  of
+       switches  and arguments.  Since SPLAT! is a CPU and memory
+       intensive application, this type  of  interface  minimizes
+       overhead,  and  also  lends itself well to scripted opera-
+       tions.  SPLAT!'s CPU and memory scheduling priority may be
+       adjusted through the use of the Unix nice command.
+
+       The number and type of switches passed to SPLAT! determine
+       its mode of operation and method of  output  data  genera-
+       tion.   Nearly all of SPLAT!'s switches may be cascaded in
+       any order on the command line when invoking the program to
+       include  all the features described by those switches when
+       performing an analysis.
+
+POINT-TO-POINT ANALYSIS
+       SPLAT! may be used to perform line-of-sight terrain analy-
+       sis between two specified site locations.  For example:
+
+       splat -t tx_site.qth -r rx_site.qth
+
+       invokes  a terrain analysis between the transmitter speci-
+       fied in tx_site.qth and receiver specified in rx_site.qth,
+       and  writes  a  SPLAT!  Obstruction  Report to the current
+       working directory.  The report  contains  details  of  the
+       transmitter  and  receiver sites, and identifies the loca-
+       tion of any obstructions detected during the analysis.  If
+       an  obstruction  can  be  cleared  by  raising the receive
+       antenna to a greater altitude, SPLAT!  will  indicate  the
+       minimum  antenna  height required for a line-of-sight path
+       to exist between the transmitter  and  receiver  locations
+       specified.   If  the  antenna must be raised a significant
+       amount, this determination may take some time.
+
+       are optional when invoking the program.  SPLAT!  automati-
+       cally  reads all SPLAT Data Files necessary to conduct the
+       terrain analysis between the sites specified.  By default,
+       the  location of SDF files is assumed to be in the current
+       working directory unless a ".splat_path" file  is  present
+       under the user's home directory.  If this file is present,
+       it must contain the full directory path to the location of
+       all the SDF files required by SPLAT! to perform its analy-
+       sis for the region containing the transmitter and receiver
+       sites  specified.   The  path  in this file must be of the
+       form of a single line of ASCII text:
+
+       /opt/splat/sdf/
+
+       and may be generated with any text  editor.   The  default
+       path  specified in the $HOME/.splat_path file may be over-
+       ridden at any time using the -d switch:
+
+       splat -t tx_site -r rx_site -d /cdrom/sdf/
+
+       A graph of the terrain profile between  the  receiver  and
+       transmitter  locations  as a function of distance from the
+       receiver can be generated by adding the -p switch:
+
+       splat -t tx_site -r rx_site -p terrain_profile.gif
+
+       SPLAT! invokes gnuplot when generating graphs.  The  file-
+       name  extension  specified to SPLAT! determines the format
+       of the graph produced.  .gif will produce a 640x480  color
+       GIF  graphic  file,  while .ps or .postscript will produce
+       postscript output.  Output in formats such as  PNG,  Adobe
+       Illustrator,  AutoCAD  dxf,  LaTeX,  and  many  others are
+       available.  Please consult gnuplot, and gnuplot's documen-
+       tation for details on all the supported output formats.
+
+       A graph of elevations subtended by the terrain between the
+       receiver and transmitter as a function  of  distance  from
+       the receiver can be generated by using the -e switch:
+
+       splat -t tx_site -r rx_site -e elevation_profile.gif
+
+       The  graph produced using this switch illustrates the ele-
+       vation and depression angles resulting  from  the  terrain
+       between  the  receiver's location and the transmitter site
+       from the perspective of the receiver's location.  A second
+       trace  is  plotted  between  the  left  side  of the graph
+       (receiver's location) and the location of the transmitting
+       antenna  on  the right.  This trace illustrates the eleva-
+       tion angle required for  a  line-of-sight  path  to  exist
+       between  the  receiver  and transmitter locations.  If the
+       trace intersects the elevation profile at any point on the
+       graph,  then  this  is  an indication that a line-of-sight
+       path does not exist under the conditions  given,  and  the
+       obstructions can be clearly identified on the graph at the
+       point(s) of intersection.
+
+       A graph illustrating terrain height referenced to a  line-
+       of-sight  path between the transmitter and receiver may be
+       generated using the -h switch:
+
+       splat -t tx_site -r rx_site -h height_profile.gif
+
+       The Earth's curvature is  clearly  evident  when  plotting
+       height profiles.
+
+       A  graph  showing  Longley-Rice  path  loss may be plotted
+       using the -l switch:
+
+       splat -t tx_site -r rx_site -l path_loss_profile.gif
+
+       When performing path loss profiles, a  Longley-Rice  Model
+       Path  Loss  Report is generated by SPLAT! in the form of a
+       text file with a .lro filename extension.  The report con-
+       tains  bearings  and distances between the transmitter and
+       receiver, as well as the Longley-Rice path loss for  vari-
+       ous  distances  between the transmitter and receiver loca-
+       tions.  The mode of propagation for points along the  path
+       are  given  as Line-of-Sight, Single Horizon, Double Hori-
+       zon, Diffraction Dominant, and Troposcatter Dominant.
+
+       To determine the signal-to-noise  (SNR)  ratio  at  remote
+       location  where random Johnson (thermal) noise is the pri-
+       mary limiting factor in reception:
+
+       SNR=T-NJ-L+G-NF
+
+       where T is the ERP of the transmitter in dBW, NJ is  John-
+       son  Noise  in dBW (-136 dBW for a 6 MHz TV channel), L is
+       the path loss provided by SPLAT! in dB (as a positive num-
+       ber),  G is the receive antenna gain in dB over isotropic,
+       and NF is the receiver noise figure in dB.
+
+       T may be computed as follows:
+
+       T=TI+GT
+
+       where TI is actual amount of RF  power  delivered  to  the
+       transmitting  antenna  in  dBW,  GT  is  the  transmitting
+       antenna gain (over isotropic)  in  the  direction  of  the
+       receiver (or the horizon if the receiver is over the hori-
+       zon).
+
+       To compute how much more signal is available over the min-
+       imum  to  necessary  to achieve a specific signal-to-noise
+       ratio:
+
+       Signal_Margin=SNR-S
+
+       where S is the minimum desired SNR ratio (15.5 dB for ATSC
+       DTV, 42 dB for analog NTSC television).
+
+       A  topographic map may be generated by SPLAT! to visualize
+       the path between the transmitter and receiver  sites  from
+       yet  another  perspective.   Topographic maps generated by
+       SPLAT! display elevations using a  logarithmic  grayscale,
+       with higher elevations represented through brighter shades
+       of gray.  The dynamic range of the image is scaled between
+       the highest and lowest elevations present in the map.  The
+       only exception to this is sea-level, which is  represented
+       in blue.
+
+       SPLAT!  generated  topographic  maps  are 24-bit TrueColor
+       Portable PixMap (PPM) images, and may be  viewed,  edited,
+       or  converted  to  other  graphic formats by popular image
+       viewing applications such as xv,  The  GIMP,  ImageMagick,
+       and XPaint.  PNG format is highly recommended for lossless
+       compressed storage of SPLAT!  generated topographic output
+       files.   An excellent command-line utility capable of con-
+       verting SPLAT! PPM graphic files to PNG files is wpng, and
+       is                      available                      at:
+       http://www.libpng.org/pub/png/book/sources.html.    As   a
+       last  resort,  PPM files may be compressed using the bzip2
+       utility, and read directly by The  GIMP  in  this  format.
+       Topographic output is specified using the -o switch:
+
+       splat -t tx_site -r rx_site -o topo_map.ppm
+
+       The  .ppm  extension  on the output filename is assumed by
+       SPLAT!, and is optional.
+
+       In this example, topo_map.ppm will  illustrate  the  loca-
+       tions of the transmitter and receiver sites specified.  In
+       addition, the great circle path between the two sites will
+       be  drawn  over  locations  for which an unobstructed path
+       exists to the transmitter at a  receiving  antenna  height
+       equal   to   that  of  the  receiver  site  (specified  in
+       rx_site.qth).
+
+       It may desirable to  populate  the  topographic  map  with
+       names  and  locations  of  cities,  tower  sites, or other
+       important locations.  A city file may be passed to  SPLAT!
+       using the -s switch:
+
+       splat -t tx_site -r rx_site -s cities.dat -o topo_map
+
+       Up  to five separate city files may be passed to SPLAT! at
+       a time following the -s switch.
+
+       County and state boundaries may be added  to  the  map  by
+       specifying  up  to  five  U.S.  Census Bureau cartographic
+       boundary files using the -b switch:
+
+       splat -t tx_site -r rx_site -b co34_d00.dat -o topo_map
+
+       In situations where multiple transmitter sites are in use,
+       as  many as four site locations may be passed to SPLAT! at
+       a time for analysis:
+
+       splat -t tx_site1 tx_site2 tx_site3 tx_site4 -r rx_site -p
+       profile.gif
+
+       In  this  example,  four  separate  terrain  profiles  and
+       obstruction reports will be generated by SPLAT!.  A single
+       topographic  map can be specified using the -o switch, and
+       line-of-sight  paths  between  each  transmitter  and  the
+       receiver  site indicated will be produced on the map, each
+       in its own color.  The path between the first  transmitter
+       specified  to  the  receiver  will  be  in green, the path
+       between the second transmitter and the receiver will be in
+       cyan,  the  path  between  the  third  transmitter and the
+       receiver will be in  violet,  and  the  path  between  the
+       fourth transmitter and the receiver will be in sienna.
+
+DETERMINING REGIONAL COVERAGE
+       SPLAT! can analyze a transmitter or repeater site, or net-
+       work of sites, and predict the regional coverage for  each
+       site specified.  In this mode, SPLAT! can generate a topo-
+       graphic map displaying the geometric line-of-sight  cover-
+       age  area of the sites based on the location of each site,
+       and the height of receive antenna wishing  to  communicate
+       with the site in question.  SPLAT! switches from point-to-
+       point analysis mode to area prediction mode  when  the  -c
+       switch is invoked as follows:
+
+       splat  -t tx_site -c 30.0 -s cities.dat -b co34_d00.dat -o
+       tx_coverage
+
+       In this example, SPLAT! generates a topographic map called
+       tx_coverage.ppm  that  illustrates  the predicted line-of-
+       sight regional coverage of tx_site to receiving  locations
+       having  antennas  30.0 feet above ground level (AGL).  The
+       contents of cities.dat are plotted on the map, as are  the
+       cartographic    boundaries    contained    in   the   file
+       co34_d00.dat.
+
+       When plotting line-of-sight paths and  areas  of  regional
+       coverage,  SPLAT!  by  default  does  not  account for the
+       effects of atmospheric bending.   However,  this  behavior
+       may  be modified by using the Earth radius multiplier (-m)
+       switch:
+
+       splat -t wnjt -c 30.0 -m  1.333  -s  cities.dat  -b  coun-
+       ties.dat -o map.ppm
+
+       An  earth  radius multiplier  of 1.333 instructs SPLAT! to
+       use the "four-thirds earth" model for line-of-sight propa-
+       gation  analysis.  Any appropriate earth radius multiplier
+       may be selected by the user.
+
+       When invoked in area prediction mode, SPLAT!  generates  a
+       site  report  for  each  station  analyzed.   SPLAT!  site
+       reports contain details of the site's geographic location,
+       its  height  above  mean  sea  level, the antenna's height
+       above mean sea level, the antenna's height  above  average
+       terrain,  and the height of the average terrain calculated
+       in the directions of 0, 45, 90, 135, 180,  225,  270,  and
+       315 degrees azimuth.
+
+       If  the  -c  switch is replaced by a -L switch, a Longley-
+       Rice path loss map for a transmitter site  may  be  gener-
+       ated:
+
+       splat  -t tx_site -L 30.0 -s cities.dat -b co34_d00.dat -o
+       path_loss_map
+
+       In this mode, SPLAT! generates a  multi-color  map  illus-
+       trating  expected  signal levels (path loss) in areas sur-
+       rounding the transmitter site.  A legend at the bottom  of
+       the  map  correlates  each color with a specific path loss
+       level in decibels.  Since Longley-Rice area prediction map
+       generation  is quite CPU intensive, provision for limiting
+       the analysis range is provided  by  the  -R  switch.   The
+       argument  must  be  given in miles.  If a range wider than
+       the generated topographic map is  specified,  SPLAT!  will
+       perform  Longley-Rice  path  loss calculations between all
+       four corners of the area prediction map.
+
+DETERMINING MULTIPLE REGIONS OF COVERAGE
+       SPLAT! can also display line-of-sight coverage  areas  for
+       as  many  as  four  separate transmitter sites on a common
+       topographic map.  For example:
+
+       splat -t site1 site2 site3 site4 -c 30.0 -o network.ppm
+
+       plots the regional line-of-sight coverage of site1, site2,
+       site3,  and  site4 based on a receive antenna located 30.0
+       feet above ground level.  A topographic map is then  writ-
+       ten  to  the file network.ppm.  The line-of-sight coverage
+       area of the transmitters are plotted  as  follows  in  the
+       colors  indicated (along with their corresponding RGB val-
+       ues in decimal):
+
+           site1: Green (0,255,0)
+           site2: Cyan (0,255,255)
+           site3: Medium Violet (147,112,219)
+           site4: Sienna 1 (255,130,71)
+
+           site1 + site2: Yellow (255,255,0)
+           site1 + site3: Pink (255,192,203)
+           site1 + site4: Green Yellow (173,255,47)
+           site2 + site3: Orange (255,165,0)
+           site2 + site4: Dark Sea Green 1 (193,255,193)
+           site3 + site4: Dark Turquoise (0,206,209)
+
+           site1 + site2 + site3: Dark Green (0,100,0)
+           site1 + site2 + site4: Blanched Almond (255,235,205)
+           site1 + site3 + site4: Medium Spring Green (0,250,154)
+           site2 + site3 + site4: Tan (210,180,140)
+
+           site1 + site2 + site3 + site4: Gold2 (238,201,0)
+
+       If  separate .qth files are generated, each representing a
+       common site location but a  different  antenna  height,  a
+       single  topographic map illustrating the regional coverage
+       from as many as four separate locations on a single  tower
+       may be generated by SPLAT!.
+
+TOPOGRAPHIC MAP GENERATION
+       In  certain  situations, it may be desirable to generate a
+       topographic map of  a  region  without  plotting  coverage
+       areas,  line-of-sight  paths,  or  generating  obstruction
+       reports.  There are several ways of doing  this.   If  one
+       wishes  to  generate  a  topographic  map illustrating the
+       location of a transmitter and receiver site along  with  a
+       brief  text  report describing the locations and distances
+       between the sites, the -n switch should be invoked as fol-
+       lows:
+
+       splat -t tx_site -r rx_site -n -o topo_map.ppm
+
+       If no text report is desired, then the -N switch is used:
+
+       splat -t tx_site -r rx_site -N -o topo_map.ppm
+
+       If  the  -o  switch  and  output filename are omitted when
+       using either the -n or -N switches, output is written to a
+       file  named  map.ppm  in  the current working directory by
+       default.
+
+DETERMINATION OF ANTENNA HEIGHT ABOVE AVERAGE TERRAIN
+       SPLAT! determines antenna  height  above  average  terrain
+       (HAAT)  according to the procedure defined by Federal Com-
+       munications Commission Part 73.313(d).  According to  this
+       definition, terrain elevations along eight radials between
+       2 and 10 miles (3 and 16 kilometers) from the  site  being
+       analyzed  are  sampled and averaged for each 45 degrees of
+       azimuth starting with True North.  If one or more  radials
+       lie  entirely  over water, or over land outside the United
+       States (areas for which no USGS topography data is  avail-
+       able), then those radials are omitted from the calculation
+       of average terrain.  If part of a radial  extends  over  a
+       body of water or over land outside the United States, then
+       only that part of the radial lying over United States land
+       is used in the determination of average terrain.
+
+       When  performing  point-to-point  terrain analysis, SPLAT!
+       determines the antenna height above average  terrain  only
+       if  enough topographic data has already been loaded by the
+       program to perform the point-to-point analysis.   In  most
+       cases, this will be true, unless the site in question does
+       not lie within 10 miles of the boundary of the  topography
+       data in memory.
+
+       When  performing area prediction analysis, enough topogra-
+       phy data is normally loaded by SPLAT! to  perform  average
+       terrain  calculations.  Under such conditions, SPLAT! will
+       provide the antenna height above average terrain  as  well
+       as  the  average terrain above mean sea level for azimuths
+       of 0, 45, 90, 135, 180, 225, 270,  and  315  degrees,  and
+       include such information in the site report generated.  If
+       one or more of the eight radials surveyed fall over  water
+       or  land outside the United States, SPLAT! reports No Ter-
+       rain for those radial paths.
+
+SETTING THE MAXIMUM SIZE OF AN ANALYSIS REGION
+       SPLAT! reads SDF files into a series of memory "slots"  as
+       required within the structure of the program.  Each "slot"
+       holds one SDF file.  Each SDF file represents a one degree
+       by  one  degree  region  of  terrain.   A #define MAXSLOTS
+       statement in the first several lines of splat.cpp sets the
+       maximum  number  of "slots" available for topography data.
+       It also sets the maximum size of the topographic maps gen-
+       erated  by  SPLAT!.   MAXSLOTS is set to 9 by default.  If
+       SPLAT! produces a segmentation fault on start-up with this
+       default,  it  is  an indication that not enough RAM and/or
+       virtual memory (swap space) are available  to  run  SPLAT!
+       with  this number of MAXSLOTS.  In this case, MAXSLOTS may
+       be reduced to 4, although this will greatly limit the max-
+       imum  region  SPLAT!  will  be  able  to  analyze.  If 118
+       megabytes or more of total memory (swap space plus RAM) is
+       available,  then  MAXSLOTS  may  be increased to 16.  This
+       will permit operation over a 4-degree by 4-degree  region,
+       which  is  sufficient for single antenna heights in excess
+       of 10,000 feet above mean  sea  level,  or  point-to-point
+       distances of over 1000 miles.
+
+ADDITIONAL INFORMATION
+       Invoking SPLAT! without any arguments will display all the
+       command-line options available with the program along with
+       a brief summary of each.
+
+       The  latest news and information regarding SPLAT! software
+       is available through the official SPLAT! software web page
+       located at: http://www.qsl.net/kd2bd/splat.html.
+
+FILES
+       $HOME/.splat_path
+              User-generated  file containing the default path to
+              the directory containing the SDF data files.
+
+       splat.lrp
+              Default Longley-Rice model parameters.
+
+AUTHORS
+       John A. Magliacane, KD2BD <kd2bd@amsat.org>
+              Creator, Lead Developer
+
+       Doug McDonald <mcdonald@scs.uiuc.edu>
+              Longley-Rice Model integration
+
+
+
+KD2BD Software           20 January 2004                SPLAT!(1)
diff --git a/fontdata.h b/fontdata.h
new file mode 100644 (file)
index 0000000..14e5b18
--- /dev/null
@@ -0,0 +1,343 @@
+static char fontdata[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0xe7, 0xa5, 0x99,
+   0x81, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7e,
+   0xff, 0x99, 0xdb, 0xe7, 0xff, 0xe7, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+   0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38,
+   0x10, 0xd6, 0xfe, 0xd6, 0x10, 0x38, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x54, 0x10, 0x38, 0x7c, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+   0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+   0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+   0x1a, 0x30, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x14, 0x14, 0x14, 0x10,
+   0x10, 0x30, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x22,
+   0x3e, 0x22, 0x22, 0x22, 0x22, 0x26, 0x6e, 0xe4, 0x40, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x28, 0xc6, 0x28, 0x54, 0x92, 0x10,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x7e,
+   0x7c, 0x78, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0e,
+   0x1e, 0x3e, 0x7e, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x38, 0x38, 0x38, 0x38, 0xfe, 0x7c,
+   0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+   0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf4,
+   0xf4, 0xf4, 0x74, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x1e, 0x30, 0x78, 0xdc, 0xce, 0xe7, 0x73, 0x3b, 0x1e, 0x0c, 0x78,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+   0x7c, 0xfe, 0x38, 0x38, 0x38, 0x38, 0xfe, 0x7c, 0x38, 0x10, 0xfe, 0x00,
+   0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+   0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+   0x38, 0x38, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0x0c, 0xfe, 0xff, 0xfe, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x7f, 0xff, 0x7f, 0x30, 0x10,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xee, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e,
+   0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x66, 0xcc, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c,
+   0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x10, 0x10, 0x7c, 0xd6, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0xd6, 0x7c,
+   0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc4, 0x0c, 0x08, 0x18, 0x30,
+   0x20, 0x60, 0x46, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+   0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x1c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+   0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+   0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x18, 0x30, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04,
+   0x0c, 0x08, 0x18, 0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+   0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+   0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+   0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30,
+   0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+   0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+   0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x30, 0x18, 0x0c, 0x06,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+   0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30,
+   0x18, 0x0c, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x1c, 0x30, 0x30, 0x00, 0x30, 0x30,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde,
+   0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38,
+   0x38, 0x6c, 0x6c, 0x6c, 0x7c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0xc0,
+   0xc0, 0xc0, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc,
+   0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0,
+   0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+   0xc0, 0xc0, 0xc0, 0xce, 0xc6, 0xc6, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+   0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee,
+   0xfe, 0xfe, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6,
+   0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xde, 0x7c,
+   0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc,
+   0xd8, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+   0xc0, 0x60, 0x38, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6,
+   0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0xee, 0xc6, 0xc6,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38,
+   0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66,
+   0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xfe,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+   0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40,
+   0x60, 0x20, 0x30, 0x10, 0x18, 0x08, 0x0c, 0x04, 0x06, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+   0x00, 0x00, 0x38, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x7e,
+   0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+   0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x7e, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+   0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06,
+   0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+   0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xd6, 0xd6,
+   0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x70,
+   0x1c, 0x06, 0x06, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+   0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+   0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x60, 0x60, 0x18, 0x18, 0x18, 0x0e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+   0x18, 0x18, 0x06, 0x06, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+   0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+   0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0x98, 0x70, 0x00,
+   0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe,
+   0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+   0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x7e,
+   0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38,
+   0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+   0x38, 0x98, 0x70, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x7c, 0xc6, 0xfe,
+   0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c,
+   0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+   0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x60, 0x30, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe,
+   0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38,
+   0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x0c, 0x18, 0x30, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0x1b,
+   0x7f, 0xd8, 0xdb, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3c,
+   0x3c, 0x6c, 0x6f, 0x6c, 0x7c, 0xcc, 0xcc, 0xcf, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x18, 0x3c, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+   0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x18, 0x3c, 0x66, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c,
+   0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x7c, 0x00,
+   0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+   0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00,
+   0x00, 0x00, 0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf0, 0x60, 0x60, 0x66, 0xfc,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e,
+   0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6,
+   0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xcf, 0xc6, 0xc6, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18,
+   0xd8, 0x70, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x00, 0x7c, 0x06, 0x7e,
+   0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18,
+   0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x06, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6,
+   0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+   0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6,
+   0x7e, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+   0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x70, 0xc0, 0xc0, 0xc6, 0x7c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+   0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x00, 0xff, 0x00, 0x18, 0x2c, 0x18,
+   0x30, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x00, 0xff,
+   0x00, 0x18, 0x38, 0x68, 0x7c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
+   0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0xd8, 0x6c, 0x36, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+   0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10, 0x82, 0x10,
+   0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10,
+   0x00, 0x95, 0x00, 0xa9, 0x00, 0x95, 0x00, 0xa9, 0x00, 0x95, 0x00, 0xa9,
+   0x00, 0x95, 0x00, 0xa9, 0x92, 0x49, 0x92, 0x49, 0x92, 0x49, 0x92, 0x49,
+   0x92, 0x49, 0x92, 0x49, 0x92, 0x49, 0x92, 0x49, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8,
+   0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0xfc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8,
+   0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0xfc, 0xfc, 0xfc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
+   0xfc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0xfc, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8,
+   0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x1f, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3f, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3f, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0xff, 0xff,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0xff, 0xff, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3f, 0x3f, 0x3f, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0xff, 0xff, 0xff, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x3f, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x3c, 0x3c, 0x3c, 0x3c, 0xff, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+   0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+   0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+   0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x77, 0xcc, 0xcc, 0xcc, 0xde, 0x73, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc4, 0xc8, 0xc4, 0xc6, 0xc6, 0xc6, 0xdc,
+   0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+   0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x03, 0x7e, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x68, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0xd8,
+   0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0xdb, 0xdb, 0xdb,
+   0xdb, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+   0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x24, 0xa5, 0xe7,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+   0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xcf, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+   0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+   0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x7c, 0x00, 0x00, 0xfe, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+   0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+   0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+   0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+   0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+   0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02,
+   0x06, 0x04, 0x0c, 0x08, 0xd8, 0x50, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x18, 0x30, 0x60, 0xfc,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/install b/install
new file mode 100755 (executable)
index 0000000..936ba84
--- /dev/null
+++ b/install
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# Simple shell script for installing SPLAT! and associated utilities.
+# Written by John A. Magliacane, KD2BD April 2002
+#
+
+install_splat()
+{
+       cp splat /usr/local/bin
+       echo "SPLAT! installed!"
+}
+
+install_utils()
+{
+       cd utils
+       ./install all
+       cd ..
+       echo "utils installed!"
+}
+
+install_man()
+{
+       cp docs/man/splat.1 /usr/local/man/man1/splat.1
+       echo "man page installed!"
+}
+
+whoami=`whoami`
+
+if [ $# == "0" ]; then
+       echo "Usage: ./install { splat, utils, man, all }"
+else
+       if [ $whoami == "root" ]; then
+
+               if [ $1 == "splat" ] && [ -x splat ]; then
+                       install_splat
+               fi
+
+               if [ $1 == "utils" ]; then
+                       install_utils
+               fi
+
+               if [ $1 == "man" ]; then
+                       install_man
+               fi
+
+               if [ $1 == "all" ] && [ -x splat ]; then
+                       install_splat
+                       install_utils
+                       install_man
+               fi
+       else
+               echo "Sorry, $whoami.  You need to be 'root' to install this software.  :-("
+       fi
+
+       if [ $1 != "splat" ] && [ $1 != "utils" ] && [ $1 != "man" ] && [ $1 != "all" ]; then
+               echo "Usage: ./install { splat, utils, man, all }"
+       fi
+fi
diff --git a/itm.cpp b/itm.cpp
new file mode 100644 (file)
index 0000000..602aa0b
--- /dev/null
+++ b/itm.cpp
@@ -0,0 +1,1542 @@
+/****************************************************************************
+*                                                                           *
+* This file was obtained from ftp://flattop.its.bldrdoc.gov/itm/ITMDLL.cpp  *
+* on Jan. 10, 2004 and is public domain.  It was modified by J. D. McDonald *
+* to remove Microsoft Windows dll-isms and to correct one case where a      *
+* compiler found an ambguity in overloaded calls.  It was further modified  *
+* by John A. Magliacane to remove unused variables, unneeded #includes,     *
+* and to replace pow() statements with explicit multiplications wherever    *
+* possible to increase execution speed and improve accuracy.                *
+*                                                                           *
+****************************************************************************/
+
+// *************************************
+// C++ routines for this program are taken from
+// a translation of the FORTRAN code written by
+// U.S. Department of Commerce NTIA/ITS
+// Institute for Telecommunication Sciences
+// *****************
+// Irregular Terrain Model (ITM) (Longley-Rice)
+// *************************************
+
+#include <math.h>
+#include <complex>
+#include <assert.h>
+#include <string.h>
+
+#define THIRD (1.0/3.0)
+
+using namespace std;
+
+struct tcomplex
+{      double tcreal;
+       double tcimag;
+};
+
+struct prop_type
+{      double aref;
+       double dist;
+       double hg[2];
+       double wn;
+       double dh;
+       double ens;
+       double gme;
+       double zgndreal;
+       double zgndimag;
+       double he[2];
+       double dl[2];
+       double the[2];
+       int kwx;
+       int mdp;
+};
+
+struct propv_type
+{      double sgc;
+       int lvar;
+       int mdvar;
+       int klim;
+};
+
+struct propa_type
+{      double dlsa;
+       double dx;
+       double ael;
+       double ak1;
+       double ak2;
+       double aed;
+       double emd;
+       double aes;
+       double ems;
+       double dls[2];
+       double dla;
+       double tha;
+};
+
+int mymin(const int &i, const int &j)
+{
+       if (i<j)
+               return i;
+       else
+               return j;
+}
+
+int mymax(const int &i, const int &j)
+{
+       if (i>j)
+               return i;
+       else
+               return j;
+}
+
+double mymin(const double &a, const double &b)
+{
+       if (a<b)
+               return a;
+       else
+               return b;
+}
+
+double mymax(const double &a, const double &b)
+{
+       if (a>b)
+               return a;
+       else
+               return b;
+}
+
+double FORTRAN_DIM(const double &x, const double &y)
+{
+        /* This performs the FORTRAN DIM function.  Result is x-y
+           if x is greater than y; otherwise result is 0.0 */
+
+       if (x>y)
+               return x-y;
+       else
+               return 0.0;
+}
+
+double aknfe(const double &v2)
+{
+       double a;
+
+       if (v2<5.76)
+               a=6.02+9.11*sqrt(v2)-1.27*v2;
+       else
+               a=12.953+4.343*log(v2);
+       return a;
+}
+
+double fht(const double& x, const double& pk)
+{
+       double w, fhtv;
+
+       if (x<200.0)
+       {
+               w=-log(pk);
+
+               /* if (pk<1e-5 || x*pow(w,3.0) > 5495.0) */
+               if (pk<1.0e-5 || x*w*w*w > 5495.0)
+               {
+                       fhtv=-117.0;
+
+                       if (x>1.0)
+                               fhtv=17.372*log(x)+fhtv;
+               }
+               else
+                       fhtv=2.5e-5*x*x/pk-8.686*w-15.0;
+       }
+
+       else
+       {
+               fhtv=0.05751*x-4.343*log(x);
+
+               if (x<2000.0)
+               {
+                       w=0.0134*x*exp(-0.005*x);
+                       fhtv=(1.0-w)*fhtv+w*(17.372*log(x)-117.0);
+               }
+       }
+       return fhtv;
+}
+
+double h0f(double r, double et)
+{
+       double a[5]={25.0, 80.0, 177.0, 395.0, 705.0};
+       double b[5]={24.0, 45.0,  68.0,  80.0, 105.0};
+       double q, x;
+       double h0fv, temp; 
+       int it;
+
+       it=(int)et;
+
+       if (it<=0)
+       {
+               it=1;
+               q=0.0;
+       }
+
+       else if (it>=5)
+       {
+               it=5;
+               q=0.0;
+       }
+
+       else
+               q=et-it;
+
+       /* x=pow(1.0/r,2.0); */
+
+       temp=1.0/r;
+       x=temp*temp;
+
+       h0fv=4.343*log((a[it-1]*x+b[it-1])*x+1.0);
+
+       if (q!=0.0)
+               h0fv=(1.0-q)*h0fv+q*4.343*log((a[it]*x+b[it])*x+1.0);
+
+       return h0fv;
+}
+
+double ahd(double td)
+{
+       int i;
+       double a[3]={   133.4,    104.6,     71.8};
+       double b[3]={0.332e-3, 0.212e-3, 0.157e-3};
+       double c[3]={  -4.343,   -1.086,    2.171};
+
+       if (td<=10e3)
+               i=0;
+
+       else if (td<=70e3)
+               i=1;
+
+       else
+               i=2;
+
+       return a[i]+b[i]*td+c[i]*log(td);
+}
+
+double adiff(double d, prop_type &prop, propa_type &propa)
+{
+       complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
+       static double wd1, xd1, afo, qk, aht, xht;
+       double a, q, pk, ds, th, wa, ar, wd, adiffv;
+
+       if (d==0)
+       {
+               q=prop.hg[0]*prop.hg[1];
+               qk=prop.he[0]*prop.he[1]-q;
+
+               if (prop.mdp<0.0)
+                       q+=10.0;
+
+               wd1=sqrt(1.0+qk/q);
+               xd1=propa.dla+propa.tha/prop.gme;
+               q=(1.0-0.8*exp(-propa.dlsa/50e3))*prop.dh;
+               q*=0.78*exp(-pow(q/16.0,0.25));
+               afo=mymin(15.0,2.171*log(1.0+4.77e-4*prop.hg[0]*prop.hg[1]*prop.wn*q));
+               qk=1.0/abs(prop_zgnd);
+               aht=20.0;
+               xht=0.0;
+
+               for (int j=0; j<2; ++j)
+               {
+                       /* a=0.5*pow(prop.dl[j],2.0)/prop.he[j]; */
+                       a=0.5*(prop.dl[j]*prop.dl[j])/prop.he[j];
+                       wa=pow(a*prop.wn,THIRD);
+                       pk=qk/wa;
+                       q=(1.607-pk)*151.0*wa*prop.dl[j]/a;
+                       xht+=q;
+                       aht+=fht(q,pk);
+               }
+
+               adiffv=0.0;
+       }
+
+       else
+       {
+               th=propa.tha+d*prop.gme;
+               ds=d-propa.dla;
+               /* q=0.0795775*prop.wn*ds*pow(th,2.0); */
+               q=0.0795775*prop.wn*ds*th*th;
+               adiffv=aknfe(q*prop.dl[0]/(ds+prop.dl[0]))+aknfe(q*prop.dl[1]/(ds+prop.dl[1]));
+               a=ds/th;
+               wa=pow(a*prop.wn,THIRD);
+               pk=qk/wa;
+               q=(1.607-pk)*151.0*wa*th+xht;
+               ar=0.05751*q-4.343*log(q)-aht;
+               q=(wd1+xd1/d)*mymin(((1.0-0.8*exp(-d/50e3))*prop.dh*prop.wn),6283.2);
+               wd=25.1/(25.1+sqrt(q));
+               adiffv=ar*wd+(1.0-wd)*adiffv+afo;
+       }
+
+       return adiffv;
+}
+
+double ascat( double d, prop_type &prop, propa_type &propa)
+{
+       static double ad, rr, etq, h0s;
+       double h0, r1, r2, z0, ss, et, ett, th, q;
+       double ascatv, temp;
+
+       if (d==0.0)
+       {
+               ad=prop.dl[0]-prop.dl[1];
+               rr=prop.he[1]/prop.he[0];
+
+               if (ad<0.0)
+               {
+                       ad=-ad;
+                       rr=1.0/rr;
+               }
+
+               etq=(5.67e-6*prop.ens-2.32e-3)*prop.ens+0.031;
+               h0s=-15.0;
+               ascatv=0.0;
+       }
+
+       else
+       {
+               if (h0s>15.0)
+                       h0=h0s;
+               else
+               {
+                       th=prop.the[0]+prop.the[1]+d*prop.gme;
+                       r2=2.0*prop.wn*th;
+                       r1=r2*prop.he[0];
+                       r2*=prop.he[1];
+
+                       if (r1<0.2 && r2<0.2)
+                               return 1001.0;  // <==== early return
+
+                       ss=(d-ad)/(d+ad);
+                       q=rr/ss;
+                       ss=mymax(0.1,ss);
+                       q=mymin(mymax(0.1,q),10.0);
+                       z0=(d-ad)*(d+ad)*th*0.25/d;
+                       /* et=(etq*exp(-pow(mymin(1.7,z0/8.0e3),6.0))+1.0)*z0/1.7556e3; */
+
+                       temp=mymin(1.7,z0/8.0e3);
+                       temp=temp*temp*temp*temp*temp*temp;
+                       et=(etq*exp(-temp)+1.0)*z0/1.7556e3;
+
+                       ett=mymax(et,1.0);
+                       h0=(h0f(r1,ett)+h0f(r2,ett))*0.5;
+                       h0+=mymin(h0,(1.38-log(ett))*log(ss)*log(q)*0.49);
+                       h0=FORTRAN_DIM(h0,0.0);
+
+                       if (et<1.0)
+                       {
+                               /* h0=et*h0+(1.0-et)*4.343*log(pow((1.0+1.4142/r1)*(1.0+1.4142/r2),2.0)*(r1+r2)/(r1+r2+2.8284)); */
+
+                               temp=((1.0+1.4142/r1)*(1.0+1.4142/r2));
+                               h0=et*h0+(1.0-et)*4.343*log((temp*temp)*(r1+r2)/(r1+r2+2.8284));
+                       }
+
+                       if (h0>15.0 && h0s>=0.0)
+                               h0=h0s;
+               }
+
+               h0s=h0;
+               th=propa.tha+d*prop.gme;
+               /* ascatv=ahd(th*d)+4.343*log(47.7*prop.wn*pow(th,4.0))-0.1*(prop.ens-301.0)*exp(-th*d/40e3)+h0; */
+               ascatv=ahd(th*d)+4.343*log(47.7*prop.wn*(th*th*th*th))-0.1*(prop.ens-301.0)*exp(-th*d/40e3)+h0;
+       }
+
+       return ascatv;
+}
+
+double qerfi(double q)
+{
+       double x, t, v;
+       double c0=2.515516698;
+       double c1=0.802853;
+       double c2=0.010328;
+       double d1=1.432788;
+       double d2=0.189269;
+       double d3=0.001308;
+
+       x=0.5-q;
+       t=mymax(0.5-fabs(x),0.000001);
+       t=sqrt(-2.0*log(t));
+       v=t-((c2*t+c1)*t+c0)/(((d3*t+d2)*t+d1)*t+1.0);
+
+       if (x<0.0)
+               v=-v;
+
+       return v;
+}
+
+void qlrps(double fmhz, double zsys, double en0, int ipol, double eps, double sgm, prop_type &prop)
+{
+       double gma=157e-9;
+
+       prop.wn=fmhz/47.7;
+       prop.ens=en0;
+
+       if (zsys!=0.0)
+               prop.ens*=exp(-zsys/9460.0);
+
+       prop.gme=gma*(1.0-0.04665*exp(prop.ens/179.3));
+       complex<double> zq, prop_zgnd(prop.zgndreal,prop.zgndimag);
+       zq=complex<double> (eps,376.62*sgm/prop.wn);
+       prop_zgnd=sqrt(zq-1.0);
+
+       if (ipol!=0.0)
+               prop_zgnd=prop_zgnd/zq;
+
+       prop.zgndreal=prop_zgnd.real();
+       prop.zgndimag=prop_zgnd.imag();
+}
+
+double abq_alos (complex<double> r)
+{
+       return r.real()*r.real()+r.imag()*r.imag();
+}
+
+double alos(double d, prop_type &prop, propa_type &propa)
+{
+       complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
+       static double wls;
+       complex<double> r;
+       double s, sps, q;
+       double alosv;
+
+       if (d==0.0)
+       {
+               wls=0.021/(0.021+prop.wn*prop.dh/mymax(10e3,propa.dlsa));
+               alosv=0.0;
+       }
+
+       else
+       {
+               q=(1.0-0.8*exp(-d/50e3))*prop.dh;
+               s=0.78*q*exp(-pow(q/16.0,0.25));
+               q=prop.he[0]+prop.he[1];
+               sps=q/sqrt(d*d+q*q);
+               r=(sps-prop_zgnd)/(sps+prop_zgnd)*exp(-mymin(10.0,prop.wn*s*sps));
+               q=abq_alos(r);
+
+               if (q<0.25 || q<sps)
+                       r=r*sqrt(sps/q);
+
+               alosv=propa.emd*d+propa.aed;
+               q=prop.wn*prop.he[0]*prop.he[1]*2.0/d;
+
+               if (q>1.57)
+                       q=3.14-2.4649/q;
+
+               alosv=(-4.343*log(abq_alos(complex<double>(cos(q),-sin(q))+r))-alosv)*wls+alosv;
+
+       }
+       return alosv;
+}
+
+
+void qlra(int kst[], int klimx, int mdvarx, prop_type &prop, propv_type &propv)
+{
+       double q;
+
+       for (int j=0; j<2; ++j)
+       {
+               if (kst[j]<=0)
+                        prop.he[j]=prop.hg[j];
+               else
+               {
+                       q=4.0;
+
+                       if (kst[j]!=1)
+                               q=9.0;
+
+                       if (prop.hg[j]<5.0)
+                               q*=sin(0.3141593*prop.hg[j]);
+
+                       prop.he[j]=prop.hg[j]+(1.0+q)*exp(-mymin(20.0,2.0*prop.hg[j]/mymax(1e-3,prop.dh)));
+               }
+
+               q=sqrt(2.0*prop.he[j]/prop.gme);
+               prop.dl[j]=q*exp(-0.07*sqrt(prop.dh/mymax(prop.he[j],5.0)));
+               prop.the[j]=(0.65*prop.dh*(q/prop.dl[j]-1.0)-2.0*prop.he[j])/q;
+       }
+
+       prop.mdp=1;
+       propv.lvar=mymax(propv.lvar,3);
+  
+       if (mdvarx>=0)
+       {
+               propv.mdvar=mdvarx;
+               propv.lvar=mymax(propv.lvar,4);
+       }
+
+       if (klimx>0)
+       {
+               propv.klim=klimx;
+               propv.lvar=5;
+       }
+}
+
+void freds_lrprop (double d, prop_type &prop, propa_type &propa)
+{
+       /* freds_lrprop */
+
+       static bool wlos, wscat;
+       static double dmin, xae;
+       complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
+       double a0, a1, a2, a3, a4, a5, a6;
+       double d0, d1, d2, d3, d4, d5, d6;
+       double q;
+       int j;
+
+       if (prop.mdp!=0)
+       {
+               for (j=0; j<2; ++j)
+                       propa.dls[j]=sqrt(2.0*prop.he[j]/prop.gme);
+
+               propa.dlsa=propa.dls[0]+propa.dls[1];
+               propa.dla=prop.dl[0]+prop.dl[1];
+               propa.tha=mymax(prop.the[0]+prop.the[1],-propa.dla*prop.gme);
+               wlos=false;
+               wscat=false;
+
+               if (prop.wn<0.838 || prop.wn>210.0)
+                       prop.kwx=mymax(prop.kwx,1);
+
+               for (j=0; j<2; ++j)
+                       if (prop.hg[j]<1.0 || prop.hg[j]>1000.0)
+                               prop.kwx=mymax(prop.kwx,1);
+
+               for (j=0; j<2; ++j)
+                       if (abs(prop.the[j]) >200e-3 || prop.dl[j]<0.1*propa.dls[j] || prop.dl[j]>3.0*propa.dls[j])
+                               prop.kwx=mymax(prop.kwx,3);
+
+               if (prop.ens < 250.0 || prop.ens > 400.0 || prop.gme < 75e-9 || prop.gme > 250e-9 || prop_zgnd.real() <= abs(prop_zgnd.imag()) || prop.wn < 0.419 || prop.wn > 420.0)
+                       prop.kwx=4;
+
+               for (j=0; j<2; ++j)
+                       if (prop.hg[j]<0.5 || prop.hg[j]>3000.0)
+                               prop.kwx=4;
+
+               dmin=abs(prop.he[0]-prop.he[1])/200e-3;
+               q=adiff(0.0,prop,propa);
+               xae=pow(prop.wn*prop.gme*prop.gme,-THIRD);
+               d3=mymax(propa.dlsa,1.3787*xae+propa.dla);
+               d4=d3+2.7574*xae;
+               a3=adiff(d3,prop,propa);
+               a4=adiff(d4,prop,propa);
+               propa.emd=(a4-a3)/(d4-d3);
+               propa.aed=a3-propa.emd*d3;
+
+               if (prop.mdp==0)
+                       prop.dist=0;
+
+               else if (prop.mdp>0)
+               {
+                       prop.mdp=0;
+                       prop.dist=0;
+               }
+
+               if ((prop.dist>0.0) || (prop.mdp<0.0))
+               {
+                       if (prop.dist>1000e3)
+                               prop.kwx=mymax(prop.kwx,1);
+
+                       if (prop.dist<dmin)
+                               prop.kwx=mymax(prop.kwx,3);
+
+                       if (prop.dist<1e3 || prop.dist>2000e3)
+                               prop.kwx=4;
+               }
+       }
+
+       else
+       {
+               prop.dist=d;
+
+               if (prop.dist>0.0)
+               {
+                       if (prop.dist>1000e3)
+                               prop.kwx=mymax(prop.kwx,1);
+
+                       if (prop.dist<dmin)
+                               prop.kwx=mymax(prop.kwx,3);
+
+                       if (prop.dist<1e3 || prop.dist>2000e3)
+                               prop.kwx=4;
+               }
+       }
+
+       if (prop.dist<propa.dlsa)
+       {
+               if (!wlos)
+               {
+                       /* Coefficients for the line-of-sight range */
+
+                       q=alos(0.0,prop,propa);
+                       d2=propa.dlsa;
+                       a2=propa.aed+d2*propa.emd;
+                       d0=1.908*prop.wn*prop.he[0]*prop.he[1];
+
+                       if (propa.aed>=0.0)
+                       {
+                               d0=mymin(d0,0.5*propa.dla);
+                               d1=d0+0.25*(propa.dla-d0);
+                       }
+
+                       else
+                               d1=mymax(-propa.aed/propa.emd,0.25*propa.dla);
+
+                       a1=alos(d1,prop,propa);
+        
+                       if (d0<d1)
+                       {
+                               a0=alos(d0,prop,propa);
+                               q=log(d2/d0);
+                               propa.ak2=mymax(0.0,((d2-d0)*(a1-a0)-(d1-d0)*(a2-a0))/((d2-d0)*log(d1-d0)-(d1-d0)*q));
+
+                               if (propa.ak2<=0.0 && propa.aed<0.0)
+                               {
+                                       propa.ak2=0.0;
+                                       propa.ak1=(a2-a1)/(d2-d1);
+
+                                       if (propa.ak1<=0.0)
+                                               propa.ak2=propa.emd;
+                               }
+
+                               else
+                               {
+                                       propa.ak1=(a2-a0-propa.ak2*q)/(d2-d0);
+
+                                       if (propa.ak1<0.0)
+                                       {
+                                               propa.ak1=0.0;
+                                               propa.ak2=FORTRAN_DIM(a2,a0)/q;
+
+                                               if (propa.ak2<=0.0)
+                                                       propa.ak1=propa.emd;
+                                       }
+                               }
+                               propa.ael=a2-propa.ak1*d2-propa.ak2*log(d2);
+                               wlos=true;
+                       }
+               }
+
+               if (prop.dist>0.0)
+                       prop.aref=propa.ael+propa.ak1*prop.dist+propa.ak2*log(prop.dist);
+       }
+
+       else
+       {
+               if (!wscat)
+               {
+                       q=ascat(0.0,prop,propa);
+                       d5=propa.dla+200e3;
+                       d6=d5+200e3;
+                       a6=ascat(d6,prop,propa);
+                       a5=ascat(d5,prop,propa);
+
+                       if (a5>=1000.0)
+                       {
+                               propa.ems=propa.emd;
+                               propa.aes=propa.aed;
+                               propa.dx=10e6;
+                       }
+
+                       else
+                       {
+                               propa.ems=(a6-a5)/200e3;
+                               propa.dx=mymax(propa.dlsa,mymax(propa.dla+0.3*xae*log(47.7*prop.wn),(a5-propa.aed-propa.ems*d5)/(propa.emd-propa.ems)));
+                               propa.aes=(propa.emd-propa.ems)*propa.dx+propa.aed;
+                       }
+
+                       wscat=true;
+               }
+
+               if (prop.dist<=propa.dx)
+                       prop.aref=propa.aed+propa.emd*prop.dist;
+               else
+                       prop.aref=propa.aes+propa.ems*prop.dist;
+       }
+
+       prop.aref=FORTRAN_DIM(prop.aref,0.0);
+}
+
+void lrprop (double d, prop_type &prop, propa_type &propa)
+{
+       /* PaulM_lrprop */
+       static bool wlos, wscat;
+       static double dmin, xae;
+       complex<double> prop_zgnd(prop.zgndreal,prop.zgndimag);
+       double a0, a1, a2, a3, a4, a5, a6;
+       double d0, d1, d2, d3, d4, d5, d6;
+       bool wq;
+       double q;
+       int j;
+
+       if (prop.mdp!=0)
+       {
+               for (j=0; j<2; j++)
+                       propa.dls[j]=sqrt(2.0*prop.he[j]/prop.gme);
+
+               propa.dlsa=propa.dls[0]+propa.dls[1];
+               propa.dla=prop.dl[0]+prop.dl[1];
+               propa.tha=mymax(prop.the[0]+prop.the[1],-propa.dla*prop.gme);
+               wlos=false;
+               wscat=false;
+
+               if (prop.wn<0.838 || prop.wn>210.0)
+                       prop.kwx=mymax(prop.kwx,1);
+
+               for (j=0; j<2; j++)
+                       if (prop.hg[j]<1.0 || prop.hg[j]>1000.0)
+                               prop.kwx=mymax(prop.kwx,1);
+
+               for (j=0; j<2; j++)
+                       if (abs(prop.the[j]) >200e-3 || prop.dl[j]<0.1*propa.dls[j] || prop.dl[j]>3.0*propa.dls[j] )
+                               prop.kwx=mymax(prop.kwx,3);
+
+               if (prop.ens < 250.0 || prop.ens > 400.0 || prop.gme < 75e-9 || prop.gme > 250e-9 || prop_zgnd.real() <= abs(prop_zgnd.imag()) || prop.wn < 0.419 || prop.wn > 420.0)
+                       prop.kwx=4;
+
+               for (j=0; j<2; j++)
+                       if (prop.hg[j]<0.5 || prop.hg[j]>3000.0)
+                               prop.kwx=4;
+
+               dmin=abs(prop.he[0]-prop.he[1])/200e-3;
+               q=adiff(0.0,prop,propa);
+               /* xae=pow(prop.wn*pow(prop.gme,2.),-THIRD); -- JDM made argument 2 a double */
+               xae=pow(prop.wn*(prop.gme*prop.gme),-THIRD);  /* No 2nd pow() */
+               d3=mymax(propa.dlsa,1.3787*xae+propa.dla);
+               d4=d3+2.7574*xae;
+               a3=adiff(d3,prop,propa);
+               a4=adiff(d4,prop,propa);
+               propa.emd=(a4-a3)/(d4-d3);
+               propa.aed=a3-propa.emd*d3;
+       }
+
+       if (prop.mdp>=0)
+       {
+               prop.mdp=0;
+               prop.dist=d;
+       }
+
+       if (prop.dist>0.0)
+       {
+               if (prop.dist>1000e3)
+                       prop.kwx=mymax(prop.kwx,1);
+
+               if (prop.dist<dmin)
+                       prop.kwx=mymax(prop.kwx,3);
+
+               if (prop.dist<1e3 || prop.dist>2000e3)
+                       prop.kwx=4;
+       }
+
+       if (prop.dist<propa.dlsa)
+       {
+               if (!wlos)
+               {
+                       q=alos(0.0,prop,propa);
+                       d2=propa.dlsa;
+                       a2=propa.aed+d2*propa.emd;
+                       d0=1.908*prop.wn*prop.he[0]*prop.he[1];
+
+                       if (propa.aed>=0.0)
+                       {
+                               d0=mymin(d0,0.5*propa.dla);
+                               d1=d0+0.25*(propa.dla-d0);
+                       }
+
+                       else
+                               d1=mymax(-propa.aed/propa.emd,0.25*propa.dla);
+
+                       a1=alos(d1,prop,propa);
+                       wq=false;
+
+                       if (d0<d1)
+                       {
+                               a0=alos(d0,prop,propa);
+                               q=log(d2/d0);
+                               propa.ak2=mymax(0.0,((d2-d0)*(a1-a0)-(d1-d0)*(a2-a0))/((d2-d0)*log(d1/d0)-(d1-d0)*q));
+                               wq=propa.aed>=0.0 || propa.ak2>0.0;
+
+                               if (wq)
+                               { 
+                                       propa.ak1=(a2-a0-propa.ak2*q)/(d2-d0);
+
+                                       if (propa.ak1<0.0)
+                                       {
+                                               propa.ak1=0.0;
+                                               propa.ak2=FORTRAN_DIM(a2,a0)/q;
+
+                                               if (propa.ak2==0.0)
+                                                       propa.ak1=propa.emd;
+                                       }
+                               }
+
+                               else
+                               {
+                                       propa.ak2=0.0;
+                                       propa.ak1=(a2-a1)/(d2-d1);
+
+                                       if (propa.ak1<=0.0)
+                                               propa.ak1=propa.emd;
+                               }
+                       }
+       
+                       else
+                       {
+                               propa.ak1=(a2-a1)/(d2-d1);
+                               propa.ak2=0.0;
+
+                               if (propa.ak1<=0.0)
+                                       propa.ak1=propa.emd;
+                       }
+
+                       propa.ael=a2-propa.ak1*d2-propa.ak2*log(d2);
+                       wlos=true;
+               }
+
+               if (prop.dist>0.0)
+                       prop.aref=propa.ael+propa.ak1*prop.dist+propa.ak2*log(prop.dist);
+
+       }
+
+       if (prop.dist<=0.0 || prop.dist>=propa.dlsa)
+       {
+               if(!wscat)
+               { 
+                       q=ascat(0.0,prop,propa);
+                       d5=propa.dla+200e3;
+                       d6=d5+200e3;
+                       a6=ascat(d6,prop,propa);
+                       a5=ascat(d5,prop,propa);
+
+                       if (a5<1000.0)
+                       {
+                               propa.ems=(a6-a5)/200e3;
+                               propa.dx=mymax(propa.dlsa,mymax(propa.dla+0.3*xae*log(47.7*prop.wn),(a5-propa.aed-propa.ems*d5)/(propa.emd-propa.ems)));
+                               propa.aes=(propa.emd-propa.ems)*propa.dx+propa.aed;
+                       }
+
+                       else
+                       {
+                               propa.ems=propa.emd;
+                               propa.aes=propa.aed;
+                               propa.dx=10.e6;
+                       }
+
+                       wscat=true;
+               }
+
+               if (prop.dist>propa.dx)
+                       prop.aref=propa.aes+propa.ems*prop.dist;
+               else
+                       prop.aref=propa.aed+propa.emd*prop.dist;
+       }
+
+       prop.aref=mymax(prop.aref,0.0);
+}
+
+double curve (double const &c1, double const &c2, double const &x1,
+              double const &x2, double const &x3, double const &de)
+{
+       /* return (c1+c2/(1.0+pow((de-x2)/x3,2.0)))*pow(de/x1,2.0)/(1.0+pow(de/x1,2.0)); */
+       double temp1, temp2;
+
+       temp1=(de-x2)/x3;
+       temp2=de/x1;
+
+       temp1*=temp1;
+       temp2*=temp2;
+
+       return (c1+c2/(1.0+temp1))*temp2/(1.0+temp2);
+}
+
+double avar(double zzt, double zzl, double zzc, prop_type &prop, propv_type &propv)
+{
+       static  int kdv;
+       static  double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
+               gm, gp, cv1, cv2, yv1, yv2, yv3, csm1, csm2, ysm1, ysm2,
+               ysm3, csp1, csp2, ysp1, ysp2, ysp3, csd1, zd, cfm1, cfm2,
+               cfm3, cfp1, cfp2, cfp3;
+
+       double bv1[7]={-9.67,-0.62,1.26,-9.21,-0.62,-0.39,3.15};
+       double bv2[7]={12.7,9.19,15.5,9.05,9.19,2.86,857.9};
+       double xv1[7]={144.9e3,228.9e3,262.6e3,84.1e3,228.9e3,141.7e3,2222.e3};
+       double xv2[7]={190.3e3,205.2e3,185.2e3,101.1e3,205.2e3,315.9e3,164.8e3};
+       double xv3[7]={133.8e3,143.6e3,99.8e3,98.6e3,143.6e3,167.4e3,116.3e3};
+       double bsm1[7]={2.13,2.66,6.11,1.98,2.68,6.86,8.51};
+       double bsm2[7]={159.5,7.67,6.65,13.11,7.16,10.38,169.8};
+       double xsm1[7]={762.2e3,100.4e3,138.2e3,139.1e3,93.7e3,187.8e3,609.8e3};
+       double xsm2[7]={123.6e3,172.5e3,242.2e3,132.7e3,186.8e3,169.6e3,119.9e3};
+       double xsm3[7]={94.5e3,136.4e3,178.6e3,193.5e3,133.5e3,108.9e3,106.6e3};
+       double bsp1[7]={2.11,6.87,10.08,3.68,4.75,8.58,8.43};
+       double bsp2[7]={102.3,15.53,9.60,159.3,8.12,13.97,8.19};
+       double xsp1[7]={636.9e3,138.7e3,165.3e3,464.4e3,93.2e3,216.0e3,136.2e3};
+       double xsp2[7]={134.8e3,143.7e3,225.7e3,93.1e3,135.9e3,152.0e3,188.5e3};
+       double xsp3[7]={95.6e3,98.6e3,129.7e3,94.2e3,113.4e3,122.7e3,122.9e3};
+       double bsd1[7]={1.224,0.801,1.380,1.000,1.224,1.518,1.518};
+       double bzd1[7]={1.282,2.161,1.282,20.,1.282,1.282,1.282};
+       double bfm1[7]={1.0,1.0,1.0,1.0,0.92,1.0,1.0};
+       double bfm2[7]={0.0,0.0,0.0,0.0,0.25,0.0,0.0};
+       double bfm3[7]={0.0,0.0,0.0,0.0,1.77,0.0,0.0};
+       double bfp1[7]={1.0,0.93,1.0,0.93,0.93,1.0,1.0};
+       double bfp2[7]={0.0,0.31,0.0,0.19,0.31,0.0,0.0};
+       double bfp3[7]={0.0,2.00,0.0,1.79,2.00,0.0,0.0};
+       static bool ws, w1;
+       double rt=7.8, rl=24.0, avarv, q, vs, zt, zl, zc;
+       double sgt, yr, temp1, temp2;
+       int temp_klim=propv.klim-1;
+
+       if (propv.lvar>0)
+       {
+               switch (propv.lvar)
+               {
+                       default:
+                       if (propv.klim<=0 || propv.klim>7)
+                       {
+                               propv.klim=5;
+                               temp_klim=4;
+                               prop.kwx=mymax(prop.kwx,2);
+                       }
+
+                       cv1=bv1[temp_klim];
+                       cv2=bv2[temp_klim];
+                       yv1=xv1[temp_klim];
+                       yv2=xv2[temp_klim];
+                       yv3=xv3[temp_klim];
+                       csm1=bsm1[temp_klim];
+                       csm2=bsm2[temp_klim];
+                       ysm1=xsm1[temp_klim];
+                       ysm2=xsm2[temp_klim];
+                       ysm3=xsm3[temp_klim];
+                       csp1=bsp1[temp_klim];
+                       csp2=bsp2[temp_klim];
+                       ysp1=xsp1[temp_klim];
+                       ysp2=xsp2[temp_klim];
+                       ysp3=xsp3[temp_klim];
+                       csd1=bsd1[temp_klim];
+                       zd=bzd1[temp_klim];
+                       cfm1=bfm1[temp_klim];
+                       cfm2=bfm2[temp_klim];
+                       cfm3=bfm3[temp_klim];
+                       cfp1=bfp1[temp_klim];
+                       cfp2=bfp2[temp_klim];
+                       cfp3=bfp3[temp_klim];
+
+                       case 4:
+                       kdv=propv.mdvar;
+                       ws=kdv>=20;
+
+                       if (ws)
+                               kdv-=20;
+
+                       w1=kdv>=10;
+
+                       if (w1)
+                               kdv-=10;
+
+                       if (kdv<0 || kdv>3)
+                       {
+                               kdv=0;
+                               prop.kwx=mymax(prop.kwx,2);
+                       }
+
+                       case 3:
+                       q=log(0.133*prop.wn);
+
+                       /* gm=cfm1+cfm2/(pow(cfm3*q,2.0)+1.0); */
+                       /* gp=cfp1+cfp2/(pow(cfp3*q,2.0)+1.0); */
+
+                       gm=cfm1+cfm2/((cfm3*q*cfm3*q)+1.0);
+                       gp=cfp1+cfp2/((cfp3*q*cfp3*q)+1.0);
+
+                       case 2:
+                       dexa=sqrt(18e6*prop.he[0])+sqrt(18e6*prop.he[1])+pow((575.7e12/prop.wn),THIRD);
+
+                       case 1:
+                       if (prop.dist<dexa)
+                               de=130e3*prop.dist/dexa;
+                       else
+                               de=130e3+prop.dist-dexa;
+               }
+
+               vmd=curve(cv1,cv2,yv1,yv2,yv3,de);
+               sgtm=curve(csm1,csm2,ysm1,ysm2,ysm3,de)*gm;
+               sgtp=curve(csp1,csp2,ysp1,ysp2,ysp3,de)*gp;
+               sgtd=sgtp*csd1;
+               tgtd=(sgtp-sgtd)*zd;
+
+               if (w1)
+                       sgl=0.0;
+               else
+               {
+                       q=(1.0-0.8*exp(-prop.dist/50e3))*prop.dh*prop.wn;
+                       sgl=10.0*q/(q+13.0);
+               }
+
+               if (ws)
+                       vs0=0.0;
+               else
+               {
+                       /* vs0=pow(5.0+3.0*exp(-de/100e3),2.0); */
+                       temp1=(5.0+3.0*exp(-de/100e3));
+                       vs0=temp1*temp1;
+
+               }
+
+               propv.lvar=0;
+       }
+
+       zt=zzt;
+       zl=zzl;
+       zc=zzc;
+
+       switch (kdv)
+       {
+               case 0:
+               zt=zc;
+               zl=zc;
+               break;
+
+               case 1:
+               zl=zc;
+               break;
+
+               case 2:
+               zl=zt;
+       }
+
+       if (fabs(zt)>3.1 || fabs(zl)>3.1 || fabs(zc)>3.1)
+               prop.kwx=mymax(prop.kwx,1);
+
+       if (zt<0.0)
+               sgt=sgtm;
+
+       else if (zt<=zd)
+               sgt=sgtp;
+
+       else
+               sgt=sgtd+tgtd/zt;
+
+       /* vs=vs0+pow(sgt*zt,2.0)/(rt+zc*zc)+pow(sgl*zl,2.0)/(rl+zc*zc); */
+
+       temp1=sgt*zt;
+       temp2=sgl*zl;
+
+       vs=vs0+(temp1*temp1)/(rt+zc*zc)+(temp2*temp2)/(rl+zc*zc);
+
+       if (kdv==0)
+       {
+               yr=0.0;
+               propv.sgc=sqrt(sgt*sgt+sgl*sgl+vs);
+       }
+
+       else if (kdv==1)
+       {
+               yr=sgt*zt;
+               propv.sgc=sqrt(sgl*sgl+vs);
+       }
+
+       else if (kdv==2)
+       {
+               yr=sqrt(sgt*sgt+sgl*sgl)*zt;
+               propv.sgc=sqrt(vs);
+       }
+
+       else
+       {
+               yr=sgt*zt+sgl*zl;
+               propv.sgc=sqrt(vs);
+       }
+
+       avarv=prop.aref-vmd-yr-propv.sgc*zc;
+
+       if (avarv<0.0)
+               avarv=avarv*(29.0-avarv)/(29.0-10.0*avarv);
+
+       return avarv;
+}
+
+void hzns (double pfl[], prop_type &prop)
+{
+       bool wq;
+       int np;
+       double xi, za, zb, qc, q, sb, sa;
+
+       np=(int)pfl[0];
+       xi=pfl[1];
+       za=pfl[2]+prop.hg[0];
+       zb=pfl[np+2]+prop.hg[1];
+       qc=0.5*prop.gme;
+       q=qc*prop.dist;
+       prop.the[1]=(zb-za)/prop.dist;
+       prop.the[0]=prop.the[1]-q;
+       prop.the[1]=-prop.the[1]-q;
+       prop.dl[0]=prop.dist;
+       prop.dl[1]=prop.dist;
+
+       if (np>=2)
+       {
+               sa=0.0;
+               sb=prop.dist;
+               wq=true;
+
+               for (int i=1; i<np; i++)
+               {
+                       sa+=xi;
+                       sb-=xi;
+                       q=pfl[i+2]-(qc*sa+prop.the[0])*sa-za;
+
+                       if (q>0.0)
+                       {
+                               prop.the[0]+=q/sa;
+                               prop.dl[0]=sa;
+                               wq=false;
+                       }
+
+                       if (!wq)
+                       {
+                               q=pfl[i+2]-(qc*sb+prop.the[1])*sb-zb;
+
+                               if (q>0.0)
+                               {
+                                       prop.the[1]+=q/sb;
+                                       prop.dl[1]=sb;
+                               }
+                       }
+               }
+       }
+}
+  
+void z1sq1 (double z[], const double &x1, const double &x2, double& z0, double& zn)
+{
+       double xn, xa, xb, x, a, b;
+       int n, ja, jb;
+
+       xn=z[0];
+       xa=int(FORTRAN_DIM(x1/z[1],0.0));
+       xb=xn-int(FORTRAN_DIM(xn,x2/z[1]));
+
+       if (xb<=xa)
+       {
+               xa=FORTRAN_DIM(xa,1.0);
+               xb=xn-FORTRAN_DIM(xn,xb+1.0);
+       }
+
+       ja=(int)xa;
+       jb=(int)xb;
+       n=jb-ja;
+       xa=xb-xa;
+       x=-0.5*xa;
+       xb+=x;
+       a=0.5*(z[ja+2]+z[jb+2]);
+       b=0.5*(z[ja+2]-z[jb+2])*x;
+
+       for (int i=2; i<=n; ++i)
+       {
+               ++ja;
+               x+=1.0;
+               a+=z[ja+2];
+               b+=z[ja+2]*x;
+       }
+
+       a/=xa;
+       b=b*12.0/((xa*xa+2.0)*xa);
+       z0=a-b*xb;
+       zn=a+b*(xn-xb);
+}
+
+double qtile (const int &nn, double a[], const int &ir)
+{
+       double q=0.0, r; /* q initialization -- KD2BD */
+       int m, n, i, j, j1=0, i0=0, k;  /* more initializations -- KD2BD */
+       bool done=false;
+       bool goto10=true;
+
+       m=0;
+       n=nn;
+       k=mymin(mymax(0,ir),n);
+
+       while (!done)
+       {
+               if (goto10)
+               {
+                       q=a[k];
+                       i0=m;
+                       j1=n;
+               }
+
+               i=i0;
+
+               while (i<=n && a[i]>=q)
+                       i++;
+
+               if (i>n)
+                       i=n;
+
+               j=j1;
+
+               while (j>=m && a[j]<=q)
+                       j--;
+
+               if (j<m)
+                       j=m;
+
+               if (i<j)
+               {
+                       r=a[i];
+                       a[i]=a[j];
+                       a[j]=r;
+                       i0=i+1;
+                       j1=j-1;
+                       goto10=false;
+               }
+
+               else if (i<k)
+               {
+                       a[k]=a[i];
+                       a[i]=q;
+                       m=i+1;
+                       goto10=true;
+               }
+
+               else if (j>k)
+               {
+                       a[k]=a[j];
+                       a[j]=q;
+                       n=j-1;
+                       goto10=true;
+               }
+
+               else
+               done=true;
+       }
+
+       return q;
+}
+
+double qerf(const double &z)
+{
+       double b1=0.319381530, b2=-0.356563782, b3=1.781477937;
+       double b4=-1.821255987, b5=1.330274429;
+       double rp=4.317008, rrt2pi=0.398942280;
+       double t, x, qerfv;
+
+       x=z;
+       t=fabs(x);
+
+       if (t>=10.0)
+               qerfv=0.0;
+       else
+       {
+               t=rp/(t+rp);
+               qerfv=exp(-0.5*x*x)*rrt2pi*((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t;
+       }
+
+       if (x<0.0)
+               qerfv=1.0-qerfv;
+
+       return qerfv;
+}
+
+double d1thx(double pfl[], const double &x1, const double &x2)
+{
+       int np, ka, kb, n, k, j;
+       double d1thxv, sn, xa, xb;
+       double *s;
+
+       np=(int)pfl[0];
+       xa=x1/pfl[1];
+       xb=x2/pfl[1];
+       d1thxv=0.0;
+
+       if (xb-xa<2.0)  // exit out
+               return d1thxv;
+
+       ka=(int)(0.1*(xb-xa+8.0));
+       ka=mymin(mymax(4,ka),25);
+       n=10*ka-5;
+       kb=n-ka+1;
+       sn=n-1;
+       assert((s=new double[n+2])!=0);
+       s[0]=sn;
+       s[1]=1.0;
+       xb=(xb-xa)/sn;
+       k=(int)(xa+1.0);
+       xa-=(double)k;
+
+       for (j=0; j<n; j++)
+       {
+               while (xa>0.0 && k<np)
+               {
+                       xa-=1.0;
+                       ++k;
+               }
+
+               s[j+2]=pfl[k+2]+(pfl[k+2]-pfl[k+1])*xa;
+               xa=xa+xb;
+       }
+
+       z1sq1(s,0.0,sn,xa,xb);
+       xb=(xb-xa)/sn;
+
+       for (j=0; j<n; j++)
+       {
+               s[j+2]-=xa;
+               xa=xa+xb;
+       }
+
+       d1thxv=qtile(n-1,s+2,ka-1)-qtile(n-1,s+2,kb-1);
+       d1thxv/=1.0-0.8*exp(-(x2-x1)/50.0e3);
+       delete[] s;
+
+       return d1thxv;
+}
+
+void qlrpfl(double pfl[], int klimx, int mdvarx, prop_type &prop, propa_type &propa, propv_type &propv)
+{
+       int np, j;
+       double xl[2], q, za, zb, temp;
+
+       prop.dist=pfl[0]*pfl[1];
+       np=(int)pfl[0];
+       hzns(pfl,prop);
+
+       for (j=0; j<2; j++)
+               xl[j]=mymin(15.0*prop.hg[j],0.1*prop.dl[j]);
+
+       xl[1]=prop.dist-xl[1];
+       prop.dh=d1thx(pfl,xl[0],xl[1]);
+
+       if (prop.dl[0]+prop.dl[1]>1.5*prop.dist)
+       {
+               z1sq1(pfl,xl[0],xl[1],za,zb);
+               prop.he[0]=prop.hg[0]+FORTRAN_DIM(pfl[2],za);
+               prop.he[1]=prop.hg[1]+FORTRAN_DIM(pfl[np+2],zb);
+
+               for (j=0; j<2; j++)
+                       prop.dl[j]=sqrt(2.0*prop.he[j]/prop.gme)*exp(-0.07*sqrt(prop.dh/mymax(prop.he[j],5.0)));
+
+               q=prop.dl[0]+prop.dl[1];
+
+               if (q<=prop.dist)
+               {
+                       /* q=pow(prop.dist/q,2.0); */
+                       temp=prop.dist/q;
+                       q=temp*temp;
+
+                       for (j=0; j<2; j++)
+                       {
+                               prop.he[j]*=q;
+                               prop.dl[j]=sqrt(2.0*prop.he[j]/prop.gme)*exp(-0.07*sqrt(prop.dh/mymax(prop.he[j],5.0)));
+                       }
+               }
+
+               for (j=0; j<2; j++)
+               {
+                       q=sqrt(2.0*prop.he[j]/prop.gme);
+                       prop.the[j]=(0.65*prop.dh*(q/prop.dl[j]-1.0)-2.0*prop.he[j])/q;
+               }
+       }
+
+       else
+       {
+               z1sq1(pfl,xl[0],0.9*prop.dl[0],za,q);
+               z1sq1(pfl,prop.dist-0.9*prop.dl[1],xl[1],q,zb);
+               prop.he[0]=prop.hg[0]+FORTRAN_DIM(pfl[2],za);
+               prop.he[1]=prop.hg[1]+FORTRAN_DIM(pfl[np+2],zb);
+       }
+
+       prop.mdp=-1;
+       propv.lvar=mymax(propv.lvar,3);
+
+       if (mdvarx>=0)
+       {
+               propv.mdvar=mdvarx;
+               propv.lvar=mymax(propv.lvar,4);
+       }
+
+       if (klimx>0)
+       {
+               propv.klim=klimx;
+               propv.lvar=5;
+       }
+
+       lrprop(0.0,prop,propa);
+}
+
+double deg2rad(double d)
+{
+       return d*3.1415926535897/180.0;
+}
+
+//********************************************************
+//* Point-To-Point Mode Calculations                     *
+//********************************************************
+
+void point_to_point(double elev[], double tht_m, double rht_m, double eps_dielect, double sgm_conductivity, double eno_ns_surfref, double frq_mhz, int radio_climate, int pol, double conf, double rel, double &dbloss, char *strmode, int &errnum)
+
+/******************************************************************************
+
+       pol:
+               0-Horizontal, 1-Vertical
+
+       radio_climate:
+               1-Equatorial, 2-Continental Subtropical,
+               3-Maritime Tropical, 4-Desert, 5-Continental Temperate,
+               6-Maritime Temperate, Over Land, 7-Maritime Temperate,
+               Over Sea
+
+       conf, rel: .01 to .99
+
+       elev[]: [num points - 1], [delta dist(meters)],
+               [height(meters) point 1], ..., [height(meters) point n]
+
+       errnum: 0- No Error.
+               1- Warning: Some parameters are nearly out of range.
+                           Results should be used with caution.
+               2- Note: Default parameters have been substituted for
+                        impossible ones.
+               3- Warning: A combination of parameters is out of range.
+                           Results are probably invalid.
+               Other-  Warning: Some parameters are out of range.
+                       Results are probably invalid.
+
+*****************************************************************************/
+{
+       prop_type   prop;
+       propv_type  propv;
+       propa_type  propa;
+       double zsys=0;
+       double zc, zr;
+       double eno, enso, q;
+       long ja, jb, i, np;
+       double dkm, xkm;
+       double fs;
+
+       prop.hg[0]=tht_m;
+       prop.hg[1]=rht_m;
+       propv.klim=radio_climate;
+       prop.kwx=0;
+       propv.lvar=5;
+       prop.mdp=-1;
+       zc=qerfi(conf);
+       zr=qerfi(rel);
+       np=(long)elev[0];
+       dkm=(elev[1]*elev[0])/1000.0;
+       xkm=elev[1]/1000.0;
+       eno=eno_ns_surfref;
+       enso=0.0;
+       q=enso;
+
+       if (q<=0.0)
+       {
+               ja=(long)(3.0+0.1*elev[0]);  /* KD2BD added (long) */
+               jb=np-ja+6;
+
+               for (i=ja-1; i<jb; ++i)
+                       zsys+=elev[i];
+
+               zsys/=(jb-ja+1);
+               q=eno;
+       }
+
+       propv.mdvar=12;
+       qlrps(frq_mhz,zsys,q,pol,eps_dielect,sgm_conductivity,prop);
+       qlrpfl(elev,propv.klim,propv.mdvar,prop,propa,propv);
+       fs=32.45+20.0*log10(frq_mhz)+20.0*log10(prop.dist/1000.0);
+       q=prop.dist-propa.dla;
+
+       if (int(q)<0.0)
+               strcpy(strmode,"Line-Of-Sight Mode");
+       else
+       {
+               if (int(q)==0.0)
+                       strcpy(strmode,"Single Horizon");
+
+               else if (int(q)>0.0)
+                       strcpy(strmode,"Double Horizon");
+
+               if (prop.dist<=propa.dlsa || prop.dist <= propa.dx)
+                       strcat(strmode,", Diffraction Dominant");
+
+               else if (prop.dist>propa.dx)
+                       strcat(strmode, ", Troposcatter Dominant");
+       }
+
+       dbloss=avar(zr,0.0,zc,prop,propv)+fs;
+       errnum=prop.kwx;
+}
+
+//********************************************************
+//* Area Mode Calculations                               *
+//********************************************************
+
+void area(long ModVar, double deltaH, double tht_m, double rht_m, double dist_km, int TSiteCriteria, int RSiteCriteria, double eps_dielect, double sgm_conductivity, double eno_ns_surfref, double frq_mhz, int radio_climate, int pol, double pctTime, double pctLoc, double pctConf, double &dbloss, char *strmode, int &errnum)
+{
+       // pol: 0-Horizontal, 1-Vertical
+       // TSiteCriteria, RSiteCriteria:
+       //                 0 - random, 1 - careful, 2 - very careful
+
+       // radio_climate: 1-Equatorial, 2-Continental Subtropical, 3-Maritime Tropical,
+       //                4-Desert, 5-Continental Temperate, 6-Maritime Temperate, Over Land,
+       //                7-Maritime Temperate, Over Sea
+       // ModVar: 0 - Single: pctConf is "Time/Situation/Location", pctTime, pctLoc not used
+    //         1 - Individual: pctTime is "Situation/Location", pctConf is "Confidence", pctLoc not used
+    //         2 - Mobile: pctTime is "Time/Locations (Reliability)", pctConf is "Confidence", pctLoc not used
+    //         3 - Broadcast: pctTime is "Time", pctLoc is "Location", pctConf is "Confidence"
+       // pctTime, pctLoc, pctConf: .01 to .99
+       // errnum: 0- No Error.
+       //         1- Warning: Some parameters are nearly out of range.
+       //                     Results should be used with caution.
+       //         2- Note: Default parameters have been substituted for impossible ones.
+       //         3- Warning: A combination of parameters is out of range.
+       //                     Results are probably invalid.
+       //         Other-  Warning: Some parameters are out of range.
+       //                          Results are probably invalid.
+       // NOTE: strmode is not used at this time.
+
+       prop_type prop;
+       propv_type propv;
+       propa_type propa;
+       double zt, zl, zc, xlb;
+       double fs;
+       long ivar;
+       double eps, eno, sgm;
+       long ipol;
+       int kst[2];
+
+       kst[0]=(int)TSiteCriteria;
+       kst[1]=(int)RSiteCriteria;
+       zt=qerfi(pctTime/100.0);
+       zl=qerfi(pctLoc/100.0);
+       zc=qerfi(pctConf/100.0);
+       eps=eps_dielect;
+       sgm=sgm_conductivity;
+       eno=eno_ns_surfref;
+       prop.dh=deltaH;
+       prop.hg[0]=tht_m;
+       prop.hg[1]=rht_m;
+       /* propv.klim = (__int32) radio_climate; -KD2BD replaced below */
+       propv.klim=(long)radio_climate;
+       prop.ens=eno;
+       prop.kwx=0;
+       ivar=(long)ModVar;
+       ipol=(long)pol;
+       qlrps(frq_mhz, 0.0, eno, ipol, eps, sgm, prop);
+       qlra(kst, propv.klim, ivar, prop, propv);
+
+       if (propv.lvar<1)
+               propv.lvar=1;
+
+       lrprop(dist_km*1000.0, prop, propa);
+       fs=32.45+20.0*log10(frq_mhz)+20.0*log10(prop.dist/1000.0);
+       xlb=fs+avar(zt, zl, zc, prop, propv);
+       dbloss=xlb;
+       if (prop.kwx==0)
+               errnum=0;
+       else
+               errnum=prop.kwx;
+}
diff --git a/sample.lrp b/sample.lrp
new file mode 100644 (file)
index 0000000..094c211
--- /dev/null
@@ -0,0 +1,72 @@
+15.000  ; Earth Dielectric Constant (Relative permittivity)
+0.005   ; Earth Conductivity (Siemens per meter)
+301.000 ; Atmospheric Bending Constant (N-units)
+300.000        ; Frequency in MHz (20 MHz to 20 GHz)
+5       ; Radio Climate (5 = Continental Temperate)
+0       ; Polarization (0 = Horizontal, 1 = Vertical)
+0.5     ; Fraction of situations (50% of locations)
+0.5     ; Fraction of time (50% of the time)
+
+This file contains Longley-Rice path loss parameters used
+by SPLAT!  Anything after the 8th line is ignored by the
+program.  Comments are allowed following each element of
+numeric data.  No blank lines are allowed at the top.
+
+Earth dielectric constants and conductivity values are as follows:
+
+                         Dielectric Constant   Conductivity
+       Salt water       :        80                5.000
+       Good ground      :        25                0.020
+       Fresh water      :        80                0.010
+       Marshy land      :        12                0.007
+       Farmland, forest :        15                0.005
+       Average ground   :        15                0.005
+       Mountain, sand   :        13                0.002
+       City             :         5                0.001
+       Poor ground      :         4                0.001
+
+Radio climate codes are defined as follows:
+
+       1: Equatorial (Congo)
+       2: Continental Subtropical (Sudan)
+       3: Maritime Subtropical (West coast of Africa)
+       4: Desert (Sahara)
+       5: Continental Temperate
+       6: Maritime Temperate, over land (UK and west coasts of US & EU)
+       7: Maritime Temperate, over sea
+
+The Continental Temperate climate (5) is common to large land masses in
+the temperate zone, such as the United States.  For paths shorter than
+100 km, there is little difference between Continental and Martitime
+Temperate climates.
+
+The final two parameters in the .lrp file correspond to the statistical
+analysis provided by the Longley-Rice model.  In this example, SPLAT!
+will return the maximum path loss occurring 50% of the time (fraction
+of time) in 50% of situations (fraction of situations).  Use a fraction
+of time of 0.97 for digital television, 0.50 for analog.  Isotropic
+antennas are assumed.  A tuned half-wave dipole has a gain of 2.14 dB
+above that of an isotropic antenna.
+
+Edit these parameters as required and save the result ("Save As")
+to a filename with an extension of ".lrp" in the directory normally
+used for .qth files (current working directory is assumed).  The
+base of the filename MUST match the base of the corresponding
+SPLAT! transmitter site QTH filename for proper correlation
+between data sets.  In other words:
+
+       wnjt.qth  <--- TX site data for WNJT
+       wnjt.lrp  <--- Corresponding Longly-Rice parameters for WNJT
+
+If an LRP file corresponding to the tx_site QTH file cannot be
+found, SPLAT! scans the current working directory for "splat.lrp".
+If this file cannot be found, then the default parameters listed
+above are assigned by SPLAT!, and a "splat.lrp" file containing
+these parameters is written to the current working directory.
+
+For further information on Longley-Rice model parameters, see:
+
+       http://elbert.its.bldrdoc.gov/itm.html
+       http://www.softwright.com/faq/engineering/prop_longley_rice.html
+
+Also consult SPLAT!'s documentation for more information.
diff --git a/smallfont.h b/smallfont.h
new file mode 100644 (file)
index 0000000..415af1f
--- /dev/null
@@ -0,0 +1,92 @@
+char smallfont[10][9][7] = {
+     { {0,1,1,1,1,1},    /* 0 */
+       {1,1,0,0,0,1,1},
+       {1,1,0,0,1,1,1},
+       {1,1,0,1,1,1,1},
+       {1,1,0,1,0,1,1},
+       {1,1,1,1,0,1,1},
+       {1,1,1,0,0,1,1},
+       {1,1,0,0,0,1,1},
+       {0,1,1,1,1,1} },
+     { {0,0,0,1},         /* 1 */
+       {0,0,1,1},
+       {1,1,1,1},
+       {0,0,1,1},
+       {0,0,1,1},
+       {0,0,1,1},
+       {0,0,1,1},
+       {0,0,1,1},
+       {1,1,1,1,1,1} },
+     { {0,1,1,1,1},        /* 2 */ 
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,1,1},
+       {0,0,1,1},
+       {0,1,1},
+       {1,1,0,0,1,1},
+       {1,1,1,1,1,1} },
+     { {0,1,1,1,1},        /* 3 */  
+       {1,1,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,1,1,1,1} }, 
+    {  {0,0,0,0,1,1},       /* 4 */
+       {0,0,0,1,1,1},
+       {0,0,1,1,1,1},
+       {0,1,1,0,1,1},
+       {1,1,1,1,1,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,1,1,1,1} },
+    {  {1,1,1,1,1,1},      /* 5 */
+       {1,1},
+       {1,1},
+       {1,1},
+       {1,1,1,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,1,1,1,1}  },
+    {  {0,0,1,1,1},       /* 6 */
+       {0,1,1},
+       {1,1},
+       {1,1},
+       {1,1,1,1,1},
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,1,1,1,1} },
+   {   {1,1,1,1,1,1,1},   /* 7 */
+       {1,1,0,0,0,1,1},
+       {1,1,0,0,0,1,1},
+       {0,0,0,0,0,1,1},
+       {0,0,0,0,1,1},
+       {0,0,0,1,1},
+       {0,0,1,1},
+       {0,0,1,1},
+       {0,0,1,1} },
+   {   {0,1,1,1,1},      /* 8 */
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,1,1,1,1},
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,1,1,1,1} },
+   {   {0,1,1,1,1},      /* 9 */
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {1,1,0,0,1,1},
+       {0,1,1,1,1,1},
+       {0,0,0,1,1},
+       {0,0,0,1,1},
+       {0,0,1,1},
+       {0,1,1,1} } };
+
diff --git a/splat-1.1.0.lsm b/splat-1.1.0.lsm
new file mode 100644 (file)
index 0000000..3785f71
--- /dev/null
@@ -0,0 +1,37 @@
+Begin3
+Title:         SPLAT!
+Version:       1.1.0
+Entered-date:  29JAN04
+Description:   SPLAT! is a terrestrial RF propagation analysis tool for
+               the spectrum between 20 MHz and 20 GHz.  SPLAT! provides
+               site engineering data such as the great circle distances
+               and bearings between sites, antenna elevation angles
+               (uptilt), depression angles (downtilt), antenna height
+               above mean sea level, antenna height above average
+               terrain, bearings and distances to known obstructions,
+               path loss based on the Longley-Rice Irregular Terrain
+               Model, and minimum antenna height requirements needed
+               to establish line-of-sight communication paths absent
+               of obstructions due to terrain.  SPLAT! produces
+               reports, graphs, and highly detailed and carefully
+               annotated topographic maps depicting line-of-sight paths,
+               path loss, and expected coverage areas of transmitters
+               and repeater systems.  Applications of SPLAT! include
+               site engineering, wireless network design, amateur
+               radio communications, frequency coordination,
+               communication system design, and terrestrial
+               television and radio broadcasting.  SPLAT! requires
+               gnuplot version 3.7, libbzip-1.0.1 or later, and
+               zlib, as well as an application capable of displaying
+               PPM graphic files (xv, ImageMagick, xpaint, The GIMP, etc.).
+Keywords:      Terrain analysis, site engineering, Longley-Rice path
+               loss, TV/FM radio broadcasting, TV/FM radio reception,
+               amateur radio, wireless WAN design
+Author:                kd2bd@amsat.org (John A. Magliacane) (Creator, Lead Developer)
+               mcdonald@scs.uiuc.edu (Doug McDonald) (L-R Model Integration)
+Maintained-by: kd2bd@amsat.org (John A. Magliacane)
+Primary-site:  ftp.ibiblio.org /pub/Linux/apps/ham/splat-1.1.0.tar.gz
+Original-site: http://www.qsl.net/kd2bd/splat.html
+Platforms:     Linux/Unix
+Copying-policy:        GPL
+End
diff --git a/splat.cpp b/splat.cpp
new file mode 100644 (file)
index 0000000..2fe6fd4
--- /dev/null
+++ b/splat.cpp
@@ -0,0 +1,4303 @@
+/****************************************************************************
+*                    SPLAT: A Terrain Analysis Program                     *
+*             Copyright John A. Magliacane, KD2BD 1997-2004                *
+*                       Last update: 24-Jan-2004                           *
+*****************************************************************************
+*                                                                          *
+* This program is free software; you can redistribute it and/or modify it   *
+* under the terms of the GNU General Public License as published by the     *
+* Free Software Foundation; either version 2 of the License or any later    *
+* version.                                                                 *
+*                                                                          *
+* This program is distributed in the hope that it will useful, but WITHOUT  *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     *
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
+* for more details.                                                        *
+*                                                                          *
+*****************************************************************************
+*                                                                          *
+*     Extensively modified by J. D. McDonald in Jan. 2004 to include        *
+*    the Longley-Rice propagation model using C++ code from NTIA/ITS.      *
+*                                                                          *
+*              See: http://elbert.its.bldrdoc.gov/itm.html                  *
+*                                                                          *
+*****************************************************************************
+ g++ -Wall -O3 -s -lm -lbz2 -fomit-frame-pointer itm.cpp splat.cpp -o splat 
+*****************************************************************************/
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <bzlib.h>
+#include <unistd.h>
+#include "fontdata.h"
+#include "smallfont.h"
+
+#define GAMMA 2.5
+#define MAXSLOTS 9
+#define BZBUFFER 65536
+
+#if MAXSLOTS==4
+#define ARRAYSIZE 4950
+#endif
+
+#if MAXSLOTS==9
+#define ARRAYSIZE 10870
+#endif
+
+#if MAXSLOTS==16
+#define ARRAYSIZE 19240
+#endif
+
+#if MAXSLOTS==25
+#define ARRAYSIZE 30025
+#endif
+
+char string[255], sdf_path[255], opened=0, *splat_version={"1.1.0"};
+
+double TWOPI=6.283185307179586, HALFPI=1.570796326794896,
+       PI=3.141592653589793, deg2rad=1.74532925199e-02,
+       EARTHRADIUS=20902230.97, METERS_PER_MILE=1609.344,
+       METERS_PER_FOOT=0.3048, earthradius, max_range=0.0;
+
+int    min_north=0, max_north=0, min_west=0, max_west=0,
+       max_elevation=0, min_elevation=0, bzerror;
+
+struct site { double lat;
+             double lon;
+             double alt;
+             char name[50];
+           };
+
+struct { float lat[ARRAYSIZE];
+         float lon[ARRAYSIZE];
+         float elevation[ARRAYSIZE];
+         float distance[ARRAYSIZE];
+         int length;
+       } path;
+
+struct { int min_north;
+        int max_north;
+        int min_west;
+        int max_west;
+        int max_el;
+        int min_el;
+        short data[1200][1200];
+        unsigned char mask[1200][1200];
+       } dem[MAXSLOTS];
+
+struct {
+       double eps_dielect; 
+       double sgm_conductivity; 
+       double eno_ns_surfref;
+       double frq_mhz; 
+       double conf; 
+       double rel;
+       int radio_climate;  
+       int pol;
+       } LR;
+
+double elev_l[ARRAYSIZE+10];
+
+void point_to_point(double elev[], double tht_m, double rht_m,
+         double eps_dielect, double sgm_conductivity, double eno_ns_surfref,
+         double frq_mhz, int radio_climate, int pol, double conf,
+         double rel, double &dbloss, char *strmode, int &errnum);
+
+double arccos(double x, double y)
+{
+       /* This function implements the arc cosine function,
+          returning a value between 0 and TWOPI. */
+
+       double result=0.0;
+
+       if (y>0.0)
+               result=acos(x/y);
+
+       if (y<0.0)
+               result=PI+acos(x/y);
+
+       return result;
+}
+
+char *dec2dms(double decimal)
+{
+       /* Converts decimal degrees to degrees, minutes, seconds,
+          (DMS) and returns the result as a character string. */
+       int degrees, minutes, seconds;
+       double a, b, c, d;
+
+       a=floor(decimal);
+       b=60.0*(decimal-a);
+       c=floor(b);
+       d=60.0*(b-c);
+
+       degrees=(int)a;
+       minutes=(int)c;
+       seconds=(int)d;
+
+       if (seconds<0)
+               seconds=0;
+
+       if (seconds>59)
+               seconds=59;
+
+       string[0]=0;
+       sprintf(string,"%d%c %d\' %d\"", degrees, 176, minutes, seconds);
+       return (string);
+}
+
+int OrMask(double lat, double lon, int value)
+{
+       /* Lines, text, markings, and coverage areas are stored in a
+          mask that is combined with topology data when topographic
+          maps are generated by SPLAT!.  This function sets bits in
+          the mask based on the latitude and longitude of the area
+          pointed to. */
+
+       int x, y, indx, minlat, minlon;
+       char found;
+
+       minlat=(int)floor(lat);
+       minlon=(int)floor(lon);
+
+       for (indx=0, found=0; indx<MAXSLOTS && found==0;)
+               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west)
+                       found=1;
+               else
+                       indx++;
+
+       if (found)
+       {
+               x=(int)(1199.0*(lat-floor(lat)));
+               y=(int)(1199.0*(lon-floor(lon)));
+
+               dem[indx].mask[x][y]|=value;
+               return (dem[indx].mask[x][y]);
+       }
+       else
+               return -1;
+}
+
+int GetMask(double lat, double lon)
+{
+       /* This function returns the mask bits based on the latitude
+          and longitude given. */
+
+       return (OrMask(lat,lon,0));
+}
+
+double GetElevation(struct site location)
+{
+       /* This function returns the elevation (in feet) of any location
+          represented by the digital elevation model data in memory.
+          Function returns -5000.0 for locations not found in memory. */
+
+       char found;
+       int x, y, indx, minlat, minlon;
+       double elevation;
+
+       elevation=-5000.0;
+
+       minlat=(int)floor(location.lat);
+       minlon=(int)floor(location.lon);
+
+       x=(int)(1199.0*(location.lat-floor(location.lat)));
+       y=(int)(1199.0*(location.lon-floor(location.lon)));
+
+       for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
+       {
+               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west)
+               {
+                       elevation=3.28084*dem[indx].data[x][y];
+                       found=1;
+               }
+       }
+       
+       return elevation;
+}
+
+double Distance(struct site site1, struct site site2)
+{
+       /* This function returns the great circle distance
+          in miles between any two site locations. */
+
+       double lat1, lon1, lat2, lon2, distance;
+
+       lat1=site1.lat*deg2rad;
+       lon1=site1.lon*deg2rad;
+       lat2=site2.lat*deg2rad;
+       lon2=site2.lon*deg2rad;
+
+       distance=3959.0*acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos((lon1)-(lon2)));
+
+       return distance;
+}
+
+double Azimuth(struct site source, struct site destination)
+{
+       /* This function returns the azimuth (in degrees) to the
+          destination as seen from the location of the source. */
+
+       double dest_lat, dest_lon, src_lat, src_lon,
+              beta, azimuth, diff, num, den, fraction;
+
+       dest_lat=destination.lat*deg2rad;
+       dest_lon=destination.lon*deg2rad;
+
+       src_lat=source.lat*deg2rad;
+       src_lon=source.lon*deg2rad;
+               
+       /* Calculate Surface Distance */
+
+       beta=acos(sin(src_lat)*sin(dest_lat)+cos(src_lat)*cos(dest_lat)*cos(src_lon-dest_lon));
+
+       /* Calculate Azimuth */
+
+       num=sin(dest_lat)-(sin(src_lat)*cos(beta));
+       den=cos(src_lat)*sin(beta);
+       fraction=num/den;
+
+       /* Trap potential problems in acos() due to rounding */
+
+       if (fraction>=1.0)
+               fraction=1.0;
+
+       if (fraction<=-1.0)
+               fraction=-1.0;
+
+       /* Calculate azimuth */
+
+       azimuth=acos(fraction);
+
+       /* Reference it to True North */
+
+       diff=dest_lon-src_lon;
+
+       if (diff<=-PI)
+               diff+=TWOPI;
+
+       if (diff>=PI)
+               diff-=TWOPI;
+
+       if (diff>0.0)
+               azimuth=TWOPI-azimuth;
+
+       return (azimuth/deg2rad);               
+}
+
+double ElevationAngle(struct site local, struct site remote)
+{
+       /* This function returns the angle of elevation (in degrees)
+          of the remote location as seen from the local site.
+          A positive result represents an angle of elevation (uptilt),
+          while a negative result represents an angle of depression
+          (downtilt), as referenced to a normal to the center of
+          the earth. */
+          
+       register double a, b, dx;
+
+       a=GetElevation(remote)+remote.alt+earthradius;
+       b=GetElevation(local)+local.alt+earthradius;
+
+       dx=5280.0*Distance(local,remote);
+
+       /* Apply the Law of Cosines */
+
+       return ((180.0*(acos(((b*b)+(dx*dx)-(a*a))/(2.0*b*dx)))/PI)-90.0);
+}
+
+void ReadPath(struct site source, struct site destination)
+{
+       /* This function generates a sequence of latitude and
+          longitude positions between a source location and
+          a destination along a great circle path, and stores
+          elevation and distance information for points along
+          that path in the "path" structure for later use. */
+
+       double azimuth, distance, lat1, lon1, beta,
+              den, num, lat2, lon2, total_distance;
+       int x1, y1, c;
+       struct site tempsite;
+
+       c=0;
+
+       lat1=source.lat*deg2rad;
+       lon1=source.lon*deg2rad;
+       azimuth=Azimuth(source,destination)*deg2rad;
+       total_distance=Distance(source,destination);
+
+       for (distance=0; distance<=total_distance; distance+=0.04)
+       {
+               beta=distance/3959.0;
+               lat2=asin(sin(lat1)*cos(beta)+cos(azimuth)*sin(beta)*cos(lat1));
+               num=cos(beta)-(sin(lat1)*sin(lat2));
+               den=cos(lat1)*cos(lat2);
+
+               if (azimuth==0.0 && (beta>HALFPI-lat1))
+                       lon2=lon1+PI;
+
+               else if (azimuth==HALFPI && (beta>HALFPI+lat1))
+                       lon2=lon1+PI;
+
+               else if (fabs(num/den)>1.0)
+                       lon2=lon1;
+
+               else
+               {
+                       if ((PI-azimuth)>=0.0)
+                               lon2=lon1-arccos(num,den);
+                       else
+                               lon2=lon1+arccos(num,den);
+               }
+       
+               while (lon2<0.0)
+                       lon2+=TWOPI;
+
+               while (lon2>TWOPI)
+                       lon2-=TWOPI;
+               lat2=lat2/deg2rad;
+               lon2=lon2/deg2rad;
+
+               x1=(int)(1199.0*(lat2-floor(lat2)));
+               y1=(int)(1199.0*(lon2-floor(lon2)));
+
+               path.lat[c]=lat2;
+               path.lon[c]=lon2;
+               tempsite.lat=lat2;
+               tempsite.lon=lon2;
+               path.elevation[c]=GetElevation(tempsite);
+               path.distance[c]=distance;
+               c++;
+       }
+
+       /* Make sure exact destination point is recorded at path.length-1 */
+
+       x1=(int)(1199.0*(destination.lat-floor(destination.lat)));
+       y1=(int)(1199.0*(destination.lon-floor(destination.lon)));
+
+       path.lat[c]=destination.lat;
+       path.lon[c]=destination.lon;
+       path.elevation[c]=GetElevation(destination);
+       path.distance[c]=total_distance;
+       c++;
+
+       path.length=c;
+}
+
+double AverageTerrain(struct site source, double azimuthx, double start_distance, double end_distance)
+{
+       /* This function returns the average terrain calculated in
+          the direction of "azimuth" (degrees) between "start_distance"
+          and "end_distance" (miles) from the source location.  If
+          the terrain is all water (non-critical error), -5000.0 is
+          returned.  If not enough SDF data has been loaded into
+          memory to complete the survey (critical error), then
+          -9999.0 is returned. */
+       int c, samples, endpoint;
+       double beta, lat1, lon1, lat2, lon2, num, den, azimuth, terrain=0.0;
+       struct site destination;
+
+       lat1=source.lat*deg2rad;
+       lon1=source.lon*deg2rad;
+
+       /* Generate a path of elevations between the source
+          location and the remote location provided. */
+
+       beta=end_distance/3959.0;
+
+       azimuth=deg2rad*azimuthx;
+
+       lat2=asin(sin(lat1)*cos(beta)+cos(azimuth)*sin(beta)*cos(lat1));
+       num=cos(beta)-(sin(lat1)*sin(lat2));
+       den=cos(lat1)*cos(lat2);
+
+       if (azimuth==0.0 && (beta>HALFPI-lat1))
+               lon2=lon1+PI;
+
+       else if (azimuth==HALFPI && (beta>HALFPI+lat1))
+               lon2=lon1+PI;
+
+       else if (fabs(num/den)>1.0)
+               lon2=lon1;
+
+       else
+       {
+               if ((PI-azimuth)>=0.0)
+                       lon2=lon1-arccos(num,den);
+               else
+                       lon2=lon1+arccos(num,den);
+       }
+       
+       while (lon2<0.0)
+               lon2+=TWOPI;
+
+       while (lon2>TWOPI)
+               lon2-=TWOPI;
+       lat2=lat2/deg2rad;
+       lon2=lon2/deg2rad;
+
+       destination.lat=lat2;
+       destination.lon=lon2;
+
+       /* If SDF data is missing for the endpoint of
+          the radial, then the average terrain cannot
+          be accurately calculated.  Return -9999.0 */
+
+       if (GetElevation(destination)<-4999.0)
+               return (-9999.0);
+       else
+       {
+               ReadPath(source,destination);
+
+               endpoint=path.length;
+
+               /* Shrink the length of the radial if the
+                  outermost portion is not over U.S. land. */
+
+               for (c=endpoint-1; c>=0 && path.elevation[c]==0.0; c--);
+
+               endpoint=c+1;
+
+               for (c=0, samples=0; c<endpoint; c++)
+               {
+                       if (path.distance[c]>=start_distance)
+                       {
+                               terrain+=path.elevation[c];
+                               samples++;
+                       }
+               }
+
+               if (samples==0)
+                       terrain=-5000.0;  /* No land */
+               else
+                       terrain=(terrain/(double)samples);
+
+               return terrain;
+       }
+}
+
+double haat(struct site antenna)
+{
+       /* This function returns the antenna's Height Above Average
+          Terrain (HAAT) based on FCC Part 73.313(d).  If a critical
+          error occurs, such as a lack of SDF data to complete the
+          survey, -5000.0 is returned. */
+
+       int azi, c;
+       char error=0;
+       double terrain, avg_terrain, haat, sum=0.0;
+
+       /* Calculate the average terrain between 2 and 10 miles
+          from the antenna site at azimuths of 0, 45, 90, 135,
+          180, 225, 270, and 315 degrees. */
+
+       for (c=0, azi=0; azi<=315 && error==0; azi+=45)
+       {
+               terrain=AverageTerrain(antenna, (double)azi, 2.0, 10.0);
+
+               if (terrain<-9998.0)  /* SDF data is missing */
+                       error=1;
+
+               if (terrain>-4999.0)  /* It's land, not water */
+               {
+                       sum+=terrain;  /* Sum of averages */
+                       c++;
+               }
+       }
+
+       if (error)
+               return -5000.0;
+       else
+       {
+               avg_terrain=(sum/(double)c);
+               haat=(antenna.alt+GetElevation(antenna))-avg_terrain;
+               return haat;
+       }
+}
+
+void PlaceMarker(struct site location)
+{
+       /* This function places text and marker data in the mask array
+          for illustration on topographic maps generated by SPLAT!.
+          By default, SPLAT! centers text information BELOW the marker,
+          but may move it above, to the left, or to the right of the
+          marker depending on how much room is available on the map,
+          or depending on whether the area is already occupied by
+          another marker or label.  If no room or clear space is
+          available on the map to place the marker and its associated
+          text, then the marker and text are not written to the map. */
+       int     a, b, c, byte;
+       char    ok2print, occupied;
+       double  x, y, lat, lon, textx=0.0, texty=0.0, xmin, xmax,
+               ymin, ymax, p1, p3, p6, p8, p12, p16, p24, label_length;
+
+       xmin=min_north;
+       xmax=max_north;
+       ymin=min_west;
+       ymax=max_west;
+       lat=location.lat;
+       lon=location.lon;
+
+       if (lat<xmax && lat>xmin && lon<ymax && lon>ymin)
+       {
+               p1=1.0/1200.0;
+               p3=3.0/1200.0;
+               p6=6.0/1200.0;
+               p8=8.0/1200.0;
+               p12=12.0/1200.0;
+               p16=16.0/1200.0;
+               p24=24.0/1200.0;
+               ok2print=0;
+               occupied=0;
+
+               /* Is Marker Position Clear Of Text Or Other Markers? */
+
+               for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
+                       for (y=lon-p3; (y<=ymax && y>=ymin && y<=lon+p3); y+=p1)
+                               occupied|=(GetMask(x,y)&2);
+
+               if (occupied==0)
+               {
+                       /* Determine Where Text Can Be Positioned */
+
+                       /* label_length=length in pixels.
+                          Each character is 8 pixels wide. */
+
+                       label_length=p1*(double)(strlen(location.name)<<3);
+
+                       if (((lon+label_length)<=ymax) && (lon-label_length)>=ymin)
+                       {
+                               /* Default: Centered Text */
+
+                               texty=lon+label_length/2.0;
+
+                               if ((lat-p8)>=p16)
+                               {
+                                       /* Position Text Below The Marker */
+
+                                       textx=lat-p8;
+
+                                       x=textx;
+                                       y=texty;
+       
+                                       /* Is This Position Clear Of
+                                          Text Or Other Markers? */
+
+                                       for (a=0, occupied=0; a<16; a++)
+                                       {
+                                               for (b=0; b<(int)strlen(location.name); b++)
+                                                       for (c=0; c<8; c++, y-=p1)
+                                                               occupied|=(GetMask(x,y)&2);
+                                               x-=p1;
+                                               y=texty;
+                                       }
+
+                                       x=textx;
+                                       y=texty;
+
+                                       if (occupied==0)
+                                               ok2print=1;
+                               }
+
+                               else
+                               {
+                                       /* Position Text Above The Marker */
+
+                                       textx=lat+p24;
+
+                                       x=textx;
+                                       y=texty;
+       
+                                       /* Is This Position Clear Of
+                                          Text Or Other Markers? */
+
+                                       for (a=0, occupied=0; a<16; a++)
+                                       {
+                                               for (b=0; b<(int)strlen(location.name); b++)
+                                                       for (c=0; c<8; c++, y-=p1)
+                                                               occupied|=(GetMask(x,y)&2);
+                                               x-=p1;
+                                               y=texty;
+                                       }
+
+                                       x=textx;
+                                       y=texty;
+
+                                       if (occupied==0)
+                                               ok2print=1;
+                               }
+                       }
+
+                       if (ok2print==0)
+                       {
+                               if ((lon-label_length)>=ymin)
+                               {
+                                       /* Position Text To The
+                                          Right Of The Marker */
+
+                                       textx=lat+p6;
+                                       texty=lon-p12;
+
+                                       x=textx;
+                                       y=texty;
+       
+                                       /* Is This Position Clear Of
+                                          Text Or Other Markers? */
+
+                                       for (a=0, occupied=0; a<16; a++)
+                                       {
+                                               for (b=0; b<(int)strlen(location.name); b++)
+                                                       for (c=0; c<8; c++, y-=p1)
+                                                               occupied|=(GetMask(x,y)&2);
+                                               x-=p1;
+                                               y=texty;
+                                       }
+
+                                       x=textx;
+                                       y=texty;
+
+                                       if (occupied==0)
+                                               ok2print=1;
+                               }
+
+                               else
+                               {
+                                       /* Position Text To The
+                                          Left Of The Marker */
+
+                                       textx=lat+p6;
+                                       texty=lon+p8+(label_length);
+
+                                       x=textx;
+                                       y=texty;
+       
+                                       /* Is This Position Clear Of
+                                          Text Or Other Markers? */
+
+                                       for (a=0, occupied=0; a<16; a++)
+                                       {
+                                               for (b=0; b<(int)strlen(location.name); b++)
+                                                       for (c=0; c<8; c++, y-=p1)
+                                                               occupied|=(GetMask(x,y)&2);
+                                               x-=p1;
+                                               y=texty;
+                                       }
+
+                                       x=textx;
+                                       y=texty;
+
+                                       if (occupied==0)
+                                               ok2print=1;
+                               }
+                       }
+
+                       /* textx and texty contain the latitude and longitude
+                          coordinates that describe the placement of the text
+                          on the map. */
+       
+                       if (ok2print && textx!=0.0 && texty!=0.0)
+                       {
+                               /* Draw Text */
+
+                               x=textx;
+                               y=texty;
+
+                               for (a=0; a<16 && ok2print; a++)
+                               {
+                                       for (b=0; b<(int)strlen(location.name); b++)
+                                       {
+                                               byte=fontdata[16*(location.name[b])+a];
+
+                                               for (c=128; c>0; c=c>>1, y-=p1)
+                                                       if (byte&c)
+                                                               OrMask(x,y,2);
+                                       }
+                                       x-=p1;
+                                       y=texty;
+                               }
+       
+                               /* Draw Square Marker Centered
+                                  On Location Specified */
+       
+                               for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
+                                       for (y=lon-p3; (y<=ymax && y>=ymin && y<=lon+p3); y+=p1)
+                                               OrMask(x,y,2);
+                       }
+               }
+       }
+}
+
+double ReadBearing(char *input)
+{
+       /* This function takes numeric input in the form of a character
+          string, and returns an equivalent bearing in degrees as a
+          decimal number (double).  The input may either be expressed
+          in decimal format (40.139722) or degree, minute, second
+          format (40 08 23).  This function also safely handles
+          extra spaces found either leading, trailing, or
+          embedded within the numbers expressed in the
+          input string.  Decimal seconds are permitted. */
+       double bearing=0.0;
+       char string[20];
+       int a, b, length, degrees, minutes;
+       double seconds;
+
+       /* Copy "input" to "string", and ignore any extra
+          spaces that might be present in the process. */
+
+       string[0]=0;
+       length=strlen(input);
+
+       for (a=0, b=0; a<length && a<18; a++)
+       {
+               if ((input[a]!=32 && input[a]!='\n') || (input[a]==32 && input[a+1]!=32 && b!=0))
+               {
+                       string[b]=input[a];
+                       b++;
+               }        
+       }
+
+       string[b]=0;
+
+       /* Count number of spaces in the clean string. */
+
+       length=strlen(string);
+
+       for (a=0, b=0; a<length; a++)
+               if (string[a]==32)
+                       b++;
+
+       if (b==0)  /* Decimal Format (40.139722) */
+               sscanf(string,"%lf",&bearing);
+
+       if (b==2)  /* Degree, Minute, Second Format (40 08 23) */
+       {
+               sscanf(string,"%d %d %lf",&degrees, &minutes, &seconds);
+               bearing=(double)degrees+((double)minutes/60)+(seconds/3600);
+       }
+
+       /* Anything else returns a 0.0 */
+
+       if (bearing>360.0 || bearing<0.0)
+               bearing=0.0;
+
+       return bearing;
+}
+
+struct site LoadQTH(char *filename)
+{
+       /* This function reads SPLAT! .qth (site location) files.
+          The latitude and longitude may be expressed either in
+          decimal degrees, or in degree, minute, second format.
+          Antenna height is assumed to be expressed in feet above
+          ground level (AGL), unless followed by the letter 'M',
+          or 'm', or by the word "meters" or "Meters", in which
+          case meters is assumed, and is handled accordingly. */
+
+       int x;
+       char string[50], qthfile[255];
+       struct site tempsite;
+       FILE *fd=NULL;
+
+       for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
+               qthfile[x]=filename[x];
+
+       qthfile[x]='.';
+       qthfile[x+1]='q';
+       qthfile[x+2]='t';
+       qthfile[x+3]='h';
+       qthfile[x+4]=0;
+
+       tempsite.lat=0.0;
+       tempsite.lon=0.0;
+       tempsite.alt=0.0;
+       tempsite.name[0]=0;
+
+       fd=fopen(qthfile,"r");
+
+       if (fd!=NULL)
+       {
+               /* Site Name */
+               fgets(string,49,fd);
+
+               /* Strip <CR> and/or <LF> from end of site name */
+
+               for (x=0; string[x]!=13 && string[x]!=10 && string[x]!=0; tempsite.name[x]=string[x], x++);
+
+               tempsite.name[x]=0;
+
+               /* Site Latitude */
+               fgets(string,49,fd);
+               tempsite.lat=ReadBearing(string);
+
+               /* Site Longitude */
+               fgets(string,49,fd);
+               tempsite.lon=ReadBearing(string);
+
+               /* Antenna Height */
+               fgets(string,49,fd);
+               fclose(fd);
+
+               /* Remove <CR> and/or <LF> from antenna height string */
+               for (x=0; string[x]!=13 && string[x]!=10 && string[x]!=0; x++);
+
+               string[x]=0;
+
+               /* Antenna height may either be in feet or meters.
+                  If the letter 'M' or 'm' is discovered in
+                  the string, then this is an indication that
+                  the value given is expressed in meters, and
+                  must be converted to feet before exiting. */
+
+               for (x=0; string[x]!='M' && string[x]!='m' && string[x]!=0 && x<48; x++);
+               if (string[x]=='M' || string[x]=='m')
+               {
+                       string[x]=0;
+                       sscanf(string,"%lf",&tempsite.alt);
+                       tempsite.alt*=3.28084;
+               }
+
+               else
+               {
+                       string[x]=0;
+                       sscanf(string,"%lf",&tempsite.alt);
+               }
+       }
+
+       return tempsite;
+}
+
+int LoadSDF_SDF(char *name)
+{
+       /* This function reads uncompressed SPLAT Data Files (.sdf)
+          containing digital elevation model data into memory.
+          Elevation data, maximum and minimum elevations, and
+          quadrangle limits are stored in the first available
+          dem[] structure. */
+
+       int x, y, data, indx, minlat, minlon, maxlat, maxlon;
+       char found, free_slot=0, line[20], sdf_file[255], path_plus_name[255];
+       FILE *fd;
+
+       for (x=0; name[x]!='.' && name[x]!=0 && x<250; x++)
+               sdf_file[x]=name[x];
+
+       sdf_file[x]=0;
+
+       /* Parse filename for minimum latitude and longitude values */
+
+       sscanf(sdf_file,"%d:%d:%d:%d",&minlat,&maxlat,&minlon,&maxlon);
+
+       sdf_file[x]='.';
+       sdf_file[x+1]='s';
+       sdf_file[x+2]='d';
+       sdf_file[x+3]='f';
+       sdf_file[x+4]=0;
+
+       /* Is it already in memory? */
+
+       for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
+       {
+               if (minlat!=0 && minlon!=0)
+               {
+                       if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
+                               found=1;
+               }
+       }
+
+       /* Is room available to load it? */
+
+       if (found==0)
+       {       
+               for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
+                       if (dem[indx].max_north==0 && dem[indx].max_west==0)
+                               free_slot=1;
+       }
+
+       indx--;
+
+       if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS && minlat!=0 && minlon!=0)
+       {
+               strncpy(path_plus_name,sdf_path,255);
+               strncat(path_plus_name,sdf_file,255);
+
+               fd=fopen(path_plus_name,"rb");
+
+               if (fd!=NULL)
+               {
+                       fprintf(stdout,"Loading \"%s\" into slot %d...",path_plus_name,indx+1);
+                       fflush(stdout);
+
+                       fgets(line,19,fd);
+                       sscanf(line,"%d",&dem[indx].max_west);
+
+                       fgets(line,19,fd);
+                       sscanf(line,"%d",&dem[indx].min_north);
+
+                       fgets(line,19,fd);
+                       sscanf(line,"%d",&dem[indx].min_west);
+
+                       fgets(line,19,fd);
+                       sscanf(line,"%d",&dem[indx].max_north);
+
+                       for (x=0; x<1200; x++)
+                               for (y=0; y<1200; y++)
+                               {
+                                       fgets(line,19,fd);
+                                       sscanf(line,"%d",&data);
+                                       dem[indx].data[x][y]=data;
+
+                                       if (data>dem[indx].max_el)
+                                               dem[indx].max_el=data;
+
+                                       if (dem[indx].min_el==0)
+                                               dem[indx].min_el=data;
+                                       else
+                                       {
+                                                if (data<dem[indx].min_el)
+                                                       dem[indx].min_el=data;
+                                       }
+                               }
+
+                       fclose(fd);
+
+                       if (min_elevation==0)
+                               min_elevation=dem[indx].min_el;
+
+                       else
+                       {
+                               if (dem[indx].min_el<min_elevation)
+                                       min_elevation=dem[indx].min_el;
+                       }
+
+                       if (dem[indx].max_el>max_elevation)
+                               max_elevation=dem[indx].max_el;
+
+                       if (dem[indx].max_north>max_north)
+                               max_north=dem[indx].max_north;
+
+                       if (dem[indx].max_west>max_west)
+                               max_west=dem[indx].max_west;
+
+                       if (min_north==0)
+                               min_north=dem[indx].min_north;
+                       else
+                       {
+                               if (dem[indx].min_north<min_north)
+                                       min_north=dem[indx].min_north;
+                       }
+
+                       if (min_west==0)
+                               min_west=dem[indx].min_west;
+                       else
+                       {
+                               if (dem[indx].min_west<min_west)
+                                       min_west=dem[indx].min_west;
+                       }
+
+                       fprintf(stdout," Done!\n");
+                       fflush(stdout);
+                       return 1;
+               }
+
+               else
+                       return -1;
+       }
+
+       else
+               return 0;
+}
+
+char *BZfgets(BZFILE *bzfd, unsigned length)
+{
+       /* This function returns at most one less than 'length' number
+          of characters from a bz2 compressed file whose file descriptor
+          is pointed to by *bzfd.  In operation, a buffer is filled with
+          uncompressed data (size = BZBUFFER), which is then parsed
+          and doled out as NULL terminated character strings every time
+          this function is invoked.  A NULL string indicates an EOF
+          or error condition. */
+
+       static int x, y, nBuf;
+       static char buffer[BZBUFFER+1], output[BZBUFFER+1];
+       char done=0;
+
+       if (opened!=1 && bzerror==BZ_OK)
+       {
+               /* First time through.  Initialize everything! */
+
+               x=0;
+               y=0;
+               nBuf=0;
+               opened=1;
+               output[0]=0;
+       }
+
+       do
+       {
+               if (x==nBuf && bzerror!=BZ_STREAM_END && bzerror==BZ_OK && opened)
+               {
+                       /* Uncompress data into a static buffer */
+
+                       nBuf=BZ2_bzRead(&bzerror, bzfd, buffer, BZBUFFER);
+                       buffer[nBuf]=0;
+                       x=0;
+               }
+
+               /* Build a string from buffer contents */
+
+               output[y]=buffer[x];
+
+               if (output[y]=='\n' || output[y]==0 || y==(int)length-1)
+               {
+                       output[y+1]=0;
+                       done=1;
+                       y=0;
+               }
+
+               else
+                       y++;
+               x++;
+
+       } while (done==0);
+
+       if (output[0]==0)
+               opened=0;
+
+       return (output);
+}
+
+int LoadSDF_BZ(char *name)
+{
+       /* This function reads .bz2 compressed SPLAT Data Files containing
+          digital elevation model data into memory.  Elevation data,
+          maximum and minimum elevations, and quadrangle limits are
+          stored in the first available dem[] structure. */
+
+       int x, y, data, indx, minlat, minlon, maxlat, maxlon;
+       char found, free_slot=0, sdf_file[255], path_plus_name[255];
+       FILE *fd;
+       BZFILE *bzfd;
+
+       for (x=0; name[x]!='.' && name[x]!=0 && x<247; x++)
+               sdf_file[x]=name[x];
+
+       sdf_file[x]=0;
+
+       /* Parse sdf_file name for minimum latitude and longitude values */
+
+       sscanf(sdf_file,"%d:%d:%d:%d",&minlat,&maxlat,&minlon,&maxlon);
+
+       sdf_file[x]='.';
+       sdf_file[x+1]='s';
+       sdf_file[x+2]='d';
+       sdf_file[x+3]='f';
+       sdf_file[x+4]='.';
+       sdf_file[x+5]='b';
+       sdf_file[x+6]='z';
+       sdf_file[x+7]='2';
+       sdf_file[x+8]=0;
+
+       /* Is it already in memory? */
+
+       for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
+       {
+               if (minlat!=0 && minlon!=0)
+               {
+                       if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
+                               found=1;
+               }
+       }
+
+       /* Is room available to load it? */
+
+       if (found==0)
+       {       
+               for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
+                       if (dem[indx].max_north==0 && dem[indx].max_west==0)
+                               free_slot=1;
+       }
+
+       indx--;
+
+       if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS && minlat!=0 && minlon!=0)
+       {
+               strncpy(path_plus_name,sdf_path,255);
+               strncat(path_plus_name,sdf_file,255);
+
+               fd=fopen(path_plus_name,"rb");
+               bzfd=BZ2_bzReadOpen(&bzerror,fd,0,0,NULL,0);
+
+               if (fd!=NULL && bzerror==BZ_OK)
+               {
+                       fprintf(stdout,"Loading \"%s\" into slot %d...",path_plus_name,indx+1);
+                       fflush(stdout);
+
+                       sscanf(BZfgets(bzfd,255),"%d",&dem[indx].max_west);
+                       sscanf(BZfgets(bzfd,255),"%d",&dem[indx].min_north);
+                       sscanf(BZfgets(bzfd,255),"%d",&dem[indx].min_west);
+                       sscanf(BZfgets(bzfd,255),"%d",&dem[indx].max_north);
+       
+                       for (x=0; x<1200; x++)
+                               for (y=0; y<1200; y++)
+                               {
+                                       sscanf(BZfgets(bzfd,20),"%d",&data);
+                                       dem[indx].data[x][y]=data;
+
+                                       if (data>dem[indx].max_el)
+                                               dem[indx].max_el=data;
+
+                                       if (dem[indx].min_el==0)
+                                               dem[indx].min_el=data;
+                                       else
+                                       {
+                                                if (data<dem[indx].min_el)
+                                                       dem[indx].min_el=data;
+                                       }
+                               }
+
+                       fclose(fd);
+
+                       BZ2_bzReadClose(&bzerror,bzfd);
+
+                       if (min_elevation==0)
+                               min_elevation=dem[indx].min_el;
+
+                       else
+                       {
+                               if (dem[indx].min_el<min_elevation)
+                                       min_elevation=dem[indx].min_el;
+                       }
+       
+                       if (dem[indx].max_el>max_elevation)
+                               max_elevation=dem[indx].max_el;
+
+                       if (dem[indx].max_north>max_north)
+                               max_north=dem[indx].max_north;
+
+                       if (dem[indx].max_west>max_west)
+                               max_west=dem[indx].max_west;
+
+                       if (min_north==0)
+                               min_north=dem[indx].min_north;
+                       else
+                       {
+                               if (dem[indx].min_north<min_north)
+                                       min_north=dem[indx].min_north;
+                       }
+
+                       if (min_west==0)
+                               min_west=dem[indx].min_west;
+                       else
+                       {
+                               if (dem[indx].min_west<min_west)
+                                       min_west=dem[indx].min_west;
+                       }
+
+                       fprintf(stdout," Done!\n");
+                       fflush(stdout);
+                       return 1;
+               }
+               else
+                       return -1;
+       }
+       else
+               return 0;
+}
+
+char LoadSDF(char *name)
+{
+       /* This function loads the requested SDF file from the filesystem.
+          It first tries to invoke the LoadSDF_SDF() function to load an
+          uncompressed SDF file (since uncompressed files load slightly
+          faster).  If that attempt fails, then it tries to load a
+          compressed SDF file by invoking the LoadSDF_BZ() function.
+          If that fails, then we can assume that no elevation data
+          exists for the region requested, and that the region
+          requested must be entirely over water. */
+
+       int x, y, indx, minlat, minlon, maxlat, maxlon;
+       char found, free_slot=0;
+       int  return_value=-1;
+
+       /* Try to load an uncompressed SDF first. */
+
+       return_value=LoadSDF_SDF(name);
+
+       /* If that fails, try loading a compressed SDF. */
+
+       if (return_value==0 || return_value==-1)
+               return_value=LoadSDF_BZ(name);
+
+       /* If neither format can be found, then assume the area is water. */
+
+       if (return_value==0 || return_value==-1)
+       {
+               /* Parse SDF name for minimum latitude and longitude values */
+
+               sscanf(name,"%d:%d:%d:%d",&minlat,&maxlat,&minlon,&maxlon);
+
+               /* Is it already in memory? */
+
+               for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
+               {
+                       if (minlat!=0 && minlon!=0)
+                       {
+                               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
+                                       found=1;
+                       }
+               }
+
+               /* Is room available to load it? */
+
+               if (found==0)
+               {       
+                       for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
+                               if (dem[indx].max_north==0 && dem[indx].max_west==0)
+                                       free_slot=1;
+               }
+
+               indx--;
+
+               if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS && minlat!=0 && minlon!=0)
+               {
+                       fprintf(stdout,"Region  \"%s\" assumed as sea-level into slot %d...",name,indx+1);
+                       fflush(stdout);
+
+                       dem[indx].max_west=maxlon;
+                       dem[indx].min_north=minlat;
+                       dem[indx].min_west=minlon;
+                       dem[indx].max_north=maxlat;
+
+                       for (x=0; x<1200; x++)
+                               for (y=0; y<1200; y++)
+                               {
+                                       dem[indx].data[x][y]=0;
+
+                                       if (dem[indx].min_el>0)
+                                               dem[indx].min_el=0;
+                               }
+
+                       if (dem[indx].min_el<min_elevation)
+                               min_elevation=dem[indx].min_el;
+
+                       if (dem[indx].max_el>max_elevation)
+                               max_elevation=dem[indx].max_el;
+
+                       if (dem[indx].max_north>max_north)
+                               max_north=dem[indx].max_north;
+
+                       if (dem[indx].max_west>max_west)
+                               max_west=dem[indx].max_west;
+
+                       if (min_north==0)
+                               min_north=dem[indx].min_north;
+                       else
+                       {
+                               if (dem[indx].min_north<min_north)
+                                       min_north=dem[indx].min_north;
+                       }
+
+                       if (min_west==0)
+                               min_west=dem[indx].min_west;
+                       else
+                       {
+                               if (dem[indx].min_west<min_west)
+                                       min_west=dem[indx].min_west;
+                       }
+
+                       fprintf(stdout," Done!\n");
+                       fflush(stdout);
+
+                       return_value=1;
+               }
+       }
+
+       return return_value;
+}
+
+void LoadCities(char *filename)
+{
+       /* This function reads SPLAT! city/site files, and plots
+          the locations and names of the cities and site locations
+          read on topographic maps generated by SPLAT! */
+
+       int x, y, z;
+       char input[80], str[3][80];
+       struct site city_site;
+       FILE *fd=NULL;
+
+       fd=fopen(filename,"r");
+
+       if (fd!=NULL)
+       {
+               fgets(input,78,fd);
+
+               fprintf(stdout,"Reading \"%s\"... ",filename);
+               fflush(stdout);
+
+               while (fd!=NULL && feof(fd)==0)
+               {
+                       /* Parse line for name, latitude, and longitude */
+
+                       for (x=0, y=0, z=0; x<78 && input[x]!=0 && z<3; x++)
+                       {
+                               if (input[x]!=',' && y<78)
+                               {
+                                       str[z][y]=input[x];
+                                       y++;
+                               }
+
+                               else
+                               {
+                                       str[z][y]=0;
+                                       z++;
+                                       y=0;
+                               }
+                       }
+
+                       strncpy(city_site.name,str[0],49);
+                       city_site.lat=ReadBearing(str[1]);
+                       city_site.lon=ReadBearing(str[2]);
+                       city_site.alt=0.0;
+
+                       PlaceMarker(city_site);
+
+                       fgets(input,78,fd);
+               }
+
+               fclose(fd);
+               fprintf(stdout,"Done!\n");
+               fflush(stdout);
+       }
+       else
+               fprintf(stderr,"*** ERROR: \"%s\": not found!\n",filename);
+}
+
+void LoadBoundaries(char *filename)
+{
+       /* This function reads Cartographic Boundary Files available from
+          the U.S. Census Bureau, and plots the data contained in those
+          files on the PPM Map generated by SPLAT!.  Such files contain
+          the coordinates that describe the boundaries of cities,
+          counties, and states. */
+
+       int x;
+       double lat0, lon0, lat1, lon1;
+       char string[80];
+       struct site source, destination;
+       FILE *fd=NULL;
+
+       fd=fopen(filename,"r");
+
+       if (fd!=NULL)
+       {
+               fgets(string,78,fd);
+
+               fprintf(stdout,"Reading \"%s\"... ",filename);
+               fflush(stdout);
+
+               do
+               {
+                       fgets(string,78,fd);
+                       sscanf(string,"%lf %lf", &lon0, &lat0);
+                       fgets(string,78,fd);
+
+                       do
+                       {
+                               sscanf(string,"%lf %lf", &lon1, &lat1);
+                       
+                               lon0=fabs(lon0);
+                               lon1=fabs(lon1);
+
+                               source.lat=lat0;
+                               source.lon=lon0;
+                               destination.lat=lat1;
+                               destination.lon=lon1;
+
+                               ReadPath(source,destination);
+
+                               for (x=0; x<path.length; x++)
+                                       OrMask(path.lat[x],path.lon[x],4);
+
+                               lat0=lat1;
+                               lon0=lon1;
+
+                               fgets(string,78,fd);
+
+                       } while (strncmp(string,"END",3)!=0 && feof(fd)==0);
+
+                       fgets(string,78,fd);
+
+               } while (strncmp(string,"END",3)!=0 && feof(fd)==0);
+
+               fclose(fd);
+
+               fprintf(stdout,"Done!\n");
+               fflush(stdout);
+       }
+       else
+               fprintf(stderr,"*** ERROR: \"%s\": not found!\n",filename);
+}
+
+void ReadLRParm(char *txsite_filename)
+{
+       /* This function reads Longley-Rice parameter data for the
+          transmitter site.  The file name is the same as the txsite,
+          except the filename extension is .lrp.  If the needed file
+          is not found, then the file "splat.lrp" is read from the
+          current working directory.  Failure to load this file will
+          result in the default parameters hard coded into this
+          being used and written to "splat.lrp". */
+
+       double din;
+       char filename[255], lookup[256], string[80];
+       int iin, ok=0, x;
+       FILE *fd=NULL, *outfile=NULL;
+
+       /* Default parameters in case things go bad */
+
+       LR.eps_dielect=15.0;
+       LR.sgm_conductivity=0.005;
+       LR.eno_ns_surfref=301.0;
+       LR.frq_mhz=300.0;
+       LR.radio_climate=5;
+       LR.pol=0;
+       LR.conf=0.50;
+       LR.rel=0.50;
+
+       /* Modify txsite filename to one with a .lrp extension. */
+
+       strncpy(filename,txsite_filename,255);
+
+       for (x=0; filename[x]!='.' && filename[x]!=0 && filename[x]!='\n' && x<249; x++);
+
+       filename[x]='.';
+       filename[x+1]='l';
+       filename[x+2]='r';
+       filename[x+3]='p';
+       filename[x+4]=0;
+
+       /* Small lookup table to parse file, pass
+          numeric data, and ignore comments. */
+
+       for (x=0; x<=255; x++)
+               lookup[x]=0;
+
+       /* Valid characters */
+
+       for (x=48; x<=57; x++)
+               lookup[x]=x;
+
+       lookup[32]=32;
+       lookup[46]='.';
+
+       fd=fopen(filename,"r");
+
+       if (fd==NULL)
+       {
+               /* Load default "splat.lrp" file */
+
+               strncpy(filename,"splat.lrp\0",10);
+               fd=fopen(filename,"r");
+       }
+
+       if (fd!=NULL)
+       {
+               fgets(string,80,fd);
+
+               for (x=0; lookup[(int)string[x]] && x<20; x++)
+                       string[x]=lookup[(int)string[x]];
+
+               string[x]=0;
+
+               ok=sscanf(string,"%lf", &din);
+
+               if (ok)
+               {
+                       LR.eps_dielect=din;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%lf", &din);
+               }
+
+               if (ok)
+               {
+                       LR.sgm_conductivity=din;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%lf", &din);
+               }
+
+               if (ok)
+               {
+                       LR.eno_ns_surfref=din;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%lf", &din);
+               }
+
+               if (ok)
+               {
+                       LR.frq_mhz=din;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%d", &iin);
+               }
+
+               if (ok)
+               {
+                       LR.radio_climate=iin;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%d", &iin);
+               }
+
+               if (ok)
+               {
+                       LR.pol=iin;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%lf", &din);
+               }
+
+               if (ok)
+               {
+                       LR.conf=din;
+
+                       fgets(string,80,fd);
+
+                       for (x=0; lookup[(int)string[x]] && x<20; x++)
+                               string[x]=lookup[(int)string[x]];
+
+                       string[x]=0;
+
+                       ok=sscanf(string,"%lf", &din);
+               }
+
+               if (ok)
+                       LR.rel=din;
+
+               fclose(fd);
+       } 
+
+       if (fd==NULL)
+       {
+               /* Create a "splat.lrp" file since one
+                  could not be successfully loaded. */
+
+               outfile=fopen("splat.lrp","w");
+
+               fprintf(outfile,"%.3f\t; Earth Dielectric Constant (Relative permittivity)\n",LR.eps_dielect);
+
+               fprintf(outfile,"%.3f\t; Earth Conductivity (Siemens per meter)\n", LR.sgm_conductivity);
+
+               fprintf(outfile,"%.3f\t; Atmospheric Bending Constant (N-Units)\n",LR.eno_ns_surfref);
+
+               fprintf(outfile,"%.3f\t; Frequency in MHz (20 MHz to 20 GHz)\n", LR.frq_mhz);
+
+               fprintf(outfile,"%d\t; Radio Climate\n",LR.radio_climate);
+
+               fprintf(outfile,"%d\t; Polarization (0 = Horizontal, 1 = Vertical)\n", LR.pol);
+
+               fprintf(outfile,"%.2f\t; Fraction of situations\n",LR.conf);
+
+               fprintf(outfile, "%.2f\t; Fraction of time\n",LR.rel);
+
+               fprintf(outfile,"\nPlease consult SPLAT! documentation for the meaning and use of this data.\n");
+
+               fclose(outfile);
+
+               fprintf(stderr,"\n%c*** There were problems reading your \"%s\" file! ***\nA \"splat.lrp\" file was written to your directory with default data.\n",7,filename);
+       }
+
+       if (fd==NULL || ok==0)
+               fprintf(stderr,"Longley-Rice default parameters have been assumed for this analysis.\n");
+}
+
+struct site los(struct site source, struct site destination)
+{
+       /* This function determines whether a line-of-sight path
+          unobstructed by terrain exists between source (transmitter)
+          and destination (receiver) based on the geographical
+          locations of the two sites, their respective antenna
+          heights above ground, and the terrain between them.
+          A site structure is returned upon completion.  If the
+          first character of site.name is ' ', then a clear path
+          exists between source and destination.  If the first
+          character is '*', then an obstruction exists, and the
+          site.lat and site.lon elements of the structure provide
+          the geographical location of the obstruction. */
+          
+       int x;
+       char block;
+       struct site test, blockage;
+       register double distance, tx_alt, rx_alt,
+                cos_xmtr_angle, cos_test_angle, test_alt;
+
+       ReadPath(source,destination);
+
+       distance=5280.0*Distance(source,destination);
+       tx_alt=earthradius+source.alt+GetElevation(source);
+       rx_alt=earthradius+destination.alt+GetElevation(destination);
+
+       /* Elevation angle of the xmtr (source) as seen by the rcvr */
+
+       cos_xmtr_angle=((rx_alt*rx_alt)+(distance*distance)-(tx_alt*tx_alt))/(2.0*rx_alt*distance);
+
+       /* Determine the elevation angle of each discrete location
+          along the path between the receiver and transmitter.
+
+          Since obstructions are more likely due to terrain effects
+          closest to the receiver rather than farther away, we start
+          looking for potential obstructions from the receiver's
+          location, and work our way towards the transmitter.
+          This loop is broken when the first obstruction is
+          detected.  If we can travel all the way to the transmitter
+          without detecting an obstruction, then we have a clear
+          unobstructed path between transmitter and receiver. */
+
+       for (x=path.length-1, block=0; x>0 && block==0; x--)
+       {
+               /* Build a structure for each test
+                  point along the path to be surveyed. */
+
+               test.lat=path.lat[x];
+               test.lon=path.lon[x];
+
+               /* Measure the distance between the
+                  test point and the receiver locations */
+
+               distance=5280.0*Distance(test,destination);
+               test_alt=earthradius+path.elevation[x];
+
+               /* Determine the cosine of the elevation of the test
+                  point as seen from the location of the receiver */
+
+               cos_test_angle=((rx_alt*rx_alt)+(distance*distance)-(test_alt*test_alt))/(2.0*rx_alt*distance);
+
+               /* If the elevation angle to the test point (as seen from
+                  the receiver) is greater than the elevation angle to the
+                  transmitter (as seen by the receiver), then we have a
+                  path obstructed by terrain.  Note: Since we're comparing
+                  the cosines of these angles rather than the angles
+                  themselves (eliminating the call to acos() saves
+                  considerable time), the following "if" statement is
+                  reversed from what it would normally be if the angles
+                  were compared. */
+
+               if (cos_xmtr_angle>cos_test_angle)
+               {
+                       block=1;
+                       blockage.lat=path.lat[x];
+                       blockage.lon=path.lon[x];
+                       blockage.alt=path.elevation[x];
+                       blockage.name[0]='*';
+               }
+       }
+
+       if (block==0)
+       {
+               blockage.lat=0.0;
+               blockage.lon=0.0;
+               blockage.alt=0.0;
+               blockage.name[0]=' ';
+       }
+
+       return blockage;
+}
+
+void PlotPath(struct site source, struct site destination, char mask_value)
+{
+       /* This function analyzes the path between the source and
+          destination locations.  It determines which points along
+          the path have line-of-sight visibility to the source.
+          Points along with path having line-of-sight visibility
+          to the source at an AGL altitude equal to that of the
+          destination location are stored by setting bit 1 in the
+          mask[][] array, which are displayed in green when PPM
+          maps are later generated by SPLAT!. */
+
+       char block;
+       int x, y;
+       register double cos_xmtr_angle, cos_test_angle, test_alt;
+       double distance, rx_alt, tx_alt;
+
+       ReadPath(source,destination);
+
+       for (y=0; y<path.length; y++)
+       {
+               /* Test this point only if it hasn't been already
+                  tested and found to be free of obstructions. */
+
+               if ((GetMask(path.lat[y],path.lon[y])&mask_value)==0)
+               {
+                       distance=5280.0*path.distance[y];
+                       tx_alt=earthradius+source.alt+path.elevation[0];
+                       rx_alt=earthradius+destination.alt+path.elevation[y];
+
+                       /* Calculate the cosine of the elevation of the
+                          transmitter as seen at the temp rx point. */
+
+                       cos_xmtr_angle=((rx_alt*rx_alt)+(distance*distance)-(tx_alt*tx_alt))/(2.0*rx_alt*distance);
+
+                       for (x=y, block=0; x>=0 && block==0; x--)
+                       {
+                               distance=5280.0*(path.distance[y]-path.distance[x]);
+                               test_alt=earthradius+path.elevation[x];
+
+                               cos_test_angle=((rx_alt*rx_alt)+(distance*distance)-(test_alt*test_alt))/(2.0*rx_alt*distance);
+
+                               /* Compare these two angles to determine if
+                                  a blockage exists.  Since we're comparing
+                                  the cosines of these angles rather than
+                                  the angles themselves, the following "if"
+                                  statement is reversed from what it would
+                                  be if the actual angles were compared. */
+
+                               if (cos_xmtr_angle>cos_test_angle)
+                                       block=1;
+                       }
+
+                       if (block==0)
+                               OrMask(path.lat[y],path.lon[y],mask_value);
+               }
+       }
+}
+
+void PlotLRPath(struct site source, struct site destination)
+{
+       /* This function plots the RF signal path loss
+          between source and destination points based
+          on the Longley-Rice propagation model. */
+
+       char strmode[100];
+       int x, y, errnum;
+       double loss;
+
+       ReadPath(source,destination);
+       elev_l[1]=0.04*METERS_PER_MILE;
+
+       for (x=0; x<path.length; x++)
+               elev_l[x+2]=path.elevation[x]*METERS_PER_FOOT;  
+        
+       for (y=0; y<path.length; y++)
+       {
+               /* Test this point only if it
+                  has not already been tested. */
+
+               if (GetMask(path.lat[y],path.lon[y])==0 && 0.04*y<=max_range)
+               {
+                       elev_l[0]=y+1;
+
+                       point_to_point(elev_l,source.alt*METERS_PER_FOOT, 
+                       destination.alt*METERS_PER_FOOT,
+                       LR.eps_dielect, LR.sgm_conductivity, LR.eno_ns_surfref,
+                       LR.frq_mhz, LR.radio_climate, LR.pol, LR.conf, LR.rel,
+                       loss, strmode, errnum);
+
+                       /* Note: PASS BY REFERENCE ... loss and errnum are pass
+                       by reference, only used in this file by this function */
+
+                       if (loss>225.0)
+                               loss=225.0;
+
+                       if (loss<75.0)
+                               loss=75.0;
+
+                       loss-=75.0;
+                       loss/=10.0;
+                       loss+=1.0;
+               
+                       OrMask(path.lat[y],path.lon[y],((unsigned char)(loss))<<3);
+               }
+
+               else if (GetMask(path.lat[y],path.lon[y])==0 && 0.04*y>max_range)
+                       OrMask(path.lat[y],path.lon[y],1);
+       }
+}
+
+void PlotCoverage(struct site source, double altitude)
+{
+       /* This function performs a 360 degree sweep around the
+          transmitter site (source location), and plots the
+          line-of-sight coverage of the transmitter on the SPLAT!
+          generated topographic map based on a receiver located
+          at the specified altitude (in feet AGL).  Results
+          are stored in memory, and written out in the form
+          of a topographic map when the WritePPM() function
+          is later invoked. */
+
+       double lat, lon, one_pixel;
+       static unsigned char mask_value;
+       int z, count;
+       struct site edge;
+       unsigned char symbol[4], x;
+
+       /* Initialize mask_value */
+
+       if (mask_value!=8 && mask_value!=16 && mask_value!=32)
+               mask_value=1;
+
+       one_pixel=1.0/1200.0;
+
+       symbol[0]='.';
+       symbol[1]='o';
+       symbol[2]='O';
+       symbol[3]='o';
+
+       count=0;        
+
+       fprintf(stdout,"\nComputing line-of-sight coverage of %s with an RX antenna\nat %.2f feet AGL:\n\n 0%c to  25%c ",source.name,altitude,37,37);
+       fflush(stdout);
+
+       /* 18.75=1200 pixels/degree divided by 64 loops
+          per progress indicator symbol (.oOo) printed. */
+
+       z=(int)(18.75*(max_west-min_west));
+
+       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       {
+               edge.lat=max_north;
+               edge.lon=lon;
+               edge.alt=altitude;
+
+               PlotPath(source,edge,mask_value);
+               count++;
+
+               if (count==z) 
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       count=0;
+       fprintf(stdout,"\n25%c to  50%c ",37,37);
+       fflush(stdout);
+       
+       z=(int)(18.75*(max_north-min_north));
+
+       for (lat=max_north, x=0; lat>=min_north; lat-=one_pixel)
+       {
+               edge.lat=lat;
+               edge.lon=min_west;
+               edge.alt=altitude;
+
+               PlotPath(source,edge,mask_value);
+               count++;
+
+               if (count==z) 
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       count=0;
+       fprintf(stdout,"\n50%c to  75%c ",37,37);
+       fflush(stdout);
+
+       z=(int)(18.75*(max_west-min_west));
+
+       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       {
+               edge.lat=min_north;
+               edge.lon=lon;
+               edge.alt=altitude;
+
+               PlotPath(source,edge,mask_value);
+               count++;
+
+               if (count==z)
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       count=0;
+       fprintf(stdout,"\n75%c to 100%c ",37,37);
+       fflush(stdout);
+       
+       z=(int)(18.75*(max_north-min_north));
+
+       for (lat=min_north, x=0; lat<=max_north; lat+=one_pixel)
+       {
+               edge.lat=lat;
+               edge.lon=max_west;
+               edge.alt=altitude;
+
+               PlotPath(source,edge,mask_value);
+               count++;
+
+               if (count==z)
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       fprintf(stdout,"\nDone!\n");
+       fflush(stdout);
+
+       /* Assign next mask value */
+
+       switch (mask_value)
+       {
+               case 1:
+                       mask_value=8;
+                       break;
+
+               case 8:
+                       mask_value=16;
+                       break;
+
+               case 16:
+                       mask_value=32;
+       }
+}
+
+void PlotLRMap(struct site source, double altitude)
+{
+       /* This function performs a 360 degree sweep around the
+          transmitter site (source location), and plots the
+          Longley-Rice attenuation on the SPLAT! generated
+          topographic map based on a receiver located at
+          the specified altitude (in feet AGL).  Results
+          are stored in memory, and written out in the form
+          of a topographic map when the WritePPMLR() function
+          is later invoked. */
+
+       int z, count;
+       struct site edge;
+       double lat, lon, one_pixel;
+       unsigned char symbol[4], x;
+
+       one_pixel=1.0/1200.0;
+
+       symbol[0]='.';
+       symbol[1]='o';
+       symbol[2]='O';
+       symbol[3]='o';
+
+       count=0;
+
+       fprintf(stdout,"\nComputing Longley-Rice coverage of %s ", source.name);
+       fprintf(stdout,"out to a radius\nof %.2f miles with an RX antenna at %.2f feet AGL:\n\n 0%c to  25%c ",max_range,altitude,37,37);
+       fflush(stdout);
+
+       /* 18.75=1200 pixels/degree divided by 64 loops
+          per progress indicator symbol (.oOo) printed. */
+
+       z=(int)(18.75*(max_west-min_west));
+
+       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       {
+               edge.lat=max_north;
+               edge.lon=lon;
+               edge.alt=altitude;
+
+               PlotLRPath(source,edge);
+               count++;
+
+               if (count==z) 
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       count=0;
+       fprintf(stdout,"\n25%c to  50%c ",37,37);
+       fflush(stdout);
+       
+       z=(int)(18.75*(max_north-min_north));
+
+       for (lat=max_north, x=0; lat>=min_north; lat-=one_pixel)
+       {
+               edge.lat=lat;
+               edge.lon=min_west;
+               edge.alt=altitude;
+
+               PlotLRPath(source,edge);
+               count++;
+
+               if (count==z) 
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       count=0;
+       fprintf(stdout,"\n50%c to  75%c ",37,37);
+       fflush(stdout);
+
+       z=(int)(18.75*(max_west-min_west));
+
+       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       {
+               edge.lat=min_north;
+               edge.lon=lon;
+               edge.alt=altitude;
+
+               PlotLRPath(source,edge);
+               count++;
+
+               if (count==z)
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       count=0;
+       fprintf(stdout,"\n75%c to 100%c ",37,37);
+       fflush(stdout);
+       
+       z=(int)(18.75*(max_north-min_north));
+
+       for (lat=min_north, x=0; lat<=max_north; lat+=one_pixel)
+       {
+               edge.lat=lat;
+               edge.lon=max_west;
+               edge.alt=altitude;
+
+               PlotLRPath(source,edge);
+               count++;
+
+               if (count==z)
+               {
+                       fprintf(stdout,"%c",symbol[x]);
+                       fflush(stdout);
+                       count=0;
+
+                       if (x==3)
+                               x=0;
+                       else
+                               x++;
+               }
+       }
+
+       fprintf(stdout,"\nDone!\n");
+       fflush(stdout);
+}
+
+void WritePPM(char *filename)
+{
+       /* This function generates a topographic map in Portable Pix Map
+          (PPM) format based on logarithmically scaled topology data,
+          as well as the content of flags held in the mask[][] array.
+          The image created is rotated counter-clockwise 90 degrees
+          from its representation in dem[][] so that north points
+          up and east points right in the image generated. */
+
+       int indx, x, x0, y0, minlat, minlon;
+       unsigned width, height, output;
+       unsigned char found, mask;
+       char mapfile[255];
+       double conversion, lat, lon, one_over_gamma, one_pixel;
+       FILE *fd;
+
+       one_pixel=1.0/1200.0;
+       one_over_gamma=1.0/GAMMA;
+       conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
+
+       width=1200*(max_west-min_west);
+       height=1200*(max_north-min_north);
+
+       if (filename[0]==0)
+               strncpy(mapfile, "map.ppm\0",8);
+       else
+       {
+               for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
+                       mapfile[x]=filename[x];
+
+               mapfile[x]='.';
+               mapfile[x+1]='p';
+               mapfile[x+2]='p';
+               mapfile[x+3]='m';
+               mapfile[x+4]=0;
+       }
+
+       fd=fopen(mapfile,"wb");
+
+       fprintf(fd,"P6\n%u %u\n255\n",width,height);
+
+       fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height);
+       fflush(stdout);
+
+       for (lat=(double)max_north; lat>=(double)min_north; lat-=one_pixel)
+       {
+               for (lon=(double)max_west; lon>=(double)min_west; lon-=one_pixel)
+               {
+                       minlat=(int)floor(lat);
+                       minlon=(int)floor(lon);
+
+                       for (indx=0, found=0; indx<MAXSLOTS && found==0;)
+                               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west)
+                                       found=1;
+                               else
+                                       indx++;
+                       if (found)
+                       {
+                               x0=(int)((1199.0*(lat-floor(lat)))+0.5);
+                               y0=(int)((1199.0*(lon-floor(lon)))+0.5);
+
+                               mask=dem[indx].mask[x0][y0];
+
+                               if (mask&2)
+                                       /* Text Labels: Red */
+                                       fprintf(fd,"%c%c%c",255,0,0);
+
+                               else if (mask&4)
+                                       /* County Boundaries: Light Cyan */
+                                       fprintf(fd,"%c%c%c",128,128,255);
+
+                               else switch (mask&57)
+                               {
+                                       case 1:
+                                       /* TX1: Green */
+                                       fprintf(fd,"%c%c%c",0,255,0);
+                                       break;
+
+                                       case 8:
+                                       /* TX2: Cyan */
+                                       fprintf(fd,"%c%c%c",0,255,255);
+                                       break;
+
+                                       case 9:
+                                       /* TX1 + TX2: Yellow */
+                                       fprintf(fd,"%c%c%c",255,255,0);
+                                       break;
+
+                                       case 16:
+                                       /* TX3: Medium Violet */
+                                       fprintf(fd,"%c%c%c",147,112,219);
+                                       break;
+
+                                       case 17:
+                                       /* TX1 + TX3: Pink */
+                                       fprintf(fd,"%c%c%c",255,192,203);
+                                       break;
+
+                                       case 24:
+                                       /* TX2 + TX3: Orange */
+                                       fprintf(fd,"%c%c%c",255,165,0);
+                                       break;
+
+                                       case 25:
+                                       /* TX1 + TX2 + TX3: Dark Green */
+                                       fprintf(fd,"%c%c%c",0,100,0);
+                                       break;
+
+                                       case 32:
+                                       /* TX4: Sienna 1 */
+                                       fprintf(fd,"%c%c%c",255,130,71);
+                                       break;
+
+                                       case 33:
+                                       /* TX1 + TX4: Green Yellow */
+                                       fprintf(fd,"%c%c%c",173,255,47);
+                                       break;
+
+                                       case 40:
+                                       /* TX2 + TX4: Dark Sea Green 1 */
+                                       fprintf(fd,"%c%c%c",193,255,193);
+                                       break;
+
+                                       case 41:
+                                       /* TX1 + TX2 + TX4: Blanched Almond */
+                                       fprintf(fd,"%c%c%c",255,235,205);
+                                       break;
+
+                                       case 48:
+                                       /* TX3 + TX4: Dark Turquoise */
+                                       fprintf(fd,"%c%c%c",0,206,209);
+                                       break;
+
+                                       case 49:
+                                       /* TX1 + TX3 + TX4: Medium Spring Green */
+                                       fprintf(fd,"%c%c%c",0,250,154);
+                                       break;
+
+                                       case 56:
+                                       /* TX2 + TX3 + TX4: Tan */
+                                       fprintf(fd,"%c%c%c",210,180,140);
+                                       break;
+
+                                       case 57:
+                                       /* TX1 + TX2 + TX3 + TX4: Gold2 */
+                                       fprintf(fd,"%c%c%c",238,201,0);
+                                       break;
+
+                                       default:
+                                       /* Water: Medium Blue */
+                                       if (dem[indx].data[x0][y0]==0)
+                                               fprintf(fd,"%c%c%c",0,0,170);
+                                       else
+                                       {
+                                               /* Elevation: Greyscale */
+                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                               fprintf(fd,"%c%c%c",output,output,output);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       fclose(fd);
+       fprintf(stdout,"Done!\n");
+       fflush(stdout);
+}
+
+void WritePPMLR(char *filename)
+{
+       /* This function generates a topographic map in Portable Pix Map
+          (PPM) format based on the content of flags held in the mask[][] 
+          array (only).  The image created is rotated counter-clockwise
+          90 degrees from its representation in dem[][] so that north
+          points up and east points right in the image generated. */
+
+       int indx, x, t, t2, x0, y0, minlat, minlon;
+       unsigned width, height, output;
+       unsigned char found, mask;
+       char mapfile[255];
+       double conversion, lat, lon, one_over_gamma, one_pixel;
+       FILE *fd;
+
+       one_pixel=1.0/1200.0;
+       one_over_gamma=1.0/GAMMA;
+       conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
+
+       width=1200*(max_west-min_west);
+       height=1200*(max_north-min_north);
+
+       if (filename[0]==0)
+               strncpy(mapfile, "map.ppm\0",8);
+       else
+       {
+               for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
+                       mapfile[x]=filename[x];
+
+               mapfile[x]='.';
+               mapfile[x+1]='p';
+               mapfile[x+2]='p';
+               mapfile[x+3]='m';
+               mapfile[x+4]=0;
+       }
+
+       fd=fopen(mapfile,"wb");
+
+       fprintf(fd,"P6\n%u %u\n255\n",width,height+30);
+
+       fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height+30);
+       fflush(stdout);
+
+       for (lat=(double)max_north; lat>=(double)min_north; lat-=one_pixel)
+       {
+               for (lon=(double)max_west; lon>=(double)min_west; lon-=one_pixel)
+               {
+                       minlat=(int)floor(lat);
+                       minlon=(int)floor(lon);
+
+                       for (indx=0, found=0; indx<MAXSLOTS && found==0;)
+                               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west)
+                                       found=1;
+                               else
+                                       indx++;
+                       if (found)
+                       {
+                               x0=(int)((1199.0*(lat-floor(lat)))+0.5);
+                               y0=(int)((1199.0*(lon-floor(lon)))+0.5);
+
+                               mask=dem[indx].mask[x0][y0];
+
+                               if (mask&2)
+                               {
+                                       /* Text Labels - Black or Red */
+                                       if (mask&120)
+                                               fprintf(fd,"%c%c%c",0,0,0);
+                                       else
+                                               fprintf(fd,"%c%c%c",255,0,0);
+                               }
+
+                               else if (mask&4)
+                                       /* County Boundaries: Black */
+                                       fprintf(fd,"%c%c%c",0,0,0);
+
+                               else if (mask&1 && !((mask&248)==192))
+                               {
+                                       /* Outside Analysis Range */
+                                       /* Display Greyscale / Sea Level */
+
+                                       if (dem[indx].data[x0][y0]==0)
+                                               fprintf(fd,"%c%c%c",0,0,170);
+                                       else
+                                       {
+                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                               fprintf(fd,"%c%c%c",output,output,output);
+                                       }
+                               }
+
+                               else switch ((mask&248)>>3)
+                               {
+                                       case 0:
+                                       /* Inside range, but no coverage.
+                                          Display Sea Level / Terrain */
+
+                                       if (dem[indx].data[x0][y0]==0)
+                                               fprintf(fd,"%c%c%c",0,0,170);
+                                       else
+                                       {
+                                               /* Elevation: Greyscale */
+                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                               fprintf(fd,"%c%c%c",output,output,output);
+                                       }
+
+                                       break;
+
+                                       case 1:
+                                       /* Green */
+                                       fprintf(fd,"%c%c%c",0,255,0);
+                                       break;
+
+                                       case 2:
+                                       /* Pink */
+                                       fprintf(fd,"%c%c%c",255,192,203);
+                                       break;
+
+                                       case 3:
+                                       /* Cyan */
+                                       fprintf(fd,"%c%c%c",0,255,255);
+                                       break;
+
+                                       case 4:
+                                       /* Yellow */
+                                       fprintf(fd,"%c%c%c",255,255,0);
+                                       break;
+
+                                       case 5:
+                                       /* Medium Violet */
+                                       fprintf(fd,"%c%c%c",161,131,224);
+                                       break;
+
+                                       case 6:
+                                       /* Orange */
+                                       fprintf(fd,"%c%c%c",255,165,0);
+                                       break;
+
+                                       case 7:
+                                       /* Light Green */
+                                       fprintf(fd,"%c%c%c",193,255,193);
+                                       break;
+
+                                       case 8:
+                                       /* Red Pink */
+                                       fprintf(fd,"%c%c%c",255,108,108);
+                                       break;
+
+                                       case 9:
+                                       /* TX1 + TX4: Green Yellow */
+                                       fprintf(fd,"%c%c%c",173,255,47);
+                                       break;
+
+                                       case 10:
+                                       /* Blanched Almond */
+                                       fprintf(fd,"%c%c%c",255,235,184);
+                                       break;
+
+                                       case 11:
+                                       /* Dark Turquoise */
+                                       fprintf(fd,"%c%c%c",0,206,209);
+                                       break;
+
+                                       case 12:
+                                       /* Tan */
+                                       fprintf(fd,"%c%c%c",210,180,140);
+                                       break;
+
+                                       case 13:
+                                       /* Magenta 1 */
+                                       fprintf(fd,"%c%c%c",243,110,205);
+                                       break;
+
+                                       case 14:
+                                       /* Gold2 */
+                                       fprintf(fd,"%c%c%c",238,201,0);
+                                       break;
+
+                                       case 15:
+                                       /* Medium Spring Green */
+                                       fprintf(fd,"%c%c%c",0,250,154);
+                                       break;
+
+                                       case 16:
+                                       /* Very light Blue */
+                                       fprintf(fd,"%c%c%c",244,244,255);
+                                       break;
+
+                                       default:
+                                       /* Land / Sea */
+                                       if (dem[indx].data[x0][y0]==0)
+                                               fprintf(fd,"%c%c%c",0,0,170);
+                                       else
+                                       {
+                                               /* Elevation: Greyscale */
+                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                               fprintf(fd,"%c%c%c",output,output,output);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       x0=width/16;
+
+       for (y0=0; y0<30; y0++)
+       {
+               for (indx=0; indx<16; indx++)
+               {
+                       for (x=0; x<x0; x++)
+                       {
+                               t=indx;  
+                               t2=indx+8;
+
+                               if (y0>=10 && y0<=18)
+                               {  
+                                       if (t2>9)
+                                       {
+                                               if (x>=11 && x<=17)     
+                                                       if (smallfont[t2/10][y0-10][x-11])
+                                                               t=255; 
+                                       }
+
+                                       if (x>=19 && x<=25)     
+                                               if (smallfont[t2%10][y0-10][x-19])
+                                                       t=255;
+                                       if (x>=27 && x<=33)
+                                               if (smallfont[0][y0-10][x-27])
+                                                       t=255; 
+                               }
+
+                               switch (t)
+                               {
+                                       case 0:
+                                       /* Green */
+                                       fprintf(fd,"%c%c%c",0,255,0);
+                                       break;
+
+                                       case 1:
+                                       /* Pink */
+                                       fprintf(fd,"%c%c%c",255,192,203);
+                                       break;
+
+                                       case 2:
+                                       /* Cyan */
+                                       fprintf(fd,"%c%c%c",0,255,255);
+                                       break;
+
+                                       case 3:
+                                       /* Yellow */
+                                       fprintf(fd,"%c%c%c",255,255,0);
+                                       break;
+
+                                       case 4:
+                                       /* Medium Violet */
+                                       fprintf(fd,"%c%c%c",161,131,224);
+                                       break;
+
+                                       case 5:
+                                       /* Orange */
+                                       fprintf(fd,"%c%c%c",255,165,0);
+                                       break;
+
+                                       case 6:
+                                       /* Light Green */
+                                       fprintf(fd,"%c%c%c",193,255,193);
+                                       break;
+
+                                       case 7:
+                                       /* Red Pink */
+                                       fprintf(fd,"%c%c%c",255,108,108);
+                                       break;
+
+                                       case 8:
+                                       /* Green Yellow */
+                                       fprintf(fd,"%c%c%c",173,255,47);
+                                       break;
+
+                                       case 9:
+                                       /* Blanched Almond */
+                                       fprintf(fd,"%c%c%c",255,235,184);
+                                       break;
+
+                                       case 10:
+                                       /* Dark Turquoise */
+                                       fprintf(fd,"%c%c%c",0,206,209);
+                                       break;
+
+                                       case 11:
+                                       /* Tan */
+                                       fprintf(fd,"%c%c%c",210,180,140);
+                                       break;
+
+                                       case 12:
+                                       /* Magenta 1 */
+                                       fprintf(fd,"%c%c%c",243,110,205);
+                                       break;
+
+                                       case 13:
+                                       /* Gold2 */
+                                       fprintf(fd,"%c%c%c",238,201,0);
+                                       break;
+
+                                       case 14:
+                                       /* Medium Spring Green */
+                                       fprintf(fd,"%c%c%c",0,250,154);
+                                       break;
+
+                                       case 255:
+                                       /* Black */
+                                       fprintf(fd,"%c%c%c",0,0,0);
+                                       break;
+
+                                       default:
+                                       /* Very Light Blue */
+                                       fprintf(fd,"%c%c%c",244,244,255);
+                               }
+                       } 
+               }
+       }
+
+       fclose(fd);
+       fprintf(stdout,"Done!\n");
+       fflush(stdout);
+}
+
+void GraphTerrain(struct site source, struct site destination, char *name)
+{
+       /* This function invokes gnuplot to generate an appropriate
+          output file indicating the terrain profile between the source
+          and destination locations.  "filename" is the name assigned
+          to the output file generated by gnuplot.  The filename extension
+          is used to set gnuplot's terminal setting and output file type.
+          If no extension is found, .gif is assumed.  */
+
+       int x, y, z;
+       char filename[255], term[15], ext[15];
+       FILE *fd=NULL;
+
+       ReadPath(destination,source);
+
+       fd=fopen("profile.gp","wb");
+
+       for (x=0; x<path.length; x++)
+               fprintf(fd,"%f\t%f\n",path.distance[x],path.elevation[x]);
+
+       fclose(fd);
+
+       if (name[0]==0)
+       {
+               /* Default filename and output file type */
+
+               strncpy(filename,"profile\0",8);
+               strncpy(term,"gif\0",4);
+               strncpy(ext,"gif\0",4);
+       }
+
+       else
+       {
+               /* Grab extension and terminal type from "name" */
+
+               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
+                       filename[x]=name[x];
+
+               if (name[x]=='.')
+               {
+                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       {
+                               term[y]=tolower(name[x]);
+                               ext[y]=term[y];
+                       }
+
+                       ext[y]=0;
+                       term[y]=0;
+                       filename[z]=0;
+               }
+
+               else
+               {       /* No extension -- Default is gif */
+
+                       filename[x]=0;
+                       strncpy(term,"gif\0",4);
+                       strncpy(ext,"gif\0",4);
+               }
+       }
+
+       /* Either .ps or .postscript may be used
+          as an extension for postscript output. */
+
+       if (strncmp(term,"postscript",10)==0)
+               strncpy(ext,"ps\0",3);
+
+       else if (strncmp(ext,"ps",2)==0)
+               strncpy(term,"postscript\0",11);
+
+       fprintf(stdout,"Writing \"%s.%s\"...",filename,ext);
+       fflush(stdout);
+
+       fd=fopen("splat.gp","w");
+       fprintf(fd,"set grid\n");
+       fprintf(fd,"set autoscale\n");
+       fprintf(fd,"set term %s\n",term);
+       fprintf(fd,"set title \"SPLAT! Terrain Profile\"\n");
+       fprintf(fd,"set xlabel \"Distance Between %s and %s (miles)\"\n",destination.name,source.name);
+       fprintf(fd,"set ylabel \"Ground Elevation Above Sea Level (feet)\"\n");
+       fprintf(fd,"set output \"%s.%s\"\n",filename,ext);
+       fprintf(fd,"plot \"profile.gp\" title \"\" with lines\n");
+       fclose(fd);
+                       
+       x=system("gnuplot splat.gp");
+
+       if (x!=-1)
+       {
+               unlink("splat.gp");
+               unlink("profile.gp");
+               fprintf(stdout," Done!\n");
+               fflush(stdout);
+       }
+
+       else
+               fprintf(stderr,"\n*** ERROR: Error occurred invoking gnuplot!\n");
+}
+
+void GraphElevation(struct site source, struct site destination, char *name)
+{
+       /* This function invokes gnuplot to generate an appropriate
+          output file indicating the terrain profile between the source
+          and destination locations.  "filename" is the name assigned
+          to the output file generated by gnuplot.  The filename extension
+          is used to set gnuplot's terminal setting and output file type.
+          If no extension is found, .gif is assumed. */
+
+       int x, y, z;
+       char filename[255], term[15], ext[15];
+       double angle, refangle, maxangle=-90.0;
+       struct site remote;
+       FILE *fd=NULL, *fd2=NULL;
+
+       ReadPath(destination,source);  /* destination=RX, source=TX */
+       refangle=ElevationAngle(destination,source);
+
+       fd=fopen("profile.gp","wb");
+       fd2=fopen("reference.gp","wb");
+
+       for (x=1; x<path.length-1; x++)
+       {
+               remote.lat=path.lat[x];
+               remote.lon=path.lon[x];
+               remote.alt=0.0;
+               angle=ElevationAngle(destination,remote);
+               fprintf(fd,"%f\t%f\n",path.distance[x],angle);
+               fprintf(fd2,"%f\t%f\n",path.distance[x],refangle);
+
+               if (angle>maxangle)
+                       maxangle=angle;
+       }
+
+       fprintf(fd,"%f\t%f\n",path.distance[path.length-1],refangle);
+       fprintf(fd2,"%f\t%f\n",path.distance[path.length-1],refangle);
+
+       fclose(fd);
+       fclose(fd2);
+
+       if (name[0]==0)
+       {
+               /* Default filename and output file type */
+
+               strncpy(filename,"profile\0",8);
+               strncpy(term,"gif\0",4);
+               strncpy(ext,"gif\0",4);
+       }
+
+       else
+       {
+               /* Grab extension and terminal type from "name" */
+
+               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
+                       filename[x]=name[x];
+
+               if (name[x]=='.')
+               {
+                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       {
+                               term[y]=tolower(name[x]);
+                               ext[y]=term[y];
+                       }
+
+                       ext[y]=0;
+                       term[y]=0;
+                       filename[z]=0;
+               }
+
+               else
+               {       /* No extension -- Default is gif */
+
+                       filename[x]=0;
+                       strncpy(term,"gif\0",4);
+                       strncpy(ext,"gif\0",4);
+               }
+       }
+
+       /* Either .ps or .postscript may be used
+          as an extension for postscript output. */
+
+       if (strncmp(term,"postscript",10)==0)
+               strncpy(ext,"ps\0",3);
+
+       else if (strncmp(ext,"ps",2)==0)
+               strncpy(term,"postscript\0",11);
+
+       fprintf(stdout,"Writing \"%s.%s\"...",filename,ext);
+       fflush(stdout);
+
+       fd=fopen("splat.gp","w");
+
+       fprintf(fd,"set grid\n");
+       fprintf(fd,"set yrange [%2.3f to %2.3f]\n", (-fabs(refangle)-0.25), maxangle+0.25);
+       fprintf(fd,"set term %s\n",term);
+       fprintf(fd,"set title \"SPLAT! Elevation Profile\"\n");
+       fprintf(fd,"set xlabel \"Distance Between %s and %s (miles)\"\n",destination.name,source.name);
+       fprintf(fd,"set ylabel \"Elevation Angle Along Path Between %s and %s (degrees)\"\n",destination.name,source.name);
+       fprintf(fd,"set output \"%s.%s\"\n",filename,ext);
+       fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines\n");
+
+       fclose(fd);
+                       
+       x=system("gnuplot splat.gp");
+
+       if (x!=-1)
+       {
+               unlink("splat.gp");
+               unlink("profile.gp");
+               unlink("reference.gp"); 
+
+               fprintf(stdout," Done!\n");
+               fflush(stdout);
+       }
+
+       else
+               fprintf(stderr,"\n*** ERROR: Error occurred invoking gnuplot!\n");
+}
+
+void GraphHeight(struct site source, struct site destination, char *name)
+{
+       /* This function invokes gnuplot to generate an appropriate
+          output file indicating the terrain profile between the source
+          and destination locations.  What is plotted is the height of land
+          above or below a straight line between the receibe and transmit
+          sites. "filename" is the name assigned to the output file
+          generated by gnuplot.  The filename extension is used to
+          set gnuplot's terminal setting and output file type.
+          If no extension is found, .gif is assumed. */
+
+       int x, y, z;
+       char filename[255], term[15], ext[15];
+       double a, b, c, height, refangle, cangle, maxheight=-100000.0,
+              minheight=100000.0;
+       struct site remote;
+       FILE *fd=NULL, *fd2=NULL;
+
+       ReadPath(destination,source);  /* destination=RX, source=TX */
+       refangle=ElevationAngle(destination,source);
+       b=GetElevation(destination)+destination.alt+earthradius;
+
+       fd=fopen("profile.gp","wb");
+       fd2=fopen("reference.gp","wb");
+
+       for (x=1; x<path.length-1; x++)
+       {
+               remote.lat=path.lat[x];
+               remote.lon=path.lon[x];
+               remote.alt=0.0;
+
+               a=GetElevation(remote)+earthradius;
+
+               cangle=5280.0*Distance(destination,remote)/earthradius;
+
+               c=b*sin(refangle*deg2rad+HALFPI)/sin(HALFPI-refangle*deg2rad-cangle);
+
+               height=a-c;
+
+               fprintf(fd,"%f\t%f\n",path.distance[x],height);
+               fprintf(fd2,"%f\t%f\n",path.distance[x],0.);
+
+               if (height>maxheight)
+                       maxheight=height;
+
+               if (height<minheight)
+                       minheight=height;
+       }
+
+       fprintf(fd,"%f\t%f\n",path.distance[path.length-1],0.0);
+       fprintf(fd2,"%f\t%f\n",path.distance[path.length-1],0.0);
+
+       fclose(fd);
+       fclose(fd2);
+
+       if (name[0]==0)
+       {
+               /* Default filename and output file type */
+
+               strncpy(filename,"height\0",8);
+               strncpy(term,"gif\0",4);
+               strncpy(ext,"gif\0",4);
+       }
+
+       else
+       {
+               /* Grab extension and terminal type from "name" */
+
+               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
+                       filename[x]=name[x];
+
+               if (name[x]=='.')
+               {
+                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       {
+                               term[y]=tolower(name[x]);
+                               ext[y]=term[y];
+                       }
+
+                       ext[y]=0;
+                       term[y]=0;
+                       filename[z]=0;
+               }
+
+               else
+               {       /* No extension -- Default is gif */
+
+                       filename[x]=0;
+                       strncpy(term,"gif\0",4);
+                       strncpy(ext,"gif\0",4);
+               }
+       }
+
+       /* Either .ps or .postscript may be used
+          as an extension for postscript output. */
+
+       if (strncmp(term,"postscript",10)==0)
+               strncpy(ext,"ps\0",3);
+
+       else if (strncmp(ext,"ps",2)==0)
+               strncpy(term,"postscript\0",11);
+
+       fprintf(stdout,"Writing \"%s.%s\"...",filename,ext);
+       fflush(stdout);
+
+       fd=fopen("splat.gp","w");
+
+       minheight-=20.0;
+       maxheight+=20.0;
+
+       if (maxheight<20.0)
+               maxheight=20.0;
+
+       fprintf(fd,"set grid\n");
+       fprintf(fd,"set yrange [%2.3f to %2.3f]\n", minheight, maxheight);
+       fprintf(fd,"set term %s\n",term);
+       fprintf(fd,"set title \"SPLAT! Height Profile\"\n");
+       fprintf(fd,"set xlabel \"Distance Between %s and %s (miles)\"\n",destination.name,source.name);
+       fprintf(fd,"set ylabel \"Ground Height Above Path Between %s and %s (feet)\"\n",destination.name,source.name);
+       fprintf(fd,"set output \"%s.%s\"\n",filename,ext);
+       fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines\n");
+
+       fclose(fd);
+                       
+       x=system("gnuplot splat.gp");
+
+       if (x!=-1)
+       {
+               unlink("splat.gp");
+               unlink("profile.gp");
+               unlink("reference.gp"); 
+               fprintf(stdout," Done!\n");
+               fflush(stdout);
+       }
+
+       else
+               fprintf(stderr,"\n*** ERROR: Error occurred invoking gnuplot!\n");
+}
+
+void GraphLongley(struct site source, struct site destination, char *name)
+{
+       /* This function invokes gnuplot to generate an appropriate
+          output file indicating the Longley-Rice model loss between
+          the source and destination locations.   "filename" is the
+          name assigned to the output file generated by gnuplot.
+          The filename extension is used to set gnuplot's terminal
+          setting and output file type.  If no extension is found,
+          .gif is assumed.  */
+
+       int x, y, z, errnum, errflag=0;
+       char filename[255], term[15], ext[15], strmode[100], report_name[80];
+       double maxloss=-100000.0, minloss=100000.0, loss, haavt, angle;
+       FILE *fd=NULL, *fd2=NULL;
+
+       sprintf(report_name,"%s-to-%s.lro",source.name,destination.name);
+
+       for (x=0; report_name[x]!=0; x++)
+               if (report_name[x]==32 || report_name[x]==17 || report_name[x]==92 || report_name[x]==42 || report_name[x]==47)
+                       report_name[x]='_';     
+
+       fd2=fopen(report_name,"w");
+
+       fprintf(fd2,"\n\t--==[ SPLAT! v%s Longley-Rice Model Path Loss Report ]==--\n\n",splat_version);
+       fprintf(fd2,"Analysis of RF path conditions between %s and %s:\n",source.name, destination.name);
+       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+       fprintf(fd2,"Transmitter site: %s\n",source.name);
+       fprintf(fd2,"Site location: %.4f North / %.4f West",source.lat, source.lon);
+       fprintf(fd2, " (%s N / ", dec2dms(source.lat));
+       fprintf(fd2, "%s W)\n", dec2dms(source.lon));
+       fprintf(fd2,"Ground elevation: %.2f feet AMSL\n",GetElevation(source));
+       fprintf(fd2,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",source.alt, source.alt+GetElevation(source));
+
+       haavt=haat(source);
+
+       if (haavt>-4999.0)
+               fprintf(fd2,"Antenna height above average terrain: %.2f feet\n",haavt);
+
+       fprintf(fd2,"Distance to %s: %.2f miles.\n",destination.name,Distance(source,destination));
+       fprintf(fd2,"Azimuth to %s: %.2f degrees.\n",destination.name,Azimuth(source,destination));
+
+       angle=ElevationAngle(source,destination);
+
+       if (angle>=0.0)
+               fprintf(fd2,"Angle of elevation between %s and %s: %+.4f degrees.\n",source.name,destination.name,angle);
+
+       if (angle<0.0)
+               fprintf(fd2,"Angle of depression between %s and %s: %+.4f degrees.\n",source.name,destination.name,angle);
+
+       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+
+       /* Receiver */
+
+       fprintf(fd2,"Receiver site: %s\n",destination.name);
+       fprintf(fd2,"Site location: %.4f North / %.4f West",destination.lat, destination.lon);
+       fprintf(fd2, " (%s N / ", dec2dms(destination.lat));
+       fprintf(fd2, "%s W)\n", dec2dms(destination.lon));
+       fprintf(fd2,"Ground elevation: %.2f feet AMSL\n",GetElevation(destination));
+       fprintf(fd2,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",destination.alt, destination.alt+GetElevation(destination));
+
+       haavt=haat(destination);
+
+       if (haavt>-4999.0)
+               fprintf(fd2,"Antenna height above average terrain: %.2f feet\n",haavt);
+
+       fprintf(fd2,"Distance to %s: %.2f miles.\n",source.name,Distance(source,destination));
+       fprintf(fd2,"Azimuth to %s: %.2f degrees.\n",source.name,Azimuth(destination,source));
+
+       angle=ElevationAngle(destination,source);
+
+       if (angle>=0.0)
+               fprintf(fd2,"Angle of elevation between %s and %s: %+.4f degrees.\n",destination.name,source.name,angle);
+
+       if (angle<0.0)
+               fprintf(fd2,"Angle of depression between %s and %s: %+.4f degrees.\n",destination.name,source.name,angle);
+
+       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+
+       fprintf(fd2,"Longley-Rice path calculation parameters used in this analysis:\n\n");
+       fprintf(fd2,"Earth's Dielectric Constant: %.3lf\n",LR.eps_dielect);
+       fprintf(fd2,"Earth's Conductivity: %.3lf\n",LR.sgm_conductivity);
+       fprintf(fd2,"Atmospheric Bending Constant (N): %.3lf\n",LR.eno_ns_surfref);
+       fprintf(fd2,"Frequency: %.3lf (MHz)\n",LR.frq_mhz);
+       fprintf(fd2,"Radio Climate: %d (",LR.radio_climate);
+
+       switch (LR.radio_climate)
+       {
+               case 1:
+               fprintf(fd2,"Equatorial");
+               break;
+
+               case 2:
+               fprintf(fd2,"Continental Subtropical");
+               break;
+
+               case 3:
+               fprintf(fd2,"Maritime Subtropical");
+               break;
+
+               case 4:
+               fprintf(fd2,"Desert");
+               break;
+
+               case 5:
+               fprintf(fd2,"Continental Temperate");
+               break;
+
+               case 6:
+               fprintf(fd2,"Martitime Temperate, Over Land");
+               break;
+
+               case 7:
+               fprintf(fd2,"Maritime Temperate, Over Sea");
+               break;
+
+               default:
+               fprintf(fd2,"Unknown");
+       }
+
+       fprintf(fd2,")\nPolarization: %d (",LR.pol);
+
+       if (LR.pol==0)
+               fprintf(fd2,"Horizontal");
+
+       if (LR.pol==1)
+               fprintf(fd2,"Vertical");
+
+       fprintf(fd2,")\nFraction of Situations: %.1lf%c\n",LR.conf*100.0,37);
+       fprintf(fd2,"Fraction of Time: %.1lf%c\n",LR.rel*100.0,37);
+
+       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+
+       fprintf(fd2,"Analysis Results:\n\n");
+
+       ReadPath(source, destination);  /* destination=RX, source=TX */
+
+       elev_l[1]=0.04*METERS_PER_MILE;
+
+       for (x=1; x<path.length; x++)
+               elev_l[x+1]=path.elevation[x]*METERS_PER_FOOT;  
+
+       fprintf(fd2,"Distance (mi)\tLoss (dB)\tErrnum\tComment\n\n"); 
+
+       fd=fopen("profile.gp","w");
+
+       for (x=2; x<path.length; x++)
+       {
+               elev_l[0]=x-1;
+
+               point_to_point(elev_l, source.alt*METERS_PER_FOOT, 
+                       destination.alt*METERS_PER_FOOT,
+                       LR.eps_dielect, LR.sgm_conductivity, LR.eno_ns_surfref,
+                       LR.frq_mhz, LR.radio_climate, LR.pol, LR.conf, LR.rel,
+                       loss, strmode, errnum);
+
+                       /* Note: PASS BY REFERENCE ... loss and errnum are pass
+                       by reference, only used in this file by this function */
+
+
+               fprintf(fd,"%f\t%f\n",path.distance[path.length-1]-path.distance[x],loss);
+               fprintf(fd2,"%7.2f\t\t%7.2f\t\t  %d\t%s\n",path.distance[x],loss, errnum, strmode); 
+               errflag|=errnum;
+                 
+               if (loss>maxloss)
+                       maxloss=loss;
+
+               if (loss<minloss)
+                       minloss=loss;
+       }
+
+       fclose(fd);
+
+       if (errflag)
+       {
+               fprintf(fd2,"\nNotes on \"errnum\"...\n\n");
+               fprintf(fd2,"  0: No error.  :-)\n");
+               fprintf(fd2,"  1: Warning!  Some parameters are nearly out of range.\n");
+               fprintf(fd2,"     Results should be used with caution.\n");
+               fprintf(fd2,"  2: Note: Default parameters have been substituted for impossible ones.\n");
+               fprintf(fd2,"  3: Warning!  A combination of parameters is out of range.\n");
+               fprintf(fd2,"     Results are probably invalid.\n");
+               fprintf(fd2,"  Other: Warning!  Some parameters are out of range.\n");
+               fprintf(fd2,"    Results are probably invalid.\n\nEnd of Report\n");
+       }
+
+       fprintf(stdout,"Longley-Rice Path Loss between %s and %s is %.2f db\n",source.name, destination.name, loss);
+       fprintf(stdout,"Path Loss Report written to: \"%s\"\n",report_name);
+       fflush(stdout);
+
+       fclose(fd2);
+
+       if (name[0]==0)
+       {
+               /* Default filename and output file type */
+
+               strncpy(filename,"loss\0",5);
+               strncpy(term,"gif\0",4);
+               strncpy(ext,"gif\0",4);
+       }
+
+       else
+       {
+               /* Grab extension and terminal type from "name" */
+
+               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
+                       filename[x]=name[x];
+
+               if (name[x]=='.')
+               {
+                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       {
+                               term[y]=tolower(name[x]);
+                               ext[y]=term[y];
+                       }
+
+                       ext[y]=0;
+                       term[y]=0;
+                       filename[z]=0;
+               }
+
+               else
+               {       /* No extension -- Default is gif */
+
+                       filename[x]=0;
+                       strncpy(term,"gif\0",4);
+                       strncpy(ext,"gif\0",4);
+               }
+       }
+
+       /* Either .ps or .postscript may be used
+          as an extension for postscript output. */
+
+       if (strncmp(term,"postscript",10)==0)
+               strncpy(ext,"ps\0",3);
+
+       else if (strncmp(ext,"ps",2)==0)
+               strncpy(term,"postscript\0",11);
+
+       fprintf(stdout,"Writing \"%s.%s\"...",filename,ext);
+       fflush(stdout);
+
+       fd=fopen("splat.gp","w");
+
+       fprintf(fd,"set grid\n");
+       fprintf(fd,"set yrange [%2.3f to %2.3f]\n", minloss, maxloss);
+       fprintf(fd,"set term %s\n",term);
+       fprintf(fd,"set title \"SPLAT! Loss Profile\"\n");
+       fprintf(fd,"set xlabel \"Distance Between %s and %s (miles)\"\n",destination.name,source.name);
+       fprintf(fd,"set ylabel \"Longley-Rice Loss (dB)\"\n");
+       fprintf(fd,"set output \"%s.%s\"\n",filename,ext);
+       fprintf(fd,"plot \"profile.gp\" title \"Longley-Rice Loss\" with lines\n");
+
+       fclose(fd);
+                       
+       x=system("gnuplot splat.gp");
+
+       if (x!=-1)
+       {
+               unlink("splat.gp");
+               unlink("profile.gp");
+               unlink("reference.gp"); 
+
+               fprintf(stdout," Done!\n");
+               fflush(stdout);
+       }
+
+       else
+               fprintf(stderr,"\n*** ERROR: Error occurred invoking gnuplot!\n");
+}
+
+void ObstructionReport(struct site xmtr, struct site rcvr, char report)
+{
+       struct site result, result2, new_site;
+       double angle, haavt;
+       unsigned char block;
+       char report_name[80], string[255];
+       int x;
+       FILE *fd;
+
+       sprintf(report_name,"%s-to-%s.txt",xmtr.name,rcvr.name);
+
+       for (x=0; report_name[x]!=0; x++)
+               if (report_name[x]==32 || report_name[x]==17 || report_name[x]==92 || report_name[x]==42 || report_name[x]==47)
+                       report_name[x]='_';     
+
+       fd=fopen(report_name,"w");
+
+       fprintf(fd,"\n\t\t--==[ SPLAT! v%s Obstruction Report ]==--\n\n",splat_version);
+       fprintf(fd,"Analysis of line-of-sight path conditions between %s and %s:\n",xmtr.name, rcvr.name);
+       fprintf(fd,"\n-------------------------------------------------------------------------\n\n");
+       fprintf(fd,"Transmitter site: %s\n",xmtr.name);
+       fprintf(fd,"Site location: %.4f North / %.4f West",xmtr.lat, xmtr.lon);
+       fprintf(fd, " (%s N / ", dec2dms(xmtr.lat));
+       fprintf(fd, "%s W)\n", dec2dms(xmtr.lon));
+       fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(xmtr));
+       fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",xmtr.alt, xmtr.alt+GetElevation(xmtr));
+
+       haavt=haat(xmtr);
+
+       if (haavt>-4999.0)
+               fprintf(fd,"Antenna height above average terrain: %.2f feet\n",haavt);
+
+       fprintf(fd,"Distance to %s: %.2f miles.\n",rcvr.name,Distance(xmtr,rcvr));
+       fprintf(fd,"Azimuth to %s: %.2f degrees.\n",rcvr.name,Azimuth(xmtr,rcvr));
+
+       angle=ElevationAngle(xmtr,rcvr);
+
+       if (angle>=0.0)
+               fprintf(fd,"Angle of elevation between %s and %s: %+.4f degrees.\n",xmtr.name,rcvr.name,angle);
+
+       if (angle<0.0)
+               fprintf(fd,"Angle of depression between %s and %s: %+.4f degrees.\n",xmtr.name,rcvr.name,angle);
+
+       fprintf(fd,"\n-------------------------------------------------------------------------\n\n");
+
+       /* Receiver */
+
+       fprintf(fd,"Receiver site: %s\n",rcvr.name);
+       fprintf(fd,"Site location: %.4f North / %.4f West",rcvr.lat, rcvr.lon);
+       fprintf(fd, " (%s N / ", dec2dms(rcvr.lat));
+       fprintf(fd, "%s W)\n", dec2dms(rcvr.lon));
+       fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(rcvr));
+       fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",rcvr.alt, rcvr.alt+GetElevation(rcvr));
+
+       haavt=haat(rcvr);
+
+       if (haavt>-4999.0)
+               fprintf(fd,"Antenna height above average terrain: %.2f feet\n",haavt);
+
+       fprintf(fd,"Distance to %s: %.2f miles.\n",xmtr.name,Distance(xmtr,rcvr));
+       fprintf(fd,"Azimuth to %s: %.2f degrees.\n",xmtr.name,Azimuth(rcvr,xmtr));
+
+       angle=ElevationAngle(rcvr,xmtr);
+
+       if (angle>=0.0)
+               fprintf(fd,"Angle of elevation between %s and %s: %+.4f degrees.\n",rcvr.name,xmtr.name,angle);
+
+       if (angle<0.0)
+               fprintf(fd,"Angle of depression between %s and %s: %+.4f degrees.\n",rcvr.name,xmtr.name,angle);
+
+       fprintf(fd,"\n-------------------------------------------------------------------------\n\n");
+
+       if (report=='y')
+       {
+               /* Write an Obstruction Report */
+
+               new_site=rcvr;
+               result=los(xmtr,rcvr);
+               result2=result;
+               result2.alt-=1;
+               block=result.name[0];
+
+               if (block=='*')
+                       fprintf(fd,"SPLAT! detected obstructions at:\n\n");
+
+               while (block=='*')
+               {
+                       if (result.lat!=result2.lat || result.lon!=result2.lon || result.alt!=result2.alt)
+                               fprintf(fd,"\t%.4f N, %.4f W, %5.2f miles, %6.2f feet AMSL.\n",result.lat, result.lon, Distance(rcvr,result), result.alt);
+
+                       result2=result;
+                       new_site.alt+=1.0;
+
+                       /* Can you hear me now? :-) */
+
+                       result=los(xmtr,new_site);
+                       block=result.name[0];
+               }
+
+               if (new_site.alt!=rcvr.alt)
+                       sprintf(string,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear all obstructions detected by SPLAT!\n\n",rcvr.name, new_site.alt);
+               else
+                       sprintf(string,"\nNo obstructions due to terrain were detected by SPLAT!\n\n");
+       }
+
+       fprintf(fd,"%s",string);
+
+       fclose(fd);
+
+       /* Display LOS status to terminal */
+
+       fprintf(stdout,"%sObstruction report written to: \"%s\"\n",string,report_name);
+       fflush(stdout);
+}
+
+void SiteReport(struct site xmtr)
+{
+       char report_name[80];
+       double terrain;
+       int x, azi;
+       FILE *fd;
+
+       sprintf(report_name,"%s-site_report.txt",xmtr.name);
+
+       for (x=0; report_name[x]!=0; x++)
+               if (report_name[x]==32 || report_name[x]==17 || report_name[x]==92 || report_name[x]==42 || report_name[x]==47)
+                       report_name[x]='_';     
+
+       fd=fopen(report_name,"w");
+
+       fprintf(fd,"\n\t--==[ SPLAT! v%s Site Analysis Report For: %s ]==--\n\n",splat_version,xmtr.name);
+
+       fprintf(fd,"---------------------------------------------------------------------------\n\n");
+       fprintf(fd,"Site location: %.4f North / %.4f West",xmtr.lat, xmtr.lon);
+       fprintf(fd, " (%s N / ",dec2dms(xmtr.lat));
+       fprintf(fd, "%s W)\n",dec2dms(xmtr.lon));
+       fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(xmtr));
+       fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",xmtr.alt, xmtr.alt+GetElevation(xmtr));
+
+       terrain=haat(xmtr);
+
+       if (terrain>-4999.0)
+       {
+               fprintf(fd,"Antenna height above average terrain: %.2f feet\n\n",terrain);
+
+               /* Display the average terrain between 2 and 10 miles
+                  from the transmitter site at azimuths of 0, 45, 90,
+                  135, 180, 225, 270, and 315 degrees. */
+
+               for (azi=0; azi<=315; azi+=45)
+               {
+                       fprintf(fd,"Average terrain at %3d degrees azimuth: ",azi);
+                       terrain=AverageTerrain(xmtr,(double)azi,2.0,10.0);
+
+                       if (terrain>-4999.0)
+                               fprintf(fd,"%.2f feet AMSL\n",terrain);
+                       else
+                               fprintf(fd,"No terrain\n");
+               }
+       }
+
+       fprintf(fd,"\n---------------------------------------------------------------------------\n\n");
+       fclose(fd);
+       fprintf(stdout,"\nSite analysis report written to: \"%s\"\n",report_name);
+}
+
+int main(char argc, char *argv[])
+{
+
+       int             x, y, z=0;
+       unsigned char   rxlat, rxlon, txlat, txlon, min_lat,
+                       min_lon, max_lat, max_lon, 
+                       coverage=0, LRmap=0,
+                       ext[20], terrain_plot=0,
+                       elevation_plot=0, height_plot=0, 
+                       longley_plot=0, cities=0, bfs=0, txsites=0,
+                       count, west_min, west_max, north_min, north_max,
+                       report='y';
+       char            mapfile[255], header[80], city_file[5][255], 
+                       elevation_file[255], height_file[255], 
+                       longley_file[255], terrain_file[255],
+                       string[255], rxfile[255],
+                       txfile[255], map=0, boundary_file[5][255];
+
+       double          altitude=0.0, altitudeLR=0.0, tx_range=0.0,
+                       rx_range=0.0, deg_range=0.0, deg_limit,
+                       deg_range_lon, er_mult;
+       struct          site tx_site[4], rx_site;
+       FILE            *fd;
+
+       sprintf(header,"\n  --==[ SPLAT! v%s Terrain Analysis Software (c) 1997-2004 KD2BD ]==--\n\n", splat_version);
+
+       if (argc==1)
+       {
+               fprintf(stdout, "%sAvailable Options...\n\n\t-t txsite(s).qth (max of 4)\n\t-r rxsite.qth\n",header);
+               fprintf(stdout,"\t-c plot coverage area(s) of TX(s) based on an RX antenna at X feet AGL\n");
+               fprintf(stdout,"\t-L plot path loss map of TX based on an RX antenna at X feet AGL\n");
+               fprintf(stdout,"\t-s filename(s) of city/site file(s) to import (max of 5)\n");
+               fprintf(stdout,"\t-b filename(s) of cartographic boundary file(s) to import (max of 5)\n");
+               fprintf(stdout,"\t-p filename of terrain profile graph to plot\n");
+               fprintf(stdout,"\t-e filename of terrain elevation graph to plot\n");
+               fprintf(stdout,"\t-h filename of terrain height graph to plot\n");
+               fprintf(stdout,"\t-l filename of Longley-Rice graph to plot\n");
+               fprintf(stdout,"\t-o filename of topographic map to generate (.ppm)\n");
+               fprintf(stdout,"\t-d sdf file directory path (overrides path in ~/.splat_path file)\n");
+               fprintf(stdout,"\t-n no analysis, brief report\n\t-N no analysis, no report\n");
+               fprintf(stdout,"\t-m earth radius multiplier\n");
+               fprintf(stdout,"\t-R modify default range for -c or -L (miles)\n\n");
+
+               fprintf(stdout,"Type 'man splat', or see the documentation for more details.\n\n");
+               fflush(stdout);
+               return 1;
+       }
+
+       y=argc-1;
+
+       rxfile[0]=0;
+       txfile[0]=0;
+       string[0]=0;
+       mapfile[0]=0;
+       elevation_file[0]=0;
+       terrain_file[0]=0;
+       sdf_path[0]=0;
+       path.length=0;
+       rx_site.lat=0.0;
+       rx_site.lon=0.0;
+       earthradius=EARTHRADIUS;
+
+       for (x=0; x<MAXSLOTS; x++)
+       {
+               dem[x].min_el=0;
+               dem[x].max_el=0;
+               dem[x].min_north=0;
+               dem[x].max_north=0;
+               dem[x].min_west=0;
+               dem[x].max_west=0;
+       }
+
+       /* Scan for command line arguments */
+
+       for (x=1; x<=y; x++)
+       {
+               if (strcmp(argv[x],"-R")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               sscanf(argv[z],"%lf",&max_range);
+
+                               if (max_range<0.0)
+                                       max_range=0.0;
+
+                               if (max_range>1000.0)
+                                       max_range=1000.0;
+                       }                        
+               }
+
+               if (strcmp(argv[x],"-m")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               sscanf(argv[z],"%lf",&er_mult);
+
+                               if (er_mult<0.1)
+                                       er_mult=1.0;
+
+                               if (er_mult>1.0e6)
+                                       er_mult=1.0e6;
+
+                               earthradius*=er_mult;
+                       }                        
+               }
+
+               if (strcmp(argv[x],"-o")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                               strncpy(mapfile,argv[z],253);
+                       map=1;
+               }
+
+               if (strcmp(argv[x],"-c")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               sscanf(argv[z],"%lf",&altitude);
+                               coverage=1;
+                       }
+               }
+
+               if (strcmp(argv[x],"-p")==0)
+               { 
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               strncpy(terrain_file,argv[z],253);
+                               terrain_plot=1;
+                       }
+               }
+
+               if (strcmp(argv[x],"-e")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               strncpy(elevation_file,argv[z],253);
+                               elevation_plot=1;
+                       }
+               }
+
+               if (strcmp(argv[x],"-h")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               strncpy(height_file,argv[z],253);
+                               height_plot=1;
+                       }
+               }
+
+               if (strcmp(argv[x],"-n")==0)
+               {
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               report='n';
+                               map=1;
+                       }
+               }
+
+               if (strcmp(argv[x],"-N")==0)
+               {
+                       if (z<=y && argv[z][0] && argv[z][0]!='-');
+                       {
+                               report='N';
+                               map=1;
+                       }
+               }
+
+               if (strcmp(argv[x],"-d")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                               strncpy(sdf_path,argv[z],253);
+               }
+
+               if (strcmp(argv[x],"-t")==0)
+               {
+                       /* Read Transmitter Location */
+
+                       z=x+1;
+
+                       while (z<=y && argv[z][0] && argv[z][0]!='-' && txsites<4)
+                       {
+                               strncpy(txfile,argv[z],253);
+                               tx_site[txsites]=LoadQTH(txfile);
+                               txsites++;
+                               z++;
+                       }
+                       z--;
+               }
+
+               if (strcmp(argv[x],"-L")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               sscanf(argv[z],"%lf",&altitudeLR);
+
+                               if (coverage)
+                                       fprintf(stdout,"c and L are exclusive options, ignoring L.\n");
+                               else
+                               {
+                                       LRmap=1;
+                                       ReadLRParm(txfile);
+                               } 
+                       }
+               }
+
+               if (strcmp(argv[x],"-l")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               strncpy(longley_file,argv[z],253);
+                               longley_plot=1;
+                               /* Doing this twice is harmless */
+                               ReadLRParm(txfile);
+                       }
+               }
+
+               if (strcmp(argv[x],"-r")==0)
+               {
+                       /* Read Receiver Location */
+
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               strncpy(rxfile,argv[z],253);
+                               rx_site=LoadQTH(rxfile);
+                       }
+               }
+
+               if (strcmp(argv[x],"-s")==0)
+               {
+                       /* Read city file(s) */
+
+                       z=x+1;
+
+                       while (z<=y && argv[z][0] && argv[z][0]!='-' && cities<5)
+                       {
+                               strncpy(city_file[cities],argv[z],253);
+                               cities++;
+                               z++;
+                       }
+                       z--;
+               }
+
+               if (strcmp(argv[x],"-b")==0)
+               {
+                       /* Read Boundary File(s) */
+
+                       z=x+1;
+
+                       while (z<=y && argv[z][0] && argv[z][0]!='-' && bfs<5)
+                       {
+                               strncpy(boundary_file[bfs],argv[z],253);
+                               bfs++;
+                               z++;
+                       }
+                       z--;
+               }
+       }
+
+       /* Perform some error checking on the arguments
+          and switches parsed from the command-line.
+          If an error is encountered, print a message
+          and exit gracefully. */
+
+       if (txsites==0)
+       {
+               fprintf(stderr,"\n%c*** ERROR: No transmitter site(s) specified!\n\n",7);
+               exit (-1);
+       }
+
+       for (x=0, y=0; x<txsites; x++)
+       {
+               if (tx_site[x].lat==0.0 && tx_site[x].lon==0.0)
+               {
+                       fprintf(stderr,"\n*** ERROR: Transmitter site #%d not found!",x+1);
+                       y++;
+               }
+       }
+
+       if (y)
+       {
+               fprintf(stderr,"%c\n\n",7);
+               exit (-1);
+       }
+
+       if ((coverage+LRmap)==0 && rx_site.lat==0.0 && rx_site.lon==0.0)
+       {
+               fprintf(stderr,"\n%c*** ERROR: No receiver site found or specified!\n\n",7);
+               exit (-1);
+       }
+
+       /* No errors were detected.  Whew!  :-) */
+
+       /* If no SDF path was specified on the command line (-d), check
+          for a path specified in the $HOME/.splat_path file.  If the
+          file is not found, then sdf_path[] remains NULL, and the
+          current working directory is assumed to contain the SDF
+          files. */
+
+       if (sdf_path[0]==0)
+       {
+               sprintf(string,"%s/.splat_path",getenv("HOME"));
+               fd=fopen(string,"r");
+
+               if (fd!=NULL)
+               {
+                       fgets(string,253,fd);
+
+                       /* Remove <CR> and/or <LF> from string */
+
+                       for (x=0; string[x]!=13 && string[x]!=10 && string[x]!=0 && x<253; x++);
+                       string[x]=0;
+
+                       strncpy(sdf_path,string,253);
+
+                       fclose(fd);
+               }
+       }
+
+       /* Ensure a trailing '/' is present in sdf_path */
+
+       if (sdf_path[0])
+       {
+               x=strlen(sdf_path);
+
+               if (sdf_path[x-1]!='/' && x!=0)
+               {
+                       sdf_path[x]='/';
+                       sdf_path[x+1]=0;
+               }
+       }
+
+       fprintf(stdout,"%s",header);
+       fflush(stdout);
+
+       x=0;
+       y=0;
+
+       min_lat=0;
+       max_lat=0;
+       min_lon=0;
+       max_lon=0;
+
+       rxlat=(unsigned char)floor(rx_site.lat);
+       rxlon=(unsigned char)floor(rx_site.lon);
+
+       if (rxlat!=0)
+       {
+               if (min_lat==0)
+                       min_lat=rxlat;
+
+               else if (rxlat<min_lat)
+                       min_lat=rxlat;
+       }
+
+       if (rxlon!=0)
+       {
+               if (min_lon==0)
+                       min_lon=rxlon;
+
+               else if (rxlon<min_lon)
+                       min_lon=rxlon;
+       }
+
+       if (rxlat>max_lat)
+               max_lat=rxlat;
+
+       if (rxlon>max_lon)
+               max_lon=rxlon;
+
+       for (y=0, z=0; z<txsites; z++)
+       {
+               txlat=(unsigned char)floor(tx_site[z].lat);
+               txlon=(unsigned char)floor(tx_site[z].lon);
+
+               if (txlat!=0)
+               {
+                       if (min_lat==0)
+                               min_lat=txlat;
+
+                       else if (txlat<min_lat)
+                               min_lat=txlat;
+               }
+
+               if (txlon!=0)
+               {
+                       if (min_lon==0)
+                               min_lon=txlon;
+
+                       else if (txlon<min_lon)
+                               min_lon=txlon;
+               }
+
+               if (txlat>max_lat)
+                       max_lat=txlat;
+
+               if (txlon>max_lon)
+                       max_lon=txlon;
+       }
+
+       if (min_lat!=0 && min_lon!=0 && max_lat!=0 && max_lon!=0)
+       {
+               for (y=min_lon; y<=max_lon; y++)
+                       for (x=min_lat; x<=max_lat; x++)
+                       {
+                               sprintf(string,"%u:%u:%u:%u",x, x+1, y, y+1);
+                               LoadSDF(string);
+                       }
+       }
+
+       if (coverage)
+       {
+               for (z=0; z<txsites; z++)
+               {
+                       /* "Ball park" estimates used to load any additional
+                          SDF files required to conduct this analysis. */
+
+                       tx_range=sqrt(1.5*(tx_site[z].alt+GetElevation(tx_site[z])));
+                       rx_range=sqrt(1.5*altitude);
+
+                       /* deg_range determines the maximum
+                          amount of topo data we read */
+
+                       deg_range=(tx_range+rx_range)/69.0;
+
+                       /* max_range sets the maximum size of the
+                          analysis.  A small, non-zero amount can
+                          be used to shrink the size of the analysis
+                          and limit the amount of topo data read by
+                          SPLAT!  A very large number will only increase
+                          the width of the analysis, not the size of
+                          the map. */
+
+                       if (max_range==0.0)
+                               max_range=tx_range+rx_range;
+
+                       if (max_range<(tx_range+rx_range))
+                               deg_range=max_range/69.0;
+
+                       /* Prevent the demand for a really wide coverage
+                          from allocating more slots than are available
+                          in memory. */
+
+                       switch (MAXSLOTS)
+                       {
+                               case 2: deg_limit=0.25;
+                                       break;
+
+                               case 4: deg_limit=0.5;
+                                       break;
+
+                               case 9: deg_limit=1.0;
+                                       break;
+
+                               case 16: deg_limit=2.0;
+                                       break;
+
+                               case 25: deg_limit=3.0;
+                       }
+
+                       if (tx_site[z].lat<70.0)
+                               deg_range_lon=deg_range/cos(deg2rad*tx_site[z].lat);
+                       else
+                               deg_range_lon=deg_range/cos(deg2rad*70.0);
+
+                       /* Correct for squares in degrees not being square in miles */  
+
+                       if (deg_range>deg_limit)
+                               deg_range=deg_limit;
+
+                       if (deg_range_lon>deg_limit)
+                               deg_range_lon=deg_limit;
+
+                       north_min=(unsigned char)floor(tx_site[z].lat-deg_range);
+                       north_max=(unsigned char)floor(tx_site[z].lat+deg_range);
+                       west_min=(unsigned char)floor(tx_site[z].lon-deg_range_lon);
+                       west_max=(unsigned char)floor(tx_site[z].lon+deg_range_lon);
+
+                       if (min_lat==0)
+                               min_lat=north_min;
+
+                       else if (north_min<min_lat)
+                               min_lat=north_min;
+
+                       if (min_lon==0)
+                               min_lon=west_min;
+
+                       else if (west_min<min_lon)
+                               min_lon=west_min;
+
+                       if (north_max>max_lat)
+                               max_lat=north_max;
+
+                       if (west_max>max_lon)
+                               max_lon=west_max;
+               }
+
+               if (min_lat!=0 && min_lon!=0 && max_lat!=0 && max_lon!=0)
+               {
+                       for (y=min_lon; y<=max_lon; y++)
+                               for (x=min_lat; x<=max_lat; x++)
+                               {
+                                       sprintf(string,"%u:%u:%u:%u",x, x+1, y, y+1);
+                                       LoadSDF(string);
+                               }
+               }
+       }
+
+       if (LRmap)
+       {
+               /* "Ball park" estimates used to load any additional
+                  SDF files required to conduct this analysis. */
+
+               tx_range=sqrt(1.5*(tx_site[0].alt+GetElevation(tx_site[0])));
+               rx_range=sqrt(1.5*altitudeLR);
+
+               /**
+               tx_range=sqrt(5.0*tx_site[0].alt);
+               rx_range=sqrt(5.0*altitudeLR);
+               **/
+
+               /* deg_range determines the maximum
+                  amount of topo data we read */
+
+               deg_range=(tx_range+rx_range)/69.0;
+
+               /* max_range sets the maximum size of the
+                  analysis.  A small, non-zero amount can
+                  be used to shrink the size of the analysis
+                  and limit the amount of topo data read by
+                  SPLAT!  A very large number will only increase
+                  the width of the analysis, not the size of
+                  the map. */
+
+               if (max_range==0.0)
+                       max_range=tx_range+rx_range;
+
+               if (max_range<(tx_range+rx_range))
+                       deg_range=max_range/69.0;
+
+               /* Prevent the demand for a really wide coverage
+                  from allocating more slots than are available
+                  in memory. */
+
+               switch (MAXSLOTS)
+               {
+                       case 2: deg_limit=0.25;
+                               break;
+
+                       case 4: deg_limit=0.5;
+                               break;
+
+                       case 9: deg_limit=1.0;
+                               break;
+
+                       case 16: deg_limit=2.0;
+                               break;
+
+                       case 25: deg_limit=3.0;
+               }
+
+               if (tx_site[0].lat<70.0)
+                       deg_range_lon=deg_range/cos(deg2rad*tx_site[0].lat);
+               else
+                       deg_range_lon=deg_range/cos(deg2rad*70.0);
+
+               /* Correct for squares in degrees not being square in miles */  
+
+               if (deg_range>deg_limit)
+                       deg_range=deg_limit;
+
+               if (deg_range_lon>deg_limit)
+                       deg_range_lon=deg_limit;
+
+               north_min=(unsigned char)floor(tx_site[0].lat-deg_range);
+               north_max=(unsigned char)floor(tx_site[0].lat+deg_range);
+               west_min=(unsigned char)floor(tx_site[0].lon-deg_range_lon);
+               west_max=(unsigned char)floor(tx_site[0].lon+deg_range_lon);
+
+               if (min_lat==0)
+                       min_lat=north_min;
+
+               else if (north_min<min_lat)
+                       min_lat=north_min;
+
+               if (min_lon==0)
+                       min_lon=west_min;
+
+               else if (west_min<min_lon)
+                       min_lon=west_min;
+
+               if (north_max>max_lat)
+                       max_lat=north_max;
+
+               if (west_max>max_lon)
+                       max_lon=west_max;
+
+               if (min_lat!=0 && min_lon!=0 && max_lat!=0 && max_lon!=0)
+               {
+                       for (y=min_lon; y<=max_lon; y++)
+                               for (x=min_lat; x<=max_lat; x++)
+                               {
+                                       sprintf(string,"%u:%u:%u:%u",x, x+1, y, y+1);
+                                       LoadSDF(string);
+                               }
+               }
+       }
+
+       if (mapfile[0])
+               map=1;
+
+       if (coverage)
+       {
+               for (x=0; x<txsites; x++)
+               {
+                       PlotCoverage(tx_site[x],altitude);
+                       PlaceMarker(tx_site[x]);
+
+                       if (report!='N')
+                               SiteReport(tx_site[x]);
+               }
+
+               map=1;
+       }
+
+       else if (LRmap)
+       {
+               PlotLRMap(tx_site[0],altitudeLR);
+               PlaceMarker(tx_site[0]);
+
+               if (report!='N')
+                       SiteReport(tx_site[0]);
+               
+               map=1;
+       }
+
+       else       
+       {
+               PlaceMarker(rx_site);
+
+               for (x=0; x<txsites; x++)
+               {
+                       PlaceMarker(tx_site[x]);
+
+                       if (report=='y')
+                       {
+                               switch (x)
+                               {
+                                       case 0:
+                                               PlotPath(tx_site[x],rx_site,1);
+                                               break;
+
+                                       case 1:
+                                               PlotPath(tx_site[x],rx_site,8);
+                                               break;
+
+                                       case 2:
+                                               PlotPath(tx_site[x],rx_site,16);
+                                               break;
+
+                                       case 3:
+                                               PlotPath(tx_site[x],rx_site,32);
+                               }
+                       }
+
+                       if (report!='N')
+                               ObstructionReport(tx_site[x],rx_site,report);
+               }
+       }
+
+       if (map)
+       {
+               if (bfs)
+               {
+                       for (x=0; x<bfs; x++)
+                               LoadBoundaries(boundary_file[x]);
+               }
+
+               if (cities)
+               {
+                       for (x=0; x<cities; x++)
+                               LoadCities(city_file[x]);
+               }
+                               
+               if (!LRmap)
+                       WritePPM(mapfile);
+               else
+                       WritePPMLR(mapfile);
+       }
+
+       if (terrain_plot)
+       {
+               if (txsites>1)
+               {
+                       for (x=0; terrain_file[x]!='.' && terrain_file[x]!=0 && x<80; x++);
+
+                       if (terrain_file[x]=='.')  /* extension */
+                       {
+                               ext[0]='.';
+                               for (y=1, z=x, x++; terrain_file[x]!=0 && x<253 && y<14; x++, y++)
+                                       ext[y]=terrain_file[x];
+
+                               ext[y]=0;
+                               terrain_file[z]=0;
+                       }
+
+                       else
+                       {
+                               ext[0]=0;  /* No extension */
+                               terrain_file[x]=0;
+                       }
+
+                       for (count=0; count<txsites; count++)
+                       {
+                               sprintf(string,"%s-%c%s%c",terrain_file,'1'+count,ext,0);
+                               GraphTerrain(tx_site[count],rx_site,string);
+                       }
+               }
+
+               else
+                       GraphTerrain(tx_site[0],rx_site,terrain_file);
+       }
+
+       if (elevation_plot)
+       {
+               if (txsites>1)
+               {
+                       for (x=0; elevation_file[x]!='.' && elevation_file[x]!=0 && x<80; x++);
+
+                       if (elevation_file[x]=='.')  /* extension */
+                       {
+                               ext[0]='.';
+                               for (y=1, z=x, x++; elevation_file[x]!=0 && x<253 && y<14; x++, y++)
+                                       ext[y]=elevation_file[x];
+
+                               ext[y]=0;
+                               elevation_file[z]=0;
+                       }
+
+                       else
+                       {
+                               ext[0]=0;  /* No extension */
+                               elevation_file[x]=0;
+                       }
+
+                       for (count=0; count<txsites; count++)
+                       {
+                               sprintf(string,"%s-%c%s%c",elevation_file,'1'+count,ext,0);
+                               GraphElevation(tx_site[count],rx_site,string);
+                       }
+               }
+
+               else
+                       GraphElevation(tx_site[0],rx_site,elevation_file);
+       }
+
+       if (height_plot)
+       {
+               if (txsites>1)
+               {
+                       for (x=0; height_file[x]!='.' && height_file[x]!=0 && x<80; x++);
+
+                       if (height_file[x]=='.')  /* extension */
+                       {
+                               ext[0]='.';
+                               for (y=1, z=x, x++; height_file[x]!=0 && x<253 && y<14; x++, y++)
+                                       ext[y]=height_file[x];
+
+                               ext[y]=0;
+                               height_file[z]=0;
+                       }
+
+                       else
+                       {
+                               ext[0]=0;  /* No extension */
+                               height_file[x]=0;
+                       }
+
+                       for (count=0; count<txsites; count++)
+                       {
+                               sprintf(string,"%s-%c%s%c",height_file,'1'+count,ext,0);
+                               GraphHeight(tx_site[count],rx_site,string);
+                       }
+               }
+
+               else
+                       GraphHeight(tx_site[0],rx_site,height_file);
+       }
+
+       if (longley_plot)
+       {
+               if (txsites>1)
+               {
+                       for (x=0; longley_file[x]!='.' && longley_file[x]!=0 && x<80; x++);
+
+                       if (longley_file[x]=='.')  /* extension */
+                       {
+                               ext[0]='.';
+                               for (y=1, z=x, x++; longley_file[x]!=0 && x<253 && y<14; x++, y++)
+                                       ext[y]=longley_file[x];
+
+                               ext[y]=0;
+                               longley_file[z]=0;
+                       }
+
+                       else
+                       {
+                               ext[0]=0;  /* No extension */
+                               longley_file[x]=0;
+                       }
+
+                       for (count=0; count<txsites; count++)
+                       {
+                               sprintf(string,"%s-%c%s%c",longley_file,'1'+count,ext,0);
+                               GraphLongley(tx_site[count],rx_site,string);
+                       }
+               }
+
+               else
+                       GraphLongley(tx_site[0],rx_site,longley_file);
+       }
+
+       return 0;
+}
diff --git a/utils/README b/utils/README
new file mode 100644 (file)
index 0000000..593a13c
--- /dev/null
@@ -0,0 +1,110 @@
+Utilities for use with SPLAT! software are found under the
+splat-1.1.0/utils directory.  They include the following:
+
+citydecoder
+===========
+This utility reads U.S. Census Bureau files of Incorporated Places/Census
+Designated Places, and generates city/site data files for use with SPLAT!
+software.  Files for use with this utility are available for download
+free of charge from:
+
+       http://www.census.gov/geo/www/cob/bdy_files.html.
+
+Please select the ARC/INFO Ungenerate (ASCII) Metadata Cartographic Boundary
+Files from this site and unzip them prior to importing them to citydecoder.
+U.S. Census files are cataloged by the two digit FIPS code for the region
+(state) they represent.  citydecoder takes as an argument the two-letter
+file prefix plus the FIPS code of the region or state being processed.
+For example:
+
+       citydecoder pl34
+
+reads files "pl34_d00.dat" and "pl34_d00a.dat" that are extracted after
+the downloaded file has been unzipped, and generates a list of city names
+and geographical coordinates for the state of New Jersey (FIPS code 34).
+This data may be sorted and written to a file (cities.nj.dat) in the
+following manner:
+
+       citydecoder pl34 | sort > cities.nj.dat
+
+A list of FIPS codes (fips.txt) is included under splat/utils for your
+convenience.
+
+
+usgs2sdf
+========
+The usgs2sdf utility takes as an argument the name of an uncompressed
+and record delimited Digital Elevation Model Data (DEM) downloaded from
+the US Geological Survey, and generates a SPLAT Data File (SDF) compatible
+with SPLAT! Software.  usgs2sdf may be invoked manually, or via the
+postdownload script.
+
+
+postdownload
+============
+postdownload is a front-end to the usgs2sdf utility.  postdownload
+takes as an argument the name of the gzipped Digital Elevation Model
+(DEM) downloaded from the US Geological Survey (ie: wilmington-w.gz).
+postdownload uncompresses the DEM file, adds necessary record delimiters,
+and invokes usgs2sdf to produce a SPLAT Data File (SDF).
+
+Digital Elevation Models may be downloaded from:
+
+     http://edcsgs9.cr.usgs.gov/glis/hyper/guide/1_dgr_demfig/index1m.html
+
+Invoke postdownload with the name of each DEM file downloaded to
+produce a database of SPLAT Data Files.
+
+
+fontdata
+========
+The fontdata utility reads Slackware gzipped console font data
+to create the fontdata.h file required for compilation of SPLAT!.
+Font data of the type needed by this utility may be found under
+/usr/lib/kbd/consolefonts (Slackware < 8), or under
+/usr/share/kbd/consolefonts (Slackware >= 8.0).
+
+A default fontdata.h file is already included in with SPLAT!, and is
+a derivative of the s.fnt console font type available under Slackware.
+fontdata takes as an argument the name of the file containing the
+gzipped compressed console fonts:
+
+       fontdata s.fnt.gz
+
+
+Building The Utilities
+======================
+Normally, these utilities are built and installed along with SPLAT!
+when SPLAT!'s ./configure script is invoked.  However, if you modify
+them and/or wish to build and install them separately, here is how it's
+done.  First, invoke the "build" script to compile each or all utilities
+in this directory by name.  For example:
+
+       ./build citydecoder
+
+compiles citydecoder only, while
+
+       ./build all
+
+compiles all utilities.
+
+
+Installing The Utilities
+========================
+Invoke the "install" script to install each or all utilities in this
+directory by name.  For example:
+
+       ./install citydecoder
+
+installs citydecoder only, while
+
+       ./install all
+
+installs all utilities.
+
+You need to be 'root' to install any or all of these utilities.
+
+---
+John A. Magliacane, KD2BD
+January 2004
+
diff --git a/utils/build b/utils/build
new file mode 100755 (executable)
index 0000000..fbc7581
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# Simple shell script for building SPLAT! and associated utilities.
+# Written by John A. Magliacane, KD2BD May 2002
+#
+
+build_citydecoder()
+{
+       echo -n "Compiling citydecoder... "
+       cc -Wall -O3 -s -fomit-frame-pointer citydecoder.c -o citydecoder
+       echo "Done!"
+}
+
+build_usgs2sdf()
+{
+       echo -n "Compiling usgs2sdf... "
+       cc -Wall -O3 -s -fomit-frame-pointer usgs2sdf.c -o usgs2sdf
+       echo "Done!"
+}
+
+build_fontdata()
+{
+       echo -n "Compiling fontdata... "
+       cc -Wall -O3 -s -lz -fomit-frame-pointer fontdata.c -o fontdata
+       echo "Done!"
+}
+
+if [ $# == "0" ]; then
+       echo "Usage: build  { citydecoder, usgs2sdf, fontdata, all }"
+else
+
+       if [ $1 == "citydecoder" ]; then
+               build_citydecoder
+       fi
+
+       if [ $1 == "usgs2sdf" ]; then
+               build_usgs2sdf
+       fi
+
+       if [ $1 == "fontdata" ]; then
+               build_fontdata
+       fi
+
+       if [ $1 == "clean" ]; then
+               rm -f citydecoder usgs2sdf fontdata
+       fi
+
+       if [ $1 == "all" ]; then
+               build_citydecoder
+               build_usgs2sdf
+               build_fontdata
+       fi
+
+       if [ $1 != "citydecoder" ] && [ $1 != "usgs2sdf" ] && [ $1 != "fontdata" ] && [ $1 != "clean" ] && [ $1 != "all" ]; then
+               echo "Usage: build { citydecoder, usgs2sdf, fontdata, all }"
+       fi
+fi
diff --git a/utils/citydecoder.c b/utils/citydecoder.c
new file mode 100644 (file)
index 0000000..d3618f5
--- /dev/null
@@ -0,0 +1,146 @@
+/****************************************************************************
+*                CITYDECODER: A SPLAT! File Conversion Utility              *
+*                  Copyright John A. Magliacane, KD2BD 2002                 *
+*                         Last update: 13-Apr-2002                          *
+*****************************************************************************
+*                                                                           *
+* This utility reads ASCII Metadata Cartographic Boundary Files available   *
+* through the U.S. Census Bureau, and generates a lists of cities, states,  *
+* and counties along with the latitude and longitude corresponding to their *
+* geographic centers.  Such data may be (optionally) sorted and written to  *
+* files for use with SPLAT! software.  This utility takes as an argument,   *
+* two-letter prefix plus the FIPS code for the state being processed (ie:   *
+* "citydecoder pl34" will read files "pl34_d00.dat" and "pl34_d00a.dat",    *
+* and produce a list of city names and geographical coordinates for the     *
+* state of New Jersey.                                                      *
+*                                                                           *
+*****************************************************************************
+*                                                                           *
+* This program is free software; you can redistribute it and/or modify it   *
+* under the terms of the GNU General Public License as published by the     *
+* Free Software Foundation; either version 2 of the License or any later    *
+* version.                                                                  *
+*                                                                           *
+* This program is distributed in the hope that it will useful, but WITHOUT  *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     *
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
+* for more details.                                                         *
+*                                                                           *
+*****************************************************************************
+*          To compile: gcc -Wall -O6 -s citydecoder.c -o citydecoder        *
+*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(argc,argv)
+char argc, *argv[];
+{
+       int x, y, z;
+       long attributefile_id, coordinatefile_id;
+       char string[80], name[80], attributefilename[15], coordinatefilename[15];
+       double lat, lon;
+       FILE *attributefile=NULL, *coordinatefile=NULL;
+
+       if (argc==1)
+       {
+               fprintf(stderr,"\n*** Usage: citydecoder pl34 pl36 pl42 | sort > outputfile\n\n");
+               exit(1);
+       }
+
+       for (z=1; z<argc; z++)
+       {
+               sprintf(attributefilename,"%s_d00a.dat",argv[z]);
+               sprintf(coordinatefilename,"%s_d00.dat",argv[z]);
+
+               attributefile=fopen(attributefilename,"r");
+               coordinatefile=fopen(coordinatefilename,"r");
+
+               if (attributefile!=NULL && coordinatefile!=NULL)
+               {
+                       /* Skip First ASCII File Record (ID=0) */
+
+                       for (x=0; x<7; x++)
+                               fgets(string,80,attributefile);
+
+                       do
+                       {
+                               string[0]=0;
+                               fscanf(coordinatefile,"%ld", &coordinatefile_id);
+
+                               if (coordinatefile_id!=-99999)
+                               {
+                                       name[0]=0;
+
+                                       fscanf(coordinatefile,"%lf %lf",&lon, &lat);
+
+                                       /* Read ID Number From Attribute File */
+
+                                       fgets(string,80,attributefile);
+                                       sscanf(string,"%ld",&attributefile_id);
+
+
+                                       /* Skip Two Strings in Attribute File */
+
+                                       fgets(string,80,attributefile);
+                                       fgets(string,80,attributefile);
+
+
+                                       /* Read City Name From Attribute File */
+
+                                       fgets(string,80,attributefile);
+
+                                       /* Strip "quote" characters from name */
+
+                                       for (x=2, y=0; string[x]!='"' && string[x]!=0; x++, y++)
+                                               name[y]=string[x];
+
+                                       name[y]=0;
+
+                                       /* Skip Two Strings in Attribute File */
+
+                                       fgets(string,80,attributefile);
+                                       fgets(string,80,attributefile);
+
+                                       /* Skip blank line between records */
+
+                                       fgets(string,80,attributefile);
+
+                                       if (name[0]!=0 && name[0]!=' ' && feof(attributefile)==0 && attributefile_id==coordinatefile_id)
+                                               printf("%s, %f, %f\n",name,lat,-lon);
+                               }
+
+
+                               /* Read to the end of the current coordinatefile record */
+
+                               do
+                               {
+                                       string[0]=0;
+                                       fscanf(coordinatefile,"%s",string);
+
+                               } while (strncmp(string,"END",3)!=0 && feof(coordinatefile)==0);
+
+                       } while (feof(coordinatefile)==0);
+
+                       fclose(attributefile);
+                       fclose(coordinatefile);
+               }
+
+               else
+               {
+                       /* Houston, We Have A Problem... */
+
+                       fprintf(stderr,"%c\n",7);
+
+                       if (coordinatefile==NULL)
+                               fprintf(stderr,"*** Error opening coordinate file: \"%s\"!\n",coordinatefilename);
+
+                       if (attributefile==NULL)
+                               fprintf(stderr,"*** Error opening attribute file : \"%s\"!\n",attributefilename);
+                       fprintf(stderr,"\n");
+               }
+       }
+               
+       exit(0);
+}
diff --git a/utils/fips.txt b/utils/fips.txt
new file mode 100644 (file)
index 0000000..9e86a81
--- /dev/null
@@ -0,0 +1,59 @@
+State/Region           FIPS code\r
+\r
+Alabama                        01\r
+Alaska                 02\r
+Arizona                        03\r
+Arkansas               05\r
+California             06\r
+Colorado               08 \r
+Connecticut            09\r
+Delaware               10\r
+District of Columbia   11\r
+Florida                        12\r
+Georgia                        13\r
+Hawaii                 15\r
+Idaho                  16\r
+Illinois               17\r
+Indiana                        18\r
+Iowa                   19\r
+Kansas                 20\r
+Kentucky               21\r
+Louisiana              22\r
+Maine                  23\r
+Maryland               24\r
+Massachusetts          25\r
+Michigan               26\r
+Minnesota              27\r
+Mississippi            28\r
+Missouri               29\r
+Montana                        30\r
+Nebraska               31\r
+Nevada                 32\r
+New Hampshire          33\r
+New Jersey             34\r
+New Mexico             35\r
+New York               36\r
+North Carolina         37\r
+North Dakota           38\r
+Ohio                   39\r
+Oklahoma               40\r
+Oregon                 41\r
+Pennsylvania           42\r
+Rhode Island           44\r
+South Carolina         45\r
+South Dakota           46\r
+Tennessee              47\r
+Texas                  48\r
+Utah                   49\r
+Vermont                        50\r
+Virginia               51\r
+Washington             53\r
+West Virginia          54\r
+Wisconsin              55\r
+Wyoming                        56\r
+American Samoa         60\r
+Guam                   66\r
+N. Mariana Islands     69\r
+Puerto Rico            72\r
+Virgin Islands         78\r
+\r
diff --git a/utils/fontdata.c b/utils/fontdata.c
new file mode 100644 (file)
index 0000000..f04e546
--- /dev/null
@@ -0,0 +1,91 @@
+/****************************************************************************
+*                  FONTDATA:  A "fontdata.h" File Generator                 *
+*                  Copyright John A. Magliacane, KD2BD 2002                 *
+*                         Last update: 13-Apr-2002                          *
+*****************************************************************************
+*                                                                           *
+* This utility reads gzip compressed font data, and generates a fontdata.h  *
+* file required for compilation of SPLAT!.  Slackware Linux users may       *
+* find compatible console font data files under /usr/lib/kbd/consolefonts   *
+* (Slackware < version 8), or /usr/share/kbd/consolefonts (Slackware 8).    *
+*                                                                           *
+*                       Example: fontdata s.fnt.gz                          *
+*   Writes s.fnt font data to "fontdata.h" in current working directory.    *
+*                                                                           *
+*****************************************************************************
+*          To compile: gcc -Wall -O6 -s -lz fontdata.c -o fontdata          *
+*****************************************************************************
+*                                                                           *
+* This program is free software; you can redistribute it and/or modify it   *
+* under the terms of the GNU General Public License as published by the     *
+* Free Software Foundation; either version 2 of the License or any later    *
+* version.                                                                  *
+*                                                                           *
+* This program is distributed in the hope that it will useful, but WITHOUT  *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     *
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
+* for more details.                                                         *
+*                                                                           *
+*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+       int x;
+       unsigned char line, input;
+       FILE *infile, *outfile;
+       
+       if (argc==2)
+               infile=gzopen(argv[1],"rb");
+
+       else
+       {       
+               fprintf(stderr,"Usage: fontdata fontfile.gz\n");
+               exit(-1);
+       }
+
+       if (infile!=NULL)
+       {
+               outfile=fopen("fontdata.h","wb");
+
+               fprintf(outfile,"static char fontdata[] = {\n  ");
+
+               for (x=0, line=0; x<4096; x++)
+               {
+                       input=gzgetc(infile);
+                       
+                       fprintf(outfile," 0x%.2x",input);
+                       line++;
+
+                       if (x<4095)
+                               fprintf(outfile,",");
+
+                       if (line==12)
+                       {
+                               fprintf(outfile,"\n  ");
+                               line=0;
+                       }
+               }
+
+               fprintf(outfile," };\n");
+
+               gzclose(infile);
+               fclose(outfile);
+
+               printf("fontdata.h successfully written!\n");
+       }
+
+       else
+       {
+               fprintf(stderr,"%c*** Error: %c%s%c Not Found!\n",7,34,argv[1],34);
+               exit(-1);
+       }
+
+       exit(0);
+}
diff --git a/utils/install b/utils/install
new file mode 100755 (executable)
index 0000000..78b7d1a
--- /dev/null
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Simple shell script for installing SPLAT! and associated utilities.
+# Written by John A. Magliacane, KD2BD April 2002
+#
+
+install_citydecoder()
+{
+       cp citydecoder /usr/local/bin
+       echo "citydecoder installed!"
+}
+
+install_usgs2sdf()
+{
+       cp usgs2sdf /usr/local/bin
+       echo "usgs2sdf installed!"
+}
+
+install_fontdata()
+{
+       cp fontdata /usr/local/bin
+       echo "fontdata installed!"
+}
+
+whoami=`whoami`
+
+if [ $whoami != "root" ]; then
+       echo "Sorry, $whoami.  You need to be 'root' to install this software.  :-("
+fi
+
+if [ $# == "0" ]; then
+       echo "Usage: ./install  { citydecoder, usgs2sdf, fontdata, all }"
+else 
+
+       if [ $1 == "citydecoder" ] && [ $whoami == "root" ] && [ -x citydecoder ]; then
+               install_citydecoder
+       fi
+
+       if [ $1 == "usgs2sdf" ] && [ $whoami == "root" ] && [ -x usgs2sdf ]; then
+               install_usgs2sdf
+       fi
+
+       if [ $1 == "fontdata" ] && [ $whoami == "root" ] && [ -x fontdata ]; then
+               install_fontdata
+       fi
+
+       if [ $1 == "all" ]  && [ $whoami == "root" ]; then
+               if [ -x citydecoder ]; then
+                       install_citydecoder
+               fi
+
+               if [ -x usgs2sdf ]; then
+                       install_usgs2sdf
+               fi
+
+               if [ -x fontdata ]; then
+                       install_fontdata
+               fi
+       fi
+
+       if [ $1 != "citydecoder" ] && [ $1 != "usgs2sdf" ] && [ $1 != "fontdata" ] && [ $1 != "all" ]; then
+               echo "Usage: install { citydecoder, usgs2sdf, fontdata, all }"
+       fi
+fi
diff --git a/utils/postdownload b/utils/postdownload
new file mode 100755 (executable)
index 0000000..ee608eb
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Simple script for processing of downloaded undelimited gzipped
+# USGS DEM files, and converting them to SPLAT Data Files.
+# Written by John A. Magliacane, KD2BD May 2002
+#
+if [ $# == "0" ]; then
+       echo
+       echo "This utility reads downloaded gzipped USGS DEM"
+       echo "files and generates equivalent SPLAT Data Files (SDFs)."
+       echo
+       echo "Files compatible with this SPLAT! utility may be"
+       echo "obtained via anonymous ftp at:"
+       echo
+       echo -e "\tedcftp.cr.usgs.gov"
+       echo
+       echo "in the pub/data/DEM/250 subdirectory, or via http at:"
+       echo
+       echo -e "\tedcwww.cr.usgs.gov/glis/hyper/guide/1_dgr_dem#dem7"
+       echo
+       echo "Usage: postdownload wilmington-w.gz"
+       echo
+else
+       # gunzip the downloaded file...
+       echo -n "Uncompressing $1..."
+       gunzip -c $1 > unzipped_file
+       echo
+       echo "Adding record delimiters..."
+       dd if=unzipped_file of=delimited_file ibs=4096 cbs=1024 conv=unblock
+       # Invoke usgs2sdf to generate a SPLAT Data File...
+       usgs2sdf delimited_file
+       echo -n "Removing temp files..."
+       rm delimited_file unzipped_file
+       echo
+       echo "Done!"
+fi
diff --git a/utils/s.fnt.gz b/utils/s.fnt.gz
new file mode 100644 (file)
index 0000000..6b8e2fd
Binary files /dev/null and b/utils/s.fnt.gz differ
diff --git a/utils/usgs2sdf.c b/utils/usgs2sdf.c
new file mode 100644 (file)
index 0000000..0c1f1fa
--- /dev/null
@@ -0,0 +1,311 @@
+/****************************************************************************
+*            USGS2SDF: USGS to SPLAT Data File Converter Utility            *
+*               Copyright John A. Magliacane, KD2BD 1997-2001               *
+*                         Last update: 13-Apr-2002                          *
+*****************************************************************************
+*                                                                           *
+* This program reads files containing delimited US Geological Survey        *
+* Digital Elevation Model Data files, and creates Splat Data Files          *
+* containing ONLY the raw information needed by SPLAT!, thereby saving      *
+* disk space, as well as read/write time.                                   *
+*                                                                           *
+* The format of .sdf files created by this utility is as follows:           *
+*                                                                           *
+*      maximum west longitude (degrees West)                               *
+*      minimum north latitude (degrees North)                              *
+*      minimum west longitude (degrees West)                               *
+*      maximum north latitude (degrees North)                              *
+*       ...1440000 elevation points... (1200x1200)                          *
+*                                                                           *
+* All data is represented as integers.  A single '\n' follows each value.   *
+*                                                                           *
+* SPLAT Data Files are named according to the geographical locations        *
+* they represent (ie: min_north:max_north:min_west:max_west.sdf).           *
+*                                                                           *
+*****************************************************************************
+*          To compile: gcc -Wall -O6 -s splat2sdf.c -o splat2sdf            *
+*****************************************************************************
+*                                                                           *
+* This program is free software; you can redistribute it and/or modify it   *
+* under the terms of the GNU General Public License as published by the     *
+* Free Software Foundation; either version 2 of the License or any later    *
+* version.                                                                  *
+*                                                                           *
+* This program is distributed in the hope that it will useful, but WITHOUT  *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     *
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
+* for more details.                                                         *
+*                                                                           *
+*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+char *d2e(string)
+char *string;
+{
+       /* This function is used to replace 'D's with 'E's for proper
+          exponential notation of numeric strings read from delimited
+          USGS data files.  It returns a pointer to a string. */
+
+       unsigned char x;
+
+       for (x=0; string[x]!=0; x++)
+               if (string[x]=='D')
+                       string[x]='E';
+       return (string);
+}
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+       unsigned char minimum[30], maximum[30], swlong[30], swlat[30],
+                nwlong[30], nwlat[30], nelong[30], nelat[30], selong[30],
+                selat[30], string[40];
+       double max_el, min_el,  max_west, min_west, max_north, min_north;
+       int x, y, z, c, array[1202][1202];
+       char splatfile[25];
+       FILE *fd;
+
+       if (argc!=2)
+       {
+               fprintf(stderr,"Usage: usgs2sdf uncompressed_delimited_usgs_datafile (ie: wilmington-e)\n");
+               exit(0);
+       }
+
+       fd=fopen(argv[1],"rb");
+
+       if (fd!=NULL)
+       {
+               fprintf(stdout,"Reading \"%s\"...",argv[1]);
+               fflush(stdout);
+
+               /* Skip first 548 bytes */
+
+               for (x=0; x<548; x++)
+                       getc(fd);
+
+               /* Read quadrangle corners */
+       
+               /* Read southwest longitude */
+
+               for (x=0; x<22; x++)
+                       swlong[x]=getc(fd);
+               swlong[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read southwest latitude */
+
+               for (x=0; x<22; x++)
+                       swlat[x]=getc(fd);
+               swlat[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read northwest longitude */
+
+               for (x=0; x<22; x++)
+                       nwlong[x]=getc(fd);
+               nwlong[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read northwest latitude */
+
+               for (x=0; x<22; x++)
+                       nwlat[x]=getc(fd);
+               nwlat[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read northeast longitude */
+
+               for (x=0; x<22; x++)
+                       nelong[x]=getc(fd);
+               nelong[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read northeast latitude */
+
+               for (x=0; x<22; x++)
+                       nelat[x]=getc(fd);
+               nelat[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read southeast longitude */
+
+               for (x=0; x<22; x++)
+                       selong[x]=getc(fd);
+               selong[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read southeast latitude */
+
+               for (x=0; x<22; x++)
+                       selat[x]=getc(fd);
+               selat[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read minimum elevation */ 
+
+               for (x=0; x<22; x++)
+                       minimum[x]=getc(fd);
+               minimum[x]=0;
+
+               /* Skip 2 bytes */
+
+               for (x=0; x<2; x++)
+                       getc(fd);
+
+               /* Read maximum elevation */
+
+               for (x=0; x<22; x++)
+                       maximum[x]=getc(fd);
+
+               maximum[x]=0;
+
+               sscanf(d2e(minimum),"%lf",&min_el);
+               sscanf(d2e(maximum),"%lf",&max_el);
+
+               sscanf(d2e(swlong),"%lf",&max_west);
+               sscanf(d2e(swlat),"%lf",&min_north);
+
+               sscanf(d2e(nelong),"%lf",&min_west);
+               sscanf(d2e(nelat),"%lf",&max_north);
+
+               max_west/=-3600.0;
+               min_north/=3600.0;
+               max_north/=3600.0;
+               min_west/=-3600.0;
+
+               /* Skip 84 Bytes */
+
+               for (x=0; x<84; x++)
+                       getc(fd);
+
+               /* Read elevation data... */
+
+               for (x=1200; x>=0; x--)
+               {
+                       if (x==900)
+                       {
+                               printf(" 25%c...",37);
+                               fflush(stdout);
+                       }
+
+                       if (x==600)
+                       {
+                               printf(" 50%c...",37);
+                               fflush(stdout);
+                       }
+
+                       if (x==300)
+                       {
+                               printf(" 75%c... ",37);
+                               fflush(stdout);
+                       }
+
+                       /* Skip over 9 strings of data */
+
+                       for (y=0; y<9; y++)
+                       {
+                               string[0]=0;
+
+                               do
+                               {
+                                       c=getc(fd);
+
+                               } while (c==' ' || c=='\n');
+
+                               for (z=0; c!=' ' && c!='\n' && z<28; z++)
+                               {
+                                       string[z]=c;
+                                       c=getc(fd);
+                               }
+
+                               string[z]=0;    
+                       }
+
+                       /* Store elevation data in array */
+
+                       for (y=0; y<1201; y++)
+                       {
+                               string[0]=0;
+
+                               do
+                               {
+                                       c=getc(fd);
+
+                               } while (c==' ' || c=='\n');
+
+                               for (z=0; c!=' ' && c!='\n' && z<28; z++)
+                               {
+                                       string[z]=c;
+                                       c=getc(fd);
+                               }
+
+                               string[z]=0;    
+                               sscanf(string,"%d",&array[y][x]);
+                       }
+               }
+
+               fclose(fd);
+
+               /* Write splat data file to disk */
+
+               sprintf(splatfile,"%.0f:%.0f:%.0f:%.0f.sdf",min_north,max_north,min_west,max_west);
+
+               fprintf(stdout," Done!\nWriting \"%s\"... ",splatfile);
+               fflush(stdout);
+
+               fd=fopen(splatfile,"w");
+
+               fprintf(fd,"%.0f\n%.0f\n%.0f\n%.0f\n", max_west, min_north, min_west, max_north);
+
+               for (x=0; x<1200; x++)
+                       for (y=0; y<1200; y++)
+                               fprintf(fd,"%d\n",array[x][y]);
+
+               fclose(fd);
+               fprintf(stdout,"Done!\n");
+               fflush(stdout);
+       }
+
+       if (fd==NULL)
+       {
+               fprintf(stderr,"*** %c%s%c: File Not Found!\n",34,argv[1],34);
+               exit(-1);
+       }
+       else
+               exit(0);
+}