From be05aa5b60f1ca5c65fcbae74b737b1b75a64bdc Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 30 Nov 2012 12:31:58 -0800 Subject: [PATCH] add palette.to_string() method and add python tests of fixed palette functionality --- bindings/python/mapnik_palette.cpp | 3 ++ include/mapnik/palette.hpp | 1 + src/palette.cpp | 30 +++++++++++ tests/data/palettes/palette256.act | Bin 0 -> 772 bytes tests/data/palettes/palette64.act | Bin 0 -> 772 bytes .../images/support/mapnik-palette-test.png | Bin 0 -> 12148 bytes tests/python_tests/palette_test.py | 49 ++++++++++++++++++ 7 files changed, 83 insertions(+) create mode 100644 tests/data/palettes/palette256.act create mode 100644 tests/data/palettes/palette64.act create mode 100644 tests/python_tests/images/support/mapnik-palette-test.png create mode 100644 tests/python_tests/palette_test.py diff --git a/bindings/python/mapnik_palette.cpp b/bindings/python/mapnik_palette.cpp index d21901735..16a614757 100644 --- a/bindings/python/mapnik_palette.cpp +++ b/bindings/python/mapnik_palette.cpp @@ -51,5 +51,8 @@ void export_palette () // "Creates a new color palette from a file\n" // ) .def( "__init__", boost::python::make_constructor(make_palette)) + .def("to_string", &mapnik::rgba_palette::to_string, + "Returns the palette as a string.\n" + ) ; } diff --git a/include/mapnik/palette.hpp b/include/mapnik/palette.hpp index 4dcbe2ab4..ed94fd07e 100644 --- a/include/mapnik/palette.hpp +++ b/include/mapnik/palette.hpp @@ -151,6 +151,7 @@ public: } bool valid() const; + std::string to_string() const; private: void parse(std::string const& pal, palette_type type); diff --git a/src/palette.cpp b/src/palette.cpp index f402b5dbd..669a44130 100644 --- a/src/palette.cpp +++ b/src/palette.cpp @@ -23,6 +23,10 @@ #include #include +// stl +#include +#include + namespace mapnik { @@ -74,6 +78,32 @@ bool rgba_palette::valid() const return colors_ > 0; } +std::string rgba_palette::to_string() const +{ + unsigned length = rgb_pal_.size(); + unsigned alphaLength = alpha_pal_.size(); + std::ostringstream str(""); + str << "[Palette " << length; + if (length == 1) + { + str << " color"; + } + else + { + str << " colors"; + } + str << std::hex << std::setfill('0'); + for (unsigned i = 0; i < length; i++) { + str << " #"; + str << std::setw(2) << (unsigned)rgb_pal_[i].r; + str << std::setw(2) << (unsigned)rgb_pal_[i].g; + str << std::setw(2) << (unsigned)rgb_pal_[i].b; + if (i < alphaLength) str << std::setw(2) << alpha_pal_[i]; + } + str << "]"; + return str.str(); +} + // return color index in returned earlier palette unsigned char rgba_palette::quantize(rgba const& c) const { diff --git a/tests/data/palettes/palette256.act b/tests/data/palettes/palette256.act new file mode 100644 index 0000000000000000000000000000000000000000..60ab72c457d959cf24008852471fbdba7f9c67f9 GIT binary patch literal 772 zcmWlO%}*Og0L7dCpod<2Myjf)hbl@X8a1k_P~{ehR6QW|R6;LprADBthbUFPHVt1T zX+tS#A$1&+gcM9-3~>x=*g6Yd)`LCZ@p>?mWx!*5AOo2;LwB>h!|(l`UPD7eV`F1e z(}~k3kAHFMvv~PUvK@WqrE-;?cqxoFPLZFnf>9zN9R86 zy?XxZzQ^6&-C^yUzMp?8o_nwJ`foRX{l&c2+%piWTz>y<|7Gp=Q{%>$<*ueb|G0$* z-+X!PNO|Zj-ghD#zT@{E9lzH#bbpeD-!6|F9(^#^PE$};zcSMHz)5)5jNzK&tVS!B<{ zg^dM*5yhZFViZGG%9V(_UrbU0DM9SH$uZigUwKjMWx*u4>Hypq0{92Q)jyZM|Q5-esbZaBUjHJS-SPooHIwZ{XXb^ z^~B&L%;cmI!q(GZ|41Q;Ct{|5k@9@!57 literal 0 HcmV?d00001 diff --git a/tests/python_tests/images/support/mapnik-palette-test.png b/tests/python_tests/images/support/mapnik-palette-test.png new file mode 100644 index 0000000000000000000000000000000000000000..e657620adecda0b657394e7895c640572ba8cbea GIT binary patch literal 12148 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