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