1
0
Fork 0

Added processing of DTED files.

This commit is contained in:
James.Hester 2018-09-15 19:39:02 +10:00
parent da1ade82cb
commit 8509dc1c33
5 changed files with 440 additions and 0 deletions

View file

@ -1,4 +1,5 @@
add_library(HGT STATIC
dted.cxx dted.hxx
hgt.cxx hgt.hxx
srtmbase.cxx srtmbase.hxx
)

234
src/Lib/HGT/dted.cxx Normal file
View file

@ -0,0 +1,234 @@
// dted.cxx -- SRTM "dted" data management class
//
// Written by James Hester based on hgt code of
// Curtis Olson, started February 2003.
//
// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
// Copyright (C) 2018 James Hester
//
// 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 (at your option) any later version.
//
// This program is distributed in the hope that it will be 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id: hgt.cxx,v 1.7 2005-12-19 16:06:45 curt Exp $
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#include <stdlib.h> // atof()
#include <iostream>
#ifdef SG_HAVE_STD_INCLUDES
# include <cerrno>
#else
# include <errno.h>
#endif
#ifdef _MSC_VER
# include <direct.h>
#endif
#include <simgear/constants.h>
#include <simgear/io/lowlevel.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/debug/logstream.hxx>
#include "dted.hxx"
using std::cout;
using std::endl;
using std::string;
TGDted::TGDted( int _res )
{
dted_resolution = _res;
data = new short int[MAX_DTED_SIZE][MAX_DTED_SIZE];
output_data = new short int[MAX_DTED_SIZE][MAX_DTED_SIZE];
}
TGDted::TGDted( int _res, const SGPath &file )
{
dted_resolution = _res;
data = new short int[MAX_DTED_SIZE][MAX_DTED_SIZE];
output_data = new short int[MAX_DTED_SIZE][MAX_DTED_SIZE];
TGDted::open( file );
}
// open an DTED file
bool
TGDted::open ( const SGPath &f ) {
SGPath file_name = f;
// open input file (or read from stdin)
if ( file_name.str() == "-" ) {
cout << "Loading DTED data file: stdin" << endl;
if ( (fd = gzdopen(0, "r")) == NULL ) { // 0 == STDIN_FILENO
cout << "ERROR: opening stdin" << endl;
return false;
}
} else {
if ( file_name.extension() == "zip" ) {
// extract the .zip file to /tmp and point the file name
// to the extracted file
tmp_dir = simgear::Dir::tempDir("dted");
cout << "Extracting " << file_name.str() << " to " << tmp_dir.path().str() << endl;
string command = "unzip -d \"" + tmp_dir.path().str() + "\" " + file_name.base();
if ( system( command.c_str() ) != -1 )
{
simgear::PathList files = tmp_dir.children(simgear::Dir::TYPE_FILE | simgear::Dir::NO_DOT_OR_DOTDOT);
for (const SGPath& file : files) {
string ext = file.lower_extension();
if ( ext == "dted" ) {
file_name = file;
break;
}
}
remove_tmp_file = true;
cout << "Proceeding with " << file_name.str() << endl;
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to issue system call " << command );
exit(1);
}
}
cout << "Loading DTED data file: " << file_name.str() << endl;
if ( (fd = gzopen( file_name.c_str(), "rb" )) == NULL ) {
SGPath file_name_gz = file_name;
file_name_gz.append( ".gz" );
if ( (fd = gzopen( file_name_gz.c_str(), "rb" )) == NULL ) {
cout << "ERROR: opening " << file_name.str() << " or "
<< file_name_gz.str() << " for reading!" << endl;
return false;
}
}
}
// Determine originx/originy from file contents
// User Header Label
char header[3];
char location[7];
int degrees,minutes,seconds;
char hemisphere;
// Check header
gzread(fd,header,3);
if (strncmp(header,"UHL",3) != 0) {
cout << "UHL User Header Label not found" << endl;
return false;
}
gzread(fd,header,1); //dummy
gzread(fd,location,8);//longitude
sscanf(location,"%3d%2d%2d%c",&degrees,&minutes,&seconds,&hemisphere);
originx = degrees *3600 + minutes*60 + seconds;
if(hemisphere == 'W') {
originx = - originx;
}
gzread(fd,location,8);//latitude
sscanf(location,"%3d%2d%2d%c",&degrees,&minutes,&seconds,&hemisphere);
originy = degrees *3600 + minutes*60 + seconds;
if(hemisphere == 'S') {
originy = - originy;
}
cout << " Origin = " << originx << ", " << originy << endl;
return true;
}
// close an DTED file
bool
TGDted::close () {
gzclose(fd);
return true;
}
// load an DTED file
bool
TGDted::load( ) {
int size;
if ( dted_resolution == 1 ) {
cols = rows = size = 3601;
col_step = row_step = 1;
} else if ( dted_resolution == 3 ) {
cols = rows = size = 1201;
col_step = row_step = 3;
} else {
cout << "Unknown DTED resolution, only 1 and 3 arcsec formats" << endl;
cout << " are supported!" << endl;
return false;
}
if (sgIsLittleEndian()) {
cout << "Little Endian: swapping input values" << endl;
}
//Skip headers
gzseek(fd,3428,SEEK_SET);
unsigned short int latct, longct;
short int *var;
int dummy; //to read column header
for ( int col = 0; col < size; ++col ) {
dummy = 0; // zero out all bytes
longct = 0;
latct = 0;
gzread(fd,&dummy,1); //sentinel
if(dummy != 170) {
cout << "Failed to find sentinel at col " << col << endl;
return false;
}
gzread(fd,&dummy,3); //block count
gzread(fd,&longct,2); //Longitude count
gzread(fd,&latct,2); //Latitude count
if ( sgIsLittleEndian() ) {
sgEndianSwap(&longct);
}
// cout << "Longitude count " << longct << endl;
for ( int row = 0; row < size; ++row ) {
var = &data[col][row];
if ( gzread ( fd, var, 2 ) != sizeof(short) ) {
return false;
}
if ( sgIsLittleEndian() ) {
sgEndianSwap( (unsigned short int*)var);
}
}
gzread(fd,&dummy,4); //Checksum
// Check values are right
if (col == 0) {
cout << data[col][0] << endl;
cout << data[col][1] << endl;
cout << data[col][2] << endl;
}
}
return true;
}
TGDted::~TGDted() {
// printf("class TGSrtmBase DEstructor called.\n");
delete [] data;
delete [] output_data;
}

84
src/Lib/HGT/dted.hxx Normal file
View file

@ -0,0 +1,84 @@
// dted.hxx -- SRTM "dted" data management class
//
// Written by James Hester based on hgt.hxx, which was
// written by Curtis Olson who started February 2003.
//
// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
// Copyright (c) 2018 James Hester
//
// 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 (at your option) any later version.
//
// This program is distributed in the hope that it will be 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef _DTED_HXX
#define _DTED_HXX
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#include "srtmbase.hxx"
#include <zlib.h>
#include <string>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/misc/sg_path.hxx>
#define MAX_DTED_SIZE 3601
class TGDted : public TGSrtmBase {
private:
// file pointer for input
gzFile fd;
int dted_resolution;
// pointers to the actual grid data allocated here
short int (*data)[MAX_DTED_SIZE];
short int (*output_data)[MAX_DTED_SIZE];
public:
// Constructor, _res must be either "1" for the 1arcsec data or
// "3" for the 3arcsec data.
TGDted( int _res );
TGDted( int _res, const SGPath &file );
// Destructor
~TGDted();
// open an DTED file (use "-" if input is coming from stdin)
bool open ( const SGPath &file );
// close an DTED file
bool close();
// load an dted file
bool load();
virtual short height( int x, int y ) const { return data[x][y]; }
};
#endif // _DTED_HXX

View file

@ -19,6 +19,17 @@ target_link_libraries(hgtchop
install(TARGETS hgtchop RUNTIME DESTINATION bin)
add_executable(dtedchop dtedchop.cxx)
target_link_libraries(dtedchop
HGT
${ZLIB_LIBRARY}
${SIMGEAR_CORE_LIBRARIES}
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES})
install(TARGETS dtedchop RUNTIME DESTINATION bin)
if(TIFF_FOUND)
if(MSVC AND CMAKE_CL_64)
set( SRTMCHOP_LIBRARIES ${JPEG_LIBRARY} )

View file

@ -0,0 +1,110 @@
// dtedchop.cxx -- chop up a dted file into it's corresponding pieces and stuff
// them into the workspace directory
//
// Adapted by James Hester from hgtchop
// Written by Curtis Olson, started March 1999.
//
// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
// Copyright (C) 2018 James Hester
//
// 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
// (at your option) any later version.
//
// This program is distributed in the hope that it will be 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <Include/version.h>
#include <HGT/dted.hxx>
using std::cout;
using std::endl;
using std::string;
int main(int argc, char **argv) {
sglog().setLogLevels( SG_ALL, SG_WARN );
SG_LOG( SG_GENERAL, SG_ALERT, "dtedchop version " << getTGVersion() << "\n" );
if ( argc != 4 ) {
cout << "Usage " << argv[0] << " <resolution> <dted_file> <work_dir>" << endl;
cout << endl;
cout << "\tresolution must be either 1 or 3 (1-arc-sec or 3-arc-sec)" << endl;
return EXIT_FAILURE;
}
int resolution = std::stoi(string(argv[1]));
string dted_name = string(argv[2]);
string work_dir = string(argv[3]);
// determine if file is 1arc-sec or 3arc-sec variety
if ( resolution != 1 && resolution != 3 ) {
cout << "ERROR: resolution must be 1 or 3." << endl;
return EXIT_FAILURE;
}
SGPath sgp( work_dir );
simgear::Dir workDir(sgp);
workDir.create(0755);
TGDted dted(resolution, dted_name);
dted.load();
dted.close();
SGGeod min = SGGeod::fromDeg( dted.get_originx() / 3600.0 + SG_HALF_BUCKET_SPAN,
dted.get_originy() / 3600.0 + SG_HALF_BUCKET_SPAN );
SGGeod max = SGGeod::fromDeg( (dted.get_originx() + dted.get_cols() * dted.get_col_step()) / 3600.0 - SG_HALF_BUCKET_SPAN,
(dted.get_originy() + dted.get_rows() * dted.get_row_step()) / 3600.0 - SG_HALF_BUCKET_SPAN );
SGBucket b_min( min );
SGBucket b_max( max );
if ( b_min == b_max ) {
dted.write_area( work_dir, b_min );
} else {
SGBucket b_cur;
int dx, dy;
sgBucketDiff(b_min, b_max, &dx, &dy);
cout << "DTED file spans tile boundaries (ok)" << endl;
cout << " dx = " << dx << " dy = " << dy << endl;
if ( (dx > 20) || (dy > 20) ) {
cout << "somethings really wrong!!!!" << endl;
return EXIT_FAILURE;
}
for ( int j = 0; j <= dy; ++j ) {
for ( int i = 0; i <= dx; ++i ) {
b_cur = b_min.sibling(i, j);
dted.write_area( work_dir, b_cur );
}
}
}
return EXIT_SUCCESS;
}