diff --git a/projects/VC7.1/HGT/HGT.vcproj b/projects/VC7.1/HGT/HGT.vcproj
index 847853b7..47316046 100644
--- a/projects/VC7.1/HGT/HGT.vcproj
+++ b/projects/VC7.1/HGT/HGT.vcproj
@@ -104,6 +104,9 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/VC7.1/terragear.sln b/projects/VC7.1/terragear.sln
index 3499b09c..1cce81a7 100644
--- a/projects/VC7.1/terragear.sln
+++ b/projects/VC7.1/terragear.sln
@@ -233,6 +233,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "poly2ogr", "poly2ogr\poly2o
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED} = {22540CD3-D3CA-4C86-A773-80AEEE3ACDED}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srtmchop", "srtmchop\srtmchop.vcproj", "{7490AAD8-D2A4-4F0D-8150-68DCE07F3116}"
+ ProjectSection(ProjectDependencies) = postProject
+ {322E9356-2E79-49A6-A7B6-643B35DEB67D} = {322E9356-2E79-49A6-A7B6-643B35DEB67D}
+ {22540CD3-D3CA-4C86-A773-80AEEE3ACDED} = {22540CD3-D3CA-4C86-A773-80AEEE3ACDED}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -403,6 +409,10 @@ Global
{74F5BBD4-D669-4348-8B46-11700135CCF1}.Debug.Build.0 = Debug|Win32
{74F5BBD4-D669-4348-8B46-11700135CCF1}.Release.ActiveCfg = Release|Win32
{74F5BBD4-D669-4348-8B46-11700135CCF1}.Release.Build.0 = Release|Win32
+ {7490AAD8-D2A4-4F0D-8150-68DCE07F3116}.Debug.ActiveCfg = Debug|Win32
+ {7490AAD8-D2A4-4F0D-8150-68DCE07F3116}.Debug.Build.0 = Debug|Win32
+ {7490AAD8-D2A4-4F0D-8150-68DCE07F3116}.Release.ActiveCfg = Release|Win32
+ {7490AAD8-D2A4-4F0D-8150-68DCE07F3116}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
diff --git a/src/Lib/HGT/Makefile.am b/src/Lib/HGT/Makefile.am
index 1cef06be..09188874 100644
--- a/src/Lib/HGT/Makefile.am
+++ b/src/Lib/HGT/Makefile.am
@@ -1,6 +1,6 @@
noinst_LIBRARIES = libHGT.a
-libHGT_a_SOURCES = hgt.cxx hgt.hxx
+libHGT_a_SOURCES = hgt.cxx hgt.hxx srtmbase.cxx srtmbase.hxx
noinst_PROGRAMS = testhgt
diff --git a/src/Lib/HGT/hgt.cxx b/src/Lib/HGT/hgt.cxx
index 0520a99e..7a59e137 100644
--- a/src/Lib/HGT/hgt.cxx
+++ b/src/Lib/HGT/hgt.cxx
@@ -183,124 +183,9 @@ TGHgt::load( ) {
}
-// write out the area of data covered by the specified bucket. Data
-// is written out column by column starting at the lower left hand
-// corner.
-bool
-TGHgt::write_area( const string& root, SGBucket& b ) {
- // calculate some boundaries
- double min_x = ( b.get_center_lon() - 0.5 * b.get_width() ) * 3600.0;
- double max_x = ( b.get_center_lon() + 0.5 * b.get_width() ) * 3600.0;
-
- double min_y = ( b.get_center_lat() - 0.5 * b.get_height() ) * 3600.0;
- double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0;
-
- cout << b << endl;
- cout << "width = " << b.get_width() << " height = " << b.get_height()
- << endl;
- cout << "min = " << min_x << "," << min_y
- << " max = " << max_x << "," << max_y << endl;
- int start_x = (int)((min_x - originx) / col_step);
- int span_x = (int)(b.get_width() * 3600.0 / col_step);
-
- int start_y = (int)((min_y - originy) / row_step);
- int span_y = (int)(b.get_height() * 3600.0 / row_step);
-
- cout << "start_x = " << start_x << " span_x = " << span_x << endl;
- cout << "start_y = " << start_y << " span_y = " << span_y << endl;
-
- // Do a simple sanity checking. But, please, please be nice to
- // this write_area() routine and feed it buckets that coincide
- // well with the underlying grid structure and spacing.
-
- if ( ( min_x < originx )
- || ( max_x > originx + cols * col_step )
- || ( min_y < originy )
- || ( max_y > originy + rows * row_step ) ) {
- cout << " ERROR: bucket at least partially outside HGT data range!" <<
- endl;
- return false;
- }
-
- // If the area is all ocean, skip it.
- if ( !has_non_zero_elev(start_x, span_x, start_y, span_y) ) {
- cout << "Tile is all zero elevation: skipping" << endl;
- return false;
- }
-
- // generate output file name
- string base = b.gen_base_path();
- string path = root + "/" + base;
- SGPath sgp( path );
- sgp.append( "dummy" );
- sgp.create_dir( 0755 );
-
- string array_file = path + "/" + b.gen_index_str() + ".arr.gz";
- cout << "array_file = " << array_file << endl;
-
- // write the file
- gzFile fp;
- if ( (fp = gzopen( array_file.c_str(), "wb9" )) == NULL ) {
- cout << "ERROR: cannot open " << array_file << " for writing!" << endl;
- exit(-1);
- }
-
- gzprintf( fp, "%d %d\n", (int)min_x, (int)min_y );
- gzprintf( fp, "%d %d %d %d\n", span_x + 1, (int)col_step,
- span_y + 1, (int)row_step );
- for ( int i = start_x; i <= start_x + span_x; ++i ) {
- for ( int j = start_y; j <= start_y + span_y; ++j ) {
- gzprintf( fp, "%d ", (int)data[i][j] );
- }
- gzprintf( fp, "\n" );
- }
- gzclose(fp);
-
- return true;
-}
-
-
-// write the entire area out in a simple ascii format
-bool TGHgt::write_whole_ascii( const string& file ) {
- cout << "writing to " << file << endl;
- // write the file
- gzFile fp;
- if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
- cout << "ERROR: cannot open " << file << " for writing!" << endl;
- exit(-1);
- }
-
- gzprintf( fp, "%d\n%d\n", rows, cols );
- for ( int row = rows - 1; row >= 0; row-- ) {
- for ( int col = 0; col < cols; col++ ) {
- gzprintf( fp, "%d\n", (int)data[col][row] );
- }
- }
- gzclose(fp);
-
- return true;
-}
-
-
TGHgt::~TGHgt() {
- // printf("class TGHgt DEstructor called.\n");
+ // printf("class TGSrtmBase DEstructor called.\n");
delete [] data;
delete [] output_data;
}
-
-
-bool
-TGHgt::has_non_zero_elev (int start_x, int span_x,
- int start_y, int span_y) const
-{
- for ( int row = start_y; row < start_y + span_y; row++ ) {
- for ( int col = start_x; col < start_x + span_x; col++ ) {
- if ( data[col][row] != 0 )
- return true;
- }
- }
-
- return false;
-}
-
diff --git a/src/Lib/HGT/hgt.hxx b/src/Lib/HGT/hgt.hxx
index e04f1cc9..aeebc66e 100644
--- a/src/Lib/HGT/hgt.hxx
+++ b/src/Lib/HGT/hgt.hxx
@@ -30,6 +30,8 @@
#include
+#include "srtmbase.hxx"
+
#include
#include
@@ -40,31 +42,19 @@
#define MAX_HGT_SIZE 3601
-class TGHgt {
+class TGHgt : public TGSrtmBase {
private:
// file pointer for input
gzFile fd;
- // coordinates (in arc seconds) of south west corner
- double originx, originy;
-
- // number of columns and rows
- int cols, rows;
-
- // Distance between column and row data points (in arc seconds)
- double col_step, row_step;
+ int hgt_resolution;
// pointers to the actual grid data allocated here
short int (*data)[MAX_HGT_SIZE];
short int (*output_data)[MAX_HGT_SIZE];
- int hgt_resolution;
-
- bool remove_tmp_file;
- SGPath remove_file_name;
-
public:
// Constructor, _res must be either "1" for the 1arcsec data or
@@ -84,27 +74,7 @@ public:
// load an hgt file
bool load();
- // write out the area of data covered by the specified bucket.
- // Data is written out column by column starting at the lower left
- // hand corner.
- bool write_area( const std::string& root, SGBucket& b );
-
- // write the entire area out in a simple ascii format
- bool write_whole_ascii( const std::string& file );
-
- // Informational methods
- inline double get_originx() const { return originx; }
- inline double get_originy() const { return originy; }
- inline int get_cols() const { return cols; }
- inline int get_rows() const { return rows; }
- inline double get_col_step() const { return col_step; }
- inline double get_row_step() const { return row_step; }
-
- /**
- * Test whether an area contains any non-zero elevations.
- */
- bool has_non_zero_elev (int start_x, int span_x,
- int start_y, int span_y) const;
+ virtual short height( int x, int y ) const { return data[x][y]; }
};
diff --git a/src/Lib/HGT/srtmbase.cxx b/src/Lib/HGT/srtmbase.cxx
new file mode 100644
index 00000000..97db382a
--- /dev/null
+++ b/src/Lib/HGT/srtmbase.cxx
@@ -0,0 +1,151 @@
+// hgt.hxx -- SRTM "hgt" data management class
+//
+// Written by Curtis Olson, started February 2003.
+//
+// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: hgt.cxx,v 1.7 2005-12-19 16:06:45 curt Exp $
+
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+
+#include
+#include
+
+#include "srtmbase.hxx"
+
+using std::cout;
+using std::endl;
+
+
+// write out the area of data covered by the specified bucket. Data
+// is written out column by column starting at the lower left hand
+// corner.
+bool
+TGSrtmBase::write_area( const string& root, SGBucket& b ) {
+ // calculate some boundaries
+ double min_x = ( b.get_center_lon() - 0.5 * b.get_width() ) * 3600.0;
+ double max_x = ( b.get_center_lon() + 0.5 * b.get_width() ) * 3600.0;
+
+ double min_y = ( b.get_center_lat() - 0.5 * b.get_height() ) * 3600.0;
+ double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0;
+
+ cout << b << endl;
+ cout << "width = " << b.get_width() << " height = " << b.get_height()
+ << endl;
+ cout << "min = " << min_x << "," << min_y
+ << " max = " << max_x << "," << max_y << endl;
+ int start_x = (int)((min_x - originx) / col_step);
+ int span_x = (int)(b.get_width() * 3600.0 / col_step);
+
+ int start_y = (int)((min_y - originy) / row_step);
+ int span_y = (int)(b.get_height() * 3600.0 / row_step);
+
+ cout << "start_x = " << start_x << " span_x = " << span_x << endl;
+ cout << "start_y = " << start_y << " span_y = " << span_y << endl;
+
+ // Do a simple sanity checking. But, please, please be nice to
+ // this write_area() routine and feed it buckets that coincide
+ // well with the underlying grid structure and spacing.
+
+ if ( ( min_x < originx )
+ || ( max_x > originx + cols * col_step )
+ || ( min_y < originy )
+ || ( max_y > originy + rows * row_step ) ) {
+ cout << " ERROR: bucket at least partially outside HGT data range!" <<
+ endl;
+ return false;
+ }
+
+ // If the area is all ocean, skip it.
+ if ( !has_non_zero_elev(start_x, span_x, start_y, span_y) ) {
+ cout << "Tile is all zero elevation: skipping" << endl;
+ return false;
+ }
+
+ // generate output file name
+ string base = b.gen_base_path();
+ string path = root + "/" + base;
+ SGPath sgp( path );
+ sgp.append( "dummy" );
+ sgp.create_dir( 0755 );
+
+ string array_file = path + "/" + b.gen_index_str() + ".arr.gz";
+ cout << "array_file = " << array_file << endl;
+
+ // write the file
+ gzFile fp;
+ if ( (fp = gzopen( array_file.c_str(), "wb9" )) == NULL ) {
+ cout << "ERROR: cannot open " << array_file << " for writing!" << endl;
+ exit(-1);
+ }
+
+ gzprintf( fp, "%d %d\n", (int)min_x, (int)min_y );
+ gzprintf( fp, "%d %d %d %d\n", span_x + 1, (int)col_step,
+ span_y + 1, (int)row_step );
+ for ( int i = start_x; i <= start_x + span_x; ++i ) {
+ for ( int j = start_y; j <= start_y + span_y; ++j ) {
+ gzprintf( fp, "%d ", (int)height(i,j) );
+ }
+ gzprintf( fp, "\n" );
+ }
+ gzclose(fp);
+
+ return true;
+}
+
+
+// write the entire area out in a simple ascii format
+bool TGSrtmBase::write_whole_ascii( const string& file ) {
+ cout << "writing to " << file << endl;
+ // write the file
+ gzFile fp;
+ if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
+ cout << "ERROR: cannot open " << file << " for writing!" << endl;
+ exit(-1);
+ }
+
+ gzprintf( fp, "%d\n%d\n", rows, cols );
+ for ( int row = rows - 1; row >= 0; row-- ) {
+ for ( int col = 0; col < cols; col++ ) {
+ gzprintf( fp, "%d\n", (int)height(col,row) );
+ }
+ }
+ gzclose(fp);
+
+ return true;
+}
+
+
+
+bool
+TGSrtmBase::has_non_zero_elev (int start_x, int span_x,
+ int start_y, int span_y) const
+{
+ for ( int row = start_y; row < start_y + span_y; row++ ) {
+ for ( int col = start_x; col < start_x + span_x; col++ ) {
+ if ( height(col,row) != 0 )
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/Lib/HGT/srtmbase.hxx b/src/Lib/HGT/srtmbase.hxx
new file mode 100644
index 00000000..d9015057
--- /dev/null
+++ b/src/Lib/HGT/srtmbase.hxx
@@ -0,0 +1,82 @@
+// hgt.hxx -- SRTM "hgt" data management class
+//
+// Written by Curtis Olson, started February 2003.
+//
+// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: hgt.hxx,v 1.4 2004-11-19 22:25:50 curt Exp $
+
+
+#ifndef _SRTMBASE_HXX
+#define _SRTMBASE_HXX
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+
+#include
+#include
+
+class TGSrtmBase {
+
+protected:
+
+ // coordinates (in arc seconds) of south west corner
+ double originx, originy;
+
+ // number of columns and rows
+ int cols, rows;
+
+ // Distance between column and row data points (in arc seconds)
+ double col_step, row_step;
+
+ bool remove_tmp_file;
+ SGPath remove_file_name;
+
+public:
+
+ // write out the area of data covered by the specified bucket.
+ // Data is written out column by column starting at the lower left
+ // hand corner.
+ bool write_area( const std::string& root, SGBucket& b );
+
+ // write the entire area out in a simple ascii format
+ bool write_whole_ascii( const std::string& file );
+
+ // Informational methods
+ inline double get_originx() const { return originx; }
+ inline double get_originy() const { return originy; }
+ inline int get_cols() const { return cols; }
+ inline int get_rows() const { return rows; }
+ inline double get_col_step() const { return col_step; }
+ inline double get_row_step() const { return row_step; }
+
+ /**
+ * Test whether an area contains any non-zero elevations.
+ */
+ bool has_non_zero_elev (int start_x, int span_x,
+ int start_y, int span_y) const;
+
+ virtual short height( int x, int ) const = 0;
+};
+
+
+#endif // _SRTMBASE_HXX
+
+
diff --git a/src/Prep/DemChop/Makefile.am b/src/Prep/DemChop/Makefile.am
index 0603a857..9e38595a 100644
--- a/src/Prep/DemChop/Makefile.am
+++ b/src/Prep/DemChop/Makefile.am
@@ -23,7 +23,7 @@
#---------------------------------------------------------------------------
-bin_PROGRAMS = demchop hgtchop fillvoids testassem
+bin_PROGRAMS = demchop hgtchop srtmchop fillvoids testassem
demchop_SOURCES = \
demchop.cxx point2d.hxx
@@ -41,6 +41,14 @@ hgtchop_LDADD = \
-lsgbucket -lsgmisc -lsgdebug -lsgxml -lz
$(base_LIBS)
+srtmchop_SOURCES = \
+ srtmchop.cxx point2d.hxx
+
+srtmchop_LDADD = \
+ $(top_builddir)/src/Lib/HGT/libHGT.a \
+ -lsgbucket -lsgmisc -lsgdebug -lsgxml -lz
+ $(base_LIBS)
+
fillvoids_SOURCES = \
fillvoids.cxx
diff --git a/src/Prep/DemChop/srtmchop.cxx b/src/Prep/DemChop/srtmchop.cxx
new file mode 100644
index 00000000..d213315a
--- /dev/null
+++ b/src/Prep/DemChop/srtmchop.cxx
@@ -0,0 +1,420 @@
+// srtmchop.cxx -- chop up a srtm tiff file into it's corresponding pieces and stuff
+// them into the workspace directory
+//
+// Written by Frederic Bouvier, started February 2009.
+//
+// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id:$
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _MSC_VER
+# include
+#endif
+
+#include
+#include
+#include
+
+#include
+
+#include
+
+#include
+
+#include
+
+#include
+
+using std::cout;
+using std::endl;
+using std::setfill;
+using std::setw;
+using std::string;
+using std::ifstream;
+using std::ostringstream;
+using std::ios;
+
+#define MAX_HGT_SIZE 6001
+class TGSrtmTiff : public TGSrtmBase {
+public:
+ TGSrtmTiff( const SGPath &file );
+ ~TGSrtmTiff();
+ bool open( const SGPath &f );
+ bool close();
+
+ // load an hgt file
+ bool load();
+ bool is_opened() const { return opened; }
+
+ virtual short height( int x, int y ) const { return data[x][y]; }
+
+private:
+ enum LoadKind { BottomLeft, BottomRight, TopLeft, TopRight };
+ TGSrtmTiff( const SGPath &file, LoadKind lk );
+ bool pos_from_name( string name, string &pfx, int &x, int &y );
+
+ TIFF* tif;
+ LoadKind lkind;
+ string prefix, ext;
+ SGPath dir;
+ bool opened;
+
+ // pointers to the actual grid data allocated here
+ short int (*data)[MAX_HGT_SIZE];
+ short int (*output_data)[MAX_HGT_SIZE];
+};
+
+TGSrtmTiff::TGSrtmTiff( const SGPath &file ) {
+ lkind = BottomLeft;
+ tif = 0;
+ remove_tmp_file = false;
+ data = new short int[MAX_HGT_SIZE][MAX_HGT_SIZE];
+ output_data = new short int[MAX_HGT_SIZE][MAX_HGT_SIZE];
+ opened = TGSrtmTiff::open( file );
+}
+
+TGSrtmTiff::TGSrtmTiff( const SGPath &file, LoadKind lk ) {
+ lkind = lk;
+ tif = 0;
+ remove_tmp_file = false;
+ output_data = 0;
+ if ( lkind == BottomLeft ) {
+ data = new short int[MAX_HGT_SIZE][MAX_HGT_SIZE];
+ output_data = new short int[MAX_HGT_SIZE][MAX_HGT_SIZE];
+ } else if ( lkind == TopLeft ) {
+ data = new short int[MAX_HGT_SIZE][MAX_HGT_SIZE];
+ } else if ( lkind == BottomRight ) {
+ data = new short int[1][MAX_HGT_SIZE];
+ } else /* if ( lkind == TopRight ) */ {
+ data = new short int[1][MAX_HGT_SIZE];
+ }
+ TGSrtmTiff::open( file );
+}
+
+TGSrtmTiff::~TGSrtmTiff() {
+ delete[] data;
+ delete[] output_data;
+ if ( remove_tmp_file ) {
+ ulDir *dir = ulOpenDir( remove_file_name.dir().c_str() );
+ if ( dir ) {
+ ulDirEnt *de;
+ while ( ( de = ulReadDir( dir ) ) != 0 ) {
+ if ( !strcmp(de->d_name,".") || !strcmp(de->d_name,"..") || de->d_isdir ) {
+ continue;
+ }
+ SGPath file( remove_file_name.dir() );
+ file.append( de->d_name );
+ unlink( file.c_str() );
+ }
+ ulCloseDir( dir );
+ }
+ rmdir( remove_file_name.dir().c_str() );
+ }
+ if ( tif )
+ TIFFClose( tif );
+}
+
+bool TGSrtmTiff::pos_from_name( string name, string &pfx, int &x, int &y ) {
+ size_t p = name.find( '_' );
+ if ( p == string::npos )
+ return false;
+ pfx = name.substr( 0, p );
+ name.erase( 0, p + 1 );
+ p = name.find( '.' );
+ if ( p == string::npos )
+ return false;
+ name.erase( p );
+ p = name.find( '_' );
+ if ( p == string::npos )
+ return false;
+
+ x = atoi( name.substr( 0, p ).c_str() );
+ y = atoi( name.substr( p+1 ).c_str() );
+ return true;
+}
+
+bool TGSrtmTiff::open( const SGPath &f ) {
+ SGPath file_name = f;
+ ext = file_name.extension();
+ dir = file_name.dir();
+ int x, y;
+ pos_from_name( file_name.file(), prefix, x, y );
+ if ( ext == "zip" ) {
+ // extract the .zip file to /tmp and point the file name
+ // to the extracted file
+ SGPath tmp_dir = tempnam( 0, "hgt" );
+ tmp_dir.append( "dummy" );
+ tmp_dir.create_dir( 0700 );
+ cout << "Extracting " << file_name.str() << " to " << tmp_dir.dir() << endl;
+ string command = "unzip -d \"" + tmp_dir.dir() + "\" " + file_name.str();
+ system( command.c_str() );
+
+ file_name = tmp_dir.dir();
+ ulDir *dir = ulOpenDir( tmp_dir.dir().c_str() );
+ if ( dir ) {
+ ulDirEnt *de;
+ while ( ( de = ulReadDir( dir ) ) != 0 ) {
+ if ( !strcmp(de->d_name,".") || !strcmp(de->d_name,"..") || de->d_isdir ) {
+ continue;
+ }
+ SGPath file( de->d_name );
+ string ext = file.extension();
+ if ( ext == "TIF" || ext == "tif" ) {
+ file_name.append( de->d_name );
+ break;
+ }
+ }
+ ulCloseDir( dir );
+ }
+
+ remove_tmp_file = true;
+ remove_file_name = file_name.str();
+
+ cout << "Proceeding with " << file_name.str() << endl;
+ }
+
+ tif = TIFFOpen( file_name.c_str(), "r" );
+ if ( !tif ) {
+ cout << "ERROR: opening " << file_name.str() << " for reading!" << endl;
+ return false;
+ }
+
+ // Determine originx/originy from file name
+ originx = ( double( x ) - 37.0 ) * 18000.0;
+ originy = ( 12.0 - double( y ) ) * 18000.0;
+ cout << " Origin = " << originx << ", " << originy << endl;
+
+ return true;
+}
+
+bool TGSrtmTiff::load() {
+ int size;
+ cols = rows = size = 6000;
+ col_step = row_step = 3;
+
+ uint32 w, h, d;
+ uint16 dataType;
+ uint16 samplesperpixel;
+ uint16 bitspersample;
+
+ TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &w );
+ TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &h );
+ TIFFGetField( tif, TIFFTAG_IMAGEDEPTH, &d );
+ TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel );
+ TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bitspersample );
+ TIFFGetField( tif, TIFFTAG_DATATYPE, &dataType );
+
+ tdata_t buf = _TIFFmalloc( TIFFScanlineSize( tif ) );
+ if ( lkind == BottomLeft ) {
+ uint32 row = 0;
+ for ( ; row < h; row++ ) {
+ TIFFReadScanline( tif, buf, row );
+ uint32 col = 0;
+ for ( ; col < w; col++ ) {
+ int16 v = ((int16*)buf)[col];
+ if ( v == -32768 )
+ v = 0;
+ data[col][6000-1-row] = v;
+ }
+ for ( ; col < 6000; col++ ) {
+ data[col][6000-1-row] = 0;
+ }
+ }
+ for ( ; row < 6000; row++ ) {
+ uint32 col = 0;
+ for ( ; col < 6000; col++ ) {
+ data[col][6000-1-row] = 0;
+ }
+ }
+ int x1 = int( originx / 18000.0 ) + 37,
+ y1 = int( 12 - ( originy / 18000.0 ) ),
+ x2 = x1 + 1,
+ y2 = y1 - 1;
+ if ( x2 > 72 )
+ x2 -= 72;
+ {
+ ostringstream name;
+ name << prefix << "_" << std::setfill( '0' ) << std::setw( 2 ) << x2 << "_" << std::setfill( '0' ) << std::setw( 2 ) << y1 << "." << ext;
+ SGPath f = dir;
+ f.append( name.str() );
+ if ( f.exists() ) {
+ TGSrtmTiff s( f.str(), BottomRight );
+ s.load();
+ s.close();
+ for ( int i = 0; i < 6000; ++i ) {
+ data[6000][i] = s.data[0][i];
+ }
+ } else {
+ for ( int i = 0; i < 6000; ++i ) {
+ data[6000][i] = 0;
+ }
+ }
+ }
+ if ( y2 != 0 ) {
+ ostringstream name;
+ name << prefix << "_" << std::setfill( '0' ) << std::setw( 2 ) << x1 << "_" << std::setfill( '0' ) << std::setw( 2 ) << y2 << "." << ext;
+ SGPath f = dir;
+ f.append( name.str() );
+ if ( f.exists() ) {
+ TGSrtmTiff s( f.str(), TopLeft );
+ s.load();
+ s.close();
+ for ( int i = 0; i < 6000; ++i ) {
+ data[i][6000] = s.data[i][0];
+ }
+ } else {
+ for ( int i = 0; i < 6000; ++i ) {
+ data[i][6000] = 0;
+ }
+ }
+ } else {
+ for ( int i = 0; i < 6000; ++i ) {
+ data[i][6000] = data[i][6000-1];
+ }
+ }
+ if ( y2 != 0 ) {
+ ostringstream name;
+ name << prefix << "_" << std::setfill( '0' ) << std::setw( 2 ) << x2 << "_" << std::setfill( '0' ) << std::setw( 2 ) << y2 << "." << ext;
+ SGPath f = dir;
+ f.append( name.str() );
+ if ( f.exists() ) {
+ TGSrtmTiff s( f.str(), TopRight );
+ s.load();
+ s.close();
+ data[6000][6000] = s.data[0][0];
+ } else {
+ data[6000][6000] = 0;
+ }
+ } else {
+ data[6000][6000] = data[6000][6000-1];
+ }
+ } else if ( lkind == TopLeft ) {
+ TIFFReadScanline( tif, buf, 0 );
+ uint32 col = 0;
+ for ( ; col < w; col++ ) {
+ int16 v = ((int16*)buf)[col];
+ if ( v == -32768 )
+ v = 0;
+ data[col][0] = v;
+ }
+ for ( ; col < 6000; col++ ) {
+ data[col][0] = 0;
+ }
+ } else if ( lkind == BottomRight ) {
+ uint32 row = 0;
+ for ( ; row < h; row++ ) {
+ TIFFReadScanline( tif, buf, row );
+ int16 v = ((int16*)buf)[0];
+ if ( v == -32768 )
+ v = 0;
+ data[0][6000-1-row] = v;
+ }
+ for ( ; row < 6000; row++ ) {
+ data[0][6000-1-row] = 0;
+ }
+ } else /* if ( lkind == TopRight ) */ {
+ if ( h == 6000 ) {
+ TIFFReadScanline( tif, buf, h-1 );
+ int16 v = ((int16*)buf)[0];
+ if ( v == -32768 )
+ v = 0;
+ data[0][0] = v;
+ } else {
+ data[0][0] = 0;
+ }
+ }
+ _TIFFfree(buf);
+
+ return true;
+}
+
+bool TGSrtmTiff::close() {
+ if ( tif )
+ TIFFClose( tif );
+ tif = 0;
+ return true;
+}
+
+int main(int argc, char **argv) {
+ sglog().setLogLevels( SG_ALL, SG_WARN );
+
+ if ( argc != 3 ) {
+ cout << "Usage " << argv[0] << " "
+ << endl;
+ cout << endl;
+ exit(-1);
+ }
+
+ string hgt_name = argv[1];
+ string work_dir = argv[2];
+
+ SGPath sgp( work_dir );
+ sgp.append( "dummy" );
+ sgp.create_dir( 0755 );
+
+ TGSrtmTiff hgt( hgt_name );
+ hgt.load();
+ hgt.close();
+
+ point2d min, max;
+ min.x = hgt.get_originx() / 3600.0 + SG_HALF_BUCKET_SPAN;
+ min.y = hgt.get_originy() / 3600.0 + SG_HALF_BUCKET_SPAN;
+ SGBucket b_min( min.x, min.y );
+
+ max.x = (hgt.get_originx() + hgt.get_cols() * hgt.get_col_step()) / 3600.0
+ - SG_HALF_BUCKET_SPAN;
+ max.y = (hgt.get_originy() + hgt.get_rows() * hgt.get_row_step()) / 3600.0
+ - SG_HALF_BUCKET_SPAN;
+ SGBucket b_max( max.x, max.y );
+
+ if ( b_min == b_max ) {
+ hgt.write_area( work_dir, b_min );
+ } else {
+ SGBucket b_cur;
+ int dx, dy, i, j;
+
+ sgBucketDiff(b_min, b_max, &dx, &dy);
+ cout << "HGT file spans tile boundaries (ok)" << endl;
+ cout << " dx = " << dx << " dy = " << dy << endl;
+
+ if ( (dx > 50) || (dy > 50) ) {
+ cout << "somethings really wrong!!!!" << endl;
+ exit(-1);
+ }
+
+ for ( j = 0; j <= dy; j++ ) {
+ for ( i = 0; i <= dx; i++ ) {
+ b_cur = sgBucketOffset(min.x, min.y, i, j);
+ hgt.write_area( work_dir, b_cur );
+ }
+ }
+ }
+
+ return 0;
+}