Imported Upstream version 1.1.1
[debian/splat] / splat.cpp
index 2fe6fd42a616996b8233deeb5be5e240693427ba..3e17692aafa79b69d410cb869cc403462873f38d 100644 (file)
--- a/splat.cpp
+++ b/splat.cpp
@@ -1,9 +1,17 @@
 /****************************************************************************
 /****************************************************************************
-*                    SPLAT: A Terrain Analysis Program                     *
-*             Copyright John A. Magliacane, KD2BD 1997-2004                *
-*                       Last update: 24-Jan-2004                           *
+*      SPLAT: An RF Signal Propagation Loss and Terrain Analysis Tool       *
+*                        Last update: 31-Mar-2006                          *
 *****************************************************************************
 *****************************************************************************
+*           Project started in 1997 by John A. Magliacane, KD2BD           *
+*****************************************************************************
+*                                                                          *
+*     Extensively modified by J. D. McDonald in Jan. 2004 to include        *
+*    the Longley-Rice propagation model using C++ code from NTIA/ITS.      *
 *                                                                          *
 *                                                                          *
+*              See: http://flattop.its.bldrdoc.gov/itm.html                 *
+*                                                                          *
+*****************************************************************************
+*                                                                           *
 * This program is free software; you can redistribute it and/or modify it   *
 * under the terms of the GNU General Public License as published by the     *
 * Free Software Foundation; either version 2 of the License or any later    *
 * This program is free software; you can redistribute it and/or modify it   *
 * under the terms of the GNU General Public License as published by the     *
 * Free Software Foundation; either version 2 of the License or any later    *
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
 * for more details.                                                        *
 *                                                                          *
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
 * for more details.                                                        *
 *                                                                          *
-*****************************************************************************
-*                                                                          *
-*     Extensively modified by J. D. McDonald in Jan. 2004 to include        *
-*    the Longley-Rice propagation model using C++ code from NTIA/ITS.      *
-*                                                                          *
-*              See: http://elbert.its.bldrdoc.gov/itm.html                  *
-*                                                                          *
 *****************************************************************************
  g++ -Wall -O3 -s -lm -lbz2 -fomit-frame-pointer itm.cpp splat.cpp -o splat 
 *****************************************************************************/
 *****************************************************************************
  g++ -Wall -O3 -s -lm -lbz2 -fomit-frame-pointer itm.cpp splat.cpp -o splat 
 *****************************************************************************/
 #define ARRAYSIZE 30025
 #endif
 
 #define ARRAYSIZE 30025
 #endif
 
-char string[255], sdf_path[255], opened=0, *splat_version={"1.1.0"};
+char   string[255], sdf_path[255], opened=0, *splat_version={"1.1.1"};
 
 double TWOPI=6.283185307179586, HALFPI=1.570796326794896,
        PI=3.141592653589793, deg2rad=1.74532925199e-02,
        EARTHRADIUS=20902230.97, METERS_PER_MILE=1609.344,
        METERS_PER_FOOT=0.3048, earthradius, max_range=0.0;
 
 
 double TWOPI=6.283185307179586, HALFPI=1.570796326794896,
        PI=3.141592653589793, deg2rad=1.74532925199e-02,
        EARTHRADIUS=20902230.97, METERS_PER_MILE=1609.344,
        METERS_PER_FOOT=0.3048, earthradius, max_range=0.0;
 
-int    min_north=0, max_north=0, min_west=0, max_west=0,
-       max_elevation=0, min_elevation=0, bzerror;
+int    min_north=90, max_north=-90, min_west=360, max_west=-1,
+       max_elevation=-32768, min_elevation=32768, bzerror, maxdB=230;
 
 struct site { double lat;
              double lon;
              double alt;
              char name[50];
 
 struct site { double lat;
              double lon;
              double alt;
              char name[50];
-           };
-
-struct { float lat[ARRAYSIZE];
-         float lon[ARRAYSIZE];
-         float elevation[ARRAYSIZE];
-         float distance[ARRAYSIZE];
-         int length;
-       } path;
-
-struct { int min_north;
-        int max_north;
-        int min_west;
-        int max_west;
-        int max_el;
-        int min_el;
-        short data[1200][1200];
-        unsigned char mask[1200][1200];
-       } dem[MAXSLOTS];
-
-struct {
-       double eps_dielect; 
-       double sgm_conductivity; 
-       double eno_ns_surfref;
-       double frq_mhz; 
-       double conf; 
-       double rel;
-       int radio_climate;  
-       int pol;
-       } LR;
+           } site;
+
+struct path { float lat[ARRAYSIZE];
+              float lon[ARRAYSIZE];
+              float elevation[ARRAYSIZE];
+              float distance[ARRAYSIZE];
+              int length;
+            } path;
+
+struct dem { int min_north;
+            int max_north;
+            int min_west;
+            int max_west;
+            int max_el;
+            int min_el;
+            short data[1200][1200];
+            unsigned char mask[1200][1200];
+           } dem[MAXSLOTS];
+
+struct LR { double eps_dielect; 
+           double sgm_conductivity; 
+           double eno_ns_surfref;
+           double frq_mhz; 
+           double conf; 
+           double rel;
+           int radio_climate;  
+           int pol;
+          } LR;
 
 double elev_l[ARRAYSIZE+10];
 
 
 double elev_l[ARRAYSIZE+10];
 
@@ -122,6 +122,18 @@ double arccos(double x, double y)
        return result;
 }
 
        return result;
 }
 
+int ReduceAngle(double angle)
+{
+       /* This function normalizes the argument to
+          an integer angle between 0 and 180 degrees */
+
+       double temp;
+
+       temp=acos(cos(angle*deg2rad));
+
+       return (int)rint(temp/deg2rad);
+}
+
 char *dec2dms(double decimal)
 {
        /* Converts decimal degrees to degrees, minutes, seconds,
 char *dec2dms(double decimal)
 {
        /* Converts decimal degrees to degrees, minutes, seconds,
@@ -130,6 +142,9 @@ char *dec2dms(double decimal)
        int degrees, minutes, seconds;
        double a, b, c, d;
 
        int degrees, minutes, seconds;
        double a, b, c, d;
 
+       if (decimal<0.0)
+               decimal=-decimal;
+
        a=floor(decimal);
        b=60.0*(decimal-a);
        c=floor(b);
        a=floor(decimal);
        b=60.0*(decimal-a);
        c=floor(b);
@@ -176,8 +191,10 @@ int OrMask(double lat, double lon, int value)
                y=(int)(1199.0*(lon-floor(lon)));
 
                dem[indx].mask[x][y]|=value;
                y=(int)(1199.0*(lon-floor(lon)));
 
                dem[indx].mask[x][y]|=value;
+
                return (dem[indx].mask[x][y]);
        }
                return (dem[indx].mask[x][y]);
        }
+
        else
                return -1;
 }
        else
                return -1;
 }
@@ -212,6 +229,7 @@ double GetElevation(struct site location)
        {
                if (minlat==dem[indx].min_north && minlon==dem[indx].min_west)
                {
        {
                if (minlat==dem[indx].min_north && minlon==dem[indx].min_west)
                {
+
                        elevation=3.28084*dem[indx].data[x][y];
                        found=1;
                }
                        elevation=3.28084*dem[indx].data[x][y];
                        found=1;
                }
@@ -318,19 +336,17 @@ void ReadPath(struct site source, struct site destination)
           elevation and distance information for points along
           that path in the "path" structure for later use. */
 
           elevation and distance information for points along
           that path in the "path" structure for later use. */
 
+       int c;
        double azimuth, distance, lat1, lon1, beta,
               den, num, lat2, lon2, total_distance;
        double azimuth, distance, lat1, lon1, beta,
               den, num, lat2, lon2, total_distance;
-       int x1, y1, c;
        struct site tempsite;
 
        struct site tempsite;
 
-       c=0;
-
        lat1=source.lat*deg2rad;
        lon1=source.lon*deg2rad;
        azimuth=Azimuth(source,destination)*deg2rad;
        total_distance=Distance(source,destination);
 
        lat1=source.lat*deg2rad;
        lon1=source.lon*deg2rad;
        azimuth=Azimuth(source,destination)*deg2rad;
        total_distance=Distance(source,destination);
 
-       for (distance=0; distance<=total_distance; distance+=0.04)
+       for (distance=0, c=0; distance<=total_distance; distance+=0.04)
        {
                beta=distance/3959.0;
                lat2=asin(sin(lat1)*cos(beta)+cos(azimuth)*sin(beta)*cos(lat1));
        {
                beta=distance/3959.0;
                lat2=asin(sin(lat1)*cos(beta)+cos(azimuth)*sin(beta)*cos(lat1));
@@ -363,30 +379,33 @@ void ReadPath(struct site source, struct site destination)
                lat2=lat2/deg2rad;
                lon2=lon2/deg2rad;
 
                lat2=lat2/deg2rad;
                lon2=lon2/deg2rad;
 
-               x1=(int)(1199.0*(lat2-floor(lat2)));
-               y1=(int)(1199.0*(lon2-floor(lon2)));
-
-               path.lat[c]=lat2;
-               path.lon[c]=lon2;
-               tempsite.lat=lat2;
-               tempsite.lon=lon2;
-               path.elevation[c]=GetElevation(tempsite);
-               path.distance[c]=distance;
-               c++;
+               if (c<ARRAYSIZE)
+               {
+                       path.lat[c]=lat2;
+                       path.lon[c]=lon2;
+                       tempsite.lat=lat2;
+                       tempsite.lon=lon2;
+                       path.elevation[c]=GetElevation(tempsite);
+                       path.distance[c]=distance;
+                       c++;
+               }
        }
 
        /* Make sure exact destination point is recorded at path.length-1 */
 
        }
 
        /* Make sure exact destination point is recorded at path.length-1 */
 
-       x1=(int)(1199.0*(destination.lat-floor(destination.lat)));
-       y1=(int)(1199.0*(destination.lon-floor(destination.lon)));
-
-       path.lat[c]=destination.lat;
-       path.lon[c]=destination.lon;
-       path.elevation[c]=GetElevation(destination);
-       path.distance[c]=total_distance;
-       c++;
+       if (c<ARRAYSIZE)
+       {
+               path.lat[c]=destination.lat;
+               path.lon[c]=destination.lon;
+               path.elevation[c]=GetElevation(destination);
+               path.distance[c]=total_distance;
+               c++;
+       }
 
 
-       path.length=c;
+       if (c<ARRAYSIZE)
+               path.length=c;
+       else
+               path.length=ARRAYSIZE-1;
 }
 
 double AverageTerrain(struct site source, double azimuthx, double start_distance, double end_distance)
 }
 
 double AverageTerrain(struct site source, double azimuthx, double start_distance, double end_distance)
@@ -522,6 +541,27 @@ 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
 void PlaceMarker(struct site location)
 {
        /* This function places text and marker data in the mask array
@@ -546,7 +586,8 @@ void PlaceMarker(struct site location)
        lat=location.lat;
        lon=location.lon;
 
        lat=location.lat;
        lon=location.lon;
 
-       if (lat<xmax && lat>xmin && lon<ymax && lon>ymin)
+
+       if (lat<xmax && lat>xmin && (LonDiff(lon,ymax)<0.0) && (LonDiff(lon,ymin)>0.0))
        {
                p1=1.0/1200.0;
                p3=3.0/1200.0;
        {
                p1=1.0/1200.0;
                p3=3.0/1200.0;
@@ -561,7 +602,7 @@ void PlaceMarker(struct site location)
                /* Is Marker Position Clear Of Text Or Other Markers? */
 
                for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
                /* Is Marker Position Clear Of Text Or Other Markers? */
 
                for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
-                       for (y=lon-p3; (y<=ymax && y>=ymin && y<=lon+p3); y+=p1)
+                       for (y=lon-p3; (LonDiff(y,ymax)<=0.0) && (LonDiff(y,ymin)>=0.0) && (LonDiff(y,lon+p3)<=0.0); y+=p1)
                                occupied|=(GetMask(x,y)&2);
 
                if (occupied==0)
                                occupied|=(GetMask(x,y)&2);
 
                if (occupied==0)
@@ -573,7 +614,7 @@ void PlaceMarker(struct site location)
 
                        label_length=p1*(double)(strlen(location.name)<<3);
 
 
                        label_length=p1*(double)(strlen(location.name)<<3);
 
-                       if (((lon+label_length)<=ymax) && (lon-label_length)>=ymin)
+                       if ((LonDiff(lon+label_length,ymax)<=0.0) && (LonDiff(lon-label_length,ymin)>=0.0))
                        {
                                /* Default: Centered Text */
 
                        {
                                /* Default: Centered Text */
 
@@ -638,7 +679,7 @@ void PlaceMarker(struct site location)
 
                        if (ok2print==0)
                        {
 
                        if (ok2print==0)
                        {
-                               if ((lon-label_length)>=ymin)
+                               if (LonDiff(lon-label_length,ymin)>=0.0)
                                {
                                        /* Position Text To The
                                           Right Of The Marker */
                                {
                                        /* Position Text To The
                                           Right Of The Marker */
@@ -703,7 +744,7 @@ void PlaceMarker(struct site location)
                           coordinates that describe the placement of the text
                           on the map. */
        
                           coordinates that describe the placement of the text
                           on the map. */
        
-                       if (ok2print && textx!=0.0 && texty!=0.0)
+                       if (ok2print)
                        {
                                /* Draw Text */
 
                        {
                                /* Draw Text */
 
@@ -720,6 +761,7 @@ void PlaceMarker(struct site location)
                                                        if (byte&c)
                                                                OrMask(x,y,2);
                                        }
                                                        if (byte&c)
                                                                OrMask(x,y,2);
                                        }
+
                                        x-=p1;
                                        y=texty;
                                }
                                        x-=p1;
                                        y=texty;
                                }
@@ -728,7 +770,7 @@ void PlaceMarker(struct site location)
                                   On Location Specified */
        
                                for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
                                   On Location Specified */
        
                                for (x=lat-p3; (x<=xmax && x>=xmin && x<=lat+p3); x+=p1)
-                                       for (y=lon-p3; (y<=ymax && y>=ymin && y<=lon+p3); y+=p1)
+                                       for (y=lon-p3; (LonDiff(y,ymax)<=0.0) && (LonDiff(y,ymin)>=0.0) && (LonDiff(y,lon+p3)<=0.0); y+=p1)
                                                OrMask(x,y,2);
                        }
                }
                                                OrMask(x,y,2);
                        }
                }
@@ -746,10 +788,9 @@ double ReadBearing(char *input)
           embedded within the numbers expressed in the
           input string.  Decimal seconds are permitted. */
  
           embedded within the numbers expressed in the
           input string.  Decimal seconds are permitted. */
  
-       double bearing=0.0;
+       double seconds, bearing=0.0;
        char string[20];
        int a, b, length, degrees, minutes;
        char string[20];
        int a, b, length, degrees, minutes;
-       double seconds;
 
        /* Copy "input" to "string", and ignore any extra
           spaces that might be present in the process. */
 
        /* Copy "input" to "string", and ignore any extra
           spaces that might be present in the process. */
@@ -787,7 +828,7 @@ double ReadBearing(char *input)
 
        /* Anything else returns a 0.0 */
 
 
        /* Anything else returns a 0.0 */
 
-       if (bearing>360.0 || bearing<0.0)
+       if (bearing>360.0 || bearing<-90.0)
                bearing=0.0;
 
        return bearing;
                bearing=0.0;
 
        return bearing;
@@ -817,8 +858,8 @@ struct site LoadQTH(char *filename)
        qthfile[x+3]='h';
        qthfile[x+4]=0;
 
        qthfile[x+3]='h';
        qthfile[x+4]=0;
 
-       tempsite.lat=0.0;
-       tempsite.lon=0.0;
+       tempsite.lat=91.0;
+       tempsite.lon=361.0;
        tempsite.alt=0.0;
        tempsite.name[0]=0;
 
        tempsite.alt=0.0;
        tempsite.name[0]=0;
 
@@ -907,11 +948,8 @@ int LoadSDF_SDF(char *name)
 
        for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
        {
 
        for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
        {
-               if (minlat!=0 && minlon!=0)
-               {
-                       if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
-                               found=1;
-               }
+               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
+                       found=1;
        }
 
        /* Is room available to load it? */
        }
 
        /* Is room available to load it? */
@@ -919,19 +957,31 @@ int LoadSDF_SDF(char *name)
        if (found==0)
        {       
                for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
        if (found==0)
        {       
                for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
-                       if (dem[indx].max_north==0 && dem[indx].max_west==0)
+                       if (dem[indx].max_north==-90)
                                free_slot=1;
        }
 
        indx--;
 
                                free_slot=1;
        }
 
        indx--;
 
-       if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS && minlat!=0 && minlon!=0)
+       if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS)
        {
        {
-               strncpy(path_plus_name,sdf_path,255);
-               strncat(path_plus_name,sdf_file,255);
+               /* Search for SDF file in current working directory first */
+
+               strncpy(path_plus_name,sdf_file,255);
 
                fd=fopen(path_plus_name,"rb");
 
 
                fd=fopen(path_plus_name,"rb");
 
+               if (fd==NULL)
+               {
+                       /* Next, try loading SDF file from path specified
+                          in $HOME/.splat_path file or by -d argument */
+
+                       strncpy(path_plus_name,sdf_path,255);
+                       strncat(path_plus_name,sdf_file,255);
+
+                       fd=fopen(path_plus_name,"rb");
+               }
+
                if (fd!=NULL)
                {
                        fprintf(stdout,"Loading \"%s\" into slot %d...",path_plus_name,indx+1);
                if (fd!=NULL)
                {
                        fprintf(stdout,"Loading \"%s\" into slot %d...",path_plus_name,indx+1);
@@ -954,54 +1004,70 @@ int LoadSDF_SDF(char *name)
                                {
                                        fgets(line,19,fd);
                                        sscanf(line,"%d",&data);
                                {
                                        fgets(line,19,fd);
                                        sscanf(line,"%d",&data);
+
                                        dem[indx].data[x][y]=data;
 
                                        if (data>dem[indx].max_el)
                                                dem[indx].max_el=data;
 
                                        dem[indx].data[x][y]=data;
 
                                        if (data>dem[indx].max_el)
                                                dem[indx].max_el=data;
 
-                                       if (dem[indx].min_el==0)
+                                       if (data<dem[indx].min_el)
                                                dem[indx].min_el=data;
                                                dem[indx].min_el=data;
-                                       else
-                                       {
-                                                if (data<dem[indx].min_el)
-                                                       dem[indx].min_el=data;
-                                       }
                                }
 
                        fclose(fd);
 
                                }
 
                        fclose(fd);
 
-                       if (min_elevation==0)
+                       if (dem[indx].min_el<min_elevation)
                                min_elevation=dem[indx].min_el;
 
                                min_elevation=dem[indx].min_el;
 
-                       else
-                       {
-                               if (dem[indx].min_el<min_elevation)
-                                       min_elevation=dem[indx].min_el;
-                       }
-
                        if (dem[indx].max_el>max_elevation)
                                max_elevation=dem[indx].max_el;
 
                        if (dem[indx].max_el>max_elevation)
                                max_elevation=dem[indx].max_el;
 
-                       if (dem[indx].max_north>max_north)
+                       if (max_north==-90)
                                max_north=dem[indx].max_north;
 
                                max_north=dem[indx].max_north;
 
-                       if (dem[indx].max_west>max_west)
-                               max_west=dem[indx].max_west;
+                       else if (dem[indx].max_north>max_north)
+                               max_north=dem[indx].max_north;
 
 
-                       if (min_north==0)
+                       if (min_north==90)
                                min_north=dem[indx].min_north;
                                min_north=dem[indx].min_north;
+
+                       else if (dem[indx].min_north<min_north)
+                               min_north=dem[indx].min_north;
+
+                       if (max_west==-1)
+                               max_west=dem[indx].max_west;
+
                        else
                        {
                        else
                        {
-                               if (dem[indx].min_north<min_north)
-                                       min_north=dem[indx].min_north;
+                               if (abs(dem[indx].max_west-max_west)<180)
+                               {
+                                       if (dem[indx].max_west>max_west)
+                                               max_west=dem[indx].max_west;
+                               }
+
+                               else
+                               {
+                                       if (dem[indx].max_west<max_west)
+                                               max_west=dem[indx].max_west;
+                               }
                        }
 
                        }
 
-                       if (min_west==0)
+                       if (min_west==360)
                                min_west=dem[indx].min_west;
                                min_west=dem[indx].min_west;
+
                        else
                        {
                        else
                        {
-                               if (dem[indx].min_west<min_west)
-                                       min_west=dem[indx].min_west;
+                               if (abs(dem[indx].min_west-min_west)<180)
+                               {
+                                       if (dem[indx].min_west<min_west)
+                                               min_west=dem[indx].min_west;
+                               }
+
+                               else
+                               {
+                                       if (dem[indx].min_west>min_west)
+                                               min_west=dem[indx].min_west;
+                               }
                        }
 
                        fprintf(stdout," Done!\n");
                        }
 
                        fprintf(stdout," Done!\n");
@@ -1111,11 +1177,8 @@ int LoadSDF_BZ(char *name)
 
        for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
        {
 
        for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
        {
-               if (minlat!=0 && minlon!=0)
-               {
-                       if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
-                               found=1;
-               }
+               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
+                       found=1;
        }
 
        /* Is room available to load it? */
        }
 
        /* Is room available to load it? */
@@ -1123,20 +1186,33 @@ int LoadSDF_BZ(char *name)
        if (found==0)
        {       
                for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
        if (found==0)
        {       
                for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
-                       if (dem[indx].max_north==0 && dem[indx].max_west==0)
+                       if (dem[indx].max_north==-90)
                                free_slot=1;
        }
 
        indx--;
 
                                free_slot=1;
        }
 
        indx--;
 
-       if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS && minlat!=0 && minlon!=0)
+       if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS)
        {
        {
-               strncpy(path_plus_name,sdf_path,255);
-               strncat(path_plus_name,sdf_file,255);
+               /* Search for SDF file in current working directory first */
+
+               strncpy(path_plus_name,sdf_file,255);
 
                fd=fopen(path_plus_name,"rb");
                bzfd=BZ2_bzReadOpen(&bzerror,fd,0,0,NULL,0);
 
 
                fd=fopen(path_plus_name,"rb");
                bzfd=BZ2_bzReadOpen(&bzerror,fd,0,0,NULL,0);
 
+               if (fd==NULL || bzerror!=BZ_OK)
+               {
+                       /* Next, try loading SDF file from path specified
+                          in $HOME/.splat_path file or by -d argument */
+
+                       strncpy(path_plus_name,sdf_path,255);
+                       strncat(path_plus_name,sdf_file,255);
+
+                       fd=fopen(path_plus_name,"rb");
+                       bzfd=BZ2_bzReadOpen(&bzerror,fd,0,0,NULL,0);
+               }
+
                if (fd!=NULL && bzerror==BZ_OK)
                {
                        fprintf(stdout,"Loading \"%s\" into slot %d...",path_plus_name,indx+1);
                if (fd!=NULL && bzerror==BZ_OK)
                {
                        fprintf(stdout,"Loading \"%s\" into slot %d...",path_plus_name,indx+1);
@@ -1151,56 +1227,72 @@ int LoadSDF_BZ(char *name)
                                for (y=0; y<1200; y++)
                                {
                                        sscanf(BZfgets(bzfd,20),"%d",&data);
                                for (y=0; y<1200; y++)
                                {
                                        sscanf(BZfgets(bzfd,20),"%d",&data);
+
                                        dem[indx].data[x][y]=data;
 
                                        if (data>dem[indx].max_el)
                                                dem[indx].max_el=data;
 
                                        dem[indx].data[x][y]=data;
 
                                        if (data>dem[indx].max_el)
                                                dem[indx].max_el=data;
 
-                                       if (dem[indx].min_el==0)
+                                       if (data<dem[indx].min_el)
                                                dem[indx].min_el=data;
                                                dem[indx].min_el=data;
-                                       else
-                                       {
-                                                if (data<dem[indx].min_el)
-                                                       dem[indx].min_el=data;
-                                       }
                                }
 
                        fclose(fd);
 
                        BZ2_bzReadClose(&bzerror,bzfd);
 
                                }
 
                        fclose(fd);
 
                        BZ2_bzReadClose(&bzerror,bzfd);
 
-                       if (min_elevation==0)
+                       if (dem[indx].min_el<min_elevation)
                                min_elevation=dem[indx].min_el;
                                min_elevation=dem[indx].min_el;
-
-                       else
-                       {
-                               if (dem[indx].min_el<min_elevation)
-                                       min_elevation=dem[indx].min_el;
-                       }
        
                        if (dem[indx].max_el>max_elevation)
                                max_elevation=dem[indx].max_el;
 
        
                        if (dem[indx].max_el>max_elevation)
                                max_elevation=dem[indx].max_el;
 
-                       if (dem[indx].max_north>max_north)
+                       if (max_north==-90)
                                max_north=dem[indx].max_north;
 
                                max_north=dem[indx].max_north;
 
-                       if (dem[indx].max_west>max_west)
-                               max_west=dem[indx].max_west;
+                       else if (dem[indx].max_north>max_north)
+                               max_north=dem[indx].max_north;
+
+                       if (min_north==90)
+                               min_north=dem[indx].min_north;
 
 
-                       if (min_north==0)
+                       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;
+
                        else
                        {
                        else
                        {
-                               if (dem[indx].min_north<min_north)
-                                       min_north=dem[indx].min_north;
+                               if (abs(dem[indx].max_west-max_west)<180)
+                               {
+                                       if (dem[indx].max_west>max_west)
+                                               max_west=dem[indx].max_west;
+                               }
+
+                               else
+                               {
+                                       if (dem[indx].max_west<max_west)
+                                               max_west=dem[indx].max_west;
+                               }
                        }
 
                        }
 
-                       if (min_west==0)
+                       if (min_west==360)
                                min_west=dem[indx].min_west;
                                min_west=dem[indx].min_west;
+
                        else
                        {
                        else
                        {
-                               if (dem[indx].min_west<min_west)
-                                       min_west=dem[indx].min_west;
+                               if (abs(dem[indx].min_west-min_west)<180)
+                               {
+                                       if (dem[indx].min_west<min_west)
+                                               min_west=dem[indx].min_west;
+                               }
+
+                               else
+                               {
+                                       if (dem[indx].min_west>min_west)
+                                               min_west=dem[indx].min_west;
+                               }
                        }
 
                        fprintf(stdout," Done!\n");
                        }
 
                        fprintf(stdout," Done!\n");
@@ -1250,11 +1342,8 @@ char LoadSDF(char *name)
 
                for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
                {
 
                for (indx=0, found=0; indx<MAXSLOTS && found==0; indx++)
                {
-                       if (minlat!=0 && minlon!=0)
-                       {
-                               if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
-                                       found=1;
-                       }
+                       if (minlat==dem[indx].min_north && minlon==dem[indx].min_west && maxlat==dem[indx].max_north && maxlon==dem[indx].max_west)
+                               found=1;
                }
 
                /* Is room available to load it? */
                }
 
                /* Is room available to load it? */
@@ -1262,13 +1351,13 @@ char LoadSDF(char *name)
                if (found==0)
                {       
                        for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
                if (found==0)
                {       
                        for (indx=0, free_slot=0; indx<MAXSLOTS && free_slot==0; indx++)
-                               if (dem[indx].max_north==0 && dem[indx].max_west==0)
+                               if (dem[indx].max_north==-90)
                                        free_slot=1;
                }
 
                indx--;
 
                                        free_slot=1;
                }
 
                indx--;
 
-               if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS && minlat!=0 && minlon!=0)
+               if (free_slot && found==0 && indx>=0 && indx<MAXSLOTS)
                {
                        fprintf(stdout,"Region  \"%s\" assumed as sea-level into slot %d...",name,indx+1);
                        fflush(stdout);
                {
                        fprintf(stdout,"Region  \"%s\" assumed as sea-level into slot %d...",name,indx+1);
                        fflush(stdout);
@@ -1278,6 +1367,8 @@ char LoadSDF(char *name)
                        dem[indx].min_west=minlon;
                        dem[indx].max_north=maxlat;
 
                        dem[indx].min_west=minlon;
                        dem[indx].max_north=maxlat;
 
+                       /* Fill DEM with sea-level topography */
+
                        for (x=0; x<1200; x++)
                                for (y=0; y<1200; y++)
                                {
                        for (x=0; x<1200; x++)
                                for (y=0; y<1200; y++)
                                {
@@ -1293,26 +1384,52 @@ char LoadSDF(char *name)
                        if (dem[indx].max_el>max_elevation)
                                max_elevation=dem[indx].max_el;
 
                        if (dem[indx].max_el>max_elevation)
                                max_elevation=dem[indx].max_el;
 
-                       if (dem[indx].max_north>max_north)
+                       if (max_north==-90)
                                max_north=dem[indx].max_north;
 
                                max_north=dem[indx].max_north;
 
-                       if (dem[indx].max_west>max_west)
-                               max_west=dem[indx].max_west;
+                       else if (dem[indx].max_north>max_north)
+                               max_north=dem[indx].max_north;
 
 
-                       if (min_north==0)
+                       if (min_north==90)
                                min_north=dem[indx].min_north;
                                min_north=dem[indx].min_north;
+
+                       else if (dem[indx].min_north<min_north)
+                               min_north=dem[indx].min_north;
+
+                       if (max_west==-1)
+                               max_west=dem[indx].max_west;
+
                        else
                        {
                        else
                        {
-                               if (dem[indx].min_north<min_north)
-                                       min_north=dem[indx].min_north;
+                               if (abs(dem[indx].max_west-max_west)<180)
+                               {
+                                       if (dem[indx].max_west>max_west)
+                                               max_west=dem[indx].max_west;
+                               }
+
+                               else
+                               {
+                                       if (dem[indx].max_west<max_west)
+                                               max_west=dem[indx].max_west;
+                               }
                        }
 
                        }
 
-                       if (min_west==0)
+                       if (min_west==360)
                                min_west=dem[indx].min_west;
                                min_west=dem[indx].min_west;
+
                        else
                        {
                        else
                        {
-                               if (dem[indx].min_west<min_west)
-                                       min_west=dem[indx].min_west;
+                               if (abs(dem[indx].min_west-min_west)<180)
+                               {
+                                       if (dem[indx].min_west<min_west)
+                                               min_west=dem[indx].min_west;
+                               }
+
+                               else
+                               {
+                                       if (dem[indx].min_west>min_west)
+                                               min_west=dem[indx].min_west;
+                               }
                        }
 
                        fprintf(stdout," Done!\n");
                        }
 
                        fprintf(stdout," Done!\n");
@@ -1415,7 +1532,7 @@ void LoadBoundaries(char *filename)
                        do
                        {
                                sscanf(string,"%lf %lf", &lon1, &lat1);
                        do
                        {
                                sscanf(string,"%lf %lf", &lon1, &lat1);
-                       
+
                                lon0=fabs(lon0);
                                lon1=fabs(lon1);
 
                                lon0=fabs(lon0);
                                lon1=fabs(lon1);
 
@@ -1445,6 +1562,7 @@ void LoadBoundaries(char *filename)
                fprintf(stdout,"Done!\n");
                fflush(stdout);
        }
                fprintf(stdout,"Done!\n");
                fflush(stdout);
        }
+
        else
                fprintf(stderr,"*** ERROR: \"%s\": not found!\n",filename);
 }
        else
                fprintf(stderr,"*** ERROR: \"%s\": not found!\n",filename);
 }
@@ -1794,7 +1912,7 @@ void PlotPath(struct site source, struct site destination, char mask_value)
                                cos_test_angle=((rx_alt*rx_alt)+(distance*distance)-(test_alt*test_alt))/(2.0*rx_alt*distance);
 
                                /* Compare these two angles to determine if
                                cos_test_angle=((rx_alt*rx_alt)+(distance*distance)-(test_alt*test_alt))/(2.0*rx_alt*distance);
 
                                /* Compare these two angles to determine if
-                                  a blockage exists.  Since we're comparing
+                                  an obstruction exists.  Since we're comparing
                                   the cosines of these angles rather than
                                   the angles themselves, the following "if"
                                   statement is reversed from what it would
                                   the cosines of these angles rather than
                                   the angles themselves, the following "if"
                                   statement is reversed from what it would
@@ -1828,8 +1946,7 @@ void PlotLRPath(struct site source, struct site destination)
         
        for (y=0; y<path.length; y++)
        {
         
        for (y=0; y<path.length; y++)
        {
-               /* Test this point only if it
-                  has not already been tested. */
+               /* Test this point only if it has not already been tested. */
 
                if (GetMask(path.lat[y],path.lon[y])==0 && 0.04*y<=max_range)
                {
 
                if (GetMask(path.lat[y],path.lon[y])==0 && 0.04*y<=max_range)
                {
@@ -1841,8 +1958,9 @@ void PlotLRPath(struct site source, struct site destination)
                        LR.frq_mhz, LR.radio_climate, LR.pol, LR.conf, LR.rel,
                        loss, strmode, errnum);
 
                        LR.frq_mhz, LR.radio_climate, LR.pol, LR.conf, LR.rel,
                        loss, strmode, errnum);
 
-                       /* Note: PASS BY REFERENCE ... loss and errnum are pass
-                       by reference, only used in this file by this function */
+                       /* Note: PASS BY REFERENCE ... loss and errnum are
+                          passed by reference, and are only used in this
+                          file by this function */
 
                        if (loss>225.0)
                                loss=225.0;
 
                        if (loss>225.0)
                                loss=225.0;
@@ -1873,7 +1991,7 @@ void PlotCoverage(struct site source, double altitude)
           of a topographic map when the WritePPM() function
           is later invoked. */
 
           of a topographic map when the WritePPM() function
           is later invoked. */
 
-       double lat, lon, one_pixel;
+       float lat, lon, one_pixel;
        static unsigned char mask_value;
        int z, count;
        struct site edge;
        static unsigned char mask_value;
        int z, count;
        struct site edge;
@@ -1899,10 +2017,13 @@ void PlotCoverage(struct site source, double altitude)
        /* 18.75=1200 pixels/degree divided by 64 loops
           per progress indicator symbol (.oOo) printed. */
 
        /* 18.75=1200 pixels/degree divided by 64 loops
           per progress indicator symbol (.oOo) printed. */
 
-       z=(int)(18.75*(max_west-min_west));
+       z=(int)(18.75*ReduceAngle(max_west-min_west));
 
 
-       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
        {
        {
+               if (lon>=360.0)
+                       lon-=360.0;
+
                edge.lat=max_north;
                edge.lon=lon;
                edge.alt=altitude;
                edge.lat=max_north;
                edge.lon=lon;
                edge.alt=altitude;
@@ -1955,10 +2076,13 @@ void PlotCoverage(struct site source, double altitude)
        fprintf(stdout,"\n50%c to  75%c ",37,37);
        fflush(stdout);
 
        fprintf(stdout,"\n50%c to  75%c ",37,37);
        fflush(stdout);
 
-       z=(int)(18.75*(max_west-min_west));
+       z=(int)(18.75*ReduceAngle(max_west-min_west));
 
 
-       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
        {
        {
+               if (lon>=360.0)
+                       lon-=360.0;
+
                edge.lat=min_north;
                edge.lon=lon;
                edge.alt=altitude;
                edge.lat=min_north;
                edge.lon=lon;
                edge.alt=altitude;
@@ -2040,7 +2164,7 @@ void PlotLRMap(struct site source, double altitude)
 
        int z, count;
        struct site edge;
 
        int z, count;
        struct site edge;
-       double lat, lon, one_pixel;
+       float lat, lon, one_pixel;
        unsigned char symbol[4], x;
 
        one_pixel=1.0/1200.0;
        unsigned char symbol[4], x;
 
        one_pixel=1.0/1200.0;
@@ -2059,10 +2183,13 @@ void PlotLRMap(struct site source, double altitude)
        /* 18.75=1200 pixels/degree divided by 64 loops
           per progress indicator symbol (.oOo) printed. */
 
        /* 18.75=1200 pixels/degree divided by 64 loops
           per progress indicator symbol (.oOo) printed. */
 
-       z=(int)(18.75*(max_west-min_west));
+       z=(int)(18.75*ReduceAngle(max_west-min_west));
 
 
-       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
        {
        {
+               if (lon>=360.0)
+                       lon-=360.0;
+
                edge.lat=max_north;
                edge.lon=lon;
                edge.alt=altitude;
                edge.lat=max_north;
                edge.lon=lon;
                edge.alt=altitude;
@@ -2115,10 +2242,13 @@ void PlotLRMap(struct site source, double altitude)
        fprintf(stdout,"\n50%c to  75%c ",37,37);
        fflush(stdout);
 
        fprintf(stdout,"\n50%c to  75%c ",37,37);
        fflush(stdout);
 
-       z=(int)(18.75*(max_west-min_west));
+       z=(int)(18.75*ReduceAngle(max_west-min_west));
 
 
-       for (lon=min_west, x=0; lon<=max_west; lon+=one_pixel)
+       for (lon=min_west, x=0; (LonDiff(lon,max_west)<=0.0); lon+=one_pixel)
        {
        {
+               if (lon>=360.0)
+                       lon-=360.0;
+
                edge.lat=min_north;
                edge.lon=lon;
                edge.alt=altitude;
                edge.lat=min_north;
                edge.lon=lon;
                edge.alt=altitude;
@@ -2180,19 +2310,19 @@ void WritePPM(char *filename)
           from its representation in dem[][] so that north points
           up and east points right in the image generated. */
 
           from its representation in dem[][] so that north points
           up and east points right in the image generated. */
 
-       int indx, x, x0, y0, minlat, minlon;
-       unsigned width, height, output;
-       unsigned char found, mask;
        char mapfile[255];
        char mapfile[255];
-       double conversion, lat, lon, one_over_gamma, one_pixel;
+       unsigned char found, mask;
+       unsigned width, height, output;
+       int indx, x, y, x0=0, y0=0, minlat, minlon;
+       float lat, lon, one_pixel, conversion, one_over_gamma;
        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);
 
        FILE *fd;
 
        one_pixel=1.0/1200.0;
        one_over_gamma=1.0/GAMMA;
        conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
 
-       width=1200*(max_west-min_west);
-       height=1200*(max_north-min_north);
+       width=(unsigned)(1200*ReduceAngle(max_west-min_west));
+       height=(unsigned)(1200*ReduceAngle(max_north-min_north));
 
        if (filename[0]==0)
                strncpy(mapfile, "map.ppm\0",8);
 
        if (filename[0]==0)
                strncpy(mapfile, "map.ppm\0",8);
@@ -2215,11 +2345,15 @@ void WritePPM(char *filename)
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height);
        fflush(stdout);
 
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height);
        fflush(stdout);
 
-       for (lat=(double)max_north; lat>=(double)min_north; lat-=one_pixel)
+       for (y=0, lat=((double)max_north)-one_pixel; y<(int)height; y++, lat-=one_pixel)
        {
        {
-               for (lon=(double)max_west; lon>=(double)min_west; lon-=one_pixel)
+               minlat=(int)floor(lat);
+
+               for (x=0, lon=((double)max_west)-one_pixel; x<(int)width; x++, lon-=one_pixel)
                {
                {
-                       minlat=(int)floor(lat);
+                       if (lon<0.0)
+                               lon+=360.0;
+
                        minlon=(int)floor(lon);
 
                        for (indx=0, found=0; indx<MAXSLOTS && found==0;)
                        minlon=(int)floor(lon);
 
                        for (indx=0, found=0; indx<MAXSLOTS && found==0;)
@@ -2227,10 +2361,11 @@ void WritePPM(char *filename)
                                        found=1;
                                else
                                        indx++;
                                        found=1;
                                else
                                        indx++;
+
                        if (found)
                        {
                        if (found)
                        {
-                               x0=(int)((1199.0*(lat-floor(lat)))+0.5);
-                               y0=(int)((1199.0*(lon-floor(lon)))+0.5);
+                               x0=(int)(1199.0*(lat-floor(lat)));
+                               y0=(int)(1199.0*(lon-floor(lon)));
 
                                mask=dem[indx].mask[x0][y0];
 
 
                                mask=dem[indx].mask[x0][y0];
 
@@ -2331,6 +2466,14 @@ void WritePPM(char *filename)
                                        }
                                }
                        }
                                        }
                                }
                        }
+
+                       else
+                       {
+                               /* We should never get here, but if */
+                               /* we do, display the region as black */
+
+                               fprintf(fd,"%c%c%c",0,0,0);
+                       }
                }
        }
 
                }
        }
 
@@ -2347,19 +2490,19 @@ void WritePPMLR(char *filename)
           90 degrees from its representation in dem[][] so that north
           points up and east points right in the image generated. */
 
           90 degrees from its representation in dem[][] so that north
           points up and east points right in the image generated. */
 
-       int indx, x, t, t2, x0, y0, minlat, minlon;
-       unsigned width, height, output;
-       unsigned char found, mask;
        char mapfile[255];
        char mapfile[255];
-       double conversion, lat, lon, one_over_gamma, one_pixel;
+       unsigned width, height, output;
+       unsigned char found, mask, cityorcounty;
+       int indx, x, y, t, t2, x0, y0, minlat, minlon, loss;
+       float lat, lon, one_pixel, conversion, one_over_gamma;
        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);
 
        FILE *fd;
 
        one_pixel=1.0/1200.0;
        one_over_gamma=1.0/GAMMA;
        conversion=255.0/pow((double)(max_elevation-min_elevation),one_over_gamma);
 
-       width=1200*(max_west-min_west);
-       height=1200*(max_north-min_north);
+       width=(unsigned)(1200*ReduceAngle(max_west-min_west));
+       height=(unsigned)(1200*ReduceAngle(max_north-min_north));
 
        if (filename[0]==0)
                strncpy(mapfile, "map.ppm\0",8);
 
        if (filename[0]==0)
                strncpy(mapfile, "map.ppm\0",8);
@@ -2382,11 +2525,15 @@ void WritePPMLR(char *filename)
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height+30);
        fflush(stdout);
 
        fprintf(stdout,"\nWriting \"%s\" (%ux%u pixmap image)... ",mapfile,width,height+30);
        fflush(stdout);
 
-       for (lat=(double)max_north; lat>=(double)min_north; lat-=one_pixel)
+       for (y=0, lat=((double)max_north)-one_pixel; y<(int)height; y++, lat-=one_pixel)
        {
        {
-               for (lon=(double)max_west; lon>=(double)min_west; lon-=one_pixel)
+               minlat=(int)floor(lat);
+
+               for (x=0, lon=((double)max_west)-one_pixel; x<(int)width; x++, lon-=one_pixel)
                {
                {
-                       minlat=(int)floor(lat);
+                       if (lon<0.0)
+                               lon+=360.0;
+
                        minlon=(int)floor(lon);
 
                        for (indx=0, found=0; indx<MAXSLOTS && found==0;)
                        minlon=(int)floor(lon);
 
                        for (indx=0, found=0; indx<MAXSLOTS && found==0;)
@@ -2396,150 +2543,145 @@ void WritePPMLR(char *filename)
                                        indx++;
                        if (found)
                        {
                                        indx++;
                        if (found)
                        {
-                               x0=(int)((1199.0*(lat-floor(lat)))+0.5);
-                               y0=(int)((1199.0*(lon-floor(lon)))+0.5);
+                               x0=(int)(1199.0*(lat-floor(lat)));
+                               y0=(int)(1199.0*(lon-floor(lon)));
 
                                mask=dem[indx].mask[x0][y0];
 
                                mask=dem[indx].mask[x0][y0];
+                               loss=70+(10*(int)((mask&248)>>3));
+                               cityorcounty=0;
 
                                if (mask&2)
                                {
                                        /* Text Labels - Black or Red */
 
                                if (mask&2)
                                {
                                        /* Text Labels - Black or Red */
-                                       if (mask&120)
+
+                                       /* if ((mask&120) && (loss<=maxdB)) */
+                                       if ((mask&120) && (loss<=90))
                                                fprintf(fd,"%c%c%c",0,0,0);
                                        else
                                                fprintf(fd,"%c%c%c",255,0,0);
                                                fprintf(fd,"%c%c%c",0,0,0);
                                        else
                                                fprintf(fd,"%c%c%c",255,0,0);
+
+                                       cityorcounty=1;
                                }
 
                                else if (mask&4)
                                }
 
                                else if (mask&4)
+                               {
                                        /* County Boundaries: Black */
                                        /* County Boundaries: Black */
-                                       fprintf(fd,"%c%c%c",0,0,0);
 
 
-                               else if (mask&1 && !((mask&248)==192))
-                               {
-                                       /* Outside Analysis Range */
-                                       /* Display Greyscale / Sea Level */
+                                       fprintf(fd,"%c%c%c",0,0,0);
 
 
-                                       if (dem[indx].data[x0][y0]==0)
-                                               fprintf(fd,"%c%c%c",0,0,170);
-                                       else
-                                       {
-                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
-                                               fprintf(fd,"%c%c%c",output,output,output);
-                                       }
+                                       cityorcounty=1;
                                }
 
                                }
 
-                               else switch ((mask&248)>>3)
+                               if (cityorcounty==0)
                                {
                                {
-                                       case 0:
-                                       /* Inside range, but no coverage.
-                                          Display Sea Level / Terrain */
+                                       if (loss>maxdB)
+
+                                       { /* Display land or sea elevation */
+
+                                               if (dem[indx].data[x0][y0]==0)
+                                                       fprintf(fd,"%c%c%c",0,0,170);
+                                               else
+                                               {
+                                                       /* Elevation: Greyscale */
+                                                       output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                                       fprintf(fd,"%c%c%c",output,output,output);
+                                               }
+                                       }
 
 
-                                       if (dem[indx].data[x0][y0]==0)
-                                               fprintf(fd,"%c%c%c",0,0,170);
-                                       else
+                                       else switch (loss)
                                        {
                                        {
-                                               /* Elevation: Greyscale */
-                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
-                                               fprintf(fd,"%c%c%c",output,output,output);
-                                       }
+                                               /* Plot signal loss in color */
 
 
-                                       break;
+                                               case 80:
+                                               fprintf(fd,"%c%c%c",255,0,0);
+                                               break;
 
 
-                                       case 1:
-                                       /* Green */
-                                       fprintf(fd,"%c%c%c",0,255,0);
-                                       break;
+                                               case 90:
+                                               fprintf(fd,"%c%c%c",255,128,0);
+                                               break;
 
 
-                                       case 2:
-                                       /* Pink */
-                                       fprintf(fd,"%c%c%c",255,192,203);
-                                       break;
+                                               case 100:
+                                               fprintf(fd,"%c%c%c",255,165,0);
+                                               break;
 
 
-                                       case 3:
-                                       /* Cyan */
-                                       fprintf(fd,"%c%c%c",0,255,255);
-                                       break;
+                                               case 110:
+                                               fprintf(fd,"%c%c%c",255,206,0);
+                                               break;
 
 
-                                       case 4:
-                                       /* Yellow */
-                                       fprintf(fd,"%c%c%c",255,255,0);
-                                       break;
+                                               case 120:
+                                               fprintf(fd,"%c%c%c",255,255,0);
+                                               break;
 
 
-                                       case 5:
-                                       /* Medium Violet */
-                                       fprintf(fd,"%c%c%c",161,131,224);
-                                       break;
+                                               case 130:
+                                               fprintf(fd,"%c%c%c",184,255,0);
+                                               break;
 
 
-                                       case 6:
-                                       /* Orange */
-                                       fprintf(fd,"%c%c%c",255,165,0);
-                                       break;
+                                               case 140:
+                                               fprintf(fd,"%c%c%c",0,255,0);
+                                               break;
 
 
-                                       case 7:
-                                       /* Light Green */
-                                       fprintf(fd,"%c%c%c",193,255,193);
-                                       break;
+                                               case 150:
+                                               fprintf(fd,"%c%c%c",0,208,0);
+                                               break;
 
 
-                                       case 8:
-                                       /* Red Pink */
-                                       fprintf(fd,"%c%c%c",255,108,108);
-                                       break;
+                                               case 160:
+                                               fprintf(fd,"%c%c%c",0,196,196);
+                                               break;
 
 
-                                       case 9:
-                                       /* TX1 + TX4: Green Yellow */
-                                       fprintf(fd,"%c%c%c",173,255,47);
-                                       break;
+                                               case 170:
+                                               fprintf(fd,"%c%c%c",0,148,255);
+                                               break;
 
 
-                                       case 10:
-                                       /* Blanched Almond */
-                                       fprintf(fd,"%c%c%c",255,235,184);
-                                       break;
+                                               case 180:
+                                               fprintf(fd,"%c%c%c",80,80,255);
+                                               break;
 
 
-                                       case 11:
-                                       /* Dark Turquoise */
-                                       fprintf(fd,"%c%c%c",0,206,209);
-                                       break;
+                                               case 190:
+                                               fprintf(fd,"%c%c%c",0,38,255);
+                                               break;
 
 
-                                       case 12:
-                                       /* Tan */
-                                       fprintf(fd,"%c%c%c",210,180,140);
-                                       break;
+                                               case 200:
+                                               fprintf(fd,"%c%c%c",142,63,255);
+                                               break;
 
 
-                                       case 13:
-                                       /* Magenta 1 */
-                                       fprintf(fd,"%c%c%c",243,110,205);
-                                       break;
+                                               case 210:
+                                               fprintf(fd,"%c%c%c",196,54,255);
+                                               break;
 
 
-                                       case 14:
-                                       /* Gold2 */
-                                       fprintf(fd,"%c%c%c",238,201,0);
-                                       break;
+                                               case 220:
+                                               fprintf(fd,"%c%c%c",255,0,255);
+                                               break;
 
 
-                                       case 15:
-                                       /* Medium Spring Green */
-                                       fprintf(fd,"%c%c%c",0,250,154);
-                                       break;
+                                               case 230:
+                                               fprintf(fd,"%c%c%c",255,194,204);
+                                               break;
 
 
-                                       case 16:
-                                       /* Very light Blue */
-                                       fprintf(fd,"%c%c%c",244,244,255);
-                                       break;
+                                               default:
 
 
-                                       default:
-                                       /* Land / Sea */
-                                       if (dem[indx].data[x0][y0]==0)
-                                               fprintf(fd,"%c%c%c",0,0,170);
-                                       else
-                                       {
-                                               /* Elevation: Greyscale */
-                                               output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
-                                               fprintf(fd,"%c%c%c",output,output,output);
+                                               if (dem[indx].data[x0][y0]==0)
+                                                       fprintf(fd,"%c%c%c",0,0,170);
+                                               else
+                                               {
+                                                       /* Elevation: Greyscale */
+                                                       output=(unsigned)(0.5+pow((double)(dem[indx].data[x0][y0]-min_elevation),one_over_gamma)*conversion);
+                                                       fprintf(fd,"%c%c%c",output,output,output);
+                                               }
                                        }
                                }
                        }
                                        }
                                }
                        }
+
+                       else
+                       {
+                               /* We should never get here, but if */
+                               /* we do, display the region as black */
+
+                               fprintf(fd,"%c%c%c",0,0,0);
+                       }
                }
        }
 
                }
        }
 
+       /* Display legend along bottom of image */
+
        x0=width/16;
 
        for (y0=0; y0<30; y0++)
        x0=width/16;
 
        for (y0=0; y0<30; y0++)
@@ -2572,78 +2714,63 @@ void WritePPMLR(char *filename)
                                switch (t)
                                {
                                        case 0:
                                switch (t)
                                {
                                        case 0:
-                                       /* Green */
-                                       fprintf(fd,"%c%c%c",0,255,0);
+                                       fprintf(fd,"%c%c%c",255,0,0);
                                        break;
 
                                        case 1:
                                        break;
 
                                        case 1:
-                                       /* Pink */
-                                       fprintf(fd,"%c%c%c",255,192,203);
+                                       fprintf(fd,"%c%c%c",255,128,0);
                                        break;
 
                                        case 2:
                                        break;
 
                                        case 2:
-                                       /* Cyan */
-                                       fprintf(fd,"%c%c%c",0,255,255);
+                                       fprintf(fd,"%c%c%c",255,165,0);
                                        break;
 
                                        case 3:
                                        break;
 
                                        case 3:
-                                       /* Yellow */
-                                       fprintf(fd,"%c%c%c",255,255,0);
+                                       fprintf(fd,"%c%c%c",255,206,0);
                                        break;
 
                                        case 4:
                                        break;
 
                                        case 4:
-                                       /* Medium Violet */
-                                       fprintf(fd,"%c%c%c",161,131,224);
+                                       fprintf(fd,"%c%c%c",255,255,0);
                                        break;
 
                                        case 5:
                                        break;
 
                                        case 5:
-                                       /* Orange */
-                                       fprintf(fd,"%c%c%c",255,165,0);
+                                       fprintf(fd,"%c%c%c",184,255,0);
                                        break;
 
                                        break;
 
-                                       case 6:
-                                       /* Light Green */
-                                       fprintf(fd,"%c%c%c",193,255,193);
+                                       case 6:
+                                       fprintf(fd,"%c%c%c",0,255,0);
                                        break;
 
                                        break;
 
-                                       case 7:
-                                       /* Red Pink */
-                                       fprintf(fd,"%c%c%c",255,108,108);
+                                       case 7:
+                                       fprintf(fd,"%c%c%c",0,208,0);
                                        break;
 
                                        case 8:
                                        break;
 
                                        case 8:
-                                       /* Green Yellow */
-                                       fprintf(fd,"%c%c%c",173,255,47);
+                                       fprintf(fd,"%c%c%c",0,196,196);
                                        break;
 
                                        case 9:
                                        break;
 
                                        case 9:
-                                       /* Blanched Almond */
-                                       fprintf(fd,"%c%c%c",255,235,184);
+                                       fprintf(fd,"%c%c%c",0,148,255);
                                        break;
 
                                        case 10:
                                        break;
 
                                        case 10:
-                                       /* Dark Turquoise */
-                                       fprintf(fd,"%c%c%c",0,206,209);
+                                       fprintf(fd,"%c%c%c",80,80,255);
                                        break;
 
                                        case 11:
                                        break;
 
                                        case 11:
-                                       /* Tan */
-                                       fprintf(fd,"%c%c%c",210,180,140);
+                                       fprintf(fd,"%c%c%c",0,38,255);
                                        break;
 
                                        case 12:
                                        break;
 
                                        case 12:
-                                       /* Magenta 1 */
-                                       fprintf(fd,"%c%c%c",243,110,205);
+                                       fprintf(fd,"%c%c%c",142,63,255);
                                        break;
 
                                        case 13:
                                        break;
 
                                        case 13:
-                                       /* Gold2 */
-                                       fprintf(fd,"%c%c%c",238,201,0);
+                                       fprintf(fd,"%c%c%c",196,54,255);
                                        break;
 
                                        case 14:
                                        break;
 
                                        case 14:
-                                       /* Medium Spring Green */
-                                       fprintf(fd,"%c%c%c",0,250,154);
+                                       fprintf(fd,"%c%c%c",255,0,255);
                                        break;
 
                                        case 255:
                                        break;
 
                                        case 255:
@@ -2652,8 +2779,7 @@ void WritePPMLR(char *filename)
                                        break;
 
                                        default:
                                        break;
 
                                        default:
-                                       /* Very Light Blue */
-                                       fprintf(fd,"%c%c%c",244,244,255);
+                                       fprintf(fd,"%c%c%c",255,194,204);
                                }
                        } 
                }
                                }
                        } 
                }
@@ -2884,11 +3010,11 @@ void GraphHeight(struct site source, struct site destination, char *name)
 {
        /* This function invokes gnuplot to generate an appropriate
           output file indicating the terrain profile between the source
 {
        /* This function invokes gnuplot to generate an appropriate
           output file indicating the terrain profile between the source
-          and destination locations.  What is plotted is the height of land
-          above or below a straight line between the receibe and transmit
-          sites. "filename" is the name assigned to the output file
-          generated by gnuplot.  The filename extension is used to
-          set gnuplot's terminal setting and output file type.
+          and destination locations.  What is plotted is the height of
+          land above or below a straight line between the receibe and
+          transmit sites.  "filename" is the name assigned to the output
+          file generated by gnuplot.  The filename extension is used
+          to set gnuplot's terminal setting and output file type.
           If no extension is found, .gif is assumed. */
 
        int x, y, z;
           If no extension is found, .gif is assumed. */
 
        int x, y, z;
@@ -3003,7 +3129,7 @@ void GraphHeight(struct site source, struct site destination, char *name)
        fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines\n");
 
        fclose(fd);
        fprintf(fd,"plot \"profile.gp\" title \"Real Earth Profile\" with lines, \"reference.gp\" title \"Line Of Sight Path\" with lines\n");
 
        fclose(fd);
-                       
+
        x=system("gnuplot splat.gp");
 
        if (x!=-1)
        x=system("gnuplot splat.gp");
 
        if (x!=-1)
@@ -3046,8 +3172,20 @@ void GraphLongley(struct site source, struct site destination, char *name)
        fprintf(fd2,"Analysis of RF path conditions between %s and %s:\n",source.name, destination.name);
        fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
        fprintf(fd2,"Transmitter site: %s\n",source.name);
        fprintf(fd2,"Analysis of RF path conditions between %s and %s:\n",source.name, destination.name);
        fprintf(fd2,"\n-------------------------------------------------------------------------\n\n");
        fprintf(fd2,"Transmitter site: %s\n",source.name);
-       fprintf(fd2,"Site location: %.4f North / %.4f West",source.lat, source.lon);
-       fprintf(fd2, " (%s N / ", dec2dms(source.lat));
+
+       if (source.lat>=0.0)
+       {
+               fprintf(fd2,"Site location: %.4f North / %.4f West",source.lat, source.lon);
+               fprintf(fd2, " (%s N / ", dec2dms(source.lat));
+       }
+
+       else
+       {
+
+               fprintf(fd2,"Site location: %.4f South / %.4f West",-source.lat, source.lon);
+               fprintf(fd2, " (%s S / ", dec2dms(source.lat));
+       }
+       
        fprintf(fd2, "%s W)\n", dec2dms(source.lon));
        fprintf(fd2,"Ground elevation: %.2f feet AMSL\n",GetElevation(source));
        fprintf(fd2,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",source.alt, source.alt+GetElevation(source));
        fprintf(fd2, "%s W)\n", dec2dms(source.lon));
        fprintf(fd2,"Ground elevation: %.2f feet AMSL\n",GetElevation(source));
        fprintf(fd2,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",source.alt, source.alt+GetElevation(source));
@@ -3073,8 +3211,19 @@ void GraphLongley(struct site source, struct site destination, char *name)
        /* Receiver */
 
        fprintf(fd2,"Receiver site: %s\n",destination.name);
        /* Receiver */
 
        fprintf(fd2,"Receiver site: %s\n",destination.name);
-       fprintf(fd2,"Site location: %.4f North / %.4f West",destination.lat, destination.lon);
-       fprintf(fd2, " (%s N / ", dec2dms(destination.lat));
+
+       if (destination.lat>=0.0)
+       {
+               fprintf(fd2,"Site location: %.4f North / %.4f West",destination.lat, destination.lon);
+               fprintf(fd2, " (%s N / ", dec2dms(destination.lat));
+       }
+
+       else
+       {
+               fprintf(fd2,"Site location: %.4f South / %.4f West",-destination.lat, destination.lon);
+               fprintf(fd2, " (%s S / ", dec2dms(destination.lat));
+       }
+
        fprintf(fd2, "%s W)\n", dec2dms(destination.lon));
        fprintf(fd2,"Ground elevation: %.2f feet AMSL\n",GetElevation(destination));
        fprintf(fd2,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",destination.alt, destination.alt+GetElevation(destination));
        fprintf(fd2, "%s W)\n", dec2dms(destination.lon));
        fprintf(fd2,"Ground elevation: %.2f feet AMSL\n",GetElevation(destination));
        fprintf(fd2,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",destination.alt, destination.alt+GetElevation(destination));
@@ -3174,12 +3323,14 @@ void GraphLongley(struct site source, struct site destination, char *name)
                        LR.frq_mhz, LR.radio_climate, LR.pol, LR.conf, LR.rel,
                        loss, strmode, errnum);
 
                        LR.frq_mhz, LR.radio_climate, LR.pol, LR.conf, LR.rel,
                        loss, strmode, errnum);
 
-                       /* Note: PASS BY REFERENCE ... loss and errnum are pass
-                       by reference, only used in this file by this function */
+                       /* Note: PASS BY REFERENCE ... loss and errnum are
+                          passed by reference, and are only used in this
+                          file by this function */
 
 
                fprintf(fd,"%f\t%f\n",path.distance[path.length-1]-path.distance[x],loss);
 
 
                fprintf(fd,"%f\t%f\n",path.distance[path.length-1]-path.distance[x],loss);
-               fprintf(fd2,"%7.2f\t\t%7.2f\t\t  %d\t%s\n",path.distance[x],loss, errnum, strmode); 
+               fprintf(fd2,"%7.2f\t\t%7.2f\t\t  %d\t%s\n",path.distance[x],loss, errnum, strmode);
+
                errflag|=errnum;
                  
                if (loss>maxloss)
                errflag|=errnum;
                  
                if (loss>maxloss)
@@ -3310,8 +3461,20 @@ void ObstructionReport(struct site xmtr, struct site rcvr, char report)
        fprintf(fd,"Analysis of line-of-sight path conditions between %s and %s:\n",xmtr.name, rcvr.name);
        fprintf(fd,"\n-------------------------------------------------------------------------\n\n");
        fprintf(fd,"Transmitter site: %s\n",xmtr.name);
        fprintf(fd,"Analysis of line-of-sight path conditions between %s and %s:\n",xmtr.name, rcvr.name);
        fprintf(fd,"\n-------------------------------------------------------------------------\n\n");
        fprintf(fd,"Transmitter site: %s\n",xmtr.name);
-       fprintf(fd,"Site location: %.4f North / %.4f West",xmtr.lat, xmtr.lon);
-       fprintf(fd, " (%s N / ", dec2dms(xmtr.lat));
+
+
+       if (xmtr.lat>=0.0)
+       {
+               fprintf(fd,"Site location: %.4f North / %.4f West",xmtr.lat, xmtr.lon);
+               fprintf(fd, " (%s N / ", dec2dms(xmtr.lat));
+       }
+
+       else
+       {
+               fprintf(fd,"Site location: %.4f South / %.4f West",-xmtr.lat, xmtr.lon);
+               fprintf(fd, " (%s S / ", dec2dms(xmtr.lat));
+       }
+
        fprintf(fd, "%s W)\n", dec2dms(xmtr.lon));
        fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(xmtr));
        fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",xmtr.alt, xmtr.alt+GetElevation(xmtr));
        fprintf(fd, "%s W)\n", dec2dms(xmtr.lon));
        fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(xmtr));
        fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",xmtr.alt, xmtr.alt+GetElevation(xmtr));
@@ -3337,8 +3500,19 @@ void ObstructionReport(struct site xmtr, struct site rcvr, char report)
        /* Receiver */
 
        fprintf(fd,"Receiver site: %s\n",rcvr.name);
        /* Receiver */
 
        fprintf(fd,"Receiver site: %s\n",rcvr.name);
-       fprintf(fd,"Site location: %.4f North / %.4f West",rcvr.lat, rcvr.lon);
-       fprintf(fd, " (%s N / ", dec2dms(rcvr.lat));
+
+       if (rcvr.lat>=0.0)
+       {
+               fprintf(fd,"Site location: %.4f North / %.4f West",rcvr.lat, rcvr.lon);
+               fprintf(fd, " (%s N / ", dec2dms(rcvr.lat));
+       }
+
+       else
+       {
+               fprintf(fd,"Site location: %.4f South / %.4f West",-rcvr.lat, rcvr.lon);
+               fprintf(fd, " (%s S / ", dec2dms(rcvr.lat));
+       }
+
        fprintf(fd, "%s W)\n", dec2dms(rcvr.lon));
        fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(rcvr));
        fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",rcvr.alt, rcvr.alt+GetElevation(rcvr));
        fprintf(fd, "%s W)\n", dec2dms(rcvr.lon));
        fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(rcvr));
        fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",rcvr.alt, rcvr.alt+GetElevation(rcvr));
@@ -3377,7 +3551,13 @@ void ObstructionReport(struct site xmtr, struct site rcvr, char report)
                while (block=='*')
                {
                        if (result.lat!=result2.lat || result.lon!=result2.lon || result.alt!=result2.alt)
                while (block=='*')
                {
                        if (result.lat!=result2.lat || result.lon!=result2.lon || result.alt!=result2.alt)
-                               fprintf(fd,"\t%.4f N, %.4f W, %5.2f miles, %6.2f feet AMSL.\n",result.lat, result.lon, Distance(rcvr,result), result.alt);
+                       {
+                               if (result.lat>=0.0)
+                                       fprintf(fd,"\t%.4f N, %.4f W, %5.2f miles, %6.2f feet AMSL.\n",result.lat, result.lon, Distance(rcvr,result), result.alt);
+                               else
+
+                                       fprintf(fd,"\t%.4f S, %.4f W, %5.2f miles, %6.2f feet AMSL.\n",-result.lat, result.lon, Distance(rcvr,result), result.alt);
+                       }
 
                        result2=result;
                        new_site.alt+=1.0;
 
                        result2=result;
                        new_site.alt+=1.0;
@@ -3422,8 +3602,19 @@ void SiteReport(struct site xmtr)
        fprintf(fd,"\n\t--==[ SPLAT! v%s Site Analysis Report For: %s ]==--\n\n",splat_version,xmtr.name);
 
        fprintf(fd,"---------------------------------------------------------------------------\n\n");
        fprintf(fd,"\n\t--==[ SPLAT! v%s Site Analysis Report For: %s ]==--\n\n",splat_version,xmtr.name);
 
        fprintf(fd,"---------------------------------------------------------------------------\n\n");
-       fprintf(fd,"Site location: %.4f North / %.4f West",xmtr.lat, xmtr.lon);
-       fprintf(fd, " (%s N / ",dec2dms(xmtr.lat));
+
+       if (xmtr.lat>=0.0)
+       {
+               fprintf(fd,"Site location: %.4f North / %.4f West",xmtr.lat, xmtr.lon);
+               fprintf(fd, " (%s N / ",dec2dms(xmtr.lat));
+       }
+
+       else
+       {
+               fprintf(fd,"Site location: %.4f South / %.4f West",-xmtr.lat, xmtr.lon);
+               fprintf(fd, " (%s S / ",dec2dms(xmtr.lat));
+       }
+
        fprintf(fd, "%s W)\n",dec2dms(xmtr.lon));
        fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(xmtr));
        fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",xmtr.alt, xmtr.alt+GetElevation(xmtr));
        fprintf(fd, "%s W)\n",dec2dms(xmtr.lon));
        fprintf(fd,"Ground elevation: %.2f feet AMSL\n",GetElevation(xmtr));
        fprintf(fd,"Antenna height: %.2f feet AGL / %.2f feet AMSL\n",xmtr.alt, xmtr.alt+GetElevation(xmtr));
@@ -3457,47 +3648,49 @@ void SiteReport(struct site xmtr)
 
 int main(char argc, char *argv[])
 {
 
 int main(char argc, char *argv[])
 {
+       int             x, y, ymin, ymax, width, z=0, min_lat, min_lon,
+                       max_lat, max_lon, rxlat, rxlon, txlat, txlon,
+                       west_min, west_max, north_min, north_max;
 
 
-       int             x, y, z=0;
-       unsigned char   rxlat, rxlon, txlat, txlon, min_lat,
-                       min_lon, max_lat, max_lon, 
-                       coverage=0, LRmap=0,
-                       ext[20], terrain_plot=0,
+       unsigned char   coverage=0, LRmap=0, ext[20], terrain_plot=0,
                        elevation_plot=0, height_plot=0, 
                        longley_plot=0, cities=0, bfs=0, txsites=0,
                        elevation_plot=0, height_plot=0, 
                        longley_plot=0, cities=0, bfs=0, txsites=0,
-                       count, west_min, west_max, north_min, north_max,
-                       report='y';
+                       count, report='y';
  
        char            mapfile[255], header[80], city_file[5][255], 
                        elevation_file[255], height_file[255], 
                        longley_file[255], terrain_file[255],
  
        char            mapfile[255], header[80], city_file[5][255], 
                        elevation_file[255], height_file[255], 
                        longley_file[255], terrain_file[255],
-                       string[255], rxfile[255],
-                       txfile[255], map=0, boundary_file[5][255];
+                       string[255], rxfile[255], *env=NULL,
+                       txfile[255], map=0, boundary_file[5][255],
+                       rxsite=0;
 
        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;
 
        double          altitude=0.0, altitudeLR=0.0, tx_range=0.0,
                        rx_range=0.0, deg_range=0.0, deg_limit,
                        deg_range_lon, er_mult;
+
        struct          site tx_site[4], rx_site;
        struct          site tx_site[4], rx_site;
+
        FILE            *fd;
 
        FILE            *fd;
 
-       sprintf(header,"\n  --==[ SPLAT! v%s Terrain Analysis Software (c) 1997-2004 KD2BD ]==--\n\n", splat_version);
+       sprintf(header,"\n\t\t--==[ Welcome To SPLAT! v%s ]==--\n\n", splat_version);
 
        if (argc==1)
        {
 
        if (argc==1)
        {
-               fprintf(stdout, "%sAvailable Options...\n\n\t-t txsite(s).qth (max of 4)\n\t-r rxsite.qth\n",header);
-               fprintf(stdout,"\t-c plot coverage area(s) of TX(s) based on an RX antenna at X feet AGL\n");
-               fprintf(stdout,"\t-L plot path loss map of TX based on an RX antenna at X feet AGL\n");
-               fprintf(stdout,"\t-s filename(s) of city/site file(s) to import (max of 5)\n");
-               fprintf(stdout,"\t-b filename(s) of cartographic boundary file(s) to import (max of 5)\n");
-               fprintf(stdout,"\t-p filename of terrain profile graph to plot\n");
-               fprintf(stdout,"\t-e filename of terrain elevation graph to plot\n");
-               fprintf(stdout,"\t-h filename of terrain height graph to plot\n");
-               fprintf(stdout,"\t-l filename of Longley-Rice graph to plot\n");
-               fprintf(stdout,"\t-o filename of topographic map to generate (.ppm)\n");
-               fprintf(stdout,"\t-d sdf file directory path (overrides path in ~/.splat_path file)\n");
-               fprintf(stdout,"\t-n no analysis, brief report\n\t-N no analysis, no report\n");
-               fprintf(stdout,"\t-m earth radius multiplier\n");
-               fprintf(stdout,"\t-R modify default range for -c or -L (miles)\n\n");
+               fprintf(stdout, "%sAvailable Options...\n\n\t -t txsite(s).qth (max of 4)\n\t -r rxsite.qth\n",header);
+               fprintf(stdout,"\t -c plot coverage area(s) of TX(s) based on an RX antenna at X feet AGL\n");
+               fprintf(stdout,"\t -L plot path loss map of TX based on an RX antenna at X feet AGL\n");
+               fprintf(stdout,"\t -s filename(s) of city/site file(s) to import (max of 5)\n");
+               fprintf(stdout,"\t -b filename(s) of cartographic boundary file(s) to import (max of 5)\n");
+               fprintf(stdout,"\t -p filename of terrain profile graph to plot\n");
+               fprintf(stdout,"\t -e filename of terrain elevation graph to plot\n");
+               fprintf(stdout,"\t -h filename of terrain height graph to plot\n");
+               fprintf(stdout,"\t -l filename of Longley-Rice graph to plot\n");
+               fprintf(stdout,"\t -o filename of topographic map to generate (.ppm)\n");
+               fprintf(stdout,"\t -d sdf file directory path (overrides path in ~/.splat_path file)\n");
+               fprintf(stdout,"\t -n no analysis, brief report\n\t -N no analysis, no report\n");
+               fprintf(stdout,"\t -m earth radius multiplier\n");
+               fprintf(stdout,"\t -R modify default range for -c or -L (miles)\n");
+               fprintf(stdout,"\t-db maximum loss contour to display on path loss maps (80-230 dB)\n\n");
 
                fprintf(stdout,"Type 'man splat', or see the documentation for more details.\n\n");
                fflush(stdout);
 
                fprintf(stdout,"Type 'man splat', or see the documentation for more details.\n\n");
                fflush(stdout);
@@ -3514,20 +3707,27 @@ int main(char argc, char *argv[])
        terrain_file[0]=0;
        sdf_path[0]=0;
        path.length=0;
        terrain_file[0]=0;
        sdf_path[0]=0;
        path.length=0;
-       rx_site.lat=0.0;
-       rx_site.lon=0.0;
+       rx_site.lat=91.0;
+       rx_site.lon=361.0;
        earthradius=EARTHRADIUS;
 
        earthradius=EARTHRADIUS;
 
+       for (x=0; x<4; x++)
+       {
+               tx_site[x].lat=91.0;
+               tx_site[x].lon=361.0;
+       }
+
        for (x=0; x<MAXSLOTS; x++)
        {
        for (x=0; x<MAXSLOTS; x++)
        {
-               dem[x].min_el=0;
-               dem[x].max_el=0;
-               dem[x].min_north=0;
-               dem[x].max_north=0;
-               dem[x].min_west=0;
-               dem[x].max_west=0;
+               dem[x].min_el=32768;
+               dem[x].max_el=-32768;
+               dem[x].min_north=90;
+               dem[x].max_north=-90;
+               dem[x].min_west=360;
+               dem[x].max_west=-1;
        }
 
        }
 
+
        /* Scan for command line arguments */
 
        for (x=1; x<=y; x++)
        /* Scan for command line arguments */
 
        for (x=1; x<=y; x++)
@@ -3586,6 +3786,24 @@ int main(char argc, char *argv[])
                        }
                }
 
                        }
                }
 
+               if (strcmp(argv[x],"-db")==0)
+               {
+                       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 (strcmp(argv[x],"-p")==0)
                { 
                        z=x+1;
                if (strcmp(argv[x],"-p")==0)
                { 
                        z=x+1;
@@ -3702,6 +3920,7 @@ int main(char argc, char *argv[])
                        {
                                strncpy(rxfile,argv[z],253);
                                rx_site=LoadQTH(rxfile);
                        {
                                strncpy(rxfile,argv[z],253);
                                rx_site=LoadQTH(rxfile);
+                               rxsite=1;
                        }
                }
 
                        }
                }
 
@@ -3749,7 +3968,7 @@ int main(char argc, char *argv[])
 
        for (x=0, y=0; x<txsites; x++)
        {
 
        for (x=0, y=0; x<txsites; x++)
        {
-               if (tx_site[x].lat==0.0 && tx_site[x].lon==0.0)
+               if (tx_site[x].lat==91.0 && tx_site[x].lon==361.0)
                {
                        fprintf(stderr,"\n*** ERROR: Transmitter site #%d not found!",x+1);
                        y++;
                {
                        fprintf(stderr,"\n*** ERROR: Transmitter site #%d not found!",x+1);
                        y++;
@@ -3762,7 +3981,7 @@ int main(char argc, char *argv[])
                exit (-1);
        }
 
                exit (-1);
        }
 
-       if ((coverage+LRmap)==0 && rx_site.lat==0.0 && rx_site.lon==0.0)
+       if ((coverage+LRmap)==0 && rx_site.lat==91.0 && rx_site.lon==361.0)
        {
                fprintf(stderr,"\n%c*** ERROR: No receiver site found or specified!\n\n",7);
                exit (-1);
        {
                fprintf(stderr,"\n%c*** ERROR: No receiver site found or specified!\n\n",7);
                exit (-1);
@@ -3778,7 +3997,8 @@ int main(char argc, char *argv[])
 
        if (sdf_path[0]==0)
        {
 
        if (sdf_path[0]==0)
        {
-               sprintf(string,"%s/.splat_path",getenv("HOME"));
+               env=getenv("HOME");
+               sprintf(string,"%s/.splat_path",env);
                fd=fopen(string,"r");
 
                if (fd!=NULL)
                fd=fopen(string,"r");
 
                if (fd!=NULL)
@@ -3815,87 +4035,121 @@ int main(char argc, char *argv[])
        x=0;
        y=0;
 
        x=0;
        y=0;
 
-       min_lat=0;
-       max_lat=0;
-       min_lon=0;
-       max_lon=0;
+       min_lat=90;
+       max_lat=-90;
 
 
-       rxlat=(unsigned char)floor(rx_site.lat);
-       rxlon=(unsigned char)floor(rx_site.lon);
+       min_lon=(int)floor(tx_site[0].lon);
+       max_lon=(int)floor(tx_site[0].lon);
 
 
-       if (rxlat!=0)
+       for (y=0, z=0; z<txsites; z++)
        {
        {
-               if (min_lat==0)
-                       min_lat=rxlat;
+               txlat=(int)floor(tx_site[z].lat);
+               txlon=(int)floor(tx_site[z].lon);
 
 
-               else if (rxlat<min_lat)
-                       min_lat=rxlat;
+               if (txlat<min_lat)
+                       min_lat=txlat;
+
+               if (txlat>max_lat)
+                       max_lat=txlat;
+
+               if (LonDiff(txlon,min_lon)<0.0)
+                       min_lon=txlon;
+
+               if (LonDiff(txlon,max_lon)>0.0)
+                       max_lon=txlon;
        }
 
        }
 
-       if (rxlon!=0)
+       if (rxsite)
        {
        {
-               if (min_lon==0)
-                       min_lon=rxlon;
+               rxlat=(int)floor(rx_site.lat);
+               rxlon=(int)floor(rx_site.lon);
+
+               if (rxlat<min_lat)
+                       min_lat=rxlat;
 
 
-               else if (rxlon<min_lon)
+               if (rxlat>max_lat)
+                       max_lat=rxlat;
+
+               if (LonDiff(rxlon,min_lon)<0.0)
                        min_lon=rxlon;
                        min_lon=rxlon;
+
+               if (LonDiff(rxlon,max_lon)>0.0)
+                       max_lon=rxlon;
        }
 
        }
 
-       if (rxlat>max_lat)
-               max_lat=rxlat;
 
 
-       if (rxlon>max_lon)
-               max_lon=rxlon;
+       /* Load the required SDF files */ 
 
 
-       for (y=0, z=0; z<txsites; z++)
+       width=ReduceAngle(max_lon-min_lon);
+
+       if ((max_lon-min_lon)<=180.0)
        {
        {
-               txlat=(unsigned char)floor(tx_site[z].lat);
-               txlon=(unsigned char)floor(tx_site[z].lon);
+               for (y=0; y<=width; y++)
+                       for (x=min_lat; x<=max_lat; x++)
+                       {
+                               ymin=(int)(min_lon+(double)y);
 
 
-               if (txlat!=0)
-               {
-                       if (min_lat==0)
-                               min_lat=txlat;
+                               while (ymin<0)
+                                       ymin+=360;
 
 
-                       else if (txlat<min_lat)
-                               min_lat=txlat;
-               }
+                               while (ymin>=360)
+                                       ymin-=360;
 
 
-               if (txlon!=0)
-               {
-                       if (min_lon==0)
-                               min_lon=txlon;
+                               ymax=ymin+1;
 
 
-                       else if (txlon<min_lon)
-                               min_lon=txlon;
-               }
+                               while (ymax<0)
+                                       ymax+=360;
 
 
-               if (txlat>max_lat)
-                       max_lat=txlat;
+                               while (ymax>=360)
+                                       ymax-=360;
 
 
-               if (txlon>max_lon)
-                       max_lon=txlon;
+                               sprintf(string,"%d:%d:%d:%d",x, x+1, ymin, ymax);
+                               LoadSDF(string);
+                       }
        }
 
        }
 
-       if (min_lat!=0 && min_lon!=0 && max_lat!=0 && max_lon!=0)
+       else
        {
        {
-               for (y=min_lon; y<=max_lon; y++)
+               for (y=0; y<=width; y++)
                        for (x=min_lat; x<=max_lat; x++)
                        {
                        for (x=min_lat; x<=max_lat; x++)
                        {
-                               sprintf(string,"%u:%u:%u:%u",x, x+1, y, y+1);
+                               ymin=max_lon+y;
+
+                               while (ymin<0)
+                                       ymin+=360;
+
+                               while (ymin>=360)
+                                       ymin-=360;
+                                       
+                               ymax=ymin+1;
+
+                               while (ymax<0)
+                                       ymax+=360;
+
+                               while (ymax>=360)
+                                       ymax-=360;
+
+                               sprintf(string,"%d:%d:%d:%d",x, x+1, ymin, ymax);
                                LoadSDF(string);
                        }
        }
 
                                LoadSDF(string);
                        }
        }
 
-       if (coverage)
+       if (coverage | LRmap)
        {
        {
+               if (LRmap)
+                       txsites=1;
+
                for (z=0; z<txsites; z++)
                {
                        /* "Ball park" estimates used to load any additional
                           SDF files required to conduct this analysis. */
 
                        tx_range=sqrt(1.5*(tx_site[z].alt+GetElevation(tx_site[z])));
                for (z=0; z<txsites; z++)
                {
                        /* "Ball park" estimates used to load any additional
                           SDF files required to conduct this analysis. */
 
                        tx_range=sqrt(1.5*(tx_site[z].alt+GetElevation(tx_site[z])));
-                       rx_range=sqrt(1.5*altitude);
+
+                       if (LRmap)
+                               rx_range=sqrt(1.5*altitudeLR);
+                       else
+                               rx_range=sqrt(1.5*altitude);
 
                        /* deg_range determines the maximum
                           amount of topo data we read */
 
                        /* deg_range determines the maximum
                           amount of topo data we read */
@@ -3950,149 +4204,111 @@ int main(char argc, char *argv[])
                        if (deg_range_lon>deg_limit)
                                deg_range_lon=deg_limit;
 
                        if (deg_range_lon>deg_limit)
                                deg_range_lon=deg_limit;
 
-                       north_min=(unsigned char)floor(tx_site[z].lat-deg_range);
-                       north_max=(unsigned char)floor(tx_site[z].lat+deg_range);
-                       west_min=(unsigned char)floor(tx_site[z].lon-deg_range_lon);
-                       west_max=(unsigned char)floor(tx_site[z].lon+deg_range_lon);
 
 
-                       if (min_lat==0)
-                               min_lat=north_min;
+                       north_min=(int)floor(tx_site[z].lat-deg_range);
+                       north_max=(int)floor(tx_site[z].lat+deg_range);
 
 
-                       else if (north_min<min_lat)
-                               min_lat=north_min;
+                       west_min=(int)floor(tx_site[z].lon-deg_range_lon);
 
 
-                       if (min_lon==0)
-                               min_lon=west_min;
+                       while (west_min<0)
+                               west_min+=360;
 
 
-                       else if (west_min<min_lon)
-                               min_lon=west_min;
+                       while (west_min>=360)
+                               west_min-=360;
 
 
-                       if (north_max>max_lat)
-                               max_lat=north_max;
+                       west_max=(int)floor(tx_site[z].lon+deg_range_lon);
 
 
-                       if (west_max>max_lon)
-                               max_lon=west_max;
-               }
+                       while (west_max<0)
+                               west_max+=360;
 
 
-               if (min_lat!=0 && min_lon!=0 && max_lat!=0 && max_lon!=0)
-               {
-                       for (y=min_lon; y<=max_lon; y++)
-                               for (x=min_lat; x<=max_lat; x++)
-                               {
-                                       sprintf(string,"%u:%u:%u:%u",x, x+1, y, y+1);
-                                       LoadSDF(string);
-                               }
-               }
-       }
+                       while (west_max>=360)
+                               west_max-=360;
 
 
-       if (LRmap)
-       {
-               /* "Ball park" estimates used to load any additional
-                  SDF files required to conduct this analysis. */
+                       if (north_min<min_lat)
+                               min_lat=north_min;
 
 
-               tx_range=sqrt(1.5*(tx_site[0].alt+GetElevation(tx_site[0])));
-               rx_range=sqrt(1.5*altitudeLR);
+                       if (north_max>max_lat)
+                               max_lat=north_max;
 
 
-               /**
-               tx_range=sqrt(5.0*tx_site[0].alt);
-               rx_range=sqrt(5.0*altitudeLR);
-               **/
+                       if (LonDiff(west_min,min_lon)<0.0)
+                               min_lon=west_min;
 
 
-               /* deg_range determines the maximum
-                  amount of topo data we read */
+                       if (LonDiff(west_max,max_lon)>0.0)
+                               max_lon=west_max;
+               }
 
 
-               deg_range=(tx_range+rx_range)/69.0;
 
 
-               /* max_range sets the maximum size of the
-                  analysis.  A small, non-zero amount can
-                  be used to shrink the size of the analysis
-                  and limit the amount of topo data read by
-                  SPLAT!  A very large number will only increase
-                  the width of the analysis, not the size of
-                  the map. */
+               /* Load the required SDF files */ 
 
 
-               if (max_range==0.0)
-                       max_range=tx_range+rx_range;
+               width=ReduceAngle(max_lon-min_lon);
 
 
-               if (max_range<(tx_range+rx_range))
-                       deg_range=max_range/69.0;
+               if ((max_lon-min_lon)<=180.0)
+               {
+                       for (y=0; y<=width; y++)
+                               for (x=min_lat; x<=max_lat; x++)
+                               {
+                                       ymin=(int)(min_lon+(double)y);
 
 
-               /* Prevent the demand for a really wide coverage
-                  from allocating more slots than are available
-                  in memory. */
+                                       while (ymin<0)
+                                               ymin+=360;
 
 
-               switch (MAXSLOTS)
-               {
-                       case 2: deg_limit=0.25;
-                               break;
+                                       while (ymin>=360)
+                                               ymin-=360;
 
 
-                       case 4: deg_limit=0.5;
-                               break;
+                                       ymax=ymin+1;
 
 
-                       case 9: deg_limit=1.0;
-                               break;
+                                       while (ymax<0)
+                                               ymax+=360;
 
 
-                       case 16: deg_limit=2.0;
-                               break;
+                                       while (ymax>=360)
+                                               ymax-=360;
 
 
-                       case 25: deg_limit=3.0;
+                                       sprintf(string,"%d:%d:%d:%d",x, x+1, ymin, ymax);
+                                       LoadSDF(string);
+                               }
                }
 
                }
 
-               if (tx_site[0].lat<70.0)
-                       deg_range_lon=deg_range/cos(deg2rad*tx_site[0].lat);
                else
                else
-                       deg_range_lon=deg_range/cos(deg2rad*70.0);
-
-               /* Correct for squares in degrees not being square in miles */  
-
-               if (deg_range>deg_limit)
-                       deg_range=deg_limit;
-
-               if (deg_range_lon>deg_limit)
-                       deg_range_lon=deg_limit;
-
-               north_min=(unsigned char)floor(tx_site[0].lat-deg_range);
-               north_max=(unsigned char)floor(tx_site[0].lat+deg_range);
-               west_min=(unsigned char)floor(tx_site[0].lon-deg_range_lon);
-               west_max=(unsigned char)floor(tx_site[0].lon+deg_range_lon);
-
-               if (min_lat==0)
-                       min_lat=north_min;
-
-               else if (north_min<min_lat)
-                       min_lat=north_min;
+               {
+                       for (y=0; y<=width; y++)
+                               for (x=min_lat; x<=max_lat; x++)
+                               {
+                                       ymin=(int)(max_lon+(double)y);
 
 
-               if (min_lon==0)
-                       min_lon=west_min;
+                                       while (ymin<0)
+                                               ymin+=360;
 
 
-               else if (west_min<min_lon)
-                       min_lon=west_min;
+                                       while (ymin>=360)
+                                               ymin-=360;
+                                       
+                                       ymax=ymin+1;
 
 
-               if (north_max>max_lat)
-                       max_lat=north_max;
+                                       while (ymax<0)
+                                               ymax+=360;
 
 
-               if (west_max>max_lon)
-                       max_lon=west_max;
+                                       while (ymax>=360)
+                                               ymax-=360;
 
 
-               if (min_lat!=0 && min_lon!=0 && max_lat!=0 && max_lon!=0)
-               {
-                       for (y=min_lon; y<=max_lon; y++)
-                               for (x=min_lat; x<=max_lat; x++)
-                               {
-                                       sprintf(string,"%u:%u:%u:%u",x, x+1, y, y+1);
+                                       sprintf(string,"%d:%d:%d:%d",x, x+1, ymin, ymax);
                                        LoadSDF(string);
                                }
                }
        }
 
                                        LoadSDF(string);
                                }
                }
        }
 
+
        if (mapfile[0])
                map=1;
 
        if (mapfile[0])
                map=1;
 
-       if (coverage)
+       if (coverage | LRmap)
        {
                for (x=0; x<txsites; x++)
                {
        {
                for (x=0; x<txsites; x++)
                {
-                       PlotCoverage(tx_site[x],altitude);
+                       if (coverage)
+                               PlotCoverage(tx_site[x],altitude);
+
+                       if (LRmap)
+                               PlotLRMap(tx_site[x],altitudeLR);
+
                        PlaceMarker(tx_site[x]);
 
                        if (report!='N')
                        PlaceMarker(tx_site[x]);
 
                        if (report!='N')
@@ -4102,18 +4318,7 @@ int main(char argc, char *argv[])
                map=1;
        }
 
                map=1;
        }
 
-       else if (LRmap)
-       {
-               PlotLRMap(tx_site[0],altitudeLR);
-               PlaceMarker(tx_site[0]);
-
-               if (report!='N')
-                       SiteReport(tx_site[0]);
-               
-               map=1;
-       }
-
-       else       
+       if (coverage==0 && LRmap==0)       
        {
                PlaceMarker(rx_site);
 
        {
                PlaceMarker(rx_site);
 
@@ -4301,3 +4506,4 @@ int main(char argc, char *argv[])
 
        return 0;
 }
 
        return 0;
 }
+