Eclipse SUMO - Simulation of Urban MObility
NIVissimDistrictConnection.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // -------------------
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <map>
25 #include <string>
26 #include <algorithm>
27 #include <cassert>
29 #include <utils/common/ToString.h>
30 #include <utils/geom/Position.h>
31 #include <utils/geom/GeomHelper.h>
34 #include "NIVissimAbstractEdge.h"
35 #include "NIVissimEdge.h"
36 #include <netbuild/NBEdge.h>
37 #include <netbuild/NBEdgeCont.h>
38 #include <netbuild/NBNode.h>
39 #include <netbuild/NBNodeCont.h>
40 #include <netbuild/NBDistrict.h>
45 
46 
47 // ===========================================================================
48 // static member definitions
49 // ===========================================================================
51 std::map<int, std::vector<int> > NIVissimDistrictConnection::myDistrictsConnections;
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
58  const std::string& name,
59  const std::vector<int>& districts, const std::vector<double>& percentages,
60  int edgeid, double position,
61  const std::vector<std::pair<int, int> >& assignedVehicles)
62  : myID(id), myName(name), myDistricts(districts),
63  myEdgeID(edgeid), myPosition(position),
64  myAssignedVehicles(assignedVehicles) {
65  std::vector<int>::iterator i = myDistricts.begin();
66  std::vector<double>::const_iterator j = percentages.begin();
67  while (i != myDistricts.end()) {
68  myPercentages[*i] = *j;
69  i++;
70  j++;
71  }
72 }
73 
74 
76 
77 
78 
79 bool
80 NIVissimDistrictConnection::dictionary(int id, const std::string& name,
81  const std::vector<int>& districts, const std::vector<double>& percentages,
82  int edgeid, double position,
83  const std::vector<std::pair<int, int> >& assignedVehicles) {
85  new NIVissimDistrictConnection(id, name, districts, percentages,
86  edgeid, position, assignedVehicles);
87  if (!dictionary(id, o)) {
88  delete o;
89  return false;
90  }
91  return true;
92 }
93 
94 
95 bool
97  DictType::iterator i = myDict.find(id);
98  if (i == myDict.end()) {
99  myDict[id] = o;
100  return true;
101  }
102  return false;
103 }
104 
105 
108  DictType::iterator i = myDict.find(id);
109  if (i == myDict.end()) {
110  return nullptr;
111  }
112  return (*i).second;
113 }
114 
115 void
117  // pre-assign connections to districts
118  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
119  NIVissimDistrictConnection* c = (*i).second;
120  const std::vector<int>& districts = c->myDistricts;
121  for (std::vector<int>::const_iterator j = districts.begin(); j != districts.end(); j++) {
122  // assign connection to district
123  myDistrictsConnections[*j].push_back((*i).first);
124  }
125  }
126 }
127 
128 
129 void
131  for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
132  const std::vector<int>& connections = (*k).second;
133  for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
135  c->checkEdgeEnd();
136  }
137  }
138 }
139 
140 
141 void
144  assert(edge != 0);
146 }
147 
148 
149 void
151  NBNodeCont& nc) {
152  for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
153  // get the connections
154  const std::vector<int>& connections = (*k).second;
155  // retrieve the current district
156  std::string dsid = toString<int>((*k).first);
157  NBDistrict* district = new NBDistrict(dsid);
158  dc.insert(district);
159  // compute the middle of the district
160  PositionVector pos;
161  for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
163  pos.push_back(c->geomPosition());
164  }
165  Position distCenter = pos.getPolygonCenter();
166  if (connections.size() == 1) { // !!! ok, ok, maybe not the best way just to add an offset
167  distCenter.add(10, 10);
168  }
169  district->setCenter(distCenter);
170  // build the node
171  std::string id = "District" + district->getID();
172  NBNode* districtNode =
173  new NBNode(id, district->getPosition(), district);
174  if (!nc.insert(districtNode)) {
175  throw 1;
176  }
177  }
178 }
179 
180 void
182  NBEdgeCont& ec,
183  NBNodeCont& nc) {
184  // add the sources and sinks
185  // their normalised probability is computed within NBDistrict
186  // to avoid double code writing and more securty within the converter
187  // go through the district table
188  for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
189  // get the connections
190  const std::vector<int>& connections = (*k).second;
191  // retrieve the current district
192  NBDistrict* district =
193  dc.retrieve(toString<int>((*k).first));
194  NBNode* districtNode = nc.retrieve("District" + district->getID());
195  assert(district != 0 && districtNode != 0);
196 
197  for (std::vector<int>::const_iterator l = connections.begin(); l != connections.end(); l++) {
199  // get the edge to connect the parking place to
200  NBEdge* e = ec.retrieve(toString<int>(c->myEdgeID));
201  if (e == nullptr) {
202  e = ec.retrievePossiblySplit(toString<int>(c->myEdgeID), c->myPosition);
203  }
204  if (e == nullptr) {
205  WRITE_WARNINGF(TL("Could not build district '%' - edge '%' is missing."), toString<int>((*k).first), toString<int>(c->myEdgeID));
206  continue;
207  }
208  std::string id = "ParkingPlace" + toString<int>(*l);
209  NBNode* parkingPlace = nc.retrieve(id);
210  if (parkingPlace == nullptr) {
211  double pos = c->getPosition();
212  if (pos < e->getLength() - pos) {
213  parkingPlace = e->getFromNode();
214  parkingPlace->invalidateIncomingConnections();
215  } else {
216  parkingPlace = e->getToNode();
217  parkingPlace->invalidateOutgoingConnections();
218  }
219  }
220  assert(
221  e->getToNode() == parkingPlace
222  ||
223  e->getFromNode() == parkingPlace);
224 
225  // build the connection to the source
226  if (e->getFromNode() == parkingPlace) {
227  id = "VissimFromParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
228  NBEdge* source =
229  new NBEdge(id, districtNode, parkingPlace,
230  "Connection", c->getMeanSpeed(/*distc*/) / 3.6, NBEdge::UNSPECIFIED_FRICTION, 3, -1,
232  if (!ec.insert(source)) { // !!! in den Konstruktor
233  throw 1; // !!!
234  }
235  double percNormed =
236  c->myPercentages[(*k).first];
237  if (!district->addSource(source, percNormed)) {
238  throw 1;
239  }
240  }
241 
242  // build the connection to the destination
243  if (e->getToNode() == parkingPlace) {
244  id = "VissimToParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
245  NBEdge* destination =
246  new NBEdge(id, parkingPlace, districtNode,
247  "Connection", 100. / 3.6, NBEdge::UNSPECIFIED_FRICTION, 2, -1,
249  if (!ec.insert(destination)) { // !!! (in den Konstruktor)
250  throw 1; // !!!
251  }
252  double percNormed2 =
253  c->myPercentages[(*k).first];
254  if (!district->addSink(destination, percNormed2)) {
255  throw 1; // !!!
256  }
257  }
258 
259  /*
260  if(e->getToNode()==districtNode) {
261  double percNormed =
262  c->myPercentages[(*k).first];
263  district->addSink(e, percNormed);
264  }
265  if(e->getFromNode()==districtNode) {
266  double percNormed =
267  c->myPercentages[(*k).first];
268  district->addSource(e, percNormed);
269  }
270  */
271  }
272 
273  /*
274  // add them as sources and sinks to the current district
275  for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) {
276  // get the current connections
277  NIVissimDistrictConnection *c = dictionary(*l);
278  // get the edge to connect the parking place to
279  NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
280  Position edgepos = c->geomPosition();
281  NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
282  e->getLength()/4.0);
283  if(edgeend==0) {
284  // Edge splitting omitted on build district connections by now
285  assert(false);
286  }
287 
288  // build the district-node if not yet existing
289  std::string id = "VissimParkingplace" + district->getID();
290  NBNode *districtNode = nc.retrieve(id);
291  assert(districtNode!=0);
292 
293  if(e->getToNode()==edgeend) {
294  // build the connection to the source
295  id = std::string("VissimFromParkingplace")
296  + toString<int>((*k).first) + "-"
297  + toString<int>(c->myID);
298  NBEdge *source =
299  new NBEdge(id, id, districtNode, edgeend,
300  "Connection", 100/3.6, 2, 100, 0,
301  NBEdge::EDGEFUNCTION_SOURCE);
302  NBEdgeCont::insert(source); // !!! (in den Konstruktor)
303  double percNormed =
304  c->myPercentages[(*k).first];
305  district->addSource(source, percNormed);
306  } else {
307  // build the connection to the destination
308  id = std::string("VissimToParkingplace")
309  + toString<int>((*k).first) + "-"
310  + toString<int>(c->myID);
311  NBEdge *destination =
312  new NBEdge(id, id, edgeend, districtNode,
313  "Connection", 100/3.6, 2, 100, 0,
314  NBEdge::EDGEFUNCTION_SINK);
315  NBEdgeCont::insert(destination); // !!! (in den Konstruktor)
316 
317  // add both the source and the sink to the district
318  double percNormed =
319  c->myPercentages[(*k).first];
320  district->addSink(destination, percNormed);
321  }
322  }
323  */
324  }
325 }
326 
327 
328 
329 Position
332  return e->getGeomPosition(myPosition);
333 }
334 
335 
338  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
339  if ((*i).second->myEdgeID == edgeid) {
340  return (*i).second;
341  }
342  }
343  return nullptr;
344 }
345 
346 
347 void
349  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
350  delete (*i).second;
351  }
352  myDict.clear();
353 }
354 
355 
356 double
358  //assert(myAssignedVehicles.size()!=0);
359  if (myAssignedVehicles.size() == 0) {
360  WRITE_WARNINGF(TL("No streams assigned at district'%'.\n Using default speed 200km/h"), toString(myID));
361  return (double) 200 / (double) 3.6;
362  }
363  double speed = 0;
364  std::vector<std::pair<int, int> >::const_iterator i;
365  for (i = myAssignedVehicles.begin(); i != myAssignedVehicles.end(); i++) {
366  speed += getRealSpeed((*i).second);
367  }
368  return speed / (double) myAssignedVehicles.size();
369 }
370 
371 
372 double
374  std::string id = toString<int>(distNo);
375  Distribution* dist = DistributionCont::dictionary("speed", id);
376  if (dist == nullptr) {
377  WRITE_WARNINGF(TL("The referenced speed distribution '%' is not known."), id);
378  WRITE_WARNING(TL(". Using default."));
379  return OptionsCont::getOptions().getFloat("vissim.default-speed");
380  }
381  assert(dist != 0);
382  double speed = dist->getMax();
383  if (speed < 0 || speed > 1000) {
384  WRITE_WARNING(" False speed at district '" + id);
385  WRITE_WARNING(TL(". Using default."));
386  speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
387  }
388  return speed;
389 }
390 
391 
392 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
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.
virtual double getMax() const =0
Returns the maximum value of this distribution.
A container for districts.
NBDistrict * retrieve(const std::string &id) const
Returns the districts with the given id.
bool insert(NBDistrict *const district)
Adds a district to the dictionary.
A class representing a single district.
Definition: NBDistrict.h:62
bool addSink(NBEdge *const sink, double weight)
Adds a sink.
Definition: NBDistrict.cpp:81
bool addSource(NBEdge *const source, double weight)
Adds a source.
Definition: NBDistrict.cpp:68
void setCenter(const Position &pos)
Sets the center coordinates.
Definition: NBDistrict.cpp:94
const Position & getPosition() const
Returns the position of this district's center.
Definition: NBDistrict.h:120
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:281
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
Definition: NBEdgeCont.cpp:317
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:182
The representation of a single edge during network building.
Definition: NBEdge.h:92
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition: NBEdge.h:351
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:542
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:342
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:345
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:535
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:57
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:87
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:116
Represents a single node (junction) during network building.
Definition: NBNode.h:66
void invalidateOutgoingConnections(bool reallowSetting=false)
invalidate outgoing connections
Definition: NBNode.cpp:1998
void invalidateIncomingConnections(bool reallowSetting=false)
invalidate incoming connections
Definition: NBNode.cpp:1990
Position getGeomPosition(double pos) const
static void dict_BuildDistricts(NBDistrictCont &dc, NBEdgeCont &ec, NBNodeCont &nc)
Builds the districts.
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.
DistrictPercentages myPercentages
A map how many vehicles (key, amount) should leave to a district (key)
std::vector< int > myDistricts
The connected districts.
static NIVissimDistrictConnection * dict_findForEdge(int edgeid)
Returns the connection to a district placed at the given node Yep, there onyl should be one,...
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...
std::vector< std::pair< int, int > > myAssignedVehicles
The vehicles using this connection.
double myPosition
The position on the edge.
static void dict_BuildDistrictNodes(NBDistrictCont &dc, NBNodeCont &nc)
Builds the nodes that belong to a district.
int myID
The id of the connections.
static void clearDict()
Clears the dictionary.
double getPosition() const
Returns the position of the connection at the edge.
static DictType myDict
District connection dictionary.
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.
std::map< int, NIVissimDistrictConnection * > DictType
Definition of a dictionary of district connections.
int myEdgeID
The id of the connected edge.
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:51
void checkDistrictConnectionExistanceAt(double pos)
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.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:132
A list of positions.
Position getPolygonCenter() const
Returns the arithmetic of all corner points.