SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NIVissimDistrictConnection.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // -------------------
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
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 <map>
34 #include <string>
35 #include <algorithm>
36 #include <cassert>
38 #include <utils/common/ToString.h>
39 #include <utils/geom/Position.h>
40 #include <utils/geom/GeomHelper.h>
43 #include "NIVissimAbstractEdge.h"
44 #include "NIVissimEdge.h"
45 #include <netbuild/NBEdge.h>
46 #include <netbuild/NBEdgeCont.h>
47 #include <netbuild/NBNode.h>
48 #include <netbuild/NBNodeCont.h>
49 #include <netbuild/NBDistrict.h>
55 
56 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 
61 // ===========================================================================
62 // static member definitions
63 // ===========================================================================
65 std::map<int, std::vector<int> > NIVissimDistrictConnection::myDistrictsConnections;
66 
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
72  const std::string& name,
73  const std::vector<int>& districts, const std::vector<SUMOReal>& percentages,
74  int edgeid, SUMOReal position,
75  const std::vector<std::pair<int, int> >& assignedVehicles)
76  : myID(id), myName(name), myDistricts(districts),
77  myEdgeID(edgeid), myPosition(position),
78  myAssignedVehicles(assignedVehicles) {
79  std::vector<int>::iterator i = myDistricts.begin();
80  std::vector<SUMOReal>::const_iterator j = percentages.begin();
81  while (i != myDistricts.end()) {
82  myPercentages[*i] = *j;
83  i++;
84  j++;
85  }
86 }
87 
88 
90 
91 
92 
93 bool
94 NIVissimDistrictConnection::dictionary(int id, const std::string& name,
95  const std::vector<int>& districts, const std::vector<SUMOReal>& percentages,
96  int edgeid, SUMOReal position,
97  const std::vector<std::pair<int, int> >& assignedVehicles) {
99  new NIVissimDistrictConnection(id, name, districts, percentages,
100  edgeid, position, assignedVehicles);
101  if (!dictionary(id, o)) {
102  delete o;
103  return false;
104  }
105  return true;
106 }
107 
108 
109 bool
111  DictType::iterator i = myDict.find(id);
112  if (i == myDict.end()) {
113  myDict[id] = o;
114  return true;
115  }
116  return false;
117 }
118 
119 
122  DictType::iterator i = myDict.find(id);
123  if (i == myDict.end()) {
124  return 0;
125  }
126  return (*i).second;
127 }
128 
129 void
131  // pre-assign connections to districts
132  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
133  NIVissimDistrictConnection* c = (*i).second;
134  const std::vector<int>& districts = c->myDistricts;
135  for (std::vector<int>::const_iterator j = districts.begin(); j != districts.end(); j++) {
136  // assign connection to district
137  myDistrictsConnections[*j].push_back((*i).first);
138  }
139  }
140 }
141 
142 
143 void
145  for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
146  const std::vector<int>& connections = (*k).second;
147  for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
149  c->checkEdgeEnd();
150  }
151  }
152 }
153 
154 
155 void
158  assert(edge != 0);
160 }
161 
162 
163 void
165  NBNodeCont& nc) {
166  for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
167  // get the connections
168  const std::vector<int>& connections = (*k).second;
169  // retrieve the current district
170  std::string dsid = toString<int>((*k).first);
171  NBDistrict* district = new NBDistrict(dsid);
172  dc.insert(district);
173  // compute the middle of the district
174  PositionVector pos;
175  for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
177  pos.push_back(c->geomPosition());
178  }
179  Position distCenter = pos.getPolygonCenter();
180  if (connections.size() == 1) { // !!! ok, ok, maybe not the best way just to add an offset
181  distCenter.add(10, 10);
182  }
183  district->setCenter(distCenter);
184  // build the node
185  std::string id = "District" + district->getID();
186  NBNode* districtNode =
187  new NBNode(id, district->getPosition(), district);
188  if (!nc.insert(districtNode)) {
189  throw 1;
190  }
191  }
192 }
193 
194 void
196  NBEdgeCont& ec,
197  NBNodeCont& nc/*,
198  NBDistribution &distc*/) {
199  // add the sources and sinks
200  // their normalised probability is computed within NBDistrict
201  // to avoid SUMOReal code writing and more securty within the converter
202  // go through the district table
203  for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
204  // get the connections
205  const std::vector<int>& connections = (*k).second;
206  // retrieve the current district
207  NBDistrict* district =
208  dc.retrieve(toString<int>((*k).first));
209  NBNode* districtNode = nc.retrieve("District" + district->getID());
210  assert(district != 0 && districtNode != 0);
211 
212  for (std::vector<int>::const_iterator l = connections.begin(); l != connections.end(); l++) {
214  // get the edge to connect the parking place to
215  NBEdge* e = ec.retrieve(toString<int>(c->myEdgeID));
216  if (e == 0) {
217  e = ec.retrievePossiblySplit(toString<int>(c->myEdgeID), c->myPosition);
218  }
219  if (e == 0) {
220  WRITE_WARNING("Could not build district '" + toString<int>((*k).first) + "' - edge '" + toString<int>(c->myEdgeID) + "' is missing.");
221  continue;
222  }
223  std::string id = "ParkingPlace" + toString<int>(*l);
224  NBNode* parkingPlace = nc.retrieve(id);
225  if (parkingPlace == 0) {
226  SUMOReal pos = c->getPosition();
227  if (pos < e->getLength() - pos) {
228  parkingPlace = e->getFromNode();
229  parkingPlace->invalidateIncomingConnections();
230  } else {
231  parkingPlace = e->getToNode();
232  parkingPlace->invalidateOutgoingConnections();
233  }
234  }
235  assert(
236  e->getToNode() == parkingPlace
237  ||
238  e->getFromNode() == parkingPlace);
239 
240  // build the connection to the source
241  if (e->getFromNode() == parkingPlace) {
242  id = "VissimFromParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
243  NBEdge* source =
244  new NBEdge(id, districtNode, parkingPlace,
245  "Connection", c->getMeanSpeed(/*distc*/) / (SUMOReal) 3.6, 3, -1,
247  if (!ec.insert(source)) { // !!! in den Konstruktor
248  throw 1; // !!!
249  }
250  SUMOReal percNormed =
251  c->myPercentages[(*k).first];
252  if (!district->addSource(source, percNormed)) {
253  throw 1;
254  }
255  }
256 
257  // build the connection to the destination
258  if (e->getToNode() == parkingPlace) {
259  id = "VissimToParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
260  NBEdge* destination =
261  new NBEdge(id, parkingPlace, districtNode,
262  "Connection", (SUMOReal) 100 / (SUMOReal) 3.6, 2, -1,
264  if (!ec.insert(destination)) { // !!! (in den Konstruktor)
265  throw 1; // !!!
266  }
267  SUMOReal percNormed2 =
268  c->myPercentages[(*k).first];
269  if (!district->addSink(destination, percNormed2)) {
270  throw 1; // !!!
271  }
272  }
273 
274  /*
275  if(e->getToNode()==districtNode) {
276  SUMOReal percNormed =
277  c->myPercentages[(*k).first];
278  district->addSink(e, percNormed);
279  }
280  if(e->getFromNode()==districtNode) {
281  SUMOReal percNormed =
282  c->myPercentages[(*k).first];
283  district->addSource(e, percNormed);
284  }
285  */
286  }
287 
288  /*
289  // add them as sources and sinks to the current district
290  for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) {
291  // get the current connections
292  NIVissimDistrictConnection *c = dictionary(*l);
293  // get the edge to connect the parking place to
294  NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
295  Position edgepos = c->geomPosition();
296  NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
297  e->getLength()/4.0);
298  if(edgeend==0) {
299  // Edge splitting omitted on build district connections by now
300  assert(false);
301  }
302 
303  // build the district-node if not yet existing
304  std::string id = "VissimParkingplace" + district->getID();
305  NBNode *districtNode = nc.retrieve(id);
306  assert(districtNode!=0);
307 
308  if(e->getToNode()==edgeend) {
309  // build the connection to the source
310  id = std::string("VissimFromParkingplace")
311  + toString<int>((*k).first) + "-"
312  + toString<int>(c->myID);
313  NBEdge *source =
314  new NBEdge(id, id, districtNode, edgeend,
315  "Connection", 100/3.6, 2, 100, 0,
316  NBEdge::EDGEFUNCTION_SOURCE);
317  NBEdgeCont::insert(source); // !!! (in den Konstruktor)
318  SUMOReal percNormed =
319  c->myPercentages[(*k).first];
320  district->addSource(source, percNormed);
321  } else {
322  // build the connection to the destination
323  id = std::string("VissimToParkingplace")
324  + toString<int>((*k).first) + "-"
325  + toString<int>(c->myID);
326  NBEdge *destination =
327  new NBEdge(id, id, edgeend, districtNode,
328  "Connection", 100/3.6, 2, 100, 0,
329  NBEdge::EDGEFUNCTION_SINK);
330  NBEdgeCont::insert(destination); // !!! (in den Konstruktor)
331 
332  // add both the source and the sink to the district
333  SUMOReal percNormed =
334  c->myPercentages[(*k).first];
335  district->addSink(destination, percNormed);
336  }
337  }
338  */
339  }
340 }
341 
342 
343 
344 Position
347  return e->getGeomPosition(myPosition);
348 }
349 
350 
353  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
354  if ((*i).second->myEdgeID == edgeid) {
355  return (*i).second;
356  }
357  }
358  return 0;
359 }
360 
361 
362 void
364  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
365  delete(*i).second;
366  }
367  myDict.clear();
368 }
369 
370 
371 SUMOReal
372 NIVissimDistrictConnection::getMeanSpeed(/*NBDistribution &dc*/) const {
373  //assert(myAssignedVehicles.size()!=0);
374  if (myAssignedVehicles.size() == 0) {
375  WRITE_WARNING("No streams assigned at district'" + toString(myID) + "'.\n Using default speed 200km/h");
376  return (SUMOReal) 200 / (SUMOReal) 3.6;
377  }
378  SUMOReal speed = 0;
379  std::vector<std::pair<int, int> >::const_iterator i;
380  for (i = myAssignedVehicles.begin(); i != myAssignedVehicles.end(); i++) {
381  speed += getRealSpeed(/*dc, */(*i).second);
382  }
383  return speed / (SUMOReal) myAssignedVehicles.size();
384 }
385 
386 
387 SUMOReal
388 NIVissimDistrictConnection::getRealSpeed(/*NBDistribution &dc, */int distNo) const {
389  std::string id = toString<int>(distNo);
390  Distribution* dist = NBDistribution::dictionary("speed", id);
391  if (dist == 0) {
392  WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
393  WRITE_WARNING(". Using default.");
394  return OptionsCont::getOptions().getFloat("vissim.default-speed");
395  }
396  assert(dist != 0);
397  SUMOReal speed = dist->getMax();
398  if (speed < 0 || speed > 1000) {
399  WRITE_WARNING(" False speed at district '" + id);
400  WRITE_WARNING(". Using default.");
401  speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
402  }
403  return speed;
404 }
405 
406 
407 
408 /****************************************************************************/
409 
static void dict_BuildDistricts(NBDistrictCont &dc, NBEdgeCont &ec, NBNodeCont &nc)
Builds the districts.
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:268
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
static std::map< int, std::vector< int > > myDistrictsConnections
Map from ditricts to connections.
Position geomPosition() const
Returns the position The position yields from the edge geometry and the place the connection is plaed...
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:119
bool addSource(NBEdge *const source, SUMOReal weight)
Adds a source.
Definition: NBDistrict.cpp:74
SUMOReal getRealSpeed(int distNo) const
The representation of a single edge during network building.
Definition: NBEdge.h:71
static bool dictionary(const std::string &type, const std::string &id, Distribution *d)
A container for districts.
void checkDistrictConnectionExistanceAt(SUMOReal pos)
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
static const SUMOReal UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:203
static NIVissimDistrictConnection * dict_findForEdge(int edgeid)
Returns the connection to a district placed at the given node Yep, there onyl should be one...
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
DistrictPercentages myPercentages
A map how many vehicles (key, amount) should leave to a district (key)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:61
int myID
The id of the connections.
A class representing a single district.
Definition: NBDistrict.h:72
const std::string & getID() const
Returns the id.
Definition: Named.h:60
std::vector< std::pair< int, int > > myAssignedVehicles
The vehicles using this connection.
void invalidateIncomingConnections()
Definition: NBNode.cpp:1025
int myEdgeID
The id of the connected edge.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:164
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
std::vector< int > myDistricts
The connected districts.
void invalidateOutgoingConnections()
Definition: NBNode.cpp:1033
Position getGeomPosition(SUMOReal pos) const
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
static DictType myDict
District connection dictionary.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:52
SUMOReal getPosition() const
Returns the position of the connection at the edge.
static bool dictionary(int id, const std::string &name, const std::vector< int > &districts, const std::vector< SUMOReal > &percentages, int edgeid, SUMOReal position, const std::vector< std::pair< int, int > > &assignedVehicles)
Inserts the connection into the dictionary after building it.
bool insert(NBDistrict *const district)
Adds a district to the dictionary.
static void clearDict()
Clears the dictionary.
void push_back(const PositionVector &p)
Appends all positions from the given vector.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:362
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
bool addSink(NBEdge *const sink, SUMOReal weight)
Adds a sink.
Definition: NBDistrict.cpp:87
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:79
static bool dictionary(int id, const std::string &name, const std::string &type, int noLanes, SUMOReal zuschlag1, SUMOReal zuschlag2, SUMOReal length, const PositionVector &geom, const NIVissimClosedLanesVector &clv)
Adds the described item to the dictionary Builds the edge first.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
#define SUMOReal
Definition: config.h:215
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:124
NIVissimDistrictConnection(int id, const std::string &name, const std::vector< int > &districts, const std::vector< SUMOReal > &percentages, int edgeid, SUMOReal position, const std::vector< std::pair< int, int > > &assignedVehicles)
Contructor.
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
std::map< int, NIVissimDistrictConnection * > DictType
Definition of a dictionary of district connections.
SUMOReal myPosition
The position on the edge.
NBDistrict * retrieve(const std::string &id) const
Returns the districts with the given id.
static void dict_BuildDistrictNodes(NBDistrictCont &dc, NBNodeCont &nc)
Builds the nodes that belong to a district.
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:354