Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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 "RandHelper.h"
27#include "SUMOVehicleClass.h"
28#include "MsgHandler.h"
29
30#define JUNCTION_TAZ_MISSING_HELP "\nSet option '--junction-taz' or load a TAZ-file"
31
32// ===========================================================================
33// class declarations
34// ===========================================================================
35
36// ===========================================================================
37// class definitions
38// ===========================================================================
44template<class E, class L, class N>
46protected:
47 MapMatcher(bool matchJunctions, bool matchTAZ, double matchDistance, MsgHandler* errorOutput):
48 myMapMatchTAZ(matchTAZ),
49 myLaneTree(nullptr),
50 myMapMatchJunctions(matchJunctions),
51 myMapMatchingDistance(matchDistance),
52 myErrorOutput(errorOutput) {}
53
54 virtual ~MapMatcher() {
55 delete myLaneTree;
56 }
57
58 void parseGeoEdges(const PositionVector& positions, bool geo, SUMOVehicleClass vClass,
59 std::vector<const E*>& into, const std::string& rid, bool isFrom, bool& ok, bool forceEdge = false) {
60 if (geo && !GeoConvHelper::getFinal().usingGeoProjection()) {
61 WRITE_ERROR(TL("Cannot convert geo-positions because the network has no geo-reference"));
62 ok = false;
63 return;
64 }
65 for (Position pos : positions) {
66 Position orig = pos;
67 if (geo) {
69 }
70 double dist = MIN2(10.0, myMapMatchingDistance);
71 const L* best = getClosestLane(pos, vClass, dist);
72 while (best == nullptr && dist < myMapMatchingDistance) {
73 dist = MIN2(dist * 2, myMapMatchingDistance);
74 best = getClosestLane(pos, vClass, dist);
75 }
76 if (best == nullptr) {
77 myErrorOutput->inform("No edge found near position " + toString(orig, geo ? gPrecisionGeo : gPrecision) + " within the route " + rid + ".");
78 ok = false;
79 } else {
80 const E* bestEdge = &best->getEdge();
81 while (bestEdge->isInternal()) {
82 bestEdge = bestEdge->getSuccessors().front();
83 }
84 if ((myMapMatchJunctions || myMapMatchTAZ) && !forceEdge) {
85 if (myMapMatchTAZ) {
86 bestEdge = getTaz(pos, bestEdge, isFrom);
87 } else {
88 bestEdge = getJunctionTaz(pos, bestEdge, vClass, isFrom);
89 }
90 if (bestEdge != nullptr) {
91 into.push_back(bestEdge);
92 } else {
93 ok = false;
94 }
95 } else {
96 // handle multiple via locations on the same edge without loops
97 if (positions.size() == 1 || into.empty() || into.back() != bestEdge) {
98 into.push_back(bestEdge);
99 }
100 }
101 }
102 }
103 }
104
105
107 const L* getClosestLane(const Position& pos, SUMOVehicleClass vClass, double distance = -1.) {
108 NamedRTree* t = getLaneTree();
109 Boundary b;
110 b.add(pos);
111 b.grow(distance < 0 ? myMapMatchingDistance : distance);
112 const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
113 const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
114 std::set<const Named*> lanes;
115 Named::StoringVisitor sv(lanes);
116 t->Search(cmin, cmax, sv);
117 // use closest
118 double minDist = std::numeric_limits<double>::max();
119 const L* best = nullptr;
120 for (const Named* o : lanes) {
121 const L* cand = static_cast<const L*>(o);
122 if (!cand->allowsVehicleClass(vClass)) {
123 continue;
124 }
125 double dist = cand->getShape().distance2D(pos);
126 if (dist < minDist) {
127 minDist = dist;
128 best = cand;
129 }
130 }
131 return best;
132 }
133
135 const E* getJunctionTaz(const Position& pos, const E* closestEdge, SUMOVehicleClass vClass, bool isFrom) {
136 if (closestEdge == nullptr) {
137 return nullptr;
138 } else {
139 const N* fromJunction = closestEdge->getFromJunction();
140 const N* toJunction = closestEdge->getToJunction();
141 const bool fromCloser = (fromJunction->getPosition().distanceSquaredTo2D(pos) <
142 toJunction->getPosition().distanceSquaredTo2D(pos));
143 const E* fromSource = retrieveEdge(fromJunction->getID() + "-source");
144 const E* fromSink = retrieveEdge(fromJunction->getID() + "-sink");
145 const E* toSource = retrieveEdge(toJunction->getID() + "-source");
146 const E* toSink = retrieveEdge(toJunction->getID() + "-sink");
147 if (fromSource == nullptr || fromSink == nullptr) {
148 myErrorOutput->inform("Junction-taz '" + fromJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
149 return nullptr;
150 }
151 if (toSource == nullptr || toSink == nullptr) {
152 myErrorOutput->inform("Junction-taz '" + toJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
153 return nullptr;
154 }
155 const bool fromPossible = isFrom ? fromSource->getSuccessors(vClass).size() > 0 : fromSink->getPredecessors().size() > 0;
156 const bool toPossible = isFrom ? toSource->getSuccessors(vClass).size() > 0 : toSink->getPredecessors().size() > 0;
157 //std::cout << "getJunctionTaz pos=" << pos << " isFrom=" << isFrom << " closest=" << closestEdge->getID() << " fromPossible=" << fromPossible << " toPossible=" << toPossible << "\n";
158 if (fromCloser && fromPossible) {
159 // return closest if possible
160 return isFrom ? fromSource : fromSink;
161 } else if (!fromCloser && toPossible) {
162 // return closest if possible
163 return isFrom ? toSource : toSink;
164 } else {
165 // return possible
166 if (fromPossible) {
167 return isFrom ? fromSource : fromSink;
168 } else {
169 return isFrom ? toSource : toSink;
170 }
171 }
172 }
173 }
174
176 const E* getTaz(const Position& pos, const E* closestEdge, bool isFrom) {
177 if (closestEdge == nullptr) {
178 return nullptr;
179 } else {
180 std::vector<const E*> cands;
181 if (isFrom) {
182 for (const E* e : closestEdge->getPredecessors()) {
183 if (e->isTazConnector()) {
184 cands.push_back(e);
185 }
186 }
187 } else {
188 for (const E* e : closestEdge->getSuccessors()) {
189 if (e->isTazConnector()) {
190 cands.push_back(e);
191 }
192 }
193 }
194 if (cands.size() == 0) {
195 myErrorOutput->inform("Taz for edge '" + closestEdge->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
196 return nullptr;
197 }
198 if (cands.size() > 1) {
199 return cands[RandHelper::rand((int)cands.size(), getRNG())];
200 } else {
201 return cands.front();
202 }
203 }
204 }
205
206 virtual SumoRNG* getRNG() {
207 return nullptr;
208 }
209
210 virtual void initLaneTree(NamedRTree* tree) = 0;
211
212 virtual E* retrieveEdge(const std::string& id) = 0;
213
215
216private:
219 if (myLaneTree == nullptr) {
220 myLaneTree = new NamedRTree();
222 }
223 return myLaneTree;
224 }
225
231
232
233private:
235 MapMatcher(const MapMatcher& s) = delete;
236
238 MapMatcher& operator=(const MapMatcher& s) = delete;
239};
#define JUNCTION_TAZ_MISSING_HELP
Definition MapMatcher.h:30
#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:343
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:45
double myMapMatchingDistance
Definition MapMatcher.h:229
virtual E * retrieveEdge(const std::string &id)=0
bool myMapMatchJunctions
Definition MapMatcher.h:228
virtual ~MapMatcher()
Definition MapMatcher.h:54
MapMatcher & operator=(const MapMatcher &s)=delete
Invalidated assignment operator.
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:107
virtual SumoRNG * getRNG()
Definition MapMatcher.h:206
MapMatcher(bool matchJunctions, bool matchTAZ, double matchDistance, MsgHandler *errorOutput)
Definition MapMatcher.h:47
MapMatcher(const MapMatcher &s)=delete
Invalidated copy constructor.
bool myMapMatchTAZ
Definition MapMatcher.h:214
virtual void initLaneTree(NamedRTree *tree)=0
const E * getJunctionTaz(const Position &pos, const E *closestEdge, SUMOVehicleClass vClass, bool isFrom)
find closest junction taz given the closest edge
Definition MapMatcher.h:135
void parseGeoEdges(const PositionVector &positions, bool geo, SUMOVehicleClass vClass, std::vector< const E * > &into, const std::string &rid, bool isFrom, bool &ok, bool forceEdge=false)
Definition MapMatcher.h:58
MsgHandler * myErrorOutput
Definition MapMatcher.h:230
NamedRTree * myLaneTree
RTree for finding lanes.
Definition MapMatcher.h:227
const E * getTaz(const Position &pos, const E *closestEdge, bool isFrom)
find closest junction taz given the closest edge
Definition MapMatcher.h:176
NamedRTree * getLaneTree()
initialize lane-RTree
Definition MapMatcher.h:218
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
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.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)