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.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