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 L* best = getClosestLane(pos, vClass, dist);
69  while (best == nullptr && dist < myMapMatchingDistance) {
70  dist = MIN2(dist * 2, myMapMatchingDistance);
71  best = getClosestLane(pos, vClass, dist);
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  const E* bestEdge = &best->getEdge();
78  while (bestEdge->isInternal()) {
79  bestEdge = bestEdge->getSuccessors().front();
80  }
81  if (myMapMatchJunctions) {
82  bestEdge = getJunctionTaz(pos, bestEdge, vClass, isFrom);
83  if (bestEdge != nullptr) {
84  into.push_back(bestEdge);
85  }
86  } else {
87  // handle multiple via locations on the same edge without loops
88  if (positions.size() == 1 || into.empty() || into.back() != bestEdge) {
89  into.push_back(bestEdge);
90  }
91  }
92  }
93  }
94  }
95 
96 
98  const L* getClosestLane(const Position& pos, SUMOVehicleClass vClass, double distance = -1.) {
99  NamedRTree* t = getLaneTree();
100  Boundary b;
101  b.add(pos);
102  b.grow(distance < 0 ? myMapMatchingDistance : distance);
103  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
104  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
105  std::set<const Named*> lanes;
106  Named::StoringVisitor sv(lanes);
107  t->Search(cmin, cmax, sv);
108  // use closest
109  double minDist = std::numeric_limits<double>::max();
110  const L* best = nullptr;
111  for (const Named* o : lanes) {
112  const L* cand = static_cast<const L*>(o);
113  if (!cand->allowsVehicleClass(vClass)) {
114  continue;
115  }
116  double dist = cand->getShape().distance2D(pos);
117  if (dist < minDist) {
118  minDist = dist;
119  best = cand;
120  }
121  }
122  return best;
123  }
124 
126  const E* getJunctionTaz(const Position& pos, const E* closestEdge, SUMOVehicleClass vClass, bool isFrom) {
127  if (closestEdge == nullptr) {
128  return nullptr;
129  } else {
130  const N* fromJunction = closestEdge->getFromJunction();
131  const N* toJunction = closestEdge->getToJunction();
132  const bool fromCloser = (fromJunction->getPosition().distanceSquaredTo2D(pos) <
133  toJunction->getPosition().distanceSquaredTo2D(pos));
134  const E* fromSource = retrieveEdge(fromJunction->getID() + "-source");
135  const E* fromSink = retrieveEdge(fromJunction->getID() + "-sink");
136  const E* toSource = retrieveEdge(toJunction->getID() + "-source");
137  const E* toSink = retrieveEdge(toJunction->getID() + "-sink");
138  if (fromSource == nullptr || fromSink == nullptr) {
139  myErrorOutput->inform("Junction-taz '" + fromJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
140  return nullptr;
141  }
142  if (toSource == nullptr || toSink == nullptr) {
143  myErrorOutput->inform("Junction-taz '" + toJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
144  return nullptr;
145  }
146  const bool fromPossible = isFrom ? fromSource->getSuccessors(vClass).size() > 0 : fromSink->getPredecessors().size() > 0;
147  const bool toPossible = isFrom ? toSource->getSuccessors(vClass).size() > 0 : toSink->getPredecessors().size() > 0;
148  //std::cout << "getJunctionTaz pos=" << pos << " isFrom=" << isFrom << " closest=" << closestEdge->getID() << " fromPossible=" << fromPossible << " toPossible=" << toPossible << "\n";
149  if (fromCloser && fromPossible) {
150  // return closest if possible
151  return isFrom ? fromSource : fromSink;
152  } else if (!fromCloser && toPossible) {
153  // return closest if possible
154  return isFrom ? toSource : toSink;
155  } else {
156  // return possible
157  if (fromPossible) {
158  return isFrom ? fromSource : fromSink;
159  } else {
160  return isFrom ? toSource : toSink;
161  }
162  }
163  }
164  }
165 
166 
167  virtual void initLaneTree(NamedRTree* tree) = 0;
168 
169  virtual E* retrieveEdge(const std::string& id) = 0;
170 
171 private:
174  if (myLaneTree == nullptr) {
175  myLaneTree = new NamedRTree();
177  }
178  return myLaneTree;
179  }
180 
186 
187 
188 private:
190  MapMatcher(const MapMatcher& s) = delete;
191 
193  MapMatcher& operator=(const MapMatcher& s) = delete;
194 };
#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:184
virtual E * retrieveEdge(const std::string &id)=0
bool myMapMatchJunctions
Definition: MapMatcher.h:183
MapMatcher(bool matchJunctions, double matchDistance, MsgHandler *errorOutput)
Definition: MapMatcher.h:46
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:173
MapMatcher(const MapMatcher &s)=delete
Invalidated copy constructor.
const L * getClosestLane(const Position &pos, SUMOVehicleClass vClass, double distance=-1.)
find closest lane within distance for the given position or nullptr
Definition: MapMatcher.h:98
const E * getJunctionTaz(const Position &pos, const E *closestEdge, SUMOVehicleClass vClass, bool isFrom)
find closest junction taz given the closest edge
Definition: MapMatcher.h:126
virtual void initLaneTree(NamedRTree *tree)=0
MsgHandler * myErrorOutput
Definition: MapMatcher.h:185
NamedRTree * myLaneTree
RTree for finding lanes.
Definition: MapMatcher.h:182
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.