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 "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// ===========================================================================
43template<class E, class L, class N>
45protected:
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 }
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.) {
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
171private:
174 if (myLaneTree == nullptr) {
175 myLaneTree = new NamedRTree();
177 }
178 return myLaneTree;
179 }
180
186
187
188private:
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: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: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.
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
MapMatcher(const MapMatcher &s)=delete
Invalidated copy constructor.
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:126
MsgHandler * myErrorOutput
Definition MapMatcher.h:185
NamedRTree * myLaneTree
RTree for finding lanes.
Definition MapMatcher.h:182
NamedRTree * getLaneTree()
initialize lane-RTree
Definition MapMatcher.h:173
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.