Imported Upstream version 1.3.0
[debian/splat] / splat.cpp
index 9a96ef989b6f5cecc3559c5684d204033ea0ce40..844a12c3cb7e7822a291ff986847a779c14b1478 100644 (file)
--- a/splat.cpp
+++ b/splat.cpp
@@ -2,7 +2,7 @@
 *         SPLAT!: An RF Signal Path Loss And Terrain Analysis Tool          *
 ******************************************************************************
 *           Project started in 1997 by John A. Magliacane, KD2BD            *
-*                        Last update: 19-Oct-2007                           *
+*                        Last update: 10-Apr-2009                           *
 ******************************************************************************
 *         Please consult the documentation for a complete list of           *
 *           individuals who have contributed to this project.               *
 #include <bzlib.h>
 #include <unistd.h>
 #include "fontdata.h"
+#include "splat.h"
 
 #define GAMMA 2.5
-#define MAXPAGES 9
 #define BZBUFFER 65536
 
-#if MAXPAGES==4
-#define ARRAYSIZE 4950
+#if HD_MODE==0
+       #if MAXPAGES==4
+       #define ARRAYSIZE 4950
+       #endif
+
+       #if MAXPAGES==9
+       #define ARRAYSIZE 10870
+       #endif
+
+       #if MAXPAGES==16
+       #define ARRAYSIZE 19240
+       #endif
+
+       #if MAXPAGES==25
+       #define ARRAYSIZE 30025
+       #endif
+
+       #if MAXPAGES==36
+       #define ARRAYSIZE 43217
+       #endif
+
+       #if MAXPAGES==49
+       #define ARRAYSIZE 58813
+       #endif
+
+       #if MAXPAGES==64
+       #define ARRAYSIZE 76810
+       #endif
+
+       #define IPPD 1200
+#endif
+
+#if HD_MODE==1
+       #if MAXPAGES==1
+       #define ARRAYSIZE 5092 
+       #endif
+
+       #if MAXPAGES==4
+       #define ARRAYSIZE 14844 
+       #endif
+
+       #if MAXPAGES==9
+       #define ARRAYSIZE 32600
+       #endif
+
+       #if MAXPAGES==16
+       #define ARRAYSIZE 57713
+       #endif
+
+       #if MAXPAGES==25
+       #define ARRAYSIZE 90072
+       #endif
+
+       #if MAXPAGES==36
+       #define ARRAYSIZE 129650
+       #endif
+
+       #if MAXPAGES==49 
+       #define ARRAYSIZE 176437
+       #endif
+
+       #if MAXPAGES==64
+       #define ARRAYSIZE 230430
+       #endif
+
+       #define IPPD 3600
 #endif
 
-#if MAXPAGES==9
-#define ARRAYSIZE 10870
+#ifndef PI
+#define PI 3.141592653589793
 #endif
 
-#if MAXPAGES==16
-#define ARRAYSIZE 19240
+#ifndef TWOPI
+#define TWOPI 6.283185307179586
 #endif
 
-#if MAXPAGES==25
-#define ARRAYSIZE 30025
+#ifndef HALFPI
+#define HALFPI 1.570796326794896
 #endif
 
-char   string[255], sdf_path[255], opened=0, *splat_version={"1.2.1"};
+#define DEG2RAD 1.74532925199e-02
+#define EARTHRADIUS 20902230.97
+#define        METERS_PER_MILE 1609.344
+#define METERS_PER_FOOT 0.3048
+#define        KM_PER_MILE 1.609344
+#define FOUR_THIRDS 1.3333333333333
+
+char   string[255], sdf_path[255], opened=0, gpsav=0, splat_name[10],
+       splat_version[6], dashes[80];
 
-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, KM_PER_MILE=1.609344, earthradius,
-       max_range=0.0, forced_erp=-1.0, fzone_clearance=0.6;
+double earthradius, max_range=0.0, forced_erp=-1.0, dpp, ppd,
+       fzone_clearance=0.6, forced_freq, clutter;
 
-int    min_north=90, max_north=-90, min_west=360, max_west=-1,
-       max_elevation=-32768, min_elevation=32768, bzerror, maxdB=230;
+int    min_north=90, max_north=-90, min_west=360, max_west=-1, ippd, mpi,
+       max_elevation=-32768, min_elevation=32768, bzerror, contour_threshold;
 
-unsigned char got_elevation_pattern, got_azimuth_pattern, metric=0;
+unsigned char got_elevation_pattern, got_azimuth_pattern, metric=0, dbm=0;
 
 struct site {  double lat;
                double lon;
@@ -84,9 +153,9 @@ struct dem { int min_north;
                int max_west;
                int max_el;
                int min_el;
-               short data[1200][1200];
-               unsigned char mask[1200][1200];
-               unsigned char signal[1200][1200];
+               short data[IPPD][IPPD];
+               unsigned char mask[IPPD][IPPD];
+               unsigned char signal[IPPD][IPPD];
            }   dem[MAXPAGES];
 
 struct LR {    double eps_dielect; 
@@ -106,7 +175,7 @@ struct region { unsigned char color[32][3];
                int levels;
              } region;
 
-double elev_l[ARRAYSIZE+10];
+double elev[ARRAYSIZE+10];
 
 void point_to_point(double elev[], double tht_m, double rht_m,
          double eps_dielect, double sgm_conductivity, double eno_ns_surfref,
@@ -136,9 +205,30 @@ int ReduceAngle(double angle)
 
        double temp;
 
-       temp=acos(cos(angle*deg2rad));
+       temp=acos(cos(angle*DEG2RAD));
+
+       return (int)rint(temp/DEG2RAD);
+}
+
+double LonDiff(double lon1, double lon2)
+{
+       /* This function returns the short path longitudinal
+          difference between longitude1 and longitude2 
+          as an angle between -180.0 and +180.0 degrees.
+          If lon1 is west of lon2, the result is positive.
+          If lon1 is east of lon2, the result is negative. */
+
+       double diff;
+
+       diff=lon1-lon2;
+
+       if (diff<=-180.0)
+               diff+=360.0;
+
+       if (diff>=180.0)
+               diff-=360.0;
 
-       return (int)rint(temp/deg2rad);
+       return diff;
 }
 
 char *dec2dms(double decimal)
@@ -175,7 +265,7 @@ char *dec2dms(double decimal)
                seconds=59;
 
        string[0]=0;
-       sprintf(string,"%d%c %d\' %d\"", degrees*sign, 176, minutes, seconds);
+       snprintf(string,250,"%d%c %d\' %d\"", degrees*sign, 176, minutes, seconds);
        return (string);
 }
 
@@ -191,19 +281,20 @@ int PutMask(double lat, double lon, int value)
        char    found;
 
        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-               if (lat>=(double)dem[indx].min_north && lat<=(double)dem[indx].max_north && lon>=(double)dem[indx].min_west && lon<=(double)dem[indx].max_west)
+       {
+               x=(int)rint(ppd*(lat-dem[indx].min_north));
+               y=mpi-(int)rint(ppd*(LonDiff(dem[indx].max_west,lon)));
+
+               if (x>=0 && x<=mpi && y>=0 && y<=mpi)
                        found=1;
                else
                        indx++;
+       }
 
        if (found)
        {
-               x=(int)(1199.0*(lat-floor(lat)));
-               y=(int)(1199.0*(lon-floor(lon)));
-
                dem[indx].mask[x][y]=value;
-
-               return (dem[indx].mask[x][y]);
+               return ((int)dem[indx].mask[x][y]);
        }
 
        else
@@ -222,19 +313,20 @@ int OrMask(double lat, double lon, int value)
        char    found;
 
        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-               if (lat>=(double)dem[indx].min_north && lat<=(double)dem[indx].max_north && lon>=(double)dem[indx].min_west && lon<=(double)dem[indx].max_west)
+       {
+               x=(int)rint(ppd*(lat-dem[indx].min_north));
+               y=mpi-(int)rint(ppd*(LonDiff(dem[indx].max_west,lon)));
+
+               if (x>=0 && x<=mpi && y>=0 && y<=mpi)
                        found=1;
                else
                        indx++;
+       }
 
        if (found)
        {
-               x=(int)(1199.0*(lat-floor(lat)));
-               y=(int)(1199.0*(lon-floor(lon)));
-
                dem[indx].mask[x][y]|=value;
-
-               return (dem[indx].mask[x][y]);
+               return ((int)dem[indx].mask[x][y]);
        }
 
        else
@@ -258,18 +350,19 @@ int PutSignal(double lat, double lon, unsigned char signal)
        char    found;
 
        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-               if (lat>=(double)dem[indx].min_north && lat<=(double)dem[indx].max_north && lon>=(double)dem[indx].min_west && lon<=(double)dem[indx].max_west)
+       {
+               x=(int)rint(ppd*(lat-dem[indx].min_north));
+               y=mpi-(int)rint(ppd*(LonDiff(dem[indx].max_west,lon)));
+
+               if (x>=0 && x<=mpi && y>=0 && y<=mpi)
                        found=1;
                else
                        indx++;
+       }
 
        if (found)
        {
-               x=(int)(1199.0*(lat-floor(lat)));
-               y=(int)(1199.0*(lon-floor(lon)));
-
                dem[indx].signal[x][y]=signal;
-
                return (dem[indx].signal[x][y]);
        }
 
@@ -287,19 +380,18 @@ unsigned char GetSignal(double lat, double lon)
        char    found;
 
        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-               if (lat>=(double)dem[indx].min_north && lat<=(double)dem[indx].max_north && lon>=(double)dem[indx].min_west && lon<=(double)dem[indx].max_west)
+       {
+               x=(int)rint(ppd*(lat-dem[indx].min_north));
+               y=mpi-(int)rint(ppd*(LonDiff(dem[indx].max_west,lon)));
+
+               if (x>=0 && x<=mpi && y>=0 && y<=mpi)
                        found=1;
                else
                        indx++;
+       }
 
        if (found)
-       {
-               x=(int)(1199.0*(lat-floor(lat)));
-               y=(int)(1199.0*(lon-floor(lon)));
-
                return (dem[indx].signal[x][y]);
-       }
-
        else
                return 0;
 }
@@ -314,19 +406,21 @@ double GetElevation(struct site location)
        int     x, y, indx;
        double  elevation;
 
-       elevation=-5000.0;
-
-       x=(int)(1199.0*(location.lat-floor(location.lat)));
-       y=(int)(1199.0*(location.lon-floor(location.lon)));
-
-       for (indx=0, found=0; indx<MAXPAGES && found==0; indx++)
+       for (indx=0, found=0; indx<MAXPAGES && found==0;)
        {
-               if (location.lat>=(double)dem[indx].min_north && location.lat<=(double)dem[indx].max_north && location.lon>=(double)dem[indx].min_west && location.lon<=(double)dem[indx].max_west)
-               {
-                       elevation=3.28084*dem[indx].data[x][y];
+               x=(int)rint(ppd*(location.lat-dem[indx].min_north));
+               y=mpi-(int)rint(ppd*(LonDiff(dem[indx].max_west,location.lon)));
+
+               if (x>=0 && x<=mpi && y>=0 && y<=mpi)
                        found=1;
-               }
+               else
+                       indx++;
        }
+
+       if (found)
+               elevation=3.28084*dem[indx].data[x][y];
+       else
+               elevation=-5000.0;
        
        return elevation;
 }
@@ -341,18 +435,20 @@ int AddElevation(double lat, double lon, double height)
        char    found;
        int     x, y, indx;
 
-       x=(int)(1199.0*(lat-floor(lat)));
-       y=(int)(1199.0*(lon-floor(lon)));
-
-       for (indx=0, found=0; indx<MAXPAGES && found==0; indx++)
+       for (indx=0, found=0; indx<MAXPAGES && found==0;)
        {
-               if (lat>=(double)dem[indx].min_north && lat<=(double)dem[indx].max_north && lon>=(double)dem[indx].min_west && lon<=(double)dem[indx].max_west)
-               {
-                       dem[indx].data[x][y]+=(short)rint(height);
+               x=(int)rint(ppd*(lat-dem[indx].min_north));
+               y=mpi-(int)rint(ppd*(LonDiff(dem[indx].max_west,lon)));
+
+               if (x>=0 && x<=mpi && y>=0 && y<=mpi)
                        found=1;
-               }
+               else
+                       indx++;
        }
-       
+
+       if (found)
+               dem[indx].data[x][y]+=(short)rint(height);
+
        return found;
 }
 
@@ -363,10 +459,10 @@ double Distance(struct site site1, struct site site2)
 
        double  lat1, lon1, lat2, lon2, distance;
 
-       lat1=site1.lat*deg2rad;
-       lon1=site1.lon*deg2rad;
-       lat2=site2.lat*deg2rad;
-       lon2=site2.lon*deg2rad;
+       lat1=site1.lat*DEG2RAD;
+       lon1=site1.lon*DEG2RAD;
+       lat2=site2.lat*DEG2RAD;
+       lon2=site2.lon*DEG2RAD;
 
        distance=3959.0*acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos((lon1)-(lon2)));
 
@@ -381,11 +477,11 @@ double Azimuth(struct site source, struct site destination)
        double  dest_lat, dest_lon, src_lat, src_lon,
                beta, azimuth, diff, num, den, fraction;
 
-       dest_lat=destination.lat*deg2rad;
-       dest_lon=destination.lon*deg2rad;
+       dest_lat=destination.lat*DEG2RAD;
+       dest_lon=destination.lon*DEG2RAD;
 
-       src_lat=source.lat*deg2rad;
-       src_lon=source.lon*deg2rad;
+       src_lat=source.lat*DEG2RAD;
+       src_lon=source.lon*DEG2RAD;
                
        /* Calculate Surface Distance */
 
@@ -422,7 +518,7 @@ double Azimuth(struct site source, struct site destination)
        if (diff>0.0)
                azimuth=TWOPI-azimuth;
 
-       return (azimuth/deg2rad);               
+       return (azimuth/DEG2RAD);               
 }
 
 double ElevationAngle(struct site source, struct site destination)
@@ -456,28 +552,55 @@ void ReadPath(struct site source, struct site destination)
 
        int     c;
        double  azimuth, distance, lat1, lon1, beta, den, num,
-               lat2, lon2, total_distance, x, y, path_length,
-               increment;
+               lat2, lon2, total_distance, dx, dy, path_length,
+               miles_per_sample, samples_per_radian=68755.0;
        struct  site tempsite;
 
-       lat1=source.lat*deg2rad;
-       lon1=source.lon*deg2rad;
+       lat1=source.lat*DEG2RAD;
+       lon1=source.lon*DEG2RAD;
+
+       lat2=destination.lat*DEG2RAD;
+       lon2=destination.lon*DEG2RAD;
 
-       lat2=destination.lat*deg2rad;
-       lon2=destination.lon*deg2rad;
+       if (ppd==1200.0)
+               samples_per_radian=68755.0;
 
-       azimuth=Azimuth(source,destination)*deg2rad;
+       if (ppd==3600.0)
+               samples_per_radian=206265.0;
+
+       azimuth=Azimuth(source,destination)*DEG2RAD;
 
        total_distance=Distance(source,destination);
 
-       x=68755.0*acos(cos(lon1-lon2));         /* 1200 samples per degree */
-       y=68755.0*acos(cos(lat1-lat2));         /* 68755 samples per radian */
+       if (total_distance>(30.0/ppd))          /* > 0.5 pixel distance */
+       {
+               dx=samples_per_radian*acos(cos(lon1-lon2));
+               dy=samples_per_radian*acos(cos(lat1-lat2));
+
+               path_length=sqrt((dx*dx)+(dy*dy));              /* Total number of samples */
+
+               miles_per_sample=total_distance/path_length;    /* Miles per sample */
+       }
+
+       else
+       {
+               c=0;
+               dx=0.0;
+               dy=0.0;
+               path_length=0.0;
+               miles_per_sample=0.0;
+               total_distance=0.0;
 
-       path_length=sqrt((x*x)+(y*y));          /* Total number of samples */
+               lat1=lat1/DEG2RAD;
+               lon1=lon1/DEG2RAD;
 
-       increment=total_distance/path_length;   /* Miles per sample */
+               path.lat[c]=lat1;
+               path.lon[c]=lon1;
+               path.elevation[c]=GetElevation(source);
+               path.distance[c]=0.0;
+       }
 
-       for (distance=0, c=0; (distance<=total_distance && c<ARRAYSIZE); distance+=increment, c++)
+       for (distance=0.0, c=0; (total_distance!=0.0 && distance<=total_distance && c<ARRAYSIZE); c++, distance=miles_per_sample*(double)c)
        {
                beta=distance/3959.0;
                lat2=asin(sin(lat1)*cos(beta)+cos(azimuth)*sin(beta)*cos(lat1));
@@ -488,10 +611,10 @@ void ReadPath(struct site source, struct site destination)
                        lon2=lon1+PI;
 
                else if (azimuth==HALFPI && (beta>HALFPI+lat1))
-                       lon2=lon1+PI;
+                               lon2=lon1+PI;
 
                else if (fabs(num/den)>1.0)
-                       lon2=lon1;
+                               lon2=lon1;
 
                else
                {
@@ -507,8 +630,8 @@ void ReadPath(struct site source, struct site destination)
                while (lon2>TWOPI)
                        lon2-=TWOPI;
  
-               lat2=lat2/deg2rad;
-               lon2=lon2/deg2rad;
+               lat2=lat2/DEG2RAD;
+               lon2=lon2/DEG2RAD;
 
                path.lat[c]=lat2;
                path.lon[c]=lon2;
@@ -574,7 +697,7 @@ double ElevationAngle2(struct site source, struct site destination, double er)
        {
                distance=5280.0*path.distance[x];
 
-               test_alt=earthradius+path.elevation[x];
+               test_alt=earthradius+(path.elevation[x]==0.0?path.elevation[x]:path.elevation[x]+clutter);
 
                cos_test_angle=((source_alt2)+(distance*distance)-(test_alt*test_alt))/(2.0*source_alt*distance);
 
@@ -586,10 +709,10 @@ double ElevationAngle2(struct site source, struct site destination, double er)
                   what it would be if the angles themselves
                   were compared. */
 
-               if (cos_xmtr_angle>cos_test_angle)
+               if (cos_xmtr_angle>=cos_test_angle)
                {
                        block=1;
-                       first_obstruction_angle=((acos(cos_test_angle))/deg2rad)-90.0;
+                       first_obstruction_angle=((acos(cos_test_angle))/DEG2RAD)-90.0;
                }
        }
 
@@ -597,7 +720,7 @@ double ElevationAngle2(struct site source, struct site destination, double er)
                elevation=first_obstruction_angle;
 
        else
-               elevation=((acos(cos_xmtr_angle))/deg2rad)-90.0;
+               elevation=((acos(cos_xmtr_angle))/DEG2RAD)-90.0;
 
        path=temp;
 
@@ -618,15 +741,15 @@ double AverageTerrain(struct site source, double azimuthx, double start_distance
        double  beta, lat1, lon1, lat2, lon2, num, den, azimuth, terrain=0.0;
        struct  site destination;
 
-       lat1=source.lat*deg2rad;
-       lon1=source.lon*deg2rad;
+       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;
+       azimuth=DEG2RAD*azimuthx;
 
        lat2=asin(sin(lat1)*cos(beta)+cos(azimuth)*sin(beta)*cos(lat1));
        num=cos(beta)-(sin(lat1)*sin(lat2));
@@ -636,10 +759,10 @@ double AverageTerrain(struct site source, double azimuthx, double start_distance
                lon2=lon1+PI;
 
        else if (azimuth==HALFPI && (beta>HALFPI+lat1))
-               lon2=lon1+PI;
+                       lon2=lon1+PI;
 
        else if (fabs(num/den)>1.0)
-               lon2=lon1;
+                       lon2=lon1;
 
        else
        {
@@ -655,8 +778,8 @@ double AverageTerrain(struct site source, double azimuthx, double start_distance
        while (lon2>TWOPI)
                lon2-=TWOPI;
  
-       lat2=lat2/deg2rad;
-       lon2=lon2/deg2rad;
+       lat2=lat2/DEG2RAD;
+       lon2=lon2/DEG2RAD;
 
        destination.lat=lat2;
        destination.lon=lon2;
@@ -684,7 +807,7 @@ double AverageTerrain(struct site source, double azimuthx, double start_distance
                {
                        if (path.distance[c]>=start_distance)
                        {
-                               terrain+=path.elevation[c];
+                               terrain+=(path.elevation[c]==0.0?path.elevation[c]:path.elevation[c]+clutter);
                                samples++;
                        }
                }
@@ -737,27 +860,6 @@ double haat(struct site antenna)
        }
 }
 
-float LonDiff(float lon1, float lon2)
-{
-       /* This function returns the short path longitudinal
-          difference between longitude1 and longitude2 
-          as an angle between -180.0 and +180.0 degrees.
-          If lon1 is west of lon2, the result is positive.
-          If lon1 is east of lon2, the result is negative. */
-
-       float diff;
-
-       diff=lon1-lon2;
-
-       if (diff<=-180.0)
-               diff+=360.0;
-
-       if (diff>=180.0)
-               diff-=360.0;
-
-       return diff;
-}
-
 void PlaceMarker(struct site location)
 {
        /* This function places text and marker data in the mask array
@@ -775,29 +877,30 @@ void PlaceMarker(struct site location)
        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;
+       xmin=(double)min_north;
+       xmax=(double)max_north;
+       ymin=(double)min_west;
+       ymax=(double)max_west;
        lat=location.lat;
        lon=location.lon;
 
-       if (lat<xmax && lat>xmin && (LonDiff(lon,ymax)<0.0) && (LonDiff(lon,ymin)>0.0))
+       if (lat<xmax && lat>=xmin && (LonDiff(lon,ymax)<=0.0) && (LonDiff(lon,ymin)>=dpp))
        {
-               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;
+               p1=1.0/ppd;
+               p3=3.0/ppd;
+               p6=6.0/ppd;
+               p8=8.0/ppd;
+               p12=12.0/ppd;
+               p16=16.0/ppd;
+               p24=24.0/ppd;
+
                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; (LonDiff(y,ymax)<=0.0) && (LonDiff(y,ymin)>=0.0) && (LonDiff(y,lon+p3)<=0.0); y+=p1)
+               for (a=0, x=lat-p3; (x<=xmax && x>=xmin && a<7); x+=p1, a++)
+                       for (b=0, y=lon-p3; (LonDiff(y,ymax)<=0.0) && (LonDiff(y,ymin)>=dpp) && b<7; y+=p1, b++)
                                occupied|=(GetMask(x,y)&2);
 
                if (occupied==0)
@@ -809,7 +912,7 @@ void PlaceMarker(struct site location)
 
                        label_length=p1*(double)(strlen(location.name)<<3);
 
-                       if ((LonDiff(lon+label_length,ymax)<=0.0) && (LonDiff(lon-label_length,ymin)>=0.0))
+                       if ((LonDiff(lon+label_length,ymax)<=0.0) && (LonDiff(lon-label_length,ymin)>=dpp))
                        {
                                /* Default: Centered Text */
 
@@ -874,7 +977,7 @@ void PlaceMarker(struct site location)
 
                        if (ok2print==0)
                        {
-                               if (LonDiff(lon-label_length,ymin)>=0.0)
+                               if (LonDiff(lon-label_length,ymin)>=dpp)
                                {
                                        /* Position Text To The
                                           Right Of The Marker */
@@ -945,8 +1048,8 @@ void PlaceMarker(struct site location)
 
                                x=textx;
                                y=texty;
-
-                               for (a=0; a<16 && ok2print; a++)
+                               
+                               for (a=0; a<16; a++)
                                {
                                        for (b=0; b<(int)strlen(location.name); b++)
                                        {
@@ -963,9 +1066,9 @@ void PlaceMarker(struct site location)
        
                                /* Draw Square Marker Centered
                                   On Location Specified */
-       
-                               for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
-                                       for (y=lon-p3; (LonDiff(y,ymax)<=0.0) && (LonDiff(y,ymin)>=0.0) && (LonDiff(y,lon+p3)<=0.0); y+=p1)
+
+                               for (a=0, x=lat-p3; (x<=xmax && x>=xmin && a<7); x+=p1, a++)
+                                       for (b=0, y=lon-p3; (LonDiff(y,ymax)<=0.0) && (LonDiff(y,ymin)>=dpp) && b<7; y+=p1, b++)
                                                OrMask(x,y,2);
                        }
                }
@@ -1015,11 +1118,13 @@ double ReadBearing(char *input)
        if (b==0)  /* Decimal Format (40.139722) */
                sscanf(string,"%lf",&bearing);
 
-       if (b==2)  /* Degree, Minute, Second Format (40 08 23) */
+       if (b==2)  /* Degree, Minute, Second Format (40 08 23.xx) */
        {
                sscanf(string,"%d %d %lf",&degrees, &minutes, &seconds);
 
-               bearing=(double)abs(degrees)+((double)abs(minutes)/60)+(fabs(seconds)/3600);
+               bearing=fabs((double)degrees);
+               bearing+=fabs(((double)minutes)/60.0);
+               bearing+=fabs(seconds/3600.0);
 
                if ((degrees<0) || (minutes<0) || (seconds<0.0))
                        bearing=-bearing;
@@ -1044,18 +1149,20 @@ struct site LoadQTH(char *filename)
           case meters is assumed, and is handled accordingly. */
 
        int     x;
-       char    string[50], qthfile[255];
+       char    string[50], qthfile[255], *s=NULL;
        struct  site tempsite;
        FILE    *fd=NULL;
 
-       for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
-               qthfile[x]=filename[x];
+       x=strlen(filename);
+       strncpy(qthfile, filename, 254);
+
+       if (qthfile[x-3]!='q' || qthfile[x-2]!='t' || qthfile[x-1]!='h')
+       {
+               if (x>249)
+                       qthfile[249]=0;
 
-       qthfile[x]='.';
-       qthfile[x+1]='q';
-       qthfile[x+2]='t';
-       qthfile[x+3]='h';
-       qthfile[x+4]=0;
+               strncat(qthfile,".qth\0",5);
+       }
 
        tempsite.lat=91.0;
        tempsite.lon=361.0;
@@ -1068,7 +1175,7 @@ struct site LoadQTH(char *filename)
        if (fd!=NULL)
        {
                /* Site Name */
-               fgets(string,49,fd);
+               s=fgets(string,49,fd);
 
                /* Strip <CR> and/or <LF> from end of site name */
 
@@ -1077,18 +1184,18 @@ struct site LoadQTH(char *filename)
                tempsite.name[x]=0;
 
                /* Site Latitude */
-               fgets(string,49,fd);
+               s=fgets(string,49,fd);
                tempsite.lat=ReadBearing(string);
 
                /* Site Longitude */
-               fgets(string,49,fd);
+               s=fgets(string,49,fd);
                tempsite.lon=ReadBearing(string);
 
                if (tempsite.lon<0.0)
                        tempsite.lon+=360.0;
 
                /* Antenna Height */
-               fgets(string,49,fd);
+               s=fgets(string,49,fd);
                fclose(fd);
 
                /* Remove <CR> and/or <LF> from antenna height string */
@@ -1133,7 +1240,7 @@ void LoadPAT(char *filename)
           loaded SPLAT! .lrp files.  */
 
        int     a, b, w, x, y, z, last_index, next_index, span;
-       char    string[255], azfile[255], elfile[255], *pointer=NULL;
+       char    string[255], azfile[255], elfile[255], *pointer=NULL, *s=NULL;
        float   az, xx, elevation, amplitude, rotation, valid1, valid2,
                delta, azimuth[361], azimuth_pattern[361], el_pattern[10001],
                elevation_pattern[361][1001], slant_angle[361], tilt,
@@ -1181,7 +1288,7 @@ void LoadPAT(char *filename)
                   in degrees measured clockwise
                   from true North. */
 
-               fgets(string,254,fd);
+               s=fgets(string,254,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -1194,7 +1301,7 @@ void LoadPAT(char *filename)
                   normalized field radiation pattern amplitude
                   (0.0 to 1.0) until EOF is reached. */
 
-               fgets(string,254,fd);
+               s=fgets(string,254,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -1212,7 +1319,7 @@ void LoadPAT(char *filename)
                                read_count[x]++;
                        }
 
-                       fgets(string,254,fd);
+                       s=fgets(string,254,fd);
                        pointer=strchr(string,';');
 
                        if (pointer!=NULL)
@@ -1315,7 +1422,7 @@ void LoadPAT(char *filename)
                   tilt azimuth in degrees measured
                   clockwise from true North. */  
 
-               fgets(string,254,fd);
+               s=fgets(string,254,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -1327,7 +1434,7 @@ void LoadPAT(char *filename)
                   normalized field radiation pattern amplitude
                   (0.0 to 1.0) until EOF is reached. */
 
-               fgets(string,254,fd);
+               s=fgets(string,254,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -1349,7 +1456,7 @@ void LoadPAT(char *filename)
                                read_count[x]++;
                        }
 
-                       fgets(string,254,fd);
+                       s=fgets(string,254,fd);
                        pointer=strchr(string,';');
 
                        if (pointer!=NULL)
@@ -1502,7 +1609,7 @@ int LoadSDF_SDF(char *name)
 
        int     x, y, data, indx, minlat, minlon, maxlat, maxlon;
        char    found, free_page=0, line[20], sdf_file[255],
-               path_plus_name[255];
+               path_plus_name[255], *s=NULL;
        FILE    *fd;
 
        for (x=0; name[x]!='.' && name[x]!=0 && x<250; x++)
@@ -1563,22 +1670,22 @@ int LoadSDF_SDF(char *name)
                        fprintf(stdout,"Loading \"%s\" into page %d...",path_plus_name,indx+1);
                        fflush(stdout);
 
-                       fgets(line,19,fd);
+                       s=fgets(line,19,fd);
                        sscanf(line,"%d",&dem[indx].max_west);
 
-                       fgets(line,19,fd);
+                       s=fgets(line,19,fd);
                        sscanf(line,"%d",&dem[indx].min_north);
 
-                       fgets(line,19,fd);
+                       s=fgets(line,19,fd);
                        sscanf(line,"%d",&dem[indx].min_west);
 
-                       fgets(line,19,fd);
+                       s=fgets(line,19,fd);
                        sscanf(line,"%d",&dem[indx].max_north);
 
-                       for (x=0; x<1200; x++)
-                               for (y=0; y<1200; y++)
+                       for (x=0; x<ippd; x++)
+                               for (y=0; y<ippd; y++)
                                {
-                                       fgets(line,19,fd);
+                                       s=fgets(line,19,fd);
                                        data=atoi(line);
 
                                        dem[indx].data[x][y]=data;
@@ -1604,13 +1711,13 @@ int LoadSDF_SDF(char *name)
                                max_north=dem[indx].max_north;
 
                        else if (dem[indx].max_north>max_north)
-                               max_north=dem[indx].max_north;
+                                       max_north=dem[indx].max_north;
 
                        if (min_north==90)
                                min_north=dem[indx].min_north;
 
                        else if (dem[indx].min_north<min_north)
-                               min_north=dem[indx].min_north;
+                                       min_north=dem[indx].min_north;
 
                        if (max_west==-1)
                                max_west=dem[indx].max_west;
@@ -1635,7 +1742,7 @@ int LoadSDF_SDF(char *name)
 
                        else
                        {
-                               if (abs(dem[indx].min_west-min_west)<180)
+                               if (fabs(dem[indx].min_west-min_west)<180.0)
                                {
                                        if (dem[indx].min_west<min_west)
                                                min_west=dem[indx].min_west;
@@ -1650,6 +1757,7 @@ int LoadSDF_SDF(char *name)
 
                        fprintf(stdout," Done!\n");
                        fflush(stdout);
+
                        return 1;
                }
 
@@ -1801,8 +1909,8 @@ int LoadSDF_BZ(char *name)
                        sscanf(BZfgets(bzfd,255),"%d",&dem[indx].min_west);
                        sscanf(BZfgets(bzfd,255),"%d",&dem[indx].max_north);
        
-                       for (x=0; x<1200; x++)
-                               for (y=0; y<1200; y++)
+                       for (x=0; x<ippd; x++)
+                               for (y=0; y<ippd; y++)
                                {
                                        string=BZfgets(bzfd,20);
                                        data=atoi(string);
@@ -1832,13 +1940,13 @@ int LoadSDF_BZ(char *name)
                                max_north=dem[indx].max_north;
 
                        else if (dem[indx].max_north>max_north)
-                               max_north=dem[indx].max_north;
+                                       max_north=dem[indx].max_north;
 
                        if (min_north==90)
                                min_north=dem[indx].min_north;
 
                        else if (dem[indx].min_north<min_north)
-                               min_north=dem[indx].min_north;
+                                       min_north=dem[indx].min_north;
 
                        if (max_west==-1)
                                max_west=dem[indx].max_west;
@@ -1878,6 +1986,7 @@ int LoadSDF_BZ(char *name)
 
                        fprintf(stdout," Done!\n");
                        fflush(stdout);
+
                        return 1;
                }
 
@@ -1952,8 +2061,8 @@ char LoadSDF(char *name)
 
                        /* Fill DEM with sea-level topography */
 
-                       for (x=0; x<1200; x++)
-                               for (y=0; y<1200; y++)
+                       for (x=0; x<ippd; x++)
+                               for (y=0; y<ippd; y++)
                                {
                                        dem[indx].data[x][y]=0;
                                        dem[indx].signal[x][y]=0;
@@ -1973,13 +2082,13 @@ char LoadSDF(char *name)
                                max_north=dem[indx].max_north;
 
                        else if (dem[indx].max_north>max_north)
-                               max_north=dem[indx].max_north;
+                                       max_north=dem[indx].max_north;
 
                        if (min_north==90)
                                min_north=dem[indx].min_north;
 
                        else if (dem[indx].min_north<min_north)
-                               min_north=dem[indx].min_north;
+                                       min_north=dem[indx].min_north;
 
                        if (max_west==-1)
                                max_west=dem[indx].max_west;
@@ -2034,7 +2143,7 @@ void LoadCities(char *filename)
           read on topographic maps generated by SPLAT! */
 
        int     x, y, z;
-       char    input[80], str[3][80];
+       char    input[80], str[3][80], *s=NULL;
        struct  site city_site;
        FILE    *fd=NULL;
 
@@ -2042,7 +2151,7 @@ void LoadCities(char *filename)
 
        if (fd!=NULL)
        {
-               fgets(input,78,fd);
+               s=fgets(input,78,fd);
 
                fprintf(stdout,"\nReading \"%s\"... ",filename);
                fflush(stdout);
@@ -2077,7 +2186,7 @@ void LoadCities(char *filename)
 
                        PlaceMarker(city_site);
 
-                       fgets(input,78,fd);
+                       s=fgets(input,78,fd);
                }
 
                fclose(fd);
@@ -2086,7 +2195,7 @@ void LoadCities(char *filename)
        }
 
        else
-               fprintf(stderr,"*** ERROR: \"%s\": not found!\n",filename);
+               fprintf(stderr,"\n*** ERROR: \"%s\": not found!",filename);
 }
 
 void LoadUDT(char *filename)
@@ -2099,14 +2208,12 @@ void LoadUDT(char *filename)
           are added to the ground elevations described by the digital
           elevation data already loaded into memory. */
 
-       int     i, x, y, z, fd=0;
-       char    input[80], str[3][80], tempname[15], *pointer=NULL;
-       double  latitude, longitude, height, templat, templon,
-               tempheight, one_pixel;
+       int     i, x, y, z, ypix, xpix, tempxpix, tempypix, fd=0, n=0;
+       char    input[80], str[3][80], tempname[15], *pointer=NULL, *s=NULL;
+       double  latitude, longitude, height, tempheight;
        FILE    *fd1=NULL, *fd2=NULL;
 
        strcpy(tempname,"/tmp/XXXXXX\0");
-       one_pixel=1.0/1200.0;
 
        fd1=fopen(filename,"r");
 
@@ -2115,7 +2222,7 @@ void LoadUDT(char *filename)
                fd=mkstemp(tempname);
                fd2=fopen(tempname,"w");
 
-               fgets(input,78,fd1);
+               s=fgets(input,78,fd1);
 
                pointer=strchr(input,';');
 
@@ -2175,13 +2282,13 @@ void LoadUDT(char *filename)
                        else
                        {
                                str[2][i]=0;
-                               height=rint(3.28084*atof(str[2]));
+                               height=rint(METERS_PER_FOOT*atof(str[2]));
                        }
 
                        if (height>0.0)
-                               fprintf(fd2,"%f, %f, %f\n",latitude, longitude, height);
+                               fprintf(fd2,"%d, %d, %f\n",(int)rint(latitude/dpp), (int)rint(longitude/dpp), height);
 
-                       fgets(input,78,fd1);
+                       s=fgets(input,78,fd1);
 
                        pointer=strchr(input,';');
 
@@ -2199,28 +2306,44 @@ void LoadUDT(char *filename)
                fd1=fopen(tempname,"r");
                fd2=fopen(tempname,"r");
 
-               fscanf(fd1,"%lf, %lf, %lf", &latitude, &longitude, &height);
+               y=0;
+
+               n=fscanf(fd1,"%d, %d, %lf", &xpix, &ypix, &height);
 
-               for (y=0; feof(fd1)==0; y++)
+               do
                {
-                       rewind(fd2);
+                       x=0;
+                       z=0;
 
-                       fscanf(fd2,"%lf, %lf, %lf", &templat, &templon, &tempheight);
+                       n=fscanf(fd2,"%d, %d, %lf", &tempxpix, &tempypix, &tempheight);
 
-                       for (x=0, z=0; feof(fd2)==0; x++)
+                       do
                        {
-                               if (x>y)
-                                       if (fabs(latitude-templat)<=one_pixel && fabs(longitude-templon)<=one_pixel)
-                                               z=1;
+                               if (x>y && xpix==tempxpix && ypix==tempypix)
+                               {
+                                               z=1;  /* Dupe! */
 
-                               fscanf(fd2,"%lf, %lf, %lf", &templat, &templon, &tempheight);
-                       }
+                                               if (tempheight>height)
+                                                       height=tempheight;
+                               }
 
-                       if (z==0)
-                               AddElevation(latitude, longitude, height);
+                               else
+                               {
+                                       n=fscanf(fd2,"%d, %d, %lf", &tempxpix, &tempypix, &tempheight);
+                                       x++;
+                               }
 
-                       fscanf(fd1,"%lf, %lf, %lf", &latitude, &longitude, &height);
-               }
+                       } while (feof(fd2)==0 && z==0);
+
+                       if (z==0)  /* No duplicate found */
+                               AddElevation(xpix*dpp, ypix*dpp, height);
+
+                       n=fscanf(fd1,"%d, %d, %lf", &xpix, &ypix, &height);
+                       y++;
+
+                       rewind(fd2);
+
+               } while (feof(fd1)==0);
 
                fclose(fd1);
                fclose(fd2);
@@ -2229,6 +2352,8 @@ void LoadUDT(char *filename)
 
        else
                fprintf(stderr,"\n*** ERROR: \"%s\": not found!",filename);
+
+       fprintf(stdout,"\n");
 }
 
 void LoadBoundaries(char *filename)
@@ -2241,7 +2366,7 @@ void LoadBoundaries(char *filename)
 
        int     x;
        double  lat0, lon0, lat1, lon1;
-       char    string[80];
+       char    string[80], *s=NULL;
        struct  site source, destination;
        FILE    *fd=NULL;
 
@@ -2249,28 +2374,25 @@ void LoadBoundaries(char *filename)
 
        if (fd!=NULL)
        {
-               fgets(string,78,fd);
+               s=fgets(string,78,fd);
 
                fprintf(stdout,"\nReading \"%s\"... ",filename);
                fflush(stdout);
 
                do
                {
-                       fgets(string,78,fd);
+                       s=fgets(string,78,fd);
                        sscanf(string,"%lf %lf", &lon0, &lat0);
-                       fgets(string,78,fd);
+                       s=fgets(string,78,fd);
 
                        do
                        {
                                sscanf(string,"%lf %lf", &lon1, &lat1);
 
-                               lon0=fabs(lon0);
-                               lon1=fabs(lon1);
-
                                source.lat=lat0;
-                               source.lon=lon0;
+                               source.lon=(lon0>0.0 ? 360.0-lon0 : -lon0);
                                destination.lat=lat1;
-                               destination.lon=lon1;
+                               destination.lon=(lon1>0.0 ? 360.0-lon1 : -lon1);
 
                                ReadPath(source,destination);
 
@@ -2280,11 +2402,11 @@ void LoadBoundaries(char *filename)
                                lat0=lat1;
                                lon0=lon1;
 
-                               fgets(string,78,fd);
+                               s=fgets(string,78,fd);
 
                        } while (strncmp(string,"END",3)!=0 && feof(fd)==0);
 
-                       fgets(string,78,fd);
+                       s=fgets(string,78,fd);
 
                } while (strncmp(string,"END",3)!=0 && feof(fd)==0);
 
@@ -2310,7 +2432,7 @@ char ReadLRParm(struct site txsite, char forced_read)
           "splat.lrp". */
 
        double  din;
-       char    filename[255], string[80], *pointer=NULL, return_value=0;
+       char    filename[255], string[80], *pointer=NULL, *s=NULL, return_value=0;
        int     iin, ok=0, x;
        FILE    *fd=NULL, *outfile=NULL;
 
@@ -2349,7 +2471,7 @@ char ReadLRParm(struct site txsite, char forced_read)
 
        if (fd!=NULL)
        {
-               fgets(string,80,fd);
+               s=fgets(string,80,fd);
 
                pointer=strchr(string,';');
 
@@ -2362,7 +2484,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.eps_dielect=din;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2376,7 +2498,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.sgm_conductivity=din;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2390,7 +2512,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.eno_ns_surfref=din;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2404,7 +2526,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.frq_mhz=din;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2418,7 +2540,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.radio_climate=iin;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2432,7 +2554,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.pol=iin;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2446,7 +2568,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                {
                        LR.conf=din;
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
 
                        pointer=strchr(string,';');
 
@@ -2471,6 +2593,15 @@ char ReadLRParm(struct site txsite, char forced_read)
 
                                if (sscanf(string,"%lf", &din))
                                        LR.erp=din;
+
+                               /* ERP in SPLAT! is referenced to 1 Watt
+                                  into a dipole (0 dBd).  If ERP is
+                                  expressed in dBm (referenced to a
+                                  0 dBi radiator), convert dBm in EIRP
+                                  to ERP.  */
+
+                               if ((strstr(string, "dBm")!=NULL) || (strstr(string,"dbm")!=NULL))
+                                       LR.erp=(pow(10.0,(LR.erp-32.14)/10.0));
                        }
                }
 
@@ -2479,6 +2610,9 @@ char ReadLRParm(struct site txsite, char forced_read)
                if (forced_erp!=-1.0)
                        LR.erp=forced_erp;
 
+               if (forced_freq>=20.0 && forced_freq<=20000.0)
+                       LR.frq_mhz=forced_freq;
+
                if (ok)
                        LoadPAT(filename);
        } 
@@ -2510,7 +2644,7 @@ char ReadLRParm(struct site txsite, char forced_read)
                fprintf(outfile,"%d\t; Polarization (0 = Horizontal, 1 = Vertical)\n", LR.pol);
                fprintf(outfile,"%.2f\t; Fraction of situations\n",LR.conf);
                fprintf(outfile,"%.2f\t; Fraction of time\n",LR.rel);
-               fprintf(outfile,"%.2f\t; Transmitter Effective Radiated Power in Watts (optional)\n",LR.erp);
+               fprintf(outfile,"%.2f\t; Transmitter Effective Radiated Power in Watts or dBm (optional)\n",LR.erp);
                fprintf(outfile,"\nPlease consult SPLAT! documentation for the meaning and use of this data.\n");
 
                fclose(outfile);
@@ -2521,7 +2655,7 @@ char ReadLRParm(struct site txsite, char forced_read)
        }
 
        else if (forced_read==0)
-               return_value=0;
+                       return_value=0;
 
        if (forced_read && (fd==NULL || ok==0))
        {
@@ -2580,7 +2714,7 @@ void PlotPath(struct site source, struct site destination, char mask_value)
                        for (x=y, block=0; x>=0 && block==0; x--)
                        {
                                distance=5280.0*(path.distance[y]-path.distance[x]);
-                               test_alt=earthradius+path.elevation[x];
+                               test_alt=earthradius+(path.elevation[x]==0.0?path.elevation[x]:path.elevation[x]+clutter);
 
                                cos_test_angle=((rx_alt*rx_alt)+(distance*distance)-(test_alt*test_alt))/(2.0*rx_alt*distance);
 
@@ -2591,7 +2725,7 @@ void PlotPath(struct site source, struct site destination, char mask_value)
                                   statement is reversed from what it would
                                   be if the actual angles were compared. */
 
-                               if (cos_xmtr_angle>cos_test_angle)
+                               if (cos_xmtr_angle>=cos_test_angle)
                                        block=1;
                        }
 
@@ -2613,17 +2747,22 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
                xmtr_alt, dest_alt, xmtr_alt2, dest_alt2,
                cos_rcvr_angle, cos_test_angle=0.0, test_alt,
                elevation=0.0, distance=0.0, four_thirds_earth,
-               field_strength=0.0;
+               field_strength=0.0, rxp, dBm;
        struct  site temp;
 
        ReadPath(source,destination);
 
-       four_thirds_earth=EARTHRADIUS*(4.0/3.0);
+       four_thirds_earth=FOUR_THIRDS*EARTHRADIUS;
 
-       /* Copy elevations along path into the elev_l[] array. */
+       /* Copy elevations plus clutter along path into the elev[] array. */
 
-       for (x=0; x<path.length; x++)
-               elev_l[x+2]=path.elevation[x]*METERS_PER_FOOT;
+       for (x=1; x<path.length-1; x++)
+               elev[x+2]=(path.elevation[x]==0.0?path.elevation[x]*METERS_PER_FOOT:(clutter+path.elevation[x])*METERS_PER_FOOT);
+
+       /* Copy ending points without clutter */
+
+       elev[2]=path.elevation[0]*METERS_PER_FOOT;
+       elev[path.length+1]=path.elevation[path.length-1]*METERS_PER_FOOT;
 
        /* Since the only energy the Longley-Rice model considers
           reaching the destination is based on what is scattered
@@ -2633,9 +2772,7 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
           using a 4/3rds Earth radius to match the model used by
           Longley-Rice.  This information is required for properly
           integrating the antenna's elevation pattern into the
-          calculation for overall path loss.  (Using path.length-1
-          below avoids a Longley-Rice model error from occuring at
-          the destination point.) */
+          calculation for overall path loss. */
 
        for (y=2; (y<(path.length-1) && path.distance[y]<=max_range); y++)
        {
@@ -2665,13 +2802,13 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
                        {
                                /* Determine the elevation angle to the first obstruction
                                   along the path IF elevation pattern data is available
-                                  or an output (.plo) file has been designated. */
+                                  or an output (.ano) file has been designated. */
 
                                for (x=2, block=0; (x<y && block==0); x++)
                                {
                                        distance=5280.0*path.distance[x];
 
-                                       test_alt=four_thirds_earth+path.elevation[x];
+                                       test_alt=four_thirds_earth+(path.elevation[x]==0.0?path.elevation[x]:path.elevation[x]+clutter);
 
                                        /* Calculate the cosine of the elevation
                                           angle of the terrain (test point)
@@ -2693,14 +2830,14 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
                                           what it would be if the angles themselves
                                           were compared. */
 
-                                       if (cos_rcvr_angle>cos_test_angle)
+                                       if (cos_rcvr_angle>=cos_test_angle)
                                                block=1;
                                }
 
                                if (block)
-                                       elevation=((acos(cos_test_angle))/deg2rad)-90.0;
+                                       elevation=((acos(cos_test_angle))/DEG2RAD)-90.0;
                                else
-                                       elevation=((acos(cos_rcvr_angle))/deg2rad)-90.0;
+                                       elevation=((acos(cos_rcvr_angle))/DEG2RAD)-90.0;
                        }
 
                        /* Determine attenuation for each point along the
@@ -2709,12 +2846,13 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
                           shortest distance terrain can play a role in
                           path loss. */
  
-                       elev_l[0]=y-1;  /* (number of points - 1) */
+                       elev[0]=y-1;  /* (number of points - 1) */
 
                        /* Distance between elevation samples */
-                       elev_l[1]=METERS_PER_MILE*(path.distance[y]-path.distance[y-1]);
 
-                       point_to_point(elev_l,source.alt*METERS_PER_FOOT, 
+                       elev[1]=METERS_PER_MILE*(path.distance[y]-path.distance[y-1]);
+
+                       point_to_point(elev,source.alt*METERS_PER_FOOT, 
                        destination.alt*METERS_PER_FOOT, LR.eps_dielect,
                        LR.sgm_conductivity, LR.eno_ns_surfref, LR.frq_mhz,
                        LR.radio_climate, LR.pol, LR.conf, LR.rel, loss,
@@ -2725,10 +2863,15 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
 
                        azimuth=(Azimuth(source,temp));
 
-                       /* Write path loss data to output file */
-
                        if (fd!=NULL)
-                               fprintf(fd,"%.7f, %.7f, %.3f, %.3f, %.2f",path.lat[y], path.lon[y], azimuth, elevation, loss);
+                               fprintf(fd,"%.7f, %.7f, %.3f, %.3f, ",path.lat[y], path.lon[y], azimuth, elevation);
+
+                       /* If ERP==0, write path loss to alphanumeric
+                          output file.  Otherwise, write field strength
+                          or received power level (below), as appropriate. */
+
+                       if (fd!=NULL && LR.erp==0.0)
+                               fprintf(fd,"%.2f",loss);
 
                        /* Integrate the antenna's radiation
                           pattern into the overall path loss. */
@@ -2745,33 +2888,62 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
                                {
                                        pattern=20.0*log10(pattern);
                                        loss-=pattern;
-
-                                       if (fd!=NULL && (got_elevation_pattern || got_azimuth_pattern))
-                                               fprintf(fd,", %.2f",loss);
                                }
                        }
 
                        if (LR.erp!=0.0)
                        {
-                               field_strength=(137.26+(20.0*log10(LR.frq_mhz))-loss)+(10.0*log10(LR.erp/1000.0));
+                               if (dbm)
+                               {
+                                       /* dBm is based on EIRP (ERP + 2.14) */
 
-                               ifs=100+(int)rint(field_strength);
+                                       rxp=LR.erp/(pow(10.0,(loss-2.14)/10.0));
 
-                               if (ifs<0)
-                                       ifs=0;
+                                       dBm=10.0*(log10(rxp*1000.0));
 
-                               if (ifs>255)
-                                       ifs=255;
+                                       if (fd!=NULL)
+                                               fprintf(fd,"%.3f",dBm);
 
-                               ofs=GetSignal(path.lat[y],path.lon[y]);
+                                       /* Scale roughly between 0 and 255 */
 
-                               if (ofs>ifs)
-                                       ifs=ofs;
+                                       ifs=200+(int)rint(dBm);
 
-                               PutSignal(path.lat[y],path.lon[y],(unsigned char)ifs);
-               
-                               if (fd!=NULL)
-                                       fprintf(fd,", %.3f",field_strength);
+                                       if (ifs<0)
+                                               ifs=0;
+
+                                       if (ifs>255)
+                                               ifs=255;
+
+                                       ofs=GetSignal(path.lat[y],path.lon[y]);
+
+                                       if (ofs>ifs)
+                                               ifs=ofs;
+
+                                       PutSignal(path.lat[y],path.lon[y],(unsigned char)ifs);
+                               }
+
+                               else
+                               {
+                                       field_strength=(139.4+(20.0*log10(LR.frq_mhz))-loss)+(10.0*log10(LR.erp/1000.0));
+
+                                       ifs=100+(int)rint(field_strength);
+
+                                       if (ifs<0)
+                                               ifs=0;
+
+                                       if (ifs>255)
+                                               ifs=255;
+
+                                       ofs=GetSignal(path.lat[y],path.lon[y]);
+
+                                       if (ofs>ifs)
+                                               ifs=ofs;
+
+                                       PutSignal(path.lat[y],path.lon[y],(unsigned char)ifs);
+       
+                                       if (fd!=NULL)
+                                               fprintf(fd,"%.3f",field_strength);
+                               }
                        }
 
                        else
@@ -2797,14 +2969,14 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
                                fprintf(fd,"\n");
                        }
 
-                       /* Mark this point as being analyzed */
+                       /* Mark this point as having been analyzed */
 
-                       PutMask(path.lat[y],path.lon[y],(GetMask(path.lat[y],path.lon[y])&7)+mask_value<<3);
+                       PutMask(path.lat[y],path.lon[y],(GetMask(path.lat[y],path.lon[y])&7)+(mask_value<<3));
                }
        }
 }
 
-void PlotCoverage(struct site source, double altitude)
+void PlotLOSMap(struct site source, double altitude)
 {
        /* This function performs a 360 degree sweep around the
           transmitter site (source location), and plots the
@@ -2815,13 +2987,11 @@ void PlotCoverage(struct site source, double altitude)
           of a topographic map when the WritePPM() function
           is later invoked. */
 
-       float lat, lon, one_pixel;
-       static unsigned char mask_value=1;
-       int z, count;
+       int y, z, count;
        struct site edge;
        unsigned char symbol[4], x;
-
-       one_pixel=1.0/1200.0;
+       double lat, lon, minwest, maxnorth, th;
+       static unsigned char mask_value=1;
 
        symbol[0]='.';
        symbol[1]='o';
@@ -2830,15 +3000,25 @@ void PlotCoverage(struct site source, double altitude)
 
        count=0;        
 
-       fprintf(stdout,"\n\nComputing line-of-sight coverage of \"%s\" with an RX antenna\nat %.2f %s AGL...\n\n 0%c to  25%c ",source.name,metric?altitude*METERS_PER_FOOT:altitude,metric?"meters":"feet",37,37);
+       fprintf(stdout,"\nComputing line-of-sight coverage of \"%s\" with an RX antenna\nat %.2f %s AGL",source.name,metric?altitude*METERS_PER_FOOT:altitude,metric?"meters":"feet");
+
+       if (clutter>0.0)
+               fprintf(stdout," and %.2f %s of ground clutter",metric?clutter*METERS_PER_FOOT:clutter,metric?"meters":"feet");
+
+       fprintf(stdout,"...\n\n 0%c to  25%c ",37,37);
        fflush(stdout);
 
-       /* 18.75=1200 pixels/degree divided by 64 loops
-          per progress indicator symbol (.oOo) printed. */
+       /* th=pixels/degree divided by 64 loops per
+          progress indicator symbol (.oOo) printed. */
+       
+       th=ppd/64.0;
+
+       z=(int)(th*ReduceAngle(max_west-min_west));
 
-       z=(int)(18.75*ReduceAngle(max_west-min_west));
+       minwest=dpp+(double)min_west;
+       maxnorth=(double)max_north-dpp;
 
-       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
+       for (lon=minwest, x=0, y=0; (LonDiff(lon,(double)max_west)<=0.0); y++, lon=minwest+(dpp*(double)y))
        {
                if (lon>=360.0)
                        lon-=360.0;
@@ -2867,9 +3047,9 @@ void PlotCoverage(struct site source, double altitude)
        fprintf(stdout,"\n25%c to  50%c ",37,37);
        fflush(stdout);
        
-       z=(int)(18.75*(max_north-min_north));
+       z=(int)(th*(double)(max_north-min_north));
 
-       for (lat=max_north, x=0; lat>=min_north; lat-=one_pixel)
+       for (lat=maxnorth, x=0, y=0; lat>=(double)min_north; y++, lat=maxnorth-(dpp*(double)y))
        {
                edge.lat=lat;
                edge.lon=min_west;
@@ -2895,9 +3075,9 @@ void PlotCoverage(struct site source, double altitude)
        fprintf(stdout,"\n50%c to  75%c ",37,37);
        fflush(stdout);
 
-       z=(int)(18.75*ReduceAngle(max_west-min_west));
+       z=(int)(th*ReduceAngle(max_west-min_west));
 
-       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
+       for (lon=minwest, x=0, y=0; (LonDiff(lon,(double)max_west)<=0.0); y++, lon=minwest+(dpp*(double)y))
        {
                if (lon>=360.0)
                        lon-=360.0;
@@ -2926,9 +3106,9 @@ void PlotCoverage(struct site source, double altitude)
        fprintf(stdout,"\n75%c to 100%c ",37,37);
        fflush(stdout);
        
-       z=(int)(18.75*(max_north-min_north));
+       z=(int)(th*(double)(max_north-min_north));
 
-       for (lat=min_north, x=0; lat<=max_north; lat+=one_pixel)
+       for (lat=(double)min_north, x=0, y=0; lat<(double)max_north; y++, lat=(double)min_north+(dpp*(double)y))
        {
                edge.lat=lat;
                edge.lon=max_west;
@@ -2981,14 +3161,15 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
           of a topographic map when the WritePPMLR() or
           WritePPMSS() functions are later invoked. */
 
-       int z, count;
+       int y, z, count;
        struct site edge;
-       float lat, lon, one_pixel;
+       double lat, lon, minwest, maxnorth, th;
        unsigned char x, symbol[4];
        static unsigned char mask_value=1;
        FILE *fd=NULL;
 
-       one_pixel=1.0/1200.0;
+       minwest=dpp+(double)min_west;
+       maxnorth=(double)max_north-dpp;
 
        symbol[0]='.';
        symbol[1]='o';
@@ -2997,9 +3178,24 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
 
        count=0;
 
-       fprintf(stdout,"\n\nComputing Longley-Rice contours of \"%s\" ", source.name);
+       fprintf(stdout,"\nComputing Longley-Rice ");
+
+       if (LR.erp==0.0)
+               fprintf(stdout,"path loss");
+       else
+       {
+               if (dbm)
+                       fprintf(stdout,"signal power level");
+               else
+                       fprintf(stdout,"field strength");
+       }
+       fprintf(stdout," contours of \"%s\"\nout to a radius of %.2f %s with an RX antenna at %.2f %s AGL",source.name,metric?max_range*KM_PER_MILE:max_range,metric?"kilometers":"miles",metric?altitude*METERS_PER_FOOT:altitude,metric?"meters":"feet");
+
+       if (clutter>0.0)
+               fprintf(stdout,"\nand %.2f %s of ground clutter",metric?clutter*METERS_PER_FOOT:clutter,metric?"meters":"feet");
 
-       fprintf(stdout,"out to a radius\nof %.2f %s with an RX antenna at %.2f %s AGL...\n\n 0%c to  25%c ",metric?max_range*KM_PER_MILE:max_range,metric?"kilometers":"miles",metric?altitude*METERS_PER_FOOT:altitude,metric?"meters":"feet",37,37);
+       fprintf(stdout,"...\n\n 0%c to  25%c ",37,37);
        fflush(stdout);
 
        if (plo_filename[0]!=0)
@@ -3012,12 +3208,14 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
                fprintf(fd,"%d, %d\t; max_west, min_west\n%d, %d\t; max_north, min_north\n",max_west, min_west, max_north, min_north);
        }
 
-       /* 18.75=1200 pixels/degree divided by 64 loops
-          per progress indicator symbol (.oOo) printed. */
+       /* th=pixels/degree divided by 64 loops per
+          progress indicator symbol (.oOo) printed. */
+       
+       th=ppd/64.0;
 
-       z=(int)(18.75*ReduceAngle(max_west-min_west));
+       z=(int)(th*ReduceAngle(max_west-min_west));
 
-       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
+       for (lon=minwest, x=0, y=0; (LonDiff(lon,(double)max_west)<=0.0); y++, lon=minwest+(dpp*(double)y))
        {
                if (lon>=360.0)
                        lon-=360.0;
@@ -3046,9 +3244,9 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
        fprintf(stdout,"\n25%c to  50%c ",37,37);
        fflush(stdout);
        
-       z=(int)(18.75*(max_north-min_north));
+       z=(int)(th*(double)(max_north-min_north));
 
-       for (lat=max_north, x=0; lat>=min_north; lat-=one_pixel)
+       for (lat=maxnorth, x=0, y=0; lat>=(double)min_north; y++, lat=maxnorth-(dpp*(double)y))
        {
                edge.lat=lat;
                edge.lon=min_west;
@@ -3074,9 +3272,9 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
        fprintf(stdout,"\n50%c to  75%c ",37,37);
        fflush(stdout);
 
-       z=(int)(18.75*ReduceAngle(max_west-min_west));
+       z=(int)(th*ReduceAngle(max_west-min_west));
 
-       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
+       for (lon=minwest, x=0, y=0; (LonDiff(lon,(double)max_west)<=0.0); y++, lon=minwest+(dpp*(double)y))
        {
                if (lon>=360.0)
                        lon-=360.0;
@@ -3105,9 +3303,9 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
        fprintf(stdout,"\n75%c to 100%c ",37,37);
        fflush(stdout);
        
-       z=(int)(18.75*(max_north-min_north));
+       z=(int)(th*(double)(max_north-min_north));
 
-       for (lat=min_north, x=0; lat<=max_north; lat+=one_pixel)
+       for (lat=(double)min_north, x=0, y=0; lat<(double)max_north; y++, lat=(double)min_north+(dpp*(double)y))
        {
                edge.lat=lat;
                edge.lon=max_west;
@@ -3142,7 +3340,7 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
 void LoadSignalColors(struct site xmtr)
 {
        int x, y, ok, val[4];
-       char filename[255], string[80], *pointer=NULL;
+       char filename[255], string[80], *pointer=NULL, *s=NULL;
        FILE *fd=NULL;
 
        for (x=0; xmtr.filename[x]!='.' && xmtr.filename[x]!=0 && x<250; x++)
@@ -3251,7 +3449,7 @@ void LoadSignalColors(struct site xmtr)
        else
        {
                x=0;
-               fgets(string,80,fd);
+               s=fgets(string,80,fd);
 
                while (x<32 && feof(fd)==0)
                {
@@ -3280,7 +3478,7 @@ void LoadSignalColors(struct site xmtr)
                                x++;
                        }
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
                }
 
                fclose(fd);
@@ -3291,7 +3489,7 @@ void LoadSignalColors(struct site xmtr)
 void LoadLossColors(struct site xmtr)
 {
        int x, y, ok, val[4];
-       char filename[255], string[80], *pointer=NULL;
+       char filename[255], string[80], *pointer=NULL, *s=NULL;
        FILE *fd=NULL;
 
        for (x=0; xmtr.filename[x]!='.' && xmtr.filename[x]!=0 && x<250; x++)
@@ -3415,7 +3613,7 @@ void LoadLossColors(struct site xmtr)
        else
        {
                x=0;
-               fgets(string,80,fd);
+               s=fgets(string,80,fd);
 
                while (x<32 && feof(fd)==0)
                {
@@ -3444,7 +3642,7 @@ void LoadLossColors(struct site xmtr)
                                x++;
                        }
 
-                       fgets(string,80,fd);
+                       s=fgets(string,80,fd);
                }
 
                fclose(fd);
@@ -3452,54 +3650,246 @@ void LoadLossColors(struct site xmtr)
        }
 }
 
-void WritePPM(char *filename, unsigned char geo, unsigned char kml, unsigned char ngs)
+void LoadDBMColors(struct site xmtr)
 {
-       /* 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 x, y, ok, val[4];
+       char filename[255], string[80], *pointer=NULL, *s=NULL;
+       FILE *fd=NULL;
 
-       char mapfile[255], geofile[255], kmlfile[255];
-       unsigned char found, mask;
-       unsigned width, height, terrain;
-       int indx, x, y, x0=0, y0=0;
-       double lat, lon, one_pixel, conversion, one_over_gamma;  /* USED to be float... */
-       FILE *fd;
+       for (x=0; xmtr.filename[x]!='.' && xmtr.filename[x]!=0 && x<250; x++)
+               filename[x]=xmtr.filename[x];
 
-       one_pixel=1.0/1200.0;
-       one_over_gamma=1.0/GAMMA;
-       conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
+       filename[x]='.';
+       filename[x+1]='d';
+       filename[x+2]='c';
+       filename[x+3]='f';
+       filename[x+4]=0;
 
-       width=(unsigned)(1200*ReduceAngle(max_west-min_west));
-       height=(unsigned)(1200*ReduceAngle(max_north-min_north));
+       /* Default values */
 
-       if (filename[0]==0)
-               strncpy(filename, "map.ppm\0",8);
+       region.level[0]=0;
+       region.color[0][0]=255;
+       region.color[0][1]=0;
+       region.color[0][2]=0;
 
-       for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
-       {
-               mapfile[x]=filename[x];
-               geofile[x]=filename[x];
-               kmlfile[x]=filename[x];
-       }
+       region.level[1]=-10;
+       region.color[1][0]=255;
+       region.color[1][1]=128;
+       region.color[1][2]=0;
 
-       mapfile[x]='.';
-       geofile[x]='.';
-       kmlfile[x]='.';
-       mapfile[x+1]='p';
-       geofile[x+1]='g';
-       kmlfile[x+1]='k';
-       mapfile[x+2]='p';
-       geofile[x+2]='e';
-       kmlfile[x+2]='m';
-       mapfile[x+3]='m';
-       geofile[x+3]='o';
-       kmlfile[x+3]='l';
-       mapfile[x+4]=0;
-       geofile[x+4]=0;
-       kmlfile[x+4]=0;
+       region.level[2]=-20;
+       region.color[2][0]=255;
+       region.color[2][1]=165;
+       region.color[2][2]=0;
+
+       region.level[3]=-30;
+       region.color[3][0]=255;
+       region.color[3][1]=206;
+       region.color[3][2]=0;
+
+       region.level[4]=-40;
+       region.color[4][0]=255;
+       region.color[4][1]=255;
+       region.color[4][2]=0;
+
+       region.level[5]=-50;
+       region.color[5][0]=184;
+       region.color[5][1]=255;
+       region.color[5][2]=0;
+
+       region.level[6]=-60;
+       region.color[6][0]=0;
+       region.color[6][1]=255;
+       region.color[6][2]=0;
+
+       region.level[7]=-70;
+       region.color[7][0]=0;
+       region.color[7][1]=208;
+       region.color[7][2]=0;
+
+       region.level[8]=-80;
+       region.color[8][0]=0;
+       region.color[8][1]=196;
+       region.color[8][2]=196;
+
+       region.level[9]=-90;
+       region.color[9][0]=0;
+       region.color[9][1]=148;
+       region.color[9][2]=255;
+
+       region.level[10]=-100;
+       region.color[10][0]=80;
+       region.color[10][1]=80;
+       region.color[10][2]=255;
+
+       region.level[11]=-110;
+       region.color[11][0]=0;
+       region.color[11][1]=38;
+       region.color[11][2]=255;
+
+       region.level[12]=-120;
+       region.color[12][0]=142;
+       region.color[12][1]=63;
+       region.color[12][2]=255;
+
+       region.level[13]=-130;
+       region.color[13][0]=196;
+       region.color[13][1]=54;
+       region.color[13][2]=255;
+
+       region.level[14]=-140;
+       region.color[14][0]=255;
+       region.color[14][1]=0;
+       region.color[14][2]=255;
+
+       region.level[15]=-150;
+       region.color[15][0]=255;
+       region.color[15][1]=194;
+       region.color[15][2]=204;
+
+       region.levels=16;
+
+       fd=fopen("splat.dcf","r");
+
+       if (fd==NULL)
+               fd=fopen(filename,"r");
+
+       if (fd==NULL)
+       {
+               fd=fopen(filename,"w");
+
+               fprintf(fd,"; SPLAT! Auto-generated DBM Signal Level Color Definition (\"%s\") File\n",filename);
+               fprintf(fd,";\n; Format for the parameters held in this file is as follows:\n;\n");
+               fprintf(fd,";    dBm: red, green, blue\n;\n");
+               fprintf(fd,"; ...where \"dBm\" is the received signal power level between +40 dBm\n");
+               fprintf(fd,"; and -200 dBm, and \"red\", \"green\", and \"blue\" are the corresponding\n");
+               fprintf(fd,"; RGB color definitions ranging from 0 to 255 for the region specified.\n");
+               fprintf(fd,";\n; The following parameters may be edited and/or expanded\n");
+               fprintf(fd,"; for future runs of SPLAT!  A total of 32 contour regions\n");
+               fprintf(fd,"; may be defined in this file.\n;\n;\n");
+
+               for (x=0; x<region.levels; x++)
+                       fprintf(fd,"%+4d: %3d, %3d, %3d\n",region.level[x], region.color[x][0], region.color[x][1], region.color[x][2]);
+
+               fclose(fd);
+       }
+
+       else
+       {
+               x=0;
+               s=fgets(string,80,fd);
+
+               while (x<32 && feof(fd)==0)
+               {
+                       pointer=strchr(string,';');
+
+                       if (pointer!=NULL)
+                               *pointer=0;
+
+                       ok=sscanf(string,"%d: %d, %d, %d", &val[0], &val[1], &val[2], &val[3]);
+
+                       if (ok==4)
+                       {
+                               if (val[0]<-200)
+                                       val[0]=-200;
+
+                               if (val[0]>+40)
+                                       val[0]=+40;
+
+                               region.level[x]=val[0];
+
+                               for (y=1; y<4; y++)
+                               {
+                                       if (val[y]>255)
+                                               val[y]=255;
+
+                                       if (val[y]<0)
+                                               val[y]=0;
+                               }
+       
+                               region.color[x][0]=val[1];
+                               region.color[x][1]=val[2];
+                               region.color[x][2]=val[3];
+                               x++;
+                       }
+
+                       s=fgets(string,80,fd);
+               }
+
+               fclose(fd);
+               region.levels=x;
+       }
+}
+
+void WritePPM(char *filename, unsigned char geo, unsigned char kml, unsigned char ngs, struct site *xmtr, unsigned char txsites)
+{
+       /* 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. */
+
+       char mapfile[255], geofile[255], kmlfile[255];
+       unsigned char found, mask;
+       unsigned width, height, terrain;
+       int indx, x, y, x0=0, y0=0;
+       double lat, lon, conversion, one_over_gamma,
+       north, south, east, west, minwest;
+       FILE *fd;
+
+       one_over_gamma=1.0/GAMMA;
+       conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
+
+       width=(unsigned)(ippd*ReduceAngle(max_west-min_west));
+       height=(unsigned)(ippd*ReduceAngle(max_north-min_north));
+
+       if (filename[0]==0)
+       {
+               strncpy(filename, xmtr[0].filename,254);
+               filename[strlen(filename)-4]=0;  /* Remove .qth */
+       }
+
+       y=strlen(filename);
+
+       if (y>4)
+       {
+               if (filename[y-1]=='m' && filename[y-2]=='p' && filename[y-3]=='p' && filename[y-4]=='.')
+                       y-=4;
+       }
+
+       for (x=0; x<y; x++)
+       {
+               mapfile[x]=filename[x];
+               geofile[x]=filename[x];
+               kmlfile[x]=filename[x];
+       }
+
+       mapfile[x]='.';
+       geofile[x]='.';
+       kmlfile[x]='.';
+       mapfile[x+1]='p';
+       geofile[x+1]='g';
+       kmlfile[x+1]='k';
+       mapfile[x+2]='p';
+       geofile[x+2]='e';
+       kmlfile[x+2]='m';
+       mapfile[x+3]='m';
+       geofile[x+3]='o';
+       kmlfile[x+3]='l';
+       mapfile[x+4]=0;
+       geofile[x+4]=0;
+       kmlfile[x+4]=0;
+
+       minwest=((double)min_west)+dpp;
+
+       if (minwest>360.0)
+               minwest-=360.0;
+
+       north=(double)max_north-dpp;
+       south=(double)min_north;
+       east=(minwest<180.0?-minwest:360.0-min_west);
+       west=(double)(max_west<180?-max_west:360-max_west);
 
        if (kml==0 && geo)
        {
@@ -3507,10 +3897,10 @@ void WritePPM(char *filename, unsigned char geo, unsigned char kml, unsigned cha
 
                fprintf(fd,"FILENAME\t%s\n",mapfile);
                fprintf(fd,"#\t\tX\tY\tLong\t\tLat\n");
-               fprintf(fd,"TIEPOINT\t0\t0\t%d.000\t\t%d.000\n",(max_west<180?-max_west:360-max_west),max_north);
-               fprintf(fd,"TIEPOINT\t%u\t%u\t%d.000\t\t%d.000\n",width-1,height-1,(min_west<180?-min_west:360-min_west),min_north);
+               fprintf(fd,"TIEPOINT\t0\t0\t%.3f\t\t%.3f\n",west,north);
+               fprintf(fd,"TIEPOINT\t%u\t%u\t%.3f\t\t%.3f\n",width-1,height-1,east,south);
                fprintf(fd,"IMAGESIZE\t%u\t%u\n",width,height);
-               fprintf(fd,"#\n# Auto Generated by SPLAT! v%s\n#\n",splat_version);
+               fprintf(fd,"#\n# Auto Generated by %s v%s\n#\n",splat_name,splat_version);
 
                fclose(fd);
        }
@@ -3522,23 +3912,50 @@ void WritePPM(char *filename, unsigned char geo, unsigned char kml, unsigned cha
                fprintf(fd,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                fprintf(fd,"<kml xmlns=\"http://earth.google.com/kml/2.1\">\n");
                fprintf(fd,"  <Folder>\n");
-               fprintf(fd,"   <name>SPLAT!</name>\n");
+               fprintf(fd,"   <name>%s</name>\n",splat_name);
                fprintf(fd,"     <description>Line-of-Sight Overlay</description>\n");
                fprintf(fd,"       <GroundOverlay>\n");
-               fprintf(fd,"         <name>SPLAT! Line-of-Sight Overlay</name>\n");
+               fprintf(fd,"         <name>%s Line-of-Sight Overlay</name>\n",splat_name);
                fprintf(fd,"           <description>SPLAT! Coverage</description>\n");
                fprintf(fd,"            <Icon>\n");
                fprintf(fd,"              <href>%s</href>\n",mapfile);
                fprintf(fd,"            </Icon>\n");
                fprintf(fd,"            <opacity>128</opacity>\n");
                fprintf(fd,"            <LatLonBox>\n");
-               fprintf(fd,"               <north>%.5f</north>\n",(double)max_north-one_pixel);
-               fprintf(fd,"               <south>%.5f</south>\n",(double)min_north);
-               fprintf(fd,"               <east>%.5f</east>\n",((double)min_west<180.0?(double)-min_west:360.0-(double)min_west));
-               fprintf(fd,"               <west>%.5f</west>\n",(((double)max_west-one_pixel)<180.0?-((double)max_west-one_pixel):(360.0-(double)max_west-one_pixel)));
+               fprintf(fd,"               <north>%.5f</north>\n",north);
+               fprintf(fd,"               <south>%.5f</south>\n",south);
+               fprintf(fd,"               <east>%.5f</east>\n",east);
+               fprintf(fd,"               <west>%.5f</west>\n",west);
                fprintf(fd,"               <rotation>0.0</rotation>\n");
                fprintf(fd,"            </LatLonBox>\n");
                fprintf(fd,"       </GroundOverlay>\n");
+
+               for (x=0; x<txsites; x++)
+               {
+                       fprintf(fd,"     <Placemark>\n");
+                       fprintf(fd,"       <name>%s</name>\n",xmtr[x].name);
+                       fprintf(fd,"       <visibility>1</visibility>\n");
+                       fprintf(fd,"       <Style>\n");
+                       fprintf(fd,"       <IconStyle>\n");
+                       fprintf(fd,"        <Icon>\n");
+                       fprintf(fd,"          <href>root://icons/palette-5.png</href>\n");
+                       fprintf(fd,"          <x>224</x>\n");
+                       fprintf(fd,"          <y>224</y>\n");
+                       fprintf(fd,"          <w>32</w>\n");
+                       fprintf(fd,"          <h>32</h>\n");
+                       fprintf(fd,"        </Icon>\n");
+                       fprintf(fd,"       </IconStyle>\n");
+                       fprintf(fd,"       </Style>\n");
+                       fprintf(fd,"      <Point>\n");
+                       fprintf(fd,"        <extrude>1</extrude>\n");
+                       fprintf(fd,"        <altitudeMode>relativeToGround</altitudeMode>\n");
+                       fprintf(fd,"        <coordinates>%f,%f,%f</coordinates>\n",(xmtr[x].lon<180.0?-xmtr[x].lon:360.0-xmtr[x].lon), xmtr[x].lat, xmtr[x].alt);
+                       fprintf(fd,"      </Point>\n");
+                       fprintf(fd,"     </Placemark>\n");
+               }
+
+
+
                fprintf(fd,"  </Folder>\n");
                fprintf(fd,"</kml>\n");
 
@@ -3551,24 +3968,26 @@ void WritePPM(char *filename, unsigned char geo, unsigned char kml, unsigned cha
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height);
        fflush(stdout);
 
-       for (y=0, lat=(double)max_north-one_pixel; y<(int)height; y++, lat=(double)max_north-(one_pixel*(double)y))
+       for (y=0, lat=north; y<(int)height; y++, lat=north-(dpp*(double)y))
        {
-               for (x=0, lon=(double)max_west-one_pixel; x<(int)width; x++, lon=(double)max_west-(one_pixel*(double)x))
+               for (x=0, lon=max_west; x<(int)width; x++, lon=(double)max_west-(dpp*(double)x))
                {
                        if (lon<0.0)
                                lon+=360.0;
 
                        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-                               if (lat>=(double)dem[indx].min_north && lat<(double)dem[indx].max_north && LonDiff(lon,(double)dem[indx].min_west)>=0.0 && LonDiff(lon,(double)dem[indx].max_west)<0.0)
+                       {
+                               x0=(int)rint(ppd*(lat-(double)dem[indx].min_north));
+                               y0=mpi-(int)rint(ppd*(LonDiff((double)dem[indx].max_west,lon)));
+
+                               if (x0>=0 && x0<=mpi && y0>=0 && y0<=mpi)
                                        found=1;
                                else
                                        indx++;
+                       }
 
                        if (found)
                        {
-                               x0=(int)(1199.0*(lat-floor(lat)));
-                               y0=(int)(1199.0*(lon-floor(lon)));
-
                                mask=dem[indx].mask[x0][y0];
 
                                if (mask&2)
@@ -3697,27 +4116,38 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
           90 degrees from its representation in dem[][] so that north
           points up and east points right in the image generated. */
 
-       char mapfile[255], geofile[255], kmlfile[255], color=0;
+       char mapfile[255], geofile[255], kmlfile[255];
        unsigned width, height, red, green, blue, terrain=0;
        unsigned char found, mask, cityorcounty;
        int indx, x, y, z, colorwidth, x0, y0, loss, level,
            hundreds, tens, units, match;
-       double lat, lon, one_pixel, conversion, one_over_gamma;
+       double lat, lon, conversion, one_over_gamma,
+       north, south, east, west, minwest;
        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=(unsigned)(1200*ReduceAngle(max_west-min_west));
-       height=(unsigned)(1200*ReduceAngle(max_north-min_north));
+       width=(unsigned)(ippd*ReduceAngle(max_west-min_west));
+       height=(unsigned)(ippd*ReduceAngle(max_north-min_north));
 
        LoadLossColors(xmtr[0]);
 
        if (filename[0]==0)
+       {
                strncpy(filename, xmtr[0].filename,254);
+               filename[strlen(filename)-4]=0;  /* Remove .qth */
+       }
 
-       for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
+       y=strlen(filename);
+
+       if (y>4)
+       {
+               if (filename[y-1]=='m' && filename[y-2]=='p' && filename[y-3]=='p' && filename[y-4]=='.')
+                       y-=4;
+       }
+
+       for (x=0; x<y; x++)
        {
                mapfile[x]=filename[x];
                geofile[x]=filename[x];
@@ -3740,16 +4170,33 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
        geofile[x+4]=0;
        kmlfile[x+4]=0;
 
+       minwest=((double)min_west)+dpp;
+
+       if (minwest>360.0)
+               minwest-=360.0;
+
+       north=(double)max_north-dpp;
+
+       if (kml || geo)
+               south=(double)min_north;        /* No bottom legend */
+       else
+               south=(double)min_north-(30.0/ppd); /* 30 pixels for bottom legend */
+
+       east=(minwest<180.0?-minwest:360.0-min_west);
+       west=(double)(max_west<180?-max_west:360-max_west);
+
        if (kml==0 && geo)
        {
                fd=fopen(geofile,"wb");
 
                fprintf(fd,"FILENAME\t%s\n",mapfile);
                fprintf(fd,"#\t\tX\tY\tLong\t\tLat\n");
-               fprintf(fd,"TIEPOINT\t0\t0\t%d.000\t\t%d.000\n",(max_west<180?-max_west:360-max_west),max_north);
-               fprintf(fd,"TIEPOINT\t%u\t%u\t%d.000\t\t%.3f\n",width-1,height+29,(min_west<180?-min_west:360-min_west),(double)(min_north-0.025));
-               fprintf(fd,"IMAGESIZE\t%u\t%u\n",width,height+30);
-               fprintf(fd,"#\n# Auto Generated by SPLAT! v%s\n#\n",splat_version);
+               fprintf(fd,"TIEPOINT\t0\t0\t%.3f\t\t%.3f\n",west,north);
+
+               fprintf(fd,"TIEPOINT\t%u\t%u\t%.3f\t\t%.3f\n",width-1,height-1,east,south);
+               fprintf(fd,"IMAGESIZE\t%u\t%u\n",width,height);
+
+               fprintf(fd,"#\n# Auto Generated by %s v%s\n#\n",splat_name,splat_version);
 
                fclose(fd);
        }
@@ -3760,9 +4207,9 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
 
                fprintf(fd,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                fprintf(fd,"<kml xmlns=\"http://earth.google.com/kml/2.1\">\n");
-               fprintf(fd,"<!-- Generated by SPLAT! Version %s -->\n",splat_version);
+               fprintf(fd,"<!-- Generated by %s Version %s -->\n",splat_name,splat_version);
                fprintf(fd,"  <Folder>\n");
-               fprintf(fd,"   <name>SPLAT!</name>\n");
+               fprintf(fd,"   <name>%s</name>\n",splat_name);
                fprintf(fd,"     <description>%s Transmitter Path Loss Overlay</description>\n",xmtr[0].name);
                fprintf(fd,"       <GroundOverlay>\n");
                fprintf(fd,"         <name>SPLAT! Path Loss Overlay</name>\n");
@@ -3772,10 +4219,10 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
                fprintf(fd,"            </Icon>\n");
                fprintf(fd,"            <opacity>128</opacity>\n");
                fprintf(fd,"            <LatLonBox>\n");
-               fprintf(fd,"               <north>%.5f</north>\n",(double)max_north-one_pixel);
-               fprintf(fd,"               <south>%.5f</south>\n",(double)min_north);
-               fprintf(fd,"               <east>%.5f</east>\n",((double)min_west<180.0?(double)-min_west:360.0-(double)min_west));
-               fprintf(fd,"               <west>%.5f</west>\n",(((double)max_west-one_pixel)<180.0?-((double)max_west-one_pixel):(360.0-(double)max_west-one_pixel)));
+               fprintf(fd,"               <north>%.5f</north>\n",north);
+               fprintf(fd,"               <south>%.5f</south>\n",south);
+               fprintf(fd,"               <east>%.5f</east>\n",east);
+               fprintf(fd,"               <west>%.5f</west>\n",west);
                fprintf(fd,"               <rotation>0.0</rotation>\n");
                fprintf(fd,"            </LatLonBox>\n");
                fprintf(fd,"       </GroundOverlay>\n");
@@ -3816,24 +4263,26 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,(kml?height:height+30));
        fflush(stdout);
 
-       for (y=0, lat=(double)max_north-one_pixel; y<(int)height; y++, lat=(double)max_north-(one_pixel*(double)y))
+       for (y=0, lat=north; y<(int)height; y++, lat=north-(dpp*(double)y))
        {
-               for (x=0, lon=(double)max_west-one_pixel; x<(int)width; x++, lon=(double)max_west-(one_pixel*(double)x))
+               for (x=0, lon=max_west; x<(int)width; x++, lon=max_west-(dpp*(double)x))
                {
                        if (lon<0.0)
                                lon+=360.0;
 
                        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-                               if (lat>=(double)dem[indx].min_north && lat<(double)dem[indx].max_north && LonDiff(lon,(double)dem[indx].min_west)>=0.0 && LonDiff(lon,(double)dem[indx].max_west)<0.0)
+                       {
+                               x0=(int)rint(ppd*(lat-(double)dem[indx].min_north));
+                               y0=mpi-(int)rint(ppd*(LonDiff((double)dem[indx].max_west,lon)));
+
+                               if (x0>=0 && x0<=mpi && y0>=0 && y0<=mpi)
                                        found=1;
                                else
                                        indx++;
+                       }
 
                        if (found)
                        {
-                               x0=(int)(1199.0*(lat-floor(lat)));
-                               y0=(int)(1199.0*(lon-floor(lon)));
-
                                mask=dem[indx].mask[x0][y0];
                                loss=(dem[indx].signal[x0][y0]);
                                cityorcounty=0;
@@ -3860,11 +4309,9 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
                                        red=region.color[match][0];
                                        green=region.color[match][1];
                                        blue=region.color[match][2];
-
-                                       color=1;
                                }
 
-                               if ((mask&2) && (kml==0))
+                               if (mask&2)
                                {
                                        /* Text Labels: Red or otherwise */
 
@@ -3876,7 +4323,7 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
                                         cityorcounty=1;
                                }
 
-                               else if ((mask&4) && (kml==0))
+                               else if (mask&4)
                                {
                                        /* County Boundaries: Black */
 
@@ -3887,7 +4334,7 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
 
                                if (cityorcounty==0)
                                {
-                                       if (loss>maxdB || loss==0)
+                                       if (loss==0 || (contour_threshold!=0 && loss>abs(contour_threshold)))
                                        {
                                                if (ngs)  /* No terrain */
                                                        fprintf(fd,"%c%c%c",255,255,255);
@@ -3937,9 +4384,11 @@ void WritePPMLR(char *filename, unsigned char geo, unsigned char kml, unsigned c
                }
        }
 
-       if (kml==0 && color)
+       if (kml==0 && geo==0)
        {
-               /* Display legend along bottom of image */
+               /* Display legend along bottom of image
+                * if not generating .kml or .geo output.
+                */
 
                colorwidth=(int)rint((float)width/(float)region.levels);
 
@@ -4019,27 +4468,38 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
           90 degrees from its representation in dem[][] so that north
           points up and east points right in the image generated. */
 
-       char mapfile[255], geofile[255], kmlfile[255], color=0;
+       char mapfile[255], geofile[255], kmlfile[255];
        unsigned width, height, terrain, red, green, blue;
        unsigned char found, mask, cityorcounty;
        int indx, x, y, z=1, x0, y0, signal, level, hundreds,
            tens, units, match, colorwidth;
-       double lat, lon, one_pixel, conversion, one_over_gamma;
+       double conversion, one_over_gamma, lat, lon,
+       north, south, east, west, minwest;
        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=(unsigned)(1200*ReduceAngle(max_west-min_west));
-       height=(unsigned)(1200*ReduceAngle(max_north-min_north));
+       width=(unsigned)(ippd*ReduceAngle(max_west-min_west));
+       height=(unsigned)(ippd*ReduceAngle(max_north-min_north));
 
        LoadSignalColors(xmtr[0]);
 
        if (filename[0]==0)
+       {
                strncpy(filename, xmtr[0].filename,254);
+               filename[strlen(filename)-4]=0;  /* Remove .qth */
+       }
 
-       for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
+       y=strlen(filename);
+
+       if (y>4)
+       {
+               if (filename[y-1]=='m' && filename[y-2]=='p' && filename[y-3]=='p' && filename[y-4]=='.')
+                       y-=4;
+       }
+
+       for (x=0; x<y; x++)
        {
                mapfile[x]=filename[x];
                geofile[x]=filename[x];
@@ -4062,16 +4522,33 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
        geofile[x+4]=0;
        kmlfile[x+4]=0;
 
+       minwest=((double)min_west)+dpp;
+
+       if (minwest>360.0)
+               minwest-=360.0;
+
+       north=(double)max_north-dpp;
+
+       if (kml || geo)
+               south=(double)min_north;        /* No bottom legend */
+       else
+               south=(double)min_north-(30.0/ppd);     /* 30 pixels for bottom legend */
+
+       east=(minwest<180.0?-minwest:360.0-min_west);
+       west=(double)(max_west<180?-max_west:360-max_west);
+
        if (geo && kml==0)
        {
                fd=fopen(geofile,"wb");
 
                fprintf(fd,"FILENAME\t%s\n",mapfile);
                fprintf(fd,"#\t\tX\tY\tLong\t\tLat\n");
-               fprintf(fd,"TIEPOINT\t0\t0\t%d.000\t\t%d.000\n",(max_west<180?-max_west:360-max_west),max_north);
-               fprintf(fd,"TIEPOINT\t%u\t%u\t%d.000\t\t%.3f\n",width-1,height+29,(min_west<180?-min_west:360-min_west),(double)(min_north-0.025));
-               fprintf(fd,"IMAGESIZE\t%u\t%u\n",width,height+30);
-               fprintf(fd,"#\n# Auto Generated by SPLAT! v%s\n#\n",splat_version);
+               fprintf(fd,"TIEPOINT\t0\t0\t%.3f\t\t%.3f\n",west,north);
+
+               fprintf(fd,"TIEPOINT\t%u\t%u\t%.3f\t\t%.3f\n",width-1,height-1,east,south);
+               fprintf(fd,"IMAGESIZE\t%u\t%u\n",width,height);
+
+               fprintf(fd,"#\n# Auto Generated by %s v%s\n#\n",splat_name,splat_version);
 
                fclose(fd);
        }
@@ -4082,9 +4559,9 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
 
                fprintf(fd,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                fprintf(fd,"<kml xmlns=\"http://earth.google.com/kml/2.1\">\n");
-               fprintf(fd,"<!-- Generated by SPLAT! Version %s -->\n",splat_version);
+               fprintf(fd,"<!-- Generated by %s Version %s -->\n",splat_name,splat_version);
                fprintf(fd,"  <Folder>\n");
-               fprintf(fd,"   <name>SPLAT!</name>\n");
+               fprintf(fd,"   <name>%s</name>\n",splat_name);
                fprintf(fd,"     <description>%s Transmitter Coverage Overlay</description>\n",xmtr[0].name);
                fprintf(fd,"       <GroundOverlay>\n");
                fprintf(fd,"         <name>SPLAT! Signal Strength Overlay</name>\n");
@@ -4094,10 +4571,10 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
                fprintf(fd,"            </Icon>\n");
                fprintf(fd,"            <opacity>128</opacity>\n");
                fprintf(fd,"            <LatLonBox>\n");
-               fprintf(fd,"               <north>%.5f</north>\n",(double)max_north-one_pixel);
-               fprintf(fd,"               <south>%.5f</south>\n",(double)min_north);
-               fprintf(fd,"               <east>%.5f</east>\n",((double)min_west<180.0?(double)-min_west:360.0-(double)min_west));
-               fprintf(fd,"               <west>%.5f</west>\n",(((double)max_west-one_pixel)<180.0?-((double)max_west-one_pixel):(360.0-(double)max_west-one_pixel)));
+               fprintf(fd,"               <north>%.5f</north>\n",north);
+               fprintf(fd,"               <south>%.5f</south>\n",south);
+               fprintf(fd,"               <east>%.5f</east>\n",east);
+               fprintf(fd,"               <west>%.5f</west>\n",west);
                fprintf(fd,"               <rotation>0.0</rotation>\n");
                fprintf(fd,"            </LatLonBox>\n");
                fprintf(fd,"       </GroundOverlay>\n");
@@ -4138,24 +4615,26 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,(kml?height:height+30));
        fflush(stdout);
 
-       for (y=0, lat=(double)max_north-one_pixel; y<(int)height; y++, lat=(double)max_north-(one_pixel*(double)y))
+       for (y=0, lat=north; y<(int)height; y++, lat=north-(dpp*(double)y))
        {
-               for (x=0, lon=(double)max_west-one_pixel; x<(int)width; x++, lon=(double)max_west-(one_pixel*(double)x))
+               for (x=0, lon=max_west; x<(int)width; x++, lon=max_west-(dpp*(double)x))
                {
                        if (lon<0.0)
                                lon+=360.0;
 
                        for (indx=0, found=0; indx<MAXPAGES && found==0;)
-                               if (lat>=(double)dem[indx].min_north && lat<(double)dem[indx].max_north && LonDiff(lon,(double)dem[indx].min_west)>=0.0 && LonDiff(lon,(double)dem[indx].max_west)<0.0)
+                       {
+                               x0=(int)rint(ppd*(lat-(double)dem[indx].min_north));
+                               y0=mpi-(int)rint(ppd*(LonDiff((double)dem[indx].max_west,lon)));
+
+                               if (x0>=0 && x0<=mpi && y0>=0 && y0<=mpi)
                                        found=1;
                                else
                                        indx++;
+                       }
 
                        if (found)
                        {
-                               x0=(int)(1199.0*(lat-floor(lat)));
-                               y0=(int)(1199.0*(lon-floor(lon)));
-
                                mask=dem[indx].mask[x0][y0];
                                signal=(dem[indx].signal[x0][y0])-100;
                                cityorcounty=0;
@@ -4182,11 +4661,9 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
                                        red=region.color[match][0];
                                        green=region.color[match][1];
                                        blue=region.color[match][2];
-
-                                       color=1;
                                }
 
-                               if ((mask&2) && (kml==0))
+                               if (mask&2) 
                                {
                                        /* Text Labels: Red or otherwise */
 
@@ -4198,7 +4675,7 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
                                        cityorcounty=1;
                                }
 
-                               else if ((mask&4) && (kml==0))
+                               else if (mask&4)
                                {
                                        /* County Boundaries: Black */
 
@@ -4209,7 +4686,7 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
 
                                if (cityorcounty==0)
                                {
-                                       if (dem[indx].signal[x0][y0]==0)
+                                       if (contour_threshold!=0 && signal<contour_threshold)
                                        {
                                                if (ngs)
                                                        fprintf(fd,"%c%c%c",255,255,255);
@@ -4264,9 +4741,11 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
                }
        }
 
-       if (kml==0 && color)
+       if (kml==0 && geo==0)
        {
-               /* Display legend along bottom of image */
+               /* Display legend along bottom of image
+                * if not generating .kml or .geo output.
+                */
 
                colorwidth=(int)rint((float)width/(float)region.levels);
 
@@ -4319,7 +4798,7 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
                                                        indx=255;
 
                                        if (x>=52 && x<=59)
-                                               if (fontdata[16*('u')+(y0-8)]&(128>>(x-52)))
+                                               if (fontdata[16*(230)+(y0-8)]&(128>>(x-52)))
                                                        indx=255;
 
                                        if (x>=60 && x<=67)
@@ -4354,66 +4833,501 @@ void WritePPMSS(char *filename, unsigned char geo, unsigned char kml, unsigned c
        fflush(stdout);
 }
 
-void GraphTerrain(struct site source, struct site destination, char *name)
+void WritePPMDBM(char *filename, unsigned char geo, unsigned char kml, unsigned char ngs, struct site *xmtr, unsigned char txsites)
 {
-       /* 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, .png is assumed.  */
+       /* This function generates a topographic map in Portable Pix Map
+          (PPM) format based on the signal power level values held in the
+          signal[][] 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     x, y, z;
-       char    filename[255], term[30], ext[15];
-       FILE    *fd=NULL;
+       char mapfile[255], geofile[255], kmlfile[255];
+       unsigned width, height, terrain, red, green, blue;
+       unsigned char found, mask, cityorcounty;
+       int indx, x, y, z=1, x0, y0, dBm, level, hundreds,
+           tens, units, match, colorwidth;
+       double conversion, one_over_gamma, lat, lon,
+       north, south, east, west, minwest;
+       FILE *fd;
+
+       one_over_gamma=1.0/GAMMA;
+       conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
+
+       width=(unsigned)(ippd*ReduceAngle(max_west-min_west));
+       height=(unsigned)(ippd*ReduceAngle(max_north-min_north));
+
+       LoadDBMColors(xmtr[0]);
+
+       if (filename[0]==0)
+       {
+               strncpy(filename, xmtr[0].filename,254);
+               filename[strlen(filename)-4]=0;  /* Remove .qth */
+       }
+
+       y=strlen(filename);
+
+       if (y>4)
+       {
+               if (filename[y-1]=='m' && filename[y-2]=='p' && filename[y-3]=='p' && filename[y-4]=='.')
+                       y-=4;
+       }
+
+       for (x=0; x<y; x++)
+       {
+               mapfile[x]=filename[x];
+               geofile[x]=filename[x];
+               kmlfile[x]=filename[x];
+       }
+
+       mapfile[x]='.';
+       geofile[x]='.';
+       kmlfile[x]='.';
+       mapfile[x+1]='p';
+       geofile[x+1]='g';
+       kmlfile[x+1]='k';
+       mapfile[x+2]='p';
+       geofile[x+2]='e';
+       kmlfile[x+2]='m';
+       mapfile[x+3]='m';
+       geofile[x+3]='o';
+       kmlfile[x+3]='l';
+       mapfile[x+4]=0;
+       geofile[x+4]=0;
+       kmlfile[x+4]=0;
+
+       minwest=((double)min_west)+dpp;
+
+       if (minwest>360.0)
+               minwest-=360.0;
+
+       north=(double)max_north-dpp;
+
+       if (kml || geo)
+               south=(double)min_north;        /* No bottom legend */
+       else
+               south=(double)min_north-(30.0/ppd);     /* 30 pixels for bottom legend */
+
+       east=(minwest<180.0?-minwest:360.0-min_west);
+       west=(double)(max_west<180?-max_west:360-max_west);
+
+       if (geo && kml==0)
+       {
+               fd=fopen(geofile,"wb");
+
+               fprintf(fd,"FILENAME\t%s\n",mapfile);
+               fprintf(fd,"#\t\tX\tY\tLong\t\tLat\n");
+               fprintf(fd,"TIEPOINT\t0\t0\t%.3f\t\t%.3f\n",west,north);
+
+               fprintf(fd,"TIEPOINT\t%u\t%u\t%.3f\t\t%.3f\n",width-1,height-1,east,south);
+               fprintf(fd,"IMAGESIZE\t%u\t%u\n",width,height);
+
+               fprintf(fd,"#\n# Auto Generated by %s v%s\n#\n",splat_name,splat_version);
+
+               fclose(fd);
+       }
+
+       if (kml && geo==0)
+       {
+               fd=fopen(kmlfile,"wb");
+
+               fprintf(fd,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+               fprintf(fd,"<kml xmlns=\"http://earth.google.com/kml/2.1\">\n");
+               fprintf(fd,"<!-- Generated by %s Version %s -->\n",splat_name,splat_version);
+               fprintf(fd,"  <Folder>\n");
+               fprintf(fd,"   <name>%s</name>\n",splat_name);
+               fprintf(fd,"     <description>%s Transmitter Coverage Overlay</description>\n",xmtr[0].name);
+               fprintf(fd,"       <GroundOverlay>\n");
+               fprintf(fd,"         <name>SPLAT! Signal Power Level Overlay</name>\n");
+               fprintf(fd,"           <description>SPLAT! Coverage</description>\n");
+               fprintf(fd,"            <Icon>\n");
+               fprintf(fd,"              <href>%s</href>\n",mapfile);
+               fprintf(fd,"            </Icon>\n");
+               fprintf(fd,"            <opacity>128</opacity>\n");
+               fprintf(fd,"            <LatLonBox>\n");
+               fprintf(fd,"               <north>%.5f</north>\n",north);
+               fprintf(fd,"               <south>%.5f</south>\n",south);
+               fprintf(fd,"               <east>%.5f</east>\n",east);
+               fprintf(fd,"               <west>%.5f</west>\n",west);
+               fprintf(fd,"               <rotation>0.0</rotation>\n");
+               fprintf(fd,"            </LatLonBox>\n");
+               fprintf(fd,"       </GroundOverlay>\n");
+
+               for (x=0; x<txsites; x++)
+               {
+                       fprintf(fd,"     <Placemark>\n");
+                       fprintf(fd,"       <name>%s</name>\n",xmtr[x].name);
+                       fprintf(fd,"       <visibility>1</visibility>\n");
+                       fprintf(fd,"       <Style>\n");
+                       fprintf(fd,"       <IconStyle>\n");
+                       fprintf(fd,"        <Icon>\n");
+                       fprintf(fd,"          <href>root://icons/palette-5.png</href>\n");
+                       fprintf(fd,"          <x>224</x>\n");
+                       fprintf(fd,"          <y>224</y>\n");
+                       fprintf(fd,"          <w>32</w>\n");
+                       fprintf(fd,"          <h>32</h>\n");
+                       fprintf(fd,"        </Icon>\n");
+                       fprintf(fd,"       </IconStyle>\n");
+                       fprintf(fd,"       </Style>\n");
+                       fprintf(fd,"      <Point>\n");
+                       fprintf(fd,"        <extrude>1</extrude>\n");
+                       fprintf(fd,"        <altitudeMode>relativeToGround</altitudeMode>\n");
+                       fprintf(fd,"        <coordinates>%f,%f,%f</coordinates>\n",(xmtr[x].lon<180.0?-xmtr[x].lon:360.0-xmtr[x].lon), xmtr[x].lat, xmtr[x].alt);
+                       fprintf(fd,"      </Point>\n");
+                       fprintf(fd,"     </Placemark>\n");
+               }
+
+               fprintf(fd,"  </Folder>\n");
+               fprintf(fd,"</kml>\n");
+
+               fclose(fd);
+       }
+
+       fd=fopen(mapfile,"wb");
+
+       fprintf(fd,"P6\n%u %u\n255\n",width,(kml?height:height+30));
+       fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,(kml?height:height+30));
+       fflush(stdout);
+
+       for (y=0, lat=north; y<(int)height; y++, lat=north-(dpp*(double)y))
+       {
+               for (x=0, lon=max_west; x<(int)width; x++, lon=max_west-(dpp*(double)x))
+               {
+                       if (lon<0.0)
+                               lon+=360.0;
+
+                       for (indx=0, found=0; indx<MAXPAGES && found==0;)
+                       {
+                               x0=(int)rint(ppd*(lat-(double)dem[indx].min_north));
+                               y0=mpi-(int)rint(ppd*(LonDiff((double)dem[indx].max_west,lon)));
+
+                               if (x0>=0 && x0<=mpi && y0>=0 && y0<=mpi)
+                                       found=1;
+                               else
+                                       indx++;
+                       }
+
+                       if (found)
+                       {
+                               mask=dem[indx].mask[x0][y0];
+                               dBm=(dem[indx].signal[x0][y0])-200;
+                               cityorcounty=0;
+
+                               match=255;
+
+                               red=0;
+                               green=0;
+                               blue=0;
+
+                               if (dBm>=region.level[0])
+                                       match=0;
+                               else
+                               {
+                                       for (z=1; (z<region.levels && match==255); z++)
+                                       {
+                                               if (dBm<region.level[z-1] && dBm>=region.level[z])
+                                                       match=z;
+                                       }
+                               }
+
+                               if (match<region.levels)
+                               {
+                                       red=region.color[match][0];
+                                       green=region.color[match][1];
+                                       blue=region.color[match][2];
+                               }
+
+                               if (mask&2) 
+                               {
+                                       /* Text Labels: Red or otherwise */
+
+                                       if (red>=180 && green<=75 && blue<=75 && dBm!=0)
+                                               fprintf(fd,"%c%c%c",255^red,255^green,255^blue);
+                                       else
+                                               fprintf(fd,"%c%c%c",255,0,0);
+
+                                       cityorcounty=1;
+                               }
+
+                               else if (mask&4)
+                               {
+                                       /* County Boundaries: Black */
+
+                                       fprintf(fd,"%c%c%c",0,0,0);
+
+                                       cityorcounty=1;
+                               }
+
+                               if (cityorcounty==0)
+                               {
+                                       if (contour_threshold!=0 && dBm<contour_threshold)
+                                       {
+                                               if (ngs) /* No terrain */
+                                                       fprintf(fd,"%c%c%c",255,255,255);
+                                               else
+                                               {
+                                                       /* Display land or sea elevation */
+
+                                                       if (dem[indx].data[x0][y0]==0)
+                                                               fprintf(fd,"%c%c%c",0,0,170);
+                                                       else
+                                                       {
+                                                               terrain=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                                               fprintf(fd,"%c%c%c",terrain,terrain,terrain);
+                                                       }
+                                               }
+                                       }
+
+                                       else
+                                       {
+                                               /* Plot signal power level regions in color */
+
+                                               if (red!=0 || green!=0 || blue!=0)
+                                                       fprintf(fd,"%c%c%c",red,green,blue);
+
+                                               else  /* terrain / sea-level */
+                                               {
+                                                       if (ngs)
+                                                               fprintf(fd,"%c%c%c",255,255,255);
+                                                       else
+                                                       {
+                                                               if (dem[indx].data[x0][y0]==0)
+                                                                       fprintf(fd,"%c%c%c",0,0,170);
+                                                               else
+                                                               {
+                                                                       /* Elevation: Greyscale */
+                                                                       terrain=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                                                       fprintf(fd,"%c%c%c",terrain,terrain,terrain);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       else
+                       {
+                               /* We should never get here, but if */
+                               /* we do, display the region as black */
+
+                               fprintf(fd,"%c%c%c",0,0,0);
+                       }
+               }
+       }
+
+       if (kml==0 && geo==0)
+       {
+               /* Display legend along bottom of image
+                  if not generating .kml or .geo output. */
+
+               colorwidth=(int)rint((float)width/(float)region.levels);
+
+               for (y0=0; y0<30; y0++)
+               {
+                       for (x0=0; x0<(int)width; x0++)
+                       {
+                               indx=x0/colorwidth;
+                               x=x0%colorwidth;
+
+                               level=abs(region.level[indx]);
+
+                               hundreds=level/100;
+
+                               if (hundreds>0)
+                                       level-=(hundreds*100);
+
+                               tens=level/10;
+
+                               if (tens>0)
+                                       level-=(tens*10);
+
+                               units=level;
+
+                               if (y0>=8 && y0<=23)
+                               {
+                                       if (hundreds>0)
+                                       {
+                                               if (region.level[indx]<0)
+                                               {
+                                                       if (x>=5 && x<=12)
+                                                               if (fontdata[16*('-')+(y0-8)]&(128>>(x-5)))
+                                                                       indx=255;
+                                               }
+
+                                               else
+                                               {       
+                                                       if (x>=5 && x<=12)
+                                                               if (fontdata[16*('+')+(y0-8)]&(128>>(x-5)))
+                                                                       indx=255;
+                                               }
+
+                                               if (x>=13 && x<=20)     
+                                                       if (fontdata[16*(hundreds+'0')+(y0-8)]&(128>>(x-13)))
+                                                               indx=255; 
+                                       }
+
+                                       if (tens>0 || hundreds>0)
+                                       {
+                                               if (hundreds==0)
+                                               {
+                                                       if (region.level[indx]<0)
+                                                       {
+                                                               if (x>=13 && x<=20)
+                                                                       if (fontdata[16*('-')+(y0-8)]&(128>>(x-13)))
+                                                                               indx=255;
+                                                       }
+
+                                                       else
+                                                       {
+                                                               if (x>=13 && x<=20)
+                                                                       if (fontdata[16*('+')+(y0-8)]&(128>>(x-13)))
+                                                                               indx=255;
+                                                       }
+                                               }
+                                               
+                                               if (x>=21 && x<=28)     
+                                                       if (fontdata[16*(tens+'0')+(y0-8)]&(128>>(x-21)))
+                                                               indx=255;
+                                       }
+
+                                       if (hundreds==0 && tens==0)
+                                       {
+                                               if (region.level[indx]<0)
+                                               {
+                                                       if (x>=21 && x<=28)
+                                                               if (fontdata[16*('-')+(y0-8)]&(128>>(x-21)))
+                                                                       indx=255;
+                                               }
+
+                                               else
+                                               {
+                                                       if (x>=21 && x<=28)
+                                                               if (fontdata[16*('+')+(y0-8)]&(128>>(x-21)))
+                                                                       indx=255;
+                                               }
+                                       }
+
+                                       if (x>=29 && x<=36)
+                                               if (fontdata[16*(units+'0')+(y0-8)]&(128>>(x-29)))
+                                                       indx=255;
+
+                                       if (x>=37 && x<=44)
+                                               if (fontdata[16*('d')+(y0-8)]&(128>>(x-37)))
+                                                       indx=255;
+
+                                       if (x>=45 && x<=52)
+                                               if (fontdata[16*('B')+(y0-8)]&(128>>(x-45)))
+                                                       indx=255;
+
+                                       if (x>=53 && x<=60)
+                                               if (fontdata[16*('m')+(y0-8)]&(128>>(x-53)))
+                                                       indx=255;
+                               }
+
+                               if (indx>region.levels)
+                                       fprintf(fd,"%c%c%c",0,0,0);
+                               else
+                               {
+                                       red=region.color[indx][0];
+                                       green=region.color[indx][1];
+                                       blue=region.color[indx][2];
+
+                                       fprintf(fd,"%c%c%c",red,green,blue);
+                               }
+                       } 
+               }
+       }
+
+       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 when the -p command line option
+          is used.  "basename" 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, .png is assumed.  */
+
+       int     x, y, z;
+       char    basename[255], term[30], ext[15];
+       double  minheight=100000.0, maxheight=-100000.0;
+       FILE    *fd=NULL, *fd1=NULL;
 
        ReadPath(destination,source);
 
        fd=fopen("profile.gp","wb");
 
+       if (clutter>0.0)
+               fd1=fopen("clutter.gp","wb");
+
        for (x=0; x<path.length; x++)
        {
+               if ((path.elevation[x]+clutter)>maxheight)
+                       maxheight=path.elevation[x]+clutter;
+
+               if (path.elevation[x]<minheight)
+                       minheight=path.elevation[x];
+
                if (metric)
+               {
                        fprintf(fd,"%f\t%f\n",KM_PER_MILE*path.distance[x],METERS_PER_FOOT*path.elevation[x]);
+
+                       if (fd1!=NULL && x>0 && x<path.length-2)
+                               fprintf(fd1,"%f\t%f\n",KM_PER_MILE*path.distance[x],METERS_PER_FOOT*(path.elevation[x]==0.0?path.elevation[x]:(path.elevation[x]+clutter)));
+               }
+
                else
+               {
                        fprintf(fd,"%f\t%f\n",path.distance[x],path.elevation[x]);
+
+                       if (fd1!=NULL && x>0 && x<path.length-2)
+                               fprintf(fd1,"%f\t%f\n",path.distance[x],(path.elevation[x]==0.0?path.elevation[x]:(path.elevation[x]+clutter)));
+               }
        }
 
        fclose(fd);
 
-       if (name[0]==0)
+       if (fd1!=NULL)
+               fclose(fd1);
+
+       if (name[0]=='.')
        {
                /* Default filename and output file type */
 
-               strncpy(filename,"profile\0",8);
+               strncpy(basename,"profile\0",8);
                strncpy(term,"png\0",4);
                strncpy(ext,"png\0",4);
        }
 
        else
        {
-               /* Grab extension and terminal type from "name" */
+               /* Extract extension and terminal type from "name" */
 
-               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
-                       filename[x]=name[x];
+               ext[0]=0;
+               y=strlen(name);
+               strncpy(basename,name,254);
 
-               if (name[x]=='.')
+               for (x=y-1; x>0 && name[x]!='.'; x--);
+
+               if (x>0)  /* Extension found */
                {
-                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       for (z=x+1; z<=y && (z-(x+1))<10; z++)
                        {
-                               term[y]=tolower(name[x]);
-                               ext[y]=term[y];
+                               ext[z-(x+1)]=tolower(name[z]);
+                               term[z-(x+1)]=name[z];
                        }
 
-                       ext[y]=0;
-                       term[y]=0;
-                       filename[z]=0;
+                       ext[z-(x+1)]=0;  /* Ensure an ending 0 */
+                       term[z-(x+1)]=0;
+                       basename[x]=0;
                }
 
-               else
-               {       /* No extension -- Default is png */
-
-                       filename[x]=0;
+               if (ext[0]==0)  /* No extension -- Default is png */
+               {
                        strncpy(term,"png\0",4);
                        strncpy(ext,"png\0",4);
                }
@@ -4426,21 +5340,21 @@ void GraphTerrain(struct site source, struct site destination, char *name)
                strncpy(ext,"ps\0",3);
 
        else if (strncmp(ext,"ps",2)==0)
-               strncpy(term,"postscript enhanced color\0",26);
+                       strncpy(term,"postscript enhanced color\0",26);
+
+       minheight-=(0.01*maxheight);
 
        fd=fopen("splat.gp","w");
        fprintf(fd,"set grid\n");
-       fprintf(fd,"set autoscale\n");
+       fprintf(fd,"set yrange [%2.3f to %2.3f]\n", metric?minheight*METERS_PER_FOOT:minheight, metric?maxheight*METERS_PER_FOOT:maxheight);
        fprintf(fd,"set encoding iso_8859_1\n");
        fprintf(fd,"set term %s\n",term);
-       fprintf(fd,"set title \"SPLAT! Terrain Profile Between %s and %s (%.2f%c Azimuth)\"\n",destination.name, source.name, Azimuth(destination,source),176);
+       fprintf(fd,"set title \"%s Terrain Profile Between %s and %s (%.2f%c Azimuth)\"\n",splat_name,destination.name, source.name, Azimuth(destination,source),176);
 
        if (metric)
        {
                fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f kilometers)\"\n",destination.name,source.name,KM_PER_MILE*Distance(source,destination));
                fprintf(fd,"set ylabel \"Ground Elevation Above Sea Level (meters)\"\n");
-
-
        }
 
        else
@@ -4449,18 +5363,32 @@ void GraphTerrain(struct site source, struct site destination, char *name)
                fprintf(fd,"set ylabel \"Ground Elevation Above Sea Level (feet)\"\n");
        }
 
-       fprintf(fd,"set output \"%s.%s\"\n",filename,ext);
-       fprintf(fd,"plot \"profile.gp\" title \"\" with lines\n");
+       fprintf(fd,"set output \"%s.%s\"\n",basename,ext);
+
+       if (clutter>0.0)
+       {
+               if (metric)
+                       fprintf(fd,"plot \"profile.gp\" title \"Terrain Profile\" with lines, \"clutter.gp\" title \"Clutter Profile (%.2f meters)\" with lines\n",clutter*METERS_PER_FOOT);
+               else
+                       fprintf(fd,"plot \"profile.gp\" title \"Terrain Profile\" with lines, \"clutter.gp\" title \"Clutter Profile (%.2f feet)\" with lines\n",clutter);
+       }
+
+       else
+               fprintf(fd,"plot \"profile.gp\" title \"\" with lines\n");
+
        fclose(fd);
                        
        x=system("gnuplot splat.gp");
 
        if (x!=-1)
        {
-               unlink("splat.gp");
-               unlink("profile.gp");
+               if (gpsav==0)
+               {       
+                       unlink("splat.gp");
+                       unlink("profile.gp");
+               }
 
-               fprintf(stdout,"\nTerrain plot written to: \"%s.%s\"",filename,ext);
+               fprintf(stdout,"Terrain plot written to: \"%s.%s\"\n",basename,ext);
                fflush(stdout);
        }
 
@@ -4471,22 +5399,29 @@ void GraphTerrain(struct site source, struct site destination, char *name)
 void GraphElevation(struct site source, struct site destination, char *name)
 {
        /* This function invokes gnuplot to generate an appropriate
-          output file indicating the terrain profile between the source
-          and destination locations.  "filename" is the name assigned
-          to the output file generated by gnuplot.  The filename extension
-          is used to set gnuplot's terminal setting and output file type.
-          If no extension is found, .png is assumed. */
+          output file indicating the terrain elevation profile between
+          the source and destination locations when the -e command line
+          option is used.  "basename" 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, .png is assumed.  */
 
        int     x, y, z;
-       char    filename[255], term[30], ext[15];
-       double  angle, refangle, maxangle=-90.0;
-       struct  site remote;
-       FILE    *fd=NULL, *fd2=NULL;
+       char    basename[255], term[30], ext[15];
+       double  angle, clutter_angle=0.0, refangle, maxangle=-90.0,
+               minangle=90.0, distance;
+       struct  site remote, remote2;
+       FILE    *fd=NULL, *fd1=NULL, *fd2=NULL;
 
        ReadPath(destination,source);  /* destination=RX, source=TX */
        refangle=ElevationAngle(destination,source);
+       distance=Distance(source,destination);
 
        fd=fopen("profile.gp","wb");
+
+       if (clutter>0.0)
+               fd1=fopen("clutter.gp","wb");
+
        fd2=fopen("reference.gp","wb");
 
        for (x=1; x<path.length-1; x++)
@@ -4496,20 +5431,47 @@ void GraphElevation(struct site source, struct site destination, char *name)
                remote.alt=0.0;
                angle=ElevationAngle(destination,remote);
 
+               if (clutter>0.0)
+               {
+                       remote2.lat=path.lat[x];
+                       remote2.lon=path.lon[x];
+
+                       if (path.elevation[x]!=0.0)
+                               remote2.alt=clutter;
+                       else
+                               remote2.alt=0.0;
+
+                       clutter_angle=ElevationAngle(destination,remote2);
+               }
+
                if (metric)
                {
                        fprintf(fd,"%f\t%f\n",KM_PER_MILE*path.distance[x],angle);
+
+                       if (fd1!=NULL)
+                               fprintf(fd1,"%f\t%f\n",KM_PER_MILE*path.distance[x],clutter_angle);
+
                        fprintf(fd2,"%f\t%f\n",KM_PER_MILE*path.distance[x],refangle);
                }
 
                else
                {
                        fprintf(fd,"%f\t%f\n",path.distance[x],angle);
+
+                       if (fd1!=NULL)
+                               fprintf(fd1,"%f\t%f\n",path.distance[x],clutter_angle);
+
                        fprintf(fd2,"%f\t%f\n",path.distance[x],refangle);
                }
 
                if (angle>maxangle)
                        maxangle=angle;
+
+               if (clutter_angle>maxangle)
+                       maxangle=clutter_angle;
+
+               if (angle<minangle)
+                       minangle=angle;
        }
 
        if (metric)
@@ -4525,41 +5487,46 @@ void GraphElevation(struct site source, struct site destination, char *name)
        }
 
        fclose(fd);
+
+       if (fd1!=NULL)
+               fclose(fd1);
+
        fclose(fd2);
 
-       if (name[0]==0)
+       if (name[0]=='.')
        {
                /* Default filename and output file type */
 
-               strncpy(filename,"profile\0",8);
+               strncpy(basename,"profile\0",8);
                strncpy(term,"png\0",4);
                strncpy(ext,"png\0",4);
        }
 
        else
        {
-               /* Grab extension and terminal type from "name" */
+               /* Extract extension and terminal type from "name" */
 
-               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
-                       filename[x]=name[x];
+               ext[0]=0;
+               y=strlen(name);
+               strncpy(basename,name,254);
 
-               if (name[x]=='.')
+               for (x=y-1; x>0 && name[x]!='.'; x--);
+
+               if (x>0)  /* Extension found */
                {
-                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       for (z=x+1; z<=y && (z-(x+1))<10; z++)
                        {
-                               term[y]=tolower(name[x]);
-                               ext[y]=term[y];
+                               ext[z-(x+1)]=tolower(name[z]);
+                               term[z-(x+1)]=name[z];
                        }
 
-                       ext[y]=0;
-                       term[y]=0;
-                       filename[z]=0;
+                       ext[z-(x+1)]=0;  /* Ensure an ending 0 */
+                       term[z-(x+1)]=0;
+                       basename[x]=0;
                }
 
-               else
-               {       /* No extension -- Default is png */
-
-                       filename[x]=0;
+               if (ext[0]==0)  /* No extension -- Default is png */
+               {
                        strncpy(term,"png\0",4);
                        strncpy(ext,"png\0",4);
                }
@@ -4572,25 +5539,40 @@ void GraphElevation(struct site source, struct site destination, char *name)
                strncpy(ext,"ps\0",3);
 
        else if (strncmp(ext,"ps",2)==0)
-               strncpy(term,"postscript enhanced color\0",26);
+                       strncpy(term,"postscript enhanced color\0",26);
 
        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);
+
+       if (distance>2.0)
+               fprintf(fd,"set yrange [%2.3f to %2.3f]\n", (-fabs(refangle)-0.25), maxangle+0.25);
+       else
+               fprintf(fd,"set yrange [%2.3f to %2.3f]\n", minangle, refangle+(-minangle/8.0));
+
        fprintf(fd,"set encoding iso_8859_1\n");
        fprintf(fd,"set term %s\n",term);
-       fprintf(fd,"set title \"SPLAT! Elevation Profile Between %s and %s (%.2f%c azimuth)\"\n",destination.name,source.name,Azimuth(destination,source),176);
+       fprintf(fd,"set title \"%s Elevation Profile Between %s and %s (%.2f%c azimuth)\"\n",splat_name,destination.name,source.name,Azimuth(destination,source),176);
 
        if (metric)
-               fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f kilometers)\"\n",destination.name,source.name,KM_PER_MILE*Distance(source,destination));
+               fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f kilometers)\"\n",destination.name,source.name,KM_PER_MILE*distance);
        else
-               fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f miles)\"\n",destination.name,source.name,Distance(source,destination));
+               fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f miles)\"\n",destination.name,source.name,distance);
 
 
-       fprintf(fd,"set ylabel \"Elevation Angle Along LOS 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 (%.2f%c elevation)\" with lines\n",refangle,176);
+       fprintf(fd,"set ylabel \"Elevation Angle Along LOS Path Between\\n%s and %s (degrees)\"\n",destination.name,source.name);
+       fprintf(fd,"set output \"%s.%s\"\n",basename,ext);
+
+       if (clutter>0.0)
+       {
+               if (metric)
+                       fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"clutter.gp\" title \"Clutter Profile (%.2f meters)\" with lines, \"reference.gp\" title \"Line of Sight Path (%.2f%c elevation)\" with lines\n",clutter*METERS_PER_FOOT,refangle,176);
+               else
+                       fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"clutter.gp\" title \"Clutter Profile (%.2f feet)\" with lines, \"reference.gp\" title \"Line of Sight Path (%.2f%c elevation)\" with lines\n",clutter,refangle,176);
+       }
+
+       else
+               fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"reference.gp\" title \"Line of Sight Path (%.2f%c elevation)\" with lines\n",refangle,176);
 
        fclose(fd);
                        
@@ -4598,11 +5580,17 @@ void GraphElevation(struct site source, struct site destination, char *name)
 
        if (x!=-1)
        {
-               unlink("splat.gp");
-               unlink("profile.gp");
-               unlink("reference.gp"); 
+               if (gpsav==0)
+               {
+                       unlink("splat.gp");
+                       unlink("profile.gp");
+                       unlink("reference.gp");
+
+                       if (clutter>0.0)
+                               unlink("clutter.gp");
+               }       
 
-               fprintf(stdout,"\nElevation plot written to: \"%s.%s\"",filename,ext);
+               fprintf(stdout,"Elevation plot written to: \"%s.%s\"\n",basename,ext);
                fflush(stdout);
        }
 
@@ -4610,25 +5598,27 @@ void GraphElevation(struct site source, struct site destination, char *name)
                fprintf(stderr,"\n*** ERROR: Error occurred invoking gnuplot!\n");
 }
 
-void GraphHeight(struct site source, struct site destination, char *name, double f, unsigned char n)
+void GraphHeight(struct site source, struct site destination, char *name, unsigned char fresnel_plot, unsigned char normalized)
 {
        /* This function invokes gnuplot to generate an appropriate
-          output file indicating the terrain profile between the source
-          and destination locations referenced to the line-of-sight path
-          between the receive 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, .png is assumed. */
+          output file indicating the terrain height profile between
+          the source and destination locations referenced to the
+          line-of-sight path between the receive and transmit sites
+          when the -h or -H command line option is used.  "basename"
+          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,
+          .png is assumed.  */
 
        int     x, y, z;
-       char    filename[255], term[30], ext[15];
+       char    basename[255], term[30], ext[15];
        double  a, b, c, height=0.0, refangle, cangle, maxheight=-100000.0,
                minheight=100000.0, lambda=0.0, f_zone=0.0, fpt6_zone=0.0,
                nm=0.0, nb=0.0, ed=0.0, es=0.0, r=0.0, d=0.0, d1=0.0,
                terrain, azimuth, distance, dheight=0.0, minterrain=100000.0,
                minearth=100000.0, miny, maxy, min2y, max2y;
        struct  site remote;
-       FILE    *fd=NULL, *fd2=NULL, *fd3=NULL, *fd4=NULL, *fd5=NULL;
+       FILE    *fd=NULL, *fd1=NULL, *fd2=NULL, *fd3=NULL, *fd4=NULL, *fd5=NULL;
 
        ReadPath(destination,source);  /* destination=RX, source=TX */
        azimuth=Azimuth(destination,source);
@@ -4638,13 +5628,13 @@ void GraphHeight(struct site source, struct site destination, char *name, double
 
        /* Wavelength and path distance (great circle) in feet. */
 
-       if (f)
+       if (fresnel_plot)
        {
-               lambda=9.8425e8/(f*1e6);
+               lambda=9.8425e8/(LR.frq_mhz*1e6);
                d=5280.0*path.distance[path.length-1];
        }
 
-       if (n)
+       if (normalized)
        {
                ed=GetElevation(destination);
                es=GetElevation(source);
@@ -4653,10 +5643,14 @@ void GraphHeight(struct site source, struct site destination, char *name, double
        }
 
        fd=fopen("profile.gp","wb");
+
+       if (clutter>0.0)
+               fd1=fopen("clutter.gp","wb");
+
        fd2=fopen("reference.gp","wb");
        fd5=fopen("curvature.gp", "wb");
 
-       if (f)
+       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
        {
                fd3=fopen("fresnel.gp", "wb");
                fd4=fopen("fresnel_pt_6.gp", "wb");
@@ -4675,7 +5669,7 @@ void GraphHeight(struct site source, struct site destination, char *name, double
 
                a=terrain+earthradius;
                cangle=5280.0*Distance(destination,remote)/earthradius;
-               c=b*sin(refangle*deg2rad+HALFPI)/sin(HALFPI-refangle*deg2rad-cangle);
+               c=b*sin(refangle*DEG2RAD+HALFPI)/sin(HALFPI-refangle*DEG2RAD-cangle);
 
                height=a-c;
 
@@ -4688,19 +5682,19 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                 * path to the first Fresnel zone boundary.
                 */
 
-               if (f)
+               if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
                {
                        d1=5280.0*path.distance[x];
                        f_zone=-1.0*sqrt(lambda*d1*(d-d1)/d);
                        fpt6_zone=f_zone*fzone_clearance;
                }
 
-               if (n)
+               if (normalized)
                {
                        r=-(nm*path.distance[x])-nb;
                        height+=r;
 
-                       if (f>0) 
+                       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
                        {
                                f_zone+=r;
                                fpt6_zone+=r;
@@ -4713,6 +5707,10 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                if (metric)
                {
                        fprintf(fd,"%f\t%f\n",KM_PER_MILE*path.distance[x],METERS_PER_FOOT*height);
+
+                       if (fd1!=NULL && x>0 && x<path.length-2)
+                               fprintf(fd1,"%f\t%f\n",KM_PER_MILE*path.distance[x],METERS_PER_FOOT*(terrain==0.0?height:(height+clutter)));
+
                        fprintf(fd2,"%f\t%f\n",KM_PER_MILE*path.distance[x],METERS_PER_FOOT*r);
                        fprintf(fd5,"%f\t%f\n",KM_PER_MILE*path.distance[x],METERS_PER_FOOT*(height-terrain));
                }
@@ -4720,11 +5718,15 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                else
                {
                        fprintf(fd,"%f\t%f\n",path.distance[x],height);
+
+                       if (fd1!=NULL && x>0 && x<path.length-2)
+                               fprintf(fd1,"%f\t%f\n",path.distance[x],(terrain==0.0?height:(height+clutter)));
+
                        fprintf(fd2,"%f\t%f\n",path.distance[x],r);
                        fprintf(fd5,"%f\t%f\n",path.distance[x],height-terrain);
                }
 
-               if (f)
+               if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
                {
                        if (metric)
                        {
@@ -4742,8 +5744,8 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                                minheight=f_zone;
                }
 
-               if (height>maxheight)
-                       maxheight=height;
+               if ((height+clutter)>maxheight)
+                       maxheight=height+clutter;
 
                if (height<minheight)
                        minheight=height;
@@ -4758,7 +5760,7 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                        minearth=height-terrain;
        }
 
-       if (n)
+       if (normalized)
                r=-(nm*path.distance[path.length-1])-nb;
        else
                r=0.0;
@@ -4775,7 +5777,7 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                fprintf(fd2,"%f\t%f\n",path.distance[path.length-1],r);
        }
 
-       if (f)
+       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
        {
                if (metric)
                {
@@ -4797,48 +5799,53 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                minheight=r;
 
        fclose(fd);
+
+       if (fd1!=NULL)
+               fclose(fd1);
+
        fclose(fd2);
        fclose(fd5);
 
-       if (f)
+       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
        {
                fclose(fd3);
                fclose(fd4);
        }
 
-       if (name[0]==0)
+       if (name[0]=='.')
        {
                /* Default filename and output file type */
 
-               strncpy(filename,"height\0",8);
+               strncpy(basename,"profile\0",8);
                strncpy(term,"png\0",4);
                strncpy(ext,"png\0",4);
        }
 
        else
        {
-               /* Grab extension and terminal type from "name" */
+               /* Extract extension and terminal type from "name" */
 
-               for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
-                       filename[x]=name[x];
+               ext[0]=0;
+               y=strlen(name);
+               strncpy(basename,name,254);
 
-               if (name[x]=='.')
+               for (x=y-1; x>0 && name[x]!='.'; x--);
+
+               if (x>0)  /* Extension found */
                {
-                       for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                       for (z=x+1; z<=y && (z-(x+1))<10; z++)
                        {
-                               term[y]=tolower(name[x]);
-                               ext[y]=term[y];
+                               ext[z-(x+1)]=tolower(name[z]);
+                               term[z-(x+1)]=name[z];
                        }
 
-                       ext[y]=0;
-                       term[y]=0;
-                       filename[z]=0;
+                       ext[z-(x+1)]=0;  /* Ensure an ending 0 */
+                       term[z-(x+1)]=0;
+                       basename[x]=0;
                }
 
-               else
-               {       /* No extension -- Default is png */
-
-                       filename[x]=0;
+               if (ext[0]==0)  /* No extension -- Default is png */
+               {
                        strncpy(term,"png\0",4);
                        strncpy(ext,"png\0",4);
                }
@@ -4851,7 +5858,7 @@ void GraphHeight(struct site source, struct site destination, char *name, double
                strncpy(ext,"ps\0",3);
 
        else if (strncmp(ext,"ps",2)==0)
-               strncpy(term,"postscript enhanced color\0",26);
+                       strncpy(term,"postscript enhanced color\0",26);
 
        fd=fopen("splat.gp","w");
 
@@ -4880,18 +5887,18 @@ void GraphHeight(struct site source, struct site destination, char *name, double
        fprintf(fd,"set encoding iso_8859_1\n");
        fprintf(fd,"set term %s\n",term);
 
-       if (f)
-               fprintf(fd,"set title \"SPLAT! Path Profile Between %s and %s (%.2f%c azimuth)\\nWith First Fresnel Zone\"\n",destination.name, source.name, azimuth,176);
+       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
+               fprintf(fd,"set title \"%s Path Profile Between %s and %s (%.2f%c azimuth)\\nWith First Fresnel Zone\"\n",splat_name, destination.name, source.name, azimuth,176);
 
        else
-               fprintf(fd,"set title \"SPLAT! Height Profile Between %s and %s (%.2f%c azimuth)\"\n",destination.name, source.name, azimuth,176);
+               fprintf(fd,"set title \"%s Height Profile Between %s and %s (%.2f%c azimuth)\"\n",splat_name, destination.name, source.name, azimuth,176);
 
        if (metric)
                fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f kilometers)\"\n",destination.name,source.name,KM_PER_MILE*Distance(source,destination));
        else
                fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f miles)\"\n",destination.name,source.name,Distance(source,destination));
 
-       if (n)
+       if (normalized)
        {
                if (metric)
                        fprintf(fd,"set ylabel \"Normalized Height Referenced To LOS Path Between\\n%s and %s (meters)\"\n",destination.name,source.name);
@@ -4904,19 +5911,42 @@ void GraphHeight(struct site source, struct site destination, char *name, double
        else
        {
                if (metric)
-                       fprintf(fd,"set ylabel \"Height Referenced To LOS Path Between %s and %s (meters)\"\n",destination.name,source.name);
+                       fprintf(fd,"set ylabel \"Height Referenced To LOS Path Between\\n%s and %s (meters)\"\n",destination.name,source.name);
 
                else
-                       fprintf(fd,"set ylabel \"Height Referenced To LOS Path Between %s and %s (feet)\"\n",destination.name,source.name);
+                       fprintf(fd,"set ylabel \"Height Referenced To LOS Path Between\\n%s and %s (feet)\"\n",destination.name,source.name);
        }
 
-       fprintf(fd,"set output \"%s.%s\"\n",filename,ext);
+       fprintf(fd,"set output \"%s.%s\"\n",basename,ext);
 
-       if (f)
-               fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"reference.gp\" title \"Line of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines, \"fresnel.gp\" axes x1y1 title \"First Fresnel Zone (%.3f MHz)\" with lines, \"fresnel_pt_6.gp\" title \"%.0f%% of First Fresnel Zone\" with lines\n",f,fzone_clearance*100.0);
+       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
+       {
+               if (clutter>0.0)
+               {
+                       if (metric)
+                               fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"clutter.gp\" title \"Ground Clutter (%.2f meters)\" with lines, \"reference.gp\" title \"Line of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines, \"fresnel.gp\" axes x1y1 title \"First Fresnel Zone (%.3f MHz)\" with lines, \"fresnel_pt_6.gp\" title \"%.0f%% of First Fresnel Zone\" with lines\n",clutter*METERS_PER_FOOT,LR.frq_mhz,fzone_clearance*100.0);
+                       else
+                               fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"clutter.gp\" title \"Ground Clutter (%.2f feet)\" with lines, \"reference.gp\" title \"Line of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines, \"fresnel.gp\" axes x1y1 title \"First Fresnel Zone (%.3f MHz)\" with lines, \"fresnel_pt_6.gp\" title \"%.0f%% of First Fresnel Zone\" with lines\n",clutter,LR.frq_mhz,fzone_clearance*100.0);
+               }
+
+               else
+                       fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"reference.gp\" title \"Line of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines, \"fresnel.gp\" axes x1y1 title \"First Fresnel Zone (%.3f MHz)\" with lines, \"fresnel_pt_6.gp\" title \"%.0f%% of First Fresnel Zone\" with lines\n",LR.frq_mhz,fzone_clearance*100.0);
+       }
 
        else
-               fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines\n");
+       {
+               if (clutter>0.0)
+               {
+                       if (metric)
+                               fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"clutter.gp\" title \"Ground Clutter (%.2f meters)\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines\n",clutter*METERS_PER_FOOT);
+                       else
+                               fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"clutter.gp\" title \"Ground Clutter (%.2f feet)\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines\n",clutter);
+               }
+
+               else
+                       fprintf(fd,"plot \"profile.gp\" title \"Point-to-Point Profile\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines, \"curvature.gp\" axes x1y2 title \"Earth's Curvature Contour\" with lines\n");
+
+       }
 
        fclose(fd);
 
@@ -4924,18 +5954,24 @@ void GraphHeight(struct site source, struct site destination, char *name, double
 
        if (x!=-1)
        {
-               unlink("splat.gp");
-               unlink("profile.gp");
-               unlink("reference.gp");
-               unlink("curvature.gp");
-
-               if (f)
+               if (gpsav==0)
                {
-                       unlink("fresnel.gp");
-                       unlink("fresnel_pt_6.gp");
+                       unlink("splat.gp");
+                       unlink("profile.gp");
+                       unlink("reference.gp");
+                       unlink("curvature.gp");
+
+                       if (fd1!=NULL)
+                               unlink("clutter.gp");
+
+                       if ((LR.frq_mhz>=20.0) && (LR.frq_mhz<=20000.0) && fresnel_plot)
+                       {
+                               unlink("fresnel.gp");
+                               unlink("fresnel_pt_6.gp");
+                       }
                }
 
-               fprintf(stdout,"\nHeight plot written to: \"%s.%s\"",filename,ext);
+               fprintf(stdout,"\nHeight plot written to: \"%s.%s\"",basename,ext);
                fflush(stdout);
        }
 
@@ -4969,6 +6005,18 @@ void ObstructionAnalysis(struct site xmtr, struct site rcvr, double f, FILE *out
        if (f)
                lambda=9.8425e8/(f*1e6);
 
+       if (clutter>0.0)
+       {
+               fprintf(outfile,"Terrain has been raised by");
+
+               if (metric)
+                       fprintf(outfile," %.2f meters",METERS_PER_FOOT*clutter);
+               else
+                       fprintf(outfile," %.2f feet",clutter);
+
+               fprintf(outfile," to account for ground clutter.\n\n");
+       }
+
        /* At each point along the path calculate the cosine
           of a sort of "inverse elevation angle" at the receiver.
           From the antenna, 0 deg. looks at the ground, and 90 deg.
@@ -4989,7 +6037,7 @@ void ObstructionAnalysis(struct site xmtr, struct site rcvr, double f, FILE *out
                site_x.lon=path.lon[x];
                site_x.alt=0.0;
 
-               h_x=GetElevation(site_x)+earthradius;
+               h_x=GetElevation(site_x)+earthradius+clutter;
                d_x=5280.0*Distance(rcvr,site_x);
 
                /* Deal with the LOS path first. */
@@ -4999,23 +6047,23 @@ void ObstructionAnalysis(struct site xmtr, struct site rcvr, double f, FILE *out
                if (cos_tx_angle>cos_test_angle)
                {
                        if (h_r==h_r_orig)
-                               fprintf(outfile,"Between %s and %s, SPLAT! detected obstructions at:\n\n",rcvr.name,xmtr.name);
+                               fprintf(outfile,"Between %s and %s, %s detected obstructions at:\n\n",rcvr.name,xmtr.name,splat_name);
 
                        if (site_x.lat>=0.0)
                        {
                                if (metric)
-                                       fprintf(outfile,"\t%.4f N, %.4f W, %5.2f kilometers, %6.2f meters AMSL\n",site_x.lat, site_x.lon, KM_PER_MILE*(d_x/5280.0), METERS_PER_FOOT*(h_x-earthradius));
+                                       fprintf(outfile,"   %8.4f N,%9.4f W, %5.2f kilometers, %6.2f meters AMSL\n",site_x.lat, site_x.lon, KM_PER_MILE*(d_x/5280.0), METERS_PER_FOOT*(h_x-earthradius));
                                else
-                                       fprintf(outfile,"\t%.4f N, %.4f W, %5.2f miles, %6.2f feet AMSL\n",site_x.lat, site_x.lon, d_x/5280.0, h_x-earthradius);
+                                       fprintf(outfile,"   %8.4f N,%9.4f W, %5.2f miles, %6.2f feet AMSL\n",site_x.lat, site_x.lon, d_x/5280.0, h_x-earthradius);
                        }
 
                        else
                        {
                                if (metric)
-                                       fprintf(outfile,"\t%.4f S, %.4f W, %5.2f kilometers, %6.2f meters AMSL\n",-site_x.lat, site_x.lon, KM_PER_MILE*(d_x/5280.0), METERS_PER_FOOT*(h_x-earthradius));
+                                       fprintf(outfile,"   %8.4f S,%9.4f W, %5.2f kilometers, %6.2f meters AMSL\n",-site_x.lat, site_x.lon, KM_PER_MILE*(d_x/5280.0), METERS_PER_FOOT*(h_x-earthradius));
                                else
 
-                                       fprintf(outfile,"\t%.4f S, %.4f W, %5.2f miles, %6.2f feet AMSL\n",-site_x.lat, site_x.lon, d_x/5280.0, h_x-earthradius);
+                                       fprintf(outfile,"   %8.4f S,%9.4f W, %5.2f miles, %6.2f feet AMSL\n",-site_x.lat, site_x.lon, d_x/5280.0, h_x-earthradius);
                        }
                }
 
@@ -5061,40 +6109,40 @@ void ObstructionAnalysis(struct site xmtr, struct site rcvr, double f, FILE *out
        if (h_r>h_r_orig)
        {
                if (metric)
-                       sprintf(string,"\nAntenna at %s must be raised to at least %.2f meters AGL\nto clear all obstructions detected by SPLAT!\n",rcvr.name, METERS_PER_FOOT*(h_r-GetElevation(rcvr)-earthradius));
+                       snprintf(string,150,"\nAntenna at %s must be raised to at least %.2f meters AGL\nto clear all obstructions detected by %s.\n",rcvr.name, METERS_PER_FOOT*(h_r-GetElevation(rcvr)-earthradius),splat_name);
                else
-                       sprintf(string,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear all obstructions detected by SPLAT!\n",rcvr.name, h_r-GetElevation(rcvr)-earthradius);
+                       snprintf(string,150,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear all obstructions detected by %s.\n",rcvr.name, h_r-GetElevation(rcvr)-earthradius,splat_name);
        }
 
        else
-               sprintf(string,"\nNo obstructions to LOS path due to terrain were detected by SPLAT!\n");
+               snprintf(string,150,"\nNo obstructions to LOS path due to terrain were detected by %s\n",splat_name);
 
        if (f)
        {
                if (h_r_fpt6>h_r_orig)
                {
                        if (metric)
-                               sprintf(string_fpt6,"\nAntenna at %s must be raised to at least %.2f meters AGL\nto clear %.0f%c of the first Fresnel zone.\n",rcvr.name, METERS_PER_FOOT*(h_r_fpt6-GetElevation(rcvr)-earthradius),fzone_clearance*100.0,37);
+                               snprintf(string_fpt6,150,"\nAntenna at %s must be raised to at least %.2f meters AGL\nto clear %.0f%c of the first Fresnel zone.\n",rcvr.name, METERS_PER_FOOT*(h_r_fpt6-GetElevation(rcvr)-earthradius),fzone_clearance*100.0,37);
 
                        else
-                               sprintf(string_fpt6,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear %.0f%c of the first Fresnel zone.\n",rcvr.name, h_r_fpt6-GetElevation(rcvr)-earthradius,fzone_clearance*100.0,37);
+                               snprintf(string_fpt6,150,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear %.0f%c of the first Fresnel zone.\n",rcvr.name, h_r_fpt6-GetElevation(rcvr)-earthradius,fzone_clearance*100.0,37);
                }
 
                else
-                       sprintf(string_fpt6,"\n%.0f%c of the first Fresnel zone is clear.\n",fzone_clearance*100.0,37);
+                       snprintf(string_fpt6,150,"\n%.0f%c of the first Fresnel zone is clear.\n",fzone_clearance*100.0,37);
        
                if (h_r_f1>h_r_orig)
                {
                        if (metric)
-                               sprintf(string_f1,"\nAntenna at %s must be raised to at least %.2f meters AGL\nto clear the first Fresnel zone.\n",rcvr.name, METERS_PER_FOOT*(h_r_f1-GetElevation(rcvr)-earthradius));
+                               snprintf(string_f1,150,"\nAntenna at %s must be raised to at least %.2f meters AGL\nto clear the first Fresnel zone.\n",rcvr.name, METERS_PER_FOOT*(h_r_f1-GetElevation(rcvr)-earthradius));
 
                        else                    
-                               sprintf(string_f1,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear the first Fresnel zone.\n",rcvr.name, h_r_f1-GetElevation(rcvr)-earthradius);
+                               snprintf(string_f1,150,"\nAntenna at %s must be raised to at least %.2f feet AGL\nto clear the first Fresnel zone.\n",rcvr.name, h_r_f1-GetElevation(rcvr)-earthradius);
 
                }
 
                else
-                   sprintf(string_f1,"\nThe first Fresnel zone is clear.\n\n");
+                   snprintf(string_f1,150,"\nThe first Fresnel zone is clear.\n");
        }
 
        fprintf(outfile,"%s",string);
@@ -5118,19 +6166,20 @@ void PathReport(struct site source, struct site destination, char *name, char gr
           found, .png is assumed. */
 
        int     x, y, z, errnum;
-       char    filename[255], term[30], ext[15], strmode[100],
+       char    basename[255], term[30], ext[15], strmode[100],
                report_name[80], block=0;
        double  maxloss=-100000.0, minloss=100000.0, loss, haavt,
                angle1, angle2, azimuth, pattern=1.0, patterndB=0.0,
                total_loss=0.0, cos_xmtr_angle, cos_test_angle=0.0,
                source_alt, test_alt, dest_alt, source_alt2, dest_alt2,
                distance, elevation, four_thirds_earth, field_strength,
-               free_space_loss=0.0, voltage;
+               free_space_loss=0.0, eirp=0.0, voltage, rxp, dBm,
+               power_density;
        FILE    *fd=NULL, *fd2=NULL;
 
        sprintf(report_name,"%s-to-%s.txt",source.name,destination.name);
 
-       four_thirds_earth=EARTHRADIUS*(4.0/3.0);
+       four_thirds_earth=FOUR_THIRDS*EARTHRADIUS;
 
        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)
@@ -5138,8 +6187,8 @@ void PathReport(struct site source, struct site destination, char *name, char gr
 
        fd2=fopen(report_name,"w");
 
-       fprintf(fd2,"\n\t\t--==[ SPLAT! v%s Path Analysis ]==--\n\n",splat_version);
-       fprintf(fd2,"-------------------------------------------------------------------------\n\n");
+       fprintf(fd2,"\n\t\t--==[ %s v%s Path Analysis ]==--\n\n",splat_name,splat_version);
+       fprintf(fd2,"%s\n\n",dashes);
        fprintf(fd2,"Transmitter site: %s\n",source.name);
 
        if (source.lat>=0.0)
@@ -5194,10 +6243,10 @@ void PathReport(struct site source, struct site destination, char *name, char gr
        }
 
        if (metric)
-               fprintf(fd2,"Distance to %s: %.2f kilometers\n",destination.name,METERS_PER_FOOT*Distance(source,destination));
+               fprintf(fd2,"Distance to %s: %.2f kilometers\n",destination.name,KM_PER_MILE*Distance(source,destination));
 
        else
-               fprintf(fd2,"Distance to %s: %.2f miles.\n",destination.name,Distance(source,destination));
+               fprintf(fd2,"Distance to %s: %.2f miles\n",destination.name,Distance(source,destination));
 
        fprintf(fd2,"Azimuth to %s: %.2f degrees\n",destination.name,azimuth);
 
@@ -5217,7 +6266,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                fprintf(fd2," angle to the first obstruction: %+.4f degrees\n",angle2);
        }
 
-       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+       fprintf(fd2,"\n%s\n\n",dashes);
 
        /* Receiver */
 
@@ -5270,7 +6319,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
        angle1=ElevationAngle(destination,source);
        angle2=ElevationAngle2(destination,source,earthradius);
 
-       fprintf(fd2,"Azimuth to %s: %.2f degrees.\n",source.name,azimuth);
+       fprintf(fd2,"Azimuth to %s: %.2f degrees\n",source.name,azimuth);
 
        if (angle1>=0.0)
                fprintf(fd2,"Elevation angle to %s: %+.4f degrees\n",source.name,angle1);
@@ -5288,7 +6337,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                fprintf(fd2," angle to the first obstruction: %+.4f degrees\n",angle2);
        }
 
-       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+       fprintf(fd2,"\n%s\n\n",dashes);
 
        if (LR.frq_mhz>0.0)
        {
@@ -5349,19 +6398,43 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                        fprintf(fd2,"Transmitter ERP: ");
 
                        if (LR.erp<1.0)
-                               fprintf(fd2,"%.1lf milliwatts\n",1000.0*LR.erp);
+                               fprintf(fd2,"%.1lf milliwatts",1000.0*LR.erp);
 
                        if (LR.erp>=1.0 && LR.erp<10.0)
-                               fprintf(fd2,"%.1lf Watts\n",LR.erp);
+                               fprintf(fd2,"%.1lf Watts",LR.erp);
 
                        if (LR.erp>=10.0 && LR.erp<10.0e3)
-                               fprintf(fd2,"%.0lf Watts\n",LR.erp);
+                               fprintf(fd2,"%.0lf Watts",LR.erp);
 
                        if (LR.erp>=10.0e3)
-                               fprintf(fd2,"%.3lf kilowatts\n",LR.erp/1.0e3);
+                               fprintf(fd2,"%.3lf kilowatts",LR.erp/1.0e3);
+
+                       dBm=10.0*(log10(LR.erp*1000.0));
+                       fprintf(fd2," (%+.2f dBm)\n",dBm);
+
+                       /* EIRP = ERP + 2.14 dB */
+
+                       fprintf(fd2,"Transmitter EIRP: ");
+
+                       eirp=LR.erp*1.636816521;
+
+                       if (eirp<1.0)
+                               fprintf(fd2,"%.1lf milliwatts",1000.0*eirp);
+
+                       if (eirp>=1.0 && eirp<10.0)
+                               fprintf(fd2,"%.1lf Watts",eirp);
+
+                       if (eirp>=10.0 && eirp<10.0e3)
+                               fprintf(fd2,"%.0lf Watts",eirp);
+
+                       if (eirp>=10.0e3)
+                               fprintf(fd2,"%.3lf kilowatts",eirp/1.0e3);
+
+                       dBm=10.0*(log10(eirp*1000.0));
+                       fprintf(fd2," (%+.2f dBm)\n",dBm);
                }
 
-                       fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+               fprintf(fd2,"\n%s\n\n",dashes);
 
                fprintf(fd2,"Summary for the link between %s and %s:\n\n",source.name, destination.name);
 
@@ -5370,10 +6443,16 @@ void PathReport(struct site source, struct site destination, char *name, char gr
 
                ReadPath(source, destination);  /* source=TX, destination=RX */
 
-               /* Copy elevations along path into the elev_l[] array. */
+               /* Copy elevations plus clutter along
+                  path into the elev[] array. */
+
+               for (x=1; x<path.length-1; x++)
+                       elev[x+2]=METERS_PER_FOOT*(path.elevation[x]==0.0?path.elevation[x]:(clutter+path.elevation[x]));
 
-               for (x=0; x<path.length; x++)
-                       elev_l[x+2]=path.elevation[x]*METERS_PER_FOOT;  
+               /* Copy ending points without clutter */
+
+               elev[2]=path.elevation[0]*METERS_PER_FOOT;
+               elev[path.length+1]=path.elevation[path.length-1]*METERS_PER_FOOT;
 
                fd=fopen("profile.gp","w");
 
@@ -5417,7 +6496,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                                           what it would be if the angles themselves
                                           were compared. */
 
-                                       if (cos_xmtr_angle>cos_test_angle)
+                                       if (cos_xmtr_angle>=cos_test_angle)
                                                block=1;
                                }
 
@@ -5431,21 +6510,22 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                           shortest distance terrain can play a role in
                           path loss. */
 
-                       elev_l[0]=y-1;  /* (number of points - 1) */
+                       elev[0]=y-1;    /* (number of points - 1) */
 
                        /* Distance between elevation samples */
-                       elev_l[1]=METERS_PER_MILE*(path.distance[y]-path.distance[y-1]);
 
-                       point_to_point(elev_l, source.alt*METERS_PER_FOOT, 
+                       elev[1]=METERS_PER_MILE*(path.distance[y]-path.distance[y-1]);
+
+                       point_to_point(elev, source.alt*METERS_PER_FOOT, 
                        destination.alt*METERS_PER_FOOT, LR.eps_dielect,
                        LR.sgm_conductivity, LR.eno_ns_surfref, LR.frq_mhz,
                        LR.radio_climate, LR.pol, LR.conf, LR.rel, loss,
                        strmode, errnum);
 
                        if (block)
-                               elevation=((acos(cos_test_angle))/deg2rad)-90.0;
+                               elevation=((acos(cos_test_angle))/DEG2RAD)-90.0;
                        else
-                               elevation=((acos(cos_xmtr_angle))/deg2rad)-90.0;
+                               elevation=((acos(cos_xmtr_angle))/DEG2RAD)-90.0;
 
                        /* Integrate the antenna's radiation
                           pattern into the overall path loss. */
@@ -5493,24 +6573,62 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                fprintf(fd2,"Longley-Rice path loss: %.2f dB\n",loss);
 
                if (free_space_loss!=0.0)
-                       fprintf(fd2,"Attenuation due to effects of terrain: %.2f dB\n",loss-free_space_loss);
+                       fprintf(fd2,"Attenuation due to terrain shielding: %.2f dB\n",loss-free_space_loss);
 
                if (patterndB!=0.0)
                        fprintf(fd2,"Total path loss including %s antenna pattern: %.2f dB\n",source.name,total_loss);
 
                if (LR.erp!=0.0)
                {
-                       field_strength=(137.26+(20.0*log10(LR.frq_mhz))-total_loss)+(10.0*log10(LR.erp/1000.0));
+                       field_strength=(139.4+(20.0*log10(LR.frq_mhz))-total_loss)+(10.0*log10(LR.erp/1000.0));
+
+                       /* dBm is referenced to EIRP */
+
+                       rxp=eirp/(pow(10.0,(total_loss/10.0)));
+                       dBm=10.0*(log10(rxp*1000.0));
+                       power_density=(eirp/(pow(10.0,(total_loss-free_space_loss)/10.0)));
+                       /* divide by 4*PI*distance_in_meters squared */
+                       power_density/=(4.0*PI*distance*distance*2589988.11);
+
                        fprintf(fd2,"Field strength at %s: %.2f dBuV/meter\n", destination.name,field_strength);
-                       voltage=(pow(10.0,field_strength/20.0)*39.52726907)/LR.frq_mhz;
-                       fprintf(fd2,"Voltage produced by a terminated 50 ohm 0 dBd gain antenna: %.2f uV\n",voltage);
-                       voltage=(pow(10.0,field_strength/20.0)*48.41082007)/LR.frq_mhz;
-                       fprintf(fd2,"Voltage produced by a terminated 75 ohm 0 dBd gain antenna: %.2f uV\n",voltage);
+                       fprintf(fd2,"Signal power level at %s: %+.2f dBm\n",destination.name,dBm);
+                       fprintf(fd2,"Signal power density at %s: %+.2f dBW per square meter\n",destination.name,10.0*log10(power_density));
+                       voltage=1.0e6*sqrt(50.0*(eirp/(pow(10.0,(total_loss-2.14)/10.0))));
+                       fprintf(fd2,"Voltage across 50 ohm dipole at %s: %.2f uV (%.2f dBuV)\n",destination.name,voltage,20.0*log10(voltage));
+
+                       voltage=1.0e6*sqrt(75.0*(eirp/(pow(10.0,(total_loss-2.14)/10.0))));
+                       fprintf(fd2,"Voltage across 75 ohm dipole at %s: %.2f uV (%.2f dBuV)\n",destination.name,voltage,20.0*log10(voltage));
                }
 
                fprintf(fd2,"Mode of propagation: %s\n",strmode);
+               fprintf(fd2,"Longley-Rice model error number: %d",errnum);
+
+               switch (errnum)
+               {
+                       case 0:
+                               fprintf(fd2," (No error)\n");
+                               break;
 
-               fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
+                       case 1:
+                               fprintf(fd2,"\n  Warning: Some parameters are nearly out of range.\n");
+                               fprintf(fd2,"  Results should be used with caution.\n");
+                               break;
+
+                       case 2:
+                               fprintf(fd2,"\n  Note: Default parameters have been substituted for impossible ones.\n");
+                               break;
+
+                       case 3:
+                               fprintf(fd2,"\n  Warning: A combination of parameters is out of range.\n");
+                               fprintf(fd2,"  Results are probably invalid.\n");
+                               break;
+
+                       default:
+                               fprintf(fd2,"\n  Warning: Some parameters are out of range.\n");
+                               fprintf(fd2,"  Results are probably invalid.\n");
+               }
+
+               fprintf(fd2,"\n%s\n\n",dashes);
        }
 
        fprintf(stdout,"\nPath Loss Report written to: \"%s\"\n",report_name);
@@ -5524,42 +6642,43 @@ void PathReport(struct site source, struct site destination, char *name, char gr
 
        if (graph_it)
        {
-               if (name[0]==0)
+               if (name[0]=='.')
                {
                        /* Default filename and output file type */
 
-                       strncpy(filename,"loss\0",5);
+                       strncpy(basename,"profile\0",8);
                        strncpy(term,"png\0",4);
                        strncpy(ext,"png\0",4);
                }
 
                else
                {
-                       /* Grab extension and terminal type from "name" */
+                       /* Extract extension and terminal type from "name" */
+
+                       ext[0]=0;
+                       y=strlen(name);
+                       strncpy(basename,name,254);
 
-                       for (x=0; name[x]!='.' && name[x]!=0 && x<254; x++)
-                               filename[x]=name[x];
+                       for (x=y-1; x>0 && name[x]!='.'; x--);
 
-                       if (name[x]=='.')
+                       if (x>0)  /* Extension found */
                        {
-                               for (y=0, z=x, x++; name[x]!=0 && x<254 && y<14; x++, y++)
+                               for (z=x+1; z<=y && (z-(x+1))<10; z++)
                                {
-                                       term[y]=tolower(name[x]);
-                                       ext[y]=term[y];
+                                       ext[z-(x+1)]=tolower(name[z]);
+                                       term[z-(x+1)]=name[z];
                                }
 
-                               ext[y]=0;
-                               term[y]=0;
-                               filename[z]=0;
+                               ext[z-(x+1)]=0;  /* Ensure an ending 0 */
+                               term[z-(x+1)]=0;
+                               basename[x]=0;
                        }
+               }
 
-                       else
-                       {       /* No extension -- Default is png */
-
-                               filename[x]=0;
-                               strncpy(term,"png\0",4);
-                               strncpy(ext,"png\0",4);
-                       }
+               if (ext[0]==0)  /* No extension -- Default is png */
+               {
+                       strncpy(term,"png\0",4);
+                       strncpy(ext,"png\0",4);
                }
 
                /* Either .ps or .postscript may be used
@@ -5569,7 +6688,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                        strncpy(ext,"ps\0",3);
 
                else if (strncmp(ext,"ps",2)==0)
-                       strncpy(term,"postscript enhanced color\0",26);
+                               strncpy(term,"postscript enhanced color\0",26);
 
                fd=fopen("splat.gp","w");
 
@@ -5577,7 +6696,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                fprintf(fd,"set yrange [%2.3f to %2.3f]\n", minloss, maxloss);
                fprintf(fd,"set encoding iso_8859_1\n");
                fprintf(fd,"set term %s\n",term);
-               fprintf(fd,"set title \"SPLAT! Loss Profile Along Path Between %s and %s (%.2f%c azimuth)\"\n",destination.name, source.name, Azimuth(destination,source),176);
+               fprintf(fd,"set title \"%s Loss Profile Along Path Between %s and %s (%.2f%c azimuth)\"\n",splat_name, destination.name, source.name, Azimuth(destination,source),176);
 
                if (metric)
                        fprintf(fd,"set xlabel \"Distance Between %s and %s (%.2f kilometers)\"\n",destination.name,source.name,KM_PER_MILE*Distance(destination,source));
@@ -5589,7 +6708,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                else
                        fprintf(fd,"set ylabel \"Longley-Rice Path Loss (dB)");
 
-               fprintf(fd,"\"\nset output \"%s.%s\"\n",filename,ext);
+               fprintf(fd,"\"\nset output \"%s.%s\"\n",basename,ext);
                fprintf(fd,"plot \"profile.gp\" title \"Path Loss\" with lines\n");
 
                fclose(fd);
@@ -5598,11 +6717,14 @@ void PathReport(struct site source, struct site destination, char *name, char gr
 
                if (x!=-1)
                {
-                       unlink("splat.gp");
-                       unlink("profile.gp");
-                       unlink("reference.gp"); 
+                       if (gpsav==0)
+                       {
+                               unlink("splat.gp");
+                               unlink("profile.gp");
+                               unlink("reference.gp");
+                       }       
 
-                       fprintf(stdout,"Path loss plot written to: \"%s.%s\"\n",filename,ext);
+                       fprintf(stdout,"Path loss plot written to: \"%s.%s\"\n",basename,ext);
                        fflush(stdout);
                }
 
@@ -5610,7 +6732,7 @@ void PathReport(struct site source, struct site destination, char *name, char gr
                        fprintf(stderr,"\n*** ERROR: Error occurred invoking gnuplot!\n");
        }
 
-       if (x!=-1)
+       if (x!=-1 && gpsav==0)
                unlink("profile.gp");
 }
 
@@ -5629,9 +6751,9 @@ void SiteReport(struct site xmtr)
 
        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\t--==[ %s v%s Site Analysis Report For: %s ]==--\n\n",splat_name, splat_version, xmtr.name);
 
-       fprintf(fd,"---------------------------------------------------------------------------\n\n");
+       fprintf(fd,"%s\n\n",dashes);
 
        if (xmtr.lat>=0.0)
        {
@@ -5690,9 +6812,9 @@ void SiteReport(struct site xmtr)
                }
        }
 
-       fprintf(fd,"\n---------------------------------------------------------------------------\n\n");
+       fprintf(fd,"\n%s\n\n",dashes);
        fclose(fd);
-       fprintf(stdout,"\nSite analysis report written to: \"%s\"",report_name);
+       fprintf(stdout,"\nSite analysis report written to: \"%s\"\n",report_name);
 }
 
 void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat)
@@ -5725,7 +6847,10 @@ void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat)
                                while (ymax>=360)
                                        ymax-=360;
 
-                               sprintf(string,"%d:%d:%d:%d",x, x+1, ymin, ymax);
+                               if (ippd==3600)
+                                       snprintf(string,19,"%d:%d:%d:%d-hd",x, x+1, ymin, ymax);
+                               else
+                                       snprintf(string,16,"%d:%d:%d:%d",x, x+1, ymin, ymax);
                                LoadSDF(string);
                        }
        }
@@ -5751,28 +6876,31 @@ void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat)
                                while (ymax>=360)
                                        ymax-=360;
 
-                               sprintf(string,"%d:%d:%d:%d",x, x+1, ymin, ymax);
+                               if (ippd==3600)
+                                       snprintf(string,19,"%d:%d:%d:%d-hd",x, x+1, ymin, ymax);
+                               else
+                                       snprintf(string,16,"%d:%d:%d:%d",x, x+1, ymin, ymax);
                                LoadSDF(string);
                        }
        }
 }
 
-int LoadPLI(char *filename)
+int LoadANO(char *filename)
 {
-       /* This function reads a SPLAT! path-loss output 
-          file (-plo) for analysis and/or map generation. */
+       /* This function reads a SPLAT! alphanumeric output 
+          file (-ani option) for analysis and/or map generation. */
 
        int     error=0, max_west, min_west, max_north, min_north;
-       char    string[80], *pointer=NULL;
+       char    string[80], *pointer=NULL, *s=NULL;
        double  latitude=0.0, longitude=0.0, azimuth=0.0, elevation=0.0,
-               loss=0.0;
+               ano=0.0;
        FILE    *fd;
 
        fd=fopen(filename,"r");
 
        if (fd!=NULL)
        {
-               fgets(string,78,fd);
+               s=fgets(string,78,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -5780,7 +6908,7 @@ int LoadPLI(char *filename)
 
                sscanf(string,"%d, %d",&max_west, &min_west);
 
-               fgets(string,78,fd);
+               s=fgets(string,78,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -5788,7 +6916,7 @@ int LoadPLI(char *filename)
 
                sscanf(string,"%d, %d",&max_north, &min_north);
 
-               fgets(string,78,fd);
+               s=fgets(string,78,fd);
                pointer=strchr(string,';');
 
                if (pointer!=NULL)
@@ -5799,19 +6927,64 @@ int LoadPLI(char *filename)
                fprintf(stdout,"\nReading \"%s\"... ",filename);
                fflush(stdout);
 
-               fgets(string,78,fd);
-               sscanf(string,"%lf, %lf, %lf, %lf, %lf",&latitude, &longitude, &azimuth, &elevation, &loss);
+               s=fgets(string,78,fd);
+               sscanf(string,"%lf, %lf, %lf, %lf, %lf",&latitude, &longitude, &azimuth, &elevation, &ano);
 
                while (feof(fd)==0)
                {
-                       if (loss>255.0)
-                               loss=255.0;
+                       if (LR.erp==0.0)
+                       {
+                               /* Path loss */
+
+                               if (contour_threshold==0 || (fabs(ano)<=(double)contour_threshold))
+                               {
+                                       ano=fabs(ano);
+
+                                       if (ano>255.0)
+                                               ano=255.0;
+
+                                       PutSignal(latitude,longitude,((unsigned char)round(ano)));
+                               }
+                       }
+
+                       if (LR.erp!=0.0 && dbm!=0)
+                       {
+                               /* signal power level in dBm */
+
+                               if (contour_threshold==0 || (ano>=(double)contour_threshold))
+                               {
+                                       ano=200.0+rint(ano);
+
+                                       if (ano<0.0)
+                                               ano=0.0;
+
+                                       if (ano>255.0)
+                                               ano=255.0;
+
+                                       PutSignal(latitude,longitude,((unsigned char)round(ano)));
+                               }
+                       }
+
+                       if (LR.erp!=0.0 && dbm==0)
+                       {
+                               /* field strength dBuV/m */
+
+                               if (contour_threshold==0 || (ano>=(double)contour_threshold))
+                               {
+                                       ano=100.0+rint(ano);
+
+                                       if (ano<0.0)
+                                               ano=0.0;
+
+                                       if (ano>255.0)
+                                               ano=255.0;
 
-                       if (loss<=(double)maxdB)
-                               PutSignal(latitude,longitude,((unsigned char)round(loss)));
+                                       PutSignal(latitude,longitude,((unsigned char)round(ano)));
+                               }
+                       }
 
-                       fgets(string,78,fd);
-                       sscanf(string,"%lf, %lf, %lf, %lf, %lf",&latitude, &longitude, &azimuth, &elevation, &loss);
+                       s=fgets(string,78,fd);
+                       sscanf(string,"%lf, %lf, %lf, %lf, %lf",&latitude, &longitude, &azimuth, &elevation, &ano);
                }
 
                fclose(fd);
@@ -5846,7 +7019,7 @@ void WriteKML(struct site source, struct site destination)
 
        fprintf(fd,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        fprintf(fd,"<kml xmlns=\"http://earth.google.com/kml/2.0\">\n");
-       fprintf(fd,"<!-- Generated by SPLAT! Version %s -->\n",splat_version);
+       fprintf(fd,"<!-- Generated by %s Version %s -->\n",splat_name, splat_version);
        fprintf(fd,"<Folder>\n");
        fprintf(fd,"<name>SPLAT! Path</name>\n");
        fprintf(fd,"<open>1</open>\n");
@@ -5906,7 +7079,6 @@ void WriteKML(struct site source, struct site destination)
 
        fprintf(fd,"       <BR>%s West</BR>\n",dec2dms(destination.lon));
 
-
        if (metric)
                fprintf(fd,"       <BR>%.2f km",distance*KM_PER_MILE);
        else
@@ -6004,7 +7176,7 @@ void WriteKML(struct site source, struct site destination)
                           statement is reversed from what it would
                           be if the actual angles were compared. */
 
-                       if (cos_xmtr_angle>cos_test_angle)
+                       if (cos_xmtr_angle>=cos_test_angle)
                                block=1;
                }
 
@@ -6036,39 +7208,48 @@ void WriteKML(struct site source, struct site destination)
        fflush(stdout);
 }
 
-int main(char argc, char *argv[])
+int main(int argc, char *argv[])
 {
        int             x, y, z=0, min_lat, min_lon, max_lat, max_lon,
                        rxlat, rxlon, txlat, txlon, west_min, west_max,
                        north_min, north_max;
 
        unsigned char   coverage=0, LRmap=0, terrain_plot=0,
-                       elevation_plot=0, height_plot=0, map=0, nf=0,
+                       elevation_plot=0, height_plot=0, map=0,
                        longley_plot=0, cities=0, bfs=0, txsites=0,
                        norm=0, topomap=0, geo=0, kml=0, pt2pt_mode=0,
                        area_mode=0, max_txsites, ngs=0, nolospath=0,
-                       nositereports=0;
+                       nositereports=0, fresnel_plot=1;
  
        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], *env=NULL,
                        txfile[255], boundary_file[5][255],
-                       udt_file[255], rxsite=0, plo_filename[255],
-                       pli_filename[255], ext[20];
+                       udt_file[255], rxsite=0, ani_filename[255],
+                       ano_filename[255], ext[20], *s=NULL;
 
        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, freq=0.0;
+                       rx_range=0.0, deg_range=0.0, deg_limit=0.0,
+                       deg_range_lon, er_mult;
 
        struct          site tx_site[32], rx_site;
 
        FILE            *fd;
 
+       strncpy(splat_version,"1.3.0\0",6);
+
+       if (HD_MODE==1)
+               strncpy(splat_name,"SPLAT! HD\0",10);
+       else
+               strncpy(splat_name,"SPLAT!\0",7);
+
+       strncpy(dashes,"---------------------------------------------------------------------------\0",76);
 
        if (argc==1)
        {
-               fprintf(stdout,"\n\t\t --==[ SPLAT! v%s Available Options... ]==--\n\n",splat_version);
+               fprintf(stdout,"\n\t\t --==[ %s v%s Available Options... ]==--\n\n",splat_name, splat_version);
+
                fprintf(stdout,"       -t txsite(s).qth (max of 4 with -c, max of 30 with -L)\n");
                fprintf(stdout,"       -r rxsite.qth\n");
                fprintf(stdout,"       -c plot coverage of TX(s) with an RX antenna at X feet/meters AGL\n");
@@ -6079,7 +7260,7 @@ int main(char argc, char *argv[])
                fprintf(stdout,"       -e filename of terrain elevation graph to plot\n");
                fprintf(stdout,"       -h filename of terrain height graph to plot\n");
                fprintf(stdout,"       -H filename of normalized terrain height graph to plot\n");
-               fprintf(stdout,"       -l filename of Longley-Rice graph to plot\n");
+               fprintf(stdout,"       -l filename of path loss graph to plot\n");
                fprintf(stdout,"       -o filename of topographic map to generate (.ppm)\n");
                fprintf(stdout,"       -u filename of user-defined terrain file to import\n");
                fprintf(stdout,"       -d sdf file directory path (overrides path in ~/.splat_path file)\n");
@@ -6088,20 +7269,40 @@ int main(char argc, char *argv[])
                fprintf(stdout,"       -N do not produce unnecessary site or obstruction reports\n");   
                fprintf(stdout,"       -f frequency for Fresnel zone calculation (MHz)\n");
                fprintf(stdout,"       -R modify default range for -c or -L (miles/kilometers)\n");
-               fprintf(stdout,"      -db maximum loss contour to display on path loss maps (80-230 dB)\n");
+               fprintf(stdout,"      -db threshold beyond which contours will not be displayed\n");
                fprintf(stdout,"      -nf do not plot Fresnel zones in height plots\n");
                fprintf(stdout,"      -fz Fresnel zone clearance percentage (default = 60)\n");
+               fprintf(stdout,"      -gc ground clutter height (feet/meters)\n");
                fprintf(stdout,"     -ngs display greyscale topography as white in .ppm files\n");      
                fprintf(stdout,"     -erp override ERP in .lrp file (Watts)\n");
-               fprintf(stdout,"     -pli filename of path-loss input file\n");
-               fprintf(stdout,"     -plo filename of path-loss output file\n");
-               fprintf(stdout,"     -udt filename of user defined terrain input file\n");
+               fprintf(stdout,"     -ano name of alphanumeric output file\n");
+               fprintf(stdout,"     -ani name of alphanumeric input file\n");
+               fprintf(stdout,"     -udt name of user defined terrain input file\n");
                fprintf(stdout,"     -kml generate Google Earth (.kml) compatible output\n");
                fprintf(stdout,"     -geo generate an Xastir .geo georeference file (with .ppm output)\n");
+               fprintf(stdout,"     -dbm plot signal power level contours rather than field strength\n");
+               fprintf(stdout,"   -gpsav preserve gnuplot temporary working files after SPLAT! execution\n");
                fprintf(stdout,"  -metric employ metric rather than imperial units for all user I/O\n\n");
                fprintf(stdout,"If that flew by too fast, consider piping the output through 'less':\n");
-               fprintf(stdout,"\n\tsplat | less\n\n");
+
+               if (HD_MODE==0)
+                       fprintf(stdout,"\n\tsplat | less\n\n");
+               else
+                       fprintf(stdout,"\n\tsplat-hd | less\n\n");
+
                fprintf(stdout,"Type 'man splat', or see the documentation for more details.\n\n");
+
+               y=(int)sqrt((int)MAXPAGES);
+
+               fprintf(stdout,"This compilation of %s supports analysis over a region of\n%d square ",splat_name,y);
+
+               if (y==1)
+
+                       fprintf(stdout,"degree");
+               else
+                       fprintf(stdout,"degrees");
+
+               fprintf(stdout," of terrain.\n\n");
                fflush(stdout);
 
                return 1;
@@ -6111,27 +7312,37 @@ int main(char argc, char *argv[])
 
        kml=0;
        geo=0;
+       dbm=0;
+       gpsav=0;
        metric=0;
        rxfile[0]=0;
        txfile[0]=0;
        string[0]=0;
        mapfile[0]=0;
+       clutter=0.0;
+       forced_erp=-1.0;
+       forced_freq=0.0;
        elevation_file[0]=0;
        terrain_file[0]=0;
        sdf_path[0]=0;
        udt_file[0]=0;
        path.length=0;
        max_txsites=30;
-       LR.frq_mhz=0.0;
        fzone_clearance=0.6;
+       contour_threshold=0;
        rx_site.lat=91.0;
        rx_site.lon=361.0;
        longley_file[0]=0;
-       plo_filename[0]=0;
-       pli_filename[0]=0;
+       ano_filename[0]=0;
+       ani_filename[0]=0;
        earthradius=EARTHRADIUS;
 
-       sprintf(header,"\n\t\t--==[ Welcome To SPLAT! v%s ]==--\n\n", splat_version);
+       ippd=IPPD;              /* pixels per degree (integer) */
+       ppd=(double)ippd;       /* pixels per degree (double)  */
+       dpp=1.0/ppd;            /* degrees per pixel */
+       mpi=ippd-1;             /* maximum pixel index per degree */
+
+       sprintf(header,"\n\t\t--==[ Welcome To %s v%s ]==--\n\n", splat_name, splat_version);
 
        for (x=0; x<4; x++)
        {
@@ -6187,6 +7398,19 @@ int main(char argc, char *argv[])
                        }                        
                }
 
+               if (strcmp(argv[x],"-gc")==0)
+               {
+                       z=x+1;
+
+                       if (z<=y && argv[z][0] && argv[z][0]!='-')
+                       {
+                               sscanf(argv[z],"%lf",&clutter);
+
+                               if (clutter<0.0)
+                                       clutter=0.0;
+                       }                        
+               }
+
                if (strcmp(argv[x],"-fz")==0)
                {
                        z=x+1;
@@ -6211,7 +7435,7 @@ int main(char argc, char *argv[])
                        map=1;
                }
 
-               if (strcmp(argv[x],"-u")==0)
+               if (strcmp(argv[x],"-udt")==0)
                {
                        z=x+1;
 
@@ -6237,18 +7461,8 @@ int main(char argc, char *argv[])
                {
                        z=x+1;
 
-                       if (z<=y && argv[z][0] && argv[z][0]!='-')
-                       {
-                               sscanf(argv[z],"%d",&maxdB);
-
-                               maxdB=abs(maxdB);
-
-                               if (maxdB<80)
-                                       maxdB=80;
-
-                               if (maxdB>230)
-                                       maxdB=230;
-                       }                        
+                       if (z<=y && argv[z][0]) /* A minus argument is legal here */
+                               sscanf(argv[z],"%d",&contour_threshold);
                }
 
                if (strcmp(argv[x],"-p")==0)
@@ -6295,6 +7509,9 @@ int main(char argc, char *argv[])
                if (strcmp(argv[x],"-metric")==0)
                        metric=1;
 
+               if (strcmp(argv[x],"-gpsav")==0)
+                       gpsav=1;
+
                if (strcmp(argv[x],"-geo")==0)
                        geo=1;
 
@@ -6302,7 +7519,7 @@ int main(char argc, char *argv[])
                        kml=1;
 
                if (strcmp(argv[x],"-nf")==0)
-                       nf=1;
+                       fresnel_plot=0;
 
                if (strcmp(argv[x],"-ngs")==0)
                        ngs=1;
@@ -6310,6 +7527,9 @@ int main(char argc, char *argv[])
                if (strcmp(argv[x],"-n")==0)
                        nolospath=1;
 
+               if (strcmp(argv[x],"-dbm")==0)
+                       dbm=1;
+
                if (strcmp(argv[x],"-N")==0)
                {
                        nolospath=1;
@@ -6422,14 +7642,14 @@ int main(char argc, char *argv[])
 
                        if (z<=y && argv[z][0] && argv[z][0]!='-')
                        {
-                               sscanf(argv[z],"%lf",&freq);
+                               sscanf(argv[z],"%lf",&forced_freq);
 
-                               if (freq<20)
-                                       freq=20;
+                               if (forced_freq<20.0)
+                                       forced_freq=0.0;
 
-                               if (freq>20e3)
-                                       freq=20e3;
-                       }                        
+                               if (forced_freq>20.0e3)
+                                       forced_freq=20.0e3;
+                       }
                }
 
                if (strcmp(argv[x],"-erp")==0)
@@ -6445,20 +7665,20 @@ int main(char argc, char *argv[])
                        }                        
                }
 
-               if (strcmp(argv[x],"-plo")==0)
+               if (strcmp(argv[x],"-ano")==0)
                {
                        z=x+1;
 
                        if (z<=y && argv[z][0] && argv[z][0]!='-')
-                               strncpy(plo_filename,argv[z],253);
+                               strncpy(ano_filename,argv[z],253);
                }
 
-               if (strcmp(argv[x],"-pli")==0)
+               if (strcmp(argv[x],"-ani")==0)
                {
                        z=x+1;
 
                        if (z<=y && argv[z][0] && argv[z][0]!='-')
-                               strncpy(pli_filename,argv[z],253);
+                               strncpy(ani_filename,argv[z],253);
                }
        }
 
@@ -6488,7 +7708,7 @@ int main(char argc, char *argv[])
                exit (-1);
        }
 
-       if ((coverage+LRmap+pli_filename[0])==0 && rx_site.lat==91.0 && rx_site.lon==361.0)
+       if ((coverage+LRmap+ani_filename[0])==0 && rx_site.lat==91.0 && rx_site.lon==361.0)
        {
                if (max_range!=0.0 && txsites!=0)
                {
@@ -6514,6 +7734,7 @@ int main(char argc, char *argv[])
                altitudeLR/=METERS_PER_FOOT;    /* meters --> feet */
                max_range/=KM_PER_MILE;         /* kilometers --> miles */
                altitude/=METERS_PER_FOOT;      /* meters --> feet */
+               clutter/=METERS_PER_FOOT;       /* meters --> feet */
        }
 
        /* If no SDF path was specified on the command line (-d), check
@@ -6525,12 +7746,12 @@ int main(char argc, char *argv[])
        if (sdf_path[0]==0)
        {
                env=getenv("HOME");
-               sprintf(string,"%s/.splat_path",env);
+               snprintf(string,253,"%s/.splat_path",env);
                fd=fopen(string,"r");
 
                if (fd!=NULL)
                {
-                       fgets(string,253,fd);
+                       s=fgets(string,253,fd);
 
                        /* Remove <CR> and/or <LF> from string */
 
@@ -6559,9 +7780,10 @@ int main(char argc, char *argv[])
        fprintf(stdout,"%s",header);
        fflush(stdout);
 
-       if (pli_filename[0])
+       if (ani_filename[0])
        {
-               y=LoadPLI(pli_filename);
+               ReadLRParm(tx_site[0],0); /* Get ERP status */
+               y=LoadANO(ani_filename);
 
                for (x=0; x<txsites && x<max_txsites; x++)
                        PlaceMarker(tx_site[x]);
@@ -6573,15 +7795,29 @@ int main(char argc, char *argv[])
                {
                        for (x=0; x<bfs; x++)
                                LoadBoundaries(boundary_file[x]);
+
+                       fprintf(stdout,"\n");
+                       fflush(stdout);
                }
 
                if (cities)
                {
                        for (x=0; x<cities; x++)
                                LoadCities(city_file[x]);
+
+                       fprintf(stdout,"\n");
+                       fflush(stdout);
                }
 
-               WritePPMLR(mapfile,geo,kml,ngs,tx_site,txsites);
+               if (LR.erp==0.0)
+                       WritePPMLR(mapfile,geo,kml,ngs,tx_site,txsites);
+               else
+               {
+                       if (dbm)
+                               WritePPMDBM(mapfile,geo,kml,ngs,tx_site,txsites);
+                       else
+                               WritePPMSS(mapfile,geo,kml,ngs,tx_site,txsites);
+               }
 
                exit(0);
        }
@@ -6609,7 +7845,7 @@ int main(char argc, char *argv[])
                if (LonDiff(txlon,min_lon)<0.0)
                        min_lon=txlon;
 
-               if (LonDiff(txlon,max_lon)>0.0)
+               if (LonDiff(txlon,max_lon)>=0.0)
                        max_lon=txlon;
        }
 
@@ -6627,11 +7863,10 @@ int main(char argc, char *argv[])
                if (LonDiff(rxlon,min_lon)<0.0)
                        min_lon=rxlon;
 
-               if (LonDiff(rxlon,max_lon)>0.0)
+               if (LonDiff(rxlon,max_lon)>=0.0)
                        max_lon=rxlon;
        }
 
-
        /* Load the required SDF files */ 
 
        LoadTopoData(max_lon, min_lon, max_lat, min_lat);
@@ -6653,21 +7888,20 @@ int main(char argc, char *argv[])
                        /* deg_range determines the maximum
                           amount of topo data we read */
 
-                       deg_range=(tx_range+rx_range)/69.0;
+                       deg_range=(tx_range+rx_range)/57.0;
 
-                       /* max_range sets the maximum size of the
+                       /* max_range regulates the 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
+                          SPLAT!  A large number will increase the
+                          width of the analysis and 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;
+                       deg_range=max_range/57.0;
 
                        /* Prevent the demand for a really wide coverage
                           from allocating more "pages" than are available
@@ -6675,6 +7909,9 @@ int main(char argc, char *argv[])
 
                        switch (MAXPAGES)
                        {
+                               case 1: deg_limit=0.125;
+                                       break;
+
                                case 2: deg_limit=0.25;
                                        break;
 
@@ -6684,16 +7921,26 @@ int main(char argc, char *argv[])
                                case 9: deg_limit=1.0;
                                        break;
 
-                               case 16: deg_limit=2.0;
+                               case 16: deg_limit=1.5;  /* WAS 2.0 */
+                                       break;
+
+                               case 25: deg_limit=2.0;  /* WAS 3.0 */
+                                       break;
+
+                               case 36: deg_limit=2.5;  /* New! */
+                                       break;
+
+                               case 49: deg_limit=3.0;  /* New! */
                                        break;
 
-                               case 25: deg_limit=3.0;
+                               case 64: deg_limit=3.5;  /* New! */
+                                       break;
                        }
 
-                       if (tx_site[z].lat<70.0)
-                               deg_range_lon=deg_range/cos(deg2rad*tx_site[z].lat);
+                       if (fabs(tx_site[z].lat)<70.0)
+                               deg_range_lon=deg_range/cos(DEG2RAD*tx_site[z].lat);
                        else
-                               deg_range_lon=deg_range/cos(deg2rad*70.0);
+                               deg_range_lon=deg_range/cos(DEG2RAD*70.0);
 
                        /* Correct for squares in degrees not being square in miles */  
 
@@ -6731,7 +7978,7 @@ int main(char argc, char *argv[])
                        if (LonDiff(west_min,min_lon)<0.0)
                                min_lon=west_min;
 
-                       if (LonDiff(west_max,max_lon)>0.0)
+                       if (LonDiff(west_max,max_lon)>=0.0)
                                max_lon=west_max;
                }
 
@@ -6750,90 +7997,92 @@ int main(char argc, char *argv[])
        {
                PlaceMarker(rx_site);
 
-               if (longley_plot)
+               if (terrain_plot)
                {
-                       /* Grab extension to determine graphic file type */
+                       /* Extract extension (if present)
+                          from "terrain_file" */
 
-                       for (x=0; longley_file[x]!='.' && longley_file[x]!=0 && x<80; x++);
+                       y=strlen(terrain_file);
 
-                       if (longley_file[x]=='.')
+                       for (x=y-1; x>0 && terrain_file[x]!='.'; x--);
+
+                       if (x>0)  /* Extension found */
                        {
-                               ext[0]='.';
-                               for (y=1, z=x, x++; longley_file[x]!=0 && x<253 && y<14; x++, y++)
-                                       ext[y]=longley_file[x];
+                               for (z=x+1; z<=y && (z-(x+1))<10; z++)
+                                       ext[z-(x+1)]=tolower(terrain_file[z]);
 
-                               ext[y]=0;
-                               longley_file[z]=0;
+                               ext[z-(x+1)]=0;     /* Ensure an ending 0 */
+                               terrain_file[x]=0;  /* Chop off extension */
                        }
 
                        else
-                       {
-                               ext[0]=0;  /* No extension */
-                               longley_file[x]=0;
-                       }
+                               strncpy(ext,"png\0",4);
                }
 
-               if (terrain_plot)
+               if (elevation_plot)
                {
-                       for (x=0; terrain_file[x]!='.' && terrain_file[x]!=0 && x<80; x++);
+                       /* Extract extension (if present)
+                          from "elevation_file" */
 
-                       if (terrain_file[x]=='.')  /* extension */
+                       y=strlen(elevation_file);
+
+                       for (x=y-1; x>0 && elevation_file[x]!='.'; x--);
+
+                       if (x>0)  /* Extension found */
                        {
-                               ext[0]='.';
-                               for (y=1, z=x, x++; terrain_file[x]!=0 && x<253 && y<14; x++, y++)
-                                       ext[y]=terrain_file[x];
+                               for (z=x+1; z<=y && (z-(x+1))<10; z++)
+                                       ext[z-(x+1)]=tolower(elevation_file[z]);
 
-                               ext[y]=0;
-                               terrain_file[z]=0;
+                               ext[z-(x+1)]=0;       /* Ensure an ending 0 */
+                               elevation_file[x]=0;  /* Chop off extension */
                        }
 
                        else
-                       {
-                               ext[0]=0;  /* No extension */
-                               terrain_file[x]=0;
-                       }
+                               strncpy(ext,"png\0",4);
                }
 
-               if (elevation_plot)
+               if (height_plot)
                {
-                       for (x=0; elevation_file[x]!='.' && elevation_file[x]!=0 && x<80; x++);
+                       /* Extract extension (if present)
+                          from "height_file" */
+
+                       y=strlen(height_file);
 
-                       if (elevation_file[x]=='.')  /* extension */
+                       for (x=y-1; x>0 && height_file[x]!='.'; x--);
+
+                       if (x>0)  /* Extension found */
                        {
-                               ext[0]='.';
-                               for (y=1, z=x, x++; elevation_file[x]!=0 && x<253 && y<14; x++, y++)
-                                       ext[y]=elevation_file[x];
+                               for (z=x+1; z<=y && (z-(x+1))<10; z++)
+                                       ext[z-(x+1)]=tolower(height_file[z]);
 
-                               ext[y]=0;
-                               elevation_file[z]=0;
+                               ext[z-(x+1)]=0;    /* Ensure an ending 0 */
+                               height_file[x]=0;  /* Chop off extension */
                        }
 
                        else
-                       {
-                               ext[0]=0;  /* No extension */
-                               elevation_file[x]=0;
-                       }
+                               strncpy(ext,"png\0",4);
                }
 
-               if (height_plot)
+               if (longley_plot)
                {
-                       for (x=0; height_file[x]!='.' && height_file[x]!=0 && x<80; x++);
+                       /* Extract extension (if present)
+                          from "longley_file" */
+
+                       y=strlen(longley_file);
+
+                       for (x=y-1; x>0 && longley_file[x]!='.'; x--);
 
-                       if (height_file[x]=='.')  /* extension */
+                       if (x>0)  /* Extension found */
                        {
-                               ext[0]='.';
-                               for (y=1, z=x, x++; height_file[x]!=0 && x<253 && y<14; x++, y++)
-                                       ext[y]=height_file[x];
+                               for (z=x+1; z<=y && (z-(x+1))<10; z++)
+                                       ext[z-(x+1)]=tolower(longley_file[z]);
 
-                               ext[y]=0;
-                               height_file[z]=0;
+                               ext[z-(x+1)]=0;     /* Ensure an ending 0 */
+                               longley_file[x]=0;  /* Chop off extension */
                        }
 
                        else
-                       {
-                               ext[0]=0;  /* No extension */
-                               height_file[x]=0;
-                       }
+                               strncpy(ext,"png\0",4);
                }
 
                for (x=0; x<txsites && x<4; x++)
@@ -6868,16 +8117,17 @@ int main(char argc, char *argv[])
                                WriteKML(tx_site[x],rx_site);
 
                        if (txsites>1)
-                               sprintf(string,"%s-%c%s%c",longley_file,'1'+x,ext,0);
+                               snprintf(string,250,"%s-%c.%s%c",longley_file,'1'+x,ext,0);
                        else
-                               sprintf(string,"%s%s%c",longley_file,ext,0);
+                               snprintf(string,250,"%s.%s%c",longley_file,ext,0);
 
                        if (nositereports==0)
                        {
                                if (longley_file[0]==0)
                                {
                                        ReadLRParm(tx_site[x],0);
-                                       PathReport(tx_site[x],rx_site,string,0);                                }
+                                       PathReport(tx_site[x],rx_site,string,0);
+                               }
 
                                else
                                {
@@ -6889,9 +8139,9 @@ int main(char argc, char *argv[])
                        if (terrain_plot)
                        {
                                if (txsites>1)
-                                       sprintf(string,"%s-%c%s%c",terrain_file,'1'+x,ext,0);
+                                       snprintf(string,250,"%s-%c.%s%c",terrain_file,'1'+x,ext,0);
                                else
-                                       sprintf(string,"%s%s%c",terrain_file,ext,0);
+                                       snprintf(string,250,"%s.%s%c",terrain_file,ext,0);
 
                                GraphTerrain(tx_site[x],rx_site,string);
                        }
@@ -6899,24 +8149,21 @@ int main(char argc, char *argv[])
                        if (elevation_plot)
                        {
                                if (txsites>1)
-                                       sprintf(string,"%s-%c%s%c",elevation_file,'1'+x,ext,0);
+                                       snprintf(string,250,"%s-%c.%s%c",elevation_file,'1'+x,ext,0);
                                else
-                                       sprintf(string,"%s%s%c",elevation_file,ext,0);
+                                       snprintf(string,250,"%s.%s%c",elevation_file,ext,0);
 
                                GraphElevation(tx_site[x],rx_site,string);
                        }
 
                        if (height_plot)
                        {
-                               if (freq==0.0 && nf==0)
-                                       freq=LR.frq_mhz;
-
                                if (txsites>1)
-                                       sprintf(string,"%s-%c%s%c",height_file,'1'+x,ext,0);
+                                       snprintf(string,250,"%s-%c.%s%c",height_file,'1'+x,ext,0);
                                else
-                                       sprintf(string,"%s%s%c",height_file,ext,0);
+                                       snprintf(string,250,"%s.%s%c",height_file,ext,0);
 
-                               GraphHeight(tx_site[x],rx_site,string,freq,norm);
+                               GraphHeight(tx_site[x],rx_site,string,fresnel_plot,norm);
                        }
                }
        }
@@ -6926,10 +8173,10 @@ int main(char argc, char *argv[])
                for (x=0; x<txsites && x<max_txsites; x++)
                {
                        if (coverage)
-                               PlotCoverage(tx_site[x],altitude);
+                               PlotLOSMap(tx_site[x],altitude);
 
                        else if (ReadLRParm(tx_site[x],1))
-                               PlotLRMap(tx_site[x],altitudeLR,plo_filename);
+                                       PlotLRMap(tx_site[x],altitudeLR,ano_filename);
 
                        SiteReport(tx_site[x]);
                }
@@ -6939,16 +8186,20 @@ int main(char argc, char *argv[])
        {
                /* Label the map */
 
+               if (kml==0)
+               {
+                       for (x=0; x<txsites && x<max_txsites; x++)
+                               PlaceMarker(tx_site[x]);
+               }
+
                if (cities)
                {
-                       if (kml==0)
-                       {
-                               for (x=0; x<txsites && x<max_txsites; x++)
-                                       PlaceMarker(tx_site[x]);
-                       }
 
                        for (y=0; y<cities; y++)
                                LoadCities(city_file[y]);
+
+                       fprintf(stdout,"\n");
+                       fflush(stdout);
                }
 
                /* Load city and county boundary data files */
@@ -6957,19 +8208,25 @@ int main(char argc, char *argv[])
                {
                        for (y=0; y<bfs; y++)
                                LoadBoundaries(boundary_file[y]);
+
+                       fprintf(stdout,"\n");
+                       fflush(stdout);
                }
 
                /* Plot the map */
 
                if (coverage || pt2pt_mode || topomap)
-                       WritePPM(mapfile,geo,kml,ngs);
+                       WritePPM(mapfile,geo,kml,ngs,tx_site,txsites);
 
                else
                {
                        if (LR.erp==0.0)
                                WritePPMLR(mapfile,geo,kml,ngs,tx_site,txsites);
                        else
-                               WritePPMSS(mapfile,geo,kml,ngs,tx_site,txsites);
+                               if (dbm)
+                                       WritePPMDBM(mapfile,geo,kml,ngs,tx_site,txsites);
+                               else
+                                       WritePPMSS(mapfile,geo,kml,ngs,tx_site,txsites);
                }
        }