| 52 | } |
| 53 | |
| 54 | std::string ColorPicker::GetNearestColor(std::string const & rgb) |
| 55 | { |
| 56 | static std::string const kDefaultColor = "default"; |
| 57 | if (rgb.empty()) |
| 58 | return kDefaultColor; |
| 59 | |
| 60 | auto [it, inserted] = m_colorsToNames.emplace(rgb, kDefaultColor); |
| 61 | if (!inserted) |
| 62 | return it->second; |
| 63 | |
| 64 | std::string nearestColor = kDefaultColor; |
| 65 | |
| 66 | unsigned int intColor; |
| 67 | // We do not need to add to the cache invalid color, so we just return. |
| 68 | if (!strings::to_uint(rgb, intColor, 16)) |
| 69 | return nearestColor; |
| 70 | |
| 71 | dp::Color const color = df::ToDrapeColor(static_cast<uint32_t>(intColor)); |
| 72 | double minDist = std::numeric_limits<double>::max(); |
| 73 | |
| 74 | for (auto const & [name, transitColor] : m_drapeClearColors) |
| 75 | { |
| 76 | if (double const dist = GetDistance(color, transitColor); dist < minDist) |
| 77 | { |
| 78 | minDist = dist; |
| 79 | nearestColor = name; |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | if (nearestColor.find(df::kTransitColorPrefix + df::kTransitLinePrefix) == 0) |
| 84 | nearestColor = nearestColor.substr(df::kTransitColorPrefix.size() + df::kTransitLinePrefix.size()); |
| 85 | |
| 86 | it->second = nearestColor; |
| 87 | return nearestColor; |
| 88 | } |
| 89 | } // namespace transit |