Eclipse SUMO - Simulation of Urban MObility
MapMatcher.h
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 /****************************************************************************/
18 // Utility functions for matching locations to edges (during route parsing)
19 /****************************************************************************/
20 #pragma once
21 #include <config.h>
22 
25 #include "NamedRTree.h"
26 #include "SUMOVehicleClass.h"
27 #include "MsgHandler.h"
28 
29 #define JUNCTION_TAZ_MISSING_HELP "\nSet option '--junction-taz' or load a TAZ-file"
30 
31 // ===========================================================================
32 // class declarations
33 // ===========================================================================
34 
35 // ===========================================================================
36 // class definitions
37 // ===========================================================================
43 template<class E, class L, class N>
44 class MapMatcher {
45 protected:
46  MapMatcher(bool matchJunctions, double matchDistance, MsgHandler* errorOutput):
47  myLaneTree(nullptr),
48  myMapMatchJunctions(matchJunctions),
49  myMapMatchingDistance(matchDistance),
50  myErrorOutput(errorOutput) {}
51 
52  virtual ~MapMatcher() {
53  delete myLaneTree;
54  }
55 
56  void parseGeoEdges(const PositionVector& positions, bool geo, SUMOVehicleClass vClass,
57  std::vector<const E*>& into, const std::string& rid, bool isFrom, bool& ok) {
58  if (geo && !GeoConvHelper::getFinal().usingGeoProjection()) {
59  WRITE_ERROR(TL("Cannot convert geo-positions because the network has no geo-reference"));
60  return;
61  }
62  for (Position pos : positions) {
63  Position orig = pos;
64  if (geo) {
66  }
67  double dist = MIN2(10.0, myMapMatchingDistance);
68  const E* best = getClosestEdge(pos, dist, vClass);
69  while (best == nullptr && dist < myMapMatchingDistance) {
70  dist = MIN2(dist * 2, myMapMatchingDistance);
71  best = getClosestEdge(pos, dist, vClass);
72  }
73  if (best == nullptr) {
74  myErrorOutput->inform("No edge found near position " + toString(orig, geo ? gPrecisionGeo : gPrecision) + " within the route " + rid + ".");
75  ok = false;
76  } else {
77  if (myMapMatchJunctions) {
78  best = getJunctionTaz(pos, best, vClass, isFrom);
79  if (best != nullptr) {
80  into.push_back(best);
81  }
82  } else {
83  // handle multiple via locations on the same edge without loops
84  if (positions.size() == 1 || into.empty() || into.back() != best) {
85  into.push_back(best);
86  }
87  }
88  }
89  }
90  }
91 
92 
94  const E* getClosestEdge(const Position& pos, double distance, SUMOVehicleClass vClass) {
95  NamedRTree* t = getLaneTree();
96  Boundary b;
97  b.add(pos);
98  b.grow(distance);
99  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
100  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
101  std::set<const Named*> lanes;
102  Named::StoringVisitor sv(lanes);
103  t->Search(cmin, cmax, sv);
104  // use closest
105  double minDist = std::numeric_limits<double>::max();
106  const L* best = nullptr;
107  for (const Named* o : lanes) {
108  const L* cand = static_cast<const L*>(o);
109  if (!cand->allowsVehicleClass(vClass)) {
110  continue;
111  }
112  double dist = cand->getShape().distance2D(pos);
113  if (dist < minDist) {
114  minDist = dist;
115  best = cand;
116  }
117  }
118  if (best == nullptr) {
119  return nullptr;
120  } else {
121  const E* bestEdge = &best->getEdge();
122  while (bestEdge->isInternal()) {
123  bestEdge = bestEdge->getSuccessors().front();
124  }
125  return bestEdge;
126  }
127  }
128 
130  const E* getJunctionTaz(const Position& pos, const E* closestEdge, SUMOVehicleClass vClass, bool isFrom) {
131  if (closestEdge == nullptr) {
132  return nullptr;
133  } else {
134  const N* fromJunction = closestEdge->getFromJunction();
135  const N* toJunction = closestEdge->getToJunction();
136  const bool fromCloser = (fromJunction->getPosition().distanceSquaredTo2D(pos) <
137  toJunction->getPosition().distanceSquaredTo2D(pos));
138  const E* fromSource = retrieveEdge(fromJunction->getID() + "-source");
139  const E* fromSink = retrieveEdge(fromJunction->getID() + "-sink");
140  const E* toSource = retrieveEdge(toJunction->getID() + "-source");
141  const E* toSink = retrieveEdge(toJunction->getID() + "-sink");
142  if (fromSource == nullptr || fromSink == nullptr) {
143  myErrorOutput->inform("Junction-taz '" + fromJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
144  return nullptr;
145  }
146  if (toSource == nullptr || toSink == nullptr) {
147  myErrorOutput->inform("Junction-taz '" + toJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
148  return nullptr;
149  }
150  const bool fromPossible = isFrom ? fromSource->getSuccessors(vClass).size() > 0 : fromSink->getPredecessors().size() > 0;
151  const bool toPossible = isFrom ? toSource->getSuccessors(vClass).size() > 0 : toSink->getPredecessors().size() > 0;
152  //std::cout << "getJunctionTaz pos=" << pos << " isFrom=" << isFrom << " closest=" << closestEdge->getID() << " fromPossible=" << fromPossible << " toPossible=" << toPossible << "\n";
153  if (fromCloser && fromPossible) {
154  // return closest if possible
155  return isFrom ? fromSource : fromSink;
156  } else if (!fromCloser && toPossible) {
157  // return closest if possible
158  return isFrom ? toSource : toSink;
159  } else {
160  // return possible
161  if (fromPossible) {
162  return isFrom ? fromSource : fromSink;
163  } else {
164  return isFrom ? toSource : toSink;
165  }
166  }
167  }
168  }
169 
170 
171  virtual void initLaneTree(NamedRTree* tree) = 0;
172 
173  virtual E* retrieveEdge(const std::string& id) = 0;
174 
175 private:
178  if (myLaneTree == nullptr) {
179  myLaneTree = new NamedRTree();
181  }
182  return myLaneTree;
183  }
184 
190 
191 
192 private:
194  MapMatcher(const MapMatcher& s) = delete;
195 
197  MapMatcher& operator=(const MapMatcher& s) = delete;
198 };
#define JUNCTION_TAZ_MISSING_HELP
Definition: MapMatcher.h:29
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:26
int gPrecisionGeo
Definition: StdDefs.cpp:27
T MIN2(T a, T b)
Definition: StdDefs.h:76
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:130
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:118
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:319
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:136
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:124
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
Provides utility functions for matching locations to edges (during route parsing)
Definition: MapMatcher.h:44
double myMapMatchingDistance
Definition: MapMatcher.h:188
virtual E * retrieveEdge(const std::string &id)=0
bool myMapMatchJunctions
Definition: MapMatcher.h:187
MapMatcher(bool matchJunctions, double matchDistance, MsgHandler *errorOutput)
Definition: MapMatcher.h:46
const E * getClosestEdge(const Position &pos, double distance, SUMOVehicleClass vClass)
find closest edge within distance for the given position or nullptr
Definition: MapMatcher.h:94
virtual ~MapMatcher()
Definition: MapMatcher.h:52
void parseGeoEdges(const PositionVector &positions, bool geo, SUMOVehicleClass vClass, std::vector< const E * > &into, const std::string &rid, bool isFrom, bool &ok)
Definition: MapMatcher.h:56
MapMatcher & operator=(const MapMatcher &s)=delete
Invalidated assignment operator.
NamedRTree * getLaneTree()
initialize lane-RTree
Definition: MapMatcher.h:177
MapMatcher(const MapMatcher &s)=delete
Invalidated copy constructor.
const E * getJunctionTaz(const Position &pos, const E *closestEdge, SUMOVehicleClass vClass, bool isFrom)
find closest junction taz given the closest edge
Definition: MapMatcher.h:130
virtual void initLaneTree(NamedRTree *tree)=0
MsgHandler * myErrorOutput
Definition: MapMatcher.h:189
NamedRTree * myLaneTree
RTree for finding lanes.
Definition: MapMatcher.h:186
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:154
Allows to store the object; used as context while traveling the rtree in TraCI.
Definition: Named.h:90
Base class for objects which have an id.
Definition: Named.h:54
A RT-tree for efficient storing of SUMO's Named objects.
Definition: NamedRTree.h:61
int Search(const float a_min[2], const float a_max[2], const Named::StoringVisitor &c) const
Find all within search rectangle.
Definition: NamedRTree.h:112
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.