openModeller  Version 1.4.0
om_points.cpp
Go to the documentation of this file.
00001 #include <openmodeller/om.hh>
00002 #include <openmodeller/om_defs.hh>
00003 #include <openmodeller/Log.hh>
00004 #include <openmodeller/os_specific.hh>
00005 
00006 #include "getopts/getopts.h"
00007 
00008 #include "om_cmd_utils.hh"
00009 
00010 #include <iostream>  // I/O 
00011 
00012 #include <string>
00013 #include <vector>
00014 
00015 #include <stdexcept>
00016 
00017 using namespace std;
00018 
00019 void writeOutput( ostream & stream, std::string format, OccurrencesPtr presences, OccurrencesPtr absences, std::string label );
00020 
00021 int main( int argc, char **argv ) {
00022 
00023   Options opts;
00024   int option;
00025 
00026   // command-line parameters (short name, long name, description, take args)
00027   opts.addOption( "" , "log-level"  , "Set the log level (debug, warn, info, error)", true );
00028   opts.addOption( "v", "version"    , "Display version info"                        , false );
00029   opts.addOption( "l", "list"       , "List available formats"                      , false );
00030   opts.addOption( "s", "source"     , "Source where points are located"             , true );
00031   opts.addOption( "n", "name"       , "Name (label) to filter points"               , true );
00032   opts.addOption( "w", "wkt"        , "Spatial reference in WKT"                    , true );
00033   opts.addOption( "o", "type"       , "Output type"                                 , true );
00034   opts.addOption( "" , "split"      , "Split points using the specified proportion (0,1)"  , true );
00035   opts.addOption( "" , "file1"      , "File name to store 1st subset (used w/ param split)", true );
00036   opts.addOption( "" , "file2"      , "File name to store 2nd subset (used w/ param split)", true );
00037   opts.addOption( "c", "config-file", "Configuration file for openModeller"         , true );
00038 
00039   std::string log_level("info");
00040   bool        list_formats = false;
00041   std::string source("");
00042   std::string label("");
00043   std::string wkt("GEOGCS[\"WGS84\",DATUM[\"WGS84\",SPHEROID[\"WGS84\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"degree\",0.017453292519943295],AXIS[\"Longitude\",EAST],AXIS[\"Latitude\",NORTH]]");
00044   std::string format("TXT");
00045   std::string split_prop_string;
00046   std::string file1;
00047   std::string file2;
00048   std::string config_file;
00049 
00050   if ( ! opts.parse( argc, argv ) ) {
00051 
00052     opts.showHelp( argv[0] ); 
00053     exit(0);
00054   }
00055 
00056   // Set up any related external resources
00057   setupExternalResources();
00058 
00059   OpenModeller om;
00060 
00061   while ( ( option = opts.cycle() ) >= 0 ) {
00062 
00063     switch ( option ) {
00064 
00065       case 0:
00066         log_level = opts.getArgs( option );
00067         break;
00068       case 1:
00069         printf( "om_points %s\n", om.getVersion().c_str() );
00070         printf("This is free software; see the source for copying conditions. There is NO\n");
00071         printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
00072         exit(0);
00073         break;
00074       case 2:
00075         list_formats = true;
00076         break;
00077       case 3:
00078         source = opts.getArgs( option );
00079         break;
00080       case 4:
00081         label = opts.getArgs( option );
00082         break;
00083       case 5:
00084         wkt = opts.getArgs( option );
00085         break;
00086       case 6:
00087         format = opts.getArgs( option );
00088         break;
00089       case 7:
00090         split_prop_string = opts.getArgs( option );
00091         break;
00092       case 8:
00093         file1 = opts.getArgs( option );
00094         break;
00095       case 9:
00096         file2 = opts.getArgs( option );
00097         break;
00098       case 10:
00099         config_file = opts.getArgs( option );
00100         break;
00101       default:
00102         break;
00103     }
00104   }
00105 
00106   // om configuration
00107   if ( ! config_file.empty() ) { 
00108 
00109     Settings::loadConfig( config_file );
00110   }
00111 
00112   // Log stuff
00113 
00114   Log::Level level_code = getLogLevel( log_level );
00115 
00116   Log::instance()->setLevel( level_code );
00117 
00118   // Real work
00119 
00120   try {
00121 
00122     if ( list_formats ) {
00123 
00124       // Process list drivers request
00125 
00126       std::vector<std::string> driver_ids = OccurrencesFactory::instance().getRegisteredDrivers();
00127 
00128       printf( "Available formats (id: description (input/output))\n" );
00129 
00130       for ( size_t i = 0; i < driver_ids.size(); ++i ) {
00131 
00132         std::string description("?");
00133         std::string io("I");
00134 
00135         if ( driver_ids[i] == "GBIF" ) {
00136 
00137           description = "GBIF Web Service for occurrence points";
00138         }
00139         else if ( driver_ids[i] == "TAPIR" ) {
00140 
00141           description = "TAPIR Web Service using DarwinCore 1.4 and the geospatial extension";
00142         }
00143         else if ( driver_ids[i] == "TerraLib" ) {
00144 
00145           description = "Points stored in a TerraLib database";
00146         }
00147         else if ( driver_ids[i] == "TXT" ) {
00148 
00149           description = "Delimited text file (id, label, long, lat, abundance)";
00150 
00151           io = "I/O";
00152         }
00153         else if ( driver_ids[i] == "XML" ) {
00154 
00155           description = "openModeller serialized XML for occurrences";
00156 
00157           io = "I/O";
00158         }
00159 
00160         printf( "  %s: %s (%s)\n", driver_ids[i].c_str(), description.c_str(), io.c_str() );
00161       }
00162 
00163       return 0;
00164     }
00165 
00166 
00167     // Check requirements
00168     if ( source.empty() ) {
00169 
00170       printf( "Please specify a source to load points from.\n");
00171       exit(-1);
00172     }
00173     if ( label.empty() ) {
00174 
00175       printf( "Please specify a name to filter points.\n");
00176       exit(-1);
00177     }
00178 
00179     // Check parameter split
00180     double split_prop = 0.0;
00181 
00182     if ( ! split_prop_string.empty() ) {
00183 
00184       if ( file1.empty() || file2.empty() ) {
00185 
00186         printf( "When splitting points, you need to specify file1 and file2.\n");
00187         exit(-1);
00188       }
00189 
00190       split_prop = atof( split_prop_string.c_str() );
00191 
00192       if ( split_prop <= 0.0 || split_prop >= 1.0 ) {
00193 
00194         printf( "Splitting proportion must be a value between 0 and 1.\n");
00195         exit(-1);
00196       }
00197     }
00198 
00199     // Read occurrences
00200     OccurrencesReader * occ = OccurrencesFactory::instance().create( source.c_str(), wkt.c_str() );
00201 
00202     OccurrencesPtr presences = occ->getPresences( label.c_str() );
00203 
00204     OccurrencesPtr absences = occ->getAbsences( label.c_str() );
00205 
00206     delete occ;
00207 
00208     // Split points if necessary
00209     if ( split_prop ) {
00210 
00211       OccurrencesPtr pres1, abs1, pres2, abs2;
00212 
00213       if ( presences ) {
00214 
00215         pres1 = new OccurrencesImpl( presences->label(), presences->coordSystem() );
00216         pres2 = new OccurrencesImpl( presences->label(), presences->coordSystem() );
00217 
00218         splitOccurrences( presences, pres1, pres2, split_prop );
00219       }
00220 
00221       if ( absences ) {
00222 
00223         abs1 = new OccurrencesImpl( absences->label(), absences->coordSystem() );
00224         abs2 = new OccurrencesImpl( absences->label(), absences->coordSystem() );
00225 
00226         splitOccurrences( absences, abs1, abs2, split_prop );
00227       }
00228 
00229       // Write result in two files
00230 
00231       ofstream outfile1( file1.c_str() );
00232 
00233       writeOutput( outfile1, format, pres1, abs1, label );
00234 
00235       outfile1.close();
00236 
00237       ofstream outfile2( file2.c_str() );
00238 
00239       writeOutput( outfile2, format, pres2, abs2, label );
00240 
00241       outfile2.close();
00242 
00243       return 0;
00244     }
00245 
00246     // Write result in cout
00247 
00248     std::cerr << flush;
00249 
00250     writeOutput( cout, format, presences, absences, label );
00251   }
00252   catch ( runtime_error e ) {
00253 
00254     printf( "om_points: %s\n", e.what() );
00255     exit(-1);
00256   }
00257 
00258   return 0;
00259 }
00260 
00261 
00262 // Function to output result
00263 void writeOutput( ostream & stream, std::string format, OccurrencesPtr presences, OccurrencesPtr absences, std::string label ) {
00264 
00265     if ( format == "XML" ) {
00266 
00267       if ( presences ) {
00268 
00269         ConfigurationPtr cfg = presences->getConfiguration();
00270         cfg->setName( "Presence" );
00271 
00272         Configuration::writeXml( cfg, stream );
00273       }
00274 
00275       if ( absences && absences->numOccurrences() ) {
00276 
00277         ConfigurationPtr cfg = absences->getConfiguration();
00278         cfg->setName( "Absence" );
00279 
00280         Configuration::writeXml( cfg, stream );
00281       }
00282     }
00283     else {
00284 
00285       // Header
00286       stream << "#id\t" << "label\t" << "long\t" << "lat\t" << "abundance" << endl << flush;
00287 
00288       if ( presences ) {
00289 
00290         OccurrencesImpl::iterator it   = presences->begin();
00291         OccurrencesImpl::iterator last = presences->end();
00292 
00293         while ( it != last ) {
00294 
00295           stream << (*it)->id() << "\t" << label.c_str() << "\t" << (*it)->x() << "\t" << (*it)->y() << "\t" << (*it)->abundance() << endl << flush;
00296           ++it;
00297         }
00298       }
00299 
00300       if ( absences ) {
00301 
00302         OccurrencesImpl::iterator it   = absences->begin();
00303         OccurrencesImpl::iterator last = absences->end();
00304 
00305         while ( it != last ) {
00306 
00307           stream << (*it)->id() << "\t" << label.c_str() << "\t" << (*it)->x() << "\t" << (*it)->y() << "\t" << (*it)->abundance() << endl << flush;
00308           ++it;
00309         }
00310       }
00311     }
00312 }