gnss-sim/3rdparty/boost/geometry/algorithms/detail/overlay/add_rings.hpp

187 lines
5.6 KiB
C++

// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017-2020.
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
#include <boost/throw_exception.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace overlay
{
template
<
typename GeometryOut,
typename Geometry1,
typename Geometry2,
typename RingCollection
>
inline void convert_and_add(GeometryOut& result,
Geometry1 const& geometry1, Geometry2 const& geometry2,
RingCollection const& collection,
ring_identifier id,
bool reversed, bool append)
{
typedef typename geometry::tag<Geometry1>::type tag1;
typedef typename geometry::tag<Geometry2>::type tag2;
typedef typename geometry::tag<GeometryOut>::type tag_out;
if (id.source_index == 0)
{
convert_ring<tag_out>::apply(result,
get_ring<tag1>::apply(id, geometry1),
append, reversed);
}
else if (id.source_index == 1)
{
convert_ring<tag_out>::apply(result,
get_ring<tag2>::apply(id, geometry2),
append, reversed);
}
else if (id.source_index == 2)
{
convert_ring<tag_out>::apply(result,
get_ring<void>::apply(id, collection),
append, reversed);
}
}
enum add_rings_error_handling
{
add_rings_ignore_unordered,
add_rings_add_unordered,
add_rings_throw_if_reversed
};
template
<
typename GeometryOut,
typename SelectionMap,
typename Geometry1,
typename Geometry2,
typename RingCollection,
typename OutputIterator,
typename Strategy
>
inline OutputIterator add_rings(SelectionMap const& map,
Geometry1 const& geometry1, Geometry2 const& geometry2,
RingCollection const& collection,
OutputIterator out,
Strategy const& strategy,
add_rings_error_handling error_handling = add_rings_ignore_unordered)
{
std::size_t const min_num_points = core_detail::closure::minimum_ring_size
<
geometry::closure
<
typename boost::range_value
<
RingCollection const
>::type
>::value
>::value;
for (auto const& pair : map)
{
if (! pair.second.discarded
&& pair.second.parent.source_index == -1)
{
GeometryOut result;
convert_and_add(result, geometry1, geometry2, collection,
pair.first, pair.second.reversed, false);
// Add children
for (auto const& child : pair.second.children)
{
auto mit = map.find(child);
if (mit != map.end() && ! mit->second.discarded)
{
convert_and_add(result, geometry1, geometry2, collection,
child, mit->second.reversed, true);
}
}
// Only add rings if they satisfy minimal requirements.
// This cannot be done earlier (during traversal), not
// everything is figured out yet (sum of positive/negative rings)
if (geometry::num_points(result) >= min_num_points)
{
typedef typename geometry::area_result<GeometryOut, Strategy>::type area_type;
area_type const area = geometry::area(result, strategy);
area_type const zero = 0;
// Ignore if area is 0
if (! math::equals(area, zero))
{
if (error_handling == add_rings_add_unordered
|| area > zero)
{
*out++ = result;
}
else if (error_handling == add_rings_throw_if_reversed)
{
BOOST_THROW_EXCEPTION(invalid_output_exception());
}
}
}
}
}
return out;
}
template
<
typename GeometryOut,
typename SelectionMap,
typename Geometry,
typename RingCollection,
typename OutputIterator,
typename Strategy
>
inline OutputIterator add_rings(SelectionMap const& map,
Geometry const& geometry,
RingCollection const& collection,
OutputIterator out,
Strategy const& strategy)
{
Geometry empty;
return add_rings<GeometryOut>(map, geometry, empty, collection, out, strategy);
}
}} // namespace detail::overlay
#endif // DOXYGEN_NO_DETAIL
}} // namespace geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP