Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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>
30#include <utils/geom/Position.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// ===========================================================================
51std::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
79bool
80NIVissimDistrictConnection::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
95bool
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
115void
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
129void
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
141void
147
148
149void
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
180void
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
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
347void
349 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
350 delete (*i).second;
351 }
352 myDict.clear();
353}
354
355
356double
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
372double
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.
bool addSource(NBEdge *const source, double weight)
Adds a source.
void setCenter(const Position &pos)
Sets the center coordinates.
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.
NBEdge * retrievePossiblySplit(const std::string &id, bool downstream) const
Tries to retrieve an edge, even if it is splitted.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
The representation of a single edge during network building.
Definition NBEdge.h:92
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:546
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition NBEdge.h:355
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition NBEdge.h:539
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition NBEdge.h:349
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.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
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.
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.
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.