openModeller  Version 1.5.0
om_points.cpp
Go to the documentation of this file.
1 #include <openmodeller/om.hh>
3 #include <openmodeller/Log.hh>
5 
6 #include "getopts/getopts.h"
7 
8 #include "om_cmd_utils.hh"
9 
10 #include <iostream> // I/O
11 
12 #include <string>
13 #include <vector>
14 
15 #include <stdexcept>
16 
17 using namespace std;
18 
19 void writeOutput( ostream & stream, std::string format, OccurrencesPtr presences, OccurrencesPtr absences, std::string label );
20 
21 int main( int argc, char **argv ) {
22 
23  Options opts;
24  int option;
25 
26  // command-line parameters (short name, long name, description, take args)
27  opts.addOption( "" , "log-level" , "Set the log level (debug, warn, info, error)", true );
28  opts.addOption( "v", "version" , "Display version info" , false );
29  opts.addOption( "l", "list" , "List available formats" , false );
30  opts.addOption( "s", "source" , "Source where points are located" , true );
31  opts.addOption( "n", "name" , "Name (label) to filter points" , true );
32  opts.addOption( "w", "wkt" , "Spatial reference in WKT" , true );
33  opts.addOption( "o", "type" , "Output type" , true );
34  opts.addOption( "" , "split" , "Split points using the specified proportion (0,1)" , true );
35  opts.addOption( "" , "file1" , "File name to store 1st subset (used w/ param split)", true );
36  opts.addOption( "" , "file2" , "File name to store 2nd subset (used w/ param split)", true );
37  opts.addOption( "c", "config-file", "Configuration file for openModeller" , true );
38 
39  std::string log_level("info");
40  bool list_formats = false;
41  std::string source("");
42  std::string label("");
43  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]]");
44  std::string format("TXT");
45  std::string split_prop_string;
46  std::string file1;
47  std::string file2;
48  std::string config_file;
49 
50  if ( ! opts.parse( argc, argv ) ) {
51 
52  opts.showHelp( argv[0] );
53  exit(0);
54  }
55 
56  // Set up any related external resources
58 
59  OpenModeller om;
60 
61  while ( ( option = opts.cycle() ) >= 0 ) {
62 
63  switch ( option ) {
64 
65  case 0:
66  log_level = opts.getArgs( option );
67  break;
68  case 1:
69  printf( "om_points %s\n", om.getVersion().c_str() );
70  printf("This is free software; see the source for copying conditions. There is NO\n");
71  printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
72  exit(0);
73  break;
74  case 2:
75  list_formats = true;
76  break;
77  case 3:
78  source = opts.getArgs( option );
79  break;
80  case 4:
81  label = opts.getArgs( option );
82  break;
83  case 5:
84  wkt = opts.getArgs( option );
85  break;
86  case 6:
87  format = opts.getArgs( option );
88  break;
89  case 7:
90  split_prop_string = opts.getArgs( option );
91  break;
92  case 8:
93  file1 = opts.getArgs( option );
94  break;
95  case 9:
96  file2 = opts.getArgs( option );
97  break;
98  case 10:
99  config_file = opts.getArgs( option );
100  break;
101  default:
102  break;
103  }
104  }
105 
106  // Log stuff
107 
108  Log::Level level_code = getLogLevel( log_level );
109 
110  Log::instance()->setLevel( level_code );
111 
112  // om configuration
113  if ( ! config_file.empty() ) {
114 
115  Settings::loadConfig( config_file );
116  }
117 
118  // Real work
119 
120  try {
121 
122  if ( list_formats ) {
123 
124  // Process list drivers request
125 
126  std::vector<std::string> driver_ids = OccurrencesFactory::instance().getRegisteredDrivers();
127 
128  printf( "Available formats (id: description (input/output))\n" );
129 
130  for ( size_t i = 0; i < driver_ids.size(); ++i ) {
131 
132  std::string description("?");
133  std::string io("I");
134 
135  if ( driver_ids[i] == "GBIF" ) {
136 
137  description = "GBIF Web Service for occurrence points";
138  }
139  else if ( driver_ids[i] == "TAPIR" ) {
140 
141  description = "TAPIR Web Service using DarwinCore 1.4 and the geospatial extension";
142  }
143  else if ( driver_ids[i] == "TerraLib" ) {
144 
145  description = "Points stored in a TerraLib database";
146  }
147  else if ( driver_ids[i] == "TXT" ) {
148 
149  description = "Delimited text file (id, label, long, lat, abundance)";
150 
151  io = "I/O";
152  }
153  else if ( driver_ids[i] == "XML" ) {
154 
155  description = "openModeller serialized XML for occurrences";
156 
157  io = "I/O";
158  }
159 
160  printf( " %s: %s (%s)\n", driver_ids[i].c_str(), description.c_str(), io.c_str() );
161  }
162 
163  return 0;
164  }
165 
166 
167  // Check requirements
168  if ( source.empty() ) {
169 
170  printf( "Please specify a source to load points from.\n");
171  exit(-1);
172  }
173  if ( label.empty() ) {
174 
175  printf( "Please specify a name to filter points.\n");
176  exit(-1);
177  }
178 
179  // Check parameter split
180  double split_prop = 0.0;
181 
182  if ( ! split_prop_string.empty() ) {
183 
184  if ( file1.empty() || file2.empty() ) {
185 
186  printf( "When splitting points, you need to specify file1 and file2.\n");
187  exit(-1);
188  }
189 
190  split_prop = atof( split_prop_string.c_str() );
191 
192  if ( split_prop <= 0.0 || split_prop >= 1.0 ) {
193 
194  printf( "Splitting proportion must be a value between 0 and 1.\n");
195  exit(-1);
196  }
197  }
198 
199  // Read occurrences
200  OccurrencesReader * occ = OccurrencesFactory::instance().create( source.c_str(), wkt.c_str() );
201 
202  OccurrencesPtr presences = occ->getPresences( label.c_str() );
203 
204  OccurrencesPtr absences = occ->getAbsences( label.c_str() );
205 
206  delete occ;
207 
208  // Split points if necessary
209  if ( split_prop ) {
210 
211  OccurrencesPtr pres1, abs1, pres2, abs2;
212 
213  if ( presences ) {
214 
215  pres1 = new OccurrencesImpl( presences->label(), presences->coordSystem() );
216  pres2 = new OccurrencesImpl( presences->label(), presences->coordSystem() );
217 
218  splitOccurrences( presences, pres1, pres2, split_prop );
219  }
220 
221  if ( absences ) {
222 
223  abs1 = new OccurrencesImpl( absences->label(), absences->coordSystem() );
224  abs2 = new OccurrencesImpl( absences->label(), absences->coordSystem() );
225 
226  splitOccurrences( absences, abs1, abs2, split_prop );
227  }
228 
229  // Write result in two files
230 
231  ofstream outfile1( file1.c_str() );
232 
233  writeOutput( outfile1, format, pres1, abs1, label );
234 
235  outfile1.close();
236 
237  ofstream outfile2( file2.c_str() );
238 
239  writeOutput( outfile2, format, pres2, abs2, label );
240 
241  outfile2.close();
242 
243  return 0;
244  }
245 
246  // Write result in cout
247 
248  std::cerr << flush;
249 
250  writeOutput( cout, format, presences, absences, label );
251  }
252  catch ( runtime_error e ) {
253 
254  printf( "om_points: %s\n", e.what() );
255  exit(-1);
256  }
257 
258  return 0;
259 }
260 
261 
262 // Function to output result
263 void writeOutput( ostream & stream, std::string format, OccurrencesPtr presences, OccurrencesPtr absences, std::string label ) {
264 
265  if ( format == "XML" ) {
266 
267  if ( presences ) {
268 
269  ConfigurationPtr cfg = presences->getConfiguration();
270  cfg->setName( "Presence" );
271 
272  Configuration::writeXml( cfg, stream );
273  }
274 
275  if ( absences && absences->numOccurrences() ) {
276 
277  ConfigurationPtr cfg = absences->getConfiguration();
278  cfg->setName( "Absence" );
279 
280  Configuration::writeXml( cfg, stream );
281  }
282  }
283  else {
284 
285  // Header
286  stream << "#id\t" << "label\t" << "long\t" << "lat\t" << "abundance" << endl << flush;
287 
288  if ( presences ) {
289 
290  OccurrencesImpl::iterator it = presences->begin();
291  OccurrencesImpl::iterator last = presences->end();
292 
293  while ( it != last ) {
294 
295  stream << (*it)->id() << "\t" << label.c_str() << "\t" << (*it)->x() << "\t" << (*it)->y() << "\t" << (*it)->abundance() << endl << flush;
296  ++it;
297  }
298  }
299 
300  if ( absences ) {
301 
302  OccurrencesImpl::iterator it = absences->begin();
303  OccurrencesImpl::iterator last = absences->end();
304 
305  while ( it != last ) {
306 
307  stream << (*it)->id() << "\t" << label.c_str() << "\t" << (*it)->x() << "\t" << (*it)->y() << "\t" << (*it)->abundance() << endl << flush;
308  ++it;
309  }
310  }
311  }
312 }
static void loadConfig(const std::string configFile)
Definition: Settings.cpp:100
std::vector< OccurrencePtr >::iterator iterator
Definition: Occurrences.hh:86
vector< string > getRegisteredDrivers()
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
static OccurrencesFactory & instance()
void writeOutput(ostream &stream, std::string format, OccurrencesPtr presences, OccurrencesPtr absences, std::string label)
Definition: om_points.cpp:263
Log::Level getLogLevel(std::string level)
virtual OccurrencesPtr getAbsences(const char *groupId)
Level
Definition: Log.hh:54
void setLevel(Level level)
Definition: Log.hh:107
int main(int argc, char **argv)
Definition: om_points.cpp:21
void setupExternalResources()
Definition: os_specific.cpp:95
virtual OccurrencesPtr getPresences(const char *groupId)
void splitOccurrences(const OccurrencesPtr &occurrences, OccurrencesPtr &trainOccurrences, OccurrencesPtr &testOccurrences, double propTrain)
static void writeXml(const ConstConfigurationPtr &config, char const *fileaname)
std::string getVersion()
OccurrencesReader * create(const char *source, const char *coordSystem)