diff --git a/include/mapnik/raster_colorizer.hpp b/include/mapnik/raster_colorizer.hpp index dc76e5eba..506224cb6 100644 --- a/include/mapnik/raster_colorizer.hpp +++ b/include/mapnik/raster_colorizer.hpp @@ -32,164 +32,165 @@ #include -using mapnik::color; -using std::vector; - namespace mapnik { - struct MAPNIK_DECL color_band +struct MAPNIK_DECL color_band +{ + float value_; + color color_; + unsigned midpoints_; + bool is_interpolated_; + color_band(float value, color c) + : value_(value), + color_(c), + midpoints_(0), + is_interpolated_(false) {} + const bool is_interpolated() const { - float value_; - color color_; - unsigned midpoints_; - bool is_interpolated_; - color_band(float value, color c) - : value_(value), - color_(c), - midpoints_(0), - is_interpolated_(false) {} - const bool is_interpolated() const - { - return is_interpolated_; - } - const unsigned get_midpoints() const - { - return midpoints_; - } - const float get_value() const - { - return value_; - } - const color& get_color() const - { - return color_; - } - bool operator==(color_band const& other) const - { - return value_ == other.value_ && color_ == other.color_; - } - std::string to_string() const - { - std::stringstream ss; - ss << color_.to_string() << " " << value_; - return ss.str(); - } - }; - - typedef vector color_bands; - - struct MAPNIK_DECL raster_colorizer + return is_interpolated_; + } + const unsigned get_midpoints() const { - explicit raster_colorizer() - : colors_() {} + return midpoints_; + } + const float get_value() const + { + return value_; + } + const color& get_color() const + { + return color_; + } + bool operator==(color_band const& other) const + { + return value_ == other.value_ && color_ == other.color_; + } + std::string to_string() const + { + std::stringstream ss; + ss << color_.to_string() << " " << value_; + return ss.str(); + } +}; - raster_colorizer(const raster_colorizer &ps) - : colors_(ps.colors_) {} +typedef std::vector color_bands; - raster_colorizer(color_bands &colors) - : colors_(colors) {} +struct MAPNIK_DECL raster_colorizer +{ + explicit raster_colorizer() + : colors_() {} - const color_bands& get_color_bands() const - { - return colors_; - } - void append_band (color_band band) - { - if (colors_.size() > 0 && colors_.back().value_ > band.value_) { + raster_colorizer(const raster_colorizer &ps) + : colors_(ps.colors_) {} + + raster_colorizer(color_bands &colors) + : colors_(colors) {} + + const color_bands& get_color_bands() const + { + return colors_; + } + void append_band (color_band band) + { + if (colors_.size() > 0 && colors_.back().value_ > band.value_) { #ifdef MAPNIK_DEBUG - std::clog << "prev.v=" << colors_.back().value_ << ". band.v=" << band.value_ << "\n"; + std::clog << "prev.v=" << colors_.back().value_ << ". band.v=" << band.value_ << "\n"; #endif - throw config_error( - "Bands must be appended in ascending value order" - ); - } - colors_.push_back(band); - } - void append_band (color_band band, unsigned midpoints) - { - band.midpoints_ = midpoints; - if (colors_.size() > 0 && midpoints > 0) { - color_band lo = colors_.back(); - color_band const &hi = band; - int steps = midpoints+1; - float dv = (hi.value_ - lo.value_)/steps; - float da = (float(hi.color_.alpha()) - lo.color_.alpha())/steps; - float dr = (float(hi.color_.red()) - lo.color_.red())/steps; - float dg = (float(hi.color_.green()) - lo.color_.green())/steps; - float db = (float(hi.color_.blue()) - lo.color_.blue())/steps; + throw config_error( + "Bands must be appended in ascending value order" + ); + } + colors_.push_back(band); + } + void append_band (color_band band, unsigned midpoints) + { + band.midpoints_ = midpoints; + if (colors_.size() > 0 && midpoints > 0) { + color_band lo = colors_.back(); + color_band const &hi = band; + int steps = midpoints+1; + float dv = (hi.value_ - lo.value_)/steps; + float da = (float(hi.color_.alpha()) - lo.color_.alpha())/steps; + float dr = (float(hi.color_.red()) - lo.color_.red())/steps; + float dg = (float(hi.color_.green()) - lo.color_.green())/steps; + float db = (float(hi.color_.blue()) - lo.color_.blue())/steps; #ifdef MAPNIK_DEBUG - std::clog << "lo.v=" << lo.value_ << ", hi.v=" << hi.value_ << ", dv="<value) { - hi = pos-1; - } else { - lo = pos+1; - break; - } - } - lo--; - if ((0 <= lo && lo < last) || - (lo==last && colors_[last].value_==value)) - return colors_[lo].color_; - else - return color(0,0,0,0); - } + /* rgba = + * if cs[pos].value <= value < cs[pos+1].value: cs[pos].color + * otherwise: transparent + * where 0 <= pos < length(bands)-1 + * Last band is special, its value represents the upper bound and its + * color will only be used if the value matches its value exactly. + */ + color get_color(float value) const { + int pos=-1, last=(int)colors_.size()-1, lo=0, hi=last; + while (lo<=hi) { + pos = (lo+hi)/2; + if (colors_[pos].value_value) { + hi = pos-1; + } else { + lo = pos+1; + break; + } + } + lo--; + if ((0 <= lo && lo < last) || + (lo==last && colors_[last].value_==value)) + return colors_[lo].color_; + else + return color(0,0,0,0); + } - void colorize(mapnik::raster_ptr const& raster) const { - float *rasterData = (float*)raster->data_.getBytes(); - unsigned *imageData = raster->data_.getData(); - unsigned i; - for (i=0; idata_.width()*raster->data_.height(); i++) - imageData[i] = get_color(rasterData[i]).rgba(); - } + void colorize(raster_ptr const& raster) const + { + float *rasterData = reinterpret_cast(raster->data_.getBytes()); + unsigned *imageData = raster->data_.getData(); + unsigned i; + for (i=0; idata_.width()*raster->data_.height(); i++) + { + imageData[i] = get_color(rasterData[i]).rgba(); + } + } - private: - color_bands colors_; - }; +private: + color_bands colors_; +}; - typedef boost::shared_ptr raster_colorizer_ptr; -} +typedef boost::shared_ptr raster_colorizer_ptr; + +} // mapnik namespace #endif //RASTER_COLORIZER_HPP