LCOV - code coverage report
Current view: top level - src/opendrive - AdMapFactory.cpp (source / functions) Hit Total Coverage
Test: ad_map_access Lines: 220 261 84.3 %
Date: 2022-10-04 09:48:07 Functions: 14 14 100.0 %
Branches: 221 388 57.0 %

           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 &parametricSpeed : 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

Generated by: LCOV version 1.14