LCOV - code coverage report
Current view: top level - src/config - MapConfigFileHandler.cpp (source / functions) Hit Total Coverage
Test: ad_map_access Lines: 153 153 100.0 %
Date: 2022-10-04 09:48:07 Functions: 17 17 100.0 %
Branches: 197 336 58.6 %

           Branch data     Line data    Source code
       1                 :            : // ----------------- BEGIN LICENSE BLOCK ---------------------------------
       2                 :            : //
       3                 :            : // Copyright (C) 2018-2021 Intel Corporation
       4                 :            : //
       5                 :            : // SPDX-License-Identifier: MIT
       6                 :            : //
       7                 :            : // ----------------- END LICENSE BLOCK -----------------------------------
       8                 :            : 
       9                 :            : #include "ad/map/config/MapConfigFileHandler.hpp"
      10                 :            : 
      11                 :            : #include <boost/algorithm/string/predicate.hpp>
      12                 :            : #include <boost/filesystem/operations.hpp>
      13                 :            : #include <boost/filesystem/path.hpp>
      14                 :            : #include <boost/program_options/parsers.hpp>
      15                 :            : #include <boost/program_options/variables_map.hpp>
      16                 :            : #include <fstream>
      17                 :            : #include "ad/map/access/Logging.hpp"
      18                 :            : #include "ad/map/point/GeoOperation.hpp"
      19                 :            : 
      20                 :         44 : inline std::istream &operator>>(std::istream &input, ::ad::physics::Distance &distance)
      21                 :            : {
      22                 :            :   double dummy;
      23   [ +  -  +  -  :         44 :   if (input >> dummy)
                   +  + ]
      24                 :            :   {
      25                 :         43 :     distance = ::ad::physics::Distance(dummy);
      26                 :            :   }
      27                 :         44 :   return input;
      28                 :            : }
      29                 :            : 
      30                 :        669 : inline std::istream &operator>>(std::istream &input, ::ad::map::point::Latitude &latitude)
      31                 :            : {
      32                 :            :   double dummy;
      33   [ +  -  +  -  :        669 :   if (input >> dummy)
                   +  + ]
      34                 :            :   {
      35                 :        667 :     latitude = ::ad::map::point::Latitude(dummy);
      36                 :            :   }
      37                 :        669 :   return input;
      38                 :            : }
      39                 :            : 
      40                 :        667 : inline std::istream &operator>>(std::istream &input, ::ad::map::point::Longitude &longitude)
      41                 :            : {
      42                 :            :   double dummy;
      43   [ +  -  +  -  :        667 :   if (input >> dummy)
                   +  + ]
      44                 :            :   {
      45                 :        664 :     longitude = ::ad::map::point::Longitude(dummy);
      46                 :            :   }
      47                 :        667 :   return input;
      48                 :            : }
      49                 :            : 
      50                 :        664 : inline std::istream &operator>>(std::istream &input, ::ad::map::point::Altitude &altitude)
      51                 :            : {
      52                 :            :   double dummy;
      53   [ +  -  +  -  :        664 :   if (input >> dummy)
                   +  + ]
      54                 :            :   {
      55                 :        662 :     altitude = ::ad::map::point::Altitude(dummy);
      56                 :            :   }
      57                 :        664 :   return input;
      58                 :            : }
      59                 :            : 
      60                 :            : namespace ad {
      61                 :            : namespace map {
      62                 :            : namespace config {
      63                 :            : 
      64                 :        214 : bool MapConfigFileHandler::readConfig(std::string const &configFileName)
      65                 :            : {
      66                 :        214 :   reset();
      67         [ +  + ]:        214 :   if (!parseConfigFile(configFileName))
      68                 :            :   {
      69                 :         18 :     reset();
      70                 :         18 :     return false;
      71                 :            :   }
      72                 :        196 :   return true;
      73                 :            : }
      74                 :            : 
      75                 :     900742 : bool MapConfigFileHandler::isInitialized() const
      76                 :            : {
      77                 :     900742 :   return !mConfigFileName.empty();
      78                 :            : }
      79                 :            : 
      80                 :         74 : std::vector<PointOfInterest> const &MapConfigFileHandler::pointsOfInterest() const
      81                 :            : {
      82                 :         74 :   return mPointsOfInterest;
      83                 :            : }
      84                 :            : 
      85                 :          2 : bool MapConfigFileHandler::isInitializedWithFilename(std::string const &configFileName) const
      86                 :            : {
      87   [ +  -  +  -  :          4 :   auto path = boost::filesystem::canonical(boost::filesystem::path(configFileName));
                   +  - ]
      88                 :          2 :   auto const isEqual = (path.string() == mConfigFileName);
      89                 :            : 
      90         [ +  + ]:          2 :   if (!isEqual)
      91                 :            :   {
      92   [ +  -  +  - ]:          2 :     access::getLogger()->warn("AdMapAccess already initialized with a different config. Present {}, Requested {}",
      93                 :          1 :                               mConfigFileName,
      94                 :          1 :                               path.string());
      95                 :            :   }
      96                 :            : 
      97                 :          4 :   return isEqual;
      98                 :            : }
      99                 :            : 
     100                 :        210 : void MapConfigFileHandler::updateFilenameAndPath(std::string const &configFileName)
     101                 :            : {
     102   [ +  -  +  -  :        420 :   auto path = boost::filesystem::canonical(boost::filesystem::path(configFileName));
                   +  - ]
     103         [ +  - ]:        210 :   mConfigFileName = path.string();
     104   [ +  -  +  - ]:        210 :   mBaseDir = path.parent_path().string();
     105                 :        210 : }
     106                 :            : 
     107                 :        214 : bool MapConfigFileHandler::parseConfigFile(std::string const &configFileName)
     108                 :            : {
     109                 :            :   namespace po = boost::program_options;
     110         [ +  - ]:        428 :   po::variables_map vm;
     111         [ +  - ]:        428 :   po::options_description options;
     112                 :            :   // clang-format off
     113   [ +  -  +  -  :        214 :   options.add_options()("ADMap.map", po::value<std::string>(), "AD map")
                   +  - ]
     114   [ +  -  +  - ]:        214 :                        ("ADMap.openDriveOverlapMargin", po::value<std::string>(), "OpenDrive Map reader margin for overlap calculation")
     115   [ +  -  +  - ]:        214 :                        ("ADMap.openDriveDefaultIntersectionType", po::value<std::string>(), "OpenDrive Map default intersection type")
     116   [ +  -  +  - ]:        214 :                        ("ADMap.openDriveDefaultTrafficLightType", po::value<std::string>(), "OpenDrive Map default traffic light type (only relevant for IntersectionType::TrafficLight)")
     117   [ +  -  +  - ]:        214 :                        ("POI.poi", po::value<std::vector<std::string>>(), "Points of interest")
     118   [ +  -  +  - ]:        214 :                        ("ENUReference.default", po::value<std::string>(), "Default ENU reference point");
     119                 :            :   // clang-format on
     120                 :            : 
     121                 :            :   try
     122                 :            :   {
     123         [ +  - ]:        217 :     std::ifstream settingsFile(configFileName);
     124   [ +  -  +  + ]:        214 :     if (!settingsFile.is_open())
     125                 :            :     {
     126   [ +  -  +  - ]:          8 :       access::getLogger()->error("Cannot open config file for reading: {}", configFileName);
     127                 :          4 :       return false;
     128                 :            :     }
     129   [ +  -  +  - ]:        420 :     access::getLogger()->trace("Reading config file {}", configFileName);
     130   [ +  -  +  - ]:        210 :     po::store(po::parse_config_file(settingsFile, options), vm);
     131         [ +  - ]:        210 :     po::notify(vm);
     132                 :            : 
     133                 :            :     // we need the correct mBaseDir before we can construct any filename for the maps
     134         [ +  - ]:        210 :     updateFilenameAndPath(configFileName);
     135                 :            : 
     136   [ +  -  +  -  :        210 :     if (vm.count("ADMap.map"))
                   +  - ]
     137                 :            :     {
     138         [ +  - ]:        213 :       MapEntry mapEntry;
     139   [ +  -  +  -  :        423 :       auto const mapFilename = vm["ADMap.map"].as<std::string>();
             +  -  +  - ]
     140         [ +  - ]:        213 :       boost::filesystem::path path(mBaseDir);
     141   [ +  -  +  - ]:        210 :       path /= boost::filesystem::path(mapFilename);
     142   [ +  -  +  + ]:        212 :       path = boost::filesystem::canonical(path);
     143   [ +  -  +  + ]:        208 :       if (!boost::starts_with(path.string(), mBaseDir))
     144                 :            :       {
     145   [ +  -  +  - ]:          2 :         access::getLogger()->error("Given map file {} seems not to be located below current configuration directory {} "
     146                 :            :                                    "concatenating results in: {}",
     147                 :            :                                    mapFilename,
     148                 :          1 :                                    mBaseDir,
     149                 :          1 :                                    path.string());
     150                 :          1 :         return false;
     151                 :            :       }
     152         [ +  - ]:        207 :       mapEntry.filename = path.string();
     153                 :            : 
     154                 :        207 :       physics::Distance openDriveOverlapMargin{0.};
     155   [ +  -  +  -  :        207 :       if (vm.count("ADMap.openDriveOverlapMargin"))
                   +  + ]
     156                 :            :       {
     157   [ +  -  +  -  :         88 :         auto const overlapMarginString = vm["ADMap.openDriveOverlapMargin"].as<std::string>();
             +  -  +  - ]
     158         [ +  - ]:         44 :         std::istringstream input{overlapMarginString};
     159   [ +  -  +  -  :         44 :         if (!(input >> openDriveOverlapMargin))
                   +  + ]
     160                 :            :         {
     161   [ +  -  +  - ]:          1 :           access::getLogger()->warn("Error extracting openDriveOverlapMargin");
     162                 :          1 :           return false;
     163                 :            :         }
     164                 :            :       }
     165                 :        206 :       mapEntry.openDriveOverlapMargin = openDriveOverlapMargin;
     166                 :            : 
     167                 :        206 :       intersection::IntersectionType openDriveDefaultIntersectionType = intersection::IntersectionType::Unknown;
     168   [ +  -  +  -  :        206 :       if (vm.count("ADMap.openDriveDefaultIntersectionType"))
                   +  + ]
     169                 :            :       {
     170                 :            :         auto const openDriveDefaultIntersectionTypeString
     171   [ +  -  +  -  :         65 :           = vm["ADMap.openDriveDefaultIntersectionType"].as<std::string>();
             +  -  +  - ]
     172                 :            :         openDriveDefaultIntersectionType
     173         [ +  + ]:         32 :           = fromString<intersection::IntersectionType>(openDriveDefaultIntersectionTypeString);
     174                 :            :       }
     175                 :        205 :       mapEntry.openDriveDefaultIntersectionType = openDriveDefaultIntersectionType;
     176                 :            : 
     177         [ +  + ]:        205 :       if (mapEntry.openDriveDefaultIntersectionType == intersection::IntersectionType::TrafficLight)
     178                 :            :       {
     179                 :         19 :         landmark::TrafficLightType openDriveDefaultTrafficLightType
     180                 :            :           = landmark::TrafficLightType::SOLID_RED_YELLOW_GREEN;
     181   [ +  -  +  -  :         19 :         if (vm.count("ADMap.openDriveDefaultTrafficLightType"))
                   +  + ]
     182                 :            :         {
     183                 :            :           auto const openDriveDefaultTrafficLightTypeString
     184   [ +  -  +  -  :         36 :             = vm["ADMap.openDriveDefaultTrafficLightType"].as<std::string>();
             +  -  +  - ]
     185                 :            :           openDriveDefaultTrafficLightType
     186         [ +  - ]:         18 :             = fromString<landmark::TrafficLightType>(openDriveDefaultTrafficLightTypeString);
     187                 :            :         }
     188                 :         19 :         mapEntry.openDriveDefaultTrafficLightType = openDriveDefaultTrafficLightType;
     189                 :            :       }
     190                 :            : 
     191         [ +  - ]:        205 :       mAdMapEntry = mapEntry;
     192                 :            :     }
     193                 :            : 
     194   [ +  -  +  -  :        205 :     if (vm.count("POI.poi"))
                   +  + ]
     195                 :            :     {
     196   [ +  -  +  -  :        119 :       auto const &entries = vm["POI.poi"].as<std::vector<std::string>>();
                   +  - ]
     197         [ +  + ]:        631 :       for (auto const &entry : entries)
     198                 :            :       {
     199   [ +  -  +  + ]:        517 :         if (!parsePointOfIntereset(entry))
     200                 :            :         {
     201   [ +  -  +  - ]:         10 :           access::getLogger()->warn("Invalid  POI poi entry in config file: {}, Entry: {}", configFileName, entry);
     202                 :          5 :           return false;
     203                 :            :         }
     204                 :            :       }
     205                 :            :     }
     206                 :            : 
     207   [ +  -  +  -  :        200 :     if (vm.count("ENUReference.default"))
                   +  + ]
     208                 :            :     {
     209   [ +  -  +  -  :        153 :       auto const &entry = vm["ENUReference.default"].as<std::string>();
                   +  - ]
     210   [ +  -  +  + ]:        153 :       if (!parseENUReference(entry))
     211                 :            :       {
     212   [ +  -  +  - ]:          8 :         access::getLogger()->warn(
     213                 :            :           "Invalid default ENU reference entry in config file: {}, Entry: {}", configFileName, entry);
     214                 :          4 :         return false;
     215                 :            :       }
     216                 :            :     }
     217                 :            :   }
     218                 :          3 :   catch (std::exception const &e)
     219                 :            :   {
     220   [ +  -  +  - ]:          6 :     access::getLogger()->error("Error while parsing {}, Reason: {}", configFileName, e.what());
     221                 :          3 :     return false;
     222                 :            :   }
     223                 :        196 :   return true;
     224                 :            : }
     225                 :            : 
     226                 :        517 : bool MapConfigFileHandler::parsePointOfIntereset(std::string const &entry)
     227                 :            : {
     228         [ +  - ]:       1034 :   std::istringstream input{entry};
     229         [ +  - ]:       1034 :   PointOfInterest poi;
     230   [ +  -  +  -  :        517 :   if (!(input >> poi.name))
                   +  + ]
     231                 :            :   {
     232   [ +  -  +  - ]:          1 :     access::getLogger()->warn("Error extracting name of poi!");
     233                 :          1 :     return false;
     234                 :            :   }
     235   [ +  -  +  -  :        516 :   if (!(input >> poi.geoPoint.latitude))
                   +  + ]
     236                 :            :   {
     237   [ +  -  +  - ]:          1 :     access::getLogger()->warn("Error extracting lat");
     238                 :          1 :     return false;
     239                 :            :   }
     240   [ +  -  +  -  :        515 :   if (!(input >> poi.geoPoint.longitude))
                   +  + ]
     241                 :            :   {
     242   [ +  -  +  - ]:          1 :     access::getLogger()->warn("Error extracting lon");
     243                 :          1 :     return false;
     244                 :            :   }
     245   [ +  -  +  -  :        514 :   if (!(input >> poi.geoPoint.altitude))
                   +  + ]
     246                 :            :   {
     247   [ +  -  +  - ]:          1 :     access::getLogger()->warn("Error extracting altitude");
     248                 :          1 :     return false;
     249                 :            :   }
     250   [ +  +  +  - ]:       1855 :   for (auto existingEntry : mPointsOfInterest)
     251                 :            :   {
     252         [ +  + ]:       1343 :     if (existingEntry.name == poi.name)
     253                 :            :     {
     254   [ +  -  +  - ]:          2 :       access::getLogger()->warn("POI defined twice: {}", existingEntry.name);
     255                 :          1 :       return false;
     256                 :            :     }
     257                 :            :   }
     258         [ +  - ]:        512 :   mPointsOfInterest.push_back(poi);
     259                 :            : 
     260                 :        512 :   return true;
     261                 :            : }
     262                 :            : 
     263                 :        153 : bool MapConfigFileHandler::parseENUReference(std::string const &entry)
     264                 :            : {
     265         [ +  - ]:        306 :   std::istringstream input{entry};
     266         [ +  - ]:        153 :   point::GeoPoint enuReference;
     267   [ +  -  +  -  :        153 :   if (!(input >> enuReference.latitude))
                   +  + ]
     268                 :            :   {
     269   [ +  -  +  - ]:          1 :     access::getLogger()->warn("Error extracting lat");
     270                 :          1 :     return false;
     271                 :            :   }
     272   [ +  -  +  -  :        152 :   if (!(input >> enuReference.longitude))
                   +  + ]
     273                 :            :   {
     274   [ +  -  +  - ]:          2 :     access::getLogger()->warn("Error extracting lon");
     275                 :          2 :     return false;
     276                 :            :   }
     277   [ +  -  +  -  :        150 :   if (!(input >> enuReference.altitude))
                   +  + ]
     278                 :            :   {
     279   [ +  -  +  - ]:          1 :     access::getLogger()->warn("Error extracting altitude");
     280                 :          1 :     return false;
     281                 :            :   }
     282                 :        149 :   mDefaultEnuReference = enuReference;
     283                 :        149 :   return true;
     284                 :            : }
     285                 :            : 
     286                 :          9 : std::string const &MapConfigFileHandler::configFileName() const
     287                 :            : {
     288                 :          9 :   return mConfigFileName;
     289                 :            : }
     290                 :            : 
     291                 :        317 : MapEntry const &MapConfigFileHandler::adMapEntry() const
     292                 :            : {
     293                 :        317 :   return mAdMapEntry;
     294                 :            : }
     295                 :            : 
     296                 :        680 : void MapConfigFileHandler::reset()
     297                 :            : {
     298                 :        680 :   mConfigFileName = "";
     299                 :        680 :   mAdMapEntry = MapEntry();
     300                 :        680 :   mPointsOfInterest.clear();
     301                 :        680 :   mDefaultEnuReference = point::GeoPoint();
     302                 :        680 :   mBaseDir.clear();
     303                 :        680 : }
     304                 :            : 
     305                 :        144 : point::GeoPoint MapConfigFileHandler::defaultEnuReference() const
     306                 :            : {
     307                 :        144 :   return mDefaultEnuReference;
     308                 :            : }
     309                 :            : 
     310                 :        189 : bool MapConfigFileHandler::defaultEnuReferenceAvailable() const
     311                 :            : {
     312                 :        189 :   return point::isValid(mDefaultEnuReference, false);
     313                 :            : }
     314                 :            : 
     315                 :            : } // namespace config
     316                 :            : } // namespace map
     317                 :            : } // namespace ad

Generated by: LCOV version 1.14