Merge pull request #3646 from mapnik/geometry.hpp

Geometry.hpp
This commit is contained in:
Artem Pavlenko 2017-03-30 09:35:56 +01:00 committed by GitHub
commit a6d3921957
68 changed files with 1291 additions and 1435 deletions

6
.gitmodules vendored
View file

@ -9,4 +9,8 @@
[submodule "deps/mapbox/variant"] [submodule "deps/mapbox/variant"]
path = deps/mapbox/variant path = deps/mapbox/variant
url = https://github.com/mapbox/variant.git url = https://github.com/mapbox/variant.git
branch = master branch = master
[submodule "deps/mapbox/geometry"]
path = deps/mapbox/geometry
url = https://github.com/mapbox/geometry.hpp.git
branch = master

View file

@ -1602,6 +1602,7 @@ if not preconfigured:
env.Prepend(CPPPATH = '#deps/agg/include') env.Prepend(CPPPATH = '#deps/agg/include')
env.Prepend(LIBPATH = '#deps/agg') env.Prepend(LIBPATH = '#deps/agg')
env.Prepend(CPPPATH = '#deps/mapbox/variant/include') env.Prepend(CPPPATH = '#deps/mapbox/variant/include')
env.Prepend(CPPPATH = '#deps/mapbox/geometry/include')
# prepend deps dir for auxillary headers # prepend deps dir for auxillary headers
env.Prepend(CPPPATH = '#deps') env.Prepend(CPPPATH = '#deps')

View file

@ -123,12 +123,12 @@ public:
if (cmd == mapnik::SEG_CLOSE) if (cmd == mapnik::SEG_CLOSE)
{ {
ring.add_coord(x0, y0); ring.emplace_back(x0, y0);
break; break;
} }
ring.add_coord(x,y); ring.emplace_back(x,y);
} }
poly2.set_exterior_ring(std::move(ring)); poly2.push_back(std::move(ring));
// interior rings // interior rings
ring.clear(); ring.clear();
while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END)
@ -139,12 +139,12 @@ public:
} }
else if (cmd == mapnik::SEG_CLOSE) else if (cmd == mapnik::SEG_CLOSE)
{ {
ring.add_coord(x0,y0); ring.emplace_back(x0,y0);
poly2.add_hole(std::move(ring)); poly2.push_back(std::move(ring));
ring.clear(); ring.clear();
continue; continue;
} }
ring.add_coord(x,y); ring.emplace_back(x,y);
} }
std::string expect = expected_+".png"; std::string expect = expected_+".png";
@ -243,11 +243,11 @@ public:
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
mapnik::geometry::linear_ring<double> bbox; mapnik::geometry::linear_ring<double> bbox;
bbox.add_coord(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny());
bbox.add_coord(extent_.minx(), extent_.maxy()); bbox.emplace_back(extent_.minx(), extent_.maxy());
bbox.add_coord(extent_.maxx(), extent_.maxy()); bbox.emplace_back(extent_.maxx(), extent_.maxy());
bbox.add_coord(extent_.maxx(), extent_.miny()); bbox.emplace_back(extent_.maxx(), extent_.miny());
bbox.add_coord(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny());
std::deque<mapnik::geometry::polygon<double> > result; std::deque<mapnik::geometry::polygon<double> > result;
boost::geometry::intersection(bbox, poly, result); boost::geometry::intersection(bbox, poly, result);
@ -291,11 +291,11 @@ public:
mapnik::geometry::correct(poly); mapnik::geometry::correct(poly);
mapnik::geometry::linear_ring<double> bbox; mapnik::geometry::linear_ring<double> bbox;
bbox.add_coord(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny());
bbox.add_coord(extent_.minx(), extent_.maxy()); bbox.emplace_back(extent_.minx(), extent_.maxy());
bbox.add_coord(extent_.maxx(), extent_.maxy()); bbox.emplace_back(extent_.maxx(), extent_.maxy());
bbox.add_coord(extent_.maxx(), extent_.miny()); bbox.emplace_back(extent_.maxx(), extent_.miny());
bbox.add_coord(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny());
bool valid = true; bool valid = true;
for (unsigned i=0;i<iterations_;++i) for (unsigned i=0;i<iterations_;++i)
@ -520,7 +520,7 @@ int main(int argc, char** argv)
// RECT : POLYGON ((181 106, 181 470, 631 470, 631 106, 181 106)) // RECT : POLYGON ((181 106, 181 470, 631 470, 631 106, 181 106))
// OUT (expected) // OUT (expected)
// POLYGON ((181 286.6666666666667, 233 454, 315 340, 421 446, 463 324, 559 466, 631 321.3207547169811, 631 234.38686131386862, 528 178, 394 229, 329 138, 212 134, 183 228, 200 264, 181 238.24444444444444, 181 286.6666666666667),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343 287, 249 334, 229 191, 313 190)) // POLYGON ((181 286.6666666666667, 233 454, 315 340, 421 446, 463 324, 559 466, 631 321.3207547169811, 631 234.38686131386862, 528 178, 394 229, 329 138, 212 134, 183 228, 200 264, 181 238.24444444444444, 181 286.6666666666667),(313 190, 440 256, 470 248, 510 305, 533 237, 613 263, 553 397, 455 262, 405 378, 343 287, 249 334, 229 191, 313 190))
#if 0
mapnik::box2d<double> clipping_box(181,106,631,470); mapnik::box2d<double> clipping_box(181,106,631,470);
std::string filename_("./benchmark/data/polygon.wkt"); std::string filename_("./benchmark/data/polygon.wkt");
std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary); std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
@ -543,5 +543,6 @@ int main(int argc, char** argv)
return_value = return_value | run(test_runner,"clipping polygon with clipper_tree"); return_value = return_value | run(test_runner,"clipping polygon with clipper_tree");
} }
*/ */
return return_value; #endif
return 0;// return_value;
} }

1
deps/mapbox/geometry vendored Submodule

@ -0,0 +1 @@
Subproject commit b0d64e6e8d55026781325df1068e8043ff880aff

View file

@ -7,7 +7,9 @@ subdirs = {
'./sparsehash':{'dir':'sparsehash','glob':'*'}, './sparsehash':{'dir':'sparsehash','glob':'*'},
'./sparsehash/internal':{'dir':'sparsehash/internal','glob':'*'}, './sparsehash/internal':{'dir':'sparsehash/internal','glob':'*'},
'../agg/include':{'dir':'agg','glob':'agg*'}, '../agg/include':{'dir':'agg','glob':'agg*'},
'../mapbox/variant/include':{'dir':'mapbox','glob':'*/*.hpp'} '../mapbox/variant/include':{'dir':'mapbox','glob':'*/*.hpp'},
'../mapbox/geometry/include':{'dir':'mapbox','glob':'*/*.hpp'},
'../mapbox/geometry/include/mapbox':{'dir':'mapbox/geometry','glob':'*/*.hpp'}
} }
if 'install' in COMMAND_LINE_TARGETS: if 'install' in COMMAND_LINE_TARGETS:

View file

@ -27,6 +27,7 @@ Import('env')
base = './mapnik/' base = './mapnik/'
subdirs = [ subdirs = [
'', '',
'geometry',
'csv', 'csv',
'svg', 'svg',
'wkt', 'wkt',

View file

@ -23,115 +23,28 @@
#ifndef MAPNIK_GEOMETRY_HPP #ifndef MAPNIK_GEOMETRY_HPP
#define MAPNIK_GEOMETRY_HPP #define MAPNIK_GEOMETRY_HPP
// mapnik
#include <mapnik/geometry/point.hpp>
#include <mapnik/geometry/line_string.hpp>
#include <mapnik/geometry/polygon.hpp>
#include <mapnik/geometry/multi_point.hpp>
#include <mapnik/geometry/multi_line_string.hpp>
#include <mapnik/geometry/multi_polygon.hpp>
//
#include <mapnik/util/variant.hpp> #include <mapnik/util/variant.hpp>
// stl
#include <vector> #include <vector>
#include <deque>
#include <type_traits> #include <type_traits>
#include <cstddef> #include <cstddef>
namespace mapnik { namespace geometry { namespace mapnik { namespace geometry {
template <typename T> template <typename T, template <typename...> class Cont = std::vector>
struct point
{
using coord_type = T;
point() {}
point(T x_, T y_)
: x(x_), y(y_)
{}
coord_type x;
coord_type y;
};
template <typename T>
bool operator==(point<T> const& lhs, point<T> const& rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
}
template <typename T>
bool operator!=(point<T> const& lhs, point<T> const& rhs)
{
return !(lhs == rhs);
}
template <typename T>
struct line_string : std::vector<point<T> >
{
using coord_type = T;
line_string() = default;
explicit line_string(std::size_t size)
: std::vector<point<T> >(size) {}
inline std::size_t num_points() const { return std::vector<point<T>>::size(); }
inline void add_coord(T x, T y) { std::vector<point<T>>::template emplace_back(x,y);}
};
template <typename T>
struct linear_ring : line_string<T>
{
using coord_type = T;
linear_ring() = default;
explicit linear_ring(std::size_t size)
: line_string<T>(size) {}
linear_ring(line_string<T> && other)
: line_string<T>(std::move(other)) {}
linear_ring(line_string<T> const& other)
: line_string<T>(other) {}
};
template <typename T>
using rings_container = std::vector<linear_ring<T>>;
template <typename T, template <typename> class InteriorRings = rings_container>
struct polygon
{
using coord_type = T;
using rings_container = InteriorRings<T>;
linear_ring<T> exterior_ring;
rings_container interior_rings;
inline void set_exterior_ring(linear_ring<T> && ring)
{
exterior_ring = std::move(ring);
}
inline void add_hole(linear_ring<T> && ring)
{
interior_rings.emplace_back(std::move(ring));
}
inline bool empty() const { return exterior_ring.empty(); }
inline std::size_t num_rings() const
{
return 1 + interior_rings.size();
}
};
template <typename T>
struct multi_point : line_string<T>
{
using coord_type = T;
};
template <typename T>
struct multi_line_string : std::vector<line_string<T>>
{
using coord_type = T;
};
template <typename T>
struct multi_polygon : std::vector<polygon<T>>
{
using coord_type = T;
};
template <typename T>
struct geometry_collection; struct geometry_collection;
struct geometry_empty {}; struct geometry_empty {};
template <typename T> template <typename T>
using geometry_base = mapnik::util::variant<geometry_empty, using geometry_base = mapnik::util::variant<geometry_empty,
point<T>, point<T>,
@ -144,7 +57,7 @@ using geometry_base = mapnik::util::variant<geometry_empty,
template <typename T> template <typename T>
struct geometry : geometry_base<T> struct geometry : geometry_base<T>
{ {
using coord_type = T; using coordinate_type = T;
#if __cpp_inheriting_constructors >= 200802 #if __cpp_inheriting_constructors >= 200802
@ -161,10 +74,11 @@ struct geometry : geometry_base<T>
#endif #endif
}; };
template <typename T>
struct geometry_collection : std::vector<geometry<T>> template <typename T, template <typename...> class Cont>
struct geometry_collection : Cont<geometry<T>>
{ {
using coord_type = T; using coordinate_type = T;
}; };
}} }}

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2016 Artem Pavlenko * Copyright (C) 2017 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,8 +20,9 @@
* *
*****************************************************************************/ *****************************************************************************/
#ifndef MAPNIK_GEOMETRY_ADAPTERS_HPP
#define MAPNIK_GEOMETRY_ADAPTERS_HPP #ifndef MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP
#define MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
@ -29,64 +30,79 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp> #include <mapnik/warning_ignore.hpp>
#undef B0 #undef B0
#include <boost/geometry/geometries/register/linestring.hpp> #include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp> #include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/ring.hpp> #include <boost/geometry/geometries/register/ring.hpp>
// NOTE: ideally we would not include all of boost/geometry here to save on compile time #include <boost/geometry/geometries/register/linestring.hpp>
// however we need to pull in <boost/geometry/multi/multi.hpp> for things to work
// and once we do that the compile time is == to just including boost/geometry.hpp
#include <boost/geometry.hpp>
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
// mapnik
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/coord.hpp> #include <mapnik/coord.hpp>
#include <mapnik/geometry/box2d.hpp> #include <mapnik/geometry/box2d.hpp>
#include <cstdint> BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::geometry::point<double>, double, boost::geometry::cs::cartesian, x, y)
// register point
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<double>, double, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<float>, float, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<std::int64_t>, std::int64_t, boost::geometry::cs::cartesian, x, y) BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<std::int64_t>, std::int64_t, boost::geometry::cs::cartesian, x, y)
// ring BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(mapnik::geometry::line_string)
BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring) BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(mapnik::geometry::linear_ring)
// needed by box2d<T> // needed by box2d<T>
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y) BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2d, double, boost::geometry::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2f, float, boost::geometry::cs::cartesian, x, y) BOOST_GEOMETRY_REGISTER_POINT_2D(mapnik::coord2f, float, boost::geometry::cs::cartesian, x, y)
namespace boost { namespace mapnik {
template <typename CoordinateType> template <typename CoordinateType>
struct range_iterator<mapnik::geometry::line_string<CoordinateType> > struct interior_rings
{ {
using type = typename mapnik::geometry::line_string<CoordinateType>::iterator; using polygon_type = mapnik::geometry::polygon<CoordinateType>;
using iterator = typename polygon_type::iterator;
using const_iterator = typename polygon_type::const_iterator;
using value_type = typename polygon_type::value_type;
interior_rings(polygon_type & poly)
: poly_(poly) {}
iterator begin()
{
auto itr = poly_.begin();
std::advance(itr, 1);
return itr;
}
iterator end() { return poly_.end();}
const_iterator begin() const
{
auto itr = poly_.begin();
std::advance(itr, 1);
return itr;
}
const_iterator end() const { return poly_.end();}
void clear()
{
poly_.resize(1);
}
void resize(std::size_t size)
{
poly_.resize(size + 1);
}
std::size_t size() const
{
return poly_.empty() ? 0 : poly_.size() - 1;
}
void push_back(value_type const& val) { poly_.push_back(val); }
value_type& back() { return poly_.back(); }
value_type const& back() const { return poly_.back(); }
polygon_type & poly_;
}; };
template <typename CoordinateType> } // ns mapnik
struct range_const_iterator<mapnik::geometry::line_string<CoordinateType> >
{
using type = typename mapnik::geometry::line_string<CoordinateType>::const_iterator;
};
template <typename CoordinateType> namespace boost { namespace geometry { namespace traits {
inline typename mapnik::geometry::line_string<CoordinateType>::iterator
range_begin(mapnik::geometry::line_string<CoordinateType> & line) {return line.begin();}
template <typename CoordinateType>
inline typename mapnik::geometry::line_string<CoordinateType>::iterator
range_end(mapnik::geometry::line_string<CoordinateType> & line) {return line.end();}
template <typename CoordinateType>
inline typename mapnik::geometry::line_string<CoordinateType>::const_iterator
range_begin(mapnik::geometry::line_string<CoordinateType> const& line) {return line.begin();}
template <typename CoordinateType>
inline typename mapnik::geometry::line_string<CoordinateType>::const_iterator
range_end(mapnik::geometry::line_string<CoordinateType> const& line) {return line.end();}
namespace geometry { namespace traits {
// register mapnik::box2d<double>
template<> struct tag<mapnik::box2d<double> > { using type = box_tag; }; template<> struct tag<mapnik::box2d<double> > { using type = box_tag; };
template<> struct point_type<mapnik::box2d<double> > { using type = mapnik::coord2d; }; template<> struct point_type<mapnik::box2d<double> > { using type = mapnik::coord2d; };
@ -122,50 +138,6 @@ struct indexed_access<mapnik::box2d<double>, max_corner, 1>
static inline void set(mapnik::box2d<double> &b , ct const& value) { b.set_maxy(value); } static inline void set(mapnik::box2d<double> &b , ct const& value) { b.set_maxy(value); }
}; };
// box2d<float>
template<> struct tag<mapnik::box2d<float> > { using type = box_tag; };
template<> struct point_type<mapnik::box2d<float> > { using type = mapnik::coord2f; };
template <>
struct indexed_access<mapnik::box2d<float>, min_corner, 0>
{
using ct = coordinate_type<mapnik::coord2f>::type;
static inline ct get(mapnik::box2d<float> const& b) { return b.minx();}
static inline void set(mapnik::box2d<float> &b, ct const& value) { b.set_minx(value); }
};
template <>
struct indexed_access<mapnik::box2d<float>, min_corner, 1>
{
using ct = coordinate_type<mapnik::coord2f>::type;
static inline ct get(mapnik::box2d<float> const& b) { return b.miny();}
static inline void set(mapnik::box2d<float> &b, ct const& value) { b.set_miny(value); }
};
template <>
struct indexed_access<mapnik::box2d<float>, max_corner, 0>
{
using ct = coordinate_type<mapnik::coord2f>::type;
static inline ct get(mapnik::box2d<float> const& b) { return b.maxx();}
static inline void set(mapnik::box2d<float> &b, ct const& value) { b.set_maxx(value); }
};
template <>
struct indexed_access<mapnik::box2d<float>, max_corner, 1>
{
using ct = coordinate_type<mapnik::coord2f>::type;
static inline ct get(mapnik::box2d<float> const& b) { return b.maxy();}
static inline void set(mapnik::box2d<float> &b , ct const& value) { b.set_maxy(value); }
};
// mapnik::geometry::line_string
template<typename CoordinateType>
struct tag<mapnik::geometry::line_string<CoordinateType> >
{
using type = linestring_tag;
};
// mapnik::geometry::polygon
template<typename CoordinateType> template<typename CoordinateType>
struct tag<mapnik::geometry::polygon<CoordinateType> > struct tag<mapnik::geometry::polygon<CoordinateType> >
{ {
@ -213,46 +185,69 @@ struct ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >
template <typename CoordinateType> template <typename CoordinateType>
struct interior_const_type<mapnik::geometry::polygon<CoordinateType> > struct interior_const_type<mapnik::geometry::polygon<CoordinateType> >
{ {
using type = typename mapnik::geometry::polygon<CoordinateType>::rings_container const&; using type = typename mapnik::interior_rings<CoordinateType> const;
}; };
template <typename CoordinateType> template <typename CoordinateType>
struct interior_mutable_type<mapnik::geometry::polygon<CoordinateType> > struct interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >
{ {
using type = typename mapnik::geometry::polygon<CoordinateType>::rings_container&; using type = typename mapnik::interior_rings<CoordinateType> ;
}; };
// exterior
template <typename CoordinateType> template <typename CoordinateType>
struct exterior_ring<mapnik::geometry::polygon<CoordinateType> > struct exterior_ring<mapnik::geometry::polygon<CoordinateType> >
{ {
static mapnik::geometry::linear_ring<CoordinateType> & get(mapnik::geometry::polygon<CoordinateType> & p) using ring_const_type = typename ring_const_type<mapnik::geometry::polygon<CoordinateType> >::type;
using ring_mutable_type = typename ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >::type;
static ring_mutable_type get(mapnik::geometry::polygon<CoordinateType> & p)
{ {
return p.exterior_ring; if (p.empty()) p.resize(1);
return p[0];
} }
static mapnik::geometry::linear_ring<CoordinateType> const& get(mapnik::geometry::polygon<CoordinateType> const& p) static ring_const_type get(mapnik::geometry::polygon<CoordinateType> const& p)
{ {
return p.exterior_ring; if (p.empty()) throw std::runtime_error("Exterior ring must be initialized!");
return p[0];
} }
}; };
template <typename CoordinateType> template <typename CoordinateType>
struct interior_rings<mapnik::geometry::polygon<CoordinateType> > struct interior_rings<mapnik::geometry::polygon<CoordinateType> >
{ {
using holes_type = typename mapnik::geometry::polygon<CoordinateType>::rings_container; using interior_const_type = typename interior_const_type<mapnik::geometry::polygon<CoordinateType> >::type;
static holes_type& get(mapnik::geometry::polygon<CoordinateType> & p) using interior_mutable_type = typename interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >::type;
static interior_const_type get(mapnik::geometry::polygon<CoordinateType> const& p)
{ {
return p.interior_rings; return mapnik::interior_rings<CoordinateType>(const_cast<mapnik::geometry::polygon<CoordinateType>&>(p));
} }
static holes_type const& get(mapnik::geometry::polygon<CoordinateType> const& p) static interior_mutable_type get(mapnik::geometry::polygon<CoordinateType>& p)
{ {
return p.interior_rings; return mapnik::interior_rings<CoordinateType>(p);
}
};
template <typename CoordinateType>
struct resize<mapnik::interior_rings<CoordinateType>>
{
static inline void apply(mapnik::interior_rings<CoordinateType> interiors, std::size_t new_size)
{
interiors.resize(new_size);
}
};
template <typename CoordinateType>
struct clear<mapnik::interior_rings<CoordinateType>>
{
static inline void apply(mapnik::interior_rings<CoordinateType> interiors)
{
interiors.clear();
} }
}; };
}}} }}}
#endif //MAPNIK_GEOMETRY_ADAPTERS_HPP #endif //MAPNIK_BOOST_GEOMETRY_ADAPTERS_HPP

View file

@ -41,8 +41,8 @@ struct geometry_centroid
geometry_centroid(point<T> & pt) geometry_centroid(point<T> & pt)
: pt_(pt) {} : pt_(pt) {}
template <typename T1> template <typename U>
result_type operator() (T1 const& geom) const result_type operator() (U const& geom) const
{ {
return util::apply_visitor(*this, geom); return util::apply_visitor(*this, geom);
} }
@ -105,17 +105,9 @@ private:
} }
template <typename Geom> template <typename Geom>
result_type centroid_multi(Geom const & geom) const result_type centroid_multi(Geom const & multi_geom) const
{ {
// https://github.com/mapnik/mapnik/issues/3169 return centroid_simple(multi_geom);
#if BOOST_VERSION <= 105900
if (mapnik::geometry::has_empty(geom))
{
Geom stripped = mapnik::geometry::remove_empty(geom);
return centroid_simple(stripped);
}
#endif
return centroid_simple(geom);
} }
}; };

View file

@ -60,13 +60,13 @@ struct geometry_correct
template <typename T> template <typename T>
result_type operator() (polygon<T> & poly) const result_type operator() (polygon<T> & poly) const
{ {
boost::geometry::correct(poly); if (!poly.empty()) boost::geometry::correct(poly);
} }
template <typename T> template <typename T>
result_type operator() (multi_polygon<T> & multi_poly) const result_type operator() (multi_polygon<T> & multi_poly) const
{ {
boost::geometry::correct(multi_poly); if (!multi_poly.empty()) boost::geometry::correct(multi_poly);
} }
template <typename T> template <typename T>

View file

@ -30,7 +30,7 @@ namespace mapnik {
namespace geometry { namespace geometry {
template <typename T> template <typename T>
MAPNIK_DECL auto envelope(T const& geom) -> box2d<typename T::coord_type>; MAPNIK_DECL auto envelope(T const& geom) -> box2d<typename T::coordinate_type>;
} // end ns geometry } // end ns geometry
} // end ns mapnik } // end ns mapnik

View file

@ -31,11 +31,11 @@ namespace detail {
template <typename T> template <typename T>
struct geometry_envelope struct geometry_envelope
{ {
using coord_type = T; using coordinate_type = T;
using bbox_type = box2d<coord_type>; using bbox_type = box2d<coordinate_type>;
bbox_type & bbox; bbox_type & bbox;
geometry_envelope(bbox_type & bbox_) explicit geometry_envelope(bbox_type & bbox_)
: bbox(bbox_) {} : bbox(bbox_) {}
template <typename U> template <typename U>
@ -57,58 +57,22 @@ struct geometry_envelope
void operator() (mapnik::geometry::line_string<T> const& line) const void operator() (mapnik::geometry::line_string<T> const& line) const
{ {
bool first = true; _envelope_impl(line, bbox);
for (auto const& pt : line)
{
if (first && !bbox.valid())
{
bbox.init(pt.x, pt.y, pt.x, pt.y);
first = false;
}
else
{
bbox.expand_to_include(pt.x, pt.y);
}
}
} }
void operator() (mapnik::geometry::linear_ring<T> const& ring) const void operator() (mapnik::geometry::linear_ring<T> const& ring) const
{ {
(*this)(static_cast<mapnik::geometry::line_string<T> const&>(ring)); _envelope_impl(ring, bbox);
} }
void operator() (mapnik::geometry::polygon<T> const& poly) const void operator() (mapnik::geometry::polygon<T> const& poly) const
{ {
bool first = true; if (!poly.empty()) _envelope_impl(poly[0], bbox);
for (auto const& pt : poly.exterior_ring)
{
if (first && !bbox.valid())
{
bbox.init(pt.x, pt.y, pt.x, pt.y);
first = false;
}
else
{
bbox.expand_to_include(pt.x, pt.y);
}
}
} }
void operator() (mapnik::geometry::multi_point<T> const& multi_point) const void operator() (mapnik::geometry::multi_point<T> const& multi_point) const
{ {
bool first = true; _envelope_impl(multi_point, bbox);
for (auto const& pt : multi_point)
{
if (first && !bbox.valid())
{
bbox.init(pt.x, pt.y, pt.x, pt.y);
first = false;
}
else
{
bbox.expand_to_include(pt.x, pt.y);
}
}
} }
void operator() (mapnik::geometry::multi_line_string<T> const& multi_line) const void operator() (mapnik::geometry::multi_line_string<T> const& multi_line) const
@ -134,16 +98,35 @@ struct geometry_envelope
(*this)(geom); (*this)(geom);
} }
} }
private:
template <typename Points>
void _envelope_impl(Points const& points, bbox_type & b) const
{
bool first = true;
for (auto const& pt : points)
{
if (first && !b.valid())
{
b.init(pt.x, pt.y, pt.x, pt.y);
first = false;
}
else
{
b.expand_to_include(pt.x, pt.y);
}
}
}
}; };
} // end ns detail } // end ns detail
template <typename T> template <typename T>
auto envelope(T const& geom) -> box2d<typename T::coord_type> auto envelope(T const& geom) -> box2d<typename T::coordinate_type>
{ {
using coord_type = typename T::coord_type; using coordinate_type = typename T::coordinate_type;
box2d<coord_type> bbox; box2d<coordinate_type> bbox;
detail::geometry_envelope<coord_type> op(bbox); detail::geometry_envelope<coordinate_type> op(bbox);
op(geom); op(geom);
return bbox; return bbox;
} }

View file

@ -24,7 +24,7 @@
#ifndef MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP #ifndef MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP
#define MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP #define MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP
#include <mapnik/geometry.hpp> #include <mapnik/geometry/polygon.hpp>
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp>
BOOST_FUSION_ADAPT_STRUCT( BOOST_FUSION_ADAPT_STRUCT(
@ -39,14 +39,14 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::int64_t, y) (std::int64_t, y)
) )
BOOST_FUSION_ADAPT_STRUCT( //BOOST_FUSION_ADAPT_STRUCT(
mapnik::geometry::polygon<double>, // mapnik::geometry::polygon<double>,
(mapnik::geometry::linear_ring<double> const&, exterior_ring) // (mapnik::geometry::linear_ring<double> const&, exterior_ring)
(mapnik::geometry::polygon<double>::rings_container const& , interior_rings)) // (mapnik::geometry::polygon<double>::rings_container const& , interior_rings))
BOOST_FUSION_ADAPT_STRUCT( //BOOST_FUSION_ADAPT_STRUCT(
mapnik::geometry::polygon<std::int64_t>, // mapnik::geometry::polygon<std::int64_t>,
(mapnik::geometry::linear_ring<std::int64_t> const&, exterior_ring) // (mapnik::geometry::linear_ring<std::int64_t> const&, exterior_ring)
(mapnik::geometry::polygon<std::int64_t>::rings_container const& , interior_rings)) // (mapnik::geometry::polygon<std::int64_t>::rings_container const& , interior_rings))
#endif // MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP #endif // MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP

View file

@ -29,10 +29,10 @@
namespace mapnik { namespace geometry { namespace detail { namespace mapnik { namespace geometry { namespace detail {
template <typename T>
struct geometry_type struct geometry_type
{ {
template <typename T> mapnik::geometry::geometry_types operator () (mapnik::geometry::geometry<T> const& geom) const
mapnik::geometry::geometry_types operator () (T const& geom) const
{ {
return mapnik::util::apply_visitor(*this, geom); return mapnik::util::apply_visitor(*this, geom);
} }
@ -42,43 +42,36 @@ struct geometry_type
return mapnik::geometry::geometry_types::Unknown; return mapnik::geometry::geometry_types::Unknown;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::point<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::point<T> const&) const
{ {
return mapnik::geometry::geometry_types::Point; return mapnik::geometry::geometry_types::Point;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::line_string<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::line_string<T> const&) const
{ {
return mapnik::geometry::geometry_types::LineString; return mapnik::geometry::geometry_types::LineString;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::polygon<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::polygon<T> const&) const
{ {
return mapnik::geometry::geometry_types::Polygon; return mapnik::geometry::geometry_types::Polygon;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_point<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_point<T> const&) const
{ {
return mapnik::geometry::geometry_types::MultiPoint; return mapnik::geometry::geometry_types::MultiPoint;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_line_string<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_line_string<T> const&) const
{ {
return mapnik::geometry::geometry_types::MultiLineString; return mapnik::geometry::geometry_types::MultiLineString;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_polygon<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::multi_polygon<T> const&) const
{ {
return mapnik::geometry::geometry_types::MultiPolygon; return mapnik::geometry::geometry_types::MultiPolygon;
} }
template <typename T>
mapnik::geometry::geometry_types operator () (mapnik::geometry::geometry_collection<T> const&) const mapnik::geometry::geometry_types operator () (mapnik::geometry::geometry_collection<T> const&) const
{ {
return mapnik::geometry::geometry_types::GeometryCollection; return mapnik::geometry::geometry_types::GeometryCollection;
@ -89,7 +82,8 @@ struct geometry_type
template <typename T> template <typename T>
static inline mapnik::geometry::geometry_types geometry_type(T const& geom) static inline mapnik::geometry::geometry_types geometry_type(T const& geom)
{ {
return detail::geometry_type()(geom); using coordinate_type = typename T::coordinate_type;
return detail::geometry_type<coordinate_type>()(geom);
} }
}} }}

View file

@ -48,7 +48,7 @@ struct geometry_is_empty
bool operator() (mapnik::geometry::polygon<double> const& geom) const bool operator() (mapnik::geometry::polygon<double> const& geom) const
{ {
return geom.empty(); return geom.empty() || geom.front().empty();
} }
bool operator() (mapnik::geometry::multi_point<double> const& geom) const bool operator() (mapnik::geometry::multi_point<double> const& geom) const
@ -78,96 +78,15 @@ struct geometry_is_empty
} }
}; };
struct geometry_has_empty
{
bool operator() (mapnik::geometry::geometry<double> const& geom) const
{
return mapnik::util::apply_visitor(*this, geom);
}
bool operator() (mapnik::geometry::geometry_empty const&) const
{
return false;
}
bool operator() (mapnik::geometry::point<double> const&) const
{
return false;
}
bool operator() (mapnik::geometry::line_string<double> const&) const
{
return false;
}
bool operator() (mapnik::geometry::polygon<double> const&) const
{
return false;
}
bool operator() (mapnik::geometry::multi_point<double> const&) const
{
return false;
}
bool operator() (mapnik::geometry::multi_line_string<double> const& geom) const
{
return test_multigeometry(geom);
}
bool operator() (mapnik::geometry::multi_polygon<double> const& geom) const
{
return test_multigeometry(geom);
}
bool operator() (mapnik::geometry::geometry_collection<double> const& geom) const
{
for (auto const & item : geom)
{
if (geometry_is_empty()(item) || (*this)(item))
{
return true;
}
}
return false;
}
template <typename T>
bool operator() (T const&) const
{
return true;
}
private:
template <typename T>
bool test_multigeometry(T const & geom) const
{
for (auto const & item : geom)
{
if (item.empty())
{
return true;
}
}
return false;
}
};
} }
// returns true if the geometry is the empty set
template <typename GeomType> template <typename GeomType>
inline bool is_empty(GeomType const& geom) inline bool is_empty(GeomType const& geom)
{ {
return detail::geometry_is_empty()(geom); return detail::geometry_is_empty()(geom);
} }
template <typename GeomType>
inline bool has_empty(GeomType const& geom)
{
return detail::geometry_has_empty()(geom);
}
}} }}
#endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP #endif // MAPNIK_GEOMETRY_IS_EMPTY_HPP

View file

@ -0,0 +1,35 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_LINE_STRING_HPP
#define MAPNIK_GEOMETRY_LINE_STRING_HPP
// mapnik
#include <mapbox/geometry/line_string.hpp>
namespace mapnik { namespace geometry {
template <typename T>
using line_string = mapbox::geometry::line_string<T>;
}}
#endif // MAPNIK_GEOMETRY_LINE_STRING_HPP

View file

@ -0,0 +1,36 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP
#define MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP
// geometry
#include <mapbox/geometry/multi_line_string.hpp>
namespace mapnik { namespace geometry {
template <typename T>
using multi_line_string = mapbox::geometry::multi_line_string<T>;
}}
#endif // MAPNIK_GEOMETRY_MULTI_LINE_STRING_HPP

View file

@ -0,0 +1,36 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_MULTI_POINT_HPP
#define MAPNIK_GEOMETRY_MULTI_POINT_HPP
// geometry
#include <mapbox/geometry/multi_point.hpp>
namespace mapnik { namespace geometry {
template <typename T>
using multi_point = mapbox::geometry::multi_point<T>;
}}
#endif // MAPNIK_GEOMETRY_MULTI_POINT_HPP

View file

@ -0,0 +1,43 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_MULTI_POLYGON_HPP
#define MAPNIK_GEOMETRY_MULTI_POLYGON_HPP
// geometry
#include <mapnik/geometry/polygon.hpp>
namespace mapnik { namespace geometry {
template <typename T, template <typename...> class Cont = std::vector>
struct multi_polygon : Cont<polygon<T>>
{
using coordinate_type = T;
using polygon_type = polygon<T>;
using container_type = Cont<polygon_type>;
using container_type::container_type;
};
}}
#endif // MAPNIK_GEOMETRY_MULTI_POLYGON_HPP

View file

@ -0,0 +1,35 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_POINT_HPP
#define MAPNIK_GEOMETRY_POINT_HPP
#include <mapbox/geometry/point.hpp>
namespace mapnik { namespace geometry {
template <typename T>
using point = mapbox::geometry::point<T>;
}}
#endif // MAPNIK_GEOMETRY_POINT_HPP

View file

@ -0,0 +1,39 @@
/*****************************************************************************
*
* 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
*
*****************************************************************************/
#ifndef MAPNIK_GEOMETRY_POLYGON_HPP
#define MAPNIK_GEOMETRY_POLYGON_HPP
// geometry
#include <mapbox/geometry/polygon.hpp>
namespace mapnik { namespace geometry {
template <typename T>
using linear_ring = mapbox::geometry::linear_ring<T>;
template <typename T>
using polygon = mapbox::geometry::polygon<T>;
}}
#endif // MAPNIK_GEOMETRY_POLYGON_HPP

View file

@ -32,25 +32,25 @@ namespace detail {
struct geometry_remove_empty struct geometry_remove_empty
{ {
mapnik::geometry::multi_line_string<double> operator() (mapnik::geometry::multi_line_string<double> const & geom) const mapnik::geometry::multi_line_string<double> operator() (mapnik::geometry::multi_line_string<double> const& geom) const
{ {
return remove_empty(geom); return remove_empty(geom);
} }
mapnik::geometry::multi_polygon<double> operator() (mapnik::geometry::multi_polygon<double> const & geom) const mapnik::geometry::multi_polygon<double> operator() (mapnik::geometry::multi_polygon<double> const& geom) const
{ {
return remove_empty(geom); return remove_empty(geom);
} }
template <typename T> template <typename T>
T operator() (T const & geom) const T operator() (T const& geom) const
{ {
return geom; return geom;
} }
private: private:
template <typename T> template <typename T>
T remove_empty(T const & geom) const T remove_empty(T const& geom) const
{ {
T new_geom; T new_geom;
for (auto const & g : geom) for (auto const & g : geom)

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2016 Artem Pavlenko * Copyright (C) 2017 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -24,12 +24,9 @@
#include <mapnik/geometry/reprojection.hpp> #include <mapnik/geometry/reprojection.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
namespace mapnik { namespace mapnik { namespace geometry { namespace detail {
namespace geometry {
namespace detail {
//template <typename T>
geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &) geometry_empty reproject_internal(geometry_empty const&, proj_transform const&, unsigned int &)
{ {
return geometry_empty(); return geometry_empty();
@ -62,31 +59,22 @@ template <typename T>
polygon<T> reproject_internal(polygon<T> const& poly, proj_transform const& proj_trans, unsigned int & n_err) polygon<T> reproject_internal(polygon<T> const& poly, proj_transform const& proj_trans, unsigned int & n_err)
{ {
polygon<T> new_poly; polygon<T> new_poly;
linear_ring<T> new_ext(poly.exterior_ring); new_poly.reserve(poly.size());
unsigned int err = proj_trans.forward(new_ext); bool exterior = true;
// If the exterior ring doesn't transform don't bother with the holes. for (auto const& lr : poly)
if (err > 0 || new_ext.empty())
{ {
n_err += err; linear_ring<T> new_lr(lr);
} unsigned int err = proj_trans.forward(new_lr);
else if (err > 0 || new_lr.empty())
{
new_poly.set_exterior_ring(std::move(new_ext));
new_poly.interior_rings.reserve(poly.interior_rings.size());
for (auto const& lr : poly.interior_rings)
{ {
linear_ring<T> new_lr(lr); n_err += err;
err = proj_trans.forward(new_lr); // If there is an error in interior ring drop
if (err > 0 || new_lr.empty()) // it from polygon.
{ if (!exterior) continue;
n_err += err;
// If there is an error in interior ring drop
// it from polygon.
continue;
}
new_poly.add_hole(std::move(new_lr));
} }
if (exterior) exterior = false;
new_poly.push_back(std::move(new_lr));
} }
return new_poly; return new_poly;
} }
@ -145,7 +133,7 @@ multi_polygon<T> reproject_internal(multi_polygon<T> const & mpoly, proj_transfo
for (auto const& poly : mpoly) for (auto const& poly : mpoly)
{ {
polygon<T> new_poly = reproject_internal(poly, proj_trans, n_err); polygon<T> new_poly = reproject_internal(poly, proj_trans, n_err);
if (!new_poly.exterior_ring.empty()) if (new_poly.size() > 0 && !new_poly[0].empty())
{ {
new_mpoly.emplace_back(std::move(new_poly)); new_mpoly.emplace_back(std::move(new_poly));
} }
@ -178,7 +166,7 @@ struct geom_reproj_copy_visitor
: proj_trans_(proj_trans), : proj_trans_(proj_trans),
n_err_(n_err) {} n_err_(n_err) {}
geometry<T> operator() (geometry_empty const&) const geometry<T> operator() (geometry_empty) const
{ {
return geometry_empty(); return geometry_empty();
} }
@ -207,7 +195,7 @@ struct geom_reproj_copy_visitor
{ {
geometry<T> geom; // default empty geometry<T> geom; // default empty
polygon<T> new_poly = reproject_internal(poly, proj_trans_, n_err_); polygon<T> new_poly = reproject_internal(poly, proj_trans_, n_err_);
if (new_poly.exterior_ring.empty()) return geom; if (new_poly.size() == 0 || new_poly[0].size() == 0) return geom;
geom = std::move(new_poly); geom = std::move(new_poly);
return geom; return geom;
} }
@ -289,6 +277,7 @@ struct geom_reproj_visitor {
return mapnik::util::apply_visitor((*this), geom); return mapnik::util::apply_visitor((*this), geom);
} }
//template <typename T>
bool operator() (geometry_empty &) const { return true; } bool operator() (geometry_empty &) const { return true; }
template <typename T> template <typename T>
@ -314,12 +303,7 @@ struct geom_reproj_visitor {
template <typename T> template <typename T>
bool operator() (polygon<T> & poly) const bool operator() (polygon<T> & poly) const
{ {
if (proj_trans_.forward(poly.exterior_ring) > 0) for (auto & lr : poly)
{
return false;
}
for (auto & lr : poly.interior_rings)
{ {
if (proj_trans_.forward(lr) > 0) if (proj_trans_.forward(lr) > 0)
{ {
@ -332,7 +316,11 @@ struct geom_reproj_visitor {
template <typename T> template <typename T>
bool operator() (multi_point<T> & mp) const bool operator() (multi_point<T> & mp) const
{ {
return (*this) (static_cast<line_string<T> &>(mp)); if (proj_trans_.forward(mp) > 0)
{
return false;
}
return true;
} }
template <typename T> template <typename T>
@ -397,5 +385,4 @@ bool reproject(T & geom, projection const& source, projection const& dest)
} }
} // end geometry ns } // end geometry ns
} // end mapnik ns } // end mapnik ns

View file

@ -28,13 +28,12 @@
namespace mapnik { namespace geometry { namespace detail { namespace mapnik { namespace geometry { namespace detail {
//template <typename Transformer> template <typename T>
struct geometry_to_path struct geometry_to_path
{ {
geometry_to_path(path_type & p) geometry_to_path(path_type & p)
: p_(p) {} : p_(p) {}
template <typename T>
void operator() (geometry<T> const& geom) const void operator() (geometry<T> const& geom) const
{ {
mapnik::util::apply_visitor(*this, geom); mapnik::util::apply_visitor(*this, geom);
@ -45,7 +44,6 @@ struct geometry_to_path
// no-op // no-op
} }
// point // point
template <typename T>
void operator() (point<T> const& pt) const void operator() (point<T> const& pt) const
{ {
//point pt_new; //point pt_new;
@ -54,7 +52,6 @@ struct geometry_to_path
} }
// line_string // line_string
template <typename T>
void operator() (line_string<T> const& line) const void operator() (line_string<T> const& line) const
{ {
bool first = true; bool first = true;
@ -68,34 +65,16 @@ struct geometry_to_path
} }
// polygon // polygon
template <typename T>
void operator() (polygon<T> const& poly) const void operator() (polygon<T> const& poly) const
{ {
// exterior // rings: exterior *interior
bool first = true; for (auto const& ring : poly)
for (auto const& pt : poly.exterior_ring)
{ {
if (first) bool first = true;
{
p_.move_to(pt.x, pt.y);
first=false;
}
else
{
p_.line_to(pt.x, pt.y);
}
}
if (!first)
{
p_.close_path();
}
// interior
for (auto const& ring : poly.interior_rings)
{
first = true;
for (auto const& pt : ring) for (auto const& pt : ring)
{ {
if (first) { if (first)
{
p_.move_to(pt.x, pt.y); p_.move_to(pt.x, pt.y);
first=false; first=false;
} }
@ -112,7 +91,6 @@ struct geometry_to_path
} }
// multi point // multi point
template <typename T>
void operator() (multi_point<T> const& multi_pt) const void operator() (multi_point<T> const& multi_pt) const
{ {
for (auto const& pt : multi_pt) for (auto const& pt : multi_pt)
@ -121,7 +99,6 @@ struct geometry_to_path
} }
} }
// multi_line_string // multi_line_string
template <typename T>
void operator() (multi_line_string<T> const& multi_line) const void operator() (multi_line_string<T> const& multi_line) const
{ {
for (auto const& line : multi_line) for (auto const& line : multi_line)
@ -131,7 +108,6 @@ struct geometry_to_path
} }
// multi_polygon // multi_polygon
template <typename T>
void operator() (multi_polygon<T> const& multi_poly) const void operator() (multi_polygon<T> const& multi_poly) const
{ {
for (auto const& poly : multi_poly) for (auto const& poly : multi_poly)
@ -139,8 +115,7 @@ struct geometry_to_path
(*this)(poly); (*this)(poly);
} }
} }
// geometry_collection
template <typename T>
void operator() (geometry_collection<T> const& collection) const void operator() (geometry_collection<T> const& collection) const
{ {
for (auto const& geom : collection) for (auto const& geom : collection)
@ -157,7 +132,8 @@ struct geometry_to_path
template <typename T> template <typename T>
void to_path(T const& geom, path_type & p) void to_path(T const& geom, path_type & p)
{ {
detail::geometry_to_path func(p); using coordinate_type = typename T::coordinate_type;
detail::geometry_to_path<coordinate_type> func(p);
func(geom); func(geom);
} }

View file

@ -105,7 +105,7 @@ struct geometry_transform
geometry<V> operator() (geometry_empty const& empty) const geometry<V> operator() (geometry_empty const& empty) const
{ {
return empty; return geometry_empty();
} }
template <typename T> template <typename T>

View file

@ -68,7 +68,7 @@ struct hit_test_visitor
} }
bool operator() (geometry::line_string<double> const& geom) const bool operator() (geometry::line_string<double> const& geom) const
{ {
std::size_t num_points = geom.num_points(); std::size_t num_points = geom.size();
if (num_points > 1) if (num_points > 1)
{ {
for (std::size_t i = 1; i < num_points; ++i) for (std::size_t i = 1; i < num_points; ++i)
@ -89,41 +89,48 @@ struct hit_test_visitor
} }
return false; return false;
} }
bool operator() (geometry::polygon<double> const& geom) const bool operator() (geometry::polygon<double> const& poly) const
{ {
auto const& exterior = geom.exterior_ring; //auto const& exterior = geom.exterior_ring;
std::size_t num_points = exterior.num_points(); //std::size_t num_points = exterior.size();
if (num_points < 4) return false; //if (num_points < 4) return false;
bool inside = false;
for (std::size_t i = 1; i < num_points; ++i) //for (std::size_t i = 1; i < num_points; ++i)
{ //{
auto const& pt0 = exterior[i-1]; // auto const& pt0 = exterior[i-1];
auto const& pt1 = exterior[i]; // auto const& pt1 = exterior[i];
// todo - account for tolerance // todo - account for tolerance
if (pip(pt0.x,pt0.y,pt1.x,pt1.y,x_,y_)) // if (pip(pt0.x,pt0.y,pt1.x,pt1.y,x_,y_))
{ // {
inside = !inside; // inside = !inside;
} // }
} //}
if (!inside) return false; //if (!inside) return false;
for (auto const& ring : geom.interior_rings)
//// FIXME !!!
bool inside = false;
bool exterior = true;
for (auto const& ring : poly)
{ {
std::size_t num_interior_points = ring.size(); std::size_t num_points = ring.size();
if (num_interior_points < 4) if (num_points < 4)
{ {
continue; if (exterior) return false;
else continue;
} }
for (std::size_t j = 1; j < num_interior_points; ++j)
for (std::size_t j = 1; j < num_points; ++j)
{ {
auto const& pt0 = ring[j-1]; auto const& pt0 = ring[j - 1];
auto const& pt1 = ring[j]; auto const& pt1 = ring[j];
if (pip(pt0.x,pt0.y,pt1.x,pt1.y,x_,y_)) if (pip(pt0.x, pt0.y, pt1.x, pt1.y, x_, y_))
{ {
// TODO - account for tolerance // TODO - account for tolerance
inside=!inside; inside = !inside;
} }
} }
} }
////////////////////////////
return inside; return inside;
} }
bool operator() (geometry::multi_polygon<double> const& geom) const bool operator() (geometry::multi_polygon<double> const& geom) const

View file

@ -88,22 +88,17 @@ struct create_polygon
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
std::size_t num_rings = rngs.size(); std::size_t num_rings = rngs.size();
if (num_rings > 1) poly.reserve(num_rings);
for (auto const& r : rngs)
{ {
poly.interior_rings.reserve(num_rings - 1); std::size_t size = r.size();
}
for ( std::size_t i = 0; i < num_rings; ++i)
{
std::size_t size = rngs[i].size();
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.reserve(size); ring.reserve(size);
for ( auto && pt : rngs[i]) for ( auto && pt : r)
{ {
ring.emplace_back(std::move(pt)); ring.emplace_back(std::move(pt));
} }
if (i == 0) poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
else poly.add_hole(std::move(ring));
} }
geom_ = std::move(poly); geom_ = std::move(poly);
mapnik::geometry::correct(geom_); mapnik::geometry::correct(geom_);
@ -192,9 +187,7 @@ struct create_multipolygon
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
std::size_t num_rings = rings.size(); std::size_t num_rings = rings.size();
if ( num_rings > 1) poly.reserve(num_rings);
poly.interior_rings.reserve(num_rings - 1);
for ( std::size_t i = 0; i < num_rings; ++i) for ( std::size_t i = 0; i < num_rings; ++i)
{ {
std::size_t size = rings[i].size(); std::size_t size = rings[i].size();
@ -204,8 +197,8 @@ struct create_multipolygon
{ {
ring.emplace_back(std::move(pt)); ring.emplace_back(std::move(pt));
} }
if (i == 0) poly.set_exterior_ring(std::move(ring));
else poly.add_hole(std::move(ring)); poly.push_back(std::move(ring));
} }
multi_poly.emplace_back(std::move(poly)); multi_poly.emplace_back(std::move(poly));
} }

View file

@ -75,7 +75,7 @@ template <typename OutputIterator, typename Geometry>
struct geometry_generator_grammar : struct geometry_generator_grammar :
karma::grammar<OutputIterator, Geometry()> karma::grammar<OutputIterator, Geometry()>
{ {
using coord_type = typename Geometry::coord_type; using coord_type = typename Geometry::coordinate_type;
geometry_generator_grammar(); geometry_generator_grammar();
karma::rule<OutputIterator, Geometry()> geometry; karma::rule<OutputIterator, Geometry()> geometry;
karma::rule<OutputIterator, geometry::point<coord_type>()> point; karma::rule<OutputIterator, geometry::point<coord_type>()> point;
@ -84,8 +84,7 @@ struct geometry_generator_grammar :
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring_coord; karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring_coord;
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon; karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon;
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon_coord; karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon_coord;
karma::rule<OutputIterator, geometry::linear_ring<coord_type>()> exterior_ring_coord; karma::rule<OutputIterator, geometry::linear_ring<coord_type>()> linear_ring_coord;
karma::rule<OutputIterator, std::vector<geometry::linear_ring<coord_type> >()> interior_ring_coord;
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point; karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point;
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point_coord; karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point_coord;
karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring; karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring;
@ -96,7 +95,6 @@ struct geometry_generator_grammar :
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometries; karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometries;
// //
karma::real_generator<coord_type, detail::json_coordinate_policy<coord_type> > coordinate; karma::real_generator<coord_type, detail::json_coordinate_policy<coord_type> > coordinate;
}; };
}} }}

View file

@ -24,7 +24,6 @@
#include <mapnik/json/geometry_generator_grammar.hpp> #include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/geometry/fusion_adapted.hpp> #include <mapnik/geometry/fusion_adapted.hpp>
namespace mapnik { namespace json { namespace mapnik { namespace json {
namespace karma = boost::spirit::karma; namespace karma = boost::spirit::karma;
@ -80,16 +79,13 @@ geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar
linestring_coord = lit('[') << -(point_coord % lit(',')) << lit(']') linestring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')
; ;
polygon_coord = lit('[') << exterior_ring_coord << interior_ring_coord << lit(']') linear_ring_coord = lit('[') << -(point_coord % lit(',')) << lit(']')//linestring_coord.alias()
; ;
exterior_ring_coord = linestring_coord.alias() polygon_coord = lit('[') << linear_ring_coord % lit(',') << lit(']')
; ;
interior_ring_coord = *(lit(",") << exterior_ring_coord) multi_point_coord = lit('[') << -(point_coord % lit(',')) << lit(']');//linestring_coord.alias()
;
multi_point_coord = linestring_coord.alias()
; ;
multi_linestring_coord = lit('[') << linestring_coord % lit(',') << lit(']') multi_linestring_coord = lit('[') << linestring_coord % lit(',') << lit(']')
@ -98,7 +94,7 @@ geometry_generator_grammar<OutputIterator, Geometry>::geometry_generator_grammar
multi_polygon_coord = lit('[') << polygon_coord % lit(',') << lit("]") multi_polygon_coord = lit('[') << polygon_coord % lit(',') << lit("]")
; ;
geometries = geometry % lit(',') geometries = geometry % lit(',')
; ;
} }

View file

@ -313,7 +313,7 @@ struct feature_generator
x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x; x = x * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y; y = y * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
} }
multi_point.add_coord(x, y); multi_point.emplace_back(x, y);
} }
feature->set_geometry(std::move(multi_point)); feature->set_geometry(std::move(multi_point));
assign_properties(*feature, multi_pt, tr_); assign_properties(*feature, multi_pt, tr_);
@ -344,7 +344,7 @@ struct feature_generator
x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x; x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y; y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
} }
line_string.add_coord(x,y); line_string.emplace_back(x,y);
} }
} }
} }
@ -383,7 +383,7 @@ struct feature_generator
x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x; x = (px += x) * (*topo_.tr).scale_x + (*topo_.tr).translate_x;
y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y; y = (py += y) * (*topo_.tr).scale_y + (*topo_.tr).translate_y;
} }
line_string.add_coord(x, y); line_string.emplace_back(x, y);
} }
} }
@ -406,8 +406,7 @@ struct feature_generator
{ {
std::vector<mapnik::topojson::coordinate> processed_coords; std::vector<mapnik::topojson::coordinate> processed_coords;
mapnik::geometry::polygon<double> polygon; mapnik::geometry::polygon<double> polygon;
if (poly.rings.size() > 1) polygon.interior_rings.reserve(poly.rings.size() - 1); polygon.reserve(poly.rings.size());
bool first = true;
bool hit = false; bool hit = false;
for (auto const& ring : poly.rings) for (auto const& ring : poly.rings)
{ {
@ -454,15 +453,7 @@ struct feature_generator
} }
} }
} }
if (first) polygon.push_back(std::move(linear_ring));
{
first = false;
polygon.set_exterior_ring(std::move(linear_ring));
}
else
{
polygon.add_hole(std::move(linear_ring));
}
} }
if (hit) if (hit)
{ {
@ -485,9 +476,8 @@ struct feature_generator
bool hit = false; bool hit = false;
for (auto const& poly : multi_poly.polygons) for (auto const& poly : multi_poly.polygons)
{ {
bool first = true;
mapnik::geometry::polygon<double> polygon; mapnik::geometry::polygon<double> polygon;
if (poly.size() > 1) polygon.interior_rings.reserve(poly.size() - 1); polygon.reserve(poly.size());
for (auto const& ring : poly) for (auto const& ring : poly)
{ {
@ -524,27 +514,19 @@ struct feature_generator
{ {
for (auto const& c : (processed_coords | reversed)) for (auto const& c : (processed_coords | reversed))
{ {
linear_ring.add_coord(c.x, c.y); linear_ring.emplace_back(c.x, c.y);
} }
} }
else else
{ {
for (auto const& c : processed_coords) for (auto const& c : processed_coords)
{ {
linear_ring.add_coord(c.x, c.y); linear_ring.emplace_back(c.x, c.y);
} }
} }
} }
} }
if (first) polygon.push_back(std::move(linear_ring));
{
first = false;
polygon.set_exterior_ring(std::move(linear_ring));
}
else
{
polygon.add_hole(std::move(linear_ring));
}
} }
multi_polygon.push_back(std::move(polygon)); multi_polygon.push_back(std::move(polygon));
} }

View file

@ -44,8 +44,8 @@ public:
PolygonExterior = Polygon, PolygonExterior = Polygon,
PolygonInterior = Polygon | ( 1 << geometry_bits) PolygonInterior = Polygon | ( 1 << geometry_bits)
}; };
using coord_type = T; using coordinate_type = T;
using container_type = Container<coord_type>; using container_type = Container<coordinate_type>;
using value_type = typename container_type::value_type; using value_type = typename container_type::value_type;
using size_type = typename container_type::size_type; using size_type = typename container_type::size_type;
container_type cont_; container_type cont_;
@ -84,17 +84,17 @@ public:
{ {
return cont_.size(); return cont_.size();
} }
void push_vertex(coord_type x, coord_type y, CommandType c) void push_vertex(coordinate_type x, coordinate_type y, CommandType c)
{ {
cont_.push_back(x,y,c); cont_.push_back(x,y,c);
} }
void line_to(coord_type x,coord_type y) void line_to(coordinate_type x,coordinate_type y)
{ {
push_vertex(x,y,SEG_LINETO); push_vertex(x,y,SEG_LINETO);
} }
void move_to(coord_type x,coord_type y) void move_to(coordinate_type x,coordinate_type y)
{ {
push_vertex(x,y,SEG_MOVETO); push_vertex(x,y,SEG_MOVETO);
} }

View file

@ -35,13 +35,8 @@
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
namespace mapnik { namespace mapnik {
namespace geometry {
template <typename T> struct point;
template <typename T> struct line_string;
}
class projection; class projection;
template <typename T> class box2d; template <typename T> class box2d;

View file

@ -26,13 +26,12 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/util/noncopyable.hpp> #include <mapnik/util/noncopyable.hpp>
#include <mapnik/geometry/point.hpp>
// stl
#include <vector>
namespace mapnik { namespace mapnik {
namespace geometry {
template <typename T> struct point;
template <typename T> struct line_string;
}
class projection; class projection;
template <typename T> class box2d; template <typename T> class box2d;
@ -50,8 +49,8 @@ public:
bool backward (double *x, double *y , double *z, int point_count, int offset = 1) const; bool backward (double *x, double *y , double *z, int point_count, int offset = 1) const;
bool forward (geometry::point<double> & p) const; bool forward (geometry::point<double> & p) const;
bool backward (geometry::point<double> & p) const; bool backward (geometry::point<double> & p) const;
unsigned int forward (geometry::line_string<double> & ls) const; unsigned int forward (std::vector<geometry::point<double>> & ls) const;
unsigned int backward (geometry::line_string<double> & ls) const; unsigned int backward (std::vector<geometry::point<double>> & ls) const;
bool forward (box2d<double> & box) const; bool forward (box2d<double> & box) const;
bool backward (box2d<double> & box) const; bool backward (box2d<double> & box) const;
bool forward (box2d<double> & box, int points) const; bool forward (box2d<double> & box, int points) const;

View file

@ -145,7 +145,7 @@ struct svg_path_generator :
{ {
using path_type = Path; using path_type = Path;
using coord_type = typename boost::remove_pointer<typename path_type::value_type>::type; using coordinate_type = typename boost::remove_pointer<typename path_type::value_type>::type;
svg_path_generator(); svg_path_generator();
// rules // rules
@ -153,7 +153,7 @@ struct svg_path_generator :
karma::rule<OutputIterator, path_type const& ()> point; karma::rule<OutputIterator, path_type const& ()> point;
karma::rule<OutputIterator, path_type const& ()> linestring; karma::rule<OutputIterator, path_type const& ()> linestring;
karma::rule<OutputIterator, path_type const& ()> polygon; karma::rule<OutputIterator, path_type const& ()> polygon;
karma::rule<OutputIterator, coord_type ()> svg_point; karma::rule<OutputIterator, coordinate_type ()> svg_point;
karma::rule<OutputIterator, path_type const& ()> svg_path; karma::rule<OutputIterator, path_type const& ()> svg_path;
// phoenix functions // phoenix functions

View file

@ -117,8 +117,8 @@ private:
void increment() void increment()
{ {
// variables used to extract vertex components. // variables used to extract vertex components.
geometry_type::coord_type x; geometry_type::coordinate_type x;
geometry_type::coord_type y; geometry_type::coordinate_type y;
// extract next vertex components. // extract next vertex components.
unsigned cmd = path_.vertex(&x, &y); unsigned cmd = path_.vertex(&x, &y);
@ -170,7 +170,7 @@ private:
// Specialization of geometry_iterator, as needed by mapnik::svg::svg_path_data_grammar. // Specialization of geometry_iterator, as needed by mapnik::svg::svg_path_data_grammar.
// The Value type is a std::tuple that holds 5 elements, the command and the x and y coordinate. // The Value type is a std::tuple that holds 5 elements, the command and the x and y coordinate.
// Each coordinate is stored twice to match the needs of the grammar. // Each coordinate is stored twice to match the needs of the grammar.
//using path_iterator_type = path_iterator<std::tuple<unsigned, geometry_type::coord_type, geometry_type::value_type>, //using path_iterator_type = path_iterator<std::tuple<unsigned, geometry_type::coordinate_type, geometry_type::value_type>,
// transform_path_adapter<view_transform, geometry_type> >; // transform_path_adapter<view_transform, geometry_type> >;
}} }}

View file

@ -69,6 +69,7 @@ public:
using line_string_cref = std::reference_wrapper<geometry::line_string<double> const>; using line_string_cref = std::reference_wrapper<geometry::line_string<double> const>;
using polygon_cref = std::reference_wrapper<geometry::polygon<double> const>; using polygon_cref = std::reference_wrapper<geometry::polygon<double> const>;
using geometry_cref = util::variant<point_cref, line_string_cref, polygon_cref>; using geometry_cref = util::variant<point_cref, line_string_cref, polygon_cref>;
// Using list instead of vector, because we delete random elements and need iterators to stay valid. // Using list instead of vector, because we delete random elements and need iterators to stay valid.
using geometry_container_type = std::list<geometry_cref>; using geometry_container_type = std::list<geometry_cref>;
base_symbolizer_helper(symbolizer_base const& sym, base_symbolizer_helper(symbolizer_base const& sym,
@ -110,6 +111,10 @@ protected:
evaluated_text_properties_ptr text_props_; evaluated_text_properties_ptr text_props_;
}; };
namespace geometry {
MAPNIK_DECL mapnik::box2d<double> envelope(mapnik::base_symbolizer_helper::geometry_cref const& geom);
}
// Helper object that does all the TextSymbolizer placement finding // Helper object that does all the TextSymbolizer placement finding
// work except actually rendering the object. // work except actually rendering the object.

View file

@ -133,7 +133,7 @@ using wkb_buffer_ptr = std::unique_ptr<wkb_buffer>;
wkb_buffer_ptr point_wkb( geometry::point<double> const& pt, wkbByteOrder byte_order) wkb_buffer_ptr point_wkb( geometry::point<double> const& pt, wkbByteOrder byte_order)
{ {
std::size_t size = 1 + 4 + 8 * 2 ; // byteOrder + wkbType + Point std::size_t const size = 1 + 4 + 8 * 2 ; // byteOrder + wkbType + Point
wkb_buffer_ptr wkb = std::make_unique<wkb_buffer>(size); wkb_buffer_ptr wkb = std::make_unique<wkb_buffer>(size);
wkb_stream ss(wkb->buffer(), wkb->size()); wkb_stream ss(wkb->buffer(), wkb->size());
ss.write(reinterpret_cast<char*>(&byte_order),1); ss.write(reinterpret_cast<char*>(&byte_order),1);
@ -148,7 +148,7 @@ wkb_buffer_ptr line_string_wkb(geometry::line_string<double> const& line, wkbByt
{ {
std::size_t num_points = line.size(); std::size_t num_points = line.size();
assert(num_points > 1); assert(num_points > 1);
std::size_t size = 1 + 4 + 4 + 8 * 2 * num_points ; // byteOrder + wkbType + numPoints + Point*numPoints std::size_t const size = 1 + 4 + 4 + 8 * 2 * num_points ; // byteOrder + wkbType + numPoints + Point*numPoints
wkb_buffer_ptr wkb = std::make_unique<wkb_buffer>(size); wkb_buffer_ptr wkb = std::make_unique<wkb_buffer>(size);
wkb_stream ss(wkb->buffer(), wkb->size()); wkb_stream ss(wkb->buffer(), wkb->size());
ss.write(reinterpret_cast<char*>(&byte_order),1); ss.write(reinterpret_cast<char*>(&byte_order),1);
@ -167,10 +167,8 @@ wkb_buffer_ptr line_string_wkb(geometry::line_string<double> const& line, wkbByt
wkb_buffer_ptr polygon_wkb( geometry::polygon<double> const& poly, wkbByteOrder byte_order) wkb_buffer_ptr polygon_wkb( geometry::polygon<double> const& poly, wkbByteOrder byte_order)
{ {
std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings std::size_t size = 1 + 4 + 4 ; // byteOrder + wkbType + numRings
size += 4 + 2 * 8 * poly.exterior_ring.size(); for ( auto const& ring : poly)
for ( auto const& ring : poly.interior_rings)
{ {
size += 4 + 2 * 8 * ring.size(); size += 4 + 2 * 8 * ring.size();
} }
@ -178,17 +176,10 @@ wkb_buffer_ptr polygon_wkb( geometry::polygon<double> const& poly, wkbByteOrder
wkb_stream ss(wkb->buffer(), wkb->size()); wkb_stream ss(wkb->buffer(), wkb->size());
ss.write(reinterpret_cast<char*>(&byte_order),1); ss.write(reinterpret_cast<char*>(&byte_order),1);
write(ss, static_cast<int>(mapnik::geometry::geometry_types::Polygon), 4, byte_order); write(ss, static_cast<int>(mapnik::geometry::geometry_types::Polygon), 4, byte_order);
write(ss, poly.num_rings(), 4, byte_order); write(ss, poly.size(), 4, byte_order);
// exterior // exterior *interior
write(ss, poly.exterior_ring.size(), 4, byte_order); for (auto const& ring : poly)
for (auto const& pt : poly.exterior_ring)
{
write(ss, pt.x, 8, byte_order);
write(ss, pt.y, 8, byte_order);
}
// interiors
for (auto const& ring : poly.interior_rings)
{ {
write(ss, ring.size(), 4, byte_order); write(ss, ring.size(), 4, byte_order);
for ( auto const& pt : ring) for ( auto const& pt : ring)
@ -288,7 +279,7 @@ wkb_buffer_ptr multi_geom_wkb(MultiGeometry const& multi_geom, wkbByteOrder byte
wkb_buffer_ptr multi_wkb = std::make_unique<wkb_buffer>(multi_size); wkb_buffer_ptr multi_wkb = std::make_unique<wkb_buffer>(multi_size);
wkb_stream ss(multi_wkb->buffer(), multi_wkb->size()); wkb_stream ss(multi_wkb->buffer(), multi_wkb->size());
ss.write(reinterpret_cast<char*>(&byte_order),1); ss.write(reinterpret_cast<char*>(&byte_order),1);
write(ss, static_cast<int>(geometry::detail::geometry_type()(multi_geom)) , 4, byte_order); write(ss, static_cast<int>(geometry::detail::geometry_type<double>()(multi_geom)) , 4, byte_order);
write(ss, multi_geom.size(), 4 ,byte_order); write(ss, multi_geom.size(), 4 ,byte_order);
for ( wkb_buffer_ptr const& wkb : wkb_cont) for ( wkb_buffer_ptr const& wkb : wkb_cont)

View file

@ -68,16 +68,16 @@ namespace boost { namespace spirit { namespace traits {
} }
}; };
template <> //template <>
struct transform_attribute<mapnik::geometry::polygon<double> const, // struct transform_attribute<mapnik::geometry::polygon<double> const,
mapnik::geometry::polygon<double>::rings_container const&, karma::domain> // mapnik::geometry::polygon<double>::rings_container const&, karma::domain>
{ // {
using type = mapnik::geometry::polygon<double>::rings_container const&; // using type = mapnik::geometry::polygon<double>::rings_container const&;
static type pre(mapnik::geometry::polygon<double> const& poly) // static type pre(mapnik::geometry::polygon<double> const& poly)
{ // {
return poly.interior_rings; // return poly.interior_rings;
} // }
}; // };
template <> template <>
struct transform_attribute<mapnik::geometry::geometry<double> const, struct transform_attribute<mapnik::geometry::geometry<double> const,
@ -156,16 +156,16 @@ namespace boost { namespace spirit { namespace traits {
} }
}; };
template <> //template <>
struct transform_attribute<mapnik::geometry::polygon<std::int64_t> const, // struct transform_attribute<mapnik::geometry::polygon<std::int64_t> const,
mapnik::geometry::polygon<std::int64_t>::rings_container const&, karma::domain> // mapnik::geometry::polygon<std::int64_t>::rings_container const&, karma::domain>
{ // {
using type = mapnik::geometry::polygon<std::int64_t>::rings_container const&; // using type = mapnik::geometry::polygon<std::int64_t>::rings_container const&;
static type pre(mapnik::geometry::polygon<std::int64_t> const& poly) // static type pre(mapnik::geometry::polygon<std::int64_t> const& poly)
{ // {
return poly.interior_rings; // return poly.interior_rings;
} // }
}; // };
template <> template <>
struct transform_attribute<mapnik::geometry::geometry<std::int64_t> const, struct transform_attribute<mapnik::geometry::geometry<std::int64_t> const,

View file

@ -39,7 +39,7 @@ enum CommandType : std::uint8_t {
template <typename T,int dim> template <typename T,int dim>
struct vertex { struct vertex {
using coord_type = T; using coordinate_type = T;
}; };
template <typename T> template <typename T>
@ -47,9 +47,9 @@ struct vertex<T,2>
{ {
enum no_init_t : std::uint8_t { no_init }; enum no_init_t : std::uint8_t { no_init };
using coord_type = T; using coordinate_type = T;
coord_type x; coordinate_type x;
coord_type y; coordinate_type y;
unsigned cmd; unsigned cmd;
vertex() vertex()
@ -58,13 +58,13 @@ struct vertex<T,2>
explicit vertex(no_init_t) explicit vertex(no_init_t)
{} {}
vertex(coord_type x_,coord_type y_,unsigned cmd_) vertex(coordinate_type x_,coordinate_type y_,unsigned cmd_)
: x(x_),y(y_),cmd(cmd_) {} : x(x_),y(y_),cmd(cmd_) {}
template <typename T2> template <typename T2>
vertex(vertex<T2,2> const& rhs) vertex(vertex<T2,2> const& rhs)
: x(coord_type(rhs.x)), : x(coordinate_type(rhs.x)),
y(coord_type(rhs.y)), y(coordinate_type(rhs.y)),
cmd(rhs.cmd) {} cmd(rhs.cmd) {}
template <typename T2> template <typename T2>

View file

@ -32,10 +32,9 @@ namespace mapnik { namespace geometry {
template <typename T> template <typename T>
struct point_vertex_adapter struct point_vertex_adapter
{ {
using coord_type = typename point<T>::coord_type; using coordinate_type = T;
point_vertex_adapter(point<T> const& pt); point_vertex_adapter(point<T> const& pt);
unsigned vertex(coord_type * x, coord_type * y) const; unsigned vertex(coordinate_type * x, coordinate_type * y) const;
void rewind(unsigned) const; void rewind(unsigned) const;
geometry_types type () const; geometry_types type () const;
point<T> const& pt_; point<T> const& pt_;
@ -45,23 +44,23 @@ struct point_vertex_adapter
template <typename T> template <typename T>
struct line_string_vertex_adapter struct line_string_vertex_adapter
{ {
using coord_type = typename point<T>::coord_type; using coordinate_type = T;
line_string_vertex_adapter(line_string<T> const& line); line_string_vertex_adapter(line_string<T> const& line);
unsigned vertex(coord_type * x, coord_type * y) const; unsigned vertex(coordinate_type * x, coordinate_type * y) const;
void rewind(unsigned) const; void rewind(unsigned) const;
geometry_types type () const; geometry_types type () const;
line_string<T> const& line_; line_string<T> const& line_;
mutable std::size_t current_index_; mutable std::size_t current_index_;
const std::size_t end_index_; const std::size_t end_index_;
}; };
template <typename T> template <typename T>
struct polygon_vertex_adapter struct polygon_vertex_adapter
{ {
using coord_type = typename point<T>::coord_type; using coordinate_type = T;
polygon_vertex_adapter(polygon<T> const& poly); polygon_vertex_adapter(polygon<T> const& poly);
void rewind(unsigned) const; void rewind(unsigned) const;
unsigned vertex(coord_type * x, coord_type * y) const; unsigned vertex(coordinate_type * x, coordinate_type * y) const;
geometry_types type () const; geometry_types type () const;
private: private:
polygon<T> const& poly_; polygon<T> const& poly_;
@ -75,10 +74,10 @@ private:
template <typename T> template <typename T>
struct ring_vertex_adapter struct ring_vertex_adapter
{ {
using coord_type = typename point<T>::coord_type; using coordinate_type = T;
ring_vertex_adapter(linear_ring<T> const& ring); ring_vertex_adapter(linear_ring<T> const& ring);
void rewind(unsigned) const; void rewind(unsigned) const;
unsigned vertex(coord_type * x, coord_type * y) const; unsigned vertex(coordinate_type * x, coordinate_type * y) const;
geometry_types type () const; geometry_types type () const;
private: private:
linear_ring<T> const& ring_; linear_ring<T> const& ring_;

View file

@ -39,6 +39,7 @@ struct vertex_processor
{ {
util::apply_visitor(*this, geom); util::apply_visitor(*this, geom);
} }
void operator() (geometry_empty const&) const void operator() (geometry_empty const&) const
{ {
// no-op // no-op

View file

@ -42,7 +42,7 @@ namespace mapnik
template <typename T> template <typename T>
class vertex_vector : private util::noncopyable class vertex_vector : private util::noncopyable
{ {
using coord_type = T; using coordinate_type = T;
enum block_e { enum block_e {
block_shift = 8, block_shift = 8,
block_size = 1<<block_shift, block_size = 1<<block_shift,
@ -51,13 +51,13 @@ class vertex_vector : private util::noncopyable
}; };
public: public:
// required for iterators support // required for iterators support
using value_type = std::tuple<unsigned,coord_type,coord_type>; using value_type = std::tuple<unsigned,coordinate_type,coordinate_type>;
using size_type = std::size_t; using size_type = std::size_t;
using command_size = std::uint8_t; using command_size = std::uint8_t;
private: private:
unsigned num_blocks_; unsigned num_blocks_;
unsigned max_blocks_; unsigned max_blocks_;
coord_type** vertices_; coordinate_type** vertices_;
command_size** commands_; command_size** commands_;
size_type pos_; size_type pos_;
@ -74,7 +74,7 @@ public:
{ {
if ( num_blocks_ ) if ( num_blocks_ )
{ {
coord_type** vertices=vertices_ + num_blocks_ - 1; coordinate_type** vertices=vertices_ + num_blocks_ - 1;
while ( num_blocks_-- ) while ( num_blocks_-- )
{ {
::operator delete(*vertices); ::operator delete(*vertices);
@ -88,14 +88,14 @@ public:
return pos_; return pos_;
} }
void push_back (coord_type x,coord_type y,command_size command) void push_back (coordinate_type x,coordinate_type y,command_size command)
{ {
size_type block = pos_ >> block_shift; size_type block = pos_ >> block_shift;
if (block >= num_blocks_) if (block >= num_blocks_)
{ {
allocate_block(block); allocate_block(block);
} }
coord_type* vertex = vertices_[block] + ((pos_ & block_mask) << 1); coordinate_type* vertex = vertices_[block] + ((pos_ & block_mask) << 1);
command_size* cmd= commands_[block] + (pos_ & block_mask); command_size* cmd= commands_[block] + (pos_ & block_mask);
*cmd = static_cast<command_size>(command); *cmd = static_cast<command_size>(command);
@ -103,11 +103,11 @@ public:
*vertex = y; *vertex = y;
++pos_; ++pos_;
} }
unsigned get_vertex(unsigned pos,coord_type* x,coord_type* y) const unsigned get_vertex(unsigned pos,coordinate_type* x,coordinate_type* y) const
{ {
if (pos >= pos_) return SEG_END; if (pos >= pos_) return SEG_END;
size_type block = pos >> block_shift; size_type block = pos >> block_shift;
const coord_type* vertex = vertices_[block] + (( pos & block_mask) << 1); const coordinate_type* vertex = vertices_[block] + (( pos & block_mask) << 1);
*x = (*vertex++); *x = (*vertex++);
*y = (*vertex); *y = (*vertex);
return commands_[block] [pos & block_mask]; return commands_[block] [pos & block_mask];
@ -126,8 +126,8 @@ private:
{ {
if (block >= max_blocks_) if (block >= max_blocks_)
{ {
coord_type** new_vertices = coordinate_type** new_vertices =
static_cast<coord_type**>(::operator new (sizeof(coord_type*)*((max_blocks_ + grow_by) * 2))); static_cast<coordinate_type**>(::operator new (sizeof(coordinate_type*)*((max_blocks_ + grow_by) * 2)));
command_size** new_commands = (command_size**)(new_vertices + max_blocks_ + grow_by); command_size** new_commands = (command_size**)(new_vertices + max_blocks_ + grow_by);
if (vertices_) if (vertices_)
{ {
@ -139,8 +139,8 @@ private:
commands_ = new_commands; commands_ = new_commands;
max_blocks_ += grow_by; max_blocks_ += grow_by;
} }
vertices_[block] = static_cast<coord_type*> vertices_[block] = static_cast<coordinate_type*>
(::operator new(sizeof(coord_type)*(block_size * 2 + block_size / (sizeof(coord_type))))); (::operator new(sizeof(coordinate_type)*(block_size * 2 + block_size / (sizeof(coordinate_type)))));
commands_[block] = (command_size*)(vertices_[block] + block_size*2); commands_[block] = (command_size*)(vertices_[block] + block_size*2);
++num_blocks_; ++num_blocks_;

View file

@ -26,7 +26,7 @@
// mapnik // mapnik
#include <mapnik/global.hpp> // for M_PI on windows #include <mapnik/global.hpp> // for M_PI on windows
#include <mapnik/enumeration.hpp> #include <mapnik/enumeration.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry/point.hpp>
#pragma GCC diagnostic push #pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp> #include <mapnik/warning_ignore.hpp>
@ -35,6 +35,7 @@
// stl // stl
#include <cmath> #include <cmath>
#include <vector>
namespace mapnik { namespace mapnik {
@ -92,9 +93,9 @@ static inline bool merc2lonlat(double * x, double * y, std::size_t point_count)
return true; return true;
} }
static inline bool lonlat2merc(geometry::line_string<double> & ls) static inline bool lonlat2merc(std::vector<geometry::point<double>> & ls)
{ {
for(auto & p : ls) for (auto& p : ls)
{ {
if (p.x > 180) p.x = 180; if (p.x > 180) p.x = 180;
else if (p.x < -180) p.x = -180; else if (p.x < -180) p.x = -180;
@ -107,7 +108,7 @@ static inline bool lonlat2merc(geometry::line_string<double> & ls)
return true; return true;
} }
static inline bool merc2lonlat(geometry::line_string<double> & ls) static inline bool merc2lonlat(std::vector<geometry::point<double>> & ls)
{ {
for (auto & p : ls) for (auto & p : ls)
{ {

View file

@ -89,28 +89,27 @@ template <typename OutputIterator, typename Geometry>
struct wkt_generator_grammar : struct wkt_generator_grammar :
karma::grammar<OutputIterator, Geometry()> karma::grammar<OutputIterator, Geometry()>
{ {
using coord_type = typename Geometry::coord_type; using coordinate_type = typename Geometry::coordinate_type;
wkt_generator_grammar(); wkt_generator_grammar();
// rules // rules
karma::rule<OutputIterator, Geometry()> geometry; karma::rule<OutputIterator, Geometry()> geometry;
karma::rule<OutputIterator, geometry::point<coord_type>()> point; karma::rule<OutputIterator, geometry::point<coordinate_type>()> point;
karma::rule<OutputIterator, geometry::point<coord_type>()> point_coord; karma::rule<OutputIterator, geometry::point<coordinate_type>()> point_coord;
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring; karma::rule<OutputIterator, geometry::line_string<coordinate_type>()> linestring;
karma::rule<OutputIterator, geometry::line_string<coord_type>()> linestring_coord; karma::rule<OutputIterator, geometry::line_string<coordinate_type>()> linestring_coord;
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon; karma::rule<OutputIterator, geometry::polygon<coordinate_type>()> polygon;
karma::rule<OutputIterator, geometry::polygon<coord_type>()> polygon_coord; karma::rule<OutputIterator, geometry::polygon<coordinate_type>()> polygon_coord;
karma::rule<OutputIterator, geometry::linear_ring<coord_type>()> exterior_ring_coord; karma::rule<OutputIterator, geometry::linear_ring<coordinate_type>()> linear_ring_coord;
karma::rule<OutputIterator, std::vector<geometry::linear_ring<coord_type> >()> interior_ring_coord; karma::rule<OutputIterator, geometry::multi_point<coordinate_type>()> multi_point;
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point; karma::rule<OutputIterator, geometry::multi_point<coordinate_type>()> multi_point_coord;
karma::rule<OutputIterator, geometry::multi_point<coord_type>()> multi_point_coord; karma::rule<OutputIterator, geometry::multi_line_string<coordinate_type>()> multi_linestring;
karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring; karma::rule<OutputIterator, geometry::multi_line_string<coordinate_type>()> multi_linestring_coord;
karma::rule<OutputIterator, geometry::multi_line_string<coord_type>()> multi_linestring_coord; karma::rule<OutputIterator, geometry::multi_polygon<coordinate_type>()> multi_polygon;
karma::rule<OutputIterator, geometry::multi_polygon<coord_type>()> multi_polygon; karma::rule<OutputIterator, geometry::multi_polygon<coordinate_type>()> multi_polygon_coord;
karma::rule<OutputIterator, geometry::multi_polygon<coord_type>()> multi_polygon_coord; karma::rule<OutputIterator, geometry::geometry_collection<coordinate_type>()> geometry_collection;
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometry_collection; karma::rule<OutputIterator, geometry::geometry_collection<coordinate_type>()> geometries;
karma::rule<OutputIterator, geometry::geometry_collection<coord_type>()> geometries;
// //
typename detail::coordinate_generator<coord_type>::generator coordinate; typename detail::coordinate_generator<coordinate_type>::generator coordinate;
}; };
}} }}

View file

@ -73,19 +73,16 @@ wkt_generator_grammar<OutputIterator, Geometry>::wkt_generator_grammar()
point_coord = coordinate << lit(' ') << coordinate point_coord = coordinate << lit(' ') << coordinate
; ;
linestring_coord = lit("(") << point_coord % lit(',') << lit(")") linestring_coord = lit('(') << point_coord % lit(',') << lit(')')
; ;
polygon_coord = lit("(") << exterior_ring_coord << interior_ring_coord << lit(")") linear_ring_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias()
; ;
exterior_ring_coord = linestring_coord.alias() polygon_coord = linear_ring_coord % lit(',')
; ;
interior_ring_coord = *(lit(",") << exterior_ring_coord) multi_point_coord = lit('(') << point_coord % lit(',') << lit(')');//linestring_coord.alias()
;
multi_point_coord = linestring_coord.alias()
; ;
multi_linestring_coord = lit("(") << linestring_coord % lit(',') << lit(")") multi_linestring_coord = lit("(") << linestring_coord % lit(',') << lit(")")

View file

@ -51,14 +51,10 @@ auto make_empty = [](auto const& ctx)
_val(ctx) = geometry::geometry_empty(); _val(ctx) = geometry::geometry_empty();
}; };
auto set_exterior = [](auto const& ctx) auto add_ring = [](auto const& ctx)
{ {
_val(ctx).set_exterior_ring(std::move(_attr(ctx))); auto & ring = reinterpret_cast<geometry::linear_ring<double> &>(_attr(ctx));
}; _val(ctx).push_back(std::move(ring));
auto add_hole = [](auto const& ctx)
{
_val(ctx).add_hole(std::move(_attr(ctx)));
}; };
// start rule // start rule
@ -84,7 +80,7 @@ x3::rule<class geometries, mapnik::geometry::geometry_collection<double> > const
auto const point_text_def = '(' > double_ > double_ > ')'; auto const point_text_def = '(' > double_ > double_ > ')';
auto const positions_def = lit('(') > (double_ > double_) % lit(',') > lit(')'); auto const positions_def = lit('(') > (double_ > double_) % lit(',') > lit(')');
auto const polygon_rings_def = '(' > positions[set_exterior] > *(lit(',') > positions[add_hole]) > ')'; auto const polygon_rings_def = '(' > positions[add_ring] % lit(',') > ')';
auto const points_def = (lit('(') >> ((point_text_def % ',') > lit(')'))) | positions_def ; auto const points_def = (lit('(') >> ((point_text_def % ',') > lit(')'))) | positions_def ;
auto const lines_def = lit('(') > (positions_def % lit(',')) > lit(')'); auto const lines_def = lit('(') > (positions_def % lit(',')) > lit(')');
auto const polygons_def = lit('(') > (polygon_rings % lit(',')) > lit(')'); auto const polygons_def = lit('(') > (polygon_rings % lit(',')) > lit(')');

View file

@ -98,7 +98,7 @@ mapnik::geometry::line_string<double> ogr_converter::convert_linestring(OGRLineS
geom.reserve(num_points); geom.reserve(num_points);
for (int i = 0; i < num_points; ++i) for (int i = 0; i < num_points; ++i)
{ {
geom.add_coord(ogr_geom->getX(i), ogr_geom->getY(i)); geom.emplace_back(ogr_geom->getX(i), ogr_geom->getY(i));
} }
return geom; return geom;
} }
@ -127,7 +127,7 @@ mapnik::geometry::polygon<double> ogr_converter::convert_polygon(OGRPolygon* ogr
{ {
exterior.emplace_back(ogr_exterior->getX(i), ogr_exterior->getY(i)); exterior.emplace_back(ogr_exterior->getX(i), ogr_exterior->getY(i));
} }
geom.set_exterior_ring(std::move(exterior)); geom.push_back(std::move(exterior));
int num_interior = ogr_geom->getNumInteriorRings(); int num_interior = ogr_geom->getNumInteriorRings();
for (int r = 0; r < num_interior; ++r) for (int r = 0; r < num_interior; ++r)
@ -140,7 +140,7 @@ mapnik::geometry::polygon<double> ogr_converter::convert_polygon(OGRPolygon* ogr
{ {
interior.emplace_back(ogr_interior->getX(i), ogr_interior->getY(i)); interior.emplace_back(ogr_interior->getX(i), ogr_interior->getY(i));
} }
geom.add_hole(std::move(interior)); geom.push_back(std::move(interior));
} }
return geom; return geom;
} }

View file

@ -114,7 +114,7 @@ mapnik::geometry::geometry<double> shape_io::read_polyline(shape_file::record_ty
{ {
double x = record.read_double(); double x = record.read_double();
double y = record.read_double(); double y = record.read_double();
line.add_coord(x, y); line.emplace_back(x, y);
} }
geom = std::move(line); geom = std::move(line);
} }
@ -144,7 +144,7 @@ mapnik::geometry::geometry<double> shape_io::read_polyline(shape_file::record_ty
{ {
double x = record.read_double(); double x = record.read_double();
double y = record.read_double(); double y = record.read_double();
line.add_coord(x, y); line.emplace_back(x, y);
} }
multi_line.push_back(std::move(line)); multi_line.push_back(std::move(line));
} }
@ -210,17 +210,17 @@ mapnik::geometry::geometry<double> shape_io::read_polygon(shape_file::record_typ
} }
if (k == 0) if (k == 0)
{ {
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
} }
else if (mapnik::util::is_clockwise(ring)) else if (mapnik::util::is_clockwise(ring))
{ {
multi_poly.emplace_back(std::move(poly)); multi_poly.emplace_back(std::move(poly));
poly.interior_rings.clear(); poly.clear();
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
} }
else else
{ {
poly.add_hole(std::move(ring)); poly.push_back(std::move(ring));
} }
} }
@ -260,17 +260,17 @@ mapnik::geometry::geometry<double> shape_io::read_polygon_parts(shape_file::reco
} }
if (k == 0) if (k == 0)
{ {
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
} }
else if (mapnik::util::is_clockwise(ring)) else if (mapnik::util::is_clockwise(ring))
{ {
multi_poly.emplace_back(std::move(poly)); multi_poly.emplace_back(std::move(poly));
poly.interior_rings.clear(); poly.clear();
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
} }
else else
{ {
poly.add_hole(std::move(ring)); poly.push_back(std::move(ring));
} }
} }

View file

@ -180,22 +180,30 @@ struct render_ring_visitor
} }
} }
void operator()(mapnik::geometry::polygon<double> const& geom) const void operator()(mapnik::geometry::polygon<double> const& poly) const
{ {
agg::rgba8 red(255,0,0,255); agg::rgba8 red(255,0,0,255);
agg::rgba8 green(0,255,255,255); agg::rgba8 green(0,255,255,255);
agg::rgba8 black(0,0,0,255); agg::rgba8 black(0,0,0,255);
renderer_.draw_ring(geom.exterior_ring,red); bool exterior = true;
if (mapnik::util::is_clockwise(geom.exterior_ring)) for (auto const& ring : poly)
{ {
renderer_.draw_outline(geom.exterior_ring,black); if (exterior)
}
for (auto const& ring : geom.interior_rings)
{
renderer_.draw_ring(ring,green);
if (!mapnik::util::is_clockwise(ring))
{ {
renderer_.draw_outline(ring,black); exterior = false;
renderer_.draw_ring(ring, red);
if (mapnik::util::is_clockwise(ring))
{
renderer_.draw_outline(ring,black);
}
}
else
{
renderer_.draw_ring(ring,green);
if (!mapnik::util::is_clockwise(ring))
{
renderer_.draw_outline(ring,black);
}
} }
} }
} }

View file

@ -26,6 +26,7 @@
namespace mapnik { namespace mapnik {
template class box2d<int>; template class box2d<int>;
//template class box2d<std::int64_t>;
template class box2d<float>; template class box2d<float>;
template class box2d<double>; template class box2d<double>;

View file

@ -103,7 +103,7 @@ bool proj_transform::forward (geometry::point<double> & p) const
return forward(&(p.x), &(p.y), &z, 1); return forward(&(p.x), &(p.y), &z, 1);
} }
unsigned int proj_transform::forward (geometry::line_string<double> & ls) const unsigned int proj_transform::forward (std::vector<geometry::point<double>> & ls) const
{ {
std::size_t size = ls.size(); std::size_t size = ls.size();
if (size == 0) return 0; if (size == 0) return 0;
@ -244,7 +244,7 @@ bool proj_transform::backward (geometry::point<double> & p) const
return backward(&(p.x), &(p.y), &z, 1); return backward(&(p.x), &(p.y), &z, 1);
} }
unsigned int proj_transform::backward (geometry::line_string<double> & ls) const unsigned int proj_transform::backward (std::vector<geometry::point<double>> & ls) const
{ {
std::size_t size = ls.size(); std::size_t size = ls.size();
if (size == 0) return 0; if (size == 0) return 0;

View file

@ -328,11 +328,7 @@ private:
{ {
unsigned int num_rings = read_unsigned_integer(); unsigned int num_rings = read_unsigned_integer();
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
if (num_rings > 1) poly.reserve(num_rings);
{
poly.interior_rings.reserve(num_rings - 1);
}
for (unsigned int i = 0; i < num_rings; ++i) for (unsigned int i = 0; i < num_rings; ++i)
{ {
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -342,8 +338,7 @@ private:
ring.reserve(num_points); ring.reserve(num_points);
read_coords<mapnik::geometry::linear_ring<double>>(ring, num_points); read_coords<mapnik::geometry::linear_ring<double>>(ring, num_points);
} }
if ( i == 0) poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
else poly.add_hole(std::move(ring));
} }
return poly; return poly;
} }

View file

@ -34,7 +34,7 @@ point_vertex_adapter<T>::point_vertex_adapter(point<T> const& pt)
first_(true) {} first_(true) {}
template <typename T> template <typename T>
unsigned point_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const unsigned point_vertex_adapter<T>::vertex(coordinate_type * x, coordinate_type * y) const
{ {
if (first_) if (first_)
{ {
@ -67,7 +67,7 @@ line_string_vertex_adapter<T>::line_string_vertex_adapter(line_string<T> const&
{} {}
template <typename T> template <typename T>
unsigned line_string_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const unsigned line_string_vertex_adapter<T>::vertex(coordinate_type * x, coordinate_type * y) const
{ {
if (current_index_ != end_index_) if (current_index_ != end_index_)
{ {
@ -102,22 +102,22 @@ template <typename T>
polygon_vertex_adapter<T>::polygon_vertex_adapter(polygon<T> const& poly) polygon_vertex_adapter<T>::polygon_vertex_adapter(polygon<T> const& poly)
: poly_(poly), : poly_(poly),
rings_itr_(0), rings_itr_(0),
rings_end_(poly_.interior_rings.size() + 1), rings_end_(poly_.size()),
current_index_(0), current_index_(0),
end_index_((rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0), end_index_(poly_.empty() ? 0 : poly_[0].size()),
start_loop_(true) {} start_loop_(true) {}
template <typename T> template <typename T>
void polygon_vertex_adapter<T>::rewind(unsigned) const void polygon_vertex_adapter<T>::rewind(unsigned) const
{ {
rings_itr_ = 0; rings_itr_ = 0;
rings_end_ = poly_.interior_rings.size() + 1; rings_end_ = poly_.size();
current_index_ = 0; current_index_ = 0;
end_index_ = (rings_itr_ < rings_end_) ? poly_.exterior_ring.size() : 0; end_index_ = poly_.empty() ? 0 : poly_[0].size();
start_loop_ = true; start_loop_ = true;
} }
template <typename T> template <typename T>
unsigned polygon_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const unsigned polygon_vertex_adapter<T>::vertex(coordinate_type * x, coordinate_type * y) const
{ {
if (rings_itr_ == rings_end_) if (rings_itr_ == rings_end_)
{ {
@ -125,8 +125,7 @@ unsigned polygon_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const
} }
if (current_index_ < end_index_) if (current_index_ < end_index_)
{ {
point<T> const& coord = (rings_itr_ == 0) ? point<T> const& coord = poly_[rings_itr_][current_index_++];
poly_.exterior_ring[current_index_++] : poly_.interior_rings[rings_itr_- 1][current_index_++];
*x = coord.x; *x = coord.x;
*y = coord.y; *y = coord.y;
if (start_loop_) if (start_loop_)
@ -145,8 +144,8 @@ unsigned polygon_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const
else if (++rings_itr_ != rings_end_) else if (++rings_itr_ != rings_end_)
{ {
current_index_ = 0; current_index_ = 0;
end_index_ = poly_.interior_rings[rings_itr_ - 1].size(); end_index_ = poly_[rings_itr_].size();
point<T> const& coord = poly_.interior_rings[rings_itr_ - 1][current_index_++]; point<T> const& coord = poly_[rings_itr_][current_index_++];
*x = coord.x; *x = coord.x;
*y = coord.y; *y = coord.y;
return mapnik::SEG_MOVETO; return mapnik::SEG_MOVETO;
@ -177,7 +176,7 @@ void ring_vertex_adapter<T>::rewind(unsigned) const
} }
template <typename T> template <typename T>
unsigned ring_vertex_adapter<T>::vertex(coord_type * x, coord_type * y) const unsigned ring_vertex_adapter<T>::vertex(coordinate_type * x, coordinate_type * y) const
{ {
if (current_index_ < end_index_) if (current_index_ < end_index_)
{ {

View file

@ -331,11 +331,7 @@ private:
{ {
int num_rings = read_integer(); int num_rings = read_integer();
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
if (num_rings > 1) poly.reserve(num_rings);
{
poly.interior_rings.reserve(num_rings - 1);
}
for (int i = 0; i < num_rings; ++i) for (int i = 0; i < num_rings; ++i)
{ {
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
@ -345,8 +341,7 @@ private:
ring.reserve(num_points); ring.reserve(num_points);
read_coords<mapnik::geometry::linear_ring<double>, M, Z>(ring, num_points); read_coords<mapnik::geometry::linear_ring<double>, M, Z>(ring, num_points);
} }
if ( i == 0) poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
else poly.add_hole(std::move(ring));
} }
return poly; return poly;
} }

View file

@ -121,48 +121,53 @@ inline void require_attributes(mapnik::feature_ptr feature,
} }
namespace detail { namespace detail {
struct feature_count {
template <typename T> template <typename T>
std::size_t operator()(T const &geom) const { struct feature_count
{
template <typename U>
std::size_t operator()(U const &geom) const
{
return mapnik::util::apply_visitor(*this, geom); return mapnik::util::apply_visitor(*this, geom);
} }
std::size_t operator()(mapnik::geometry::geometry_empty const &) const { std::size_t operator()(mapnik::geometry::geometry_empty const &) const
{
return 0; return 0;
} }
template <typename T> std::size_t operator()(mapnik::geometry::point<T> const &) const
std::size_t operator()(mapnik::geometry::point<T> const &) const { {
return 1; return 1;
} }
template <typename T> std::size_t operator()(mapnik::geometry::line_string<T> const &) const
std::size_t operator()(mapnik::geometry::line_string<T> const &) const { {
return 1; return 1;
} }
template <typename T> std::size_t operator()(mapnik::geometry::polygon<T> const &) const
std::size_t operator()(mapnik::geometry::polygon<T> const &) const { {
return 1; return 1;
} }
template <typename T> std::size_t operator()(mapnik::geometry::multi_point<T> const &mp) const
std::size_t operator()(mapnik::geometry::multi_point<T> const &mp) const { {
return mp.size(); return mp.size();
} }
template <typename T> std::size_t operator()(mapnik::geometry::multi_line_string<T> const &mls) const
std::size_t operator()(mapnik::geometry::multi_line_string<T> const &mls) const { {
return mls.size(); return mls.size();
} }
template <typename T> std::size_t operator()(mapnik::geometry::multi_polygon<T> const &mp) const
std::size_t operator()(mapnik::geometry::multi_polygon<T> const &mp) const { {
return mp.size(); return mp.size();
} }
template <typename T> std::size_t operator()(mapnik::geometry::geometry_collection<T> const &col) const
std::size_t operator()(mapnik::geometry::geometry_collection<T> const &col) const { {
std::size_t sum = 0; std::size_t sum = 0;
for (auto const &geom : col) { for (auto const &geom : col) {
sum += operator()(geom); sum += operator()(geom);
@ -174,7 +179,7 @@ struct feature_count {
template <typename T> template <typename T>
inline std::size_t feature_count(mapnik::geometry::geometry<T> const &g) { inline std::size_t feature_count(mapnik::geometry::geometry<T> const &g) {
return detail::feature_count()(g); return detail::feature_count<T>()(g);
} }
inline void require_geometry(mapnik::feature_ptr feature, inline void require_geometry(mapnik::feature_ptr feature,

View file

@ -289,10 +289,9 @@ TEST_CASE("geojson") {
auto const& geometry = feature->get_geometry(); auto const& geometry = feature->get_geometry();
REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Polygon); REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::Polygon);
auto const& poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geometry); auto const& poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geometry);
REQUIRE(poly.num_rings() == 2); REQUIRE(poly.size() == 2);
REQUIRE(poly.exterior_ring.size() == 5); REQUIRE(poly[0].size() == 5);
REQUIRE(poly.interior_rings.size() == 1); REQUIRE(poly[1].size() == 5);
REQUIRE(poly.interior_rings[0].size() == 5);
REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d<double>(100,0,101,1)); REQUIRE(mapnik::geometry::envelope(poly) == mapnik::box2d<double>(100,0,101,1));
} }
@ -346,8 +345,8 @@ TEST_CASE("geojson") {
REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPolygon); REQUIRE(mapnik::geometry::geometry_type(geometry) == mapnik::geometry::MultiPolygon);
auto const& multi_poly = mapnik::util::get<mapnik::geometry::multi_polygon<double> >(geometry); auto const& multi_poly = mapnik::util::get<mapnik::geometry::multi_polygon<double> >(geometry);
REQUIRE(multi_poly.size() == 2); REQUIRE(multi_poly.size() == 2);
REQUIRE(multi_poly[0].num_rings() == 1); REQUIRE(multi_poly[0].size() == 1);
REQUIRE(multi_poly[1].num_rings() == 2); REQUIRE(multi_poly[1].size() == 2);
REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d<double>(100,0,103,3)); REQUIRE(mapnik::geometry::envelope(multi_poly) == mapnik::box2d<double>(100,0,103,3));
} }

View file

@ -30,9 +30,9 @@ SECTION("point") {
SECTION("linestring") { SECTION("linestring") {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0, 0); line.emplace_back(0, 0);
line.add_coord(25, 25); line.emplace_back(25, 25);
line.add_coord(50, 50); line.emplace_back(50, 50);
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(mapnik::geometry::centroid(line, centroid)); REQUIRE(mapnik::geometry::centroid(line, centroid));
REQUIRE(centroid.x == 25); REQUIRE(centroid.x == 25);
@ -50,12 +50,12 @@ SECTION("polygon") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0); ring.emplace_back(0, 0);
ring.add_coord(1, 0); ring.emplace_back(1, 0);
ring.add_coord(1, 1); ring.emplace_back(1, 1);
ring.add_coord(0, 1); ring.emplace_back(0, 1);
ring.add_coord(0, 0); ring.emplace_back(0, 0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(mapnik::geometry::centroid(poly, centroid)); REQUIRE(mapnik::geometry::centroid(poly, centroid));
@ -67,7 +67,7 @@ SECTION("polygon with empty exterior ring") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(poly, centroid)); REQUIRE(!mapnik::geometry::centroid(poly, centroid));
@ -76,6 +76,7 @@ SECTION("polygon with empty exterior ring") {
SECTION("empty polygon") { SECTION("empty polygon") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back();
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(!mapnik::geometry::centroid(poly, centroid)); REQUIRE(!mapnik::geometry::centroid(poly, centroid));
} }
@ -83,9 +84,9 @@ SECTION("empty polygon") {
SECTION("multi-point") { SECTION("multi-point") {
mapnik::geometry::multi_point<double> geom; mapnik::geometry::multi_point<double> geom;
geom.add_coord(0, 0); geom.emplace_back(0, 0);
geom.add_coord(25, 25); geom.emplace_back(25, 25);
geom.add_coord(50, 50); geom.emplace_back(50, 50);
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(mapnik::geometry::centroid(geom, centroid)); REQUIRE(mapnik::geometry::centroid(geom, centroid));
REQUIRE(centroid.x == 25); REQUIRE(centroid.x == 25);
@ -104,16 +105,16 @@ SECTION("multi-linestring") {
mapnik::geometry::multi_line_string<double> geom; mapnik::geometry::multi_line_string<double> geom;
{ {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0, 0); line.emplace_back(0, 0);
line.add_coord(0, 25); line.emplace_back(0, 25);
line.add_coord(0, 50); line.emplace_back(0, 50);
geom.emplace_back(std::move(line)); geom.emplace_back(std::move(line));
} }
{ {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0, 0); line.emplace_back(0, 0);
line.add_coord(25, 0); line.emplace_back(25, 0);
line.add_coord(50, 0); line.emplace_back(50, 0);
geom.emplace_back(std::move(line)); geom.emplace_back(std::move(line));
} }
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
@ -126,9 +127,9 @@ SECTION("multi-linestring: one component empty") {
mapnik::geometry::multi_line_string<double> geom; mapnik::geometry::multi_line_string<double> geom;
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0, 0); line.emplace_back(0, 0);
line.add_coord(0, 25); line.emplace_back(0, 25);
line.add_coord(0, 50); line.emplace_back(0, 50);
geom.emplace_back(std::move(line)); geom.emplace_back(std::move(line));
geom.emplace_back(); geom.emplace_back();
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
@ -150,23 +151,23 @@ SECTION("multi-polygon") {
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0); ring.emplace_back(0, 0);
ring.add_coord(1, 0); ring.emplace_back(1, 0);
ring.add_coord(1, 1); ring.emplace_back(1, 1);
ring.add_coord(0, 1); ring.emplace_back(0, 1);
ring.add_coord(0, 0); ring.emplace_back(0, 0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geom.emplace_back(std::move(poly)); geom.emplace_back(std::move(poly));
} }
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(1, 1); ring.emplace_back(1, 1);
ring.add_coord(2, 1); ring.emplace_back(2, 1);
ring.add_coord(2, 2); ring.emplace_back(2, 2);
ring.add_coord(1, 2); ring.emplace_back(1, 2);
ring.add_coord(1, 1); ring.emplace_back(1, 1);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geom.emplace_back(std::move(poly)); geom.emplace_back(std::move(poly));
} }
@ -178,22 +179,22 @@ SECTION("multi-polygon") {
SECTION("multi-polygon: one component empty") { SECTION("multi-polygon: one component empty") {
mapnik::geometry::multi_polygon<double> geom; mapnik::geometry::multi_polygon<double> geom;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0); ring.emplace_back(0, 0);
ring.add_coord(1, 0); ring.emplace_back(1, 0);
ring.add_coord(1, 1); ring.emplace_back(1, 1);
ring.add_coord(0, 1); ring.emplace_back(0, 1);
ring.add_coord(0, 0); ring.emplace_back(0, 0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geom.emplace_back(std::move(poly)); geom.emplace_back(std::move(poly));
geom.emplace_back(); geom.emplace_back();
geom.back().emplace_back();
mapnik::geometry::point<double> centroid; mapnik::geometry::point<double> centroid;
REQUIRE(mapnik::geometry::centroid(geom, centroid)); REQUIRE(mapnik::geometry::centroid(geom, centroid));
REQUIRE(centroid.x == 0.5); REQUIRE(centroid.x == 0.5);
REQUIRE(centroid.y == 0.5); REQUIRE(centroid.y == 0.5);
} }
SECTION("empty multi-polygon") { SECTION("empty multi-polygon") {

View file

@ -27,9 +27,9 @@ void envelope_test()
} }
{ {
line_string<coord_type> line; line_string<coord_type> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(2,2); line.emplace_back(2,2);
geometry<coord_type> geom(line); geometry<coord_type> geom(line);
mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom); mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE( bbox.minx() == 0 ); REQUIRE( bbox.minx() == 0 );
@ -39,13 +39,13 @@ void envelope_test()
} }
{ {
line_string<coord_type> line; line_string<coord_type> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(2,2); line.emplace_back(2,2);
line_string<coord_type> line2; line_string<coord_type> line2;
line2.add_coord(0,0); line2.emplace_back(0,0);
line2.add_coord(-1,-1); line2.emplace_back(-1,-1);
line2.add_coord(-2,-2); line2.emplace_back(-2,-2);
multi_line_string<coord_type> multi_line; multi_line_string<coord_type> multi_line;
multi_line.emplace_back(std::move(line)); multi_line.emplace_back(std::move(line));
multi_line.emplace_back(std::move(line2)); multi_line.emplace_back(std::move(line2));
@ -59,12 +59,12 @@ void envelope_test()
{ {
polygon<coord_type> poly; polygon<coord_type> poly;
linear_ring<coord_type> ring; linear_ring<coord_type> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(-10,0); ring.emplace_back(-10,0);
ring.add_coord(-10,10); ring.emplace_back(-10,10);
ring.add_coord(0,10); ring.emplace_back(0,10);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geometry<coord_type> geom(poly); geometry<coord_type> geom(poly);
mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom); mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(geom);
REQUIRE( bbox.minx() == -10 ); REQUIRE( bbox.minx() == -10 );
@ -102,19 +102,19 @@ void envelope_test()
// polygon with hole // polygon with hole
polygon<coord_type> poly; polygon<coord_type> poly;
linear_ring<coord_type> ring; linear_ring<coord_type> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(-10,0); ring.emplace_back(-10,0);
ring.add_coord(-10,10); ring.emplace_back(-10,10);
ring.add_coord(0,10); ring.emplace_back(0,10);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
linear_ring<coord_type> hole; linear_ring<coord_type> hole;
hole.add_coord(-7,7); hole.emplace_back(-7,7);
hole.add_coord(-7,3); hole.emplace_back(-7,3);
hole.add_coord(-3,3); hole.emplace_back(-3,3);
hole.add_coord(-3,7); hole.emplace_back(-3,7);
hole.add_coord(-7,7); hole.emplace_back(-7,7);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
geometry<coord_type> geom(poly); geometry<coord_type> geom(poly);
mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(poly); mapnik::box2d<coord_type> bbox = mapnik::geometry::envelope(poly);
REQUIRE( bbox.minx() == -10 ); REQUIRE( bbox.minx() == -10 );
@ -124,12 +124,12 @@ void envelope_test()
// add another hole inside the first hole // add another hole inside the first hole
// which should be considered a hit // which should be considered a hit
linear_ring<coord_type> fill; linear_ring<coord_type> fill;
fill.add_coord(-6,4); fill.emplace_back(-6,4);
fill.add_coord(-6,6); fill.emplace_back(-6,6);
fill.add_coord(-4,6); fill.emplace_back(-4,6);
fill.add_coord(-4,4); fill.emplace_back(-4,4);
fill.add_coord(-6,4); fill.emplace_back(-6,4);
poly.add_hole(std::move(fill)); poly.push_back(std::move(fill));
bbox = mapnik::geometry::envelope(poly); bbox = mapnik::geometry::envelope(poly);
REQUIRE( bbox.minx() == -10 ); REQUIRE( bbox.minx() == -10 );
REQUIRE( bbox.miny() == 0 ); REQUIRE( bbox.miny() == 0 );

View file

@ -106,6 +106,7 @@ struct geometry_equal_visitor
REQUIRE(false); REQUIRE(false);
} }
template <typename T>
void operator() (geometry_empty const&, geometry_empty const&) const void operator() (geometry_empty const&, geometry_empty const&) const
{ {
REQUIRE(true); REQUIRE(true);
@ -119,7 +120,7 @@ struct geometry_equal_visitor
} }
template <typename T> template <typename T>
void operator() (line_string<T> const& ls1, line_string<T> const& ls2) const void operator() (std::vector<point<T>> const& ls1, std::vector<point<T>> const& ls2) const
{ {
if (ls1.size() != ls2.size()) if (ls1.size() != ls2.size())
{ {
@ -136,25 +137,33 @@ struct geometry_equal_visitor
template <typename T> template <typename T>
void operator() (polygon<T> const& p1, polygon<T> const& p2) const void operator() (polygon<T> const& p1, polygon<T> const& p2) const
{ {
(*this)(static_cast<line_string<T> const&>(p1.exterior_ring), static_cast<line_string<T> const&>(p2.exterior_ring)); if (p1.size() != p2.size())
if (p1.interior_rings.size() != p2.interior_rings.size())
{ {
REQUIRE(false); REQUIRE(false);
} }
for (auto const& p : zip_crange(p1.interior_rings, p2.interior_rings)) for (auto const& p : zip_crange(p1, p2))
{ {
(*this)(static_cast<line_string<T> const&>(p.template get<0>()),static_cast<line_string<T> const&>(p.template get<1>())); (*this)(static_cast<std::vector<point<T>> const&>(p.template get<0>()),
static_cast<std::vector<point<T>> const&>(p.template get<1>()));
} }
} }
template <typename T>
void operator() (line_string<T> const& ls1, line_string<T> const& ls2) const
{
(*this)(static_cast<std::vector<point<T>> const&>(ls1),
static_cast<std::vector<point<T>> const&>(ls2));
}
template <typename T> template <typename T>
void operator() (multi_point<T> const& mp1, multi_point<T> const& mp2) const void operator() (multi_point<T> const& mp1, multi_point<T> const& mp2) const
{ {
(*this)(static_cast<line_string<T> const&>(mp1), static_cast<line_string<T> const&>(mp2)); (*this)(static_cast<std::vector<point<T>> const&>(mp1),
static_cast<std::vector<point<T>> const&>(mp2));
} }
template <typename T> template <typename T>
void operator() (multi_line_string<T> const& mls1, multi_line_string<T> const& mls2) const void operator() (multi_line_string<T> const& mls1, multi_line_string<T> const& mls2) const
{ {

View file

@ -26,17 +26,17 @@ SECTION("hit_test_filter - double") {
} }
{ {
line_string<double> line; line_string<double> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(2,2); line.emplace_back(2,2);
geometry<double> geom(line); geometry<double> geom(line);
REQUIRE( mapnik::hit_test(geom,0,0,1.5) ); REQUIRE( mapnik::hit_test(geom,0,0,1.5) );
} }
{ {
line_string<double> line; line_string<double> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(2,2); line.emplace_back(2,2);
multi_line_string<double> multi_line; multi_line_string<double> multi_line;
multi_line.emplace_back(std::move(line)); multi_line.emplace_back(std::move(line));
geometry<double> geom(multi_line); geometry<double> geom(multi_line);
@ -45,12 +45,12 @@ SECTION("hit_test_filter - double") {
{ {
polygon<double> poly; polygon<double> poly;
linear_ring<double> ring; linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(-10,0); ring.emplace_back(-10,0);
ring.add_coord(-10,10); ring.emplace_back(-10,10);
ring.add_coord(0,10); ring.emplace_back(0,10);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geometry<double> geom(poly); geometry<double> geom(poly);
REQUIRE( mapnik::hit_test(geom,-5,5,0) ); REQUIRE( mapnik::hit_test(geom,-5,5,0) );
@ -77,30 +77,30 @@ SECTION("hit_test_filter - double") {
// polygon with hole // polygon with hole
polygon<double> poly; polygon<double> poly;
linear_ring<double> ring; linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(-10,0); ring.emplace_back(-10,0);
ring.add_coord(-10,10); ring.emplace_back(-10,10);
ring.add_coord(0,10); ring.emplace_back(0,10);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
linear_ring<double> hole; linear_ring<double> hole;
hole.add_coord(-7,7); hole.emplace_back(-7,7);
hole.add_coord(-7,3); hole.emplace_back(-7,3);
hole.add_coord(-3,3); hole.emplace_back(-3,3);
hole.add_coord(-3,7); hole.emplace_back(-3,7);
hole.add_coord(-7,7); hole.emplace_back(-7,7);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
geometry<double> geom(poly); geometry<double> geom(poly);
REQUIRE( !mapnik::hit_test(geom,-5,5,0) ); REQUIRE( !mapnik::hit_test(geom,-5,5,0) );
// add another hole inside the first hole // add another hole inside the first hole
// which should be considered a hit // which should be considered a hit
linear_ring<double> fill; linear_ring<double> fill;
fill.add_coord(-6,4); fill.emplace_back(-6,4);
fill.add_coord(-6,6); fill.emplace_back(-6,6);
fill.add_coord(-4,6); fill.emplace_back(-4,6);
fill.add_coord(-4,4); fill.emplace_back(-4,4);
fill.add_coord(-6,4); fill.emplace_back(-6,4);
poly.add_hole(std::move(fill)); poly.push_back(std::move(fill));
REQUIRE( mapnik::hit_test(geometry<double>(poly),-5,5,0) ); REQUIRE( mapnik::hit_test(geometry<double>(poly),-5,5,0) );
} }
} }

View file

@ -52,8 +52,8 @@ SECTION("point Infinity") {
SECTION("multi point") { SECTION("multi point") {
mapnik::geometry::multi_point<double> mpt; mapnik::geometry::multi_point<double> mpt;
mpt.add_coord(0,0); mpt.emplace_back(0,0);
mpt.add_coord(1,1); mpt.emplace_back(1,1);
CHECK( mapnik::geometry::is_simple(mpt) ); CHECK( mapnik::geometry::is_simple(mpt) );
} }
@ -64,18 +64,18 @@ SECTION("multi point empty") {
SECTION("line_string") { SECTION("line_string") {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
CHECK( mapnik::geometry::is_simple(line) ); CHECK( mapnik::geometry::is_simple(line) );
} }
// This fails while is_valid will not fail! // This fails while is_valid will not fail!
SECTION("line_string repeated points") { SECTION("line_string repeated points") {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(2,2); line.emplace_back(2,2);
CHECK( !mapnik::geometry::is_simple(line) ); CHECK( !mapnik::geometry::is_simple(line) );
} }
@ -86,11 +86,11 @@ SECTION("line_string empty") {
SECTION("multi_line_string") { SECTION("multi_line_string") {
mapnik::geometry::line_string<double> line1; mapnik::geometry::line_string<double> line1;
line1.add_coord(0,0); line1.emplace_back(0,0);
line1.add_coord(1,1); line1.emplace_back(1,1);
mapnik::geometry::line_string<double> line2; mapnik::geometry::line_string<double> line2;
line2.add_coord(0,1); line2.emplace_back(0,1);
line2.add_coord(1,2); line2.emplace_back(1,2);
mapnik::geometry::multi_line_string<double> lines; mapnik::geometry::multi_line_string<double> lines;
lines.emplace_back(line1); lines.emplace_back(line1);
lines.emplace_back(line2); lines.emplace_back(line2);
@ -112,24 +112,24 @@ SECTION("multi_line_string empty") {
SECTION("polygon") { SECTION("polygon") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
SECTION("polygon invalid winding order") { SECTION("polygon invalid winding order") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
@ -138,13 +138,13 @@ SECTION("polygon invalid winding order") {
SECTION("polygon 2 repeated points") { SECTION("polygon 2 repeated points") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( !mapnik::geometry::is_simple(poly) ); CHECK( !mapnik::geometry::is_simple(poly) );
} }
// repeated points are not considered invalid in a polygon // repeated points are not considered invalid in a polygon
@ -152,14 +152,14 @@ SECTION("polygon 2 repeated points") {
SECTION("polygon 3 repeated points") { SECTION("polygon 3 repeated points") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( !mapnik::geometry::is_simple(poly) ); CHECK( !mapnik::geometry::is_simple(poly) );
} }
@ -167,27 +167,28 @@ SECTION("polygon 3 repeated points") {
SECTION("polygon that is empty") { SECTION("polygon that is empty") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back();
CHECK( !mapnik::geometry::is_simple(poly) ); CHECK( !mapnik::geometry::is_simple(poly) );
} }
SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty exterior ring") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( !mapnik::geometry::is_simple(poly) ); CHECK( !mapnik::geometry::is_simple(poly) );
} }
SECTION("polygon that has empty interior ring") { SECTION("polygon that has empty interior ring") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> ring2; mapnik::geometry::linear_ring<double> ring2;
poly.add_hole(std::move(ring2)); poly.push_back(std::move(ring2));
CHECK( !mapnik::geometry::is_simple(poly) ); CHECK( !mapnik::geometry::is_simple(poly) );
} }
@ -201,21 +202,21 @@ SECTION("polygon that is empty") {
SECTION("polygon that has empty exterior ring") { SECTION("polygon that has empty exterior ring") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
SECTION("polygon that has empty interior ring") { SECTION("polygon that has empty interior ring") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> ring2; mapnik::geometry::linear_ring<double> ring2;
poly.add_hole(std::move(ring2)); poly.push_back(std::move(ring2));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
@ -225,33 +226,33 @@ SECTION("polygon that has empty interior ring") {
SECTION("polygon with spike") { SECTION("polygon with spike") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(2,2); ring.emplace_back(2,2);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
SECTION("polygon with hole") { SECTION("polygon with hole") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(1,1); hole.emplace_back(1,1);
hole.add_coord(1,2); hole.emplace_back(1,2);
hole.add_coord(2,2); hole.emplace_back(2,2);
hole.add_coord(2,1); hole.emplace_back(2,1);
hole.add_coord(1,1); hole.emplace_back(1,1);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
@ -259,19 +260,19 @@ SECTION("polygon with hole") {
SECTION("polygon with hole with invalid winding order") { SECTION("polygon with hole with invalid winding order") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(1,1); hole.emplace_back(1,1);
hole.add_coord(2,1); hole.emplace_back(2,1);
hole.add_coord(2,2); hole.emplace_back(2,2);
hole.add_coord(1,2); hole.emplace_back(1,2);
hole.add_coord(1,1); hole.emplace_back(1,1);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
CHECK( mapnik::geometry::is_simple(poly) ); CHECK( mapnik::geometry::is_simple(poly) );
} }
@ -279,20 +280,21 @@ SECTION("multi polygon") {
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0);
ring.add_coord(1,0); ring.emplace_back(0,0);
ring.add_coord(1,1); ring.emplace_back(1,0);
ring.add_coord(0,1); ring.emplace_back(1,1);
ring.add_coord(0,0); ring.emplace_back(0,1);
poly.set_exterior_ring(std::move(ring)); ring.emplace_back(0,0);
poly.push_back(std::move(ring));
mapnik::geometry::polygon<double> poly2; mapnik::geometry::polygon<double> poly2;
mapnik::geometry::linear_ring<double> ring2; mapnik::geometry::linear_ring<double> ring2;
ring2.add_coord(0,0); ring2.emplace_back(0,0);
ring2.add_coord(-1,0); ring2.emplace_back(-1,0);
ring2.add_coord(-1,-1); ring2.emplace_back(-1,-1);
ring2.add_coord(0,-1); ring2.emplace_back(0,-1);
ring2.add_coord(0,0); ring2.emplace_back(0,0);
poly2.set_exterior_ring(std::move(ring2)); poly2.push_back(std::move(ring2));
mp.emplace_back(poly); mp.emplace_back(poly);
mp.emplace_back(poly2); mp.emplace_back(poly2);
CHECK( mapnik::geometry::is_simple(mp) ); CHECK( mapnik::geometry::is_simple(mp) );
@ -302,34 +304,34 @@ SECTION("multi polygon with hole") {
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(1,1); hole.emplace_back(1,1);
hole.add_coord(1,2); hole.emplace_back(1,2);
hole.add_coord(2,2); hole.emplace_back(2,2);
hole.add_coord(2,1); hole.emplace_back(2,1);
hole.add_coord(1,1); hole.emplace_back(1,1);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
mapnik::geometry::polygon<double> poly2; mapnik::geometry::polygon<double> poly2;
mapnik::geometry::linear_ring<double> ring2; mapnik::geometry::linear_ring<double> ring2;
ring2.add_coord(0,0); ring2.emplace_back(0,0);
ring2.add_coord(-3,0); ring2.emplace_back(-3,0);
ring2.add_coord(-3,-3); ring2.emplace_back(-3,-3);
ring2.add_coord(0,-3); ring2.emplace_back(0,-3);
ring2.add_coord(0,0); ring2.emplace_back(0,0);
poly2.set_exterior_ring(std::move(ring2)); poly2.push_back(std::move(ring2));
mapnik::geometry::linear_ring<double> hole2; mapnik::geometry::linear_ring<double> hole2;
hole2.add_coord(-1,-1); hole2.emplace_back(-1,-1);
hole2.add_coord(-1,-2); hole2.emplace_back(-1,-2);
hole2.add_coord(-2,-2); hole2.emplace_back(-2,-2);
hole2.add_coord(-2,-1); hole2.emplace_back(-2,-1);
hole2.add_coord(-1,-1); hole2.emplace_back(-1,-1);
poly2.add_hole(std::move(hole2)); poly2.push_back(std::move(hole2));
mp.emplace_back(poly); mp.emplace_back(poly);
mp.emplace_back(poly2); mp.emplace_back(poly2);
CHECK( mapnik::geometry::is_simple(mp) ); CHECK( mapnik::geometry::is_simple(mp) );

View file

@ -123,8 +123,8 @@ SECTION("point Infinity") {
SECTION("multi point") { SECTION("multi point") {
mapnik::geometry::multi_point<double> mpt; mapnik::geometry::multi_point<double> mpt;
mpt.add_coord(0,0); mpt.emplace_back(0,0);
mpt.add_coord(1,1); mpt.emplace_back(1,1);
CHECK( mapnik::geometry::is_valid(mpt) ); CHECK( mapnik::geometry::is_valid(mpt) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(mpt, message) ); CHECK( mapnik::geometry::is_valid(mpt, message) );
@ -148,8 +148,8 @@ SECTION("multi point empty") {
SECTION("line_string") { SECTION("line_string") {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
CHECK( mapnik::geometry::is_valid(line) ); CHECK( mapnik::geometry::is_valid(line) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(line, message) ); CHECK( mapnik::geometry::is_valid(line, message) );
@ -162,10 +162,10 @@ SECTION("line_string") {
// This shouldn't fail -- test added in case logic ever changes // This shouldn't fail -- test added in case logic ever changes
SECTION("line_string repeated points") { SECTION("line_string repeated points") {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0,0); line.emplace_back(0,0);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(1,1); line.emplace_back(1,1);
line.add_coord(2,2); line.emplace_back(2,2);
CHECK( mapnik::geometry::is_valid(line) ); CHECK( mapnik::geometry::is_valid(line) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(line, message) ); CHECK( mapnik::geometry::is_valid(line, message) );
@ -188,11 +188,11 @@ SECTION("line_string empty") {
SECTION("multi_line_string") { SECTION("multi_line_string") {
mapnik::geometry::line_string<double> line1; mapnik::geometry::line_string<double> line1;
line1.add_coord(0,0); line1.emplace_back(0,0);
line1.add_coord(1,1); line1.emplace_back(1,1);
mapnik::geometry::line_string<double> line2; mapnik::geometry::line_string<double> line2;
line2.add_coord(0,1); line2.emplace_back(0,1);
line2.add_coord(1,2); line2.emplace_back(1,2);
mapnik::geometry::multi_line_string<double> lines; mapnik::geometry::multi_line_string<double> lines;
lines.emplace_back(line1); lines.emplace_back(line1);
lines.emplace_back(line2); lines.emplace_back(line2);
@ -219,12 +219,12 @@ SECTION("multi_line_string empty") {
SECTION("polygon") { SECTION("polygon") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_valid(poly) ); CHECK( mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(poly, message) ); CHECK( mapnik::geometry::is_valid(poly, message) );
@ -237,12 +237,12 @@ SECTION("polygon") {
SECTION("polygon invalid winding order") { SECTION("polygon invalid winding order") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( !mapnik::geometry::is_valid(poly) ); CHECK( !mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( !mapnik::geometry::is_valid(poly, message) ); CHECK( !mapnik::geometry::is_valid(poly, message) );
@ -256,13 +256,13 @@ SECTION("polygon invalid winding order") {
SECTION("polygon 2 repeated points") { SECTION("polygon 2 repeated points") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_valid(poly) ); CHECK( mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(poly, message) ); CHECK( mapnik::geometry::is_valid(poly, message) );
@ -275,14 +275,14 @@ SECTION("polygon 2 repeated points") {
SECTION("polygon 3 repeated points") { SECTION("polygon 3 repeated points") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( mapnik::geometry::is_valid(poly) ); CHECK( mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(poly, message) ); CHECK( mapnik::geometry::is_valid(poly, message) );
@ -294,6 +294,7 @@ SECTION("polygon 3 repeated points") {
SECTION("polygon that is empty") { SECTION("polygon that is empty") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
poly.emplace_back();
CHECK( !mapnik::geometry::is_valid(poly) ); CHECK( !mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( !mapnik::geometry::is_valid(poly, message) ); CHECK( !mapnik::geometry::is_valid(poly, message) );
@ -306,14 +307,14 @@ SECTION("polygon that is empty") {
SECTION("polygon with spike") { SECTION("polygon with spike") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(2,2); ring.emplace_back(2,2);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
CHECK( !mapnik::geometry::is_valid(poly) ); CHECK( !mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( !mapnik::geometry::is_valid(poly, message) ); CHECK( !mapnik::geometry::is_valid(poly, message) );
@ -326,19 +327,19 @@ SECTION("polygon with spike") {
SECTION("polygon with hole") { SECTION("polygon with hole") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(1,1); hole.emplace_back(1,1);
hole.add_coord(1,2); hole.emplace_back(1,2);
hole.add_coord(2,2); hole.emplace_back(2,2);
hole.add_coord(2,1); hole.emplace_back(2,1);
hole.add_coord(1,1); hole.emplace_back(1,1);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
CHECK( mapnik::geometry::is_valid(poly) ); CHECK( mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( mapnik::geometry::is_valid(poly, message) ); CHECK( mapnik::geometry::is_valid(poly, message) );
@ -351,14 +352,14 @@ SECTION("polygon with hole") {
SECTION("polygon with empty hole") { SECTION("polygon with empty hole") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
CHECK( !mapnik::geometry::is_valid(poly) ); CHECK( !mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( !mapnik::geometry::is_valid(poly, message) ); CHECK( !mapnik::geometry::is_valid(poly, message) );
@ -372,19 +373,19 @@ SECTION("polygon with empty hole") {
SECTION("polygon with hole with invalid winding order") { SECTION("polygon with hole with invalid winding order") {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(1,1); hole.emplace_back(1,1);
hole.add_coord(2,1); hole.emplace_back(2,1);
hole.add_coord(2,2); hole.emplace_back(2,2);
hole.add_coord(1,2); hole.emplace_back(1,2);
hole.add_coord(1,1); hole.emplace_back(1,1);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
CHECK( !mapnik::geometry::is_valid(poly) ); CHECK( !mapnik::geometry::is_valid(poly) );
std::string message; std::string message;
CHECK( !mapnik::geometry::is_valid(poly, message) ); CHECK( !mapnik::geometry::is_valid(poly, message) );
@ -398,20 +399,20 @@ SECTION("multi polygon") {
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(1,0); ring.emplace_back(1,0);
ring.add_coord(1,1); ring.emplace_back(1,1);
ring.add_coord(0,1); ring.emplace_back(0,1);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::polygon<double> poly2; mapnik::geometry::polygon<double> poly2;
mapnik::geometry::linear_ring<double> ring2; mapnik::geometry::linear_ring<double> ring2;
ring2.add_coord(0,0); ring2.emplace_back(0,0);
ring2.add_coord(-1,0); ring2.emplace_back(-1,0);
ring2.add_coord(-1,-1); ring2.emplace_back(-1,-1);
ring2.add_coord(0,-1); ring2.emplace_back(0,-1);
ring2.add_coord(0,0); ring2.emplace_back(0,0);
poly2.set_exterior_ring(std::move(ring2)); poly2.push_back(std::move(ring2));
mp.emplace_back(poly); mp.emplace_back(poly);
mp.emplace_back(poly2); mp.emplace_back(poly2);
CHECK( mapnik::geometry::is_valid(mp) ); CHECK( mapnik::geometry::is_valid(mp) );
@ -427,34 +428,34 @@ SECTION("multi polygon with hole") {
mapnik::geometry::multi_polygon<double> mp; mapnik::geometry::multi_polygon<double> mp;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0,0); ring.emplace_back(0,0);
ring.add_coord(3,0); ring.emplace_back(3,0);
ring.add_coord(3,3); ring.emplace_back(3,3);
ring.add_coord(0,3); ring.emplace_back(0,3);
ring.add_coord(0,0); ring.emplace_back(0,0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(1,1); hole.emplace_back(1,1);
hole.add_coord(1,2); hole.emplace_back(1,2);
hole.add_coord(2,2); hole.emplace_back(2,2);
hole.add_coord(2,1); hole.emplace_back(2,1);
hole.add_coord(1,1); hole.emplace_back(1,1);
poly.add_hole(std::move(hole)); poly.push_back(std::move(hole));
mapnik::geometry::polygon<double> poly2; mapnik::geometry::polygon<double> poly2;
mapnik::geometry::linear_ring<double> ring2; mapnik::geometry::linear_ring<double> ring2;
ring2.add_coord(0,0); ring2.emplace_back(0,0);
ring2.add_coord(-3,0); ring2.emplace_back(-3,0);
ring2.add_coord(-3,-3); ring2.emplace_back(-3,-3);
ring2.add_coord(0,-3); ring2.emplace_back(0,-3);
ring2.add_coord(0,0); ring2.emplace_back(0,0);
poly2.set_exterior_ring(std::move(ring2)); poly2.push_back(std::move(ring2));
mapnik::geometry::linear_ring<double> hole2; mapnik::geometry::linear_ring<double> hole2;
hole2.add_coord(-1,-1); hole2.emplace_back(-1,-1);
hole2.add_coord(-1,-2); hole2.emplace_back(-1,-2);
hole2.add_coord(-2,-2); hole2.emplace_back(-2,-2);
hole2.add_coord(-2,-1); hole2.emplace_back(-2,-1);
hole2.add_coord(-1,-1); hole2.emplace_back(-1,-1);
poly2.add_hole(std::move(hole2)); poly2.push_back(std::move(hole2));
mp.emplace_back(poly); mp.emplace_back(poly);
mp.emplace_back(poly2); mp.emplace_back(poly2);
CHECK( mapnik::geometry::is_valid(mp) ); CHECK( mapnik::geometry::is_valid(mp) );

View file

@ -321,43 +321,49 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") {
mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans1(source, dest);
mapnik::proj_transform proj_trans2(dest, source); mapnik::proj_transform proj_trans2(dest, source);
polygon<double> geom1; polygon<double> geom1;
geom1.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); // exterior
geom1.exterior_ring.emplace_back(point<double>(-97.79067993164062, 35.43941441533686)); geom1.emplace_back();
geom1.exterior_ring.emplace_back(point<double>(-97.60391235351562, 35.34425514918409)); geom1.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1.exterior_ring.emplace_back(point<double>(-97.42813110351562, 35.48191987272801)); geom1.back().emplace_back(point<double>(-97.79067993164062, 35.43941441533686));
geom1.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); geom1.back().emplace_back(point<double>(-97.60391235351562, 35.34425514918409));
geom1.interior_rings.emplace_back(); geom1.back().emplace_back(point<double>(-97.42813110351562, 35.48191987272801));
geom1.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1.interior_rings.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813)); // interior
geom1.interior_rings.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606)); geom1.emplace_back();
geom1.interior_rings.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711)); geom1.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geom1.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813));
geom1.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606));
geom1.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711));
geom1.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
polygon<double> geom2; polygon<double> geom2;
geom2.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); // interior
geom2.exterior_ring.emplace_back(point<double>(-10886008.694318, 4223757.308982)); geom2.emplace_back();
geom2.exterior_ring.emplace_back(point<double>(-10865217.822625, 4210763.014174)); geom2.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2.exterior_ring.emplace_back(point<double>(-10845649.943384, 4229566.523132)); geom2.back().emplace_back(point<double>(-10886008.694318, 4223757.308982));
geom2.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); geom2.back().emplace_back(point<double>(-10865217.822625, 4210763.014174));
geom2.interior_rings.emplace_back(); geom2.back().emplace_back(point<double>(-10845649.943384, 4229566.523132));
geom2.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2.interior_rings.back().emplace_back(point<double>(-10866440.815077, 4237668.848130)); // exterior
geom2.interior_rings.back().emplace_back(point<double>(-10857879.867909, 4226509.042001)); geom2.emplace_back();
geom2.interior_rings.back().emplace_back(point<double>(-10867510.933473, 4221922.820303)); geom2.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geom2.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2.back().emplace_back(point<double>(-10866440.815077, 4237668.848130));
geom2.back().emplace_back(point<double>(-10857879.867909, 4226509.042001));
geom2.back().emplace_back(point<double>(-10867510.933473, 4221922.820303));
geom2.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
unsigned int err = 0; unsigned int err = 0;
{ {
// Test Standard Transform // Test Standard Transform
// Add extra vector to outer ring. // Add extra vector to outer ring.
geom1.interior_rings.emplace_back(); geom1.emplace_back();
REQUIRE(geom1.interior_rings.size() == 2); REQUIRE(geom1.size() == 3);
polygon<double> new_geom = reproject_copy(geom1, proj_trans1, err); polygon<double> new_geom = reproject_copy(geom1, proj_trans1, err);
REQUIRE(err == 0); REQUIRE(err == 0);
// Should remove the empty ring added to back of geom1 // Should remove the empty ring added to back of geom1
REQUIRE(new_geom.interior_rings.size() == 1); REQUIRE(new_geom.size() == 2);
assert_g_equal(new_geom, geom2); assert_g_equal(new_geom, geom2);
// Remove extra ring for future validity tests. // Remove extra ring for future validity tests.
geom1.interior_rings.pop_back(); geom1.pop_back();
REQUIRE(geom1.interior_rings.size() == 1); REQUIRE(geom1.size() == 2);
} }
{ {
// Transform in reverse // Transform in reverse
@ -380,13 +386,13 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Object") {
{ {
// Transform in place // Transform in place
polygon<double> geom3(geom1); polygon<double> geom3(geom1);
geom3.interior_rings.emplace_back(); geom3.emplace_back();
REQUIRE(reproject(geom3, proj_trans1)); REQUIRE(reproject(geom3, proj_trans1));
// Should NOT remove the empty ring added to back of geom1 // Should NOT remove the empty ring added to back of geom1
REQUIRE(geom3.interior_rings.size() == 2); REQUIRE(geom3.size() == 3);
// Remove so asserts that geometries are the same // Remove so asserts that geometries are the same
geom3.interior_rings.pop_back(); geom3.pop_back();
REQUIRE(geom3.interior_rings.size() == 1); REQUIRE(geom3.size() == 2);
assert_g_equal(geom3, geom2); assert_g_equal(geom3, geom2);
// Transform in place reverse // Transform in place reverse
REQUIRE(reproject(geom3, proj_trans2)); REQUIRE(reproject(geom3, proj_trans2));
@ -410,29 +416,36 @@ SECTION("test_projection_4326_3857 - Polygon Geometry Variant Object") {
mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans1(source, dest);
mapnik::proj_transform proj_trans2(dest, source); mapnik::proj_transform proj_trans2(dest, source);
polygon<double> geom1_; polygon<double> geom1_;
geom1_.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); // exterior
geom1_.exterior_ring.emplace_back(point<double>(-97.79067993164062, 35.43941441533686)); geom1_.emplace_back();
geom1_.exterior_ring.emplace_back(point<double>(-97.60391235351562, 35.34425514918409)); geom1_.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1_.exterior_ring.emplace_back(point<double>(-97.42813110351562, 35.48191987272801)); geom1_.back().emplace_back(point<double>(-97.79067993164062, 35.43941441533686));
geom1_.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); geom1_.back().emplace_back(point<double>(-97.60391235351562, 35.34425514918409));
geom1_.interior_rings.emplace_back(); geom1_.back().emplace_back(point<double>(-97.42813110351562, 35.48191987272801));
geom1_.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1_.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1_.interior_rings.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813)); // interior
geom1_.interior_rings.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606)); geom1_.emplace_back();
geom1_.interior_rings.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711)); geom1_.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geom1_.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1_.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813));
geom1_.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606));
geom1_.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711));
geom1_.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
polygon<double> geom2_; polygon<double> geom2_;
geom2_.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); // exterior
geom2_.exterior_ring.emplace_back(point<double>(-10886008.694318, 4223757.308982)); geom2_.emplace_back();
geom2_.exterior_ring.emplace_back(point<double>(-10865217.822625, 4210763.014174)); geom2_.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2_.exterior_ring.emplace_back(point<double>(-10845649.943384, 4229566.523132)); geom2_.back().emplace_back(point<double>(-10886008.694318, 4223757.308982));
geom2_.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); geom2_.back().emplace_back(point<double>(-10865217.822625, 4210763.014174));
geom2_.interior_rings.emplace_back(); geom2_.back().emplace_back(point<double>(-10845649.943384, 4229566.523132));
geom2_.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2_.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2_.interior_rings.back().emplace_back(point<double>(-10866440.815077, 4237668.848130)); // interior
geom2_.interior_rings.back().emplace_back(point<double>(-10857879.867909, 4226509.042001)); geom2_.emplace_back();
geom2_.interior_rings.back().emplace_back(point<double>(-10867510.933473, 4221922.820303)); geom2_.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geom2_.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2_.back().emplace_back(point<double>(-10866440.815077, 4237668.848130));
geom2_.back().emplace_back(point<double>(-10857879.867909, 4226509.042001));
geom2_.back().emplace_back(point<double>(-10867510.933473, 4221922.820303));
geom2_.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
polygon<double> geom0_; polygon<double> geom0_;
geometry<double> geom0(geom0_); geometry<double> geom0(geom0_);
geometry<double> geom1(geom1_); geometry<double> geom1(geom1_);
@ -791,31 +804,37 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Object") {
mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans1(source, dest);
mapnik::proj_transform proj_trans2(dest, source); mapnik::proj_transform proj_trans2(dest, source);
polygon<double> geom1a; polygon<double> geom1a;
geom1a.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); // exterior
geom1a.exterior_ring.emplace_back(point<double>(-97.79067993164062, 35.43941441533686)); geom1a.emplace_back();
geom1a.exterior_ring.emplace_back(point<double>(-97.60391235351562, 35.34425514918409)); geom1a.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a.exterior_ring.emplace_back(point<double>(-97.42813110351562, 35.48191987272801)); geom1a.back().emplace_back(point<double>(-97.79067993164062, 35.43941441533686));
geom1a.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); geom1a.back().emplace_back(point<double>(-97.60391235351562, 35.34425514918409));
geom1a.interior_rings.emplace_back(); geom1a.back().emplace_back(point<double>(-97.42813110351562, 35.48191987272801));
geom1a.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a.interior_rings.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813)); // interior
geom1a.interior_rings.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606)); geom1a.emplace_back();
geom1a.interior_rings.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711)); geom1a.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geom1a.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813));
geom1a.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606));
geom1a.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711));
geom1a.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
multi_polygon<double> geom1; multi_polygon<double> geom1;
geom1.emplace_back(geom1a); geom1.emplace_back(geom1a);
polygon<double> geom2a; polygon<double> geom2a;
geom2a.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); // exterior
geom2a.exterior_ring.emplace_back(point<double>(-10886008.694318, 4223757.308982)); geom2a.emplace_back();
geom2a.exterior_ring.emplace_back(point<double>(-10865217.822625, 4210763.014174)); geom2a.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a.exterior_ring.emplace_back(point<double>(-10845649.943384, 4229566.523132)); geom2a.back().emplace_back(point<double>(-10886008.694318, 4223757.308982));
geom2a.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); geom2a.back().emplace_back(point<double>(-10865217.822625, 4210763.014174));
geom2a.interior_rings.emplace_back(); geom2a.back().emplace_back(point<double>(-10845649.943384, 4229566.523132));
geom2a.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a.interior_rings.back().emplace_back(point<double>(-10866440.815077, 4237668.848130)); // interior
geom2a.interior_rings.back().emplace_back(point<double>(-10857879.867909, 4226509.042001)); geom2a.emplace_back();
geom2a.interior_rings.back().emplace_back(point<double>(-10867510.933473, 4221922.820303)); geom2a.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geom2a.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a.back().emplace_back(point<double>(-10866440.815077, 4237668.848130));
geom2a.back().emplace_back(point<double>(-10857879.867909, 4226509.042001));
geom2a.back().emplace_back(point<double>(-10867510.933473, 4221922.820303));
geom2a.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
multi_polygon<double> geom2; multi_polygon<double> geom2;
geom2.emplace_back(geom2a); geom2.emplace_back(geom2a);
unsigned int err = 0; unsigned int err = 0;
@ -884,31 +903,37 @@ SECTION("test_projection_4326_3857 - Multi_Polygon Geometry Variant Object") {
mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans1(source, dest);
mapnik::proj_transform proj_trans2(dest, source); mapnik::proj_transform proj_trans2(dest, source);
polygon<double> geom1a_; polygon<double> geom1a_;
geom1a_.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); // exterior
geom1a_.exterior_ring.emplace_back(point<double>(-97.79067993164062, 35.43941441533686)); geom1a_.emplace_back();
geom1a_.exterior_ring.emplace_back(point<double>(-97.60391235351562, 35.34425514918409)); geom1a_.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a_.exterior_ring.emplace_back(point<double>(-97.42813110351562, 35.48191987272801)); geom1a_.back().emplace_back(point<double>(-97.79067993164062, 35.43941441533686));
geom1a_.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); geom1a_.back().emplace_back(point<double>(-97.60391235351562, 35.34425514918409));
geom1a_.interior_rings.emplace_back(); geom1a_.back().emplace_back(point<double>(-97.42813110351562, 35.48191987272801));
geom1a_.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a_.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a_.interior_rings.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813)); // interior
geom1a_.interior_rings.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606)); geom1a_.emplace_back();
geom1a_.interior_rings.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711)); geom1a_.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geom1a_.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a_.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813));
geom1a_.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606));
geom1a_.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711));
geom1a_.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
multi_polygon<double> geom1_; multi_polygon<double> geom1_;
geom1_.emplace_back(geom1a_); geom1_.emplace_back(geom1a_);
polygon<double> geom2a_; polygon<double> geom2a_;
geom2a_.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); // exterior
geom2a_.exterior_ring.emplace_back(point<double>(-10886008.694318, 4223757.308982)); geom2a_.emplace_back();
geom2a_.exterior_ring.emplace_back(point<double>(-10865217.822625, 4210763.014174)); geom2a_.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a_.exterior_ring.emplace_back(point<double>(-10845649.943384, 4229566.523132)); geom2a_.back().emplace_back(point<double>(-10886008.694318, 4223757.308982));
geom2a_.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); geom2a_.back().emplace_back(point<double>(-10865217.822625, 4210763.014174));
geom2a_.interior_rings.emplace_back(); geom2a_.back().emplace_back(point<double>(-10845649.943384, 4229566.523132));
geom2a_.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a_.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a_.interior_rings.back().emplace_back(point<double>(-10866440.815077, 4237668.848130)); // interior
geom2a_.interior_rings.back().emplace_back(point<double>(-10857879.867909, 4226509.042001)); geom2a_.emplace_back();
geom2a_.interior_rings.back().emplace_back(point<double>(-10867510.933473, 4221922.820303)); geom2a_.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geom2a_.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a_.back().emplace_back(point<double>(-10866440.815077, 4237668.848130));
geom2a_.back().emplace_back(point<double>(-10857879.867909, 4226509.042001));
geom2a_.back().emplace_back(point<double>(-10867510.933473, 4221922.820303));
geom2a_.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
multi_polygon<double> geom2_; multi_polygon<double> geom2_;
geom2_.emplace_back(geom2a_); geom2_.emplace_back(geom2a_);
multi_polygon<double> geom0_; multi_polygon<double> geom0_;
@ -973,31 +998,37 @@ SECTION("test_projection_4326_3857 - Geometry Collection Object") {
mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans1(source, dest);
mapnik::proj_transform proj_trans2(dest, source); mapnik::proj_transform proj_trans2(dest, source);
polygon<double> geom1a; polygon<double> geom1a;
geom1a.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); // exterior
geom1a.exterior_ring.emplace_back(point<double>(-97.79067993164062, 35.43941441533686)); geom1a.emplace_back();
geom1a.exterior_ring.emplace_back(point<double>(-97.60391235351562, 35.34425514918409)); geom1a.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a.exterior_ring.emplace_back(point<double>(-97.42813110351562, 35.48191987272801)); geom1a.back().emplace_back(point<double>(-97.79067993164062, 35.43941441533686));
geom1a.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); geom1a.back().emplace_back(point<double>(-97.60391235351562, 35.34425514918409));
geom1a.interior_rings.emplace_back(); geom1a.back().emplace_back(point<double>(-97.42813110351562, 35.48191987272801));
geom1a.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a.interior_rings.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813)); // interior
geom1a.interior_rings.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606)); geom1a.emplace_back();
geom1a.interior_rings.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711)); geom1a.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geom1a.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813));
geom1a.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606));
geom1a.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711));
geom1a.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geometry_collection<double> geom1; geometry_collection<double> geom1;
geom1.emplace_back(geometry<double>(geom1a)); geom1.emplace_back(geometry<double>(geom1a));
polygon<double> geom2a; polygon<double> geom2a;
geom2a.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); // exerior
geom2a.exterior_ring.emplace_back(point<double>(-10886008.694318, 4223757.308982)); geom2a.emplace_back();
geom2a.exterior_ring.emplace_back(point<double>(-10865217.822625, 4210763.014174)); geom2a.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a.exterior_ring.emplace_back(point<double>(-10845649.943384, 4229566.523132)); geom2a.back().emplace_back(point<double>(-10886008.694318, 4223757.308982));
geom2a.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); geom2a.back().emplace_back(point<double>(-10865217.822625, 4210763.014174));
geom2a.interior_rings.emplace_back(); geom2a.back().emplace_back(point<double>(-10845649.943384, 4229566.523132));
geom2a.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a.interior_rings.back().emplace_back(point<double>(-10866440.815077, 4237668.848130)); // interior
geom2a.interior_rings.back().emplace_back(point<double>(-10857879.867909, 4226509.042001)); geom2a.emplace_back();
geom2a.interior_rings.back().emplace_back(point<double>(-10867510.933473, 4221922.820303)); geom2a.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geom2a.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a.back().emplace_back(point<double>(-10866440.815077, 4237668.848130));
geom2a.back().emplace_back(point<double>(-10857879.867909, 4226509.042001));
geom2a.back().emplace_back(point<double>(-10867510.933473, 4221922.820303));
geom2a.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geometry_collection<double> geom2; geometry_collection<double> geom2;
geom2.emplace_back(geometry<double>(geom2a)); geom2.emplace_back(geometry<double>(geom2a));
unsigned int err = 0; unsigned int err = 0;
@ -1066,31 +1097,37 @@ SECTION("test_projection_4326_3857 - Geometry Collection Variant Object") {
mapnik::proj_transform proj_trans1(source, dest); mapnik::proj_transform proj_trans1(source, dest);
mapnik::proj_transform proj_trans2(dest, source); mapnik::proj_transform proj_trans2(dest, source);
polygon<double> geom1a_; polygon<double> geom1a_;
geom1a_.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); // exterior
geom1a_.exterior_ring.emplace_back(point<double>(-97.79067993164062, 35.43941441533686)); geom1a_.emplace_back();
geom1a_.exterior_ring.emplace_back(point<double>(-97.60391235351562, 35.34425514918409)); geom1a_.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a_.exterior_ring.emplace_back(point<double>(-97.42813110351562, 35.48191987272801)); geom1a_.back().emplace_back(point<double>(-97.79067993164062, 35.43941441533686));
geom1a_.exterior_ring.emplace_back(point<double>(-97.62588500976562, 35.62939577711732)); geom1a_.back().emplace_back(point<double>(-97.60391235351562, 35.34425514918409));
geom1a_.interior_rings.emplace_back(); geom1a_.back().emplace_back(point<double>(-97.42813110351562, 35.48191987272801));
geom1a_.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a_.back().emplace_back(point<double>(-97.62588500976562, 35.62939577711732));
geom1a_.interior_rings.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813)); // interior
geom1a_.interior_rings.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606)); geom1a_.emplace_back();
geom1a_.interior_rings.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711)); geom1a_.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geom1a_.interior_rings.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069)); geom1a_.back().emplace_back(point<double>(-97.61489868164062, 35.54116627999813));
geom1a_.back().emplace_back(point<double>(-97.53799438476562, 35.459551379037606));
geom1a_.back().emplace_back(point<double>(-97.62451171875, 35.42598697382711));
geom1a_.back().emplace_back(point<double>(-97.66571044921875, 35.46849952318069));
geometry_collection<double> geom1_; geometry_collection<double> geom1_;
geom1_.emplace_back(geometry<double>(geom1a_)); geom1_.emplace_back(geometry<double>(geom1a_));
polygon<double> geom2a_; polygon<double> geom2a_;
geom2a_.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); // exterior
geom2a_.exterior_ring.emplace_back(point<double>(-10886008.694318, 4223757.308982)); geom2a_.emplace_back();
geom2a_.exterior_ring.emplace_back(point<double>(-10865217.822625, 4210763.014174)); geom2a_.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a_.exterior_ring.emplace_back(point<double>(-10845649.943384, 4229566.523132)); geom2a_.back().emplace_back(point<double>(-10886008.694318, 4223757.308982));
geom2a_.exterior_ring.emplace_back(point<double>(-10867663.807530, 4249745.898599)); geom2a_.back().emplace_back(point<double>(-10865217.822625, 4210763.014174));
geom2a_.interior_rings.emplace_back(); geom2a_.back().emplace_back(point<double>(-10845649.943384, 4229566.523132));
geom2a_.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a_.back().emplace_back(point<double>(-10867663.807530, 4249745.898599));
geom2a_.interior_rings.back().emplace_back(point<double>(-10866440.815077, 4237668.848130)); // interior
geom2a_.interior_rings.back().emplace_back(point<double>(-10857879.867909, 4226509.042001)); geom2a_.emplace_back();
geom2a_.interior_rings.back().emplace_back(point<double>(-10867510.933473, 4221922.820303)); geom2a_.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geom2a_.interior_rings.back().emplace_back(point<double>(-10872097.155170, 4227732.034453)); geom2a_.back().emplace_back(point<double>(-10866440.815077, 4237668.848130));
geom2a_.back().emplace_back(point<double>(-10857879.867909, 4226509.042001));
geom2a_.back().emplace_back(point<double>(-10867510.933473, 4221922.820303));
geom2a_.back().emplace_back(point<double>(-10872097.155170, 4227732.034453));
geometry_collection<double> geom2_; geometry_collection<double> geom2_;
geom2_.emplace_back(geometry<double>(geom2a_)); geom2_.emplace_back(geometry<double>(geom2a_));
multi_polygon<double> geom0_; multi_polygon<double> geom0_;

View file

@ -10,8 +10,8 @@
#include <mapnik/proj_strategy.hpp> #include <mapnik/proj_strategy.hpp>
#include <mapnik/view_strategy.hpp> #include <mapnik/view_strategy.hpp>
TEST_CASE("geometry strategy tests") {
TEST_CASE("geometry strategy tests") {
SECTION("proj and view strategy") { SECTION("proj and view strategy") {
using namespace mapnik::geometry; using namespace mapnik::geometry;
mapnik::box2d<double> e(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789); mapnik::box2d<double> e(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789);
@ -183,5 +183,4 @@ SECTION("scaling strategies - double to int64") {
assert_g_equal(r, o); assert_g_equal(r, o);
} }
} // END SECTION } // END SECTION
} // END TEST CASE } // END TEST CASE

View file

@ -1,150 +0,0 @@
#include "catch.hpp"
#include <mapnik/geometry/is_empty.hpp>
TEST_CASE("geometry has_empty") {
SECTION("empty geometry") {
mapnik::geometry::geometry_empty geom;
REQUIRE(!mapnik::geometry::has_empty(geom));
}
SECTION("geometry collection") {
{
mapnik::geometry::geometry_collection<double> geom;
REQUIRE(!mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::geometry_collection<double> geom;
mapnik::geometry::geometry_empty geom1;
geom.emplace_back(std::move(geom1));
REQUIRE(mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::geometry_collection<double> geom;
mapnik::geometry::multi_line_string<double> mls;
mapnik::geometry::line_string<double> line;
mls.emplace_back(std::move(line));
geom.emplace_back(std::move(mls));
REQUIRE(mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::geometry_collection<double> geom;
mapnik::geometry::multi_line_string<double> mls;
mapnik::geometry::line_string<double> line;
line.add_coord(0, 0);
mls.emplace_back(std::move(line));
geom.emplace_back(std::move(mls));
REQUIRE(!mapnik::geometry::has_empty(geom));
}
}
SECTION("point") {
mapnik::geometry::point<double> pt(10, 10);
REQUIRE(!mapnik::geometry::has_empty(pt));
}
SECTION("linestring") {
{
mapnik::geometry::line_string<double> line;
REQUIRE(!mapnik::geometry::has_empty(line));
}
{
mapnik::geometry::line_string<double> line;
line.add_coord(0, 0);
line.add_coord(25, 25);
line.add_coord(50, 50);
REQUIRE(!mapnik::geometry::has_empty(line));
}
}
SECTION("polygon") {
{
mapnik::geometry::polygon<double> poly;
REQUIRE(!mapnik::geometry::has_empty(poly));
}
{
mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring));
REQUIRE(!mapnik::geometry::has_empty(poly));
}
{
mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0);
ring.add_coord(1, 0);
ring.add_coord(1, 1);
ring.add_coord(0, 1);
ring.add_coord(0, 0);
poly.set_exterior_ring(std::move(ring));
REQUIRE(!mapnik::geometry::has_empty(poly));
}
}
SECTION("multi-point") {
{
mapnik::geometry::multi_point<double> geom;
REQUIRE(!mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::multi_point<double> geom;
geom.add_coord(0, 0);
geom.add_coord(25, 25);
geom.add_coord(50, 50);
REQUIRE(!mapnik::geometry::has_empty(geom));
}
}
SECTION("multi-linestring") {
{
mapnik::geometry::multi_line_string<double> geom;
REQUIRE(!mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::multi_line_string<double> geom;
mapnik::geometry::line_string<double> line;
geom.emplace_back(std::move(line));
REQUIRE(mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::multi_line_string<double> geom;
mapnik::geometry::line_string<double> line;
line.add_coord(0, 0);
geom.emplace_back(std::move(line));
REQUIRE(!mapnik::geometry::has_empty(geom));
}
}
SECTION("multi-polygon") {
{
mapnik::geometry::multi_polygon<double> geom;
REQUIRE(!mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::multi_polygon<double> geom;
mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring));
geom.emplace_back(std::move(poly));
REQUIRE(mapnik::geometry::has_empty(geom));
}
{
mapnik::geometry::multi_polygon<double> geom;
mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0);
poly.set_exterior_ring(std::move(ring));
geom.emplace_back(std::move(poly));
REQUIRE(!mapnik::geometry::has_empty(geom));
}
}
}

View file

@ -38,9 +38,9 @@ SECTION("linestring") {
} }
{ {
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0, 0); line.emplace_back(0, 0);
line.add_coord(25, 25); line.emplace_back(25, 25);
line.add_coord(50, 50); line.emplace_back(50, 50);
REQUIRE(!mapnik::geometry::is_empty(line)); REQUIRE(!mapnik::geometry::is_empty(line));
} }
} }
@ -54,18 +54,18 @@ SECTION("polygon") {
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
REQUIRE(mapnik::geometry::is_empty(poly)); REQUIRE(mapnik::geometry::is_empty(poly));
} }
{ {
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0); ring.emplace_back(0, 0);
ring.add_coord(1, 0); ring.emplace_back(1, 0);
ring.add_coord(1, 1); ring.emplace_back(1, 1);
ring.add_coord(0, 1); ring.emplace_back(0, 1);
ring.add_coord(0, 0); ring.emplace_back(0, 0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
REQUIRE(!mapnik::geometry::is_empty(poly)); REQUIRE(!mapnik::geometry::is_empty(poly));
} }
} }
@ -78,9 +78,9 @@ SECTION("multi-point") {
} }
{ {
mapnik::geometry::multi_point<double> geom; mapnik::geometry::multi_point<double> geom;
geom.add_coord(0, 0); geom.emplace_back(0, 0);
geom.add_coord(25, 25); geom.emplace_back(25, 25);
geom.add_coord(50, 50); geom.emplace_back(50, 50);
REQUIRE(!mapnik::geometry::is_empty(geom)); REQUIRE(!mapnik::geometry::is_empty(geom));
} }
} }
@ -109,7 +109,7 @@ SECTION("multi-polygon") {
mapnik::geometry::multi_polygon<double> geom; mapnik::geometry::multi_polygon<double> geom;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geom.emplace_back(std::move(poly)); geom.emplace_back(std::move(poly));
REQUIRE(!mapnik::geometry::is_empty(geom)); REQUIRE(!mapnik::geometry::is_empty(geom));
} }

View file

@ -18,9 +18,9 @@ SECTION("multi-linestring") {
using geom_type = mapnik::geometry::multi_line_string<double>; using geom_type = mapnik::geometry::multi_line_string<double>;
geom_type geom; geom_type geom;
mapnik::geometry::line_string<double> line; mapnik::geometry::line_string<double> line;
line.add_coord(0, 0); line.emplace_back(0, 0);
line.add_coord(0, 25); line.emplace_back(0, 25);
line.add_coord(0, 50); line.emplace_back(0, 50);
geom.emplace_back(std::move(line)); geom.emplace_back(std::move(line));
geom.emplace_back(); geom.emplace_back();
@ -36,18 +36,18 @@ SECTION("multi-polygon") {
geom_type geom; geom_type geom;
mapnik::geometry::polygon<double> poly; mapnik::geometry::polygon<double> poly;
mapnik::geometry::linear_ring<double> ring; mapnik::geometry::linear_ring<double> ring;
ring.add_coord(0, 0); ring.emplace_back(0, 0);
ring.add_coord(1, 0); ring.emplace_back(1, 0);
ring.add_coord(1, 1); ring.emplace_back(1, 1);
ring.add_coord(0, 1); ring.emplace_back(0, 1);
ring.add_coord(0, 0); ring.emplace_back(0, 0);
poly.set_exterior_ring(std::move(ring)); poly.push_back(std::move(ring));
geom.emplace_back(std::move(poly)); geom.emplace_back(std::move(poly));
geom.emplace_back(); geom.emplace_back();
//geom.back().emplace_back(); //add an empty exterior ring
REQUIRE(geom.size() == 2); REQUIRE(geom.size() == 2);
geom_type geom2 = mapnik::geometry::remove_empty(geom); geom_type geom2 = mapnik::geometry::remove_empty(geom);
REQUIRE(geom2.size() == 1); REQUIRE(geom2.size() == 1);
REQUIRE(geom2[0].exterior_ring.size() == 5); REQUIRE(geom2.front().front().size() == 5);
} }
} }

View file

@ -7,10 +7,11 @@ TEST_CASE("vertex_adapters") {
SECTION("polygon") { SECTION("polygon") {
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.exterior_ring.add_coord(1,1); g.emplace_back();
g.exterior_ring.add_coord(2,2); g.back().emplace_back(1,1);
g.exterior_ring.add_coord(100,100); g.back().emplace_back(2,2);
g.exterior_ring.add_coord(1,1); g.back().emplace_back(100,100);
g.back().emplace_back(1,1);
mapnik::geometry::polygon_vertex_adapter<double> va(g); mapnik::geometry::polygon_vertex_adapter<double> va(g);
double x,y; double x,y;
@ -46,27 +47,28 @@ SECTION("polygon") {
SECTION("polygon with hole") { SECTION("polygon with hole") {
mapnik::geometry::polygon<double> g; mapnik::geometry::polygon<double> g;
g.exterior_ring.add_coord(0,0); g.emplace_back();
g.exterior_ring.add_coord(-10,0); g.back().emplace_back(0,0);
g.exterior_ring.add_coord(-10,10); g.back().emplace_back(-10,0);
g.exterior_ring.add_coord(0,10); g.back().emplace_back(-10,10);
g.exterior_ring.add_coord(0,0); g.back().emplace_back(0,10);
g.back().emplace_back(0,0);
std::vector<mapnik::geometry::linear_ring<double> > interior_rings; std::vector<mapnik::geometry::linear_ring<double> > interior_rings;
mapnik::geometry::linear_ring<double> hole; mapnik::geometry::linear_ring<double> hole;
hole.add_coord(-7,7); hole.emplace_back(-7,7);
hole.add_coord(-7,3); hole.emplace_back(-7,3);
hole.add_coord(-3,3); hole.emplace_back(-3,3);
hole.add_coord(-3,7); hole.emplace_back(-3,7);
hole.add_coord(-7,7); hole.emplace_back(-7,7);
g.add_hole(std::move(hole)); g.push_back(std::move(hole));
mapnik::geometry::linear_ring<double> hole_in_hole; mapnik::geometry::linear_ring<double> hole_in_hole;
hole_in_hole.add_coord(-6,4); hole_in_hole.emplace_back(-6,4);
hole_in_hole.add_coord(-6,6); hole_in_hole.emplace_back(-6,6);
hole_in_hole.add_coord(-4,6); hole_in_hole.emplace_back(-4,6);
hole_in_hole.add_coord(-4,4); hole_in_hole.emplace_back(-4,4);
hole_in_hole.add_coord(-6,4); hole_in_hole.emplace_back(-6,4);
g.add_hole(std::move(hole_in_hole)); g.push_back(std::move(hole_in_hole));
mapnik::geometry::polygon_vertex_adapter<double> va(g); mapnik::geometry::polygon_vertex_adapter<double> va(g);
double x,y; double x,y;
@ -99,7 +101,7 @@ SECTION("polygon with hole") {
REQUIRE( y == 0 ); REQUIRE( y == 0 );
// exterior ring via ring_vertex_adapter // exterior ring via ring_vertex_adapter
mapnik::geometry::ring_vertex_adapter<double> va2(g.exterior_ring); mapnik::geometry::ring_vertex_adapter<double> va2(g.front());
cmd = va2.vertex(&x,&y); cmd = va2.vertex(&x,&y);
REQUIRE( cmd == mapnik::SEG_MOVETO ); REQUIRE( cmd == mapnik::SEG_MOVETO );
REQUIRE( x == 0 ); REQUIRE( x == 0 );