Eclipse SUMO - Simulation of Urban MObility
NGNet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2003-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // The class storing the generated network
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <iostream>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <cmath>
31 #include <netbuild/NBNode.h>
32 #include <netbuild/NBNodeCont.h>
33 #include <netbuild/NBEdge.h>
34 #include <netbuild/NBEdgeCont.h>
35 #include <netbuild/NBNetBuilder.h>
36 #include <utils/common/ToString.h>
41 #include "NGNet.h"
42 
43 
44 // ===========================================================================
45 // method definitions
46 // ===========================================================================
48  myLastID(0),
49  myAlphaIDs(OptionsCont::getOptions().getBool("alphanumerical-ids")),
50  myNetBuilder(nb) {
51 }
52 
53 
55  for (NGEdgeList::iterator ni = myEdgeList.begin(); ni != myEdgeList.end(); ++ni) {
56  delete *ni;
57  }
58  for (NGNodeList::iterator ni = myNodeList.begin(); ni != myNodeList.end(); ++ni) {
59  delete *ni;
60  }
61 }
62 
63 
64 std::string
66  return toString<int>(++myLastID);
67 }
68 
69 
70 NGNode*
71 NGNet::findNode(int xID, int yID) {
72  for (NGNodeList::iterator ni = myNodeList.begin(); ni != myNodeList.end(); ++ni) {
73  if ((*ni)->samePos(xID, yID)) {
74  return *ni;
75  }
76  }
77  return nullptr;
78 }
79 
80 std::string
81 NGNet::alphabeticalCode(int i, int iMax) {
82  // lazy mans 26th root to determine number of characters for x-label
83  int xn = 1;
84  for (; std::pow(26, xn) < iMax; xn++) {};
85  std::string result = "";
86  for (int j = 0; j < xn; j++) {
87  result = char('A' + (i % 26)) + result;
88  i /= 26;
89  }
90  return result;
91 }
92 
93 void
94 NGNet::createChequerBoard(int numX, int numY, double spaceX, double spaceY, double attachLength) {
95 
96  for (int ix = 0; ix < numX; ix++) {
97  const std::string nodeIDStart = (myAlphaIDs ? alphabeticalCode(ix, numX) : toString<int>(ix) + "/");
98  for (int iy = 0; iy < numY; iy++) {
99  // create Node
100  NGNode* node = new NGNode(nodeIDStart + toString(iy), ix, iy);
101  node->setX(ix * spaceX + attachLength);
102  node->setY(iy * spaceY + attachLength);
103  myNodeList.push_back(node);
104  // create Links
105  if (ix > 0) {
106  connect(node, findNode(ix - 1, iy));
107  }
108  if (iy > 0) {
109  connect(node, findNode(ix, iy - 1));
110  }
111  }
112  }
113  if (attachLength > 0.0) {
114  for (int ix = 0; ix < numX; ix++) {
115  // create nodes
116  NGNode* topNode = new NGNode("top" + toString<int>(ix), ix, numY);
117  NGNode* bottomNode = new NGNode("bottom" + toString<int>(ix), ix, numY + 1);
118  topNode->setX(ix * spaceX + attachLength);
119  bottomNode->setX(ix * spaceX + attachLength);
120  topNode->setY((numY - 1) * spaceY + 2 * attachLength);
121  bottomNode->setY(0);
122  myNodeList.push_back(topNode);
123  myNodeList.push_back(bottomNode);
124  // create links
125  connect(topNode, findNode(ix, numY - 1));
126  connect(bottomNode, findNode(ix, 0));
127  }
128  for (int iy = 0; iy < numY; iy++) {
129  // create nodes
130  NGNode* leftNode = new NGNode("left" + toString<int>(iy), numX, iy);
131  NGNode* rightNode = new NGNode("right" + toString<int>(iy), numX + 1, iy);
132  leftNode->setX(0);
133  rightNode->setX((numX - 1) * spaceX + 2 * attachLength);
134  leftNode->setY(iy * spaceY + attachLength);
135  rightNode->setY(iy * spaceY + attachLength);
136  myNodeList.push_back(leftNode);
137  myNodeList.push_back(rightNode);
138  // create links
139  connect(leftNode, findNode(0, iy));
140  connect(rightNode, findNode(numX - 1, iy));
141  }
142  }
143 }
144 
145 
146 double
147 NGNet::radialToX(double radius, double phi) {
148  return cos(phi) * radius;
149 }
150 
151 
152 double
153 NGNet::radialToY(double radius, double phi) {
154  return sin(phi) * radius;
155 }
156 
157 
158 void
159 NGNet::createSpiderWeb(int numRadDiv, int numCircles, double spaceRad, bool hasCenter) {
160  if (numRadDiv < 3) {
161  numRadDiv = 3;
162  }
163  if (numCircles < 1) {
164  numCircles = 1;
165  }
166 
167  int ir, ic;
168  double angle = (double)(2 * M_PI / numRadDiv); // angle between radial divisions
169  NGNode* Node;
170  for (ic = 1; ic < numCircles + 1; ic++) {
171  const std::string nodeIDStart = alphabeticalCode(ic, numCircles);
172  for (ir = 1; ir < numRadDiv + 1; ir++) {
173  // create Node
174  const std::string nodeID = (myAlphaIDs ?
175  nodeIDStart + toString<int>(ir) :
176  toString<int>(ir) + "/" + toString<int>(ic));
177  Node = new NGNode(nodeID, ir, ic);
178  Node->setX(radialToX((ic) * spaceRad, (ir - 1) * angle));
179  Node->setY(radialToY((ic) * spaceRad, (ir - 1) * angle));
180  myNodeList.push_back(Node);
181  // create Links
182  if (ir > 1) {
183  connect(Node, findNode(ir - 1, ic));
184  }
185  if (ic > 1) {
186  connect(Node, findNode(ir, ic - 1));
187  }
188  if (ir == numRadDiv) {
189  connect(Node, findNode(1, ic));
190  }
191  }
192  }
193  if (hasCenter) {
194  // node
195  Node = new NGNode(myAlphaIDs ? "A1" : "1", 0, 0, true);
196  Node->setX(0);
197  Node->setY(0);
198  myNodeList.push_back(Node);
199  // links
200  for (ir = 1; ir < numRadDiv + 1; ir++) {
201  connect(Node, findNode(ir, 1));
202  }
203  }
204 }
205 
206 
207 void
208 NGNet::connect(NGNode* node1, NGNode* node2) {
209  std::string id1 = node1->getID() + (myAlphaIDs ? "" : "to") + node2->getID();
210  std::string id2 = node2->getID() + (myAlphaIDs ? "" : "to") + node1->getID();
211  NGEdge* link1 = new NGEdge(id1, node1, node2);
212  NGEdge* link2 = new NGEdge(id2, node2, node1);
213  myEdgeList.push_back(link1);
214  myEdgeList.push_back(link2);
215 }
216 
218 NGNet::getDistribution(const std::string& option) {
219  std::string val = OptionsCont::getOptions().getString(option);
220  try {
221  return Distribution_Parameterized("peturb", 0, StringUtils::toDouble(val));
222  } catch (NumberFormatException) {
223  Distribution_Parameterized result("perturb", 0, 0);
224  result.parse(val, true);
225  return result;
226  }
227 }
228 
229 void
230 NGNet::toNB() const {
231  Distribution_Parameterized perturbx = getDistribution("perturb-x");
232  Distribution_Parameterized perturby = getDistribution("perturb-y");
233  Distribution_Parameterized perturbz = getDistribution("perturb-z");
234  std::vector<NBNode*> nodes;
235  for (NGNodeList::const_iterator i1 = myNodeList.begin(); i1 != myNodeList.end(); i1++) {
236  Position perturb(
237  perturbx.sample(),
238  perturby.sample(),
239  perturbz.sample());
240  NBNode* node = (*i1)->buildNBNode(myNetBuilder, perturb);
241  nodes.push_back(node);
243  }
244  const std::string type = OptionsCont::getOptions().getString("default.type");
245  for (NGEdgeList::const_iterator i2 = myEdgeList.begin(); i2 != myEdgeList.end(); i2++) {
246  NBEdge* edge = (*i2)->buildNBEdge(myNetBuilder, type);
248  }
249  // now, let's append the reverse directions...
250  double bidiProb = OptionsCont::getOptions().getFloat("rand.bidi-probability");
251  for (std::vector<NBNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
252  NBNode* node = *i;
253  for (NBEdge* e : node->getIncomingEdges()) {
254  if (node->getConnectionTo(e->getFromNode()) == nullptr && RandHelper::rand() <= bidiProb) {
255  NBEdge* back = new NBEdge("-" + e->getID(), node, e->getFromNode(),
257  e->getNumLanes(),
258  e->getPriority(),
261  }
262  }
263  }
264  // add splits depending on turn-lane options
265  const int turnLanes = OptionsCont::getOptions().getInt("turn-lanes");
266  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
267  if (turnLanes > 0) {
268  const double turnLaneLength = OptionsCont::getOptions().getFloat("turn-lanes.length");
270  EdgeVector allEdges;
271  for (auto it = ec.begin(); it != ec.end(); ++it) {
272  allEdges.push_back(it->second);
273  }
274  for (NBEdge* e : allEdges) {
275  if (e->getToNode()->geometryLike()) {
276  continue;
277  }
278  std::vector<NBEdgeCont::Split> splits;
280  for (int i = 0; i < e->getNumLanes() + turnLanes; ++i) {
281  split.lanes.push_back(i);
282  }
283  split.pos = MAX2(0.0, e->getLength() - turnLaneLength);
284  split.speed = e->getSpeed();
285  split.node = new NBNode(e->getID() + "." + toString(split.pos), e->getGeometry().positionAtOffset(split.pos));
286  split.idBefore = e->getID();
287  split.idAfter = split.node->getID();
288  split.offsetFactor = lefthand ? -1 : 1;
289  if (turnLaneLength <= e->getLength() / 2) {
290  split.offset = -0.5 * split.offsetFactor * turnLanes * e->getLaneWidth(0);
291  if (e->getFromNode()->geometryLike()) {
292  // shift the reverse direction explicitly as it will not get a turn lane
293  NBEdge* reverse = nullptr;
294  for (NBEdge* reverseCand : e->getFromNode()->getIncomingEdges()) {
295  if (reverseCand->getFromNode() == e->getToNode()) {
296  reverse = reverseCand;
297  }
298  }
299  if (reverse != nullptr) {
300  PositionVector g = reverse->getGeometry();
301  g.move2side(-split.offset);
302  reverse->setGeometry(g);
303  }
304  }
305  }
306  splits.push_back(split);
307  ec.processSplits(e, splits,
311  }
312  }
313 }
314 
315 
316 void
318  myNodeList.push_back(node);
319 }
320 
321 
322 void
324  myEdgeList.push_back(edge);
325 }
326 
327 
328 int
329 NGNet::nodeNo() const {
330  return (int)myNodeList.size();
331 }
332 
333 
334 /****************************************************************************/
335 
NBEdge::UNSPECIFIED_OFFSET
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:318
NGNet::createChequerBoard
void createChequerBoard(int numX, int numY, double spaceX, double spaceY, double attachLength)
Creates a grid network.
Definition: NGNet.cpp:94
Distribution_Parameterized
Definition: Distribution_Parameterized.h:42
OptionsCont::getInt
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
Definition: OptionsCont.cpp:215
ToString.h
NGNet::toNB
void toNB() const
Converts the stored network into its netbuilder-representation.
Definition: NGNet.cpp:230
NBEdgeCont
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:60
NBNetBuilder
Instance responsible for building networks.
Definition: NBNetBuilder.h:109
Distribution_Parameterized::sample
double sample(std::mt19937 *which=0) const
Draw a sample of the distribution.
Definition: Distribution_Parameterized.cpp:84
OptionsCont.h
NBNode::getConnectionTo
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
Definition: NBNode.cpp:2158
StringUtils::toDouble
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
Definition: StringUtils.cpp:345
EdgeVector
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
NBNodeCont::insert
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:78
NGNet::getNextFreeID
std::string getNextFreeID()
Returns the next free id.
Definition: NGNet.cpp:65
OptionsCont::getString
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
Definition: OptionsCont.cpp:201
NGNet::myNodeList
NGNodeList myNodeList
The list of nodes.
Definition: NGNet.h:211
NBEdgeCont::processSplits
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
Definition: NBEdgeCont.cpp:412
NBEdgeCont.h
NGEdge
A netgen-representation of an edge.
Definition: NGEdge.h:54
NGNet::radialToX
double radialToX(double radius, double phi)
Returns the x-position resulting from the given radius and angle.
Definition: NGNet.cpp:147
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:222
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
NGNet::alphabeticalCode
std::string alphabeticalCode(int i, int iMax)
return a letter code for the given integer index
Definition: NGNet.cpp:81
NBEdgeCont::insert
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:153
PositionVector
A list of positions.
Definition: PositionVector.h:45
NGNet::myAlphaIDs
const bool myAlphaIDs
Whether to use alphanumericalIDs.
Definition: NGNet.h:205
NBNetBuilder::getEdgeCont
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:150
NBEdge
The representation of a single edge during network building.
Definition: NBEdge.h:91
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
NumberFormatException
Definition: UtilExceptions.h:95
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
NGNet::createSpiderWeb
void createSpiderWeb(int numRadDiv, int numCircles, double spaceRad, bool hasCenter)
Creates a spider network.
Definition: NGNet.cpp:159
NBEdge::getGeometry
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:692
NGNet::findNode
NGNode * findNode(int xPos, int yPos)
Returns the node at the given position.
Definition: NGNet.cpp:71
NGNet::myLastID
int myLastID
The last ID given to node or link.
Definition: NGNet.h:202
NBTypeCont::getSpeed
double getSpeed(const std::string &type) const
Returns the maximal velocity for the given type [m/s].
Definition: NBTypeCont.cpp:177
NBNetBuilder.h
NGNet::myEdgeList
NGEdgeList myEdgeList
The list of links.
Definition: NGNet.h:214
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
NGNet::nodeNo
int nodeNo() const
Returns the number of stored nodes.
Definition: NGNet.cpp:329
OptionsCont
A storage for options typed value containers)
Definition: OptionsCont.h:89
NBEdgeCont::end
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:192
split
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition: MSSOTLE2Sensors.cpp:488
Distribution_Parameterized.h
NGNet::getDistribution
static Distribution_Parameterized getDistribution(const std::string &option)
get distribution from option
Definition: NGNet.cpp:218
OptionsCont::getFloat
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Definition: OptionsCont.cpp:208
NBNodeCont.h
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
StringUtils.h
NGNet::radialToY
double radialToY(double radius, double phi)
Returns the y-position resulting from the given radius and angle.
Definition: NGNet.cpp:153
M_PI
#define M_PI
Definition: odrSpiral.cpp:40
NBNetBuilder::getTLLogicCont
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Definition: NBNetBuilder.h:165
NBNode::getIncomingEdges
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition: NBNode.h:255
NBTypeCont::getWidth
double getWidth(const std::string &type) const
Returns the lane width for the given type [m].
Definition: NBTypeCont.cpp:227
NBNetBuilder::getDistrictCont
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:170
NGNet::~NGNet
~NGNet()
Destructor.
Definition: NGNet.cpp:54
config.h
NGNet::connect
void connect(NGNode *node1, NGNode *node2)
Connects both nodes with two edges, one for each direction.
Definition: NGNet.cpp:208
RandHelper.h
NGNet::myNetBuilder
NBNetBuilder & myNetBuilder
The builder used to build NB*-structures.
Definition: NGNet.h:208
NGNet::NGNet
NGNet(NBNetBuilder &nb)
Constructor.
Definition: NGNet.cpp:47
Distribution_Parameterized::parse
void parse(const std::string &description, const bool hardFail)
Overwrite by parsable distribution description.
Definition: Distribution_Parameterized.cpp:57
NBNode
Represents a single node (junction) during network building.
Definition: NBNode.h:67
NGNet::add
void add(NGNode *node)
Adds the given node to the network.
Definition: NGNet.cpp:317
NBNetBuilder::getNodeCont
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:155
NBNetBuilder::getTypeCont
NBTypeCont & getTypeCont()
Returns a reference to the type container.
Definition: NBNetBuilder.h:160
NBNode.h
NGNode::setY
void setY(double y)
Sets a new value for y-position.
Definition: NGNode.h:122
NBEdgeCont::Split
A structure which describes changes of lane number or speed along the road.
Definition: NBEdgeCont.h:205
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
NBEdgeCont::begin
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:184
NBEdge::getFromNode
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:491
NGNode
A netgen-representation of a node.
Definition: NGNode.h:50
NGNet.h
NBEdge::setGeometry
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
Definition: NBEdge.cpp:582
PositionVector::move2side
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
Definition: PositionVector.cpp:1103
NBEdge.h
NGNode::setX
void setX(double x)
Sets a new value for x-position.
Definition: NGNode.h:113