13 return !lhs.expired() && !rhs.expired() && lhs.lock() == rhs.lock();
20 auto parameterIt = parameters.find(role);
21 if (parameterIt == parameters.end()) {
24 auto& parameter = parameterIt->second;
26 if (it == parameter.end()) {
30 if (parameter.empty()) {
31 parameters.erase(parameterIt);
37 Optional<T> tryGetFront(
const std::vector<T>& vec) {
45 RuleParameters toRuleParameters(
const std::vector<T>& primitives) {
50 RuleParameters toRuleParameters(
const std::vector<LineStringOrPolygon3d>& primitives) {
51 return utils::transform(primitives, [](
const auto& elem) {
return elem.asRuleParameter(); });
55 auto params = paramsMap.find(role);
56 if (params == paramsMap.end()) {
61 for (
const auto& param : params->second) {
62 const auto* l = boost::get<LineString3d>(¶m);
66 const auto*
p = boost::get<Polygon3d>(¶m);
76 [](
auto& lsOrPoly) {
return static_cast<ConstLineStringOrPolygon3d
>(lsOrPoly); });
79 void updateTrafficSigns(TrafficSignsWithType trafficSigns) {
80 if (!trafficSigns.type.empty()) {
81 for (
auto& sign : trafficSigns.trafficSigns) {
82 sign.applyVisitor([](
auto prim) { prim.setAttribute(AttributeName::Type, AttributeValueString::TrafficSign); });
83 sign.applyVisitor([&](
auto prim) { prim.setAttribute(AttributeName::Subtype, trafficSigns.type); });
90 const Optional<LineString3d>& stopLine) {
91 RuleParameterMap rpm = {{RoleNameString::Refers, toRuleParameters(trafficLights)}};
93 rpm.
insert({RoleNameString::RefLine, {*stopLine}});
95 auto data = std::make_shared<RegulatoryElementData>(
id, std::move(rpm), attributes);
96 data->attributes[AttributeName::Type] = AttributeValueString::RegulatoryElement;
97 data->attributes[AttributeName::Subtype] = AttributeValueString::TrafficLight;
101 const TrafficSignsWithType& trafficSigns,
102 const TrafficSignsWithType& cancellingTrafficSigns,
104 updateTrafficSigns(trafficSigns);
105 updateTrafficSigns(cancellingTrafficSigns);
106 RuleParameterMap rpm = {{RoleNameString::Refers, toRuleParameters(trafficSigns.trafficSigns)},
107 {RoleNameString::Cancels, toRuleParameters(cancellingTrafficSigns.trafficSigns)},
108 {RoleNameString::RefLine, toRuleParameters(refLines)},
109 {RoleNameString::CancelLine, toRuleParameters(cancelLines)}};
110 auto data = std::make_shared<RegulatoryElementData>(
id, std::move(rpm), attributes);
111 data->attributes[AttributeName::Type] = AttributeValueString::RegulatoryElement;
112 data->attributes[AttributeName::Subtype] = AttributeValueString::TrafficSign;
116 const TrafficSignsWithType& trafficSigns,
117 const TrafficSignsWithType& cancellingTrafficSigns,
119 auto data = constructTrafficSignData(
id, attributes, trafficSigns, cancellingTrafficSigns, refLines, cancelLines);
120 data->attributes[AttributeName::Subtype] = AttributeValueString::SpeedLimit;
124 const Lanelets& yield,
const Optional<LineString3d>& stopLine) {
125 RuleParameterMap rpm = {{RoleNameString::RightOfWay, toRuleParameters(rightOfWay)},
126 {RoleNameString::Yield, toRuleParameters(yield)}};
127 auto data = std::make_shared<RegulatoryElementData>(
id, std::move(rpm), attributes);
128 data->attributes[AttributeName::Type] = AttributeValueString::RegulatoryElement;
129 data->attributes[AttributeName::Subtype] = AttributeValueString::RightOfWay;
131 data->parameters[RoleName::RefLine] = {*stopLine};
140 auto sl = utils::createReserved<RuleParameters>(lltWithStop.size());
142 if (!!stop.stopLine) {
143 sl.push_back(static_cast<RuleParameter>(*stop.stopLine));
147 {RoleNameString::Yield, llts}, {RoleNameString::RefLine, sl}, {RoleNameString::Refers, toRuleParameters(signs)}};
148 auto data = std::make_shared<RegulatoryElementData>(
id, std::move(rpm), attributes);
149 data->attributes[AttributeName::Type] = AttributeValueString::RegulatoryElement;
150 data->attributes[AttributeName::Subtype] = AttributeValueString::AllWayStop;
160 #if __cplusplus < 201703L 161 constexpr
char TrafficLight::RuleName[];
162 constexpr
char RightOfWay::RuleName[];
163 constexpr
char TrafficSign::RuleName[];
164 constexpr
char SpeedLimit::RuleName[];
165 constexpr
char AllWayStop::RuleName[];
179 :
TrafficLight(constructTrafficLightData(id, attributes, trafficLights, stopLine)) {}
207 throw InvalidInputError(
"A maneuver must refer to at least one lanelet that has right of way!");
210 throw InvalidInputError(
"A maneuver must refer to at least one lanelet that has to yield!");
216 :
RightOfWay(constructRightOfWayData(id, attributes, rightOfWay, yield, stopLine)) {}
278 constructTrafficSignData(id, attributes, trafficSigns, cancellingTrafficSigns, refLines, cancelLines)) {}
288 if (!signs.empty() &&
290 const auto& attr = signs.front().applyVisitor([](
auto& prim) {
return prim.attribute(
AttributeName::Subtype); });
293 if (!signs.empty()) {
294 throw InvalidInputError(
"Regulatory element has a traffic sign without subtype attribute!");
299 throw InvalidInputError(
"Regulatory element can not determine the type of the traffic sign!");
332 constructSpeedLimitData(id, attributes, trafficSigns, cancellingTrafficSigns, refLines, cancelLines)) {}
337 updateTrafficSigns(signs);
355 std::vector<std::string> types;
356 types.reserve(signs.size());
357 for (
auto& sign : signs) {
358 types.push_back(sign.applyVisitor([](
auto& prim) { return prim.attribute(AttributeName::Subtype); }).value());
360 std::sort(types.begin(), types.end());
361 types.erase(std::unique(types.begin(), types.end()), types.end());
378 auto sl = stopLines();
382 auto llts = lanelets();
383 auto it =
std::find(llts.begin(), llts.end(), llt);
384 if (it == llts.end()) {
391 auto sl = stopLines();
395 auto llts = lanelets();
396 auto it =
std::find(llts.begin(), llts.end(), llt);
397 if (it == llts.end()) {
418 auto sl = stopLines();
419 if (sl.empty() && !lanelets().empty() && !!lltWithStop.
stopLine) {
420 throw InvalidInputError(
"A lanelet with stop line was added, but existing lanelets don't have a stop line!");
422 if (!sl.empty() && !lltWithStop.
stopLine) {
423 throw InvalidInputError(
"A lanelet without stopline was added, but existing lanelets have a stop line!");
436 auto& yieldLLts = yieldIt->second;
438 if (lltIt == yieldLLts.end()) {
442 if (linesIt !=
parameters().
end() && !linesIt->second.empty()) {
443 linesIt->second.erase(linesIt->second.begin() +
std::distance(yieldLLts.begin(), lltIt));
445 yieldLLts.erase(lltIt);
451 :
AllWayStop{constructAllWayStopData(
id, attributes, lltsWithStop, signs)} {}
458 throw InvalidInputError(
"An all way stop must not have a lanelet with right of way!");
465 "Inconsistent number of lanelets and stop lines found! Either one stop line per lanelet or no stop lines!");
template class for registering new RegulatoryElements.
A lanelet that has right of way in a relation.
SpeedLimit(Id id, const AttributeMap &attributes, const TrafficSignsWithType &trafficSigns, const TrafficSignsWithType &cancellingTrafficSigns={}, const LineStrings3d &refLines={}, const LineStrings3d &cancelLines={})
ConstLanelets lanelets() const
get the lanelets that potentially have to yield
bool hasAttribute(const std::string &name) const noexcept
check whether this primitive has a specific attribute
std::vector< ConstLineString3d > ConstLineStrings3d
void addCancellingRefLine(const LineString3d &line)
Add a new line from where the sign becomes inactive.
ManeuverType
Enum to distinguish maneuver types.
std::vector< ConstLineStringOrPolygon3d > ConstLineStringsOrPolygons3d
auto find(ContainerT &&c, const ValueT &val)
ConstLanelets yieldLanelets() const
get the lanelets that have to yield
Optional< ConstLineString3d > stopLine() const
get the stop line for the traffic light
void addRightOfWayLanelet(const Lanelet &lanelet)
Adds a lanelet for RightOfWay.
const_iterator end() const
AllWayStop(Id id, const AttributeMap &attributes, const LaneletsWithStopLines &lltsWithStop, const LineStringsOrPolygons3d &signs)
static RegisterRegulatoryElement< TrafficSign > regTrafficSign
bool removeLanelet(const Lanelet &llt)
Removes a lanelet and the associated stop line, if there is one.
bool removeRefLine(const LineString3d &line)
Remove a reference line. Returns true on success.
The referring line where the rule becomes active.
std::pair< iterator, bool > insert(const value_type &v)
void removeStopLine()
Removes the stop line.
ConstLanelets rightOfWayLanelets() const
get the lanelets have right of way
iterator find(const key_type &k)
const std::string & value() const
gets the value of this attribute
void addLanelet(const LaneletWithStopLine &lltWithStop)
HybridMap< Attribute, decltype(AttributeNamesString::Map)&, AttributeNamesString::Map > AttributeMap
void addYieldLanelet(const Lanelet &lanelet)
Add yielding lanelet.
const AttributeMap & attributes() const
get the attributes of this primitive
This class holds either a LineString3d or a Polygon3d.
RoleName
Typical role names within lanelet (for faster lookup)
The famous (mutable) lanelet class.
bool removeYieldLanelet(const Lanelet &lanelet)
Removes a yielding lanelet and returns true no success.
std::vector< Lanelet > Lanelets
Optional< LineString3d > stopLine
bool removeTrafficSign(const LineStringOrPolygon3d &sign)
remove a traffic sign and returns true on success
std::shared_ptr< RegulatoryElementData > RegulatoryElementDataPtr
TrafficSign(Id id, const AttributeMap &attributes, const TrafficSignsWithType &trafficSigns, const TrafficSignsWithType &cancellingTrafficSigns={}, const LineStrings3d &refLines={}, const LineStrings3d &cancelLines={})
Defines right of way restrictions.
static RegisterRegulatoryElement< AllWayStop > regAllWayStop
const RuleParameterMap & parameters() const
static RegisterRegulatoryElement< SpeedLimit > regSpeedLimit
const Attribute & attribute(const std::string &name) const
retrieve an attribute
RuleParameter asRuleParameter() const
auto strong(std::vector< WeakT > v)
transforms a vector of weak_ptrs to a vector of shared_ptrs
std::string type() const
get the id/number of the sign(s)
bool operator==(const lanelet::LaneletDataConstWptr &lhs, const lanelet::LaneletDataConstWptr &rhs)
ConstLineStringsOrPolygons3d trafficSigns() const
returns the traffic signs
static RegisterRegulatoryElement< TrafficLight > regTraffic
Represents a traffic light restriction on the lanelet.
std::vector< RuleParameter > RuleParameters
Multiple parameters can have the same role in a rule (eg traffic_lights)
ConstLineStringsOrPolygons3d trafficLights() const
get the relevant traffic lights
RegulatoryElementDataPtr data()
primitive(s) that invalidate a rule (eg end of speed zone)
Used as input argument to create TrafficSign regElem.
bool removeCancellingTrafficSign(const LineStringOrPolygon3d &sign)
remove a cancelling traffic sign, returns true on success
void forEach(Container &&c, Func &&f)
ConstLineStrings3d cancelLines() const
gets the line(s) from which a sign becomes invalid.
A normal 3d linestring with mutable data.
boost::optional< T > Optional
ConstLineStringsOrPolygons3d cancellingTrafficSigns() const
get list of cancellingTrafficSigns, if existing
std::weak_ptr< const LaneletData > LaneletDataConstWptr
bool empty() const
returns true if this object contains no parameters
std::vector< LaneletWithStopLine > LaneletsWithStopLines
bool removeRightOfWayLanelet(const Lanelet &lanelet)
Removes a right of way lanelet and returns true on success.
std::vector< LineStringOrPolygon3d > LineStringsOrPolygons3d
RightOfWay(Id id, const AttributeMap &attributes, const Lanelets &rightOfWay, const Lanelets &yield, const Optional< LineString3d > &stopLine={})
void setStopLine(const LineString3d &stopLine)
Overwrites the stop line.
bool removeCancellingRefLine(const LineString3d &line)
Remove a cancelling line. Returns true on success.
void addRefLine(const LineString3d &line)
Add a new reference line.
void addCancellingTrafficSign(const TrafficSignsWithType &signs)
Add new cancelling traffic sign.
Optional< double > distance
void removeStopLine()
Deletes the stop line.
auto transform(Container &&c, Func f)
void addTrafficSign(const LineStringOrPolygon3d &sign)
Adds another traffic sign.
Optional< ConstLineString3d > getStopLine(const ConstLanelet &llt) const
gets the stop line for a lanelet, if there is one
void setStopLine(const LineString3d &stopLine)
set a new stop line, overwrite the old one
ConstLineStrings3d refLines() const
gets the line(s) from which a sign becomes valid.
bool contains(const Container &c, const Value &v)
Lanelet ist not part of relation.
A general rule or limitation for a lanelet (abstract base class)
The line from which a rule is invalidated.
A lanelet that has to yield.
LineStringsOrPolygons3d trafficSigns
Lists relevant traffic signs.
bool removeTrafficLight(const LineStringOrPolygon3d &primitive)
remove a traffic light
void addTrafficSign(const LineStringOrPolygon3d &sign)
Adds another traffic sign.
TrafficLight(Id id, const AttributeMap &attributes, const LineStringsOrPolygons3d &trafficLights, const Optional< LineString3d > &stopLine)
Expresses a generic traffic sign rule.
static RegisterRegulatoryElement< RightOfWay > regRightOfWay
Optional< ConstLineString3d > stopLine() const
get the stop line for the yield lanelets, if present
std::vector< std::string > cancelTypes() const
Types of the cancelling traffic signs if they exist.
void addTrafficLight(const LineStringOrPolygon3d &primitive)
add a new traffic light
size_t size() const
get the number of roles in this regulatoryElement
ConstLineStringsOrPolygons3d trafficSigns() const
get list of traffic signs that constitute this AllWayStop if existing
static constexpr const char SignType[]
Defines an all way stop. These are a special form of right of way, where all lanelets have to yield...
bool removeTrafficSign(const LineStringOrPolygon3d &sign)
removes a traffic sign and returns true on success
ConstLineStrings3d stopLines() const
get the stop lines
HybridMap< RuleParameters, decltype(RoleNameString::Map)&, RoleNameString::Map > RuleParameterMap
Rules are stored in a map internally.
std::vector< LineString3d > LineStrings3d
ManeuverType getManeuver(const ConstLanelet &lanelet) const
returns whether a lanelet has to yield or has right of way
boost::variant< Point3d, LineString3d, Polygon3d, WeakLanelet, WeakArea > RuleParameter
The primitive(s) that are the origin of this rule (ie signs)
std::vector< ConstLanelet > ConstLanelets