LCOV - code coverage report
Current view: top level - src/polyconvert - PCPolyContainer.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 98 109 89.9 %
Date: 2024-04-27 15:34:54 Functions: 9 12 75.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2005-2024 German Aerospace Center (DLR) and others.
       4             : // This program and the accompanying materials are made available under the
       5             : // terms of the Eclipse Public License 2.0 which is available at
       6             : // https://www.eclipse.org/legal/epl-2.0/
       7             : // This Source Code may also be made available under the following Secondary
       8             : // Licenses when the conditions for such availability set forth in the Eclipse
       9             : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10             : // or later which is available at
      11             : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12             : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13             : /****************************************************************************/
      14             : /// @file    PCPolyContainer.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @author  Melanie Knocke
      19             : /// @date    Mon, 05 Dec 2005
      20             : ///
      21             : // A storage for loaded polygons and pois
      22             : /****************************************************************************/
      23             : #include <config.h>
      24             : 
      25             : #include <string>
      26             : #include <algorithm>
      27             : #include <map>
      28             : #include <utils/common/MsgHandler.h>
      29             : #include <utils/common/ToString.h>
      30             : #include <utils/common/UtilExceptions.h>
      31             : #include <utils/common/StringUtils.h>
      32             : #include <utils/geom/GeoConvHelper.h>
      33             : #include <utils/shapes/SUMOPolygon.h>
      34             : #include <utils/iodevices/OutputDevice.h>
      35             : #include <utils/xml/SUMOSAXAttributes.h>
      36             : #include <utils/options/OptionsCont.h>
      37             : #include "PCPolyContainer.h"
      38             : 
      39             : 
      40             : // ===========================================================================
      41             : // method definitions
      42             : // ===========================================================================
      43          45 : PCPolyContainer::PCPolyContainer(bool prune,
      44             :                                  const Boundary& pruningBoundary,
      45          45 :                                  const std::vector<std::string>& removeByNames)
      46          45 :     : myPruningBoundary(pruningBoundary), myDoPrune(prune),
      47          45 :       myRemoveByNames(removeByNames) {}
      48             : 
      49             : 
      50          45 : PCPolyContainer::~PCPolyContainer() {
      51          45 :     myPolygons.clear();
      52          45 :     myPOIs.clear();
      53          90 : }
      54             : 
      55             : 
      56             : bool
      57        6066 : PCPolyContainer::add(SUMOPolygon* poly, bool ignorePruning) {
      58             :     // check whether the polygon lies within the wished area
      59             :     //  - if such an area was given
      60        6066 :     if (myDoPrune && !ignorePruning) {
      61           0 :         Boundary b = poly->getShape().getBoxBoundary();
      62           0 :         if (!b.partialWithin(myPruningBoundary)) {
      63           0 :             delete poly;
      64             :             return false;
      65             :         }
      66           0 :     }
      67             :     // check whether the polygon was named to be a removed one
      68        6066 :     if (find(myRemoveByNames.begin(), myRemoveByNames.end(), poly->getID()) != myRemoveByNames.end()) {
      69           0 :         delete poly;
      70           0 :         return false;
      71             :     }
      72        6066 :     return ShapeContainer::add(poly);
      73             : }
      74             : 
      75             : 
      76             : bool
      77        5515 : PCPolyContainer::add(PointOfInterest* poi, bool ignorePruning) {
      78             :     // check whether the poi lies within the wished area
      79             :     //  - if such an area was given
      80        5515 :     if (myDoPrune && !ignorePruning) {
      81           7 :         if (!myPruningBoundary.around(*poi)) {
      82           4 :             delete poi;
      83           4 :             return false;
      84             :         }
      85             :     }
      86             :     // check whether the polygon was named to be a removed one
      87        5511 :     if (find(myRemoveByNames.begin(), myRemoveByNames.end(), poi->getID()) != myRemoveByNames.end()) {
      88           0 :         delete poi;
      89           0 :         return false;
      90             :     }
      91        5511 :     return ShapeContainer::add(poi);
      92             : }
      93             : 
      94             : 
      95             : void
      96           1 : PCPolyContainer::addLanePos(const std::string& poiID, const std::string& laneID, const double lanePos, const bool friendlyPos, const double lanePosLat) {
      97           2 :     myLanePosPois[poiID] = LanePos(laneID, lanePos, friendlyPos, lanePosLat);
      98           1 : }
      99             : 
     100             : 
     101             : void
     102          41 : PCPolyContainer::save(const std::string& file, bool useGeo) {
     103             :     const GeoConvHelper& gch = GeoConvHelper::getFinal();
     104          41 :     if (useGeo && !gch.usingGeoProjection()) {
     105           4 :         WRITE_WARNING(TL("Ignoring option \"proj.plain-geo\" because no geo-conversion has been defined"));
     106             :         useGeo = false;
     107             :     }
     108          41 :     OutputDevice& out = OutputDevice::getDevice(file);
     109         123 :     out.writeXMLHeader("additional", "additional_file.xsd");
     110          41 :     if (useGeo) {
     111          16 :         out.setPrecision(gPrecisionGeo);
     112          25 :     } else if (gch.usingGeoProjection()) {
     113          18 :         GeoConvHelper::writeLocation(out);
     114             :     }
     115             :     // write polygons
     116        6105 :     for (auto i : myPolygons) {
     117        6064 :         i.second->writeXML(out, useGeo);
     118             :     }
     119             :     // write pois
     120          82 :     const double zOffset = OptionsCont::getOptions().getFloat("poi-layer-offset");
     121        5549 :     for (const auto& POI : myPOIs) {
     122        5508 :         std::map<std::string, LanePos>::const_iterator it = myLanePosPois.find(POI.first);
     123        5508 :         if (it == myLanePosPois.end()) {
     124       11014 :             POI.second->writeXML(out, useGeo, zOffset);
     125             :         } else {
     126           2 :             POI.second->writeXML(out, useGeo, zOffset, it->second.laneID, it->second.pos, it->second.friendlyPos, it->second.posLat);
     127             :         }
     128             :     }
     129          41 :     out.close();
     130          41 : }
     131             : 
     132             : 
     133           2 : void PCPolyContainer::writeDlrTDPHeader(OutputDevice& device, const OptionsCont& oc) {
     134             :     // XXX duplicate of NWWriter_DlrNavteq::writeHeader()
     135           2 :     device << "# Format matches Extraction version: V6.5 \n";
     136           2 :     std::stringstream tmp;
     137           4 :     oc.writeConfiguration(tmp, true, false, false);
     138           2 :     tmp.seekg(std::ios_base::beg);
     139             :     std::string line;
     140          82 :     while (!tmp.eof()) {
     141          80 :         std::getline(tmp, line);
     142          80 :         device << "# " << line << "\n";
     143             :     }
     144           2 :     device << "#\n";
     145           2 : }
     146             : 
     147             : 
     148             : void
     149           1 : PCPolyContainer::saveDlrTDP(const std::string& prefix) {
     150           1 :     const OptionsCont& oc = OptionsCont::getOptions();
     151             :     const GeoConvHelper& gch = GeoConvHelper::getFinal();
     152           1 :     const bool haveGeo = gch.usingGeoProjection();
     153           1 :     const double geoScale = pow(10.0f, haveGeo ? 5 : 2); // see NIImporter_DlrNavteq::GEO_SCALE
     154             :     // write pois
     155           1 :     OutputDevice& out = OutputDevice::getDevice(prefix + "_points_of_interest.txt");
     156           1 :     out.setPrecision(0);
     157           1 :     writeDlrTDPHeader(out, oc);
     158             :     // write format specifier
     159           1 :     out << "# ID\tCITY\tTYPE\tNAME\tgeo_x\tgeo_y\n";
     160           1 :     int id = 0;
     161           2 :     for (const auto& i : myPOIs) {
     162           1 :         Position pos(*i.second);
     163           1 :         gch.cartesian2geo(pos);
     164             :         pos.mul(geoScale);
     165           1 :         out << id << "\t";
     166           1 :         out << "" << "\t";
     167           1 :         out << i.second->getShapeType() << "\t";
     168           1 :         out << i.first << "\t";
     169           1 :         out << pos.x() << "\t";
     170           1 :         out << pos.y() << "\t";
     171           1 :         id++;
     172             :     }
     173           1 :     out.close();
     174             :     // write polygons
     175           1 :     OutputDevice& out2 = OutputDevice::getDevice(prefix + "_polygons.txt");
     176           1 :     out2.setPrecision(0);
     177           1 :     writeDlrTDPHeader(out2, oc);
     178             :     // write format specifier
     179           1 :     out2 << "# ID\tCITY\tTYPE\tNAME\tgeo_x1\tgeo_y1\t[geo_x2 geo_y2 ...]\n";
     180           1 :     id = 0;
     181           2 :     for (const auto& i : myPolygons) {
     182           1 :         out2 << id << "\t";
     183           1 :         out2 << "" << "\t";
     184           1 :         out2 << i.second->getShapeType() << "\t";
     185           1 :         out2 << i.first << "\t";
     186             : 
     187           6 :         for (Position pos : i.second->getShape()) {
     188           5 :             gch.cartesian2geo(pos);
     189             :             pos.mul(geoScale);
     190           5 :             out2 << pos.x() << "\t";
     191           5 :             out2 << pos.y() << "\t";
     192             :         }
     193           1 :         id++;
     194             :     }
     195           1 :     out2.close();
     196           1 : }
     197             : 
     198             : 
     199             : int
     200           7 : PCPolyContainer::getEnumIDFor(const std::string& key) {
     201           7 :     return myIDEnums[key]++;
     202             : }
     203             : 
     204             : 
     205           1 : PCPolyContainer::LanePos::LanePos() :
     206           1 :     pos(0),
     207           1 :     friendlyPos(false),
     208           1 :     posLat(0) {
     209           0 : }
     210             : 
     211             : 
     212           1 : PCPolyContainer::LanePos::LanePos(const std::string& _laneID, double _pos, bool _friendlyPos, double _posLat) :
     213           0 :     laneID(_laneID),
     214           1 :     pos(_pos),
     215           1 :     friendlyPos(_friendlyPos),
     216           1 :     posLat(_posLat) {
     217           0 : }
     218             : 
     219             : /****************************************************************************/

Generated by: LCOV version 1.14