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