geometry : allow boost::geoemetry algorithms to work directly with box2d<double>, removing bounding_box

This commit is contained in:
artemp 2015-04-09 12:33:31 +02:00
parent 2581e48087
commit 3f1aa7b4b4
6 changed files with 33 additions and 110 deletions

View file

@ -368,8 +368,7 @@ public:
mapnik::geometry::polygon & poly = mapnik::util::get<mapnik::geometry::polygon>(geom); mapnik::geometry::polygon & poly = mapnik::util::get<mapnik::geometry::polygon>(geom);
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
std::deque<mapnik::geometry::polygon> result; std::deque<mapnik::geometry::polygon> result;
mapnik::geometry::bounding_box bbox(extent_.minx(),extent_.miny(),extent_.maxx(),extent_.maxy()); boost::geometry::intersection(extent_,poly,result);
boost::geometry::intersection(bbox,poly,result);
std::string expect = expected_+".png"; std::string expect = expected_+".png";
std::string actual = expected_+"_actual.png"; std::string actual = expected_+"_actual.png";
mapnik::geometry::multi_polygon mp; mapnik::geometry::multi_polygon mp;
@ -407,12 +406,11 @@ public:
} }
mapnik::geometry::polygon & poly = mapnik::util::get<mapnik::geometry::polygon>(geom); mapnik::geometry::polygon & poly = mapnik::util::get<mapnik::geometry::polygon>(geom);
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
mapnik::geometry::bounding_box bbox(extent_.minx(),extent_.miny(),extent_.maxx(),extent_.maxy());
bool valid = true; bool valid = true;
for (unsigned i=0;i<iterations_;++i) for (unsigned i=0;i<iterations_;++i)
{ {
std::deque<mapnik::geometry::polygon> result; std::deque<mapnik::geometry::polygon> result;
boost::geometry::intersection(bbox,poly,result); boost::geometry::intersection(extent_,poly,result);
unsigned count = 0; unsigned count = 0;
for (auto const& geom : result) for (auto const& geom : result)
{ {
@ -567,12 +565,11 @@ public:
} }
mapnik::geometry::polygon & poly = mapnik::util::get<mapnik::geometry::polygon>(geom); mapnik::geometry::polygon & poly = mapnik::util::get<mapnik::geometry::polygon>(geom);
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
mapnik::geometry::bounding_box bbox(extent_.minx(),extent_.miny(),extent_.maxx(),extent_.maxy());
bool valid = true; bool valid = true;
for (unsigned i=0;i<iterations_;++i) for (unsigned i=0;i<iterations_;++i)
{ {
std::deque<mapnik::geometry::polygon> result; std::deque<mapnik::geometry::polygon> result;
boost::geometry::intersection(bbox,poly,result); boost::geometry::intersection(extent_,poly,result);
unsigned count = 0; unsigned count = 0;
for (auto const& geom : result) for (auto const& geom : result)
{ {

View file

@ -24,7 +24,7 @@
#define MAPNIK_GEOMETRY_HPP #define MAPNIK_GEOMETRY_HPP
#include <mapnik/util/variant.hpp> #include <mapnik/util/variant.hpp>
#include <mapnik/coord.hpp>
#include <vector> #include <vector>
#include <type_traits> #include <type_traits>
#include <cstddef> #include <cstddef>
@ -38,6 +38,9 @@ struct point
point(double x_, double y_) point(double x_, double y_)
: x(x_), y(y_) : x(x_), y(y_)
{} {}
// temp - remove when geometry is templated on value_type
point(mapnik::coord<double, 2> const& c)
: x(c.x), y(c.y) {}
point(point const& other) = default; point(point const& other) = default;
point(point && other) noexcept = default; point(point && other) noexcept = default;
@ -46,16 +49,6 @@ struct point
value_type y; value_type y;
}; };
struct bounding_box
{
bounding_box() {} // no-init
bounding_box(double lox, double loy, double hix, double hiy)
: p0(lox,loy),
p1(hix,hiy) {}
point p0;
point p1;
};
struct line_string : std::vector<point> struct line_string : std::vector<point>
{ {
line_string() = default; line_string() = default;

View file

@ -34,12 +34,17 @@
#include <boost/geometry/core/mutable_range.hpp> #include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/core/tag.hpp> #include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp> #include <boost/geometry/core/tags.hpp>
//
#include <mapnik/box2d.hpp>
// register point // register point
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, double, cs::cartesian, x, y) BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point, double, cs::cartesian, x, y)
// ring // ring
BOOST_GEOMETRY_REGISTER_RING(mapnik::geometry::linear_ring) BOOST_GEOMETRY_REGISTER_RING(mapnik::geometry::linear_ring)
// needed by box2d<double>
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, cs::cartesian, x, y)
namespace boost { namespace boost {
template <> template <>
@ -69,39 +74,45 @@ range_end(mapnik::geometry::line_string const& line) {return line.end();}
namespace geometry { namespace traits { namespace geometry { namespace traits {
template<> struct tag<mapnik::geometry::bounding_box> { using type = box_tag; }; // register mapnik::box2d<double>
template<> struct point_type<mapnik::geometry::bounding_box> { using type = mapnik::geometry::point; }; template<> struct tag<mapnik::box2d<double> > { using type = box_tag; };
template<> struct point_type<mapnik::box2d<double> > { using type = mapnik::coord2d; };
template <> template <>
struct indexed_access<mapnik::geometry::bounding_box, min_corner, 0> struct indexed_access<mapnik::box2d<double>, min_corner, 0>
{ {
static inline double get(mapnik::geometry::bounding_box const& b) { return b.p0.x;} using ct = coordinate_type<mapnik::coord2d>::type;
static inline void set(mapnik::geometry::bounding_box& b, double value) { b.p0.x = value; } static inline ct get(mapnik::box2d<double> const& b) { return b.minx();}
static inline void set(mapnik::box2d<double> &b, ct const& value) { b.set_minx(value); }
}; };
template <> template <>
struct indexed_access<mapnik::geometry::bounding_box, min_corner, 1> struct indexed_access<mapnik::box2d<double>, min_corner, 1>
{ {
static inline double get(mapnik::geometry::bounding_box const& b) { return b.p0.y;} using ct = coordinate_type<mapnik::coord2d>::type;
static inline void set(mapnik::geometry::bounding_box& b, double value) { b.p0.y = value; } static inline ct get(mapnik::box2d<double> const& b) { return b.miny();}
static inline void set(mapnik::box2d<double> &b, ct const& value) { b.set_miny(value); }
}; };
template <> template <>
struct indexed_access<mapnik::geometry::bounding_box, max_corner, 0> struct indexed_access<mapnik::box2d<double>, max_corner, 0>
{ {
static inline double get(mapnik::geometry::bounding_box const& b) { return b.p1.x;} using ct = coordinate_type<mapnik::coord2d>::type;
static inline void set(mapnik::geometry::bounding_box& b, double value) { b.p1.x = value; } static inline ct get(mapnik::box2d<double> const& b) { return b.maxx();}
static inline void set(mapnik::box2d<double> &b, ct const& value) { b.set_maxx(value); }
}; };
template <> template <>
struct indexed_access<mapnik::geometry::bounding_box, max_corner, 1> struct indexed_access<mapnik::box2d<double>, max_corner, 1>
{ {
static inline double get(mapnik::geometry::bounding_box const& b) { return b.p1.y;} using ct = coordinate_type<mapnik::coord2d>::type;
static inline void set(mapnik::geometry::bounding_box& b, double value) { b.p1.y = value; } static inline ct get(mapnik::box2d<double> const& b) { return b.maxy();}
static inline void set(mapnik::box2d<double> &b , ct const& value) { b.set_maxy(value); }
}; };
// mapnik::geometry::line_string
template<> template<>
struct tag<mapnik::geometry::line_string> struct tag<mapnik::geometry::line_string>
{ {

View file

@ -220,7 +220,7 @@ void apply_markers_multi(feature_impl const& feature, attributes const& vars, Co
multi_policy == MARKER_WHOLE_MULTI) multi_policy == MARKER_WHOLE_MULTI)
{ {
geometry::point pt; geometry::point pt;
if (geometry::centroid(geom, pt)) if (geometry::centroid(geom, pt) && converter.disp_.args_.bbox.contains(pt.x, pt.y))
{ {
// unset any clipping since we're now dealing with a point // unset any clipping since we're now dealing with a point
converter.template unset<clip_poly_tag>(); converter.template unset<clip_poly_tag>();

View file

@ -1,77 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 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
*
*****************************************************************************/
#ifndef BOOST_GEOMETRY_ADAPTERS_HPP
#define BOOST_GEOMETRY_ADAPTERS_HPP
// boost
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/register/point.hpp>
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, cs::cartesian, x, y)
// register mapnik::box2d<double>
namespace boost { namespace geometry { namespace traits
{
template<> struct tag<mapnik::box2d<double> > { using type = box_tag; };
template<> struct point_type<mapnik::box2d<double> > { using type = mapnik::coord2d; };
template <>
struct indexed_access<mapnik::box2d<double>, min_corner, 0>
{
using ct = coordinate_type<mapnik::coord2d>::type;
static inline ct get(mapnik::box2d<double> const& b) { return b.minx();}
static inline void set(mapnik::box2d<double> &b, ct const& value) { b.set_minx(value); }
};
template <>
struct indexed_access<mapnik::box2d<double>, min_corner, 1>
{
using ct = coordinate_type<mapnik::coord2d>::type;
static inline ct get(mapnik::box2d<double> const& b) { return b.miny();}
static inline void set(mapnik::box2d<double> &b, ct const& value) { b.set_miny(value); }
};
template <>
struct indexed_access<mapnik::box2d<double>, max_corner, 0>
{
using ct = coordinate_type<mapnik::coord2d>::type;
static inline ct get(mapnik::box2d<double> const& b) { return b.maxx();}
static inline void set(mapnik::box2d<double> &b, ct const& value) { b.set_maxx(value); }
};
template <>
struct indexed_access<mapnik::box2d<double>, max_corner, 1>
{
using ct = coordinate_type<mapnik::coord2d>::type;
static inline ct get(mapnik::box2d<double> const& b) { return b.maxy();}
static inline void set(mapnik::box2d<double> &b , ct const& value) { b.set_maxy(value); }
};
}}}
#endif //BOOST_GEOMETRY_ADAPTERS_HPP

View file

@ -47,7 +47,6 @@
#include <mapnik/make_unique.hpp> #include <mapnik/make_unique.hpp>
#include <mapnik/json/feature_collection_grammar.hpp> #include <mapnik/json/feature_collection_grammar.hpp>
#include <mapnik/json/extract_bounding_box_grammar_impl.hpp> #include <mapnik/json/extract_bounding_box_grammar_impl.hpp>
#include <mapnik/util/boost_geometry_adapters.hpp> // boost.geometry - register box2d<double>
#if defined(SHAPE_MEMORY_MAPPED_FILE) #if defined(SHAPE_MEMORY_MAPPED_FILE)
#include <boost/interprocess/mapped_region.hpp> #include <boost/interprocess/mapped_region.hpp>