// demconvert.cxx -- convert dem into lower resolutions // // Copyright (C) 2016 Peter Sadrozinski // // 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char** argv) { std::string demroot; std::string inputvfp; int tileWidth; int tileHeight; int resx, resy; int overlap = 0; SGDem dem; osg::ApplicationUsage* usage = new osg::ApplicationUsage(); usage->setApplicationName("demconvert"); usage->setCommandLineUsage( "Convert high resolution DEM to low res suitable for terrasync dl."); usage->addCommandLineOption("--inputvfp ", "input VFP root directory"); usage->addCommandLineOption("--demroot ", "input/ouput DEM root directory"); usage->addCommandLineOption("--width ", "width (in degrees) of created tiles"); usage->addCommandLineOption("--height ", "height (in degrees) of created tiles"); usage->addCommandLineOption("--resx ", "resolution of created tiles (w/o overlap)"); usage->addCommandLineOption("--resy ", "resolution of created tiles (w/o overlap)"); usage->addCommandLineOption("--overlap ", "number of pixels of overlap"); // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc, argv); arguments.setApplicationUsage(usage); sglog().setLogLevels( SG_TERRAIN, SG_INFO ); arguments.read("--inputvfp", inputvfp); printf( "--inputvfp is %s\n", inputvfp.c_str() ); arguments.read("--demroot", demroot); if ( inputvfp.empty() && demroot.empty() ) { arguments.reportError("--inputvfp or --demroot argument required."); } else if ( !demroot.empty() ) { SGPath s(demroot); if (!s.isDir()) { arguments.reportError( "--demroot directory does not exist or is not directory."); } else if (!s.canRead()) { arguments.reportError( "--demroot directory cannot be read. Check permissions."); } else if (!s.canWrite()) { arguments.reportError( "--demroot directory cannot be written. Check permissions."); } else if ( !dem.addRoot(s) ) { // see if we specified input as raw directory if ( inputvfp.empty() ) { arguments.reportError( "--demroot directory is not a DEM heiarchy"); } else { // create a new dem heiarchy printf("Creating new dem heiarchy at %s\n", s.c_str() ); dem.createRoot(s); } } } else { SGPath s(inputvfp); if (!s.isDir()) { arguments.reportError( "--inputvfp directory does not exist or is not directory."); } else if (!s.canRead()) { arguments.reportError( "--inputvfp directory cannot be read. Check permissions."); } } if (!arguments.read("--width", tileWidth)) { arguments.reportError("--width argument required."); } else { if ( tileWidth < 1 || tileWidth > 60 ) arguments.reportError( "--width must be between 1 and 60"); } if (!arguments.read("--height", tileHeight)) { arguments.reportError("--height argument required."); } else { if ( tileHeight < 1 || tileHeight > 60 ) arguments.reportError( "--height must be between 1 and 60"); } if (!arguments.read("--resx", resx)) { arguments.reportError("--resx argument required."); } else { if ( resx < 2 ) arguments.reportError( "--resx must be between greater than 2"); } if (!arguments.read("--resy", resy)) { arguments.reportError("--resy argument required."); } else { if ( resy < 2 ) arguments.reportError( "--resy must be between greater than 2"); } if (arguments.read("--overlap", overlap)) { if ( overlap > (resx/2) || overlap > (resy/2) ) arguments.reportError( "--overlap is greater than half tile"); } if (arguments.errors()) { arguments.writeErrorMessages(std::cout); arguments.getApplicationUsage()->write(std::cout, osg::ApplicationUsage::COMMAND_LINE_OPTION | osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE, 80, true); return EXIT_FAILURE; } double lat_dec = (double)tileHeight / (double)resy; double lon_inc = (double)tileWidth / (double)resx; SG_LOG( SG_TERRAIN, SG_INFO, "tileWidth: " << tileWidth); SG_LOG( SG_TERRAIN, SG_INFO, "tileHeight: " << tileHeight); SG_LOG( SG_TERRAIN, SG_INFO, "lon_inc: " << lon_inc); SG_LOG( SG_TERRAIN, SG_INFO, "lat_dec: " << lat_dec); #define MIN_X -180 #define MIN_Y -90 #define MAX_X 180 #define MAX_Y 90 // create a new dem level in demRoot SGDemRoot* root = dem.getRoot(0); if ( root ) { int outLvl = root->createLevel( tileWidth, tileHeight, resx, resy, overlap, ".tiff" ); if ( outLvl >= 0 ) { printf("SGDem::createLevel success\n"); // traverse the new tiles, 1 at a time for ( int tilex = MIN_X; tilex < MAX_X; tilex += tileWidth ) { for ( int tiley = MAX_Y; tiley > MIN_Y; tiley -= tileHeight ) { // traverse rows from north to south, then columns west to east double lonmin = (double)tilex; double lonmax = lonmin + (double)tileWidth; double latmax = (double)tiley; double latmin = latmax - (double)tileHeight; unsigned wo = SGDem::longitudeDegToOffset(lonmin); unsigned eo = SGDem::longitudeDegToOffset(lonmax); unsigned so = SGDem::latitudeDegToOffset(latmin); unsigned no = SGDem::latitudeDegToOffset(latmax); if ( !inputvfp.empty() ) { // read from vfp files printf("open session from raw directory\n"); SGDemSession s = dem.openSession( SGGeod::fromDeg(lonmin, latmin), SGGeod::fromDeg(lonmax, latmax), SGPath(inputvfp) ); printf("opened session from raw directory\n"); // create a new dem tile for the new level SGDemTileRef tile = root->createTile( outLvl, (int)lonmin, (int)latmin, overlap, s ); s.close(); } else { // read session from DEM root - don't cache - include adjacent tiles fprintf( stderr, "open session from DEM level %d\n", outLvl-1); SGDemSession s = dem.openSession( wo, so, eo, no, outLvl-1, false ); fprintf( stderr, "session has %d tiles\n", s.size() ); // create a new dem tile for the new level SGDemTileRef tile = root->createTile( outLvl, (int)lonmin, (int)latmin, overlap, s ); s.close(); } } } printf("SGDem::close Level \n"); root->closeLevel( outLvl ); } else { printf("SGDem::createLevel failed\n"); } } else { printf("SGDem::getRoot failed\n"); } return EXIT_SUCCESS; }