From 6105463602cfe75248d398a42003e39cdc6b0f99 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 20 Apr 2016 10:51:33 +0200 Subject: [PATCH] split box2d implementation into *.hpp, *._impl.hpp and *.cpp ref #3405 --- include/mapnik/box2d.hpp | 5 +- include/mapnik/box2d_impl.hpp | 496 ++++++++++++++++++++++++++++++++++ src/box2d.cpp | 475 +------------------------------- 3 files changed, 501 insertions(+), 475 deletions(-) create mode 100644 include/mapnik/box2d_impl.hpp diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp index a790c1d24..267120111 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/box2d.hpp @@ -40,9 +40,8 @@ struct trans_affine; namespace mapnik { -/*! - * A spatial envelope (i.e. bounding box) which also defines some basic operators. - */ +// A spatial envelope (i.e. bounding box) which also defines some basic operators. + template class MAPNIK_DECL box2d : boost::equality_comparable , boost::addable, diff --git a/include/mapnik/box2d_impl.hpp b/include/mapnik/box2d_impl.hpp new file mode 100644 index 000000000..7f3e9d1e7 --- /dev/null +++ b/include/mapnik/box2d_impl.hpp @@ -0,0 +1,496 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include + +// stl +#include +#include +#include + +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#pragma GCC diagnostic pop + +// agg +#include "agg_trans_affine.h" + +BOOST_FUSION_ADAPT_TPL_ADT( + (T), + (mapnik::box2d)(T), + (T, T, obj.minx(), obj.set_minx(mapnik::safe_cast(val))) + (T, T, obj.miny(), obj.set_miny(mapnik::safe_cast(val))) + (T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast(val))) + (T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast(val)))) + +namespace mapnik +{ +template +box2d::box2d() + :minx_( std::numeric_limits::max()), + miny_( std::numeric_limits::max()), + maxx_(-std::numeric_limits::max()), + maxy_(-std::numeric_limits::max()) {} + +template +box2d::box2d(T minx,T miny,T maxx,T maxy) +{ + init(minx,miny,maxx,maxy); +} + +template +box2d::box2d(coord const& c0, coord const& c1) +{ + init(c0.x,c0.y,c1.x,c1.y); +} + +template +box2d::box2d(box2d_type const& rhs) + : minx_(rhs.minx_), + miny_(rhs.miny_), + maxx_(rhs.maxx_), + maxy_(rhs.maxy_) {} + +template +box2d::box2d(box2d_type && rhs) + : minx_(std::move(rhs.minx_)), + miny_(std::move(rhs.miny_)), + maxx_(std::move(rhs.maxx_)), + maxy_(std::move(rhs.maxy_)) {} + +template +box2d& box2d::operator=(box2d_type other) +{ + swap(*this, other); + return *this; +} + +template +box2d::box2d(box2d_type const& rhs, agg::trans_affine const& tr) +{ + double x0 = rhs.minx_, y0 = rhs.miny_; + double x1 = rhs.maxx_, y1 = rhs.miny_; + double x2 = rhs.maxx_, y2 = rhs.maxy_; + double x3 = rhs.minx_, y3 = rhs.maxy_; + tr.transform(&x0, &y0); + tr.transform(&x1, &y1); + tr.transform(&x2, &y2); + tr.transform(&x3, &y3); + init(static_cast(x0), static_cast(y0), + static_cast(x2), static_cast(y2)); + expand_to_include(static_cast(x1), static_cast(y1)); + expand_to_include(static_cast(x3), static_cast(y3)); +} + +template +bool box2d::operator==(box2d const& other) const +{ + return minx_==other.minx_ && + miny_==other.miny_ && + maxx_==other.maxx_ && + maxy_==other.maxy_; +} + +template +T box2d::minx() const +{ + return minx_; +} + +template +T box2d::maxx() const +{ + return maxx_; +} + +template +T box2d::miny() const +{ + return miny_; +} + +template +T box2d::maxy() const +{ + return maxy_; +} + +template +void box2d::set_minx(T v) +{ + minx_ = v; +} + +template +void box2d::set_miny(T v) +{ + miny_ = v; +} + +template +void box2d::set_maxx(T v) +{ + maxx_ = v; +} + +template +void box2d::set_maxy(T v) +{ + maxy_ = v; +} + +template +T box2d::width() const +{ + return maxx_-minx_; +} + +template +T box2d::height() const +{ + return maxy_-miny_; +} + +template +void box2d::width(T w) +{ + T cx=center().x; + minx_=static_cast(cx-w*0.5); + maxx_=static_cast(cx+w*0.5); +} + +template +void box2d::height(T h) +{ + T cy=center().y; + miny_=static_cast(cy-h*0.5); + maxy_=static_cast(cy+h*0.5); +} + +template +coord box2d::center() const +{ + return coord(static_cast(0.5*(minx_+maxx_)), + static_cast(0.5*(miny_+maxy_))); +} + +template +void box2d::expand_to_include(coord const& c) +{ + expand_to_include(c.x,c.y); +} + +template +void box2d::expand_to_include(T x,T y) +{ + if (xmaxx_) maxx_=x; + if (ymaxy_) maxy_=y; +} + +template +void box2d::expand_to_include(box2d const& other) +{ + if (other.minx_maxx_) maxx_=other.maxx_; + if (other.miny_maxy_) maxy_=other.maxy_; +} + +template +bool box2d::contains(coord const& c) const +{ + return contains(c.x,c.y); +} + +template +bool box2d::contains(T x,T y) const +{ + return x>=minx_ && x<=maxx_ && y>=miny_ && y<=maxy_; +} + +template +bool box2d::contains(box2d const& other) const +{ + return other.minx_>=minx_ && + other.maxx_<=maxx_ && + other.miny_>=miny_ && + other.maxy_<=maxy_; +} + +template +bool box2d::intersects(coord const& c) const +{ + return intersects(c.x,c.y); +} + +template +bool box2d::intersects(T x,T y) const +{ + return !(x>maxx_ || xmaxy_ || y +bool box2d::intersects(box2d const& other) const +{ + return !(other.minx_>maxx_ || other.maxx_maxy_ || other.maxy_ +box2d box2d::intersect(box2d_type const& other) const +{ + if (intersects(other)) + { + T x0=std::max(minx_,other.minx_); + T y0=std::max(miny_,other.miny_); + T x1=std::min(maxx_,other.maxx_); + T y1=std::min(maxy_,other.maxy_); + return box2d(x0,y0,x1,y1); + } + else + { + return box2d(); + } +} + +template +void box2d::re_center(T cx,T cy) +{ + T dx=cx-center().x; + T dy=cy-center().y; + minx_+=dx; + miny_+=dy; + maxx_+=dx; + maxy_+=dy; +} + +template +void box2d::re_center(coord const& c) +{ + re_center(c.x,c.y); +} + +template +void box2d::init(T x0, T y0, T x1, T y1) +{ + if (x0 < x1) + { + minx_ = x0; + maxx_ = x1; + } + else + { + minx_ = x1; + maxx_ = x0; + } + if (y0 < y1) + { + miny_ = y0; + maxy_ = y1; + } + else + { + miny_ = y1; + maxy_ = y0; + } +} + +template +void box2d::init(T x, T y) +{ + init(x, y, x, y); +} + +template +void box2d::clip(box2d_type const& other) +{ + minx_ = std::max(minx_, other.minx()); + miny_ = std::max(miny_, other.miny()); + maxx_ = std::min(maxx_, other.maxx()); + maxy_ = std::min(maxy_, other.maxy()); +} + +template +void box2d::pad(T padding) +{ + minx_ -= padding; + miny_ -= padding; + maxx_ += padding; + maxy_ += padding; +} + +template +bool box2d::from_string(std::string const& str) +{ + boost::spirit::qi::lit_type lit; + boost::spirit::qi::double_type double_; + boost::spirit::ascii::space_type space; + bool r = boost::spirit::qi::phrase_parse(str.begin(), + str.end(), + double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_, + space, + *this); + return r; +} + +template +bool box2d::valid() const +{ + return (minx_ <= maxx_ && miny_ <= maxy_) ; +} + +template +void box2d::move(T x, T y) +{ + minx_ += x; + maxx_ += x; + miny_ += y; + maxy_ += y; +} + +template +std::string box2d::to_string() const +{ + std::ostringstream s; + if (valid()) + { + s << "box2d(" << std::fixed << std::setprecision(16) + << minx_ << ',' << miny_ << ',' + << maxx_ << ',' << maxy_ << ')'; + } + else + { + s << "box2d(INVALID)"; + } + return s.str(); +} + + +template +box2d& box2d::operator+=(box2d const& other) +{ + expand_to_include(other); + return *this; +} + +template +box2d box2d::operator+ (T other) const +{ + return box2d(minx_ - other, miny_ - other, maxx_ + other, maxy_ + other); +} + +template +box2d& box2d::operator+= (T other) +{ + minx_ -= other; + miny_ -= other; + maxx_ += other; + maxy_ += other; + return *this; +} + + +template +box2d& box2d::operator*=(T t) +{ + coord c = center(); + T sx = static_cast(0.5 * width() * t); + T sy = static_cast(0.5 * height() * t); + minx_ = c.x - sx; + maxx_ = c.x + sx; + miny_ = c.y - sy; + maxy_ = c.y + sy; + return *this; +} + +template +box2d& box2d::operator/=(T t) +{ + coord c = center(); + T sx = static_cast(0.5 * width() / t); + T sy = static_cast(0.5 * height() / t); + minx_ = c.x - sx; + maxx_ = c.x + sx; + miny_ = c.y - sy; + maxy_ = c.y + sy; + return *this; +} + +template +T box2d::operator[] (int index) const +{ + switch(index) + { + case 0: + return minx_; + case 1: + return miny_; + case 2: + return maxx_; + case 3: + return maxy_; + case -4: + return minx_; + case -3: + return miny_; + case -2: + return maxx_; + case -1: + return maxy_; + default: + throw std::out_of_range("index out of range, max value is 3, min value is -4 "); + } +} + +template +box2d box2d::operator*(agg::trans_affine const& tr) const +{ + return box2d(*this, tr); +} + +template +box2d& box2d::operator*=(agg::trans_affine const& tr) +{ + double x0 = minx_, y0 = miny_; + double x1 = maxx_, y1 = miny_; + double x2 = maxx_, y2 = maxy_; + double x3 = minx_, y3 = maxy_; + tr.transform(&x0, &y0); + tr.transform(&x1, &y1); + tr.transform(&x2, &y2); + tr.transform(&x3, &y3); + init(static_cast(x0), static_cast(y0), + static_cast(x2), static_cast(y2)); + expand_to_include(static_cast(x1), static_cast(y1)); + expand_to_include(static_cast(x3), static_cast(y3)); + return *this; +} +} diff --git a/src/box2d.cpp b/src/box2d.cpp index 7d54233f0..407c054ba 100644 --- a/src/box2d.cpp +++ b/src/box2d.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,478 +21,9 @@ *****************************************************************************/ // mapnik -#include -#include +#include -// stl -#include -#include -#include - -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#pragma GCC diagnostic pop - -// agg -#include "agg_trans_affine.h" - -BOOST_FUSION_ADAPT_TPL_ADT( - (T), - (mapnik::box2d)(T), - (T, T, obj.minx(), obj.set_minx(mapnik::safe_cast(val))) - (T, T, obj.miny(), obj.set_miny(mapnik::safe_cast(val))) - (T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast(val))) - (T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast(val)))) - -namespace mapnik -{ -template -box2d::box2d() - :minx_( std::numeric_limits::max()), - miny_( std::numeric_limits::max()), - maxx_(-std::numeric_limits::max()), - maxy_(-std::numeric_limits::max()) {} - -template -box2d::box2d(T minx,T miny,T maxx,T maxy) -{ - init(minx,miny,maxx,maxy); -} - -template -box2d::box2d(coord const& c0, coord const& c1) -{ - init(c0.x,c0.y,c1.x,c1.y); -} - -template -box2d::box2d(box2d_type const& rhs) - : minx_(rhs.minx_), - miny_(rhs.miny_), - maxx_(rhs.maxx_), - maxy_(rhs.maxy_) {} - -template -box2d::box2d(box2d_type && rhs) - : minx_(std::move(rhs.minx_)), - miny_(std::move(rhs.miny_)), - maxx_(std::move(rhs.maxx_)), - maxy_(std::move(rhs.maxy_)) {} - -template -box2d& box2d::operator=(box2d_type other) -{ - swap(*this, other); - return *this; -} - -template -box2d::box2d(box2d_type const& rhs, agg::trans_affine const& tr) -{ - double x0 = rhs.minx_, y0 = rhs.miny_; - double x1 = rhs.maxx_, y1 = rhs.miny_; - double x2 = rhs.maxx_, y2 = rhs.maxy_; - double x3 = rhs.minx_, y3 = rhs.maxy_; - tr.transform(&x0, &y0); - tr.transform(&x1, &y1); - tr.transform(&x2, &y2); - tr.transform(&x3, &y3); - init(static_cast(x0), static_cast(y0), - static_cast(x2), static_cast(y2)); - expand_to_include(static_cast(x1), static_cast(y1)); - expand_to_include(static_cast(x3), static_cast(y3)); -} - -template -bool box2d::operator==(box2d const& other) const -{ - return minx_==other.minx_ && - miny_==other.miny_ && - maxx_==other.maxx_ && - maxy_==other.maxy_; -} - -template -T box2d::minx() const -{ - return minx_; -} - -template -T box2d::maxx() const -{ - return maxx_; -} - -template -T box2d::miny() const -{ - return miny_; -} - -template -T box2d::maxy() const -{ - return maxy_; -} - -template -void box2d::set_minx(T v) -{ - minx_ = v; -} - -template -void box2d::set_miny(T v) -{ - miny_ = v; -} - -template -void box2d::set_maxx(T v) -{ - maxx_ = v; -} - -template -void box2d::set_maxy(T v) -{ - maxy_ = v; -} - -template -T box2d::width() const -{ - return maxx_-minx_; -} - -template -T box2d::height() const -{ - return maxy_-miny_; -} - -template -void box2d::width(T w) -{ - T cx=center().x; - minx_=static_cast(cx-w*0.5); - maxx_=static_cast(cx+w*0.5); -} - -template -void box2d::height(T h) -{ - T cy=center().y; - miny_=static_cast(cy-h*0.5); - maxy_=static_cast(cy+h*0.5); -} - -template -coord box2d::center() const -{ - return coord(static_cast(0.5*(minx_+maxx_)), - static_cast(0.5*(miny_+maxy_))); -} - -template -void box2d::expand_to_include(coord const& c) -{ - expand_to_include(c.x,c.y); -} - -template -void box2d::expand_to_include(T x,T y) -{ - if (xmaxx_) maxx_=x; - if (ymaxy_) maxy_=y; -} - -template -void box2d::expand_to_include(box2d const& other) -{ - if (other.minx_maxx_) maxx_=other.maxx_; - if (other.miny_maxy_) maxy_=other.maxy_; -} - -template -bool box2d::contains(coord const& c) const -{ - return contains(c.x,c.y); -} - -template -bool box2d::contains(T x,T y) const -{ - return x>=minx_ && x<=maxx_ && y>=miny_ && y<=maxy_; -} - -template -bool box2d::contains(box2d const& other) const -{ - return other.minx_>=minx_ && - other.maxx_<=maxx_ && - other.miny_>=miny_ && - other.maxy_<=maxy_; -} - -template -bool box2d::intersects(coord const& c) const -{ - return intersects(c.x,c.y); -} - -template -bool box2d::intersects(T x,T y) const -{ - return !(x>maxx_ || xmaxy_ || y -bool box2d::intersects(box2d const& other) const -{ - return !(other.minx_>maxx_ || other.maxx_maxy_ || other.maxy_ -box2d box2d::intersect(box2d_type const& other) const -{ - if (intersects(other)) - { - T x0=std::max(minx_,other.minx_); - T y0=std::max(miny_,other.miny_); - T x1=std::min(maxx_,other.maxx_); - T y1=std::min(maxy_,other.maxy_); - return box2d(x0,y0,x1,y1); - } - else - { - return box2d(); - } -} - -template -void box2d::re_center(T cx,T cy) -{ - T dx=cx-center().x; - T dy=cy-center().y; - minx_+=dx; - miny_+=dy; - maxx_+=dx; - maxy_+=dy; -} - -template -void box2d::re_center(coord const& c) -{ - re_center(c.x,c.y); -} - -template -void box2d::init(T x0, T y0, T x1, T y1) -{ - if (x0 < x1) - { - minx_ = x0; - maxx_ = x1; - } - else - { - minx_ = x1; - maxx_ = x0; - } - if (y0 < y1) - { - miny_ = y0; - maxy_ = y1; - } - else - { - miny_ = y1; - maxy_ = y0; - } -} - -template -void box2d::init(T x, T y) -{ - init(x, y, x, y); -} - -template -void box2d::clip(box2d_type const& other) -{ - minx_ = std::max(minx_, other.minx()); - miny_ = std::max(miny_, other.miny()); - maxx_ = std::min(maxx_, other.maxx()); - maxy_ = std::min(maxy_, other.maxy()); -} - -template -void box2d::pad(T padding) -{ - minx_ -= padding; - miny_ -= padding; - maxx_ += padding; - maxy_ += padding; -} - -template -bool box2d::from_string(std::string const& str) -{ - boost::spirit::qi::lit_type lit; - boost::spirit::qi::double_type double_; - boost::spirit::ascii::space_type space; - bool r = boost::spirit::qi::phrase_parse(str.begin(), - str.end(), - double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_, - space, - *this); - return r; -} - -template -bool box2d::valid() const -{ - return (minx_ <= maxx_ && miny_ <= maxy_) ; -} - -template -void box2d::move(T x, T y) -{ - minx_ += x; - maxx_ += x; - miny_ += y; - maxy_ += y; -} - -template -std::string box2d::to_string() const -{ - std::ostringstream s; - if (valid()) - { - s << "box2d(" << std::fixed << std::setprecision(16) - << minx_ << ',' << miny_ << ',' - << maxx_ << ',' << maxy_ << ')'; - } - else - { - s << "box2d(INVALID)"; - } - return s.str(); -} - - -template -box2d& box2d::operator+=(box2d const& other) -{ - expand_to_include(other); - return *this; -} - -template -box2d box2d::operator+ (T other) const -{ - return box2d(minx_ - other, miny_ - other, maxx_ + other, maxy_ + other); -} - -template -box2d& box2d::operator+= (T other) -{ - minx_ -= other; - miny_ -= other; - maxx_ += other; - maxy_ += other; - return *this; -} - - -template -box2d& box2d::operator*=(T t) -{ - coord c = center(); - T sx = static_cast(0.5 * width() * t); - T sy = static_cast(0.5 * height() * t); - minx_ = c.x - sx; - maxx_ = c.x + sx; - miny_ = c.y - sy; - maxy_ = c.y + sy; - return *this; -} - -template -box2d& box2d::operator/=(T t) -{ - coord c = center(); - T sx = static_cast(0.5 * width() / t); - T sy = static_cast(0.5 * height() / t); - minx_ = c.x - sx; - maxx_ = c.x + sx; - miny_ = c.y - sy; - maxy_ = c.y + sy; - return *this; -} - -template -T box2d::operator[] (int index) const -{ - switch(index) - { - case 0: - return minx_; - case 1: - return miny_; - case 2: - return maxx_; - case 3: - return maxy_; - case -4: - return minx_; - case -3: - return miny_; - case -2: - return maxx_; - case -1: - return maxy_; - default: - throw std::out_of_range("index out of range, max value is 3, min value is -4 "); - } -} - -template -box2d box2d::operator*(agg::trans_affine const& tr) const -{ - return box2d(*this, tr); -} - -template -box2d& box2d::operator*=(agg::trans_affine const& tr) -{ - double x0 = minx_, y0 = miny_; - double x1 = maxx_, y1 = miny_; - double x2 = maxx_, y2 = maxy_; - double x3 = minx_, y3 = maxy_; - tr.transform(&x0, &y0); - tr.transform(&x1, &y1); - tr.transform(&x2, &y2); - tr.transform(&x3, &y3); - init(static_cast(x0), static_cast(y0), - static_cast(x2), static_cast(y2)); - expand_to_include(static_cast(x1), static_cast(y1)); - expand_to_include(static_cast(x3), static_cast(y3)); - return *this; -} +namespace mapnik { template class box2d; template class box2d;