mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-03 11:23:48 +00:00
[gpx] Save bookmark color to gpx export (#11238)
* [gpx] Save bookmark color to gpx export * [gpx] Code-review fixes * [gpx] Use m_rgba to store initial color, reset on predefined color change * [gpx] Move MapPredefinedColor to color parser * [gpx] Adjust naming Signed-off-by: cyber-toad <the.cyber.toad@proton.me>
This commit is contained in:
committed by
Konstantin Pastbin
parent
bf79f7a95c
commit
fd342c2a17
@@ -1,6 +1,7 @@
|
||||
#include "color_parser.hpp"
|
||||
|
||||
#include "coding/hex.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
@@ -31,6 +32,97 @@ std::optional<uint32_t> ParseHexColor(std::string_view c)
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<int, int, int> ExtractRGB(uint32_t rgbaColor)
|
||||
{
|
||||
return {(rgbaColor >> 24) & 0xFF, (rgbaColor >> 16) & 0xFF, (rgbaColor >> 8) & 0xFF};
|
||||
}
|
||||
|
||||
static int ColorDistance(uint32_t rgbaColor1, uint32_t rgbaColor2)
|
||||
{
|
||||
auto const [r1, g1, b1] = ExtractRGB(rgbaColor1);
|
||||
auto const [r2, g2, b2] = ExtractRGB(rgbaColor2);
|
||||
return (r1 - r2) * (r1 - r2) + (g1 - g2) * (g1 - g2) + (b1 - b2) * (b1 - b2);
|
||||
}
|
||||
|
||||
struct RGBAToGarmin
|
||||
{
|
||||
uint32_t rgba;
|
||||
std::string_view color;
|
||||
};
|
||||
|
||||
auto constexpr kRGBAToGarmin = std::to_array<RGBAToGarmin>({{0x000000ff, "Black"},
|
||||
{0x8b0000ff, "DarkRed"},
|
||||
{0x006400ff, "DarkGreen"},
|
||||
{0xb5b820ff, "DarkYellow"},
|
||||
{0x00008bff, "DarkBlue"},
|
||||
{0x8b008bff, "DarkMagenta"},
|
||||
{0x008b8bff, "DarkCyan"},
|
||||
{0xccccccff, "LightGray"},
|
||||
{0x444444ff, "DarkGray"},
|
||||
{0xff0000ff, "Red"},
|
||||
{0x00ff00ff, "Green"},
|
||||
{0xffff00ff, "Yellow"},
|
||||
{0x0000ffff, "Blue"},
|
||||
{0xff00ffff, "Magenta"},
|
||||
{0x00ffffff, "Cyan"},
|
||||
{0xffffffff, "White"}});
|
||||
|
||||
std::string_view MapGarminColor(uint32_t rgba)
|
||||
{
|
||||
std::string_view closestColor = kRGBAToGarmin[0].color;
|
||||
auto minDistance = std::numeric_limits<int>::max();
|
||||
for (auto const & [rgbaGarmin, color] : kRGBAToGarmin)
|
||||
{
|
||||
auto const distance = ColorDistance(rgba, rgbaGarmin);
|
||||
|
||||
if (distance == 0)
|
||||
return color; // Exact match.
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
closestColor = color;
|
||||
}
|
||||
}
|
||||
return closestColor;
|
||||
}
|
||||
|
||||
struct RGBAToPredefined
|
||||
{
|
||||
uint32_t rgba;
|
||||
PredefinedColor predefinedColor;
|
||||
};
|
||||
|
||||
static std::array<RGBAToPredefined, kOrderedPredefinedColors.size()> buildRGBAToPredefined()
|
||||
{
|
||||
auto res = std::array<RGBAToPredefined, kOrderedPredefinedColors.size()>();
|
||||
for (size_t i = 0; i < kOrderedPredefinedColors.size(); ++i)
|
||||
res[i] = {ColorFromPredefinedColor(kOrderedPredefinedColors[i]).GetRGBA(), kOrderedPredefinedColors[i]};
|
||||
return res;
|
||||
}
|
||||
|
||||
auto const kRGBAToPredefined = buildRGBAToPredefined();
|
||||
|
||||
PredefinedColor MapPredefinedColor(uint32_t rgba)
|
||||
{
|
||||
auto closestColor = kRGBAToPredefined[0].predefinedColor;
|
||||
auto minDistance = std::numeric_limits<int>::max();
|
||||
for (auto const & [rgbaGarmin, color] : kRGBAToPredefined)
|
||||
{
|
||||
auto const distance = ColorDistance(rgba, rgbaGarmin);
|
||||
|
||||
if (distance == 0)
|
||||
return color; // Exact match.
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
closestColor = color;
|
||||
}
|
||||
}
|
||||
return closestColor;
|
||||
}
|
||||
|
||||
// Garmin extensions spec: https://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd
|
||||
// Color mapping: https://help.locusmap.eu/topic/extend-garmin-gpx-compatibilty
|
||||
std::optional<uint32_t> ParseGarminColor(std::string_view c)
|
||||
|
||||
Reference in New Issue
Block a user