Branch data Line data Source code
1 : : // ----------------- BEGIN LICENSE BLOCK ---------------------------------
2 : : //
3 : : // Copyright (C) 2019-2021 Intel Corporation
4 : : //
5 : : // SPDX-License-Identifier: MIT
6 : : //
7 : : // ----------------- END LICENSE BLOCK -----------------------------------
8 : :
9 : : #include "ad/map/opendrive/AdMapFactory.hpp"
10 : :
11 : : #include <boost/algorithm/string.hpp>
12 : : #include <opendrive/OpenDrive.hpp>
13 : : #include "DataTypeConversion.hpp"
14 : : #include "ad/map/access/Logging.hpp"
15 : : #include "ad/map/point/GeoOperation.hpp"
16 : : #include "ad/map/point/Transform.hpp"
17 : :
18 : : namespace ad {
19 : : namespace map {
20 : : namespace opendrive {
21 : :
22 : 45 : AdMapFactory::AdMapFactory(access::Store &store)
23 : 45 : : access::Factory(store)
24 : : {
25 : 45 : }
26 : :
27 : 190 : bool AdMapFactory::isOpenDriveMap(std::string const &mapName)
28 : : {
29 : : // @todo Check whether the file is xml and contains the tags <OpenDRIVE>
30 [ + - ]: 190 : return ::boost::iends_with(mapName, ".xodr");
31 : : }
32 : :
33 : 43 : bool AdMapFactory::createAdMap(std::string const &mapFilePath,
34 : : double const overlapMargin,
35 : : intersection::IntersectionType const defaultIntersectionType,
36 : : landmark::TrafficLightType const defaultTrafficLightType)
37 : : {
38 : : // parse data from xml file
39 [ + - ]: 86 : ::opendrive::OpenDriveData openDriveData;
40 [ + - + + ]: 43 : if (!::opendrive::Load(mapFilePath, openDriveData))
41 : : {
42 [ + - + - ]: 2 : access::getLogger()->warn("Unable to open opendrive map for reading {}", mapFilePath);
43 : 1 : return false;
44 : : }
45 [ + - ]: 42 : return createAdMap(openDriveData, overlapMargin, defaultIntersectionType, defaultTrafficLightType);
46 : : }
47 : :
48 : 3 : bool AdMapFactory::createAdMapFromString(std::string const &mapContent,
49 : : double const overlapMargin,
50 : : intersection::IntersectionType const defaultIntersectionType,
51 : : landmark::TrafficLightType const defaultTrafficLightType)
52 : : {
53 : : // parse data from string
54 [ + - ]: 6 : ::opendrive::OpenDriveData openDriveData;
55 [ + - + + ]: 3 : if (!::opendrive::Parse(mapContent, openDriveData))
56 : : {
57 [ + - + - ]: 1 : access::getLogger()->warn("Unable to parse opendrive content");
58 : 1 : return false;
59 : : }
60 [ + - ]: 2 : return createAdMap(openDriveData, overlapMargin, defaultIntersectionType, defaultTrafficLightType);
61 : : }
62 : :
63 : 44 : bool AdMapFactory::createAdMap(::opendrive::OpenDriveData &openDriveData,
64 : : double const overlapMargin,
65 : : intersection::IntersectionType const defaultIntersectionType,
66 : : landmark::TrafficLightType const defaultTrafficLightType)
67 : : {
68 [ + - + + ]: 44 : if (!::opendrive::GenerateLaneMap(openDriveData, overlapMargin))
69 : : {
70 [ + - + - ]: 7 : access::getLogger()->warn("LaneMap geometry generated with errors");
71 : : }
72 : :
73 [ + - ]: 88 : auto coordinateTransform = access::getCoordinateTransform();
74 [ + - + + ]: 44 : if (coordinateTransform->setGeoProjection(openDriveData.geoReference.projection))
75 : : {
76 [ + - + - : 66 : access::getLogger()->info("Opened opendrive map: using proj geo reference {}", access::getENUReferencePoint());
+ - ]
77 : : }
78 [ + - - + : 11 : else if (std::isnan(openDriveData.geoReference.latitude) || std::isnan(openDriveData.geoReference.longitude))
- + ]
79 : : {
80 [ # # ]: 0 : auto geoRefPoint = access::getENUReferencePoint();
81 : 0 : openDriveData.geoReference.latitude = static_cast<double>(geoRefPoint.latitude);
82 : 0 : openDriveData.geoReference.longitude = static_cast<double>(geoRefPoint.longitude);
83 [ # # # # : 0 : access::getLogger()->info("Opened opendrive map: using external geo reference {}", access::getENUReferencePoint());
# # ]
84 : : }
85 : : else
86 : : {
87 [ + - ]: 11 : point::GeoPoint geoRefPoint;
88 : 11 : geoRefPoint.longitude = ::ad::map::point::Longitude(openDriveData.geoReference.longitude);
89 : 11 : geoRefPoint.latitude = ::ad::map::point::Latitude(openDriveData.geoReference.latitude);
90 : 11 : geoRefPoint.altitude = ::ad::map::point::Altitude(openDriveData.geoReference.altitude);
91 [ + - ]: 11 : access::setENUReferencePoint(geoRefPoint);
92 [ + - + - : 22 : access::getLogger()->info("Opened opendrive map: using geo reference {}", access::getENUReferencePoint());
+ - ]
93 : : }
94 : :
95 [ + - ]: 88 : return convertToAdMap(openDriveData, defaultIntersectionType, defaultTrafficLightType);
96 : : }
97 : :
98 : 85033 : restriction::Restrictions AdMapFactory::createRoadRestrictions() const
99 : : {
100 : 170066 : restriction::Restriction roadRestriction;
101 : 85033 : roadRestriction.negated = false;
102 : 85033 : roadRestriction.passengersMin = 0.;
103 : : roadRestriction.roadUserTypes
104 [ + - ]: 85033 : = {restriction::RoadUserType::CAR, restriction::RoadUserType::BUS, restriction::RoadUserType::TRUCK};
105 : 85033 : restriction::Restrictions roadRestrictions;
106 [ + - ]: 85033 : roadRestrictions.conjunctions.push_back(roadRestriction);
107 : 170066 : return roadRestrictions;
108 : : }
109 : :
110 : 23435 : bool AdMapFactory::setLaneSpeed(::opendrive::Lane const &lane)
111 : : {
112 : 23435 : bool ok = true;
113 : :
114 : 23435 : auto laneId = toLaneId(lane.id);
115 : :
116 [ + + ]: 58689 : for (auto const ¶metricSpeed : lane.speed)
117 : : {
118 [ + - ]: 35254 : restriction::SpeedLimit speedLimit;
119 : 35254 : speedLimit.lanePiece.minimum = physics::ParametricValue(parametricSpeed.start);
120 : 35254 : speedLimit.lanePiece.maximum = physics::ParametricValue(parametricSpeed.end);
121 : 35254 : speedLimit.speedLimit = physics::Speed(parametricSpeed.speed);
122 [ + - - + ]: 35254 : if (!add(laneId, speedLimit))
123 : : {
124 : 0 : ok = false;
125 : : }
126 : : }
127 : :
128 : 23435 : return ok;
129 : : }
130 : :
131 : 1218 : bool AdMapFactory::addLandmark(::opendrive::Landmark const &landmark)
132 : : {
133 : 1218 : bool ok = true;
134 : :
135 [ + - ]: 1218 : point::Geometry boundingBox;
136 : 1218 : landmark::LandmarkId landmarkId(toLandmarkId(landmark.id));
137 : 1218 : access::PartitionId partitionId(0);
138 : :
139 [ + - ]: 1218 : auto position = toECEF(landmark.position);
140 : :
141 : 1218 : point::Longitude landmarkDirectionLon(landmark.position.x + cos(landmark.orientation));
142 : 1218 : point::Latitude landmarkDirectionLat(landmark.position.y + sin(landmark.orientation));
143 : :
144 : : point::GeoPoint geoOrientation
145 [ + - ]: 1218 : = point::createGeoPoint(landmarkDirectionLon, landmarkDirectionLat, point::Altitude(0.));
146 [ + - ]: 1218 : auto orientation = point::toECEF(geoOrientation);
147 : :
148 [ + - ]: 1218 : auto landmarkType = toLandmarkType(landmark.type);
149 : :
150 [ + + ]: 1218 : if (landmarkType == landmark::LandmarkType::TRAFFIC_LIGHT)
151 : : {
152 [ + - ]: 1198 : auto trafficLightType = toTrafficLightType(landmark.type, landmark.subtype);
153 [ + - - + ]: 1198 : if (!addTrafficLight(partitionId, landmarkId, trafficLightType, position, orientation, boundingBox))
154 : : {
155 : 0 : ok = false;
156 : : }
157 : : }
158 [ + + ]: 20 : else if (landmarkType == landmark::LandmarkType::TRAFFIC_SIGN)
159 : : {
160 [ + - ]: 10 : auto trafficSignType = toTrafficSignType(landmark.type, landmark.subtype);
161 [ + - + - : 10 : if (!addTrafficSign(partitionId, landmarkId, trafficSignType, position, orientation, boundingBox, "None"))
- + ]
162 : : {
163 : 0 : ok = false;
164 : : }
165 : : }
166 : : else
167 : : {
168 [ + - + - ]: 10 : if (Factory::addLandmark(partitionId, landmarkId, landmarkType, position, orientation, boundingBox))
169 : : {
170 : 10 : ok = false;
171 : : }
172 : : }
173 : :
174 : 2436 : return ok;
175 : : }
176 : :
177 : 11616 : bool AdMapFactory::isDrivableLane(lane::LaneType laneType) const
178 : : {
179 [ + + ]: 11616 : switch (laneType)
180 : : {
181 : 5597 : case lane::LaneType::NORMAL:
182 : : case lane::LaneType::MULTI:
183 : : case lane::LaneType::TURN:
184 : : case lane::LaneType::INTERSECTION:
185 : 5597 : return true;
186 : 6019 : default:
187 : 6019 : return false;
188 : : }
189 : : }
190 : :
191 : 23435 : bool AdMapFactory::addLane(::opendrive::Lane const &lane)
192 : : {
193 : 23435 : bool ok = true;
194 [ + - - + : 23435 : if ((lane.leftEdge.size() < 2) || (lane.rightEdge.size() < 2))
- + ]
195 : : {
196 [ # # # # ]: 0 : access::getLogger()->error("Invalid number of points for lane {}. Skip lane.", lane.id);
197 : 0 : return false;
198 : : }
199 : :
200 [ + - ]: 46870 : point::Geometry leftEcefEdge;
201 [ + - ]: 46870 : point::Geometry rightEcefEdge;
202 : : try
203 : : {
204 [ + - + - ]: 23435 : leftEcefEdge = toGeometry(lane.leftEdge);
205 [ + - + - ]: 23435 : rightEcefEdge = toGeometry(lane.rightEdge);
206 : : }
207 : 0 : catch (...)
208 : : {
209 [ - - - - ]: 0 : access::getLogger()->error("Invalid points for lane {}. Skip lane.", lane.id);
210 [ - - ]: 0 : return false;
211 : : }
212 : :
213 [ + - ]: 23435 : lane::LaneType type = toLaneType(lane.type);
214 : :
215 : : // opendrive assigns an id if the lane belongs to a certain junction
216 [ + + + - : 23435 : if ((lane.junction != -1) && isDrivableLane(type))
+ + + + ]
217 : : {
218 : 5597 : type = lane::LaneType::INTERSECTION;
219 : : }
220 : :
221 [ + - ]: 23435 : lane::LaneDirection direction = toLaneDirection(lane);
222 : :
223 : 23435 : auto partitionId = access::PartitionId(0);
224 : 23435 : auto laneId = toLaneId(lane.id);
225 : :
226 [ + - - + ]: 23435 : if (!add(partitionId, laneId, type, direction))
227 : : {
228 : 0 : ok = false;
229 : : }
230 [ + - - + ]: 23435 : if (!set(laneId, leftEcefEdge, rightEcefEdge))
231 : : {
232 : 0 : ok = false;
233 : : }
234 [ + - - + ]: 23435 : if (!setLaneSpeed(lane))
235 : : {
236 : 0 : ok = false;
237 : : }
238 : :
239 : 23435 : return ok;
240 : : }
241 : :
242 : 2911 : bool AdMapFactory::addSpecialContact(::opendrive::Lane const &lane,
243 : : ::opendrive::Landmark const &landmark,
244 : : lane::ContactLocation const &location)
245 : : {
246 : 2911 : bool ok = true;
247 [ + - ]: 2911 : auto const contact = ::ad::map::opendrive::toContactType(landmark.type);
248 [ + + ]: 2911 : if ((contact == lane::ContactType::UNKNOWN))
249 : : {
250 : : // The landmark does not generate any contact
251 : 120 : return true;
252 : : }
253 [ - + ]: 2791 : else if (contact == lane::ContactType::INVALID)
254 : : {
255 [ # # # # ]: 0 : access::getLogger()->warn("addSpecialContact() Invalid contact type");
256 : 0 : return false;
257 : : }
258 : :
259 [ + - ]: 5582 : auto const contacts = lane::ContactTypeList{contact};
260 [ + - ]: 2791 : auto const restrictions = createRoadRestrictions(); // to do generate restrictions from traffic signs
261 [ + + ]: 2791 : auto const &laneContacts = (location == lane::ContactLocation::SUCCESSOR) ? lane.successors : lane.predecessors;
262 : :
263 [ + + ]: 5572 : for (auto const &contactId : laneContacts)
264 : : {
265 [ + - ]: 2781 : if (contact == lane::ContactType::TRAFFIC_LIGHT)
266 : : {
267 : 2781 : landmark::LandmarkId trafficLightId(toLandmarkId(landmark.id));
268 [ + - - + ]: 2781 : if (!add(toLaneId(lane.id), toLaneId(contactId), location, contacts, restrictions, trafficLightId))
269 : : {
270 : 0 : ok = false;
271 : : }
272 : : }
273 : : else
274 : : {
275 [ # # # # ]: 0 : if (!add(toLaneId(lane.id), toLaneId(contactId), location, contacts, restrictions))
276 : : {
277 : 0 : ok = false;
278 : : }
279 : : }
280 : : }
281 : 2791 : return ok;
282 : : }
283 : :
284 : 23435 : bool AdMapFactory::addSpecialContacts(::opendrive::Lane const &lane, ::opendrive::LandmarkMap const &landmarks)
285 : : {
286 : 23435 : bool ok = true;
287 [ + + ]: 26346 : for (auto const &signalReference : lane.signalReferences)
288 : : {
289 [ + - ]: 2911 : auto const location = toContactLocation(signalReference, lane.junction != -1);
290 [ + - ]: 2911 : auto const &landmark = landmarks.at(signalReference.id);
291 [ + - - + ]: 2911 : if (!addSpecialContact(lane, landmark, location))
292 : : {
293 : 0 : ok = false;
294 : : }
295 : : }
296 : :
297 : 23435 : return ok;
298 : : }
299 : :
300 : 23435 : bool AdMapFactory::addContactLanes(::opendrive::Lane const &lane,
301 : : intersection::IntersectionType const defaultIntersectionType,
302 : : landmark::TrafficLightType const defaultTrafficLightType)
303 : : {
304 : 23435 : bool ok = true;
305 : :
306 [ + - ]: 46870 : lane::ContactTypeList const laneContinuation({lane::ContactType::LANE_CONTINUATION});
307 [ + - ]: 46870 : lane::ContactTypeList const laneChange({lane::ContactType::LANE_CHANGE});
308 : 23435 : lane::ContactLocation const left(lane::ContactLocation::LEFT);
309 : 23435 : lane::ContactLocation const right(lane::ContactLocation::RIGHT);
310 : 23435 : lane::ContactLocation const succ(lane::ContactLocation::SUCCESSOR);
311 : 23435 : lane::ContactLocation const pred(lane::ContactLocation::PREDECESSOR);
312 : 46870 : lane::ContactTypeList defaultIntersectionContact;
313 : 23435 : landmark::LandmarkId fakeTrafficLightId(landmark::LandmarkId::cMaxValue);
314 : :
315 : 23435 : auto laneId = toLaneId(lane.id);
316 [ + - ]: 46870 : auto adlanePtr = mStore.getLanePtr(laneId);
317 [ - + ]: 23435 : if (!adlanePtr)
318 : : {
319 : 0 : return false;
320 : : }
321 [ + - ]: 46870 : auto adlane = *adlanePtr;
322 : :
323 [ + + + + : 23435 : switch (defaultIntersectionType)
+ + + + +
- ]
324 : : {
325 : 306 : case intersection::IntersectionType::HasWay:
326 [ + - ]: 306 : defaultIntersectionContact.push_back(lane::ContactType::FREE);
327 : 306 : break;
328 : 306 : case intersection::IntersectionType::Stop:
329 [ + - ]: 306 : defaultIntersectionContact.push_back(lane::ContactType::STOP);
330 : 306 : break;
331 : 306 : case intersection::IntersectionType::AllWayStop:
332 [ + - ]: 306 : defaultIntersectionContact.push_back(lane::ContactType::STOP_ALL);
333 : 306 : break;
334 : 306 : case intersection::IntersectionType::Yield:
335 [ + - ]: 306 : defaultIntersectionContact.push_back(lane::ContactType::YIELD);
336 : 306 : break;
337 : 306 : case intersection::IntersectionType::Crosswalk:
338 [ + - ]: 306 : defaultIntersectionContact.push_back(lane::ContactType::CROSSWALK);
339 : 306 : break;
340 : 1506 : case intersection::IntersectionType::PriorityToRight:
341 [ + - ]: 1506 : defaultIntersectionContact.push_back(lane::ContactType::PRIO_TO_RIGHT);
342 : 1506 : break;
343 : 306 : case intersection::IntersectionType::PriorityToRightAndStraight:
344 [ + - ]: 306 : defaultIntersectionContact.push_back(lane::ContactType::PRIO_TO_RIGHT_AND_STRAIGHT);
345 : 306 : break;
346 : 5712 : case intersection::IntersectionType::TrafficLight:
347 : : {
348 [ + - ]: 5712 : defaultIntersectionContact.push_back(lane::ContactType::TRAFFIC_LIGHT);
349 : : // fake a traffic light to get the basic logic to work for now
350 [ + - ]: 11424 : point::Geometry boundingBox;
351 : 5712 : auto position = adlane.edgeLeft.ecefEdge[0];
352 : 5712 : auto orientation = adlane.edgeLeft.ecefEdge[1];
353 [ + - ]: 5712 : (void)addTrafficLight(
354 : : access::PartitionId(0), fakeTrafficLightId, defaultTrafficLightType, position, orientation, boundingBox);
355 : 5712 : break;
356 : : }
357 : 14381 : case intersection::IntersectionType::Unknown:
358 : : // nothing to be done here
359 : 14381 : break;
360 : 0 : default:
361 [ # # # # ]: 0 : access::getLogger()->error("Invalid defaultIntersectionType passed {}",
362 : 0 : static_cast<int>(defaultIntersectionType));
363 : 0 : return false;
364 : : }
365 : :
366 [ + + ]: 23435 : if (lane.leftNeighbor != 0u)
367 : : {
368 [ + - ]: 36150 : auto restrictions = createRoadRestrictions();
369 [ + - - + ]: 18075 : if (!add(laneId, toLaneId(lane.leftNeighbor), left, laneChange, restrictions))
370 : : {
371 : 0 : ok = false;
372 : : }
373 : : }
374 [ + + ]: 23435 : if (lane.rightNeighbor != 0u)
375 : : {
376 [ + - ]: 36150 : auto restrictions = createRoadRestrictions();
377 [ + - - + ]: 18075 : if (!add(laneId, toLaneId(lane.rightNeighbor), right, laneChange, restrictions))
378 : : {
379 : 0 : ok = false;
380 : : }
381 : : }
382 : :
383 [ + + ]: 46501 : for (auto const &successorId : lane.successors)
384 : : {
385 [ + - ]: 23066 : auto restrictions = createRoadRestrictions();
386 [ + - - + ]: 23066 : if (!add(laneId, toLaneId(successorId), succ, laneContinuation, restrictions))
387 : : {
388 : 0 : ok = false;
389 : : }
390 : :
391 [ + + ]: 23066 : if (adlane.type != lane::LaneType::INTERSECTION)
392 : : {
393 [ + - ]: 17469 : auto successorPtr = mStore.getLanePtr(toLaneId(successorId));
394 [ - + ]: 17469 : if (!successorPtr)
395 : : {
396 : 0 : return false;
397 : : }
398 [ + - ]: 34938 : auto successor = *successorPtr;
399 [ + + ]: 17469 : if (successor.type == lane::LaneType::INTERSECTION)
400 : : {
401 : : //@todo: determine the correct right of way for that intersection
402 [ + + ]: 4663 : if (!defaultIntersectionContact.empty())
403 : : {
404 [ + + ]: 2160 : if (defaultIntersectionContact.front() == lane::ContactType::TRAFFIC_LIGHT)
405 : : {
406 [ + - - + ]: 1368 : if (!add(laneId, toLaneId(successorId), succ, defaultIntersectionContact, restrictions, fakeTrafficLightId))
407 : : {
408 : 0 : ok = false;
409 : : }
410 : : }
411 : : else
412 : : {
413 [ + - - + ]: 792 : if (!add(laneId, toLaneId(successorId), succ, defaultIntersectionContact, restrictions))
414 : : {
415 : 0 : ok = false;
416 : : }
417 : : }
418 : : }
419 : : }
420 : : }
421 : : }
422 : :
423 [ + + ]: 46461 : for (auto const &predecessorId : lane.predecessors)
424 : : {
425 [ + - ]: 23026 : auto restrictions = createRoadRestrictions();
426 [ + - - + ]: 23026 : if (!add(laneId, toLaneId(predecessorId), pred, laneContinuation, restrictions))
427 : : {
428 : 0 : ok = false;
429 : : }
430 : :
431 [ + + ]: 23026 : if (adlane.type != lane::LaneType::INTERSECTION)
432 : : {
433 [ + - ]: 17436 : auto predecessorPtr = mStore.getLanePtr(toLaneId(predecessorId));
434 [ - + ]: 17436 : if (!predecessorPtr)
435 : : {
436 : 0 : return false;
437 : : }
438 [ + - ]: 34872 : auto predecessor = *predecessorPtr;
439 [ + + ]: 17436 : if (predecessor.type == lane::LaneType::INTERSECTION)
440 : : {
441 : : //@todo: determine the correct right of way for that intersection
442 [ + + ]: 4616 : if (!defaultIntersectionContact.empty())
443 : : {
444 [ + + ]: 2160 : if (defaultIntersectionContact.front() == lane::ContactType::TRAFFIC_LIGHT)
445 : : {
446 [ + - ]: 1368 : if (!add(
447 [ - + ]: 2736 : laneId, toLaneId(predecessorId), pred, defaultIntersectionContact, restrictions, fakeTrafficLightId))
448 : : {
449 : 0 : ok = false;
450 : : }
451 : : }
452 : : else
453 : : {
454 [ + - - + ]: 792 : if (!add(laneId, toLaneId(predecessorId), pred, defaultIntersectionContact, restrictions))
455 : : {
456 : 0 : ok = false;
457 : : }
458 : : }
459 : : }
460 : : }
461 : : }
462 : : }
463 : :
464 [ + + ]: 52495 : for (auto const &overlappingLaneId : lane.overlaps)
465 : : {
466 [ + - + - ]: 87180 : if (!add(laneId,
467 : 58120 : toLaneId(overlappingLaneId),
468 : : lane::ContactLocation::OVERLAP,
469 : : {lane::ContactType::UNKNOWN},
470 [ - + ]: 58120 : restriction::Restrictions()))
471 : : {
472 : 0 : ok = false;
473 : : }
474 : : }
475 : :
476 : 23435 : return ok;
477 : : }
478 : :
479 : 44 : bool AdMapFactory::convertToAdMap(::opendrive::OpenDriveData &mapData,
480 : : intersection::IntersectionType const defaultIntersectionType,
481 : : landmark::TrafficLightType const defaultTrafficLightType)
482 : : {
483 : 44 : bool ok = true;
484 : :
485 : : // @todo OpenDRIVE has not tags to define if right or left hand traffic
486 : : // right now a function exists "toLaneDirection" inside DataTypeConversion.hpp which
487 : : // calculates the lane direction given the lane attributes and a bool value for right hand traffic
488 [ + - ]: 44 : set(access::TrafficType::RIGHT_HAND_TRAFFIC);
489 : :
490 : : // we first need to add all the lane ids and geometry to the store
491 : 44 : bool laneGenerationOk = (mapData.laneMap.size() != 0);
492 [ + + ]: 23479 : for (auto const &element : mapData.laneMap)
493 : : {
494 [ + - - + ]: 23435 : if (!addLane(element.second))
495 : : {
496 : 0 : laneGenerationOk = false;
497 : : }
498 : : }
499 [ + - + + ]: 44 : ok = ok && laneGenerationOk;
500 : :
501 : : // add all the landmarks to the store
502 : 44 : bool landmarkGenerationOk = true;
503 [ + + ]: 1262 : for (auto const &element : mapData.landmarks)
504 : : {
505 [ + - + + ]: 1218 : if (!addLandmark(element.second))
506 : : {
507 : 10 : landmarkGenerationOk = false;
508 : : }
509 : : }
510 [ + + + + ]: 44 : ok = ok && landmarkGenerationOk;
511 : :
512 : : // after all lanes are in the store we can add the contact information including those derived from the landmarks
513 : 44 : bool contactGenerationOk = true;
514 [ + + ]: 23479 : for (auto const &element : mapData.laneMap)
515 : : {
516 : 23435 : auto &lane = element.second;
517 [ + - - + ]: 23435 : if (!addContactLanes(lane, defaultIntersectionType, defaultTrafficLightType))
518 : : {
519 : 0 : contactGenerationOk = false;
520 : : }
521 [ + - - + ]: 23435 : if (!addSpecialContacts(lane, mapData.landmarks))
522 : : {
523 : 0 : contactGenerationOk = false;
524 : : }
525 : : }
526 [ + + + - ]: 44 : ok = ok && contactGenerationOk;
527 : :
528 [ + + ]: 44 : if (!ok)
529 : : {
530 [ + - ]: 11 : access::getLogger()->warn("AdMap conversion generated with errors");
531 [ + + ]: 11 : if (!laneGenerationOk)
532 : : {
533 [ + - ]: 1 : access::getLogger()->warn("Lanes generated with errors");
534 : : }
535 [ + + ]: 11 : if (!landmarkGenerationOk)
536 : : {
537 [ + - ]: 10 : access::getLogger()->warn("Landmarks generated with errors");
538 : : }
539 [ - + ]: 11 : if (!contactGenerationOk)
540 : : {
541 [ # # ]: 0 : access::getLogger()->warn("Contacts generated with errors");
542 : : }
543 : : }
544 : :
545 : : // only errors during lane generation are considered to be a critical errors
546 : 44 : return laneGenerationOk;
547 : : }
548 : :
549 : : } // namespace opendrive
550 : : } // namespace map
551 : : } // namespace ad
|