This commit is contained in:
alex
2018-08-29 19:33:23 +01:00
9 changed files with 1398 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>to #include <unistd.h>
#include <math.h> #include <math.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>

15
utils/antenna/README.md Normal file
View File

@@ -0,0 +1,15 @@
Utility for convertng .ant files to Signal Server Format
ant2azel
-i antfilenam
-o outputfile
-d enable debugging
-h print help
-a Set the azimuth of the antenna
-t Set the mechanical tilt of the antenna positive numbers are downtilt.
orginal version by kd7lxl, adapted to include the azimuth and tilt

64
utils/antenna/ant2azel.py Executable file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python
import sys
import getopt
import os.path
from os.path import splitext
def db_to_norm(db):
return 10**(db/10.)
def main(argv):
antfile = ''
outfile = ''
direction = 0
tilt = 0
debug = 0
program = os.path.basename(__file__)
try:
opts, args = getopt.getopt(argv,"dha:i:o:t:",["debug","help","azimuth=","infile=","outfile=","tilt="])
except getopt.GetoptError:
print program + ' --debug --help -a <azimuth> -t <mechanicaldowntilt> -i <inputfile> -o <outputfile>'
sys.exit(2)
for opt, arg in opts:
if opt in ("-d", "--debug"):
debug = 1
elif opt in ("-h", "--help"):
print program + ' --debug --help -a <azimuth> -t <mechanicaldowntilt> -i <inputfile> -o <outputfile>'
sys.exit(2)
elif opt in ("-i", "--infile"):
antfile = arg
elif opt in ("-o", "--outfile"):
outfile = arg
elif opt in ("-a", "--azimuth"):
direction = arg
elif opt in ("-t", "--tilt"):
tilt = arg
if antfile == '':
print program + ' --debug --help -a <azimuth> -t <mechanicaldowntilt> -i <inputfile> -o <outputfile>'
sys.exit(2)
if outfile == '' :
outfile = splitext(antfile)[0]
if debug :
print "outfile " + outfile
print "downtilt " + tilt
with open(antfile, 'r') as ant:
with open(outfile + '.az', 'w') as az:
# azimuth offset as provided by command arg or 0
az.write("%d\n" % float(direction))
# Read the first 360 lines of the file
for i in xrange(360):
az.write("%d\t%0.4f\n" % (i, db_to_norm(float(next(ant)))))
with open(outfile + '.el', 'w') as el:
# mechanical downtilt, azimuth of tilt
el.write("%0.1f\t%0.1f\n" % (float(tilt), float(direction)))
# Read the lines for elevations +10 through -90).
# The rest of the .ant is unused.
for i, line in enumerate(list(ant)[80:181], -10):
el.write("%d\t%0.4f\n" % (i, db_to_norm(float(line))))
if __name__ == "__main__":
main(sys.argv[1:])

View File

@@ -0,0 +1,73 @@
#!/bin/sh
#
# Requires:
# - gdal_sieve.py
# - ogr2ogr (GDAL)
# - topojson (node.js)
# obtained from: https://gist.github.com/petesaia
# Grab the relative directory for source file.
SRC_DIR=`dirname $1`
# Which raster to compress.
ORG_FILE="$1"
ADD_COL="$2"
# Final output file.
OUTPUT_FILE="$1.json"
echo "Processing $ORG_FILE."
# Where to output the new file.
TMP_DIR=$SRC_DIR/tmp
# The amount of times the file should be passed over.
ITERATIONS=4
# Threshold for each iteration.
THRESHOLD=40
# TopoJSON area threshold for simplification.
TOPO_COMPRESSION=0.0001
# Setup internal vars.
_CUR=$THRESHOLD
_COMPRESSION=$(($ITERATIONS * $THRESHOLD))
#rm -rf $TMP_DIR
mkdir -p $TMP_DIR
# Start sieve passes.
gdal_sieve.py -st $THRESHOLD -4 $ORG_FILE $TMP_DIR/output-"$THRESHOLD".tiff
while [ $_CUR -le $_COMPRESSION ]; do
let _PREV=$_CUR
let _CUR=$_CUR+$THRESHOLD
echo "Compressing output-$_PREV.tiff into $_CUR.tiff"
gdal_sieve.py -st $THRESHOLD -4 "$TMP_DIR/output-$_PREV.tiff" \
"$TMP_DIR/output-$_CUR.tiff"
rm "$TMP_DIR/output-$_PREV.tiff"
done
# Raster to vector.
gdal_polygonize.py $TMP_DIR/output-"$_CUR".tiff \
-f "ESRI Shapefile" $TMP_DIR vector n
if [ ! -z "$ADD_COL" ]; then
echo "Adding $ADDCOL information"
ogrinfo "$TMP_DIR/vector.shp" -sql "ALTER TABLE vector ADD COLUMN fname character(32)"
ogrinfo "$TMP_DIR/vector.shp" -dialect SQLite -sql "UPDATE vector SET fname ='$ADD_COL'"
fi
# Change shapefile to geojson without the 0 layer, which is water. and simply to ~ 100m resolution
echo "Change shapefile to geojson without the 0 layer, which is water."
# and simply to ~ 100m resolution
# ogr2ogr -f "GeoJSON" -where "n != 0" "$TMP_DIR/geojson.json" "$TMP_DIR/vector.shp"
ogr2ogr -f "GeoJSON" "$TMP_DIR/geojson.json" "$TMP_DIR/vector.shp"
# Convert to compressed TopoJSON.
# topojson -o $OUTPUT_FILE --no-stitch-poles -s $TOPO_COMPRESSION \
# -p -- "$TMP_DIR/geojson.json"
# Clean up.
#rm -rf $TMP_DIR

21
utils/lidar/README.md Normal file
View File

@@ -0,0 +1,21 @@
Format used by Signal-Server for LIDAR is as follows:
GDAL Driver AAIGrid
Type Int32
Projection EPSG:4326
Pacific Northwest LIDAR comes in esri .e00 format. To get it into a usable form
we can use gdal tools.
Reproject the source data to EPSG:4326 (GRS84, lat/long)
gdalwarp -t_srs EPSG:4326 -of GS7BG -ot Float64 srcfile.e00 destfile.xyz
[user@host ~]$ gdalwarp -t_srs EPSG:4326 -of GS7BG -ot Float64 ~/q47122a71.e00 ~/q47122a71.xyz
Convert the intermedatry file to AAIGrid Int32
gdal_translate -of AAIGrid -ot Int32 srcfile.xyz destfile.asc
[user@host ~]$ gdal_translate -of AAIGrid -ot Int32 ~/q47122a71.xyz ~/q47122a71.asc
The above could be pipelined to reduce intermedaty files.

131
utils/sdf/README.md Normal file
View File

@@ -0,0 +1,131 @@
================
SPLAT! Utilities
================
Utilities for use with SPLAT! software are found under the
splat-1.3.0/utils directory. They include the following:
srtm2sdf
========
The srtm2sdf utility generates Data Files (SDFs) for use with Signal-Server
from STS-99 Space Shuttle Topography Mission (SRTM) elevation data files.
This data is of a much higher quality than that contained in older USGS
Digital Elevation Models of the same resolution. However, many SRTM
Version 2 elevation models contain data "spikes", "voids", and "wells"
that are the consequence of the radar mapping process.
The srtm2sdf utility has the ability to detect and replace SRTM data
outliers with equivalent usgs2sdf derived SDF data (see usgs2sdf below).
If such data is not available, SRTM outliers are handled either through
adjacent pixel averaging, or by threshold limiting using user-specified
limits. Of all three methods, the USGS-derived SDF replacement method
yields the best results.
The srtm2sdf utility processes SRTM-3 3-arc second resolution data
or use with Signal-Server operating in standard definition mode.
SRTM-3 Version 2 Elevation Data files may be downloaded from:
ftp://e0srp01u.ecs.nasa.gov:21/srtm/version2/
Files available at this site are ZIP compressed, and must be
uncompressed (using "unzip", or "gunzip -S .zip") prior to being
processed by srtm2sdf.
The srtm2sdf utility accepts command-line options as follows:
-d: used to specify the directory path to the location of usgs2sdf
derived SDF files that are to be used to replace outliers found
in the SRTM data file. The -d option overrides the default path
specified in your $HOME/.splat_path file.
-n: used to specify the elevation (in meters) below which SRTM data
is either replaced with usgs2sdf-derived SDF data, or averaged
among adjacent elevation data points. The default threshold for
the replacement limit is sea-level (0 meters). Unless elevations
below sea-level are known to exist for the region being
processed by the srtm2sdf utility, the -n option need not be
specified.
Some examples of srtm2sdf use:
srtm2sdf N40W074.hgt
srtm2sdf -d /cdrom/sdf N40W074.hgt
srtm2sdf -d /dev/null N40W074.hgt (/dev/null prevents USGS data
replacement from taking place)
srtm2sdf -n -5 N40W074.hgt
In all cases, SDF files are written into the current working directory.
The srtm2sdf utility may also be used to convert 3-arc second SRTM data
in Band Interleaved by Line (.BIL) format for use with SPLAT! This data
is available via the web at: http://seamless.usgs.gov/website/seamless/
Once the region of the world has been selected at this site, select the
"Define Download Area By Coordinates" button under "Downloads". Proceed
to request the download of the region(s) desired in 1 degree by 1 degree
regions only, and make sure bounding coordinates entered fall exactly on
whole numbers of latitude and longitude (no decimal fractions of a degree).
Select the "Add Area" button at the bottom.
On the next screen, select "Modify Data Request". On the subsequent screen,
de-select the National Elevation Dataset (NED) format and select "SRTM 3 arc
sec - Shuttle Radar Topography Mission [Finished]". Change the format from
ArcGrid to BIL, and from HTML to TXT.
Select the "Save Changes and Return To Summary" button.
Select the "Download" button, and save the file once it has been sent to
your web browser.
Uncompressing the file will generate a directory containing all files
contained within the downloaded archive. Move into the directory and
invoke srtm2sdf as described above with the filename having the .bil
extension given as its argument. Finally, move or copy the generated
.sdf file to your SPLAT! working directory.
srtm2sdf-hd
===========
The srtm2sdf-hd utility operates in an identical manner as srtm2sdf,
but is used to generate HD SDF files from SRTM-1 one-arc second
resolution data files for use with signalserverHD. SRTM-1 data files
are available for the United States and its territories and
possessions, and may be downloaded from:
ftp://e0srp01u.ecs.nasa.gov:21/srtm/version2/SRTM1/
usgs2sdf
========
The usgs2sdf utility takes as an argument the name of an uncompressed
and record delimited Digital Elevation Model Data (DEM) downloaded from
the US Geological Survey, and generates a SPLAT Data File (SDF) compatible
with signalserver. usgs2sdf may be invoked manually, or via the
postdownload script.
postdownload
============
postdownload is a front-end to the usgs2sdf utility. postdownload
takes as an argument the name of the gzipped Digital Elevation Model
(DEM) downloaded from the US Geological Survey (ie: wilmington-w.gz).
postdownload uncompresses the DEM file, adds necessary record delimiters,
and invokes usgs2sdf to produce a SPLAT! Data File (SDF).
USGS Digital Elevation Models may be downloaded from:
http://edcftp.cr.usgs.gov/pub/data/DEM/250/
Invoke postdownload with the name of each DEM file downloaded to
produce a database of SPLAT Data Files.
---
John A. Magliacane, KD2BD
August 2008

59
utils/sdf/build Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
#
# Simple shell script for building SPLAT! and associated utilities.
# Written by John A. Magliacane, KD2BD May 2002. Updated September 2009.
#
build_usgs2sdf()
{
echo -n "Compiling usgs2sdf... "
cc -Wall -O2 -fomit-frame-pointer usgs2sdf.c -o usgs2sdf
if [ -x usgs2sdf ]; then
echo "Done!"
else
echo "Compilation failed!"
fi
}
build_srtm2sdf()
{
echo -n "Compiling srtm2sdf... "
cc -Wall -O2 -fomit-frame-pointer srtm2sdf.c -lbz2 -o srtm2sdf
rm -f srtm2sdf-hd
ln -s srtm2sdf srtm2sdf-hd
if [ -x srtm2sdf ]; then
echo "Done!"
else
echo "Compilation failed!"
fi
}
if [ "$#" = "0" ]; then
echo "Usage: build { srtm2sdf, usgs2sdf, all }"
else
if [ "$1" = "usgs2sdf" ]; then
build_usgs2sdf
fi
if [ "$1" = "srtm2sdf" ]; then
build_srtm2sdf
fi
if [ "$1" = "clean" ]; then
rm -f usgs2sdf srtm2sdf srtm2sdf-hd
fi
if [ "$1" = "all" ]; then
build_usgs2sdf
build_srtm2sdf
fi
if [ "$1" != "citydecoder" ] && [ "$1" != "srtm2sdf" ] && [ "$1" != "usgs2sdf" ] && [ "$1" != "fontdata" ] && [ "$1" != "bearing" ] && [ "$1" != "clean" ] && [ "$1" != "all" ]; then
echo "Usage: build { srtm2sdf, usgs2sdf, all }"
fi
fi

722
utils/sdf/srtm2sdf.c Normal file
View File

@@ -0,0 +1,722 @@
/**************************************************************\
** Created originally by Jonathan Naylor, G4KLX. **
** Later embellished by John Magliacane, KD2BD to **
** detect and handle voids found in the SRTM data, **
** SRTM-3 data in .BIL and .HGT format, and high **
** resolution SRTM-1 one arc-second topography data. **
**************************************************************
** Compile like this: **
** cc -Wall -O3 -s -lbz2 srtm2sdf.c -o srtm2sdf **
** Last modification: 20-Jan-2011 **
\**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <bzlib.h>
#define BZBUFFER 65536
char sdf_filename[30], sdf_path[255], replacement_flag, opened=0,
hgt=0, bil=0;
int srtm[3601][3601], usgs[1201][1201], max_north, max_west, n,
min_north, min_west, merge=0, min_elevation, bzerror, ippd, mpi;
int ReadSRTM(char *filename)
{
int x, y, infile, byte=0, bytes_read;
unsigned char error, buffer[2];
char north[3], west[4], *base=NULL, blw_filename[255];
double cell_size, deg_north, deg_west;
FILE *fd=NULL;
if (strstr(filename, ".zip")!=NULL)
{
fprintf(stderr, "*** Error: \"%s\" must be uncompressed\n",filename);
return -1;
}
if (strstr(filename, ".tgz")!=NULL)
{
fprintf(stderr, "*** Error: \"%s\" must be uncompressed\n",filename);
return -1;
}
if ((strstr(filename, ".hgt")==NULL) && (strstr(filename, ".bil")==NULL))
{
fprintf(stderr, "*** Error: \"%s\" does not have the correct extension (.hgt or .bil)\n",filename);
return -1;
}
if (strstr(filename, ".hgt")!=NULL)
hgt=1;
if (strstr(filename, ".bil")!=NULL)
bil=1;
base=strrchr(filename, '/');
if (base==NULL)
base=filename;
else
base+=1;
if (hgt)
{
/* We obtain coordinates from the base of the .HGT filename */
north[0]=base[1];
north[1]=base[2];
north[2]=0;
west[0]=base[4];
west[1]=base[5];
west[2]=base[6];
west[3]=0;
if ((base[0]!='N' && base[0]!='S') || (base[3]!='W' && base[3]!='E'))
{
fprintf(stderr, "*** Error: \"%s\" doesn't look like a valid .hgt SRTM filename.\n", filename);
return -1;
}
max_west=atoi(west);
if (base[3]=='E')
max_west=360-max_west;
min_west=max_west-1;
if (max_west==360)
max_west=0;
if (base[0]=='N')
min_north=atoi(north);
else
min_north=-atoi(north);
max_north=min_north+1;
}
if (bil)
{
/* We obtain .BIL file coordinates
from the corresponding .BLW file */
strncpy(blw_filename,filename,250);
x=strlen(filename);
if (x>3)
{
blw_filename[x-2]='l';
blw_filename[x-1]='w';
blw_filename[x]=0;
fd=fopen(blw_filename,"rb");
if (fd!=NULL)
{
n=fscanf(fd,"%lf",&cell_size);
if ((cell_size<0.0008) || (cell_size>0.0009))
{
printf("\n*** .BIL file's cell size is incompatible with SPLAT!!\n");
exit(1);
}
n=fscanf(fd,"%lf",&deg_west);
n=fscanf(fd,"%lf",&deg_west);
n=fscanf(fd,"%lf",&deg_west);
n=fscanf(fd,"%lf",&deg_west);
n=fscanf(fd,"%lf",&deg_north);
fclose(fd);
}
min_north=(int)(deg_north);
max_north=max_north+1;
if (deg_west<0.0)
deg_west=-deg_west;
else
deg_west=360.0-deg_west;
min_west=(int)(deg_west);
if (min_west==360)
min_west=0;
max_west=min_west+1;
}
}
infile=open(filename, O_RDONLY);
if (infile==0)
{
fprintf(stderr, "*** Error: Cannot open \"%s\"\n", filename);
return -1;
}
n=read(infile,&buffer,2);
if ((buffer[0]=='P') && (buffer[1]=='K'))
{
fprintf(stderr, "*** Error: \"%s\" still appears to be compressed!\n",filename);
close(infile);
return -1;
}
lseek(infile,0L,SEEK_SET);
if (ippd==3600)
sprintf(sdf_filename, "%d:%d:%d:%d-hd.sdf", min_north, max_north, min_west, max_west);
else
sprintf(sdf_filename, "%d:%d:%d:%d.sdf", min_north, max_north, min_west, max_west);
error=0;
replacement_flag=0;
printf("Reading %s... ", filename);
fflush(stdout);
for (x=0; (x<=ippd && error==0); x++)
for (y=0; (y<=ippd && error==0); y++)
{
bytes_read=read(infile,&buffer,2);
if (bytes_read==2)
{
if (bil)
{
/* "little-endian" structure */
byte=buffer[0]+(buffer[1]<<8);
if (buffer[1]&128)
byte-=0x10000;
}
if (hgt)
{
/* "big-endian" structure */
byte=buffer[1]+(buffer[0]<<8);
if (buffer[0]&128)
byte-=0x10000;
}
/* Flag problem elevations here */
if (byte<-32768)
byte=-32768;
if (byte>32767)
byte=32767;
if (byte<=min_elevation)
replacement_flag=1;
srtm[x][y]=byte;
}
else
error=1;
}
if (error)
{
fprintf(stderr,"\n*** Error: Premature EOF detected while reading \"%s\"! :-(\n",filename);
}
close(infile);
return 0;
}
int LoadSDF_SDF(char *name)
{
/* This function reads uncompressed
SPLAT Data Files (.sdf) into memory. */
int x, y, n, dummy;
char sdf_file[255], path_plus_name[512];
FILE *infile;
for (x=0; name[x]!='.' && name[x]!=0 && x<250; x++)
sdf_file[x]=name[x];
sdf_file[x]='.';
sdf_file[x+1]='s';
sdf_file[x+2]='d';
sdf_file[x+3]='f';
sdf_file[x+4]=0;
strncpy(path_plus_name,sdf_path,255);
strncat(path_plus_name,sdf_file,254);
infile=fopen(path_plus_name,"rb");
if (infile==NULL)
return 0;
n=fscanf(infile,"%d", &dummy);
n=fscanf(infile,"%d", &dummy);
n=fscanf(infile,"%d", &dummy);
n=fscanf(infile,"%d", &dummy);
printf("\nReading %s... ",path_plus_name);
fflush(stdout);
for (x=0; x<1200; x++)
for (y=0; y<1200; y++)
n=fscanf(infile,"%d",&usgs[x][y]);
fclose(infile);
return 1;
}
char *BZfgets(BZFILE *bzfd, unsigned length)
{
/* This function returns at most one less than 'length' number
of characters from a bz2 compressed file whose file descriptor
is pointed to by *bzfd. In operation, a buffer is filled with
uncompressed data (size = BZBUFFER), which is then parsed
and doled out as NULL terminated character strings every time
this function is invoked. A NULL string indicates an EOF
or error condition. */
static int x, y, nBuf;
static char buffer[BZBUFFER+1], output[BZBUFFER+1];
char done=0;
if (opened!=1 && bzerror==BZ_OK)
{
/* First time through. Initialize everything! */
x=0;
y=0;
nBuf=0;
opened=1;
output[0]=0;
}
do
{
if (x==nBuf && bzerror!=BZ_STREAM_END && bzerror==BZ_OK && opened)
{
/* Uncompress data into a static buffer */
nBuf=BZ2_bzRead(&bzerror, bzfd, buffer, BZBUFFER);
buffer[nBuf]=0;
x=0;
}
/* Build a string from buffer contents */
output[y]=buffer[x];
if (output[y]=='\n' || output[y]==0 || y==(int)length-1)
{
output[y+1]=0;
done=1;
y=0;
}
else
y++;
x++;
} while (done==0);
if (output[0]==0)
opened=0;
return (output);
}
int LoadSDF_BZ(char *name)
{
/* This function reads .bz2 compressed
SPLAT Data Files into memory. */
int x, y, dummy;
char sdf_file[255], path_plus_name[255];
FILE *fd;
BZFILE *bzfd;
for (x=0; name[x]!='.' && name[x]!=0 && x<247; x++)
sdf_file[x]=name[x];
sdf_file[x]='.';
sdf_file[x+1]='s';
sdf_file[x+2]='d';
sdf_file[x+3]='f';
sdf_file[x+4]='.';
sdf_file[x+5]='b';
sdf_file[x+6]='z';
sdf_file[x+7]='2';
sdf_file[x+8]=0;
strncpy(path_plus_name,sdf_path,255);
strncat(path_plus_name,sdf_file,254);
fd=fopen(path_plus_name,"rb");
bzfd=BZ2_bzReadOpen(&bzerror,fd,0,0,NULL,0);
if (fd!=NULL && bzerror==BZ_OK)
{
printf("\nReading %s... ",path_plus_name);
fflush(stdout);
sscanf(BZfgets(bzfd,255),"%d",&dummy);
sscanf(BZfgets(bzfd,255),"%d",&dummy);
sscanf(BZfgets(bzfd,255),"%d",&dummy);
sscanf(BZfgets(bzfd,255),"%d",&dummy);
for (x=0; x<1200; x++)
for (y=0; y<1200; y++)
sscanf(BZfgets(bzfd,20),"%d",&usgs[x][y]);
fclose(fd);
BZ2_bzReadClose(&bzerror,bzfd);
return 1;
}
else
return 0;
}
char LoadSDF(char *name)
{
/* This function loads the requested SDF file from the filesystem.
First, it tries to invoke the LoadSDF_SDF() function to load an
uncompressed SDF file (since uncompressed files load slightly
faster). Failing that, it tries to load a compressed SDF file
by invoking the LoadSDF_BZ() function. */
int return_value=-1;
/* Try to load an uncompressed SDF first. */
return_value=LoadSDF_SDF(name);
/* If that fails, try loading a compressed SDF. */
if (return_value==0 || return_value==-1)
return_value=LoadSDF_BZ(name);
return return_value;
}
int ReadUSGS()
{
char usgs_filename[15];
/* usgs_filename is a minimal filename ("40:41:74:75").
Full path and extentions are added later though
subsequent function calls. */
sprintf(usgs_filename, "%d:%d:%d:%d", min_north, max_north, min_west, max_west);
return (LoadSDF(usgs_filename));
}
void average_terrain(y,x,z)
int x, y, z;
{
long accum;
int temp=0, count, bad_value;
double average;
bad_value=srtm[y][x];
accum=0L;
count=0;
if (y>=2)
{
temp=srtm[y-1][x];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if (y<=mpi)
{
temp=srtm[y+1][x];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if ((y>=2) && (x<=(mpi-1)))
{
temp=srtm[y-1][x+1];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if (x<=(mpi-1))
{
temp=srtm[y][x+1];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if ((x<=(mpi-1)) && (y<=mpi))
{
temp=srtm[y+1][x+1];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if ((x>=1) && (y>=2))
{
temp=srtm[y-1][x-1];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if (x>=1)
{
temp=srtm[y][x-1];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if ((y<=mpi) && (x>=1))
{
temp=srtm[y+1][x-1];
if (temp>bad_value)
{
accum+=temp;
count++;
}
}
if (count!=0)
{
average=(((double)accum)/((double)count));
temp=(int)(average+0.5);
}
if (temp>min_elevation)
srtm[y][x]=temp;
else
srtm[y][x]=min_elevation;
}
void WriteSDF(char *filename)
{
/* Like the HGT files, the extreme southwest corner
* provides the point of reference for the SDF file.
* The SDF file extends from min_north degrees to
* the south to min_north+(mpi/ippd) degrees to
* the north, and max_west degrees to the west to
* max_west-(mpi/ippd) degrees to the east. The
* overlapping edge redundancy present in the HGT
* and earlier USGS files is not necessary, nor
* is it present in SDF files.
*/
int x, y, byte, last_good_byte=0;
FILE *outfile;
printf("\nWriting %s... ", filename);
fflush(stdout);
outfile=fopen(filename,"wb");
fprintf(outfile, "%d\n%d\n%d\n%d\n", max_west, min_north, min_west, max_north);
for (y=ippd; y>=1; y--) /* Omit the northern most edge */
for (x=mpi; x>=0; x--) /* Omit the eastern most edge */
{
byte=srtm[y][x];
if (byte>min_elevation)
last_good_byte=byte;
if (byte<min_elevation)
{
if (merge)
{
if (ippd==3600)
fprintf(outfile,"%d\n",usgs[1200-(y/3)][1199-(x/3)]);
else
fprintf(outfile,"%d\n",usgs[1200-y][1199-x]);
}
else
{
average_terrain(y,x,last_good_byte);
fprintf(outfile,"%d\n",srtm[y][x]);
}
}
else
fprintf(outfile,"%d\n",byte);
}
printf("Done!\n");
fclose(outfile);
}
int main(int argc, char **argv)
{
int x, y, z=0;
char *env=NULL, string[255], *s=NULL;
FILE *fd;
if (strstr(argv[0], "srtm2sdf-hd")!=NULL)
{
ippd=3600; /* High Definition (1 arc-sec) Mode */
strncpy(string,"srtm2sdf-hd\0",12);
}
else
{
ippd=1200; /* Standard Definition (3 arc-sec) Mode */
strncpy(string,"srtm2sdf\0",9);
}
mpi=ippd-1; /* Maximum pixel index per degree */
if (argc==1 || (argc==2 && strncmp(argv[1],"-h",2)==0))
{
if (ippd==1200)
fprintf(stderr, "\nsrtm2sdf: Generates SPLAT! elevation data files from unzipped\nSRTM-3 elevation data files, and replaces SRTM data voids with\nelevation data from older usgs2sdf derived SDF files.\n\n");
if (ippd==3600)
fprintf(stderr, "\nsrtm2sdf-hd: Generates SPLAT! elevation data files from unzipped\nSRTM-1 elevation data files, and replaces SRTM data voids with\naverages, or elevation data from older usgs2sdf derived SDF files.\n\n");
fprintf(stderr, "\tAvailable Options...\n\n");
fprintf(stderr, "\t-d directory path of usgs2sdf derived SDF files\n\t (overrides path in ~/.splat_path file)\n\n");
fprintf(stderr, "\t-n elevation limit (in meters) below which SRTM data is\n\t replaced by USGS-derived .sdf data (default = 0 meters)\n\n");
fprintf(stderr, "Examples: %s N40W074.hgt\n",string);
fprintf(stderr, " %s -d /cdrom/sdf N40W074.hgt\n",string);
fprintf(stderr, " %s -d /dev/null N40W074.hgt (prevents data replacement)\n",string);
fprintf(stderr, " %s -n -5 N40W074.hgt\n\n",string);
return 1;
}
y=argc-1;
min_elevation=0;
for (x=1, z=0; x<=y; x++)
{
if (strcmp(argv[x],"-d")==0)
{
z=x+1;
if (z<=y && argv[z][0] && argv[z][0]!='-')
strncpy(sdf_path,argv[z],253);
}
if (strcmp(argv[x],"-n")==0)
{
z=x+1;
if (z<=y && argv[z][0])
{
sscanf(argv[z],"%d",&min_elevation);
if (min_elevation<-32767)
min_elevation=0;
}
}
}
/* If no SDF path was specified on the command line (-d), check
for a path specified in the $HOME/.splat_path file. If the
file is not found, then sdf_path[] remains NULL, and a data
merge will not be attempted if voids are found in the SRTM file. */
if (sdf_path[0]==0)
{
env=getenv("HOME");
sprintf(string,"%s/.splat_path",env);
fd=fopen(string,"r");
if (fd!=NULL)
{
s=fgets(string,253,fd);
/* Remove <CR> and/or <LF> from string */
for (x=0; string[x]!=13 && string[x]!=10 && string[x]!=0 && x<253; x++);
string[x]=0;
strncpy(sdf_path,string,253);
fclose(fd);
}
}
/* Ensure a trailing '/' is present in sdf_path */
if (sdf_path[0])
{
x=strlen(sdf_path);
if (sdf_path[x-1]!='/' && x!=0)
{
sdf_path[x]='/';
sdf_path[x+1]=0;
}
}
if (ReadSRTM(argv[z+1])==0)
{
if (replacement_flag && sdf_path[0])
merge=ReadUSGS();
WriteSDF(sdf_filename);
}
return 0;
}

312
utils/sdf/usgs2sdf.c Normal file
View File

@@ -0,0 +1,312 @@
/****************************************************************************
* USGS2SDF: USGS to SPLAT Data File Converter Utility *
* Copyright John A. Magliacane, KD2BD 1997-2009 *
* Last update: 14-Mar-2009 *
*****************************************************************************
* *
* This program reads files containing delimited US Geological Survey *
* Digital Elevation Model Data files, and creates Splat Data Files *
* containing ONLY the raw information needed by SPLAT!, thereby saving *
* disk space, as well as read/write time. *
* *
* The format of .sdf files created by this utility is as follows: *
* *
* maximum west longitude (degrees West) *
* minimum north latitude (degrees North) *
* minimum west longitude (degrees West) *
* maximum north latitude (degrees North) *
* ...1440000 elevation points... (1200x1200) *
* *
* All data is represented as integers. A single '\n' follows each value. *
* *
* SPLAT Data Files are named according to the geographical locations *
* they represent (ie: min_north:max_north:min_west:max_west.sdf). *
* *
*****************************************************************************
* To compile: gcc -Wall -O6 -s splat2sdf.c -o splat2sdf *
*****************************************************************************
* *
* 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 <stdio.h>
#include <stdlib.h>
char *d2e(string)
char *string;
{
/* This function is used to replace 'D's with 'E's for proper
exponential notation of numeric strings read from delimited
USGS data files. It returns a pointer to a string. */
unsigned char x;
for (x=0; string[x]!=0; x++)
if (string[x]=='D')
string[x]='E';
return (string);
}
int main(argc,argv)
int argc;
char *argv[];
{
unsigned char minimum[30], maximum[30], swlong[30], swlat[30],
nwlong[30], nwlat[30], nelong[30], nelat[30], selong[30],
selat[30];
char string[40];
double max_el, min_el, max_west, min_west, max_north, min_north;
int x, y, z, c, array[1202][1202];
char splatfile[25];
FILE *fd;
if (argc!=2)
{
fprintf(stderr,"Usage: usgs2sdf uncompressed_delimited_usgs_datafile (ie: wilmington-e)\n");
exit(0);
}
fd=fopen(argv[1],"rb");
if (fd!=NULL)
{
fprintf(stdout,"Reading \"%s\"...",argv[1]);
fflush(stdout);
/* Skip first 548 bytes */
for (x=0; x<548; x++)
getc(fd);
/* Read quadrangle corners */
/* Read southwest longitude */
for (x=0; x<22; x++)
swlong[x]=getc(fd);
swlong[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read southwest latitude */
for (x=0; x<22; x++)
swlat[x]=getc(fd);
swlat[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read northwest longitude */
for (x=0; x<22; x++)
nwlong[x]=getc(fd);
nwlong[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read northwest latitude */
for (x=0; x<22; x++)
nwlat[x]=getc(fd);
nwlat[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read northeast longitude */
for (x=0; x<22; x++)
nelong[x]=getc(fd);
nelong[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read northeast latitude */
for (x=0; x<22; x++)
nelat[x]=getc(fd);
nelat[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read southeast longitude */
for (x=0; x<22; x++)
selong[x]=getc(fd);
selong[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read southeast latitude */
for (x=0; x<22; x++)
selat[x]=getc(fd);
selat[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read minimum elevation */
for (x=0; x<22; x++)
minimum[x]=getc(fd);
minimum[x]=0;
/* Skip 2 bytes */
for (x=0; x<2; x++)
getc(fd);
/* Read maximum elevation */
for (x=0; x<22; x++)
maximum[x]=getc(fd);
maximum[x]=0;
sscanf(d2e((char*)minimum),"%lG",&min_el);
sscanf(d2e((char*)maximum),"%lf",&max_el);
sscanf(d2e((char*)swlong),"%lf",&max_west);
sscanf(d2e((char*)swlat),"%lf",&min_north);
sscanf(d2e((char*)nelong),"%lf",&min_west);
sscanf(d2e((char*)nelat),"%lf",&max_north);
max_west/=-3600.0;
min_north/=3600.0;
max_north/=3600.0;
min_west/=-3600.0;
/* Skip 84 Bytes */
for (x=0; x<84; x++)
getc(fd);
/* Read elevation data... */
for (x=1200; x>=0; x--)
{
if (x==900)
{
printf(" 25%c...",37);
fflush(stdout);
}
if (x==600)
{
printf(" 50%c...",37);
fflush(stdout);
}
if (x==300)
{
printf(" 75%c... ",37);
fflush(stdout);
}
/* Skip over 9 strings of data */
for (y=0; y<9; y++)
{
string[0]=0;
do
{
c=getc(fd);
} while (c==' ' || c=='\n');
for (z=0; c!=' ' && c!='\n' && z<28; z++)
{
string[z]=c;
c=getc(fd);
}
string[z]=0;
}
/* Store elevation data in array */
for (y=0; y<1201; y++)
{
string[0]=0;
do
{
c=getc(fd);
} while (c==' ' || c=='\n');
for (z=0; c!=' ' && c!='\n' && z<28; z++)
{
string[z]=c;
c=getc(fd);
}
string[z]=0;
sscanf(string,"%d",&array[y][x]);
}
}
fclose(fd);
/* Write splat data file to disk */
sprintf(splatfile,"%.0f:%.0f:%.0f:%.0f.sdf",min_north,max_north,min_west,max_west);
fprintf(stdout," Done!\nWriting \"%s\"... ",splatfile);
fflush(stdout);
fd=fopen(splatfile,"w");
fprintf(fd,"%.0f\n%.0f\n%.0f\n%.0f\n", max_west, min_north, min_west, max_north);
for (x=0; x<1200; x++)
for (y=0; y<1200; y++)
fprintf(fd,"%d\n",array[x][y]);
fclose(fd);
fprintf(stdout,"Done!\n");
fflush(stdout);
}
if (fd==NULL)
{
fprintf(stderr,"*** %c%s%c: File Not Found!\n",34,argv[1],34);
exit(-1);
}
else
exit(0);
}