From 996bd803ab22572b622b684221c9a8ca04b3f63a Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Thu, 5 Jun 2008 17:33:45 -0600 Subject: [PATCH 1/1] Imported Upstream version 1.1.0 --- CHANGES | 91 + COPYING | 339 +++ README | 90 + build | 42 + clean | 6 + configure | 27 + docs/man/docmaker | 16 + docs/man/splat.1 | 683 ++++++ docs/man/splat.man | 597 ++++++ docs/pdf/splat.pdf | Bin 0 -> 72975 bytes docs/postscript/splat.ps | 1063 ++++++++++ docs/text/splat.txt | 683 ++++++ fontdata.h | 343 +++ install | 58 + itm.cpp | 1542 ++++++++++++++ sample.lrp | 72 + smallfont.h | 92 + splat-1.1.0.lsm | 37 + splat.cpp | 4303 ++++++++++++++++++++++++++++++++++++++ utils/README | 110 + utils/build | 57 + utils/citydecoder.c | 146 ++ utils/fips.txt | 59 + utils/fontdata.c | 91 + utils/install | 64 + utils/postdownload | 35 + utils/s.fnt.gz | Bin 0 -> 1364 bytes utils/usgs2sdf.c | 311 +++ 28 files changed, 10957 insertions(+) create mode 100644 CHANGES create mode 100644 COPYING create mode 100644 README create mode 100755 build create mode 100755 clean create mode 100755 configure create mode 100755 docs/man/docmaker create mode 100644 docs/man/splat.1 create mode 100644 docs/man/splat.man create mode 100644 docs/pdf/splat.pdf create mode 100644 docs/postscript/splat.ps create mode 100644 docs/text/splat.txt create mode 100644 fontdata.h create mode 100755 install create mode 100644 itm.cpp create mode 100644 sample.lrp create mode 100644 smallfont.h create mode 100644 splat-1.1.0.lsm create mode 100644 splat.cpp create mode 100644 utils/README create mode 100755 utils/build create mode 100644 utils/citydecoder.c create mode 100644 utils/fips.txt create mode 100644 utils/fontdata.c create mode 100755 utils/install create mode 100755 utils/postdownload create mode 100644 utils/s.fnt.gz create mode 100644 utils/usgs2sdf.c diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..b8060bb --- /dev/null +++ b/CHANGES @@ -0,0 +1,91 @@ +Release 1.1.0: +By John A. Magliacane (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 (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 (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 (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 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 (08-Apr-2002): + +* First public release of SPLAT! + diff --git a/COPYING b/COPYING new file mode 100644 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. + + 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.) + +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. + + 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. + + 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 + + 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. + + + Copyright (C) 19yy + + 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. + + , 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 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 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 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 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 index 0000000..3891f0b --- /dev/null +++ b/docs/man/docmaker @@ -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 index 0000000..c45eceb --- /dev/null +++ b/docs/man/splat.1 @@ -0,0 +1,683 @@ +SPLAT!(1) KD2BD Software SPLAT!(1) + + + +NNAAMMEE + splat - A SSignal PPropagation, LLoss, AAnd TTerrain analysis + tool + +SSYYNNOOPPSSIISS + splat [-t _t_r_a_n_s_m_i_t_t_e_r___s_i_t_e_._q_t_h] [-r _r_e_c_e_i_v_e_r___s_i_t_e_._q_t_h] [-c + _r_x___a_n_t_e_n_n_a___h_e_i_g_h_t___f_o_r___l_o_s___c_o_v_e_r_a_g_e___a_n_a_l_y_s_i_s _(_f_e_e_t_) + _(_f_l_o_a_t_)] [-L _r_x___a_n_t_e_n_n_a___h_e_i_g_h_t___f_o_r___L_o_n_g_l_e_y_-_R_i_c_e___c_o_v_e_r_- + _a_g_e___a_n_a_l_y_s_i_s _(_f_e_e_t_) _(_f_l_o_a_t_)] [-p _t_e_r_r_a_i_n___p_r_o_f_i_l_e_._e_x_t] [-e + _e_l_e_v_a_t_i_o_n___p_r_o_f_i_l_e_._e_x_t] [-h _h_e_i_g_h_t___p_r_o_f_i_l_e_._e_x_t] [-l _L_o_n_g_- + _l_e_y_-_R_i_c_e___p_r_o_f_i_l_e_._e_x_t] [-o _t_o_p_o_g_r_a_p_h_i_c___m_a_p___f_i_l_e_n_a_m_e_._p_p_m] + [-b _c_a_r_t_o_g_r_a_p_h_i_c___b_o_u_n_d_a_r_y___f_i_l_e_n_a_m_e_._d_a_t] [-s + _s_i_t_e_/_c_i_t_y___d_a_t_a_b_a_s_e_._d_a_t] [-d _s_d_f___d_i_r_e_c_t_o_r_y___p_a_t_h] [-m + _e_a_r_t_h___r_a_d_i_u_s___m_u_l_t_i_p_l_i_e_r _(_f_l_o_a_t_)] [-R _m_a_x_i_m_u_m___c_o_v_e_r_- + _a_g_e___r_a_n_g_e _(_f_o_r _-_c _o_r _-_L_) _(_m_i_l_e_s_) _(_f_l_o_a_t_)] [-n] [-N] + +DDEESSCCRRIIPPTTIIOONN + SSPPLLAATT!! is a simple, yet powerful terrain analysis tool + written for Unix and Linux-based workstations. SSPPLLAATT!! 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 + SSPPLLAATT!! source code in proprietary or closed-source appli- + cations is a violation of this license, and is ssttrriiccttllyy + forbidden. + + SSPPLLAATT!! 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. + +IINNTTRROODDUUCCTTIIOONN + SSPPLLAATT!! 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. SSPPLLAATT!! 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. SSPPLLAATT!! + 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, SSPPLLAATT!! determines individual + and mutual areas of coverage within the network specified. + + SSPPLLAATT!! operates in two modes: _p_o_i_n_t_-_t_o_-_p_o_i_n_t _m_o_d_e, and + _a_r_e_a _p_r_e_d_i_c_t_i_o_n _m_o_d_e. 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. + +IINNPPUUTT FFIILLEESS + SSPPLLAATT!! 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. + +SSPPLLAATT DDAATTAA FFIILLEESS + SSPPLLAATT!! 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 uussggss22ssddff utility + included with SSPPLLAATT!!. USGS Digital Elevation Models com- + patible with this utility are available at no cost via the + Internet at: _h_t_t_p_:_/_/_e_d_c_- + _s_g_s_9_._c_r_._u_s_g_s_._g_o_v_/_g_l_i_s_/_h_y_p_e_r_/_g_u_i_d_e_/_1___d_g_r___d_e_m_- + _f_i_g_/_i_n_d_e_x_1_m_._h_t_m_l. + + 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 + (_._s_d_f) as generated by the uussggss22ssddff utility, or in bzip2 + compressed format (_._s_d_f_._b_z_2). Since uncompressed files + can be slightly faster to load than compressed files, + SSPPLLAATT!! searches for the needed SDF data in uncompressed + format first. If such data cannot located, then SSPPLLAATT!! + tries to read the data in bzip2 compressed format. If no + compressed SDF files can be found for the region + requested, SSPPLLAATT!! 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 SSPPLLAATT!! 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 SSPPLLAATT!! underscores the + importance of having all the SDF files required for the + region being analyzed if meaningful results are to be + expected. + +SSIITTEE LLOOCCAATTIIOONN ((QQTTHH)) FFIILLEESS + SSPPLLAATT!! imports site location information of transmitter + and receiver sites analyzed by the program from ASCII + files having a _._q_t_h 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 _m_e_t_e_r_s 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 (_w_n_j_t_._q_t_h) might read as fol- + lows: + + WNJT + 40.2833 + 74.6889 + 990.00 + + Each transmitter and receiver site analyzed by SSPPLLAATT!! must + be represented by its own site location (QTH) file. + +LLOONNGGLLEEYY--RRIICCEE PPAARRAAMMEETTEERR ((LLRRPP)) FFIILLEESS + SSPPLLAATT!! imports Longley-Rice model parameter data from + files having the same base name as the transmitter site + QTH file, but carrying a _._l_r_p 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 (_w_n_j_t_._l_r_p): + + 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, SSPPLLAATT!! 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 SSPPLLAATT!! 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 SSPPLLAATT!! 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 _._l_r_p file correspond to + the statistical analysis provided by the Longley-Rice + model. In this example, SSPPLLAATT!! 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: + _h_t_t_p_:_/_/_e_l_b_e_r_t_._i_t_s_._b_l_d_r_d_o_c_._g_o_v_/_i_t_m_._h_t_m_l and + _h_t_t_p_:_/_/_w_w_w_._s_o_f_t_w_r_i_g_h_t_._c_o_m_/_f_a_q_/_e_n_g_i_n_e_e_r_i_n_g_/_p_r_o_p___l_o_n_g_- + _l_e_y___r_i_c_e_._h_t_m_l + +CCIITTYY LLOOCCAATTIIOONN FFIILLEESS + The names and locations of cities, tower sites, or other + points of interest may imported and be plotted on topo- + graphic maps generated by SSPPLLAATT!!. SSPPLLAATT!! 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 _._q_t_h files, latitude and longi- + tude information may be entered in either decimal or + degree, minute, second (DMS) format. + + For example (_c_i_t_i_e_s_._d_a_t): + + 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. + SSPPLLAATT!! 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 cciittyyddee-- + ccooddeerr utility included with SSPPLLAATT!!. Such data is avail- + able free of charge via the Internet at: _h_t_t_p_:_/_/_w_w_w_._c_e_n_- + _s_u_s_._g_o_v_/_g_e_o_/_w_w_w_/_c_o_b_/_b_d_y___f_i_l_e_s_._h_t_m_l, and must be in ASCII + format. + +CCAARRTTOOGGRRAAPPHHIICC BBOOUUNNDDAARRYY DDAATTAA FFIILLEESS + Cartographic boundary data may also be imported to plot + the boundaries of cities, counties, or states on topo- + graphic maps generated by SSPPLLAATT!!. 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: _h_t_t_p_:_/_/_w_w_w_._c_e_n_- + _s_u_s_._g_o_v_/_g_e_o_/_w_w_w_/_c_o_b_/_c_o_2_0_0_0_._h_t_m_l_#_a_s_c_i_i and _h_t_t_p_:_/_/_w_w_w_._c_e_n_- + _s_u_s_._g_o_v_/_g_e_o_/_w_w_w_/_c_o_b_/_p_l_2_0_0_0_._h_t_m_l_#_a_s_c_i_i. 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. + +PPRROOGGRRAAMM OOPPEERRAATTIIOONN + SSPPLLAATT!! is invoked via the command-line using a series of + switches and arguments. Since SSPPLLAATT!! is a CPU and memory + intensive application, this type of interface minimizes + overhead, and also lends itself well to scripted opera- + tions. SSPPLLAATT!!'s CPU and memory scheduling priority may be + adjusted through the use of the Unix nniiccee command. + + The number and type of switches passed to SSPPLLAATT!! determine + its mode of operation and method of output data genera- + tion. Nearly all of SSPPLLAATT!!'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. + +PPOOIINNTT--TTOO--PPOOIINNTT AANNAALLYYSSIISS + SSPPLLAATT!! 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 _t_x___s_i_t_e_._q_t_h and receiver specified in _r_x___s_i_t_e_._q_t_h, + and writes a SSPPLLAATT!! 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, SSPPLLAATT!! 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. SSPPLLAATT!! 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 SSPPLLAATT!! 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 _$_H_O_M_E_/_._s_p_l_a_t___p_a_t_h 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 + + SSPPLLAATT!! invokes ggnnuupplloott when generating graphs. The file- + name extension specified to SSPPLLAATT!! determines the format + of the graph produced. _._g_i_f will produce a 640x480 color + GIF graphic file, while _._p_s or _._p_o_s_t_s_c_r_i_p_t will produce + postscript output. Output in formats such as PNG, Adobe + Illustrator, AutoCAD dxf, LaTeX, and many others are + available. Please consult ggnnuupplloott, and ggnnuupplloott'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 SSPPLLAATT!! in the form of a + text file with a _._l_r_o 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 _L_i_n_e_-_o_f_-_S_i_g_h_t, _S_i_n_g_l_e _H_o_r_i_z_o_n, _D_o_u_b_l_e _H_o_r_i_- + _z_o_n, _D_i_f_f_r_a_c_t_i_o_n _D_o_m_i_n_a_n_t, and _T_r_o_p_o_s_c_a_t_t_e_r _D_o_m_i_n_a_n_t. + + To determine the signal-to-noise (SNR) ratio at remote + location where random Johnson (thermal) noise is the pri- + mary limiting factor in reception: + + _S_N_R=_T-_N_J-_L+_G-_N_F + + where TT is the ERP of the transmitter in dBW, NNJJ is John- + son Noise in dBW (-136 dBW for a 6 MHz TV channel), LL is + the path loss provided by SSPPLLAATT!! in dB (as a _p_o_s_i_t_i_v_e num- + ber), GG is the receive antenna gain in dB over isotropic, + and NNFF is the receiver noise figure in dB. + + TT may be computed as follows: + + _T=_T_I+_G_T + + where TTII is actual amount of RF power delivered to the + transmitting antenna in dBW, GGTT 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: + + _S_i_g_n_a_l__M_a_r_g_i_n=_S_N_R-_S + + where SS 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 SSPPLLAATT!! to visualize + the path between the transmitter and receiver sites from + yet another perspective. Topographic maps generated by + SSPPLLAATT!! 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. + + SSPPLLAATT!! 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 xxvv, TThhee GGIIMMPP, IImmaaggeeMMaaggiicckk, + and XXPPaaiinntt. PNG format is highly recommended for lossless + compressed storage of SSPPLLAATT!! generated topographic output + files. An excellent command-line utility capable of con- + verting SSPPLLAATT!! PPM graphic files to PNG files is wwppnngg, and + is available at: + _h_t_t_p_:_/_/_w_w_w_._l_i_b_p_n_g_._o_r_g_/_p_u_b_/_p_n_g_/_b_o_o_k_/_s_o_u_r_c_e_s_._h_t_m_l. As a + last resort, PPM files may be compressed using the bzip2 + utility, and read directly by TThhee GGIIMMPP in this format. + Topographic output is specified using the _-_o switch: + + splat -t tx_site -r rx_site -o topo_map.ppm + + The _._p_p_m extension on the output filename is assumed by + SSPPLLAATT!!, and is optional. + + In this example, _t_o_p_o___m_a_p_._p_p_m 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 + _r_x___s_i_t_e_._q_t_h). + + 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 SSPPLLAATT!! + 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 SSPPLLAATT!! 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 SSPPLLAATT!! 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 SSPPLLAATT!!. 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. + +DDEETTEERRMMIINNIINNGG RREEGGIIOONNAALL CCOOVVEERRAAGGEE + SSPPLLAATT!! can analyze a transmitter or repeater site, or net- + work of sites, and predict the regional coverage for each + site specified. In this mode, SSPPLLAATT!! 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. SSPPLLAATT!! 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, SSPPLLAATT!! generates a topographic map called + _t_x___c_o_v_e_r_a_g_e_._p_p_m that illustrates the predicted line-of- + sight regional coverage of _t_x___s_i_t_e to receiving locations + having antennas 30.0 feet above ground level (AGL). The + contents of _c_i_t_i_e_s_._d_a_t are plotted on the map, as are the + cartographic boundaries contained in the file + _c_o_3_4___d_0_0_._d_a_t. + + When plotting line-of-sight paths and areas of regional + coverage, SSPPLLAATT!! 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 SSPPLLAATT!! 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, SSPPLLAATT!! generates a + site report for each station analyzed. SSPPLLAATT!! 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, SSPPLLAATT!! 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, SSPPLLAATT!! will + perform Longley-Rice path loss calculations between all + four corners of the area prediction map. + +DDEETTEERRMMIINNIINNGG MMUULLTTIIPPLLEE RREEGGIIOONNSS OOFF CCOOVVEERRAAGGEE + SSPPLLAATT!! 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 _n_e_t_w_o_r_k_._p_p_m. 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 _._q_t_h 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 SSPPLLAATT!!. + +TTOOPPOOGGRRAAPPHHIICC MMAAPP GGEENNEERRAATTIIOONN + 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 _m_a_p_._p_p_m in the current working directory by + default. + +DDEETTEERRMMIINNAATTIIOONN OOFF AANNTTEENNNNAA HHEEIIGGHHTT AABBOOVVEE AAVVEERRAAGGEE TTEERRRRAAIINN + SSPPLLAATT!! 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, SSPPLLAATT!! + 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 SSPPLLAATT!! to perform average + terrain calculations. Under such conditions, SSPPLLAATT!! 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, SSPPLLAATT!! reports _N_o _T_e_r_- + _r_a_i_n for those radial paths. + +SSEETTTTIINNGG TTHHEE MMAAXXIIMMUUMM SSIIZZEE OOFF AANN AANNAALLYYSSIISS RREEGGIIOONN + SSPPLLAATT!! 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 _#_d_e_f_i_n_e _M_A_X_S_L_O_T_S + statement in the first several lines of _s_p_l_a_t_._c_p_p sets the + maximum number of "slots" available for topography data. + It also sets the maximum size of the topographic maps gen- + erated by SSPPLLAATT!!. MAXSLOTS is set to 9 by default. If + SSPPLLAATT!! 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 SSPPLLAATT!! + with this number of MAXSLOTS. In this case, MAXSLOTS may + be reduced to 4, although this will greatly limit the max- + imum region SSPPLLAATT!! 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. + +AADDDDIITTIIOONNAALL IINNFFOORRMMAATTIIOONN + Invoking SSPPLLAATT!! 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 SSPPLLAATT!! software + is available through the official SSPPLLAATT!! software web page + located at: _h_t_t_p_:_/_/_w_w_w_._q_s_l_._n_e_t_/_k_d_2_b_d_/_s_p_l_a_t_._h_t_m_l. + +FFIILLEESS + $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. + +AAUUTTHHOORRSS + John A. Magliacane, KD2BD <_k_d_2_b_d_@_a_m_s_a_t_._o_r_g> + Creator, Lead Developer + + Doug McDonald <_m_c_d_o_n_a_l_d_@_s_c_s_._u_i_u_c_._e_d_u> + 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 index 0000000..b4af60b --- /dev/null +++ b/docs/man/splat.man @@ -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 index 0000000000000000000000000000000000000000..1ab6b8483f56ab2db7b85b22d8eab7d81a39be9e GIT binary patch literal 72975 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 literal 0 HcmV?d00001 diff --git a/docs/postscript/splat.ps b/docs/postscript/splat.ps new file mode 100644 index 0000000..2dbe5de --- /dev/null +++ b/docs/postscript/splat.ps @@ -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 index 0000000..40fc60a --- /dev/null +++ b/docs/text/splat.txt @@ -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 + Creator, Lead Developer + + Doug McDonald + Longley-Rice Model integration + + + +KD2BD Software 20 January 2004 SPLAT!(1) diff --git a/fontdata.h b/fontdata.h new file mode 100644 index 0000000..14e5b18 --- /dev/null +++ b/fontdata.h @@ -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 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 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 +#include +#include +#include + +#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 (ij) + return i; + else + return j; +} + +double mymin(const double &a, const double &b) +{ + if (ab) + 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 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 zq, prop_zgnd(prop.zgndreal,prop.zgndimag); + zq=complex (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 r) +{ + return r.real()*r.real()+r.imag()*r.imag(); +} + +double alos(double d, prop_type &prop, propa_type &propa) +{ + complex prop_zgnd(prop.zgndreal,prop.zgndimag); + static double wls; + complex 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 || q1.57) + q=3.14-2.4649/q; + + alosv=(-4.343*log(abq_alos(complex(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 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.dist2000e3) + prop.kwx=4; + } + } + + else + { + prop.dist=d; + + if (prop.dist>0.0) + { + if (prop.dist>1000e3) + prop.kwx=mymax(prop.kwx,1); + + if (prop.dist2000e3) + prop.kwx=4; + } + } + + if (prop.dist=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 (d00.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 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.dist2000e3) + prop.kwx=4; + } + + if (prop.dist=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=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.dist3.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; i0.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 (jk) + { + 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; j0.0 && k1.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; i0.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 index 0000000..094c211 --- /dev/null +++ b/sample.lrp @@ -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 index 0000000..415af1f --- /dev/null +++ b/smallfont.h @@ -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 index 0000000..3785f71 --- /dev/null +++ b/splat-1.1.0.lsm @@ -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 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 +#include +#include +#include +#include +#include +#include +#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=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=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 (latxmin && lonymin) + { + 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; a360.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 and/or 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 and/or 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=0 && indxdem[indx].max_el) + dem[indx].max_el=data; + + if (dem[indx].min_el==0) + dem[indx].min_el=data; + else + { + if (datamax_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=0 && indxdem[indx].max_el) + dem[indx].max_el=data; + + if (dem[indx].min_el==0) + dem[indx].min_el=data; + else + { + if (datamax_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=0 && indx0) + dem[indx].min_el=0; + } + + if (dem[indx].min_elmax_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_north0 && 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=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; x225.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=(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>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=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; xmaxangle) + 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; xmaxheight) + maxheight=height; + + if (height-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; xmaxloss) + maxloss=loss; + + if (loss-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; x1000.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 and/or 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 (rxlatmax_lat) + max_lat=rxlat; + + if (rxlon>max_lon) + max_lon=rxlon; + + for (y=0, z=0; zmax_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; zdeg_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_minmax_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_minmax_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; x1) + { + 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; count1) + { + 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; count1) + { + 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; count1) + { + 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 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 index 0000000..fbc7581 --- /dev/null +++ b/utils/build @@ -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 index 0000000..d3618f5 --- /dev/null +++ b/utils/citydecoder.c @@ -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 +#include +#include + +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 +#include +#include +#include + +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 index 0000000..78b7d1a --- /dev/null +++ b/utils/install @@ -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 index 0000000..ee608eb --- /dev/null +++ b/utils/postdownload @@ -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 index 0000000000000000000000000000000000000000..6b8e2fdd0f81a20ab1b129e29dc6e4df4f76ec8f GIT binary patch literal 1364 zcmV-a1*`fWiwFp5ExtDb19L8BZgc>3S5IpjM-*S0u=Qb4_h751P4Gd?_RY+j zzqX&Tv_HL>H}C(vO_G?({kN-kCvQ*oOT?@@xma~8hB%=@Qd8t+M_x1@EQ)*~7Vul+ zxZ=QJNu(@^e(DshX0w%k(nr?&`*rE~vy=DlPiDv;^u8TV=Ri}`udeHoFhWpbPBu3; z^L#kj(RlQH^c?8B*Z=I{g5!f1{KdgBDqKyb4P(u8QfZv_1|!BsgI?A?~V|Y;HEvw6}tOFGpxu<_1mpx<`#`h`cmxF?Pt-=lG ze6fHJ%uiCF2T(@C(-f4cTH$b+rm0z<^-DSzQe%vC+qP?uUsiy*lP{DwNr^qb@%ZwY z!G4!NN^{R(#JFE6SAo}3-+Jc&#Zrr${(U&yJO2vkvTaQLLd2-lLSw1B(tmC0tyP2t zn%vE~qWPU?zg!?9+z&V+H=jP;Ea$ksHH7E!YavuT zkvAM(FkHQJ+^569X4ZB=A0zRc)LoISpL`3MdzOf_?rZ{phO z$0d_egKO2#oIH_1s3F3}zH*3!{%QBBoncNkvZp!$$_%N*c0>7NrLKBHVG7StlQNlv z*1yUHCjQz5ZENg1*XxGajy0Jo=W;Bl#)?+4Y zv+%>jegCMIAT)E%Ja=nKsRn`g#)|>VY!}1d>-xh;!UIeWVtS%;AWbE zx-+~33ku~01y-+Z|B&O5y&-k~;^&-yt@CF~){6Aca$@4^#YbY_pE~~Te0eVi`ao`Z z^##Z_+^Cs|sQ83e?-Lhab7ut8lPyJkJwxXr-xJjVEiPU)N@J3Q{R8MFT`uWMCk_Do zq#pms!@uOuuh)hj6Yh@qfK4@4`UlsBC$j4p0KU}@N9rL=_o3^eo=)+UFR2IDbz{qyK%3FPh{{l?V541*oR_YJhO3n1ICOnat< zxu0f0_3pbB&Vw+|j?|Fk^=sH~(UX*&U;M}Lu%r*O6C7RH``I>F+g;!{+m77pg^?)d zXW8|bdts3?wZ*-ytp^%{XFmvI{`@YRq`Q&T4f)v1iu=Kt_mzBuS^i?)Z +#include + +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); +} -- 2.30.2