SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
polyconvert_main.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Main for POLYCONVERT
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #ifdef HAVE_VERSION_H
35 #include <version.h>
36 #endif
37 
38 #include <iostream>
39 #include <string>
47 #include <utils/common/ToString.h>
51 #include <utils/geom/Boundary.h>
57 #include <polyconvert/PCTypeMap.h>
60 #include <utils/xml/XMLSubSys.h>
62 
63 #ifdef CHECK_MEMORY_LEAKS
64 #include <foreign/nvwa/debug_new.h>
65 #endif // CHECK_MEMORY_LEAKS
66 
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
71 void
74  oc.addCallExample("-c <CONFIGURATION>", "run with configuration options set in file");
75 
76  // insert options sub-topics
77  SystemFrame::addConfigurationOptions(oc); // fill this subtopic, too
78  oc.addOptionSubTopic("Input");
79  oc.addOptionSubTopic("Output");
81  oc.addOptionSubTopic("Pruning");
82  oc.addOptionSubTopic("Processing");
83  oc.addOptionSubTopic("Building Defaults");
84  SystemFrame::addReportOptions(oc); // fill this subtopic, too
85 
86 
87  // register options
88  // add i/o options
89  // original network
90  oc.doRegister("net-file", 'n', new Option_FileName());
91  oc.addSynonyme("net-file", "net");
92  oc.addDescription("net-file", "Input", "Loads SUMO-network FILE as reference to offset and projection");
93 
94  // dlrnavteq import
95  oc.doRegister("dlr-navteq-poly-files", new Option_FileName());
96  oc.addDescription("dlr-navteq-poly-files", "Input", "Reads polygons from FILE assuming they're coded in DLR-Navteq (Elmar)-format");
97  oc.doRegister("dlr-navteq-poi-files", new Option_FileName());
98  oc.addDescription("dlr-navteq-poi-files", "Input", "Reads pois from FILE+ assuming they're coded in DLR-Navteq (Elmar)-format");
99 
100  // visum import
101  oc.doRegister("visum-files", new Option_FileName());
102  oc.addSynonyme("visum-files", "visum");
103  oc.addDescription("visum-files", "Input", "Reads polygons from FILE assuming it's a Visum-net");
104 
105  // xml import
106  oc.doRegister("xml-files", new Option_FileName());
107  oc.addSynonyme("xml-files", "xml");
108  oc.addDescription("xml-files", "Input", "Reads pois and shapes from FILE assuming they're coded in XML");
109 
110  // osm import
111  oc.doRegister("osm-files", new Option_FileName());
112  oc.addSynonyme("osm-files", "osm");
113  oc.addDescription("osm-files", "Input", "Reads pois from FILE+ assuming they're coded in OSM");
114  oc.doRegister("osm.keep-full-type", new Option_Bool(false));
115  oc.addDescription("osm.keep-full-type", "Input", "The type will be made of the key-value - pair.");
116  oc.doRegister("osm.use-name", new Option_Bool(false));
117  oc.addDescription("osm.use-name", "Input", "The id will be set from the given 'name' attribute.");
118 
119  // arcview import
120  oc.doRegister("shapefile-prefixes", new Option_FileName());
121  oc.addSynonyme("shapefile-prefixes", "shapefile-prefix");
122  oc.addSynonyme("shapefile-prefixes", "shapefile");
123  oc.addSynonyme("shapefile-prefixes", "shape-files", true);
124  oc.addDescription("shapefile-prefixes", "Input", "Reads shapes from shapefiles FILE+");
125 
126  oc.doRegister("shapefile.guess-projection", new Option_Bool(false));
127  oc.addSynonyme("shapefile.guess-projection", "arcview.guess-projection", true);
128  oc.addDescription("shapefile.guess-projection", "Input", "Guesses the shapefile's projection");
129 
130  oc.doRegister("shapefile.id-column", new Option_String());
131  oc.addSynonyme("shapefile.id-column", "shapefile.id-name", true);
132  oc.addSynonyme("shapefile.id-column", "shape-files.id-name", true);
133  oc.addDescription("shapefile.id-column", "Input", "Defines in which column the id can be found");
134 
135  oc.doRegister("shapefile.use-running-id", new Option_Bool());
136  oc.addDescription("shapefile.use-running-id", "Input", "A running number will be used as id.");
137 
138  // typemap reading
139  oc.doRegister("type-file", new Option_FileName());
140  oc.addSynonyme("type-file", "typemap", true);
141  oc.addDescription("type-file", "Input", "Reads types from FILE");
142 
143 
144  // output
145  oc.doRegister("output-file", 'o', new Option_FileName("polygons.xml"));
146  oc.addSynonyme("output-file", "output");
147  oc.addDescription("output-file", "Output", "Write generated polygons/pois to FILE");
148 
149 
150  // prunning options
151  oc.doRegister("prune.in-net", new Option_Bool(false));
152  oc.addSynonyme("prune.in-net", "prune.on-net", true);
153  oc.addDescription("prune.in-net", "Pruning", "Enables pruning on net boundaries");
154 
155  oc.doRegister("prune.in-net.offsets", new Option_String("0,0,0,0"));
156  oc.addSynonyme("prune.in-net.offsets", "prune.on-net.offsets", true);
157  oc.addDescription("prune.in-net.offsets", "Pruning", "Uses STR as offset definition added to the net boundaries");
158 
159  oc.doRegister("prune.boundary", new Option_String());
160  oc.addDescription("prune.boundary", "Pruning", "Uses STR as pruning boundary");
161 
162  oc.doRegister("prune.keep-list", new Option_String());
163  oc.addSynonyme("prune.keep-list", "prune.keep");
164  oc.addSynonyme("prune.keep-list", "prune.ignore", true);
165  oc.addDescription("prune.keep-list", "Pruning", "Items in STR will be kept though out of boundary");
166 
167  oc.doRegister("prune.explicit", new Option_String(""));
168  oc.addSynonyme("prune.explicit", "remove");
169  oc.addDescription("prune.explicit", "Pruning", "Items with names in STR will be removed");
170 
171 
172  oc.doRegister("offset.x", new Option_Float(0));
173  oc.addSynonyme("offset.x", "x-offset-to-apply", true);
174  oc.addDescription("offset.x", "Processing", "Adds FLOAT to net x-positions");
175 
176  oc.doRegister("offset.y", new Option_Float(0));
177  oc.addSynonyme("offset.y", "y-offset-to-apply", true);
178  oc.addDescription("offset.y", "Processing", "Adds FLOAT to net y-positions");
179 
180  oc.doRegister("all-attributes", new Option_Bool(false));
181  oc.addDescription("all-attributes", "Processing", "Imports all attributes as key/value pairs");
182 
183  oc.doRegister("ignore-errors", new Option_Bool(false));
184  oc.addDescription("ignore-errors", "Processing", "Continue on broken input");
185 
186 
187  // building defaults options
188  oc.doRegister("color", new Option_String("0.2,0.5,1."));
189  oc.addDescription("color", "Building Defaults", "Sets STR as default color");
190 
191  oc.doRegister("prefix", new Option_String(""));
192  oc.addDescription("prefix", "Building Defaults", "Sets STR as default prefix");
193 
194  oc.doRegister("type", new Option_String("unknown"));
195  oc.addDescription("type", "Building Defaults", "Sets STR as default type");
196 
197  oc.doRegister("layer", new Option_Integer(-1));
198  oc.addDescription("layer", "Building Defaults", "Sets INT as default layer");
199 
200  oc.doRegister("discard", new Option_Bool(false));
201  oc.addDescription("discard", "Building Defaults", "Sets default action to discard");
202 }
203 
204 
205 int
206 main(int argc, char** argv) {
208  oc.setApplicationDescription("Importer of polygons and POIs for the road traffic simulation SUMO.");
209  oc.setApplicationName("polyconvert", "SUMO polyconvert Version " + (std::string)VERSION_STRING);
210  int ret = 0;
211  try {
212  // initialise subsystems
213  XMLSubSys::init();
214  fillOptions();
215  OptionsIO::getOptions(true, argc, argv);
216  if (oc.processMetaOptions(argc < 2)) {
218  return 0;
219  }
220  XMLSubSys::setValidation(oc.getBool("xml-validation"));
222  // build the projection
223  int shift = 0;
224  if ((oc.isSet("dlr-navteq-poly-files") || oc.isSet("dlr-navteq-poi-files")) && oc.isDefault("proj.scale")) {
225  shift = 5;
226  }
227  if (!oc.isSet("net")) {
228  // from the given options
229 #ifdef HAVE_PROJ
230  unsigned numProjections = oc.getBool("simple-projection") + oc.getBool("proj.utm") + oc.getBool("proj.dhdn") + (oc.getString("proj").length() > 1);
231  if ((oc.isSet("osm-files") || oc.isSet("dlr-navteq-poly-files") || oc.isSet("dlr-navteq-poi-files")) && numProjections == 0) {
232  oc.set("proj.utm", "true");
233  }
234  oc.set("proj.scale", toString(shift));
235 #endif
236  if (!GeoConvHelper::init(oc)) {
237  throw ProcessError("Could not build projection!");
238  }
239  } else {
240  // from the supplied network
241  // @todo warn about given options being ignored
242  PCNetProjectionLoader::load(oc.getString("net"), shift);
243  }
244  Boundary pruningBoundary = GeoConvHelper::getFinal().getConvBoundary();
245  // check whether the input shall be pruned
246  bool prune = false;
247  if (oc.getBool("prune.in-net")) {
248  if (!oc.isSet("net")) {
249  throw ProcessError("In order to prune the input on the net, you have to supply a network.");
250  }
251  bool ok = true;
252  // !!! no proper error handling
253  Boundary offsets = GeomConvHelper::parseBoundaryReporting(oc.getString("prune.in-net.offsets"), "--prune.on-net.offsets", 0, ok);
254  pruningBoundary = Boundary(
255  pruningBoundary.xmin() + offsets.xmin(),
256  pruningBoundary.ymin() + offsets.ymin(),
257  pruningBoundary.xmax() + offsets.xmax(),
258  pruningBoundary.ymax() + offsets.ymax());
259  prune = true;
260  }
261  if (oc.isSet("prune.boundary")) {
262  bool ok = true;
263  // !!! no proper error handling
264  pruningBoundary = GeomConvHelper::parseBoundaryReporting(oc.getString("prune.boundary"), "--prune.boundary", 0, ok);
265  prune = true;
266  }
267 
268  PCPolyContainer toFill(prune, pruningBoundary, oc.getStringVector("remove"));
269 
270  // read in the type defaults
271  PCTypeMap tm(oc);
272  if (oc.isSet("type-file")) {
273  PCTypeDefHandler handler(oc, tm);
274  if (!XMLSubSys::runParser(handler, oc.getString("type-file"))) {
275  // something failed
276  throw ProcessError();
277  }
278  }
279 
280  // read in the data
281  PCLoaderXML::loadIfSet(oc, toFill, tm); // SUMO-XML
282  PCLoaderOSM::loadIfSet(oc, toFill, tm); // OSM-XML
283  PCLoaderDlrNavteq::loadIfSet(oc, toFill, tm); // Elmar-files
284  PCLoaderVisum::loadIfSet(oc, toFill, tm); // VISUM
285  PCLoaderArcView::loadIfSet(oc, toFill, tm); // shape-files
286  // error processing
287  if (MsgHandler::getErrorInstance()->wasInformed() && oc.getBool("ignore-errors")) {
289  }
290  if (!MsgHandler::getErrorInstance()->wasInformed()) {
291  // no? ok, save
292  toFill.save(oc.getString("output-file"));
293  } else {
294  throw ProcessError();
295  }
296  } catch (const ProcessError& e) {
297  if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
298  WRITE_ERROR(e.what());
299  }
300  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
301  ret = 1;
302 #ifndef _DEBUG
303  } catch (const std::exception& e) {
304  if (std::string(e.what()) != std::string("")) {
305  WRITE_ERROR(e.what());
306  }
307  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
308  ret = 1;
309  } catch (...) {
310  MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
311  ret = 1;
312 #endif
313  }
315  // report about ending
316  if (ret == 0) {
317  std::cout << "Success." << std::endl;
318  }
319  return ret;
320 }
321 
322 
323 
324 /****************************************************************************/
325