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.sourceforge.net/
13 // Copyright (C) 2001-2012 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  int enklave = TplConvert::_2int(lineParser.get("ENKLAVE").c_str()); // !!! unused
161  enklave = 0;
162  flaechenelemente[id] = tid;
163  continue;
164  }
165  // set if read
166  if (line[0] == '$') {
167  what = "";
168  if (line.find("$PUNKT") == 0) {
169  what = "$PUNKT";
170  } else if (line.find("$KANTE") == 0) {
171  what = "$KANTE";
172  } else if (line.find("$ZWISCHENPUNKT") == 0) {
173  what = "$ZWISCHENPUNKT";
174  } else if (line.find("$TEILFLAECHENELEMENT") == 0) {
175  what = "$TEILFLAECHENELEMENT";
176  } else if (line.find("$FLAECHENELEMENT") == 0) {
177  what = "$FLAECHENELEMENT";
178  }
179  if (what != "") {
180  lineParser.reinit(line.substr(what.length() + 1));
181  }
182  }
183  }
184 
185  // do some more sane job...
186  RGBColor c = RGBColor::parseColor(oc.getString("color"));
187  std::map<std::string, std::string> typemap;
188  // load the pois/polys
189  lr.reinit();
190  bool parsingCategories = false;
191  bool parsingPOIs = false;
192  bool parsingDistrictsDirectly = false;
193  PositionVector vec;
194  std::string polyType, lastID;
195  bool first = true;
196  while (lr.hasMore()) {
197  std::string line = lr.readLine();
198  // do not parse empty lines
199  if (line.length() == 0) {
200  continue;
201  }
202  // do not parse comment lines
203  if (line[0] == '*') {
204  continue;
205  }
206 
207  if (line[0] == '$') {
208  // reset parsing on new entry type
209  parsingCategories = false;
210  parsingPOIs = false;
211  parsingDistrictsDirectly = false;
212  polyType = "";
213  }
214 
215  if (parsingCategories) {
216  // parse the category
217  StringTokenizer st(line, ";");
218  std::string catid = st.next();
219  std::string catname = st.next();
220  typemap[catid] = catname;
221  }
222  if (parsingPOIs) {
223  // parse the poi
224  // $POI:Nr;CATID;CODE;NAME;Kommentar;XKoord;YKoord;
225  lineParser.parseLine(line);
226  SUMOLong idL = TplConvert::_2long(lineParser.get("Nr").c_str());
227  std::string id = toString(idL);
228  std::string catid = lineParser.get("CATID");
229  // process read values
230  SUMOReal x = TplConvert::_2SUMOReal(lineParser.get("XKoord").c_str());
231  SUMOReal y = TplConvert::_2SUMOReal(lineParser.get("YKoord").c_str());
232  Position pos(x, y);
233  if (!geoConvHelper.x2cartesian(pos)) {
234  WRITE_WARNING("Unable to project coordinates for POI '" + id + "'.");
235  }
236  std::string type = typemap[catid];
237  // patch the values
238  bool discard = oc.getBool("discard");
239  int layer = oc.getInt("layer");
240  RGBColor color;
241  if (tm.has(type)) {
242  const PCTypeMap::TypeDef& def = tm.get(type);
243  id = def.prefix + id;
244  type = def.id;
245  color = RGBColor::parseColor(def.color);
246  discard = def.discard;
247  layer = def.layer;
248  } else {
249  id = oc.getString("prefix") + id;
250  type = oc.getString("type");
251  color = c;
252  }
253  if (!discard) {
254  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer);
255  if (!toFill.insert(id, poi, layer)) {
256  WRITE_ERROR("POI '" + id + "' could not be added.");
257  delete poi;
258  }
259  }
260  }
261 
262  // poly
263  if (polyType != "") {
264  StringTokenizer st(line, ";");
265  std::string id = st.next();
266  std::string type;
267  if (!first && lastID != id) {
268  // we have parsed a polygon completely
269  RGBColor color;
270  int layer = oc.getInt("layer");
271  bool discard = oc.getBool("discard");
272  if (tm.has(polyType)) {
273  const PCTypeMap::TypeDef& def = tm.get(polyType);
274  id = def.prefix + id;
275  type = def.id;
276  color = RGBColor::parseColor(def.color);
277  discard = def.discard;
278  layer = def.layer;
279  } else {
280  id = oc.getString("prefix") + id;
281  type = oc.getString("type");
282  color = c;
283  }
284  if (!discard) {
285  Polygon* poly = new Polygon(id, type, color, vec, false, (SUMOReal)layer);
286  if (!toFill.insert(id, poly, 1)) {
287  WRITE_ERROR("Polygon '" + id + "' could not be added.");
288  delete poly;
289  }
290  }
291  vec.clear();
292  }
293  lastID = id;
294  first = false;
295  // parse current poly
296  std::string index = st.next();
297  std::string xpos = st.next();
298  std::string ypos = st.next();
299  Position pos2D((SUMOReal) atof(xpos.c_str()), (SUMOReal) atof(ypos.c_str()));
300  if (!geoConvHelper.x2cartesian(pos2D)) {
301  WRITE_WARNING("Unable to project coordinates for polygon '" + id + "'.");
302  }
303  vec.push_back(pos2D);
304  }
305 
306  // district refering a shape
307  if (parsingDistrictsDirectly) {
308  //$BEZIRK:NR CODE NAME TYPNR XKOORD YKOORD FLAECHEID BEZART IVANTEIL_Q IVANTEIL_Z OEVANTEIL METHODEANBANTEILE ZWERT1 ZWERT2 ZWERT3 ISTINAUSWAHL OBEZNR NOM_COM COD_COM
309  lineParser.parseLine(line);
310  SUMOLong idL = TplConvert::_2long(lineParser.get("NR").c_str());
311  std::string id = toString(idL);
312  SUMOLong area = TplConvert::_2long(lineParser.get("FLAECHEID").c_str());
313  SUMOReal x = TplConvert::_2SUMOReal(lineParser.get("XKOORD").c_str());
314  SUMOReal y = TplConvert::_2SUMOReal(lineParser.get("YKOORD").c_str());
315  // patch the values
316  std::string type = "district";
317  bool discard = oc.getBool("discard");
318  int layer = oc.getInt("layer");
319  RGBColor color;
320  if (tm.has(type)) {
321  const PCTypeMap::TypeDef& def = tm.get(type);
322  id = def.prefix + id;
323  type = def.id;
324  color = RGBColor::parseColor(def.color);
325  discard = def.discard;
326  layer = def.layer;
327  } else {
328  id = oc.getString("prefix") + id;
329  type = oc.getString("type");
330  color = c;
331  }
332  if (!discard) {
333  if (teilflaechen[flaechenelemente[area]].size() > 0) {
334  Polygon* poly = new Polygon(id, type, color, teilflaechen[flaechenelemente[area]], false, (SUMOReal)layer);
335  if (!toFill.insert(id, poly, layer)) {
336  WRITE_ERROR("Polygon '" + id + "' could not be added.");
337  delete poly;
338  }
339  } else {
340  Position pos(x, y);
341  if (!geoConvHelper.x2cartesian(pos)) {
342  WRITE_WARNING("Unable to project coordinates for POI '" + id + "'.");
343  }
344  PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer);
345  if (!toFill.insert(id, poi, layer)) {
346  WRITE_ERROR("POI '" + id + "' could not be added.");
347  delete poi;
348  }
349  }
350  }
351  }
352 
353 
354  if (line.find("$POIKATEGORIEDEF:") == 0 || line.find("$POIKATEGORIE:") == 0) {
355  // ok, got categories, begin parsing from next line
356  parsingCategories = true;
357  lineParser.reinit(line.substr(line.find(":") + 1));
358  }
359  if (line.find("$POI:") == 0) {
360  // ok, got pois, begin parsing from next line
361  parsingPOIs = true;
362  lineParser.reinit(line.substr(line.find(":") + 1));
363  }
364  if (line.find("$BEZIRK") == 0 && line.find("FLAECHEID") != std::string::npos) {
365  // ok, have a district header, and it seems like districts would reference shapes...
366  parsingDistrictsDirectly = true;
367  lineParser.reinit(line.substr(line.find(":") + 1));
368  }
369 
370 
371  if (line.find("$BEZIRKPOLY") != std::string::npos) {
372  polyType = "district";
373  }
374  if (line.find("$GEBIETPOLY") != std::string::npos) {
375  polyType = "area";
376  }
377 
378  }
379 }
380 
381 
382 
383 /****************************************************************************/
384