Added propagation models and knife edge diffraction :)
This commit is contained in:
Cloud-RF
2013-12-30 21:41:03 +00:00
parent bf6a259c83
commit cdabfd517a
6 changed files with 367 additions and 125 deletions

View File

@@ -1,4 +1,11 @@
Signal Server 1.3.6 changelog
Signal Server 1.3.7 changelog
v1.3.7 - 30 Dec 2013
Added propagation model option (-pm)
Added HATA urban/suburban/open models (150-1500MHz)
Added COST231-Hata (urban) model (1500-2000MHz)
Added custom Knife Edge Diffraction option (-ked) to enhance new models
Removed unused variables
v1.3.6 - 12 Aug 2013
Added LOS model for up to 100GHz

View File

@@ -1,10 +1,8 @@
Signal-Server
=============
RF coverage calculator
Signal-Server RF coverage calculator
====================================
/****************************************************************************\
* Signal Server 1.3.6: Server optimised SPLAT! by Alex Farrant *
* Signal Server 1.3.7: Server optimised SPLAT! by Alex Farrant *
******************************************************************************
* SPLAT! Project started in 1997 by John A. Magliacane, KD2BD *
* *
@@ -24,7 +22,7 @@ RF coverage calculator
* for more details. *
* *
******************************************************************************
* g++ -Wall -O3 -s -lm -fomit-frame-pointer itm.cpp main.cpp -o ss *
* g++ -Wall -O3 -s -lm -fomit-frame-pointer itm.cpp cost.cpp hata.cpp main.cpp -o ss *
\****************************************************************************/
Usage: Signalserver (options)
@@ -51,4 +49,7 @@ RF coverage calculator
-R Radius (miles/kilometers)
-res Pixels per degree. 300/600/1200(default)/3600 (optional)
-t Terrain background
-dbg Debug
-pm Propagation model. 1: ITM (Default), 2: LOS, 3-5: Hata
-ked Knife edge diffraction (Default for ITM)
-wf Win32 SDF tile names ('=' not ':')
-dbg Debug mode

41
cost.cpp Normal file
View File

@@ -0,0 +1,41 @@
/*****************************************************************************
* COST231-HATA MODEL for Signal Server by Alex Farrant *
* 30 December 2013 *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License or any later *
* version. *
* *
* This program is distributed in the hope that it will useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* */
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;
double CostHataLinkdB(float f,float h_B, float h_M, float d){
/*
COST HATA URBAN model
Frequency 1500 to 2000MHz
h_B = Base station height 30 to 200m
h_M = Mobile station height 1 to 10m
Distance 1-20km
*/
int C = 0; // 0dB for suburban
float lh_M = log10(11.75*h_M);
float C_H = 3.2*lh_M*lh_M-4.97;
float logf = log10(f);
double dbloss = 46.3 + (33.9 * logf) - (13.82 * log10(h_B)) - C_H + (44.9 - 6.55 * log10(h_B)) * log10(d) + C;
return dbloss;
}

109
hata.cpp Normal file
View File

@@ -0,0 +1,109 @@
/*****************************************************************************
* HATA MODEL for Signal Server by Alex Farrant *
* 30 December 2013 *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License or any later *
* version. *
* *
* This program is distributed in the hope that it will useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* */
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
#define PI 3.14159265
/* Acute Angle from Rx point to an obstacle of height (opp) and distance (adj) */
double incidenceAngle(double opp, double adj){
return atan2(opp,adj) * 180 / PI;
}
/*
Knife edge diffraction:
This custom function adds to the overall path loss based upon the obstacle
angle (from receive point) and the frequency. Loss increases with angle and frequency.
This is not a recognised formula like Huygens, rather it is a
compromise for increased speed which adds a realistic diffraction effect.
*/
double ked(double freq, double elev[], double rxh, double dkm){
double obh,obd,rxobaoi=0,d;
obh=0;
obd=0;
dkm=dkm*1000; // KM to metres
for(int n=2;n<(dkm/elev[1]);n++){
d = (n-2)*elev[1]; // no of points * delta = km
//Find dip(s)
if(elev[n] > 0 && elev[n]<(obh+10)){
// Angle from Rx point to obstacle
rxobaoi = incidenceAngle((obh-(elev[n]+rxh)),d-obd);
} else{
// Line of sight or higher
rxobaoi=0;
}
//note the highest point
if(elev[n]>obh){
obh=elev[n];
obd=d;
}
}
if(rxobaoi >= 0){
return (rxobaoi * 3) / (300/freq); // Exaggerate diffraction angle and divide by wavelength (m)
}else{
return 0;
}
}
double HataLinkdB(float f,float h_B, float h_M, float d, int mode){
/*
HATA URBAN model for cellular planning
Frequency (MHz) 150 to 1500MHz
Base station height 30-200m
Mobile station height 1-10m
Distance 1-20km
mode 1 = URBAN
mode 2 = SUBURBAN
mode 3 = OPEN
*/
float lh_M = log10(11.75*h_M);
float C_H = 3.2*lh_M*lh_M-4.97;
float logf = log10(f);
float L_u = 69.55 + 26.16*logf - 13.82*log10(h_B) - C_H + (44.9 - 6.55*log10(h_B))*log10(d);
if(!mode || mode==1){
return L_u; //URBAN
}
if(mode==2){ //SUBURBAN
float logf_28 = log10(f/28);
return L_u - 2*logf_28*logf_28 - 5.4;
}
if(mode==3){ //OPEN
return L_u - 4.78*logf*logf + 18.33*logf - 40.94;
}
return 0;
}

View File

@@ -1215,9 +1215,9 @@ void point_to_point(double elev[], double tht_m, double rht_m, double eps_dielec
prop.mdp=-1;
zc=qerfi(conf);
zr=qerfi(rel);
np=(long)elev[0];
dkm=(elev[1]*elev[0])/1000.0;
xkm=elev[1]/1000.0;
np=(long)elev[0]; //number of points
dkm=(elev[1]*elev[0])/1000.0; // total distance in km. elev[1]=90(m) (default)
xkm=elev[1]/1000.0; // distance between points in km
eno=eno_ns_surfref;
enso=0.0;
q=enso;

252
main.cpp
View File

@@ -1,5 +1,5 @@
/****************************************************************************\
* Signal Server 1.3.6: Server optimised SPLAT! by Alex Farrant *
* Signal Server 1.3.7: Server optimised SPLAT! by Alex Farrant *
******************************************************************************
* SPLAT! Project started in 1997 by John A. Magliacane, KD2BD *
* *
@@ -19,7 +19,7 @@
* for more details. *
* *
******************************************************************************
* g++ -Wall -O3 -s -lm -fomit-frame-pointer itm.cpp main.cpp -o ss *
* g++ -Wall -O3 -s -lm -fomit-frame-pointer itm.cpp cost.cpp hata.cpp main.cpp -o ss *
\****************************************************************************/
#include <stdio.h>
@@ -30,9 +30,9 @@
#include <unistd.h>
#define GAMMA 2.5
#define MAXPAGES 9
#define ARRAYSIZE 32600
#define IPPD 3600
#define MAXPAGES 64
#define ARRAYSIZE 76810
#define IPPD 1200
#ifndef PI
#define PI 3.141592653589793
@@ -118,6 +118,12 @@ void point_to_point(double elev[], double tht_m, double rht_m,
double frq_mhz, int radio_climate, int pol, double conf,
double rel, double &dbloss, char *strmode, int &errnum);
double HataLinkdB(float f,float h_B, float h_M, float d, int mode);
double CostHataLinkdB(float f,float h_B, float h_M, float d);
double ked(double freq, double elev[], double rxh, double dkm);
double arccos(double x, double y)
{
/* This function implements the arc cosine function,
@@ -1222,7 +1228,7 @@ void LoadPAT(char *filename)
}
}
int LoadSDF_SDF(char *name)
int LoadSDF_SDF(char *name, int winfiles)
{
/* This function reads uncompressed ss Data Files (.sdf)
containing digital elevation model data into memory.
@@ -1243,8 +1249,11 @@ int LoadSDF_SDF(char *name)
sdf_file[x]=0;
/* Parse filename for minimum latitude and longitude values */
if(winfiles==1){
sscanf(sdf_file,"%d=%d=%d=%d",&minlat,&maxlat,&minlon,&maxlon);
}else{
sscanf(sdf_file,"%d:%d:%d:%d",&minlat,&maxlat,&minlon,&maxlon);
}
sdf_file[x]='.';
sdf_file[x+1]='s';
@@ -1431,7 +1440,7 @@ int LoadSDF_SDF(char *name)
else
return 0;
}
char LoadSDF(char *name)
char LoadSDF(char *name, int winfiles)
{
/* This function loads the requested SDF file from the filesystem.
It first tries to invoke the LoadSDF_SDF() function to load an
@@ -1446,7 +1455,7 @@ char LoadSDF(char *name)
char found, free_page=0;
int return_value=-1;
return_value=LoadSDF_SDF(name);
return_value=LoadSDF_SDF(name, winfiles);
/* If neither format can be found, then assume the area is water. */
@@ -1456,10 +1465,11 @@ char LoadSDF(char *name)
/* Parse SDF name for minimum latitude and longitude values */
if(winfiles==1){
sscanf(name,"%d=%d=%d=%d",&minlat,&maxlat,&minlon,&maxlon);
}else{
sscanf(name,"%d:%d:%d:%d",&minlat,&maxlat,&minlon,&maxlon);
}
/* Is it already in memory? */
for (indx=0, found=0; indx<MAXPAGES && found==0; indx++)
@@ -1565,7 +1575,7 @@ char LoadSDF(char *name)
return return_value;
}
void PlotPath(struct site source, struct site destination, char mask_value, FILE *fd)
void PlotLOSPath(struct site source, struct site destination, char mask_value, FILE *fd)
{
/* This function analyzes the path between the source and
destination locations. It determines which points along
@@ -1623,27 +1633,26 @@ void PlotPath(struct site source, struct site destination, char mask_value, FILE
}
}
void PlotLRPath(struct site source, struct site destination, unsigned char mask_value, FILE *fd)
void PlotPropPath(struct site source, struct site destination, unsigned char mask_value, FILE *fd, int propmodel, int knifeedge)
{
/* This function plots the RF path loss between source and
destination points based on the Longley-Rice propagation
model, taking into account antenna pattern data, if available. */
int x, y, ifs, ofs, errnum;
char block=0, strmode[100];
double loss, azimuth, pattern=0.0,
xmtr_alt, dest_alt, xmtr_alt2, dest_alt2,
cos_rcvr_angle, cos_test_angle=0.0, test_alt,
elevation=0.0, distance=0.0, four_thirds_earth,
field_strength=0.0, rxp, dBm;
elevation=0.0, distance=0.0, radius=0.0, four_thirds_earth,
field_strength=0.0, rxp, dBm, txelev, dkm, diffloss, lastdiffloss;
struct site temp;
radius = Distance(source,destination);
ReadPath(source,destination);
four_thirds_earth=FOUR_THIRDS*EARTHRADIUS;
/* Copy elevations plus clutter along path into the elev[] array. */
lastdiffloss=1;
for (x=1; x<path.length-1; x++)
elev[x+2]=(path.elevation[x]==0.0?path.elevation[x]*METERS_PER_FOOT:(clutter+path.elevation[x])*METERS_PER_FOOT);
@@ -1651,6 +1660,8 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
/* Copy ending points without clutter */
elev[2]=path.elevation[0]*METERS_PER_FOOT;
txelev=elev[2]+(source.alt*METERS_PER_FOOT);
elev[path.length+1]=path.elevation[path.length-1]*METERS_PER_FOOT;
/* Since the only energy the Longley-Rice model considers
@@ -1731,8 +1742,7 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
}
/* Determine attenuation for each point along the
path using Longley-Rice's point_to_point mode
starting at y=2 (number_of_points = 1), the
path using a prop model starting at y=2 (number_of_points = 1), the
shortest distance terrain can play a role in
path loss. */
@@ -1742,11 +1752,65 @@ void PlotLRPath(struct site source, struct site destination, unsigned char mask_
elev[1]=METERS_PER_MILE*(path.distance[y]-path.distance[y-1]);
/*
elev[2]=path.elevation[0]*METERS_PER_FOOT;
elev[path.length+1]=path.elevation[path.length-1]*METERS_PER_FOOT;
*/
if(path.elevation[y] < 1){
path.elevation[y]=1;
}
dkm=(elev[1]*elev[0])/1000; // km
switch (propmodel)
{
case 1:
// Longley Rice
point_to_point(elev,source.alt*METERS_PER_FOOT,
destination.alt*METERS_PER_FOOT, LR.eps_dielect,
LR.sgm_conductivity, LR.eno_ns_surfref, LR.frq_mhz,
LR.radio_climate, LR.pol, LR.conf, LR.rel, loss,
strmode, errnum);
break;
case 3:
//HATA urban
loss=HataLinkdB(LR.frq_mhz,txelev,path.elevation[y]+(destination.alt*METERS_PER_FOOT),dkm, 1);
break;
case 4:
//HATA suburban
loss=HataLinkdB(LR.frq_mhz,txelev,path.elevation[y]+(destination.alt*METERS_PER_FOOT),dkm, 2);
break;
case 5:
//HATA open
loss=HataLinkdB(LR.frq_mhz,txelev,path.elevation[y]+(destination.alt*METERS_PER_FOOT),dkm, 3);
break;
case 6:
// COST231-HATA
loss=CostHataLinkdB(LR.frq_mhz,txelev,path.elevation[y]+(destination.alt*METERS_PER_FOOT),dkm);
break;
default:
point_to_point(elev,source.alt*METERS_PER_FOOT,
destination.alt*METERS_PER_FOOT, LR.eps_dielect,
LR.sgm_conductivity, LR.eno_ns_surfref, LR.frq_mhz,
LR.radio_climate, LR.pol, LR.conf, LR.rel, loss,
strmode, errnum);
}
if(knifeedge==1){
diffloss = ked(LR.frq_mhz,elev,destination.alt*METERS_PER_FOOT,dkm);
loss+=(diffloss); // ;)
}
if(debug){
fprintf(stdout,"\n%2f\t%2f\t%2f\t%2f",txelev,path.elevation[y],dkm,loss);
fflush(stdout);
}
//Key stage. Link dB for p2p is returned as 'loss'.
temp.lat=path.lat[y];
temp.lon=path.lon[y];
@@ -1877,9 +1941,9 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
of a topographic map when the WritePPM() function
is later invoked. */
int y, z, count;
int y, z;
struct site edge;
unsigned char symbol[4], x;
unsigned char x;
double lat, lon, minwest, maxnorth, th;
static unsigned char mask_value=1;
FILE *fd=NULL;
@@ -1909,7 +1973,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
edge.lon=lon;
edge.alt=altitude;
PlotPath(source,edge,mask_value,fd);
PlotLOSPath(source,edge,mask_value,fd);
}
@@ -1922,7 +1986,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
edge.lon=min_west;
edge.alt=altitude;
PlotPath(source,edge,mask_value,fd);
PlotLOSPath(source,edge,mask_value,fd);
}
@@ -1939,7 +2003,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
edge.lon=lon;
edge.alt=altitude;
PlotPath(source,edge,mask_value,fd);
PlotLOSPath(source,edge,mask_value,fd);
}
@@ -1952,7 +2016,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
edge.lon=max_west;
edge.alt=altitude;
PlotPath(source,edge,mask_value,fd);
PlotLOSPath(source,edge,mask_value,fd);
}
@@ -1973,21 +2037,12 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
}
}
void PlotLRMap(struct site source, double altitude, char *plo_filename)
void PlotPropagation(struct site source, double altitude, char *plo_filename, int propmodel, int knifeedge)
{
/* This function performs a 360 degree sweep around the
transmitter site (source location), and plots the
Longley-Rice attenuation on the ss generated
topographic map based on a receiver located at
the specified altitude (in feet AGL). Results
are stored in memory, and written out in the form
of a topographic map when the DoPathLoss() or
DoSigStr() functions are later invoked. */
int y, z, count;
struct site edge;
double lat, lon, minwest, maxnorth, th;
unsigned char x, symbol[4];
unsigned char x;
static unsigned char mask_value=1;
FILE *fd=NULL;
@@ -1995,9 +2050,7 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
maxnorth=(double)max_north-dpp;
count=0;
if (debug){
fprintf(stdout,"\nComputing Longley-Rice ");
}
if (LR.erp==0.0 && debug)
fprintf(stdout,"path loss");
@@ -2025,14 +2078,9 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
if (fd!=NULL)
{
/* Write header information to output file */
fprintf(fd,"%d, %d\t; max_west, min_west\n%d, %d\t; max_north, min_north\n",max_west, min_west, max_north, min_north);
}
/* th=pixels/degree divided by 64 loops per
progress indicator symbol (.oOo) printed. */
th=ppd/loops;
z=(int)(th*ReduceAngle(max_west-min_west));
@@ -2046,13 +2094,11 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
edge.lon=lon;
edge.alt=altitude;
PlotLRPath(source,edge,mask_value,fd);
PlotPropPath(source,edge,mask_value,fd,propmodel,knifeedge);
count++;
if (count==z)
{
//fprintf(stdout,"%c",symbol[x]);
//fflush(stdout);
count=0;
if (x==3)
@@ -2075,7 +2121,7 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
edge.lon=min_west;
edge.alt=altitude;
PlotLRPath(source,edge,mask_value,fd);
PlotPropPath(source,edge,mask_value,fd,propmodel,knifeedge);
count++;
if (count==z)
@@ -2107,7 +2153,7 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
edge.lon=lon;
edge.alt=altitude;
PlotLRPath(source,edge,mask_value,fd);
PlotPropPath(source,edge,mask_value,fd,propmodel,knifeedge);
count++;
if (count==z)
{
@@ -2136,13 +2182,12 @@ void PlotLRMap(struct site source, double altitude, char *plo_filename)
edge.lon=max_west;
edge.alt=altitude;
PlotLRPath(source,edge,mask_value,fd);
PlotPropPath(source,edge,mask_value,fd,propmodel,knifeedge);
count++;
if (count==z)
{
//fprintf(stdout,"%c",symbol[x]);
//fflush(stdout);
count=0;
if (x==3)
@@ -3273,9 +3318,9 @@ void DoLOS(char *filename, unsigned char geo, unsigned char kml, unsigned char n
points up and east points right in the image generated. */
char mapfile[255], geofile[255], kmlfile[255];
unsigned width, height, terrain, red, green, blue;
unsigned char found, mask, cityorcounty;
int indx, x, y, z=1, x0, y0, dBm, match;
unsigned width, height, terrain;
unsigned char found, mask;
int indx, x, y, x0, y0;
double conversion, one_over_gamma, lat, lon, minwest;
FILE *fd;
@@ -3488,7 +3533,7 @@ void DoLOS(char *filename, unsigned char geo, unsigned char kml, unsigned char n
}
void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat)
void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat, int winfiles)
{
/* This function loads the SDF files required
to cover the limits of the region specified. */
@@ -3518,13 +3563,20 @@ void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat)
while (ymax>=360)
ymax-=360;
if (winfiles==1){
if (ippd==3600)
snprintf(string,19,"%d:%d:%d:%d-hd",x, x+1, ymin, ymax);
snprintf(string,19,"%d=%d=%d=%d=hd",x, x+1, ymin, ymax);
else
snprintf(string,16,"%d=%d=%d=%d",x, x+1, ymin, ymax);
}else{
if (ippd==3600)
snprintf(string,19,"%d:%d:%d:%d=hd",x, x+1, ymin, ymax);
else
snprintf(string,16,"%d:%d:%d:%d",x, x+1, ymin, ymax);
}
LoadSDF(string);
LoadSDF(string,winfiles);
}
}
@@ -3549,11 +3601,20 @@ void LoadTopoData(int max_lon, int min_lon, int max_lat, int min_lat)
while (ymax>=360)
ymax-=360;
if (winfiles==1){
if (ippd==3600)
snprintf(string,19,"%d:%d:%d:%d-hd",x, x+1, ymin, ymax);
snprintf(string,19,"%d=%d=%d=%d=hd",x, x+1, ymin, ymax);
else
snprintf(string,16,"%d=%d=%d=%d",x, x+1, ymin, ymax);
}else{
if (ippd==3600)
snprintf(string,19,"%d:%d:%d:%d=hd",x, x+1, ymin, ymax);
else
snprintf(string,16,"%d:%d:%d:%d",x, x+1, ymin, ymax);
LoadSDF(string);
}
LoadSDF(string,winfiles);
}
}
}
@@ -3725,7 +3786,7 @@ int main(int argc, char *argv[])
{
int x, y, z=0, min_lat, min_lon, max_lat, max_lon,
rxlat, rxlon, txlat, txlon, west_min, west_max,
north_min, north_max;
north_min, north_max, propmodel, winfiles,knifeedge=0;
unsigned char LRmap=0, map=0,txsites=0,
topomap=0, geo=0, kml=0, area_mode=0, max_txsites, ngs=0;
@@ -3742,7 +3803,7 @@ int main(int argc, char *argv[])
strncpy(ss_version,"1.3.6\0",6);
strncpy(ss_version,"1.3.7\0",6);
strncpy(ss_name,"Signal Server\0",14);
if (argc==1)
@@ -3769,7 +3830,10 @@ int main(int argc, char *argv[])
fprintf(stdout," -R Radius (miles/kilometers)\n");
fprintf(stdout," -res Pixels per degree. 300/600/1200(default)/3600 (optional)\n");
fprintf(stdout," -t Terrain background\n");
fprintf(stdout," -dbg Debug\n\n");
fprintf(stdout," -pm Propagation model. 1: ITM (Default), 2: LOS, 3-5: Hata\n");
fprintf(stdout," -ked Knife edge diffraction (Default for ITM)\n");
fprintf(stdout," -wf Win32 SDF tile names ('=' not ':')\n");
fprintf(stdout," -dbg Debug mode\n\n");
@@ -3807,7 +3871,8 @@ int main(int argc, char *argv[])
ani_filename[0]=0;
earthradius=EARTHRADIUS;
max_range=1.0;
propmodel=1; //ITM
winfiles=0;
lat=0;
lon=0;
@@ -3837,10 +3902,6 @@ int main(int argc, char *argv[])
tx_site[0].lon=361.0;
//flush dem
//memset(dem, 0, ARRAYSIZE * sizeof(struct dem));
memset(dem, 0, (size_t)MAXPAGES * sizeof(struct dem));
for (x=0; x<MAXPAGES; x++)
{
dem[x].min_el=32768;
@@ -4158,7 +4219,31 @@ int main(int argc, char *argv[])
}
}
/*Prop model*/
if (strcmp(argv[x],"-pm")==0)
{
z=x+1;
if (z<=y && argv[z][0])
{
sscanf(argv[z],"%d",&propmodel);
}
}
//Knife edge diffraction
if (strcmp(argv[x],"-ked")==0)
{
z=x+1;
knifeedge=1;
}
//Windows friendly SDF filenames
if (strcmp(argv[x],"-wf")==0)
{
z=x+1;
winfiles=1;
}
}
/* ERROR DETECTION */
@@ -4221,7 +4306,10 @@ int main(int argc, char *argv[])
fprintf(stdout,"ERROR: Receiver threshold out of range (-200 / +200)");
exit(0);
}
if(propmodel>2 && LR.frq_mhz < 150){
fprintf(stdout,"ERROR: Frequency too low for Propagation model");
exit(0);
}
/* ERROR DETECTION COMPLETE */
@@ -4229,12 +4317,11 @@ int main(int argc, char *argv[])
if (metric)
{
altitudeLR/=METERS_PER_FOOT; /* RXH meters --> feet */
max_range/=KM_PER_MILE; /* RAD kilometers --> miles */
altitudeLR/=METERS_PER_FOOT; /* 10ft * 0.3 = 3.3m */
max_range/=KM_PER_MILE; /* 10 / 1.6 = 7.5 */
altitude/=METERS_PER_FOOT;
tx_site[0].alt/=METERS_PER_FOOT; /* TXH meters --> feet */
clutter/=METERS_PER_FOOT; /* CLH meters --> feet */
tx_site[0].alt/=METERS_PER_FOOT; /* Feet to metres */
clutter/=METERS_PER_FOOT; /* Feet to metres */
}
/* Ensure a trailing '/' is present in sdf_path */
@@ -4296,7 +4383,7 @@ int main(int argc, char *argv[])
/* Load the required SDF files */
LoadTopoData(max_lon, min_lon, max_lat, min_lat);
LoadTopoData(max_lon, min_lon, max_lat, min_lat, winfiles);
if (area_mode || topomap)
{
@@ -4381,22 +4468,19 @@ int main(int argc, char *argv[])
/* Load any additional SDF files, if required */
LoadTopoData(max_lon, min_lon, max_lat, min_lat);
LoadTopoData(max_lon, min_lon, max_lat, min_lat, winfiles);
}
// UDT clutter
LoadUDT (udt_file);
if (LR.frq_mhz > 20000){
if (LR.frq_mhz > 20000 || propmodel==2){
PlotLOSMap(tx_site[0],altitudeLR,ano_filename);
DoLOS(mapfile,geo,kml,ngs,tx_site,txsites);
}
else{
PlotLRMap(tx_site[0],altitudeLR,ano_filename);
PlotPropagation(tx_site[0],altitudeLR,ano_filename,propmodel,knifeedge);
if (LR.erp==0.0)
DoPathLoss(mapfile,geo,kml,ngs,tx_site,txsites);