implementation and unit test for bg::append for multi-linestring and multi-polygon

This commit is contained in:
Menelaos Karavelas 2014-03-14 23:04:01 +02:00
parent 1234e21c53
commit 429b5e0037
3 changed files with 161 additions and 29 deletions

View File

@ -105,7 +105,7 @@ struct range_to_polygon
typedef typename ring_type<Polygon>::type ring_type;
static inline void apply(Polygon& polygon, Range const& range,
int ring_index, int )
int ring_index, int = 0)
{
if (ring_index == -1)
{

View File

@ -1,8 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -23,6 +28,34 @@
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace append
{
template <typename MultiGeometry, typename RangeOrPoint>
struct append_to_multigeometry
{
static inline void apply(MultiGeometry& multigeometry,
RangeOrPoint const& range_or_point,
int ring_index, int multi_index)
{
dispatch::append
<
typename boost::range_value<MultiGeometry>::type,
RangeOrPoint
>::apply(multigeometry[multi_index], range_or_point, ring_index);
}
};
}} // namespace detail::append
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@ -40,6 +73,26 @@ struct append_range<multi_point_tag, Geometry, Range>
: detail::append::append_range<Geometry, Range>
{};
template <typename MultiGeometry, typename RangeOrPoint>
struct append_point<multi_linestring_tag, MultiGeometry, RangeOrPoint>
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
{};
template <typename MultiGeometry, typename RangeOrPoint>
struct append_range<multi_linestring_tag, MultiGeometry, RangeOrPoint>
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
{};
template <typename MultiGeometry, typename RangeOrPoint>
struct append_point<multi_polygon_tag, MultiGeometry, RangeOrPoint>
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
{};
template <typename MultiGeometry, typename RangeOrPoint>
struct append_range<multi_polygon_tag, MultiGeometry, RangeOrPoint>
: detail::append::append_to_multigeometry<MultiGeometry, RangeOrPoint>
{};
}

View File

@ -1,9 +1,14 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@ -30,51 +35,116 @@
#include <test_common/test_point.hpp>
#include <test_geometries/wrapped_boost_array.hpp>
// includes for multi-geometries
#include <boost/geometry/multi/core/point_type.hpp>
#include <boost/geometry/multi/core/tags.hpp>
#include <boost/geometry/multi/geometries/concepts/check.hpp>
#include <boost/geometry/multi/geometries/multi_geometries.hpp>
#include <boost/geometry/multi/algorithms/append.hpp>
#include <boost/geometry/multi/algorithms/clear.hpp>
#include <boost/geometry/multi/algorithms/num_points.hpp>
BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::vector)
BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(std::deque)
template <typename G>
void test_geometry(G& geometry, bool check)
template <bool EnableAll>
struct do_checks
{
typedef typename bg::point_type<G>::type P;
bg::append(geometry, bg::make_zero<P>());
if (check)
template <typename G>
static inline void apply(G const& geometry,
std::size_t size1,
std::size_t = 0,
std::size_t = 0)
{
BOOST_CHECK_EQUAL(bg::num_points(geometry), 1u);
BOOST_CHECK_EQUAL(bg::num_points(geometry), size1);
}
};
// Append a range
std::vector<P> v;
v.push_back(bg::make_zero<P>());
v.push_back(bg::make_zero<P>());
bg::append(geometry, v);
if (check)
template<>
struct do_checks<true>
{
template <typename G>
static inline void apply(G const& geometry,
std::size_t size1,
std::size_t size2 = 0,
std::size_t size3 = 0)
{
BOOST_CHECK_EQUAL(bg::num_points(geometry), 3u);
do_checks<false>::apply(geometry, size1);
BOOST_CHECK_EQUAL(bg::num_points(geometry[0]), size2);
BOOST_CHECK_EQUAL(bg::num_points(geometry[1]), size3);
}
};
bg::clear(geometry);
if (check)
template <bool HasMultiIndex, bool IsVariant>
struct test_geometry
{
template <typename G>
static inline void apply(G& geometry, bool check)
{
BOOST_CHECK_EQUAL(bg::num_points(geometry), 0u);
}
typedef typename bg::point_type<G>::type P;
typedef do_checks<HasMultiIndex && !IsVariant> checks;
bg::append(geometry, bg::make_zero<P>(), -1, 0);
if (check)
{
checks::apply(geometry, 1u, 1u, 0u);
}
// Append a range
std::vector<P> v;
v.push_back(bg::make_zero<P>());
v.push_back(bg::make_zero<P>());
bg::append(geometry, v, -1, 1);
if (check)
{
checks::apply(geometry, 3u, 1u, 2u);
}
bg::clear(geometry);
if (check)
{
do_checks<false>::apply(geometry, 0u);
// BOOST_CHECK_EQUAL(bg::num_points(geometry), 0u);
}
//P p = boost::range::front(geometry);
}
};
//P p = boost::range::front(geometry);
}
template <typename G>
void test_geometry_and_variant(bool check = true)
{
G geometry;
boost::variant<G> variant_geometry = G();
test_geometry(geometry, check);
test_geometry(variant_geometry, check);
test_geometry<false, false>::apply(geometry, check);
test_geometry<false, true>::apply(variant_geometry, check);
}
template <typename MG>
void test_multigeometry_and_variant(bool check = true)
{
typedef typename boost::range_value<MG>::type G;
G geometry;
MG multigeometry;
bg::traits::push_back<MG>::apply(multigeometry, geometry);
bg::traits::push_back<MG>::apply(multigeometry, geometry);
boost::variant<MG> variant_multigeometry = multigeometry;
test_geometry<true, false>::apply(multigeometry, check);
test_geometry<true, true>::apply(variant_multigeometry, check);
}
template <typename P>
void test_all()
{
@ -84,6 +154,15 @@ void test_all()
test_geometry_and_variant<bg::model::linestring<P> >();
test_geometry_and_variant<bg::model::ring<P> >();
test_geometry_and_variant<bg::model::polygon<P> >();
test_geometry_and_variant<bg::model::multi_point<P> >();
test_multigeometry_and_variant
<
bg::model::multi_linestring<bg::model::linestring<P> >
>();
test_multigeometry_and_variant
<
bg::model::multi_polygon<bg::model::polygon<P> >
>();
test_geometry_and_variant<std::vector<P> >();
test_geometry_and_variant<std::deque<P> >();