forked from ExternalVendorCode/Signal-Server
Handle missing antenna pattern file
This commit is contained in:
536
inputs.cc
536
inputs.cc
@@ -659,7 +659,7 @@ char LoadSDF(char *name)
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void LoadPAT(char *filename)
|
||||
int LoadPAT(char *filename)
|
||||
{
|
||||
/* This function reads and processes antenna pattern (.az
|
||||
and .el) files that correspond in name to previously
|
||||
@@ -696,38 +696,57 @@ void LoadPAT(char *filename)
|
||||
|
||||
/* Load .az antenna pattern file */
|
||||
|
||||
fd = fopen(azfile, "r");
|
||||
if( (fd = fopen(azfile, "r")) == NULL )
|
||||
return errno;
|
||||
|
||||
if (fd != NULL) {
|
||||
/* Clear azimuth pattern array */
|
||||
/* Clear azimuth pattern array */
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
azimuth[x] = 0.0;
|
||||
read_count[x] = 0;
|
||||
for (x = 0; x <= 360; x++) {
|
||||
azimuth[x] = 0.0;
|
||||
read_count[x] = 0;
|
||||
}
|
||||
|
||||
/* Read azimuth pattern rotation
|
||||
in degrees measured clockwise
|
||||
from true North. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Azimuth read error\n");
|
||||
//exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f", &rotation);
|
||||
|
||||
/* Read azimuth (degrees) and corresponding
|
||||
normalized field radiation pattern amplitude
|
||||
(0.0 to 1.0) until EOF is reached. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Azimuth read error\n");
|
||||
//exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &az, &litude);
|
||||
|
||||
do {
|
||||
x = (int)rintf(az);
|
||||
|
||||
if (x >= 0 && x <= 360 && fd != NULL) {
|
||||
azimuth[x] += amplitude;
|
||||
read_count[x]++;
|
||||
}
|
||||
|
||||
/* Read azimuth pattern rotation
|
||||
in degrees measured clockwise
|
||||
from true North. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Azimuth read error\n");
|
||||
//exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f", &rotation);
|
||||
|
||||
/* Read azimuth (degrees) and corresponding
|
||||
normalized field radiation pattern amplitude
|
||||
(0.0 to 1.0) until EOF is reached. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Azimuth read error\n");
|
||||
//exit(0);
|
||||
// exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
@@ -736,265 +755,244 @@ void LoadPAT(char *filename)
|
||||
|
||||
sscanf(string, "%f %f", &az, &litude);
|
||||
|
||||
do {
|
||||
x = (int)rintf(az);
|
||||
} while (feof(fd) == 0);
|
||||
|
||||
if (x >= 0 && x <= 360 && fd != NULL) {
|
||||
azimuth[x] += amplitude;
|
||||
read_count[x]++;
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Azimuth read error\n");
|
||||
// exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
/* Handle 0=360 degree ambiguity */
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &az, &litude);
|
||||
|
||||
} while (feof(fd) == 0);
|
||||
|
||||
fclose(fd);
|
||||
|
||||
/* Handle 0=360 degree ambiguity */
|
||||
|
||||
if ((read_count[0] == 0) && (read_count[360] != 0)) {
|
||||
read_count[0] = read_count[360];
|
||||
azimuth[0] = azimuth[360];
|
||||
}
|
||||
|
||||
if ((read_count[0] != 0) && (read_count[360] == 0)) {
|
||||
read_count[360] = read_count[0];
|
||||
azimuth[360] = azimuth[0];
|
||||
}
|
||||
|
||||
/* Average pattern values in case more than
|
||||
one was read for each degree of azimuth. */
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
if (read_count[x] > 1)
|
||||
azimuth[x] /= (float)read_count[x];
|
||||
}
|
||||
|
||||
/* Interpolate missing azimuths
|
||||
to completely fill the array */
|
||||
|
||||
last_index = -1;
|
||||
next_index = -1;
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
if (read_count[x] != 0) {
|
||||
if (last_index == -1)
|
||||
last_index = x;
|
||||
else
|
||||
next_index = x;
|
||||
}
|
||||
|
||||
if (last_index != -1 && next_index != -1) {
|
||||
valid1 = azimuth[last_index];
|
||||
valid2 = azimuth[next_index];
|
||||
|
||||
span = next_index - last_index;
|
||||
delta = (valid2 - valid1) / (float)span;
|
||||
|
||||
for (y = last_index + 1; y < next_index; y++)
|
||||
azimuth[y] = azimuth[y - 1] + delta;
|
||||
|
||||
last_index = y;
|
||||
next_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform azimuth pattern rotation
|
||||
and load azimuth_pattern[361] with
|
||||
azimuth pattern data in its final form. */
|
||||
|
||||
for (x = 0; x < 360; x++) {
|
||||
y = x + (int)rintf(rotation);
|
||||
|
||||
if (y >= 360)
|
||||
y -= 360;
|
||||
|
||||
azimuth_pattern[y] = azimuth[x];
|
||||
}
|
||||
|
||||
azimuth_pattern[360] = azimuth_pattern[0];
|
||||
|
||||
got_azimuth_pattern = 255;
|
||||
if ((read_count[0] == 0) && (read_count[360] != 0)) {
|
||||
read_count[0] = read_count[360];
|
||||
azimuth[0] = azimuth[360];
|
||||
}
|
||||
|
||||
if ((read_count[0] != 0) && (read_count[360] == 0)) {
|
||||
read_count[360] = read_count[0];
|
||||
azimuth[360] = azimuth[0];
|
||||
}
|
||||
|
||||
/* Average pattern values in case more than
|
||||
one was read for each degree of azimuth. */
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
if (read_count[x] > 1)
|
||||
azimuth[x] /= (float)read_count[x];
|
||||
}
|
||||
|
||||
/* Interpolate missing azimuths
|
||||
to completely fill the array */
|
||||
|
||||
last_index = -1;
|
||||
next_index = -1;
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
if (read_count[x] != 0) {
|
||||
if (last_index == -1)
|
||||
last_index = x;
|
||||
else
|
||||
next_index = x;
|
||||
}
|
||||
|
||||
if (last_index != -1 && next_index != -1) {
|
||||
valid1 = azimuth[last_index];
|
||||
valid2 = azimuth[next_index];
|
||||
|
||||
span = next_index - last_index;
|
||||
delta = (valid2 - valid1) / (float)span;
|
||||
|
||||
for (y = last_index + 1; y < next_index; y++)
|
||||
azimuth[y] = azimuth[y - 1] + delta;
|
||||
|
||||
last_index = y;
|
||||
next_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform azimuth pattern rotation
|
||||
and load azimuth_pattern[361] with
|
||||
azimuth pattern data in its final form. */
|
||||
|
||||
for (x = 0; x < 360; x++) {
|
||||
y = x + (int)rintf(rotation);
|
||||
|
||||
if (y >= 360)
|
||||
y -= 360;
|
||||
|
||||
azimuth_pattern[y] = azimuth[x];
|
||||
}
|
||||
|
||||
azimuth_pattern[360] = azimuth_pattern[0];
|
||||
|
||||
got_azimuth_pattern = 255;
|
||||
|
||||
/* Read and process .el file */
|
||||
|
||||
fd = fopen(elfile, "r");
|
||||
if( (fd = fopen(elfile, "r")) == NULL )
|
||||
return errno;
|
||||
|
||||
if (fd != NULL) {
|
||||
for (x = 0; x <= 10000; x++) {
|
||||
el_pattern[x] = 0.0;
|
||||
read_count[x] = 0;
|
||||
for (x = 0; x <= 10000; x++) {
|
||||
el_pattern[x] = 0.0;
|
||||
read_count[x] = 0;
|
||||
}
|
||||
|
||||
/* Read mechanical tilt (degrees) and
|
||||
tilt azimuth in degrees measured
|
||||
clockwise from true North. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Tilt read error\n");
|
||||
//exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &mechanical_tilt, &tilt_azimuth);
|
||||
|
||||
/* Read elevation (degrees) and corresponding
|
||||
normalized field radiation pattern amplitude
|
||||
(0.0 to 1.0) until EOF is reached. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Ant elevation read error\n");
|
||||
//exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &elevation, &litude);
|
||||
|
||||
while (feof(fd) == 0) {
|
||||
/* Read in normalized radiated field values
|
||||
for every 0.01 degrees of elevation between
|
||||
-10.0 and +90.0 degrees */
|
||||
|
||||
x = (int)rintf(100.0 * (elevation + 10.0));
|
||||
|
||||
if (x >= 0 && x <= 10000) {
|
||||
el_pattern[x] += amplitude;
|
||||
read_count[x]++;
|
||||
}
|
||||
|
||||
/* Read mechanical tilt (degrees) and
|
||||
tilt azimuth in degrees measured
|
||||
clockwise from true North. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Tilt read error\n");
|
||||
//exit(0);
|
||||
if (fgets(string, 254, fd) != NULL) {
|
||||
pointer = strchr(string, ';');
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &mechanical_tilt, &tilt_azimuth);
|
||||
|
||||
/* Read elevation (degrees) and corresponding
|
||||
normalized field radiation pattern amplitude
|
||||
(0.0 to 1.0) until EOF is reached. */
|
||||
|
||||
if (fgets(string, 254, fd) == NULL) {
|
||||
//fprintf(stderr,"Ant elevation read error\n");
|
||||
//exit(0);
|
||||
}
|
||||
pointer = strchr(string, ';');
|
||||
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &elevation, &litude);
|
||||
|
||||
while (feof(fd) == 0) {
|
||||
/* Read in normalized radiated field values
|
||||
for every 0.01 degrees of elevation between
|
||||
-10.0 and +90.0 degrees */
|
||||
|
||||
x = (int)rintf(100.0 * (elevation + 10.0));
|
||||
|
||||
if (x >= 0 && x <= 10000) {
|
||||
el_pattern[x] += amplitude;
|
||||
read_count[x]++;
|
||||
}
|
||||
|
||||
if (fgets(string, 254, fd) != NULL) {
|
||||
pointer = strchr(string, ';');
|
||||
}
|
||||
if (pointer != NULL)
|
||||
*pointer = 0;
|
||||
|
||||
sscanf(string, "%f %f", &elevation, &litude);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
||||
/* Average the field values in case more than
|
||||
one was read for each 0.01 degrees of elevation. */
|
||||
|
||||
for (x = 0; x <= 10000; x++) {
|
||||
if (read_count[x] > 1)
|
||||
el_pattern[x] /= (float)read_count[x];
|
||||
}
|
||||
|
||||
/* Interpolate between missing elevations (if
|
||||
any) to completely fill the array and provide
|
||||
radiated field values for every 0.01 degrees of
|
||||
elevation. */
|
||||
|
||||
last_index = -1;
|
||||
next_index = -1;
|
||||
|
||||
for (x = 0; x <= 10000; x++) {
|
||||
if (read_count[x] != 0) {
|
||||
if (last_index == -1)
|
||||
last_index = x;
|
||||
else
|
||||
next_index = x;
|
||||
}
|
||||
|
||||
if (last_index != -1 && next_index != -1) {
|
||||
valid1 = el_pattern[last_index];
|
||||
valid2 = el_pattern[next_index];
|
||||
|
||||
span = next_index - last_index;
|
||||
delta = (valid2 - valid1) / (float)span;
|
||||
|
||||
for (y = last_index + 1; y < next_index; y++)
|
||||
el_pattern[y] =
|
||||
el_pattern[y - 1] + delta;
|
||||
|
||||
last_index = y;
|
||||
next_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill slant_angle[] array with offset angles based
|
||||
on the antenna's mechanical beam tilt (if any)
|
||||
and tilt direction (azimuth). */
|
||||
|
||||
if (mechanical_tilt == 0.0) {
|
||||
for (x = 0; x <= 360; x++)
|
||||
slant_angle[x] = 0.0;
|
||||
}
|
||||
|
||||
else {
|
||||
tilt_increment = mechanical_tilt / 90.0;
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
xx = (float)x;
|
||||
y = (int)rintf(tilt_azimuth + xx);
|
||||
|
||||
while (y >= 360)
|
||||
y -= 360;
|
||||
|
||||
while (y < 0)
|
||||
y += 360;
|
||||
|
||||
if (x <= 180)
|
||||
slant_angle[y] =
|
||||
-(tilt_increment * (90.0 - xx));
|
||||
|
||||
if (x > 180)
|
||||
slant_angle[y] =
|
||||
-(tilt_increment * (xx - 270.0));
|
||||
}
|
||||
}
|
||||
|
||||
slant_angle[360] = slant_angle[0]; /* 360 degree wrap-around */
|
||||
|
||||
for (w = 0; w <= 360; w++) {
|
||||
tilt = slant_angle[w];
|
||||
|
||||
/** Convert tilt angle to
|
||||
an array index offset **/
|
||||
|
||||
y = (int)rintf(100.0 * tilt);
|
||||
|
||||
/* Copy shifted el_pattern[10001] field
|
||||
values into elevation_pattern[361][1001]
|
||||
at the corresponding azimuth, downsampling
|
||||
(averaging) along the way in chunks of 10. */
|
||||
|
||||
for (x = y, z = 0; z <= 1000; x += 10, z++) {
|
||||
for (sum = 0.0, a = 0; a < 10; a++) {
|
||||
b = a + x;
|
||||
|
||||
if (b >= 0 && b <= 10000)
|
||||
sum += el_pattern[b];
|
||||
if (b < 0)
|
||||
sum += el_pattern[0];
|
||||
if (b > 10000)
|
||||
sum += el_pattern[10000];
|
||||
}
|
||||
|
||||
elevation_pattern[w][z] = sum / 10.0;
|
||||
}
|
||||
}
|
||||
|
||||
got_elevation_pattern = 255;
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
||||
/* Average the field values in case more than
|
||||
one was read for each 0.01 degrees of elevation. */
|
||||
|
||||
for (x = 0; x <= 10000; x++) {
|
||||
if (read_count[x] > 1)
|
||||
el_pattern[x] /= (float)read_count[x];
|
||||
}
|
||||
|
||||
/* Interpolate between missing elevations (if
|
||||
any) to completely fill the array and provide
|
||||
radiated field values for every 0.01 degrees of
|
||||
elevation. */
|
||||
|
||||
last_index = -1;
|
||||
next_index = -1;
|
||||
|
||||
for (x = 0; x <= 10000; x++) {
|
||||
if (read_count[x] != 0) {
|
||||
if (last_index == -1)
|
||||
last_index = x;
|
||||
else
|
||||
next_index = x;
|
||||
}
|
||||
|
||||
if (last_index != -1 && next_index != -1) {
|
||||
valid1 = el_pattern[last_index];
|
||||
valid2 = el_pattern[next_index];
|
||||
|
||||
span = next_index - last_index;
|
||||
delta = (valid2 - valid1) / (float)span;
|
||||
|
||||
for (y = last_index + 1; y < next_index; y++)
|
||||
el_pattern[y] =
|
||||
el_pattern[y - 1] + delta;
|
||||
|
||||
last_index = y;
|
||||
next_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill slant_angle[] array with offset angles based
|
||||
on the antenna's mechanical beam tilt (if any)
|
||||
and tilt direction (azimuth). */
|
||||
|
||||
if (mechanical_tilt == 0.0) {
|
||||
for (x = 0; x <= 360; x++)
|
||||
slant_angle[x] = 0.0;
|
||||
}
|
||||
|
||||
else {
|
||||
tilt_increment = mechanical_tilt / 90.0;
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
xx = (float)x;
|
||||
y = (int)rintf(tilt_azimuth + xx);
|
||||
|
||||
while (y >= 360)
|
||||
y -= 360;
|
||||
|
||||
while (y < 0)
|
||||
y += 360;
|
||||
|
||||
if (x <= 180)
|
||||
slant_angle[y] =
|
||||
-(tilt_increment * (90.0 - xx));
|
||||
|
||||
if (x > 180)
|
||||
slant_angle[y] =
|
||||
-(tilt_increment * (xx - 270.0));
|
||||
}
|
||||
}
|
||||
|
||||
slant_angle[360] = slant_angle[0]; /* 360 degree wrap-around */
|
||||
|
||||
for (w = 0; w <= 360; w++) {
|
||||
tilt = slant_angle[w];
|
||||
|
||||
/** Convert tilt angle to
|
||||
an array index offset **/
|
||||
|
||||
y = (int)rintf(100.0 * tilt);
|
||||
|
||||
/* Copy shifted el_pattern[10001] field
|
||||
values into elevation_pattern[361][1001]
|
||||
at the corresponding azimuth, downsampling
|
||||
(averaging) along the way in chunks of 10. */
|
||||
|
||||
for (x = y, z = 0; z <= 1000; x += 10, z++) {
|
||||
for (sum = 0.0, a = 0; a < 10; a++) {
|
||||
b = a + x;
|
||||
|
||||
if (b >= 0 && b <= 10000)
|
||||
sum += el_pattern[b];
|
||||
if (b < 0)
|
||||
sum += el_pattern[0];
|
||||
if (b > 10000)
|
||||
sum += el_pattern[10000];
|
||||
}
|
||||
|
||||
elevation_pattern[w][z] = sum / 10.0;
|
||||
}
|
||||
}
|
||||
|
||||
got_elevation_pattern = 255;
|
||||
|
||||
for (x = 0; x <= 360; x++) {
|
||||
for (y = 0; y <= 1000; y++) {
|
||||
if (got_elevation_pattern)
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
int LoadSDF_SDF(char *name, int winfiles);
|
||||
char LoadSDF(char *name, int winfiles);
|
||||
void LoadPAT(char *filename);
|
||||
int LoadPAT(char *filename);
|
||||
void LoadSignalColors(struct site xmtr);
|
||||
void LoadLossColors(struct site xmtr);
|
||||
void LoadDBMColors(struct site xmtr);
|
||||
|
5
main.cc
5
main.cc
@@ -1218,7 +1218,10 @@ int main(int argc, char *argv[])
|
||||
strncpy(mapfile, argv[z], 253);
|
||||
strncpy(tx_site[0].name, "Tx", 2);
|
||||
strncpy(tx_site[0].filename, argv[z], 253);
|
||||
LoadPAT(argv[z]);
|
||||
if( (result = LoadPAT(argv[z])) != 0 ){
|
||||
fprintf(stderr,"Error reading antenna pattern file\n");
|
||||
exit(result);
|
||||
}
|
||||
} else if (z <= y && argv[z][0] && argv[z][0] == '-' && argv[z][1] == '\0' ) {
|
||||
/* Handle writing image data to stdout */
|
||||
to_stdout = true;
|
||||
|
Reference in New Issue
Block a user