SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PCLoaderVisum.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A reader of pois and polygons stored in VISUM-format
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
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 #include <string>
35 #include <map>
36 #include <fstream>
42 #include <utils/common/ToString.h>
45 #include <utils/options/Option.h>
47 #include <utils/common/StdDefs.h>
49 #include "PCLoaderVisum.h"
50 #include <utils/common/RGBColor.h>
51 #include <utils/geom/GeomHelper.h>
52 #include <utils/geom/Boundary.h>
53 #include <utils/geom/Position.h>
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
65 void
67  PCTypeMap& tm) {
68  if (!oc.isSet("visum-files")) {
69  return;
70  }
71  // parse file(s)
72  std::vector<std::string> files = oc.getStringVector("visum-files");
73  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
74  if (!FileHelpers::exists(*file)) {
75  throw ProcessError("Could not open visum-file '" + *file + "'.");
76  }
77  PROGRESS_BEGIN_MESSAGE("Parsing from visum-file '" + *file + "'");
78  load(*file, oc, toFill, tm);
80  }
81 }
82 
83 
84 
85 void
86 PCLoaderVisum::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill,
87  PCTypeMap& tm) {
89  std::string what;
90  std::map<SUMOLong, Position> punkte;
91  std::map<SUMOLong, PositionVector> kanten;
92  std::map<SUMOLong, PositionVector> teilflaechen;
93  std::map<SUMOLong, SUMOLong> flaechenelemente;
94  NamedColumnsParser lineParser;
95  LineReader lr(file);
96  while (lr.hasMore()) {
97  std::string line = lr.readLine();
98  // reset if current is over
99  if (line.length() == 0 || line[0] == '*' || line[0] == '$') {
100  what = "";
101  }
102  // read items
103  if (what == "$PUNKT") {
104  lineParser.parseLine(line);
105  SUMOLong id = TplConvert::_2long(lineParser.get("ID").c_str());
106  SUMOReal x = TplConvert::_2SUMOReal(lineParser.get("XKOORD").c_str());
107  SUMOReal y = TplConvert::_2SUMOReal(lineParser.get("YKOORD").c_str());
108  Position pos(x, y);
109  if (!geoConvHelper.x2cartesian(pos)) {
110  WRITE_WARNING("Unable to project coordinates for point '" + toString(id) + "'.");
111  }
112  punkte[id] = pos;
113  continue;
114  } else if (what == "$KANTE") {
115  lineParser.parseLine(line);
116  SUMOLong id = TplConvert::_2long(lineParser.get("ID").c_str());
117  SUMOLong fromID = TplConvert::_2long(lineParser.get("VONPUNKTID").c_str());
118  SUMOLong toID = TplConvert::_2long(lineParser.get("NACHPUNKTID").c_str());
119  PositionVector vec;
120  vec.push_back(punkte[fromID]);
121  vec.push_back(punkte[toID]);
122  kanten[id] = vec;
123  continue;
124  } else if (what == "$ZWISCHENPUNKT") {
125  lineParser.parseLine(line);
126  SUMOLong id = TplConvert::_2long(lineParser.get("KANTEID").c_str());
127  int index = TplConvert::_2int(lineParser.get("INDEX").c_str());
128  SUMOReal x = TplConvert::_2SUMOReal(lineParser.get("XKOORD").c_str());
129  SUMOReal y = TplConvert::_2SUMOReal(lineParser.get("YKOORD").c_str());
130  Position pos(x, y);
131  if (!geoConvHelper.x2cartesian(pos)) {
132  WRITE_WARNING("Unable to project coordinates for edge '" + toString(id) + "'.");
133  }
134  kanten[id].insertAt(index, pos);
135  continue;
136  } else if (what == "$TEILFLAECHENELEMENT") {
137  lineParser.parseLine(line);
138  SUMOLong id = TplConvert::_2long(lineParser.get("TFLAECHEID").c_str());
139  //int index = TplConvert::_2int(lineParser.get("INDEX").c_str());
140  //index = 0; /// hmmmm - assume it's sorted...
141  SUMOLong kid = TplConvert::_2long(lineParser.get("KANTEID").c_str());
142  int dir = TplConvert::_2int(lineParser.get("RICHTUNG").c_str());
143  if (teilflaechen.find(id) == teilflaechen.end()) {
144  teilflaechen[id] = PositionVector();
145  }
146  if (dir == 0) {
147  for (int i = 0; i < (int) kanten[kid].size(); ++i) {
148  teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
149  }
150  } else {
151  for (int i = (int) kanten[kid].size() - 1; i >= 0; --i) {
152  teilflaechen[id].push_back_noDoublePos(kanten[kid][i]);
153  }
154  }
155  continue;
156  } else if (what == "$FLAECHENELEMENT") {
157  lineParser.parseLine(line);
158  SUMOLong id = TplConvert::_2long(lineParser.get("FLAECHEID").c_str());
159  SUMOLong tid = TplConvert::_2long(lineParser.get("TFLAECHEID").c_str());
160  flaechenelemente[id] = tid;
161  continue;
162  }
163  // set if read
164  if (line[0] == '$') {
165  what = "";
166  if (line.find("$PUNKT") == 0) {
167  what = "$PUNKT";
168  } else if (line.find("$KANTE") == 0) {
169  what = "$KANTE";
170  } else if (line.find("$ZWISCHENPUNKT") == 0) {
171  what = "$ZWISCHENPUNKT";
172  } else if (line.find("$TEILFLAECHENELEMENT") == 0) {
173  what = "$TEILFLAECHENELEMENT";
174  } else if (line.find("$FLAECHENELEMENT") == 0) {
175  what = "$FLAECHENELEMENT";
176  }
177  if (what != "") {
178  lineParser.reinit(line.substr(what.length() + 1));
179  }
180  }
181  }
182 
183  // do some more sane job...
184  RGBColor c = RGBColor::parseColor(oc.getString("color"));
185  std::map<std::string, std::string> typemap;
186  // load the pois/polys
187  lr.reinit();
188  bool parsingCategories = false;
189  bool parsingPOIs = false;
190  bool parsingDistrictsDirectly = false;
191  PositionVector vec;
192  std::string polyType, lastID;
193  bool first = true;
194  while (lr.hasMore()) {
195  std::string line = lr.readLine();
196  // do not parse empty lines
197  if (line.length() == 0) {
198  continue;
199  }
200  // do not parse comment lines
201  if (line[0] == '*') {
202  continue;
203  }
204 
205  if (line[0] == '$') {
206  // reset parsing on new entry type
207  parsingCategories = false;
208  parsingPOIs = false;
209  parsingDistrictsDirectly = false;
210  polyType = "";
211  }
212 
213  if (parsingCategories) {
214  // parse the category
215  StringTokenizer st(line, ";");
216  std::string catid = st.next();
217  std::string catname = st.next();
218  typemap[catid] = catname;
219  }
220  if (parsingPOIs) {
221  // parse the poi
222  // $POI:Nr;CATID;CODE;NAME;Kommentar;XKoord;YKoord;
223  lineParser.parseLine(line);
224  SUMOLong idL = TplConvert::_2long(lineParser.get("Nr").c_str());
225  std::string id = toString(idL);
226  std::string catid = lineParser.get("CATID");
227  // process read values
228  SUMOReal x = TplConvert::_2SUMOReal(lineParser.get("XKoord").c_str());
229  SUMOReal y = TplConvert::_2SUMOReal(lineParser.get("YKoord").c_str());
230  Position pos(x, y);
231  if (!geoConvHelper.x2cartesian(pos)) {
232  WRITE_WARNING("Unable to project coordinates for POI '" + id + "'.");
233  }
234  std::string type = typemap[catid];
235  // patch the values
236  bool discard = oc.getBool("discard");
237  int layer = oc.getInt("layer");
238  RGBColor color;
239  if (tm.has(type)) {
240  const PCTypeMap::TypeDef& def = tm.get(type);
241  id = def.prefix + id;
242  type = def.id;
243  color = def.color;
244  discard = def.discard;
245  layer = def.layer;
246  } else {
247  id = oc.getString("prefix") + id;
248  type = oc.getString("type");
249  color = c;
250  }
251  if (!discard) {
252  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer);
253  if (!toFill.insert(id, poi, layer)) {
254  WRITE_ERROR("POI '" + id + "' could not be added.");
255  delete poi;
256  }
257  }
258  }
259 
260  // poly
261  if (polyType != "") {
262  StringTokenizer st(line, ";");
263  std::string id = st.next();
264  std::string type;
265  if (!first && lastID != id) {
266  // we have parsed a polygon completely
267  RGBColor color;
268  int layer = oc.getInt("layer");
269  bool discard = oc.getBool("discard");
270  if (tm.has(polyType)) {
271  const PCTypeMap::TypeDef& def = tm.get(polyType);
272  id = def.prefix + id;
273  type = def.id;
274  color = def.color;
275  discard = def.discard;
276  layer = def.layer;
277  } else {
278  id = oc.getString("prefix") + id;
279  type = oc.getString("type");
280  color = c;
281  }
282  if (!discard) {
283  Polygon* poly = new Polygon(id, type, color, vec, false, (SUMOReal)layer);
284  if (!toFill.insert(id, poly, 1)) {
285  WRITE_ERROR("Polygon '" + id + "' could not be added.");
286  delete poly;
287  }
288  }
289  vec.clear();
290  }
291  lastID = id;
292  first = false;
293  // parse current poly
294  std::string index = st.next();
295  std::string xpos = st.next();
296  std::string ypos = st.next();
297  Position pos2D((SUMOReal) atof(xpos.c_str()), (SUMOReal) atof(ypos.c_str()));
298  if (!geoConvHelper.x2cartesian(pos2D)) {
299  WRITE_WARNING("Unable to project coordinates for polygon '" + id + "'.");
300  }
301  vec.push_back(pos2D);
302  }
303 
304  // district refering a shape
305  if (parsingDistrictsDirectly) {
306  //$BEZIRK:NR CODE NAME TYPNR XKOORD YKOORD FLAECHEID BEZART IVANTEIL_Q IVANTEIL_Z OEVANTEIL METHODEANBANTEILE ZWERT1 ZWERT2 ZWERT3 ISTINAUSWAHL OBEZNR NOM_COM COD_COM
307  lineParser.parseLine(line);
308  SUMOLong idL = TplConvert::_2long(lineParser.get("NR").c_str());
309  std::string id = toString(idL);
310  SUMOLong area = TplConvert::_2long(lineParser.get("FLAECHEID").c_str());
311  SUMOReal x = TplConvert::_2SUMOReal(lineParser.get("XKOORD").c_str());
312  SUMOReal y = TplConvert::_2SUMOReal(lineParser.get("YKOORD").c_str());
313  // patch the values
314  std::string type = "district";
315  bool discard = oc.getBool("discard");
316  int layer = oc.getInt("layer");
317  RGBColor color;
318  if (tm.has(type)) {
319  const PCTypeMap::TypeDef& def = tm.get(type);
320  id = def.prefix + id;
321  type = def.id;
322  color = def.color;
323  discard = def.discard;
324  layer = def.layer;
325  } else {
326  id = oc.getString("prefix") + id;
327  type = oc.getString("type");
328  color = c;
329  }
330  if (!discard) {
331  if (teilflaechen[flaechenelemente[area]].size() > 0) {
332  Polygon* poly = new Polygon(id, type, color, teilflaechen[flaechenelemente[area]], false, (SUMOReal)layer);
333  if (!toFill.insert(id, poly, layer)) {
334  WRITE_ERROR("Polygon '" + id + "' could not be added.");
335  delete poly;
336  }
337  } else {
338  Position pos(x, y);
339  if (!geoConvHelper.x2cartesian(pos)) {
340  WRITE_WARNING("Unable to project coordinates for POI '" + id + "'.");
341  }
342  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer);
343  if (!toFill.insert(id, poi, layer)) {
344  WRITE_ERROR("POI '" + id + "' could not be added.");
345  delete poi;
346  }
347  }
348  }
349  }
350 
351 
352  if (line.find("$POIKATEGORIEDEF:") == 0 || line.find("$POIKATEGORIE:") == 0) {
353  // ok, got categories, begin parsing from next line
354  parsingCategories = true;
355  lineParser.reinit(line.substr(line.find(":") + 1));
356  }
357  if (line.find("$POI:") == 0) {
358  // ok, got pois, begin parsing from next line
359  parsingPOIs = true;
360  lineParser.reinit(line.substr(line.find(":") + 1));
361  }
362  if (line.find("$BEZIRK") == 0 && line.find("FLAECHEID") != std::string::npos) {
363  // ok, have a district header, and it seems like districts would reference shapes...
364  parsingDistrictsDirectly = true;
365  lineParser.reinit(line.substr(line.find(":") + 1));
366  }
367 
368 
369  if (line.find("$BEZIRKPOLY") != std::string::npos) {
370  polyType = "district";
371  }
372  if (line.find("$GEBIETPOLY") != std::string::npos) {
373  polyType = "area";
374  }
375 
376  }
377 }
378 
379 
380 
381 /****************************************************************************/
382 
std::string id
The new type id to use.
Definition: PCTypeMap.h:67
bool insert(const std::string &id, Polygon *poly, int layer, bool ignorePrunning=false)
Adds a polygon to the storage.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:154
A single definition of values that shall be used for a given type.
Definition: PCTypeMap.h:65
std::string next()
bool readLine(LineHandler &lh)
Reads a single (the next) line from the file and reports it to the given LineHandler.
Definition: LineReader.cpp:80
static SUMOReal _2SUMOReal(const E *const data)
Definition: TplConvert.h:223
Retrieves a file linewise and reports the lines to a handler.
Definition: LineReader.h:58
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:97
bool x2cartesian(Position &from, bool includeInBoundary=true)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static void load(const std::string &file, OptionsCont &oc, PCPolyContainer &toFill, PCTypeMap &tm)
Parses pois/polys stored within the given file.
std::string get(const std::string &name, bool prune=false) const
Returns the named information.
static SUMOLong _2long(const E *const data)
Definition: TplConvert.h:142
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
bool discard
Information whether polygons of this type shall be discarded.
Definition: PCTypeMap.h:75
A storage for loaded polygons and pois.
RGBColor color
The color to use.
Definition: PCTypeMap.h:69
A 2D- or 3D-polygon.
Definition: Polygon.h:48
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
void reinit(const std::string &def, const std::string &defDelim=";", const std::string &lineDelim=";", bool chomp=false, bool ignoreCase=true)
Reinitialises the parser.
A storage for type mappings.
Definition: PCTypeMap.h:51
const TypeDef & get(const std::string &id)
Returns a type definition.
Definition: PCTypeMap.cpp:77
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:59
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
static void loadIfSet(OptionsCont &oc, PCPolyContainer &toFill, PCTypeMap &tm)
Loads pois/polygons assumed to be stored using VISUM-format.
bool has(const std::string &id)
Returns the information whether the named type is known.
Definition: PCTypeMap.cpp:83
static bool exists(std::string path)
Checks whether the given file exists.
Definition: FileHelpers.cpp:57
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:198
#define SUMOLong
Definition: config.h:218
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
void push_back(const PositionVector &p)
Appends all positions from the given vector.
static int _2int(const E *const data)
Definition: TplConvert.h:114
std::string prefix
The prefix to use.
Definition: PCTypeMap.h:71
A storage for options typed value containers)
Definition: OptionsCont.h:108
void reinit()
Reinitialises the reading (of the previous file)
Definition: LineReader.cpp:203
A parser to retrieve information from a table with known columns.
#define SUMOReal
Definition: config.h:221
A point-of-interest.
bool hasMore() const
Returns whether another line may be read (the file was not read completely)
Definition: LineReader.cpp:64
int layer
The layer to use.
Definition: PCTypeMap.h:73
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:199
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
void parseLine(const std::string &line)
Parses the contents of the line.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.