openModeller
Version 1.4.0
|
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 }