LCOV - code coverage report
Current view: top level - src/utils/gui/settings - GUIPropertyScheme.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 51 84 60.7 %
Date: 2024-09-16 15:39:55 Functions: 11 17 64.7 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2001-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    GUIPropertyScheme.h
      15             : /// @author  Michael Behrisch
      16             : /// @author  Daniel Krajzewicz
      17             : /// @author  Jakob Erdmann
      18             : /// @date    Mon, 20.07.2009
      19             : ///
      20             : //
      21             : /****************************************************************************/
      22             : #pragma once
      23             : #include <config.h>
      24             : 
      25             : #include <cassert>
      26             : #include <vector>
      27             : #include <utils/common/RGBColor.h>
      28             : #include <utils/iodevices/OutputDevice.h>
      29             : #include <utils/gui/images/GUIIcons.h>
      30             : 
      31             : 
      32             : // ===========================================================================
      33             : // class definitions
      34             : // ===========================================================================
      35             : /**
      36             :  * @class GUIPropertyScheme
      37             :  * This class provides a mapping from real values to properties (mainly colors).
      38             :  * Each color is stored along with a threshold value.
      39             :  * Color values between thresholds are obtained by interpolation
      40             :  */
      41             : 
      42             : template<class T>
      43             : class GUIPropertyScheme {
      44             : public:
      45             :     /// Constructor
      46     8261730 :     GUIPropertyScheme(const std::string& name, const std::string& translatedName, const T& baseColor,
      47             :                       const std::string& colName = "", const bool isFixed = false, double baseValue = 0,
      48             :                       RGBColor bgColor = RGBColor::WHITE,
      49             :                       GUIIcon icon = GUIIcon::EMPTY) :
      50     8261730 :         myName(name),
      51     8261730 :         myTranslatedName(translatedName),
      52     8261730 :         myIsInterpolated(!isFixed),
      53     8261730 :         myIsFixed(isFixed),
      54     8261730 :         myAllowNegativeValues(false),
      55     8261730 :         myIcon(icon),
      56     8261730 :         myBgColor(bgColor) {
      57     8261730 :         addColor(baseColor, baseValue, colName);
      58     8261730 :     }
      59             : 
      60     4912396 :     GUIPropertyScheme(const std::string& name, const T& baseColor,
      61             :                       const std::string& colName = "", const bool isFixed = false, double baseValue = 0,
      62             :                       RGBColor bgColor = RGBColor::WHITE,
      63             :                       GUIIcon icon = GUIIcon::EMPTY) :
      64     4912396 :         myName(name),
      65     4912396 :         myTranslatedName(name),
      66     4912396 :         myIsInterpolated(!isFixed),
      67     4912396 :         myIsFixed(isFixed),
      68     4912396 :         myAllowNegativeValues(false),
      69     4912396 :         myIcon(icon),
      70     4912396 :         myBgColor(bgColor) {
      71     4912396 :         addColor(baseColor, baseValue, colName);
      72     4912396 :     }
      73             : 
      74             :     void setThreshold(const int pos, const double threshold) {
      75           0 :         myThresholds[pos] = threshold;
      76             :     }
      77             : 
      78             :     void setColor(const int pos, const T& color) {
      79           0 :         myColors[pos] = color;
      80             :     }
      81             : 
      82        2110 :     bool setColor(const std::string& name, const T& color) {
      83             :         std::vector<std::string>::iterator nameIt = myNames.begin();
      84             :         typename std::vector<T>::iterator colIt = myColors.begin();
      85        6216 :         for (; nameIt != myNames.end(); ++nameIt, ++colIt) {
      86        6202 :             if (*nameIt == name) {
      87        2096 :                 (*colIt) = color;
      88        2096 :                 return true;
      89             :             }
      90             :         }
      91             :         return false;
      92             :     }
      93             : 
      94    48166433 :     int addColor(const T& color, const double threshold, const std::string& name = "") {
      95             :         typename std::vector<T>::iterator colIt = myColors.begin();
      96             :         std::vector<double>::iterator threshIt = myThresholds.begin();
      97             :         std::vector<std::string>::iterator nameIt = myNames.begin();
      98             :         int pos = 0;
      99   146957429 :         while (threshIt != myThresholds.end() && (*threshIt) < threshold) {
     100             :             ++threshIt;
     101             :             ++colIt;
     102             :             ++nameIt;
     103    98790996 :             pos++;
     104             :         }
     105    48166433 :         myColors.insert(colIt, color);
     106    48166433 :         myThresholds.insert(threshIt, threshold);
     107    48166433 :         myNames.insert(nameIt, name);
     108    48166433 :         return pos;
     109             :     }
     110             : 
     111           0 :     void removeColor(const int pos) {
     112             :         assert(pos < (int)myColors.size());
     113           0 :         myColors.erase(myColors.begin() + pos);
     114           0 :         myThresholds.erase(myThresholds.begin() + pos);
     115           0 :         myNames.erase(myNames.begin() + pos);
     116           0 :     }
     117             : 
     118        2441 :     void clear() {
     119             :         myColors.clear();
     120             :         myThresholds.clear();
     121             :         myNames.clear();
     122        2441 :     }
     123             : 
     124    75274205 :     T getColor(const double value) const {
     125    75274205 :         if (myColors.size() == 1 || value < myThresholds.front()) {
     126    46643591 :             return myColors.front();
     127             :         }
     128             :         typename std::vector<T>::const_iterator colIt = myColors.begin() + 1;
     129             :         std::vector<double>::const_iterator threshIt = myThresholds.begin() + 1;
     130    34202833 :         while (threshIt != myThresholds.end() && (*threshIt) <= value) {
     131             :             ++threshIt;
     132             :             ++colIt;
     133             :         }
     134    28630614 :         if (threshIt == myThresholds.end()) {
     135      349530 :             return myColors.back();
     136             :         }
     137    28281084 :         if (!myIsInterpolated) {
     138    28163885 :             return *(colIt - 1);
     139             :         }
     140      117199 :         double lowVal = *(threshIt - 1);
     141      117199 :         return interpolate(*(colIt - 1), *colIt, (value - lowVal) / ((*threshIt) - lowVal));
     142             :     }
     143             : 
     144             :     void setInterpolated(const bool interpolate, double interpolationStart = 0.f) {
     145        2425 :         myIsInterpolated = interpolate;
     146        2425 :         if (interpolate) {
     147        2425 :             myThresholds[0] = interpolationStart;
     148             :         }
     149             :     }
     150             : 
     151             :     const std::string& getName() const {
     152      449955 :         return myName;
     153             :     }
     154             : 
     155             :     const std::string& getTranslatedName() const {
     156             :         return myTranslatedName;
     157             :     }
     158             : 
     159             :     const std::vector<T>& getColors() const {
     160             :         return myColors;
     161             :     }
     162             : 
     163             :     const std::vector<double>& getThresholds() const {
     164             :         return myThresholds;
     165             :     }
     166             : 
     167             :     bool isInterpolated() const {
     168           0 :         return myIsInterpolated;
     169             :     }
     170             : 
     171             :     const std::vector<std::string>& getNames() const {
     172             :         return myNames;
     173             :     }
     174             : 
     175             :     bool isFixed() const {
     176       15694 :         return myIsFixed;
     177             :     }
     178             : 
     179             :     bool allowsNegativeValues() const {
     180           0 :         return myAllowNegativeValues;
     181             :     }
     182             : 
     183             :     void setAllowsNegativeValues(bool value) {
     184     3200490 :         myAllowNegativeValues = value;
     185             :     }
     186             : 
     187             :     GUIIcon getIcon() const {
     188           0 :         return myIcon;
     189             :     }
     190             : 
     191             :     const RGBColor& getBackgroundColor() const {
     192           0 :         return myBgColor;
     193             :     }
     194             : 
     195           0 :     void save(OutputDevice& dev, const std::string& prefix = "") const {
     196             :         const int precision = dev.getPrecision();
     197             :         const bool checkPrecision = precision <= 2; // 2 is default precision (see SystemFrame)
     198           0 :         const std::string tag = getTagName(myColors);
     199             : 
     200           0 :         dev.openTag(tag);
     201           0 :         dev.writeAttr(SUMO_ATTR_NAME, prefix + myName);
     202           0 :         if (!myIsFixed) {
     203           0 :             dev.writeAttr(SUMO_ATTR_INTERPOLATED, myIsInterpolated);
     204             :         }
     205             :         typename std::vector<T>::const_iterator colIt = myColors.begin();
     206             :         std::vector<double>::const_iterator threshIt = myThresholds.begin();
     207             :         std::vector<std::string>::const_iterator nameIt = myNames.begin();
     208           0 :         while (threshIt != myThresholds.end()) {
     209           0 :             dev.openTag(SUMO_TAG_ENTRY);
     210             :             dev.writeAttr(SUMO_ATTR_COLOR, *colIt);
     211           0 :             if (!myIsFixed && (*threshIt) != std::numeric_limits<double>::max()) {
     212           0 :                 const double t = *threshIt;
     213           0 :                 if (checkPrecision && t != 0 && fabs(t) < 0.01) {
     214           0 :                     dev.setPrecision(8);
     215             :                 }
     216             :                 dev.writeAttr(SUMO_ATTR_THRESHOLD, t);
     217           0 :                 dev.setPrecision(precision);
     218             :             }
     219           0 :             if ((*nameIt) != "") {
     220             :                 dev.writeAttr(SUMO_ATTR_NAME, *nameIt);
     221             :             }
     222           0 :             dev.closeTag();
     223             :             ++threshIt;
     224             :             ++colIt;
     225             :             ++nameIt;
     226             :         }
     227           0 :         dev.closeTag();
     228           0 :     }
     229             : 
     230           0 :     bool operator==(const GUIPropertyScheme& c) const {
     231           0 :         return myName == c.myName && myColors == c.myColors && myThresholds == c.myThresholds && myIsInterpolated == c.myIsInterpolated;
     232             :     }
     233             : 
     234             : 
     235             :     /// @brief specializations for GUIColorScheme
     236             :     RGBColor interpolate(const RGBColor& min, const RGBColor& max, double weight) const {
     237      117199 :         return RGBColor::interpolate(min, max, weight);
     238             :     }
     239             : 
     240             :     std::string getTagName(std::vector<RGBColor>) const {
     241           0 :         return toString(SUMO_TAG_COLORSCHEME);
     242             :     }
     243             : 
     244             : 
     245             :     /// @brief specializations for GUIScaleScheme
     246             :     double interpolate(const double& min, const double& max, double weight) const {
     247           0 :         return min + (max - min) * weight;
     248             :     }
     249             : 
     250             :     std::string getTagName(std::vector<double>) const {
     251           0 :         return toString(SUMO_TAG_SCALINGSCHEME);
     252             :     }
     253             : 
     254             : 
     255             : private:
     256             :     std::string myName;
     257             :     std::string myTranslatedName;
     258             :     std::vector<T> myColors;
     259             :     std::vector<double> myThresholds;
     260             :     bool myIsInterpolated;
     261             :     std::vector<std::string> myNames;
     262             :     bool myIsFixed;
     263             :     bool myAllowNegativeValues;
     264             :     GUIIcon myIcon;
     265             :     RGBColor myBgColor;
     266             : 
     267             : };
     268             : 
     269             : typedef GUIPropertyScheme<RGBColor> GUIColorScheme;
     270             : typedef GUIPropertyScheme<double> GUIScaleScheme;

Generated by: LCOV version 1.14