diff --git a/inputs.cc b/inputs.cc index 0e76647..a2c4355 100644 --- a/inputs.cc +++ b/inputs.cc @@ -1,7 +1,7 @@ #include #include #include -#include to +#include #include #include #include diff --git a/utils/antenna/README.md b/utils/antenna/README.md new file mode 100644 index 0000000..56a0123 --- /dev/null +++ b/utils/antenna/README.md @@ -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 diff --git a/utils/antenna/ant2azel.py b/utils/antenna/ant2azel.py new file mode 100755 index 0000000..44a1ef7 --- /dev/null +++ b/utils/antenna/ant2azel.py @@ -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 -t -i -o ' + 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 -t -i -o ' + 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 -t -i -o ' + 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:]) diff --git a/utils/geoTiff/geotiff2geojson.sh b/utils/geoTiff/geotiff2geojson.sh new file mode 100755 index 0000000..b22f6b5 --- /dev/null +++ b/utils/geoTiff/geotiff2geojson.sh @@ -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 diff --git a/utils/lidar/README.md b/utils/lidar/README.md new file mode 100644 index 0000000..8e14f4e --- /dev/null +++ b/utils/lidar/README.md @@ -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. diff --git a/utils/sdf/README.md b/utils/sdf/README.md new file mode 100644 index 0000000..64da1a3 --- /dev/null +++ b/utils/sdf/README.md @@ -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 + diff --git a/utils/sdf/build b/utils/sdf/build new file mode 100755 index 0000000..e1713c9 --- /dev/null +++ b/utils/sdf/build @@ -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 + diff --git a/utils/sdf/srtm2sdf.c b/utils/sdf/srtm2sdf.c new file mode 100644 index 0000000..4176a4e --- /dev/null +++ b/utils/sdf/srtm2sdf.c @@ -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 +#include +#include +#include +#include +#include + +#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",°_west); + n=fscanf(fd,"%lf",°_west); + n=fscanf(fd,"%lf",°_west); + + n=fscanf(fd,"%lf",°_west); + + n=fscanf(fd,"%lf",°_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 and/or 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; +} + diff --git a/utils/sdf/usgs2sdf.c b/utils/sdf/usgs2sdf.c new file mode 100644 index 0000000..422ea85 --- /dev/null +++ b/utils/sdf/usgs2sdf.c @@ -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 +#include + +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); +}