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.sourceforge.net/
12 // Copyright (C) 2001-2012 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.retrievePossiblySplitted(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, -1, LANESPREAD_RIGHT);
246  if (!ec.insert(source)) { // !!! in den Konstruktor
247  throw 1; // !!!
248  }
249  SUMOReal percNormed =
250  c->myPercentages[(*k).first];
251  if (!district->addSource(source, percNormed)) {
252  throw 1;
253  }
254  }
255 
256  // build the connection to the destination
257  if (e->getToNode() == parkingPlace) {
258  id = "VissimToParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
259  NBEdge* destination =
260  new NBEdge(id, parkingPlace, districtNode,
261  "Connection", (SUMOReal) 100 / (SUMOReal) 3.6, 2, -1, -1, LANESPREAD_RIGHT);
262  if (!ec.insert(destination)) { // !!! (in den Konstruktor)
263  throw 1; // !!!
264  }
265  SUMOReal percNormed2 =
266  c->myPercentages[(*k).first];
267  if (!district->addSink(destination, percNormed2)) {
268  throw 1; // !!!
269  }
270  }
271 
272  /*
273  if(e->getToNode()==districtNode) {
274  SUMOReal percNormed =
275  c->myPercentages[(*k).first];
276  district->addSink(e, percNormed);
277  }
278  if(e->getFromNode()==districtNode) {
279  SUMOReal percNormed =
280  c->myPercentages[(*k).first];
281  district->addSource(e, percNormed);
282  }
283  */
284  }
285 
286  /*
287  // add them as sources and sinks to the current district
288  for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) {
289  // get the current connections
290  NIVissimDistrictConnection *c = dictionary(*l);
291  // get the edge to connect the parking place to
292  NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
293  Position edgepos = c->geomPosition();
294  NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
295  e->getLength()/4.0);
296  if(edgeend==0) {
297  // Edge splitting omitted on build district connections by now
298  assert(false);
299  }
300 
301  // build the district-node if not yet existing
302  std::string id = "VissimParkingplace" + district->getID();
303  NBNode *districtNode = nc.retrieve(id);
304  assert(districtNode!=0);
305 
306  if(e->getToNode()==edgeend) {
307  // build the connection to the source
308  id = std::string("VissimFromParkingplace")
309  + toString<int>((*k).first) + "-"
310  + toString<int>(c->myID);
311  NBEdge *source =
312  new NBEdge(id, id, districtNode, edgeend,
313  "Connection", 100/3.6, 2, 100, 0,
314  NBEdge::EDGEFUNCTION_SOURCE);
315  NBEdgeCont::insert(source); // !!! (in den Konstruktor)
316  SUMOReal percNormed =
317  c->myPercentages[(*k).first];
318  district->addSource(source, percNormed);
319  } else {
320  // build the connection to the destination
321  id = std::string("VissimToParkingplace")
322  + toString<int>((*k).first) + "-"
323  + toString<int>(c->myID);
324  NBEdge *destination =
325  new NBEdge(id, id, edgeend, districtNode,
326  "Connection", 100/3.6, 2, 100, 0,
327  NBEdge::EDGEFUNCTION_SINK);
328  NBEdgeCont::insert(destination); // !!! (in den Konstruktor)
329 
330  // add both the source and the sink to the district
331  SUMOReal percNormed =
332  c->myPercentages[(*k).first];
333  district->addSink(destination, percNormed);
334  }
335  }
336  */
337  }
338 }
339 
340 
341 
342 Position
345  return e->getGeomPosition(myPosition);
346 }
347 
348 
351  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
352  if ((*i).second->myEdgeID == edgeid) {
353  return (*i).second;
354  }
355  }
356  return 0;
357 }
358 
359 
360 void
362  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
363  delete(*i).second;
364  }
365  myDict.clear();
366 }
367 
368 
369 SUMOReal
370 NIVissimDistrictConnection::getMeanSpeed(/*NBDistribution &dc*/) const {
371  //assert(myAssignedVehicles.size()!=0);
372  if (myAssignedVehicles.size() == 0) {
373  WRITE_WARNING("No streams assigned at district'" + toString(myID) + "'.\n Using default speed 200km/h");
374  return (SUMOReal) 200 / (SUMOReal) 3.6;
375  }
376  SUMOReal speed = 0;
377  std::vector<std::pair<int, int> >::const_iterator i;
378  for (i = myAssignedVehicles.begin(); i != myAssignedVehicles.end(); i++) {
379  speed += getRealSpeed(/*dc, */(*i).second);
380  }
381  return speed / (SUMOReal) myAssignedVehicles.size();
382 }
383 
384 
385 SUMOReal
386 NIVissimDistrictConnection::getRealSpeed(/*NBDistribution &dc, */int distNo) const {
387  std::string id = toString<int>(distNo);
388  Distribution* dist = NBDistribution::dictionary("speed", id);
389  if (dist == 0) {
390  WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
391  WRITE_WARNING(". Using default.");
392  return OptionsCont::getOptions().getFloat("vissim.default-speed");
393  }
394  assert(dist != 0);
395  SUMOReal speed = dist->getMax();
396  if (speed < 0 || speed > 1000) {
397  WRITE_WARNING(" False speed at district '" + id);
398  WRITE_WARNING(". Using default.");
399  speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
400  }
401  return speed;
402 }
403 
404 
405 
406 /****************************************************************************/
407