Merge branch 'develop' into bg-prepare

# Conflicts:
#	extensions/test/Jamfile.v2
#	extensions/test/gis/io/wkb/read_wkb.cpp
#	extensions/test/gis/io/wkb/write_wkb.cpp
#	extensions/test/gis/latlong/cross_track.cpp
#	extensions/test/nsphere/nsphere-circle.cpp
#	include/boost/geometry/extensions/contrib/ttmath_stub.hpp
#	include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp
#	include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp
#	include/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp
#	test/arithmetic/cross_product.cpp
This commit is contained in:
barendgehrels
2017-02-26 21:24:37 +01:00
185 changed files with 8774 additions and 3129 deletions

View File

@@ -122,7 +122,7 @@ That's it! The methods of __boost_geometry__ can now be used directly on instanc
{ typedef point_tag type; };
template<> struct coordinate_type<QPoint>
{ typedef QPoint::double type; };
{ typedef double type; };
template<> struct coordinate_system<QPoint>
{ typedef cs::cartesian type; };

View File

@@ -1,9 +1,10 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
Copyright (c) 2009-2015 Bruno Lalande, Paris, France.
Copyright (c) 2009-2017 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
Copyright (c) 2009-2017 Bruno Lalande, Paris, France.
Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,8 +13,8 @@
[library Geometry
[quickbook 1.5]
[authors [Gehrels, Barend], [Lalande, Bruno], [Loskot, Mateusz], [Wulkiewicz, Adam], [Karavelas, Menelaos]]
[copyright 2009-2015 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its affiliates]
[authors [Gehrels, Barend], [Lalande, Bruno], [Loskot, Mateusz], [Wulkiewicz, Adam], [Karavelas, Menelaos], [Fisikopoulos, Vissarion]]
[copyright 2009-2017 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its affiliates]
[purpose Documentation of Boost.Geometry library]
[license
Distributed under the Boost Software License, Version 1.0.

View File

@@ -37,8 +37,12 @@
<div><div class="author"><h3 class="author">
<span class="firstname">Menelaos</span> <span class="surname">Karavelas</span>
</h3></div></div>
<div><p class="copyright">Copyright &#169; 2009-2014 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam
Wulkiewicz, Oracle and/or its affiliates</p></div>
<div><div class="author"><h3 class="author">
<span class="firstname">Vissarion</span> <span class="surname">Fisikopoulos</span>
</h3></div></div>
<div><p class="copyright">Copyright &#169; 2009-2017 Barend
Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its
affiliates</p></div>
<div><div class="legalnotice">
<a name="geometry.legal"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -72,6 +76,7 @@
<dt><span class="section"><a href="geometry/reference/constants.html">Constants</a></span></dt>
<dt><span class="section"><a href="geometry/reference/cs.html">Coordinate Systems</a></span></dt>
<dt><span class="section"><a href="geometry/reference/core.html">Core Metafunctions</a></span></dt>
<dt><span class="section"><a href="geometry/reference/de9im.html">DE-9IM</a></span></dt>
<dt><span class="section"><a href="geometry/reference/enumerations.html">Enumerations</a></span></dt>
<dt><span class="section"><a href="geometry/reference/exceptions.html">Exceptions</a></span></dt>
<dt><span class="section"><a href="geometry/reference/io.html">IO (input/output)</a></span></dt>
@@ -81,11 +86,9 @@
<dt><span class="section"><a href="geometry/reference/strategies.html">Strategies</a></span></dt>
<dt><span class="section"><a href="geometry/reference/views.html">Views</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="geometry/indexes.html">Indexes</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="geometry/indexes/matrix.html">Reference Matrix</a></span></dt>
<dt><span class="section"><a href="geometry/indexes/alphabetical_index.html">Alphabetical Index</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="geometry/matrix.html">Reference Matrix</a></span></dt>
<dt><span class="section"><a href="geometry/reference_alphabetical_index.html">Reference Alphabetical
Index</a></span></dt>
<dt><span class="section"><a href="geometry/examples.html">Examples</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="geometry/examples/example__adapting_a_legacy_geometry_object_model.html">Example:
@@ -124,6 +127,9 @@
<li class="listitem">
Mats Taraldsvik (documentation: adapting a legacy model)
</li>
<li class="listitem">
Matt Amos (fixes for point_on_surface)
</li>
<li class="listitem">
Samuel Debionne (variant support for distance, assign, crosses, intersection,
...)
@@ -131,7 +137,7 @@
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: July 17, 2014 at 20:45:09 GMT</small></p></td>
<td align="left"><p><small>Last revised: February 26, 2017 at 00:30:21 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@@ -135,7 +135,7 @@ strategies = ["distance::pythagoras", "distance::pythagoras_box_box"
, "side::side_by_triangle", "side::side_by_cross_track", "side::spherical_side_formula"
, "transform::inverse_transformer", "transform::map_transformer"
, "transform::rotate_transformer", "transform::scale_transformer"
, "transform::translate_transformer", "transform::ublas_transformer"
, "transform::translate_transformer", "transform::matrix_transformer"
]
views = ["box_view", "segment_view"

View File

@@ -521,7 +521,7 @@
<bridgehead renderas="sect3">Area</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="geometry.reference.strategies.strategy_area_surveyor">strategy::area::surveyor</link></member>
<member><link linkend="geometry.reference.strategies.strategy_area_huiller">strategy::area::huiller</link></member>
<!--member><link linkend="geometry.reference.strategies.strategy_area_huiller">strategy::area::huiller</link></member-->
</simplelist>
</entry>
<entry valign="top">
@@ -586,7 +586,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="geometry.reference.strategies.strategy_transform_inverse_transformer">strategy::transform::inverse_transformer</link></member>
<member><link linkend="geometry.reference.strategies.strategy_transform_map_transformer">strategy::transform::map_transformer</link></member>
<member><link linkend="geometry.reference.strategies.strategy_transform_ublas_transformer">strategy::transform::ublas_transformer</link></member>
<member><link linkend="geometry.reference.strategies.strategy_transform_matrix_transformer">strategy::transform::matrix_transformer</link></member>
<member><link linkend="geometry.reference.strategies.strategy_transform_translate_transformer">strategy::transform::translate_transformer</link></member>
<member><link linkend="geometry.reference.strategies.strategy_transform_scale_transformer">strategy::transform::scale_transformer</link></member>
<member><link linkend="geometry.reference.strategies.strategy_transform_rotate_transformer">strategy::transform::rotate_transformer</link></member>

View File

@@ -1,15 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2014 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
Copyright (c) 2009-2014 Bruno Lalande, Paris, France.
Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
Copyright (c) 2009-2017 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
Copyright (c) 2009-2017 Bruno Lalande, Paris, France.
Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
This file was modified by Oracle on 2014.
Modifications copyright (c) 2014, Oracle and/or its affiliates.
This file was modified by Oracle on 2014, 2017.
Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
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
@@ -94,10 +95,15 @@
[include generated/covered_by.qbk]
[endsect]
[section:crosses crosses]
[include generated/crosses.qbk]
[endsect]
[include generated/difference.qbk]
[section:disjoint disjoint]
[include generated/disjoint.qbk]
[endsect]
[section:distance distance]
[include generated/distance.qbk]
@@ -107,8 +113,13 @@
[include generated/envelope.qbk]
[endsect]
[section:equals equals]
[include generated/equals.qbk]
[endsect]
[section:expand expand]
[include generated/expand.qbk]
[endsect]
[section:for_each for_each]
[include generated/for_each.qbk]
@@ -143,16 +154,21 @@
[include generated/num_points.qbk]
[include generated/num_segments.qbk]
[section:overlaps overlaps]
[include generated/overlaps.qbk]
[endsect]
[section:perimeter perimeter]
[include generated/perimeter.qbk]
[endsect]
[section:relate relate]
[include generated/relate.qbk]
[endsect]
[section:relation relation]
[include generated/relation.qbk]
[endsect]
[include generated/reverse.qbk]
@@ -317,7 +333,7 @@
[include generated/distance_cross_track.qbk]
[include generated/distance_cross_track_point_box.qbk]
[include generated/area_surveyor.qbk]
[include generated/area_huiller.qbk]
[/include generated/area_huiller.qbk]
[include generated/buffer_join_round.qbk]
[include generated/buffer_join_miter.qbk]
[include generated/buffer_end_round.qbk]
@@ -339,7 +355,7 @@
[include generated/transform_rotate_transformer.qbk]
[include generated/transform_scale_transformer.qbk]
[include generated/transform_translate_transformer.qbk]
[include generated/transform_ublas_transformer.qbk]
[include generated/transform_matrix_transformer.qbk]
[include generated/within_winding.qbk]
[include generated/within_franklin.qbk]
[include generated/within_crossings_multiply.qbk]

View File

@@ -1,13 +1,13 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2016 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
Copyright (c) 2009-2016 Bruno Lalande, Paris, France.
Copyright (c) 2009-2016 Mateusz Loskot <mateusz@loskot.net>, London, UK.
Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland.
Copyright (c) 2009-2017 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
Copyright (c) 2009-2017 Bruno Lalande, Paris, France.
Copyright (c) 2009-2017 Mateusz Loskot <mateusz@loskot.net>, London, UK.
Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
This file was modified by Oracle on 2015, 2016.
Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
This file was modified by Oracle on 2015, 2017.
Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -18,6 +18,28 @@
[section:release_notes Release Notes]
[/=================]
[heading Boost 1.64]
[/=================]
[*Improvements]
* matrix transformation is now based on Boost.QVM instead of Boost.Ublas
[*Breaking changes]
* ublas_transformer is renamed to matrix_transformer
[*Solved issues]
* [@https://github.com/boostorg/geometry/issues/363 363] Missing includes in geometry/index/parameters.hpp
* [@https://github.com/boostorg/geometry/issues/364 364] within(Linear, Areal) compilation error when arguments use different point types
[*Solved tickets]
* [@https://svn.boost.org/trac/boost/ticket/12566 12566] Ambiguous template instantiation in equal_to<> when pair value contains raw pointer
* [@https://svn.boost.org/trac/boost/ticket/12861 12566] Segmentation fault in stdlibc++ (gcc 4.8.2) affecting rtree
[/=================]
[heading Boost 1.63]
[/=================]
@@ -44,8 +66,11 @@
* Rename namespace concept to concepts to avoid conflicts with the newest compilers
* New spherical intersection strategy used in relational and set operations for spherical and geographic Geometries (previously cartesian intersection strategy was used for all coordinate systems).
* [@https://svn.boost.org/trac/boost/ticket/12189 12189] Relational operations not compiling when point types of inputs are different
[*Solved tickets]
* [@https://svn.boost.org/trac/boost/ticket/12189 12189] Relational operations not compiling when point types of inputs are different (cartesian, affecting rtree)
* [@https://svn.boost.org/trac/boost/ticket/12287 12287] Invalid result of rtree.query() for contains() predicate
* [@https://svn.boost.org/trac/boost/ticket/12342 12342] Relational operations not compiling when point types of inputs are different (geographic, affecting rtree)
[/=================]
[heading Boost 1.61]

View File

@@ -144,9 +144,7 @@ int main()
// Compose matrix for the two transformation
// Create transformer attached to the transformation matrix
ublas_transformer<double, 2, 2>
combined(boost::numeric::ublas::prod(rotate.matrix(), translate.matrix()));
//combined(rotate.matrix());
matrix_transformer<double, 2, 2> combined(rotate.matrix() * translate.matrix());
// Apply transformation to subject geometry point-by-point
model::polygon<point_2d> g4;

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -274,6 +278,11 @@ inline void buffer(GeometryIn const& geometry_in,
geometry::envelope(geometry_in, box);
geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
typename strategy::intersection::services::default_strategy
<
typename cs_tag<GeometryIn>::type
>::type intersection_strategy;
rescale_policy_type rescale_policy
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
@@ -283,6 +292,7 @@ inline void buffer(GeometryIn const& geometry_in,
join_strategy,
end_strategy,
point_strategy,
intersection_strategy,
rescale_policy);
}

View File

@@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2013, 2014.
// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -14,8 +16,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
@@ -51,9 +51,13 @@ struct use_point_in_geometry
struct use_relate
{
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/)
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
return Strategy::apply(geometry1, geometry2);
typedef typename detail::de9im::static_mask_covered_by_type
<
Geometry1, Geometry2
>::type covered_by_mask;
return geometry::relate(geometry1, geometry2, covered_by_mask(), strategy);
}
};
@@ -281,23 +285,8 @@ struct covered_by
Geometry2 const& geometry2,
default_strategy)
{
typedef typename point_type<Geometry1>::type point_type1;
typedef typename point_type<Geometry2>::type point_type2;
typedef typename strategy::covered_by::services::default_strategy
<
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
typename tag<Geometry1>::type,
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::type, spherical_tag
>::type,
Geometry1,
Geometry2
>::type strategy_type;

View File

@@ -5,8 +5,10 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -15,8 +17,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
#define BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
@@ -26,12 +26,12 @@
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/relate.hpp>
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
namespace boost { namespace geometry
{
@@ -62,20 +62,51 @@ struct crosses
#endif // DOXYGEN_NO_DISPATCH
namespace resolve_strategy
{
struct crosses
{
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
return dispatch::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
}
template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
default_strategy)
{
typedef typename strategy::relate::services::default_strategy
<
Geometry1,
Geometry2
>::type strategy_type;
return apply(geometry1, geometry2, strategy_type());
}
};
} // namespace resolve_strategy
namespace resolve_variant
{
template <typename Geometry1, typename Geometry2>
struct crosses
{
static inline bool
apply(
const Geometry1& geometry1,
const Geometry2& geometry2)
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
return dispatch::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2);
return resolve_strategy::crosses::apply(geometry1, geometry2, strategy);
}
};
@@ -83,12 +114,15 @@ namespace resolve_variant
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct crosses<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2)
visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2)
, m_strategy(strategy)
{}
template <typename Geometry1>
@@ -98,15 +132,16 @@ namespace resolve_variant
<
Geometry1,
Geometry2
>::apply(geometry1, m_geometry2);
>::apply(geometry1, m_geometry2, m_strategy);
}
};
static inline bool
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2)
template <typename Strategy>
static inline bool apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(geometry2), geometry1);
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
@@ -114,12 +149,15 @@ namespace resolve_variant
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct crosses<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1)
visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1)
, m_strategy(strategy)
{}
template <typename Geometry2>
@@ -129,15 +167,16 @@ namespace resolve_variant
<
Geometry1,
Geometry2
>::apply(m_geometry1, geometry2);
>::apply(m_geometry1, geometry2, m_strategy);
}
};
static inline bool
apply(Geometry1 const& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2)
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(geometry1), geometry2);
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -145,8 +184,15 @@ namespace resolve_variant
template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
struct crosses<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
template <typename Strategy>
struct visitor: static_visitor<bool>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
result_type operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
@@ -155,21 +201,47 @@ namespace resolve_variant
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2);
>::apply(geometry1, geometry2, m_strategy);
}
};
static inline bool
apply(const variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
const variant<BOOST_VARIANT_ENUM_PARAMS(T2)>& geometry2)
template <typename Strategy>
static inline bool apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(), geometry1, geometry2);
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
} // namespace resolve_variant
/*!
\brief \brief_check2{crosses}
\ingroup crosses
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Crosses}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{crosses}
\return \return_check2{crosses}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/crosses.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool crosses(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_variant::crosses
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
/*!
\brief \brief_check2{crosses}
\ingroup crosses
@@ -184,7 +256,10 @@ namespace resolve_variant
template <typename Geometry1, typename Geometry2>
inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
return resolve_variant::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2);
return resolve_variant::crosses
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, default_strategy());
}
}} // namespace boost::geometry

View File

@@ -2,9 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2016.
// Modifications copyright (c) 2014-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2016, 2017.
// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -23,6 +24,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/formulas/spherical.hpp>
#include <boost/geometry/formulas/vincenty_inverse.hpp>
namespace boost { namespace geometry
@@ -69,22 +71,9 @@ struct azimuth<ReturnType, spherical_equatorial_tag>
template <typename P1, typename P2, typename Sphere>
static inline ReturnType apply(P1 const& p1, P2 const& p2, Sphere const& /*unused*/)
{
// http://williams.best.vwh.net/avform.htm#Crs
ReturnType dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
ReturnType cos_p2lat = cos(get_as_radian<1>(p2));
// An optimization which should kick in often for Boxes
//if ( math::equals(dlon, ReturnType(0)) )
//if ( get<0>(p1) == get<0>(p2) )
//{
// return - sin(get_as_radian<1>(p1)) * cos_p2lat);
//}
// "An alternative formula, not requiring the pre-computation of d"
// In the formula below dlon is used as "d"
return atan2(sin(dlon) * cos_p2lat,
cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
- sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
return geometry::formula::spherical_azimuth<ReturnType, false>
( get_as_radian<0>(p1), get_as_radian<1>(p1),
get_as_radian<0>(p2), get_as_radian<1>(p2)).azimuth;
}
template <typename P1, typename P2>

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 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)
@@ -854,6 +858,7 @@ template
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
typename IntersectionStrategy,
typename RobustPolicy,
typename VisitPiecesPolicy
>
@@ -863,6 +868,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
VisitPiecesPolicy& visit_pieces_policy
)
@@ -872,9 +878,10 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
typedef detail::buffer::buffered_piece_collection
<
typename geometry::ring_type<GeometryOutput>::type,
IntersectionStrategy,
RobustPolicy
> collection_type;
collection_type collection(robust_policy);
collection_type collection(intersection_strategy, robust_policy);
collection_type const& const_collection = collection;
bool const areal = boost::is_same
@@ -961,6 +968,7 @@ template
typename JoinStrategy,
typename EndStrategy,
typename PointStrategy,
typename IntersectionStrategy,
typename RobustPolicy
>
inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out,
@@ -969,13 +977,14 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
JoinStrategy const& join_strategy,
EndStrategy const& end_strategy,
PointStrategy const& point_strategy,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
{
detail::buffer::visit_pieces_default_policy visitor;
buffer_inserter<GeometryOutput>(geometry_input, out,
distance_strategy, side_strategy, join_strategy,
end_strategy, point_strategy,
robust_policy, visitor);
intersection_strategy, robust_policy, visitor);
}
#endif // DOXYGEN_NO_DETAIL

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, 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)
@@ -52,6 +56,7 @@ public :
typename Rings,
typename Turns,
typename Geometry,
typename Strategy,
typename RobustPolicy,
typename Visitor
>
@@ -63,6 +68,7 @@ public :
detail::overlay::traverse_error_type /*traverse_error*/,
Geometry const& ,
Geometry const& ,
Strategy const& ,
RobustPolicy const& ,
state_type& state,
Visitor& /*visitor*/

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2016.
// Modifications copyright (c) 2016 Oracle and/or its affiliates.
// This file was modified by Oracle on 2016-2017.
// Modifications copyright (c) 2016-2017 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,
@@ -117,10 +117,13 @@ enum segment_relation_code
*/
template <typename Ring, typename RobustPolicy>
template <typename Ring, typename IntersectionStrategy, typename RobustPolicy>
struct buffered_piece_collection
{
typedef buffered_piece_collection<Ring, RobustPolicy> this_type;
typedef buffered_piece_collection
<
Ring, IntersectionStrategy, RobustPolicy
> this_type;
typedef typename geometry::point_type<Ring>::type point_type;
typedef typename geometry::coordinate_type<Ring>::type coordinate_type;
@@ -303,7 +306,7 @@ struct buffered_piece_collection
cluster_type m_clusters;
IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
struct redundant_turn
@@ -314,8 +317,10 @@ struct buffered_piece_collection
}
};
buffered_piece_collection(RobustPolicy const& robust_policy)
buffered_piece_collection(IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
: m_first_piece_index(-1)
, m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
{}
@@ -512,10 +517,11 @@ struct buffered_piece_collection
geometry::partition
<
robust_box_type,
turn_get_box, turn_in_original_ovelaps_box,
original_get_box, original_ovelaps_box,
include_turn_policy, detail::partition::include_all_policy
>::apply(m_turns, robust_originals, visitor);
include_turn_policy,
detail::partition::include_all_policy
>::apply(m_turns, robust_originals, visitor,
turn_get_box(), turn_in_original_ovelaps_box(),
original_get_box(), original_ovelaps_box());
bool const deflate = distance_strategy.negative();
@@ -767,15 +773,17 @@ struct buffered_piece_collection
piece_vector_type,
buffered_ring_collection<buffered_ring<Ring> >,
turn_vector_type,
IntersectionStrategy,
RobustPolicy
> visitor(m_pieces, offsetted_rings, m_turns, m_robust_policy);
> visitor(m_pieces, offsetted_rings, m_turns,
m_intersection_strategy, m_robust_policy);
geometry::partition
<
robust_box_type,
detail::section::get_section_box,
detail::section::overlaps_section_box
>::apply(monotonic_sections, visitor);
robust_box_type
>::apply(monotonic_sections, visitor,
detail::section::get_section_box(),
detail::section::overlaps_section_box());
}
insert_rescaled_piece_turns();
@@ -795,10 +803,10 @@ struct buffered_piece_collection
geometry::partition
<
robust_box_type,
turn_get_box, turn_ovelaps_box,
piece_get_box, piece_ovelaps_box
>::apply(m_turns, m_pieces, visitor);
robust_box_type
>::apply(m_turns, m_pieces, visitor,
turn_get_box(), turn_ovelaps_box(),
piece_get_box(), piece_ovelaps_box());
}
}
@@ -1354,7 +1362,8 @@ struct buffered_piece_collection
traversed_rings.clear();
buffer_overlay_visitor visitor;
traverser::apply(offsetted_rings, offsetted_rings,
m_robust_policy, m_turns, traversed_rings,
m_intersection_strategy, m_robust_policy,
m_turns, traversed_rings,
m_clusters, visitor);
}

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 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)
@@ -62,6 +66,7 @@ template
typename Pieces,
typename Rings,
typename Turns,
typename IntersectionStrategy,
typename RobustPolicy
>
class piece_turn_visitor
@@ -69,6 +74,7 @@ class piece_turn_visitor
Pieces const& m_pieces;
Rings const& m_rings;
Turns& m_turns;
IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
template <typename Piece>
@@ -243,7 +249,9 @@ class piece_turn_visitor
turn_policy::apply(*prev1, *it1, *next1,
*prev2, *it2, *next2,
false, false, false, false,
the_model, m_robust_policy,
the_model,
m_intersection_strategy,
m_robust_policy,
std::back_inserter(m_turns));
}
}
@@ -254,10 +262,12 @@ public:
piece_turn_visitor(Pieces const& pieces,
Rings const& ring_collection,
Turns& turns,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
: m_pieces(pieces)
, m_rings(ring_collection)
, m_turns(turns)
, m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
{}

View File

@@ -8,6 +8,10 @@
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2016.
// Modifications copyright (c) 2016 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, 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)
@@ -30,7 +34,7 @@ class calculate_polygon_sum
template <typename ReturnType, typename Policy, typename Rings, typename Strategy>
static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy)
{
ReturnType sum = ReturnType();
ReturnType sum = ReturnType(0);
for (typename boost::range_iterator<Rings const>::type
it = boost::begin(rings); it != boost::end(rings); ++it)
{

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2014.
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -39,15 +39,45 @@ namespace detail { namespace disjoint
{
template<typename Geometry>
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
struct check_each_ring_for_within_call_covered_by
{
/*!
\tparam Strategy point_in_geometry strategy
*/
template <typename Point, typename Strategy>
static inline bool apply(Point const& p, Geometry const& g, Strategy const& strategy)
{
return geometry::covered_by(p, g, strategy);
}
};
template <typename Geometry>
struct check_each_ring_for_within_call_covered_by<Geometry, box_tag>
{
template <typename Point, typename Strategy>
static inline bool apply(Point const& p, Geometry const& g, Strategy const& )
{
return geometry::covered_by(p, g);
}
};
/*!
\tparam Strategy point_in_geometry strategy
*/
template<typename Geometry, typename Strategy>
struct check_each_ring_for_within
{
bool not_disjoint;
Geometry const& m_geometry;
Strategy const& m_strategy;
inline check_each_ring_for_within(Geometry const& g)
inline check_each_ring_for_within(Geometry const& g,
Strategy const& strategy)
: not_disjoint(false)
, m_geometry(g)
, m_strategy(strategy)
{}
template <typename Range>
@@ -56,17 +86,26 @@ struct check_each_ring_for_within
typename point_type<Range>::type pt;
not_disjoint = not_disjoint
|| ( geometry::point_on_border(pt, range)
&& geometry::covered_by(pt, m_geometry) );
&& check_each_ring_for_within_call_covered_by
<
Geometry
>::apply(pt, m_geometry, m_strategy) );
}
};
template <typename FirstGeometry, typename SecondGeometry>
/*!
\tparam Strategy point_in_geometry strategy
*/
template <typename FirstGeometry, typename SecondGeometry, typename Strategy>
inline bool rings_containing(FirstGeometry const& geometry1,
SecondGeometry const& geometry2)
SecondGeometry const& geometry2,
Strategy const& strategy)
{
check_each_ring_for_within<FirstGeometry> checker(geometry1);
check_each_ring_for_within
<
FirstGeometry, Strategy
> checker(geometry1, strategy);
geometry::detail::for_each_range(geometry2, checker);
return checker.not_disjoint;
}
@@ -76,10 +115,15 @@ inline bool rings_containing(FirstGeometry const& geometry1,
template <typename Geometry1, typename Geometry2>
struct general_areal
{
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
/*!
\tparam Strategy relate (segments intersection) strategy
*/
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
if ( ! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2) )
if ( ! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy) )
{
return false;
}
@@ -90,8 +134,10 @@ struct general_areal
// We check that using a point on the border (external boundary),
// and see if that is contained in the other geometry. And vice versa.
if ( rings_containing(geometry1, geometry2)
|| rings_containing(geometry2, geometry1) )
if ( rings_containing(geometry1, geometry2,
strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>())
|| rings_containing(geometry2, geometry1,
strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>()) )
{
return false;
}

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2016.
// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -52,6 +52,12 @@ template
>
struct box_box
{
template <typename Strategy>
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
{
return apply(box1, box2);
}
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
@@ -84,6 +90,12 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount, CSTag>
template <typename Box1, typename Box2, std::size_t DimensionCount>
struct box_box<Box1, Box2, 0, DimensionCount, spherical_tag>
{
template <typename Strategy>
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
{
return apply(box1, box2);
}
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
typedef typename geometry::select_most_precise

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2014.
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -27,43 +27,51 @@
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/relate/interface.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
namespace resolve_strategy
{
// If reversal is needed, perform it
template
<
typename Geometry1, typename Geometry2,
std::size_t DimensionCount,
typename Tag1, typename Tag2
>
struct disjoint<Geometry1, Geometry2, DimensionCount, Tag1, Tag2, true>
struct disjoint
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return disjoint
return dispatch::disjoint
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
default_strategy)
{
typedef typename strategy::disjoint::services::default_strategy
<
Geometry2, Geometry1,
DimensionCount,
Tag2, Tag1
>::apply(g2, g1);
Geometry1, Geometry2
>::type strategy_type;
return dispatch::disjoint
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy_type());
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
} // namespace resolve_strategy
namespace resolve_variant {
@@ -71,7 +79,8 @@ namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct disjoint
{
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
concepts::check_concepts_and_equal_dimensions
<
@@ -79,88 +88,135 @@ struct disjoint
Geometry2 const
>();
return dispatch::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
return resolve_strategy::disjoint::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct disjoint<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {}
visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2)
, m_strategy(strategy)
{}
template <typename Geometry1>
bool operator()(Geometry1 const& geometry1) const
{
return disjoint<Geometry1, Geometry2>::apply(geometry1, m_geometry2);
return disjoint<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy);
}
};
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2)
template <typename Strategy>
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(geometry2), geometry1);
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct disjoint<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {}
visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1)
, m_strategy(strategy)
{}
template <typename Geometry2>
bool operator()(Geometry2 const& geometry2) const
{
return disjoint<Geometry1, Geometry2>::apply(m_geometry1, geometry2);
return disjoint<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy);
}
};
static inline bool
apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(geometry1), geometry2);
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
template <
template
<
BOOST_VARIANT_ENUM_PARAMS(typename T1),
BOOST_VARIANT_ENUM_PARAMS(typename T2)
>
struct disjoint<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
struct disjoint
<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
return disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy);
}
};
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
template <typename Strategy>
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(), geometry1, geometry2);
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
} // namespace resolve_variant
/*!
\brief \brief_check2{are disjoint}
\ingroup disjoint
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Disjoint}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{disjoint}
\return \return_check2{are disjoint}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/disjoint.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool disjoint(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_variant::disjoint
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
/*!
\brief \brief_check2{are disjoint}
@@ -177,7 +233,10 @@ template <typename Geometry1, typename Geometry2>
inline bool disjoint(Geometry1 const& geometry1,
Geometry2 const& geometry2)
{
return resolve_variant::disjoint<Geometry1, Geometry2>::apply(geometry1, geometry2);
return resolve_variant::disjoint
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, default_strategy());
}

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -61,19 +61,28 @@ template <typename Geometry1, typename Geometry2,
typename Tag1OrMulti = typename tag_cast<Tag1, multi_tag>::type>
struct disjoint_no_intersections_policy
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
/*!
\tparam Strategy point_in_geometry strategy
*/
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
typedef typename point_type<Geometry1>::type point1_type;
point1_type p;
geometry::point_on_border(p, g1);
return !geometry::covered_by(p, g2);
return !geometry::covered_by(p, g2, strategy);
}
};
template <typename Geometry1, typename Geometry2, typename Tag1>
struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
/*!
\tparam Strategy point_in_geometry strategy
*/
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
// TODO: use partition or rtree on g2
typedef typename boost::range_iterator<Geometry1 const>::type iterator;
@@ -81,7 +90,7 @@ struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
{
typedef typename boost::range_value<Geometry1 const>::type value_type;
if ( ! disjoint_no_intersections_policy<value_type const, Geometry2>
::apply(*it, g2) )
::apply(*it, g2, strategy) )
{
return false;
}
@@ -96,15 +105,21 @@ template<typename Geometry1, typename Geometry2,
= disjoint_no_intersections_policy<Geometry1, Geometry2> >
struct disjoint_linear_areal
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
/*!
\tparam Strategy relate (segments intersection) strategy
*/
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
// if there are intersections - return false
if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2) )
if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2, strategy) )
{
return false;
}
return NoIntersectionsPolicy::apply(g1, g2);
return NoIntersectionsPolicy
::apply(g1, g2,
strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>());
}
};
@@ -126,16 +141,18 @@ template <typename Segment, typename Polygon>
class disjoint_segment_areal<Segment, Polygon, polygon_tag>
{
private:
template <typename InteriorRings>
template <typename InteriorRings, typename Strategy>
static inline
bool check_interior_rings(InteriorRings const& interior_rings,
Segment const& segment)
Segment const& segment,
Strategy const& strategy)
{
typedef typename boost::range_value<InteriorRings>::type ring_type;
typedef unary_disjoint_geometry_to_query_geometry
<
Segment,
Strategy,
disjoint_range_segment_or_box
<
ring_type, closure<ring_type>::value, Segment
@@ -147,24 +164,27 @@ private:
unary_predicate_type
>::apply(boost::begin(interior_rings),
boost::end(interior_rings),
unary_predicate_type(segment));
unary_predicate_type(segment, strategy));
}
public:
static inline bool apply(Segment const& segment, Polygon const& polygon)
template <typename IntersectionStrategy>
static inline bool apply(Segment const& segment,
Polygon const& polygon,
IntersectionStrategy const& strategy)
{
typedef typename geometry::ring_type<Polygon>::type ring;
if ( !disjoint_range_segment_or_box
<
ring, closure<Polygon>::value, Segment
>::apply(geometry::exterior_ring(polygon), segment) )
>::apply(geometry::exterior_ring(polygon), segment, strategy) )
{
return false;
}
if ( !check_interior_rings(geometry::interior_rings(polygon), segment) )
if ( !check_interior_rings(geometry::interior_rings(polygon), segment, strategy) )
{
return false;
}
@@ -172,7 +192,8 @@ public:
typename point_type<Segment>::type p;
detail::assign_point_from_index<0>(segment, p);
return !geometry::covered_by(p, polygon);
return !geometry::covered_by(p, polygon,
strategy.template get_point_in_geometry_strategy<Segment, Polygon>());
}
};
@@ -180,13 +201,14 @@ public:
template <typename Segment, typename MultiPolygon>
struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
{
static inline
bool apply(Segment const& segment, MultiPolygon const& multipolygon)
template <typename IntersectionStrategy>
static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon,
IntersectionStrategy const& strategy)
{
return multirange_constant_size_geometry
<
MultiPolygon, Segment
>::apply(multipolygon, segment);
>::apply(multipolygon, segment, strategy);
}
};
@@ -194,20 +216,24 @@ struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
template <typename Segment, typename Ring>
struct disjoint_segment_areal<Segment, Ring, ring_tag>
{
static inline bool apply(Segment const& segment, Ring const& ring)
template <typename IntersectionStrategy>
static inline bool apply(Segment const& segment,
Ring const& ring,
IntersectionStrategy const& strategy)
{
if ( !disjoint_range_segment_or_box
<
Ring, closure<Ring>::value, Segment
>::apply(ring, segment) )
>::apply(ring, segment, strategy) )
{
return false;
}
typename point_type<Segment>::type p;
detail::assign_point_from_index<0>(segment, p);
return !geometry::covered_by(p, ring);
return !geometry::covered_by(p, ring,
strategy.template get_point_in_geometry_strategy<Segment, Ring>());
}
};
@@ -231,14 +257,15 @@ struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
template <typename Areal, typename Linear>
struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
{
static inline
bool apply(Areal const& areal, Linear const& linear)
{
template <typename Strategy>
static inline bool apply(Areal const& areal, Linear const& linear,
Strategy const& strategy)
{
return detail::disjoint::disjoint_linear_areal
<
Linear, Areal
>::apply(linear, areal);
>::apply(linear, areal, strategy);
}
};
@@ -246,12 +273,14 @@ struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
template <typename Areal, typename Segment>
struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
{
static inline bool apply(Areal const& g1, Segment const& g2)
template <typename Strategy>
static inline bool apply(Areal const& g1, Segment const& g2,
Strategy const& strategy)
{
return detail::disjoint::disjoint_segment_areal
<
Segment, Areal
>::apply(g2, g1);
>::apply(g2, g1, strategy);
}
};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2014.
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -53,7 +53,9 @@ namespace detail { namespace disjoint
template <typename Segment1, typename Segment2>
struct disjoint_segment
{
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
template <typename Strategy>
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
Strategy const& strategy)
{
typedef typename point_type<Segment1>::type point_type;
@@ -62,23 +64,23 @@ struct disjoint_segment
rescale_policy_type robust_policy;
typedef segment_intersection_points
<
point_type,
typename segment_ratio_type
<
point_type,
typename segment_ratio_type
<
point_type,
rescale_policy_type
>::type
> intersection_return_type;
> intersection_return_type;
intersection_return_type is
= strategy::intersection::relate_cartesian_segments
typedef policies::relate::segments_intersection_points
<
policies::relate::segments_intersection_points
<
intersection_return_type
>
>::apply(segment1, segment2, robust_policy);
intersection_return_type
> intersection_policy;
intersection_return_type is = strategy.apply(segment1, segment2,
intersection_policy(),
robust_policy);
return is.count == 0;
}
@@ -109,8 +111,10 @@ struct assign_disjoint_policy
template <typename Geometry1, typename Geometry2>
struct disjoint_linear
{
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
typedef typename geometry::point_type<Geometry1>::type point_type;
typedef detail::no_rescale_policy rescale_policy_type;
@@ -147,7 +151,7 @@ struct disjoint_linear
Geometry1, Geometry2, assign_disjoint_policy
>
>::apply(0, geometry1, 1, geometry2,
rescale_policy_type(), turns, interrupt_policy);
strategy, rescale_policy_type(), turns, interrupt_policy);
return !interrupt_policy.has_intersections;
}

View File

@@ -53,8 +53,10 @@ template
>
struct disjoint_range_segment_or_box
{
static inline
bool apply(Range const& range, SegmentOrBox const& segment_or_box)
template <typename Strategy>
static inline bool apply(Range const& range,
SegmentOrBox const& segment_or_box,
Strategy const& strategy)
{
typedef typename closeable_view<Range const, Closure>::type view_type;
@@ -85,7 +87,8 @@ struct disjoint_range_segment_or_box
<
point_type, SegmentOrBox
>::apply(geometry::range::front<view_type const>(view),
segment_or_box);
segment_or_box,
strategy.template get_point_in_geometry_strategy<Range, SegmentOrBox>());
}
else
{
@@ -99,7 +102,7 @@ struct disjoint_range_segment_or_box
if ( !dispatch::disjoint
<
range_segment, SegmentOrBox
>::apply(rng_segment, segment_or_box) )
>::apply(rng_segment, segment_or_box, strategy) )
{
return false;
}

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -14,8 +15,10 @@
#include <vector>
#include <boost/range.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/box.hpp>
@@ -105,36 +108,74 @@ template <typename MultiPoint, typename Linear>
class multipoint_linear
{
private:
// structs for partition -- start
struct expand_box
struct expand_box_point
{
template <typename Box, typename Geometry>
static inline void apply(Box& total, Geometry const& geometry)
template <typename Box, typename Point>
static inline void apply(Box& total, Point const& point)
{
geometry::expand(total, geometry::return_envelope<Box>(geometry));
}
};
struct overlaps_box
{
template <typename Box, typename Geometry>
static inline bool apply(Box const& box, Geometry const& geometry)
{
return ! dispatch::disjoint<Geometry, Box>::apply(geometry, box);
geometry::expand(total, point);
}
};
// TODO: After adding non-cartesian Segment envelope to the library
// this policy should be modified to take envelope strategy.
struct expand_box_segment
{
template <typename Box, typename Segment>
static inline void apply(Box& total, Segment const& segment)
{
geometry::expand(total, geometry::return_envelope<Box>(segment));
}
};
struct overlaps_box_point
{
template <typename Box, typename Point>
static inline bool apply(Box const& box, Point const& point)
{
// The default strategy is enough in this case
typedef typename strategy::disjoint::services::default_strategy
<
Point, Box
>::type strategy_type;
return ! dispatch::disjoint<Point, Box>::apply(point, box, strategy_type());
}
};
// TODO: After implementing disjoint Segment/Box for non-cartesian geometries
// this strategy should be passed here.
// TODO: This Segment/Box strategy should somehow be derived from Point/Segment strategy
// which by default is winding containing CS-specific side strategy
// TODO: disjoint Segment/Box will be called in this case which may take
// quite long in non-cartesian CS. So we should consider passing range of bounding boxes
// of segments after calculating them once.
struct overlaps_box_segment
{
template <typename Box, typename Segment>
static inline bool apply(Box const& box, Segment const& segment)
{
typedef typename strategy::disjoint::services::default_strategy
<
Segment, Box
>::type strategy_type;
return ! dispatch::disjoint<Segment, Box>::apply(segment, box, strategy_type());
}
};
template <typename PtSegStrategy>
class item_visitor_type
{
public:
item_visitor_type() : m_intersection_found(false) {}
item_visitor_type(PtSegStrategy const& strategy)
: m_intersection_found(false)
, m_strategy(strategy)
{}
template <typename Item1, typename Item2>
inline void apply(Item1 const& item1, Item2 const& item2)
{
if (! m_intersection_found
&& ! dispatch::disjoint<Item1, Item2>::apply(item1, item2))
&& ! dispatch::disjoint<Item1, Item2>::apply(item1, item2, m_strategy))
{
m_intersection_found = true;
}
@@ -144,6 +185,7 @@ private:
private:
bool m_intersection_found;
PtSegStrategy const& m_strategy;
};
// structs for partition -- end
@@ -172,23 +214,25 @@ private:
};
public:
static inline bool apply(MultiPoint const& multipoint, Linear const& linear)
template <typename Strategy>
static inline bool apply(MultiPoint const& multipoint, Linear const& linear, Strategy const& strategy)
{
item_visitor_type visitor;
item_visitor_type<Strategy> visitor(strategy);
geometry::partition
<
geometry::model::box<typename point_type<MultiPoint>::type>,
expand_box,
overlaps_box
>::apply(multipoint, segment_range(linear), visitor);
geometry::model::box<typename point_type<MultiPoint>::type>
>::apply(multipoint, segment_range(linear), visitor,
expand_box_point(), overlaps_box_point(),
expand_box_segment(), overlaps_box_segment());
return ! visitor.intersection_found();
}
static inline bool apply(Linear const& linear, MultiPoint const& multipoint)
template <typename Strategy>
static inline bool apply(Linear const& linear, MultiPoint const& multipoint, Strategy const& strategy)
{
return apply(multipoint, linear);
return apply(multipoint, linear, strategy);
}
};
@@ -240,8 +284,10 @@ struct disjoint
multi_point_tag, multi_point_tag, false
>
{
template <typename Strategy>
static inline bool apply(MultiPoint1 const& multipoint1,
MultiPoint2 const& multipoint2)
MultiPoint2 const& multipoint2,
Strategy const& )
{
if ( boost::size(multipoint2) < boost::size(multipoint1) )
{

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, Oracle and/or its affiliates.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -25,34 +26,40 @@ namespace detail { namespace disjoint
{
template <typename Geometry, typename BinaryPredicate>
template <typename Geometry, typename Strategy, typename BinaryPredicate>
class unary_disjoint_geometry_to_query_geometry
{
public:
unary_disjoint_geometry_to_query_geometry(Geometry const& geometry)
unary_disjoint_geometry_to_query_geometry(Geometry const& geometry,
Strategy const& strategy)
: m_geometry(geometry)
, m_strategy(strategy)
{}
template <typename QueryGeometry>
inline bool apply(QueryGeometry const& query_geometry) const
{
return BinaryPredicate::apply(query_geometry, m_geometry);
return BinaryPredicate::apply(query_geometry, m_geometry, m_strategy);
}
private:
Geometry const& m_geometry;
Strategy const& m_strategy;
};
template<typename MultiRange, typename ConstantSizeGeometry>
struct multirange_constant_size_geometry
{
template <typename Strategy>
static inline bool apply(MultiRange const& multirange,
ConstantSizeGeometry const& constant_size_geometry)
ConstantSizeGeometry const& constant_size_geometry,
Strategy const& strategy)
{
typedef unary_disjoint_geometry_to_query_geometry
<
ConstantSizeGeometry,
Strategy,
dispatch::disjoint
<
typename boost::range_value<MultiRange>::type,
@@ -64,13 +71,15 @@ struct multirange_constant_size_geometry
<
unary_predicate_type
>::apply(boost::begin(multirange), boost::end(multirange),
unary_predicate_type(constant_size_geometry));
unary_predicate_type(constant_size_geometry, strategy));
}
template <typename Strategy>
static inline bool apply(ConstantSizeGeometry const& constant_size_geometry,
MultiRange const& multirange)
MultiRange const& multirange,
Strategy const& strategy)
{
return apply(multirange, constant_size_geometry);
return apply(multirange, constant_size_geometry, strategy);
}
};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
// This file was modified by Oracle on 2013-2016.
// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -28,7 +28,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
namespace boost { namespace geometry
{
@@ -44,13 +44,13 @@ namespace detail { namespace disjoint
template <typename Point, typename Box>
inline bool disjoint_point_box(Point const& point, Box const& box)
{
typedef typename strategy::disjoint::services::default_strategy
<
Point, Box
>::type strategy_type;
// ! covered_by(point, box)
return ! strategy::within::relate_point_box_loop
<
strategy::within::covered_by_range,
Point, Box,
0, dimension<Point>::type::value
>::apply(point, box);
return ! strategy_type::apply(point, box);
}
@@ -66,15 +66,11 @@ namespace dispatch
template <typename Point, typename Box, std::size_t DimensionCount>
struct disjoint<Point, Box, DimensionCount, point_tag, box_tag, false>
{
static inline bool apply(Point const& point, Box const& box)
template <typename Strategy>
static inline bool apply(Point const& point, Box const& box, Strategy const& )
{
// ! covered_by(point, box)
return ! strategy::within::relate_point_box_loop
<
strategy::within::covered_by_range,
Point, Box,
0, DimensionCount
>::apply(point, box);
return ! Strategy::apply(point, box);
}
};

View File

@@ -39,11 +39,12 @@ namespace detail { namespace disjoint
struct reverse_covered_by
{
template <typename Geometry1, typename Geometry2>
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return ! geometry::covered_by(geometry1, geometry2);
return ! geometry::covered_by(geometry1, geometry2, strategy);
}
};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -59,6 +59,12 @@ namespace detail { namespace disjoint
template <std::size_t Dimension, std::size_t DimensionCount>
struct point_point_generic
{
template <typename Point1, typename Point2, typename Strategy>
static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& )
{
return apply(p1, p2);
}
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& p1, Point2 const& p2)
{
@@ -75,7 +81,7 @@ template <std::size_t DimensionCount>
struct point_point_generic<DimensionCount, DimensionCount>
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const&, Point2 const&)
static inline bool apply(Point1 const&, Point2 const& )
{
return false;
}
@@ -135,6 +141,12 @@ private:
};
public:
template <typename Point1, typename Point2, typename Strategy>
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
{
return apply(point1, point2);
}
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& point1, Point2 const& point2)
{

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2014.
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -22,19 +22,8 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_SEGMENT_BOX_HPP
#include <cstddef>
#include <utility>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
@@ -47,236 +36,19 @@ namespace boost { namespace geometry
namespace detail { namespace disjoint
{
template <std::size_t I>
struct compute_tmin_tmax_per_dim
{
template <typename SegmentPoint, typename Box, typename RelativeDistance>
static inline void apply(SegmentPoint const& p0,
SegmentPoint const& p1,
Box const& box,
RelativeDistance& ti_min,
RelativeDistance& ti_max,
RelativeDistance& diff)
{
typedef typename coordinate_type<Box>::type box_coordinate_type;
typedef typename coordinate_type
<
SegmentPoint
>::type point_coordinate_type;
RelativeDistance c_p0 = boost::numeric_cast
<
point_coordinate_type
>( geometry::get<I>(p0) );
RelativeDistance c_p1 = boost::numeric_cast
<
point_coordinate_type
>( geometry::get<I>(p1) );
RelativeDistance c_b_min = boost::numeric_cast
<
box_coordinate_type
>( geometry::get<geometry::min_corner, I>(box) );
RelativeDistance c_b_max = boost::numeric_cast
<
box_coordinate_type
>( geometry::get<geometry::max_corner, I>(box) );
if ( geometry::get<I>(p1) >= geometry::get<I>(p0) )
{
diff = c_p1 - c_p0;
ti_min = c_b_min - c_p0;
ti_max = c_b_max - c_p0;
}
else
{
diff = c_p0 - c_p1;
ti_min = c_p0 - c_b_max;
ti_max = c_p0 - c_b_min;
}
}
};
template
<
typename RelativeDistance,
typename SegmentPoint,
typename Box,
std::size_t I,
std::size_t Dimension
>
struct disjoint_segment_box_impl
{
template <typename RelativeDistancePair>
static inline bool apply(SegmentPoint const& p0,
SegmentPoint const& p1,
Box const& box,
RelativeDistancePair& t_min,
RelativeDistancePair& t_max)
{
RelativeDistance ti_min, ti_max, diff;
compute_tmin_tmax_per_dim<I>::apply(p0, p1, box, ti_min, ti_max, diff);
if ( geometry::math::equals(diff, 0) )
{
if ( (geometry::math::equals(t_min.second, 0)
&& t_min.first > ti_max)
||
(geometry::math::equals(t_max.second, 0)
&& t_max.first < ti_min)
||
(math::sign(ti_min) * math::sign(ti_max) > 0) )
{
return true;
}
}
RelativeDistance t_min_x_diff = t_min.first * diff;
RelativeDistance t_max_x_diff = t_max.first * diff;
if ( t_min_x_diff > ti_max * t_min.second
|| t_max_x_diff < ti_min * t_max.second )
{
return true;
}
if ( ti_min * t_min.second > t_min_x_diff )
{
t_min.first = ti_min;
t_min.second = diff;
}
if ( ti_max * t_max.second < t_max_x_diff )
{
t_max.first = ti_max;
t_max.second = diff;
}
if ( t_min.first > t_min.second || t_max.first < 0 )
{
return true;
}
return disjoint_segment_box_impl
<
RelativeDistance,
SegmentPoint,
Box,
I + 1,
Dimension
>::apply(p0, p1, box, t_min, t_max);
}
};
template
<
typename RelativeDistance,
typename SegmentPoint,
typename Box,
std::size_t Dimension
>
struct disjoint_segment_box_impl
<
RelativeDistance, SegmentPoint, Box, 0, Dimension
>
{
static inline bool apply(SegmentPoint const& p0,
SegmentPoint const& p1,
Box const& box)
{
std::pair<RelativeDistance, RelativeDistance> t_min, t_max;
RelativeDistance diff;
compute_tmin_tmax_per_dim<0>::apply(p0, p1, box,
t_min.first, t_max.first, diff);
if ( geometry::math::equals(diff, 0) )
{
if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; }
if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; }
if (math::sign(t_min.first) * math::sign(t_max.first) > 0)
{
return true;
}
}
if ( t_min.first > diff || t_max.first < 0 )
{
return true;
}
t_min.second = t_max.second = diff;
return disjoint_segment_box_impl
<
RelativeDistance, SegmentPoint, Box, 1, Dimension
>::apply(p0, p1, box, t_min, t_max);
}
};
template
<
typename RelativeDistance,
typename SegmentPoint,
typename Box,
std::size_t Dimension
>
struct disjoint_segment_box_impl
<
RelativeDistance, SegmentPoint, Box, Dimension, Dimension
>
{
template <typename RelativeDistancePair>
static inline bool apply(SegmentPoint const&, SegmentPoint const&,
Box const&,
RelativeDistancePair&, RelativeDistancePair&)
{
return false;
}
};
//=========================================================================
template <typename Segment, typename Box>
struct disjoint_segment_box
{
static inline bool apply(Segment const& segment, Box const& box)
{
template <typename Segment, typename Box, typename Strategy>
static inline bool apply(Segment const& segment, Box const& box, Strategy const& strategy)
{
assert_dimension_equal<Segment, Box>();
typedef typename util::calculation_type::geometric::binary
<
Segment, Box, void
>::type relative_distance_type;
typedef typename point_type<Segment>::type segment_point_type;
segment_point_type p0, p1;
geometry::detail::assign_point_from_index<0>(segment, p0);
geometry::detail::assign_point_from_index<1>(segment, p1);
return disjoint_segment_box_impl
<
relative_distance_type, segment_point_type, Box,
0, dimension<Box>::value
>::apply(p0, p1, box);
return strategy.apply(segment, box);
}
};
}} // namespace detail::disjoint
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -284,7 +56,7 @@ namespace dispatch
template <typename Segment, typename Box, std::size_t DimensionCount>
struct disjoint<Segment, Box, DimensionCount, segment_tag, box_tag, false>
: detail::disjoint::disjoint_segment_box<Segment, Box>
: detail::disjoint::disjoint_segment_box
{};

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -97,8 +98,10 @@ struct envelope_indexed_box_on_spheroid
struct envelope_box
{
template<typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
template<typename BoxIn, typename BoxOut, typename Strategy>
static inline void apply(BoxIn const& box_in,
BoxOut& mbr,
Strategy const&)
{
envelope_indexed_box
<
@@ -115,8 +118,10 @@ struct envelope_box
struct envelope_box_on_spheroid
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
template <typename BoxIn, typename BoxOut, typename Strategy>
static inline void apply(BoxIn const& box_in,
BoxOut& mbr,
Strategy const&)
{
BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in);

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -45,8 +46,8 @@ namespace detail { namespace envelope
struct envelope_polygon
{
template <typename Polygon, typename Box>
static inline void apply(Polygon const& polygon, Box& mbr)
template <typename Polygon, typename Box, typename Strategy>
static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy)
{
typename ring_return_type<Polygon const>::type ext_ring
= exterior_ring(polygon);
@@ -57,12 +58,12 @@ struct envelope_polygon
envelope_multi_range
<
envelope_range
>::apply(interior_rings(polygon), mbr);
>::apply(interior_rings(polygon), mbr, strategy);
}
else
{
// otherwise, consider only the exterior ring
envelope_range::apply(ext_ring, mbr);
envelope_range::apply(ext_ring, mbr, strategy);
}
}
};

View File

@@ -4,10 +4,12 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -27,54 +29,124 @@
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
namespace resolve_strategy
{
template <typename Geometry>
struct envelope
{
template <typename Box, typename Strategy>
static inline void apply(Geometry const& geometry,
Box& box,
Strategy const& strategy)
{
dispatch::envelope<Geometry>::apply(geometry, box, strategy);
}
template <typename Box>
static inline void apply(Geometry const& geometry,
Box& box,
default_strategy)
{
typedef typename point_type<Geometry>::type point_type;
typedef typename coordinate_type<point_type>::type coordinate_type;
typedef typename strategy::envelope::services::default_strategy
<
typename cs_tag<point_type>::type,
coordinate_type
>::type strategy_type;
dispatch::envelope<Geometry>::apply(geometry, box, strategy_type());
}
};
} // namespace resolve_strategy
namespace resolve_variant
{
template <typename Geometry>
struct envelope
{
template <typename Box>
static inline void apply(Geometry const& geometry, Box& box)
template <typename Box, typename Strategy>
static inline void apply(Geometry const& geometry,
Box& box,
Strategy const& strategy)
{
concepts::check<Geometry const>();
concepts::check<Box>();
dispatch::envelope<Geometry>::apply(geometry, box);
resolve_strategy::envelope<Geometry>::apply(geometry, box, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Box>
template <typename Box, typename Strategy>
struct visitor: boost::static_visitor<void>
{
Box& m_box;
Strategy const& m_strategy;
visitor(Box& box): m_box(box) {}
visitor(Box& box, Strategy const& strategy)
: m_box(box)
, m_strategy(strategy)
{}
template <typename Geometry>
void operator()(Geometry const& geometry) const
{
envelope<Geometry>::apply(geometry, m_box);
envelope<Geometry>::apply(geometry, m_box, m_strategy);
}
};
template <typename Box>
template <typename Box, typename Strategy>
static inline void
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
Box& box)
Box& box,
Strategy const& strategy)
{
boost::apply_visitor(visitor<Box>(box), geometry);
boost::apply_visitor(visitor<Box, Strategy>(box, strategy), geometry);
}
};
} // namespace resolve_variant
/*!
\brief \brief_calc{envelope (with strategy)}
\ingroup envelope
\details \details_calc{envelope,\det_envelope}.
\tparam Geometry \tparam_geometry
\tparam Box \tparam_box
\tparam Strategy \tparam_strategy{Envelope}
\param geometry \param_geometry
\param mbr \param_box \param_set{envelope}
\param strategy \param_strategy{envelope}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/envelope.qbk]}
\qbk{
[heading Example]
[envelope] [envelope_output]
}
*/
template<typename Geometry, typename Box, typename Strategy>
inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strategy)
{
resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
}
/*!
\brief \brief_calc{envelope}
@@ -94,10 +166,36 @@ struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
template<typename Geometry, typename Box>
inline void envelope(Geometry const& geometry, Box& mbr)
{
resolve_variant::envelope<Geometry>::apply(geometry, mbr);
resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
}
/*!
\brief \brief_calc{envelope}
\ingroup envelope
\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
\tparam Box \tparam_box
\tparam Geometry \tparam_geometry
\tparam Strategy \tparam_strategy{Envelope}
\param geometry \param_geometry
\param strategy \param_strategy{envelope}
\return \return_calc{envelope}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/envelope.qbk]}
\qbk{
[heading Example]
[return_envelope] [return_envelope_output]
}
*/
template<typename Box, typename Geometry, typename Strategy>
inline Box return_envelope(Geometry const& geometry, Strategy const& strategy)
{
Box mbr;
resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
return mbr;
}
/*!
\brief \brief_calc{envelope}
\ingroup envelope
@@ -117,7 +215,7 @@ template<typename Box, typename Geometry>
inline Box return_envelope(Geometry const& geometry)
{
Box mbr;
resolve_variant::envelope<Geometry>::apply(geometry, mbr);
resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
return mbr;
}

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -36,12 +37,15 @@ namespace detail { namespace envelope
struct envelope_linestring_on_spheroid
{
template <typename Linestring, typename Box>
static inline void apply(Linestring const& linestring, Box& mbr)
template <typename Linestring, typename Box, typename Strategy>
static inline void apply(Linestring const& linestring,
Box& mbr,
Strategy const& strategy)
{
envelope_range::apply(geometry::segments_begin(linestring),
geometry::segments_end(linestring),
mbr);
mbr,
strategy);
}
};
@@ -65,6 +69,11 @@ struct envelope<Linestring, linestring_tag, spherical_equatorial_tag>
: detail::envelope::envelope_linestring_on_spheroid
{};
template <typename Linestring>
struct envelope<Linestring, linestring_tag, geographic_tag>
: detail::envelope::envelope_linestring_on_spheroid
{};
template <typename MultiLinestring, typename CS_Tag>
struct envelope
@@ -86,6 +95,15 @@ struct envelope
>
{};
template <typename MultiLinestring>
struct envelope
<
MultiLinestring, multi_linestring_tag, geographic_tag
> : detail::envelope::envelope_multi_range_on_spheroid
<
detail::envelope::envelope_linestring_on_spheroid
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015, Oracle and/or its affiliates.
// Copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -226,8 +227,8 @@ private:
}
public:
template <typename MultiPoint, typename Box>
static inline void apply(MultiPoint const& multipoint, Box& mbr)
template <typename MultiPoint, typename Box, typename Strategy>
static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy)
{
typedef typename point_type<MultiPoint>::type point_type;
typedef typename coordinate_type<MultiPoint>::type coordinate_type;
@@ -255,7 +256,7 @@ public:
return dispatch::envelope
<
typename boost::range_value<MultiPoint>::type
>::apply(range::front(multipoint), mbr);
>::apply(range::front(multipoint), mbr, strategy);
}
// analyze the points and put the non-pole ones in the
@@ -329,7 +330,7 @@ public:
// compute envelope for higher coordinates
iterator_type it = boost::begin(multipoint);
envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr);
envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr, strategy);
for (++it; it != boost::end(multipoint); ++it)
{
@@ -338,7 +339,7 @@ public:
strategy::compare::default_strategy,
strategy::compare::default_strategy,
2, dimension<Box>::value
>::apply(mbr, *it);
>::apply(mbr, *it, strategy);
}
}
};

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -58,8 +59,8 @@ struct envelope_one_point
>::apply(point, box_corner);
}
template <typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
template <typename Point, typename Box, typename Strategy>
static inline void apply(Point const& point, Box& mbr, Strategy const&)
{
apply<min_corner>(point, mbr);
apply<max_corner>(point, mbr);
@@ -69,8 +70,8 @@ struct envelope_one_point
struct envelope_point_on_spheroid
{
template<typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
template<typename Point, typename Box, typename Strategy>
static inline void apply(Point const& point, Box& mbr, Strategy const& strategy)
{
Point normalized_point = detail::return_normalized<Point>(point);
@@ -88,7 +89,7 @@ struct envelope_point_on_spheroid
envelope_one_point
<
2, dimension<Point>::value
>::apply(normalized_point, mbr);
>::apply(normalized_point, mbr, strategy);
}
};

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -51,8 +52,11 @@ namespace detail { namespace envelope
// implementation for simple ranges
struct envelope_range
{
template <typename Iterator, typename Box>
static inline void apply(Iterator first, Iterator last, Box& mbr)
template <typename Iterator, typename Box, typename Strategy>
static inline void apply(Iterator first,
Iterator last,
Box& mbr,
Strategy const& strategy)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
@@ -63,20 +67,20 @@ struct envelope_range
if (it != last)
{
// initialize box with first element in range
dispatch::envelope<value_type>::apply(*it, mbr);
dispatch::envelope<value_type>::apply(*it, mbr, strategy);
// consider now the remaining elements in the range (if any)
for (++it; it != last; ++it)
{
dispatch::expand<Box, value_type>::apply(mbr, *it);
dispatch::expand<Box, value_type>::apply(mbr, *it, strategy);
}
}
}
template <typename Range, typename Box>
static inline void apply(Range const& range, Box& mbr)
template <typename Range, typename Box, typename Strategy>
static inline void apply(Range const& range, Box& mbr, Strategy const& strategy)
{
return apply(boost::begin(range), boost::end(range), mbr);
return apply(boost::begin(range), boost::end(range), mbr, strategy);
}
};
@@ -85,8 +89,10 @@ struct envelope_range
template <typename EnvelopePolicy>
struct envelope_multi_range
{
template <typename MultiRange, typename Box>
static inline void apply(MultiRange const& multirange, Box& mbr)
template <typename MultiRange, typename Box, typename Strategy>
static inline void apply(MultiRange const& multirange,
Box& mbr,
Strategy const& strategy)
{
typedef typename boost::range_iterator
<
@@ -103,14 +109,14 @@ struct envelope_multi_range
if (initialized)
{
Box helper_mbr;
EnvelopePolicy::apply(*it, helper_mbr);
EnvelopePolicy::apply(*it, helper_mbr, strategy);
dispatch::expand<Box, Box>::apply(mbr, helper_mbr);
dispatch::expand<Box, Box>::apply(mbr, helper_mbr, strategy);
}
else
{
// compute the initial envelope
EnvelopePolicy::apply(*it, mbr);
EnvelopePolicy::apply(*it, mbr, strategy);
initialized = true;
}
}
@@ -129,8 +135,10 @@ struct envelope_multi_range
template <typename EnvelopePolicy>
struct envelope_multi_range_on_spheroid
{
template <typename MultiRange, typename Box>
static inline void apply(MultiRange const& multirange, Box& mbr)
template <typename MultiRange, typename Box, typename Strategy>
static inline void apply(MultiRange const& multirange,
Box& mbr,
Strategy const& strategy)
{
typedef typename boost::range_iterator
<
@@ -147,7 +155,7 @@ struct envelope_multi_range_on_spheroid
if (! geometry::is_empty(*it))
{
Box helper_box;
EnvelopePolicy::apply(*it, helper_box);
EnvelopePolicy::apply(*it, helper_box, strategy);
boxes.push_back(helper_box);
}
}
@@ -159,7 +167,7 @@ struct envelope_multi_range_on_spheroid
// and the MBR is simply initialized
if (! boxes.empty())
{
envelope_range_of_boxes::apply(boxes, mbr);
envelope_range_of_boxes::apply(boxes, mbr, strategy);
}
else
{

View File

@@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015, Oracle and/or its affiliates.
// Copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -149,8 +150,10 @@ struct envelope_range_of_longitudes
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_range_of_boxes_by_expansion
{
template <typename RangeOfBoxes, typename Box>
static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
template <typename RangeOfBoxes, typename Box, typename Strategy>
static inline void apply(RangeOfBoxes const& range_of_boxes,
Box& mbr,
Strategy const& strategy)
{
typedef typename boost::range_value<RangeOfBoxes>::type box_type;
@@ -196,7 +199,7 @@ struct envelope_range_of_boxes_by_expansion
min_corner,
Dimension,
DimensionCount
>::apply(mbr, *it);
>::apply(mbr, *it, strategy);
detail::expand::indexed_loop
<
@@ -205,7 +208,7 @@ struct envelope_range_of_boxes_by_expansion
max_corner,
Dimension,
DimensionCount
>::apply(mbr, *it);
>::apply(mbr, *it, strategy);
}
}
@@ -225,8 +228,10 @@ struct envelope_range_of_boxes
}
};
template <typename RangeOfBoxes, typename Box>
static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
template <typename RangeOfBoxes, typename Box, typename Strategy>
static inline void apply(RangeOfBoxes const& range_of_boxes,
Box& mbr,
Strategy const& strategy)
{
// boxes in the range are assumed to be normalized already
@@ -313,7 +318,7 @@ struct envelope_range_of_boxes
envelope_range_of_boxes_by_expansion
<
2, dimension<Box>::value
>::apply(range_of_boxes, mbr);
>::apply(range_of_boxes, mbr, strategy);
}
};

View File

@@ -4,9 +4,10 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -26,6 +27,7 @@
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -34,10 +36,9 @@
#include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/formulas/vertex_latitude.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/point.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
@@ -46,7 +47,6 @@
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
namespace boost { namespace geometry
{
@@ -54,63 +54,36 @@ namespace boost { namespace geometry
namespace detail { namespace envelope
{
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_one_segment
template <typename CalculationType, typename CS_Tag>
struct envelope_segment_call_vertex_latitude
{
template<typename Point, typename Box>
static inline void apply(Point const& p1, Point const& p2, Box& mbr)
template <typename T1, typename T2, typename Strategy>
static inline CalculationType apply(T1 const& lat1,
T2 const& alp1,
Strategy const& )
{
envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr);
detail::expand::point_loop
<
strategy::compare::default_strategy,
strategy::compare::default_strategy,
Dimension,
DimensionCount
>::apply(mbr, p2);
return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
::apply(lat1, alp1);
}
};
template <typename CalculationType>
struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
{
template <typename T1, typename T2, typename Strategy>
static inline CalculationType apply(T1 const& lat1,
T2 const& alp1,
Strategy const& strategy)
{
return geometry::formula::vertex_latitude<CalculationType, geographic_tag>
::apply(lat1, alp1, strategy.model());
}
};
// Computes the MBR of a segment given by (lon1, lat1) and (lon2,
// lat2), and with azimuths a1 and a2 at the two endpoints of the
// segment.
// It is assumed that the spherical coordinates of the segment are
// normalized and in radians.
// The longitudes and latitudes of the endpoints are overridden by
// those of the box.
class compute_mbr_of_segment
template <typename CS_Tag>
class envelope_segment_impl
{
private:
// computes the azimuths of the segment with endpoints (lon1, lat1)
// and (lon2, lat2)
// radians
template <typename CalculationType>
static inline void azimuths(CalculationType const& lon1,
CalculationType const& lat1,
CalculationType const& lon2,
CalculationType const& lat2,
CalculationType& a1,
CalculationType& a2)
{
BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
CalculationType dlon = lon2 - lon1;
CalculationType sin_dlon = sin(dlon);
CalculationType cos_dlon = cos(dlon);
CalculationType cos_lat1 = cos(lat1);
CalculationType cos_lat2 = cos(lat2);
CalculationType sin_lat1 = sin(lat1);
CalculationType sin_lat2 = sin(lat2);
a1 = atan2(sin_dlon * cos_lat2,
cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon);
a2 = atan2(-sin_dlon * cos_lat1,
cos_lat2 * sin_lat1 - sin_lat2 * cos_lat1 * cos_dlon);
a2 += math::pi<CalculationType>();
}
// degrees or radians
template <typename CalculationType>
@@ -134,8 +107,8 @@ private:
static CalculationType const pi_half = math::half_pi<CalculationType>();
return (a1 < a2)
? (a1 < pi_half && pi_half < a2)
: (a1 > pi_half && pi_half > a2);
? (a1 < pi_half && pi_half < a2)
: (a1 > pi_half && pi_half > a2);
}
// radians or degrees
@@ -151,21 +124,13 @@ private:
return math::abs(lon1 - lon2) > constants::half_period(); // > pi
}
// radians
template <typename CalculationType>
static inline CalculationType max_latitude(CalculationType const& azimuth,
CalculationType const& latitude)
{
// azimuth and latitude are assumed to be in radians
return acos( math::abs(cos(latitude) * sin(azimuth)) );
}
// degrees or radians
template <typename Units, typename CalculationType>
template <typename Units, typename CalculationType, typename Strategy>
static inline void compute_box_corners(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2)
CalculationType& lat2,
Strategy const& strategy)
{
// coordinates are assumed to be in radians
BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
@@ -175,13 +140,14 @@ private:
CalculationType lon2_rad = math::as_radian<Units>(lon2);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
CalculationType a1 = 0, a2 = 0;
azimuths(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2);
CalculationType a1, a2;
strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2);
if (lat1 > lat2)
{
std::swap(lat1, lat2);
std::swap(lat1_rad, lat2_rad);
std::swap(a1, a2);
}
if (math::equals(a1, a2))
@@ -192,12 +158,16 @@ private:
if (contains_pi_half(a1, a2))
{
CalculationType p_max = envelope_segment_call_vertex_latitude
<CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy);
CalculationType const mid_lat = lat1 + lat2;
if (mid_lat < 0)
{
// update using min latitude
CalculationType const lat_min_rad = -max_latitude(a1, lat1_rad);
CalculationType const lat_min = math::from_radian<Units>(lat_min_rad);
CalculationType const lat_min_rad = -p_max;
CalculationType const lat_min
= math::from_radian<Units>(lat_min_rad);
if (lat1 > lat_min)
{
@@ -207,8 +177,9 @@ private:
else if (mid_lat > 0)
{
// update using max latitude
CalculationType const lat_max_rad = max_latitude(a1, lat1_rad);
CalculationType const lat_max = math::from_radian<Units>(lat_max_rad);
CalculationType const lat_max_rad = p_max;
CalculationType const lat_max
= math::from_radian<Units>(lat_max_rad);
if (lat2 < lat_max)
{
@@ -218,11 +189,12 @@ private:
}
}
template <typename Units, typename CalculationType>
template <typename Units, typename CalculationType, typename Strategy>
static inline void apply(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2)
CalculationType& lat2,
Strategy const& strategy)
{
typedef math::detail::constants_on_spheroid
<
@@ -278,16 +250,22 @@ private:
swap(lon1, lat1, lon2, lat2);
}
compute_box_corners<Units>(lon1, lat1, lon2, lat2);
compute_box_corners<Units>(lon1, lat1, lon2, lat2, strategy);
}
public:
template <typename Units, typename CalculationType, typename Box>
template <
typename Units,
typename CalculationType,
typename Box,
typename Strategy
>
static inline void apply(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
Box& mbr)
Box& mbr,
Strategy const& strategy)
{
typedef typename coordinate_type<Box>::type box_coordinate_type;
@@ -298,7 +276,7 @@ public:
helper_box_type radian_mbr;
apply<Units>(lon1, lat1, lon2, lat2);
apply<Units>(lon1, lat1, lon2, lat2, strategy);
geometry::set
<
@@ -324,29 +302,42 @@ public:
}
};
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_one_segment
{
template<typename Point, typename Box, typename Strategy>
static inline void apply(Point const& p1,
Point const& p2,
Box& mbr,
Strategy const& strategy)
{
envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr, strategy);
detail::expand::point_loop
<
strategy::compare::default_strategy,
strategy::compare::default_strategy,
Dimension,
DimensionCount
>::apply(mbr, p2, strategy);
}
};
template <std::size_t DimensionCount>
struct envelope_segment_on_sphere
struct envelope_segment
{
template <typename Point, typename Box>
static inline void apply(Point const& p1, Point const& p2, Box& mbr)
template <typename Point, typename Box, typename Strategy>
static inline void apply(Point const& p1,
Point const& p2,
Box& mbr,
Strategy const& strategy)
{
// first compute the envelope range for the first two coordinates
Point p1_normalized = detail::return_normalized<Point>(p1);
Point p2_normalized = detail::return_normalized<Point>(p2);
typedef typename coordinate_system<Point>::type::units units_type;
compute_mbr_of_segment::template apply<units_type>(
geometry::get<0>(p1_normalized),
geometry::get<1>(p1_normalized),
geometry::get<0>(p2_normalized),
geometry::get<1>(p2_normalized),
mbr);
strategy.apply(p1, p2, mbr);
// now compute the envelope range for coordinates of
// dimension 2 and higher
envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr);
envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy);
}
template <typename Segment, typename Box>
@@ -359,21 +350,6 @@ struct envelope_segment_on_sphere
}
};
template <std::size_t DimensionCount, typename CS_Tag>
struct envelope_segment
: envelope_one_segment<0, DimensionCount>
{};
template <std::size_t DimensionCount>
struct envelope_segment<DimensionCount, spherical_equatorial_tag>
: envelope_segment_on_sphere<DimensionCount>
{};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
@@ -383,23 +359,24 @@ namespace dispatch
{
template <typename Segment, typename CS_Tag>
struct envelope<Segment, segment_tag, CS_Tag>
template <typename Segment>
struct envelope<Segment, segment_tag>
{
template <typename Box>
static inline void apply(Segment const& segment, Box& mbr)
template <typename Box, typename Strategy>
static inline void apply(Segment const& segment,
Box& mbr,
Strategy const& strategy)
{
typename point_type<Segment>::type p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
detail::envelope::envelope_segment
<
dimension<Segment>::value, CS_Tag
>::apply(p[0], p[1], mbr);
dimension<Segment>::value
>::apply(p[0], p[1], mbr, strategy);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -5,6 +5,11 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -20,6 +25,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -32,21 +38,35 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>
namespace boost { namespace geometry
{
// TODO: dispatch only by SideStrategy instead of Geometry/CSTag?
// Since these vectors (though ray would be a better name) are used in the
// implementation of equals() for Areal geometries the internal representation
// should be consistent with the default side strategy for CS because currently
// it's used in other relops.
template <
// should be consistent with the side strategy.
template
<
typename T,
typename Geometry,
typename SideStrategy,
typename CSTag = typename cs_tag<Geometry>::type
>
struct collected_vector
: nyi::not_implemented_tag
{};
// compatible with side_by_triangle cartesian strategy
template <typename T, typename Geometry, typename CT, typename CSTag>
struct collected_vector
<
T, Geometry, strategy::side::side_by_triangle<CT>, CSTag
>
{
typedef T type;
@@ -136,8 +156,13 @@ private:
//T dx_0, dy_0;
};
template <typename T, typename Geometry>
struct collected_vector<T, Geometry, spherical_equatorial_tag>
// Compatible with spherical_side_formula which currently
// is the default spherical and geographical strategy
template <typename T, typename Geometry, typename CT, typename CSTag>
struct collected_vector
<
T, Geometry, strategy::side::spherical_side_formula<CT>, CSTag
>
{
typedef T type;
@@ -232,11 +257,27 @@ private:
vector_type next; // used for collinearity check
};
template <typename T, typename Geometry>
struct collected_vector<T, Geometry, spherical_polar_tag>
: public collected_vector<T, Geometry, spherical_equatorial_tag>
// Specialization for spherical polar
template <typename T, typename Geometry, typename CT>
struct collected_vector
<
T, Geometry,
strategy::side::spherical_side_formula<CT>,
spherical_polar_tag
>
: public collected_vector
<
T, Geometry,
strategy::side::spherical_side_formula<CT>,
spherical_equatorial_tag
>
{
typedef collected_vector<T, Geometry, spherical_equatorial_tag> base_type;
typedef collected_vector
<
T, Geometry,
strategy::side::spherical_side_formula<CT>,
spherical_equatorial_tag
> base_type;
collected_vector() {}
@@ -265,24 +306,6 @@ private:
}
};
// This is consistent with the currently used default geographic side
// and intersection strategies. Spherical strategies are used by default.
// When default strategies are changed in the future this specialization
// should be changed too.
template <typename T, typename Geometry>
struct collected_vector<T, Geometry, geographic_tag>
: public collected_vector<T, Geometry, spherical_equatorial_tag>
{
typedef collected_vector<T, Geometry, spherical_equatorial_tag> base_type;
collected_vector() {}
template <typename Point>
collected_vector(Point const& p1, Point const& p2)
: base_type(p1, p2)
{}
};
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace collect_vectors

View File

@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -44,16 +45,18 @@ namespace detail { namespace expand
struct box_on_spheroid
{
template <typename BoxOut, typename BoxIn>
static inline void apply(BoxOut& box_out, BoxIn const& box_in)
template <typename BoxOut, typename BoxIn, typename Strategy>
static inline void apply(BoxOut& box_out,
BoxIn const& box_in,
Strategy const& strategy)
{
// normalize both boxes and convert box-in to be of type of box-out
BoxOut mbrs[2];
detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0]);
detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1]);
detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0], strategy);
detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1], strategy);
// compute the envelope of the two boxes
detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out);
detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out, strategy);
}
};

View File

@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -49,8 +50,8 @@ template
>
struct indexed_loop
{
template <typename Box, typename Geometry>
static inline void apply(Box& box, Geometry const& source)
template <typename Box, typename Geometry, typename Strategy>
static inline void apply(Box& box, Geometry const& source, Strategy const& strategy)
{
typedef typename strategy::compare::detail::select_strategy
<
@@ -87,7 +88,7 @@ struct indexed_loop
<
StrategyLess, StrategyGreater,
Index, Dimension + 1, DimensionCount
>::apply(box, source);
>::apply(box, source, strategy);
}
};
@@ -103,8 +104,8 @@ struct indexed_loop
Index, DimensionCount, DimensionCount
>
{
template <typename Box, typename Geometry>
static inline void apply(Box&, Geometry const&) {}
template <typename Box, typename Geometry, typename Strategy>
static inline void apply(Box&, Geometry const&, Strategy const&) {}
};
@@ -117,20 +118,22 @@ template
>
struct expand_indexed
{
template <typename Box, typename Geometry>
static inline void apply(Box& box, Geometry const& geometry)
template <typename Box, typename Geometry, typename Strategy>
static inline void apply(Box& box,
Geometry const& geometry,
Strategy const& strategy)
{
indexed_loop
<
StrategyLess, StrategyGreater,
0, Dimension, DimensionCount
>::apply(box, geometry);
>::apply(box, geometry, strategy);
indexed_loop
<
StrategyLess, StrategyGreater,
1, Dimension, DimensionCount
>::apply(box, geometry);
>::apply(box, geometry, strategy);
}
};

View File

@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -28,10 +29,50 @@
#include <boost/geometry/algorithms/dispatch/expand.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
namespace resolve_strategy
{
template <typename Geometry>
struct expand
{
template <typename Box, typename Strategy>
static inline void apply(Box& box,
Geometry const& geometry,
Strategy const& strategy)
{
dispatch::expand<Box, Geometry>::apply(box, geometry, strategy);
}
template <typename Box>
static inline void apply(Box& box,
Geometry const& geometry,
default_strategy)
{
typedef typename point_type<Geometry>::type point_type;
typedef typename coordinate_type<point_type>::type coordinate_type;
typedef typename strategy::envelope::services::default_strategy
<
typename cs_tag<point_type>::type,
coordinate_type
>::type strategy_type;
dispatch::expand<Box, Geometry>::apply(box, geometry, strategy_type());
}
};
} //namespace resolve_strategy
namespace resolve_variant
{
@@ -39,40 +80,48 @@ namespace resolve_variant
template <typename Geometry>
struct expand
{
template <typename Box>
static inline void apply(Box& box, Geometry const& geometry)
template <typename Box, typename Strategy>
static inline void apply(Box& box,
Geometry const& geometry,
Strategy const& strategy)
{
concepts::check<Box>();
concepts::check<Geometry const>();
concepts::check_concepts_and_equal_dimensions<Box, Geometry const>();
dispatch::expand<Box, Geometry>::apply(box, geometry);
resolve_strategy::expand<Geometry>::apply(box, geometry, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Box>
template <typename Box, typename Strategy>
struct visitor: boost::static_visitor<void>
{
Box& m_box;
Strategy const& m_strategy;
visitor(Box& box) : m_box(box) {}
visitor(Box& box, Strategy const& strategy)
: m_box(box)
, m_strategy(strategy)
{}
template <typename Geometry>
void operator()(Geometry const& geometry) const
{
return expand<Geometry>::apply(m_box, geometry);
return expand<Geometry>::apply(m_box, geometry, m_strategy);
}
};
template <class Box>
template <class Box, typename Strategy>
static inline void
apply(Box& box,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Box>(box), geometry);
return boost::apply_visitor(visitor<Box, Strategy>(box, strategy),
geometry);
}
};
@@ -106,21 +155,43 @@ inline void expand(Box& box, Geometry const& geometry,
}
***/
/*!
\brief Expands (with strategy)
\ingroup expand
\tparam Box type of the box
\tparam Geometry \tparam_geometry
\tparam Strategy \tparam_strategy{expand}
\param box box to be expanded using another geometry, mutable
\param geometry \param_geometry geometry which envelope (bounding box)
\param strategy \param_strategy{expand}
will be added to the box
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/expand.qbk]}
*/
template <typename Box, typename Geometry, typename Strategy>
inline void expand(Box& box, Geometry const& geometry, Strategy const& strategy)
{
resolve_variant::expand<Geometry>::apply(box, geometry, strategy);
}
/*!
\brief Expands a box using the bounding box (envelope) of another geometry (box, point)
\brief Expands a box using the bounding box (envelope) of another geometry
(box, point)
\ingroup expand
\tparam Box type of the box
\tparam Geometry \tparam_geometry
\param box box to be expanded using another geometry, mutable
\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
\param geometry \param_geometry geometry which envelope (bounding box) will be
added to the box
\qbk{[include reference/algorithms/expand.qbk]}
*/
template <typename Box, typename Geometry>
inline void expand(Box& box, Geometry const& geometry)
{
resolve_variant::expand<Geometry>::apply(box, geometry);
resolve_variant::expand<Geometry>::apply(box, geometry, default_strategy());
}
}} // namespace boost::geometry

View File

@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -59,8 +60,8 @@ template
>
struct point_loop
{
template <typename Box, typename Point>
static inline void apply(Box& box, Point const& source)
template <typename Box, typename Point, typename Strategy>
static inline void apply(Box& box, Point const& source, Strategy const& strategy)
{
typedef typename strategy::compare::detail::select_strategy
<
@@ -95,22 +96,24 @@ struct point_loop
point_loop
<
StrategyLess, StrategyGreater, Dimension + 1, DimensionCount
>::apply(box, source);
>::apply(box, source, strategy);
}
};
template
<
typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount
typename StrategyLess,
typename StrategyGreater,
std::size_t DimensionCount
>
struct point_loop
<
StrategyLess, StrategyGreater, DimensionCount, DimensionCount
>
{
template <typename Box, typename Point>
static inline void apply(Box&, Point const&) {}
template <typename Box, typename Point, typename Strategy>
static inline void apply(Box&, Point const&, Strategy const&) {}
};
@@ -123,8 +126,10 @@ template
>
struct point_loop_on_spheroid
{
template <typename Box, typename Point>
static inline void apply(Box& box, Point const& point)
template <typename Box, typename Point, typename Strategy>
static inline void apply(Box& box,
Point const& point,
Strategy const& strategy)
{
typedef typename point_type<Box>::type box_point_type;
typedef typename coordinate_type<Box>::type box_coordinate_type;
@@ -224,7 +229,7 @@ struct point_loop_on_spheroid
point_loop
<
StrategyLess, StrategyGreater, 2, DimensionCount
>::apply(box, point);
>::apply(box, point, strategy);
}
};

View File

@@ -5,9 +5,10 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
@@ -39,25 +40,29 @@ namespace boost { namespace geometry
namespace detail { namespace expand
{
struct segment_on_sphere
struct segment
{
template <typename Box, typename Segment>
static inline void apply(Box& box, Segment const& segment)
template <typename Box, typename Segment, typename Strategy>
static inline void apply(Box& box,
Segment const& segment,
Strategy const& strategy)
{
Box mbrs[2];
// compute the envelope of the segment
detail::envelope::envelope_segment_on_sphere
typename point_type<Segment>::type p[2];
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
detail::envelope::envelope_segment
<
dimension<Segment>::value
>::apply(segment, mbrs[0]);
>::apply(p[0], p[1], mbrs[0], strategy);
// normalize the box
detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1]);
detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1], strategy);
// compute the envelope of the two boxes
detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
detail::envelope::envelope_range_of_boxes::apply(mbrs, box, strategy);
}
};
@@ -69,7 +74,6 @@ struct segment_on_sphere
namespace dispatch
{
template
<
typename Box, typename Segment,
@@ -103,13 +107,27 @@ struct expand
StrategyLess, StrategyGreater,
box_tag, segment_tag,
spherical_equatorial_tag, spherical_equatorial_tag
> : detail::expand::segment_on_sphere
> : detail::expand::segment
{};
template
<
typename Box, typename Segment,
typename StrategyLess, typename StrategyGreater
>
struct expand
<
Box, Segment,
StrategyLess, StrategyGreater,
box_tag, segment_tag,
geographic_tag, geographic_tag
> : detail::expand::segment
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 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)
@@ -59,8 +63,9 @@ namespace detail { namespace overlay
{
template <typename Geometry, typename RobustPolicy>
template <typename Geometry, typename Strategy, typename RobustPolicy>
inline bool has_self_intersections(Geometry const& geometry,
Strategy const& strategy,
RobustPolicy const& robust_policy,
bool throw_on_self_intersection = true)
{
@@ -73,7 +78,7 @@ inline bool has_self_intersections(Geometry const& geometry,
std::deque<turn_info> turns;
detail::disjoint::disjoint_interrupt_policy policy;
geometry::self_turns<detail::overlay::assign_null_policy>(geometry, robust_policy, turns, policy);
geometry::self_turns<detail::overlay::assign_null_policy>(geometry, strategy, robust_policy, turns, policy);
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
bool first = true;
@@ -132,11 +137,16 @@ inline bool has_self_intersections(Geometry const& geometry,
typedef typename geometry::rescale_policy_type<point_type>::type
rescale_policy_type;
typename strategy::intersection::services::default_strategy
<
typename cs_tag<Geometry>::type
>::type strategy;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
return has_self_intersections(geometry, robust_policy,
throw_on_self_intersection);
return has_self_intersections(geometry, strategy, robust_policy,
throw_on_self_intersection);
}

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -51,10 +51,11 @@ struct intersection
typedef typename boost::range_value<GeometryOut>::type OneOut;
intersection_insert
<
Geometry1, Geometry2, OneOut,
overlay_intersection
>::apply(geometry1, geometry2, robust_policy, range::back_inserter(geometry_out), strategy);
<
Geometry1, Geometry2, OneOut,
overlay_intersection
>::apply(geometry1, geometry2, robust_policy,
range::back_inserter(geometry_out), strategy);
return true;
}
@@ -84,11 +85,12 @@ struct intersection
GeometryOut& out,
Strategy const& strategy)
{
return intersection<
Geometry2, Geometry1,
Tag2, Tag1,
false
>::apply(g2, g1, robust_policy, out, strategy);
return intersection
<
Geometry2, Geometry1,
Tag2, Tag1,
false
>::apply(g2, g1, robust_policy, out, strategy);
}
};
@@ -114,29 +116,26 @@ struct intersection
concepts::check<Geometry2 const>();
typedef typename geometry::rescale_overlay_policy_type
<
Geometry1,
Geometry2
>::type rescale_policy_type;
<
Geometry1,
Geometry2
>::type rescale_policy_type;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1,
geometry2);
typedef intersection_strategies
<
typename cs_tag<Geometry1>::type,
Geometry1,
Geometry2,
typename geometry::point_type<Geometry1>::type,
rescale_policy_type
> strategy;
typedef typename strategy::relate::services::default_strategy
<
Geometry1, Geometry2
>::type strategy_type;
return dispatch::intersection
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, robust_policy, geometry_out, strategy());
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, robust_policy, geometry_out,
strategy_type());
}
};

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -48,6 +49,8 @@
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
#include <boost/geometry/strategies/intersection.hpp>
namespace boost { namespace geometry
{
@@ -214,10 +217,16 @@ inline bool has_self_intersections(Linear const& linear)
is_acceptable_turn<Linear>
> interrupt_policy(predicate);
typedef typename strategy::intersection::services::default_strategy
<
typename cs_tag<Linear>::type
>::type strategy_type;
detail::self_get_turn_points::get_turns
<
turn_policy
>::apply(linear,
strategy_type(),
detail::no_rescale_policy(),
turns,
interrupt_policy);

View File

@@ -1,8 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@@ -47,6 +48,11 @@ class has_valid_self_turns
private:
typedef typename point_type<Geometry>::type point_type;
typedef typename strategy::intersection::services::default_strategy
<
typename cs_tag<Geometry>::type
>::type intersection_strategy_type;
typedef typename geometry::rescale_policy_type
<
point_type
@@ -76,6 +82,8 @@ public:
{
boost::ignore_unused(visitor);
intersection_strategy_type intersection_strategy;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry);
@@ -85,6 +93,7 @@ public:
> interrupt_policy;
geometry::self_turns<turn_policy>(geometry,
intersection_strategy,
robust_policy,
turns,
interrupt_policy);

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -43,6 +43,8 @@
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/strategies/intersection.hpp>
namespace boost { namespace geometry
{
@@ -109,10 +111,10 @@ private:
geometry::partition
<
geometry::model::box<typename point_type<MultiPolygon>::type>,
typename base::expand_box,
typename base::overlaps_box
>::apply(polygon_iterators, item_visitor);
geometry::model::box<typename point_type<MultiPolygon>::type>
>::apply(polygon_iterators, item_visitor,
typename base::expand_box(),
typename base::overlaps_box());
if (item_visitor.items_overlap)
{

View File

@@ -246,10 +246,8 @@ protected:
geometry::partition
<
geometry::model::box<typename point_type<Polygon>::type>,
expand_box,
overlaps_box
>::apply(ring_iterators, item_visitor);
geometry::model::box<typename point_type<Polygon>::type>
>::apply(ring_iterators, item_visitor, expand_box(), overlaps_box());
if (item_visitor.items_overlap)
{

View File

@@ -4,10 +4,11 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -46,6 +47,14 @@ struct not_
{
return ! Policy::apply(geometry1, geometry2);
}
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return ! Policy::apply(geometry1, geometry2, strategy);
}
};

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 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)
@@ -258,8 +262,9 @@ inline void assign_parents(Geometry1 const& geometry1,
geometry::partition
<
box_type, ring_info_helper_get_box, ring_info_helper_ovelaps_box
>::apply(vector, visitor);
box_type
>::apply(vector, visitor, ring_info_helper_get_box(),
ring_info_helper_ovelaps_box());
}
if (check_for_orientation)

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, 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)
@@ -106,19 +110,27 @@ class backtrack_check_self_intersections
public :
typedef state state_type;
template <typename Operation, typename Rings, typename Ring, typename Turns, typename RobustPolicy, typename Visitor>
template
<
typename Operation,
typename Rings, typename Ring, typename Turns,
typename Strategy,
typename RobustPolicy,
typename Visitor
>
static inline void apply(std::size_t size_at_start,
Rings& rings, Ring& ring,
Turns& turns,
typename boost::range_value<Turns>::type const& turn,
Operation& operation,
traverse_error_type traverse_error,
Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
state_type& state,
Visitor& visitor
)
Rings& rings,
Ring& ring,
Turns& turns,
typename boost::range_value<Turns>::type const& turn,
Operation& operation,
traverse_error_type traverse_error,
Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy,
RobustPolicy const& robust_policy,
state_type& state,
Visitor& visitor)
{
visitor.visit_traverse_reject(turns, turn, operation, traverse_error);
@@ -128,8 +140,8 @@ public :
if (! state.m_checked)
{
state.m_checked = true;
has_self_intersections(geometry1, robust_policy);
has_self_intersections(geometry2, robust_policy);
has_self_intersections(geometry1, strategy, robust_policy);
has_self_intersections(geometry2, strategy, robust_policy);
}
// Make bad output clean

View File

@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 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)
@@ -39,29 +44,33 @@ template
>
struct get_turn_without_info
{
template <typename RobustPolicy, typename OutputIterator>
template <typename Strategy, typename RobustPolicy, typename OutputIterator>
static inline OutputIterator apply(
Point1 const& pi, Point1 const& pj, Point1 const& /*pk*/,
Point2 const& qi, Point2 const& qj, Point2 const& /*qk*/,
bool /*is_p_first*/, bool /*is_p_last*/,
bool /*is_q_first*/, bool /*is_q_last*/,
TurnInfo const& ,
Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
typedef intersection_strategies
<
typename cs_tag<typename TurnInfo::point_type>::type,
Point1,
Point2,
typename TurnInfo::point_type,
RobustPolicy
> si;
typedef typename TurnInfo::point_type turn_point_type;
typedef typename si::segment_intersection_strategy_type strategy;
typedef policies::relate::segments_intersection_points
<
segment_intersection_points
<
turn_point_type,
typename geometry::segment_ratio_type
<
turn_point_type, RobustPolicy
>::type
>
> policy_type;
typedef model::referring_segment<Point1 const> segment_type1;
typedef model::referring_segment<Point1 const> segment_type2;
typedef model::referring_segment<Point2 const> segment_type2;
segment_type1 p1(pi, pj);
segment_type2 q1(qi, qj);
@@ -75,15 +84,14 @@ struct get_turn_without_info
geometry::recalculate(pj_rob, pj, robust_policy);
geometry::recalculate(qi_rob, qi, robust_policy);
geometry::recalculate(qj_rob, qj, robust_policy);
typename strategy::return_type result
= strategy::apply(p1, q1, robust_policy,
pi_rob, pj_rob, qi_rob, qj_rob);
typename policy_type::return_type result
= strategy.apply(p1, q1, policy_type(), robust_policy,
pi_rob, pj_rob, qi_rob, qj_rob);
for (std::size_t i = 0; i < result.template get<0>().count; i++)
for (std::size_t i = 0; i < result.count; i++)
{
TurnInfo tp;
geometry::convert(result.template get<0>().intersections[i], tp.point);
geometry::convert(result.intersections[i], tp.point);
*out++ = tp;
}
@@ -102,12 +110,14 @@ template
typename Geometry1,
typename Geometry2,
typename RobustPolicy,
typename Turns
typename Turns,
typename Strategy
>
inline void get_intersection_points(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
Turns& turns)
Turns& turns,
Strategy const& strategy)
{
concepts::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
@@ -142,6 +152,7 @@ inline void get_intersection_points(Geometry1 const& geometry1,
>::type::apply(
0, geometry1,
1, geometry2,
strategy,
robust_policy,
turns, interrupt_policy);
}

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -19,7 +19,6 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/intersection_strategies.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -930,6 +929,7 @@ struct get_turn_info
typename Point1,
typename Point2,
typename TurnInfo,
typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
@@ -939,13 +939,19 @@ struct get_turn_info
bool /*is_p_first*/, bool /*is_p_last*/,
bool /*is_q_first*/, bool /*is_q_last*/,
TurnInfo const& tp_model,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
inters_info;
typedef intersection_info
<
Point1, Point2,
typename TurnInfo::point_type,
IntersectionStrategy,
RobustPolicy
> inters_info;
inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy);
char const method = inters.d_info().how;
@@ -991,9 +997,12 @@ struct get_turn_info
<
typename inters_info::cs_tag,
typename inters_info::robust_point2_type,
typename inters_info::robust_point1_type
typename inters_info::robust_point1_type,
typename inters_info::side_strategy_type
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
inters.rpi(), inters.rpj(), inters.rpk());
inters.rpi(), inters.rpj(), inters.rpk(),
inters.get_side_strategy());
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
tp, inters.i_info(), inters.d_info(),
swapped_side_calc);

View File

@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014.
// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 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)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
@@ -427,8 +427,11 @@ struct get_turn_info_for_endpoint
}
else if ( ip_j2 )
{
side_calculator<cs_tag, RobustPoint1, RobustPoint2, RobustPoint2>
side_calc(ri2, ri1, rj1, ri2, rj2, rk2);
side_calculator<cs_tag,
RobustPoint1, RobustPoint2,
typename IntersectionInfo::side_strategy_type,
RobustPoint2>
side_calc(ri2, ri1, rj1, ri2, rj2, rk2, inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = operations_of_equal(side_calc);
@@ -478,8 +481,10 @@ struct get_turn_info_for_endpoint
}
else if ( ip_j2 )
{
side_calculator<cs_tag, RobustPoint1, RobustPoint2, RobustPoint2>
side_calc(ri2, rj1, ri1, ri2, rj2, rk2);
side_calculator<cs_tag, RobustPoint1, RobustPoint2,
typename IntersectionInfo::side_strategy_type,
RobustPoint2>
side_calc(ri2, rj1, ri1, ri2, rj2, rk2, inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = operations_of_equal(side_calc);

View File

@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 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)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
@@ -37,32 +37,27 @@ struct turn_operation_linear
};
template <typename TurnPointCSTag, typename PointP, typename PointQ,
typename SideStrategy,
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
>
struct side_calculator
{
// This strategy should be the same as side strategy defined in
// intersection_strategies<> which is used in various places
// of the library
typedef typename strategy::side::services::default_strategy
<
TurnPointCSTag
>::type side;
inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
Qi const& qi, Qj const& qj, Qk const& qk)
Qi const& qi, Qj const& qj, Qk const& qk,
SideStrategy const& side_strategy)
: m_pi(pi), m_pj(pj), m_pk(pk)
, m_qi(qi), m_qj(qj), m_qk(qk)
, m_side_strategy(side_strategy)
{}
inline int pk_wrt_p1() const { return side::apply(m_pi, m_pj, m_pk); }
inline int pk_wrt_q1() const { return side::apply(m_qi, m_qj, m_pk); }
inline int qk_wrt_p1() const { return side::apply(m_pi, m_pj, m_qk); }
inline int qk_wrt_q1() const { return side::apply(m_qi, m_qj, m_qk); }
inline int pk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_pk); }
inline int pk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_pk); }
inline int qk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_qk); }
inline int qk_wrt_q1() const { return m_side_strategy.apply(m_qi, m_qj, m_qk); }
inline int pk_wrt_q2() const { return side::apply(m_qj, m_qk, m_pk); }
inline int qk_wrt_p2() const { return side::apply(m_pj, m_pk, m_qk); }
inline int pk_wrt_q2() const { return m_side_strategy.apply(m_qj, m_qk, m_pk); }
inline int qk_wrt_p2() const { return m_side_strategy.apply(m_pj, m_pk, m_qk); }
Pi const& m_pi;
Pj const& m_pj;
@@ -70,6 +65,8 @@ struct side_calculator
Qi const& m_qi;
Qj const& m_qj;
Qk const& m_qk;
SideStrategy const& m_side_strategy;
};
template <typename Point1, typename Point2, typename RobustPolicy>
@@ -99,7 +96,7 @@ struct robust_points
robust_point2_type m_rqi, m_rqj, m_rqk;
};
template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
template <typename Point1, typename Point2, typename TurnPoint, typename IntersectionStrategy, typename RobustPolicy>
class intersection_info_base
: private robust_points<Point1, Point2, RobustPolicy>
{
@@ -114,14 +111,17 @@ public:
typedef typename cs_tag<TurnPoint>::type cs_tag;
typedef side_calculator<cs_tag, robust_point1_type, robust_point2_type> side_calculator_type;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
typedef side_calculator<cs_tag, robust_point1_type, robust_point2_type, side_strategy_type> side_calculator_type;
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
: base(pi, pj, pk, qi, qj, qk, robust_policy)
, m_side_calc(base::m_rpi, base::m_rpj, base::m_rpk,
base::m_rqi, base::m_rqj, base::m_rqk)
base::m_rqi, base::m_rqj, base::m_rqk,
intersection_strategy.get_side_strategy())
, m_pi(pi), m_pj(pj), m_pk(pk)
, m_qi(qi), m_qj(qj), m_qk(qk)
{}
@@ -155,8 +155,8 @@ private:
point2_type const& m_qk;
};
template <typename Point1, typename Point2, typename TurnPoint>
class intersection_info_base<Point1, Point2, TurnPoint, detail::no_rescale_policy>
template <typename Point1, typename Point2, typename TurnPoint, typename IntersectionStrategy>
class intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, detail::no_rescale_policy>
{
public:
typedef Point1 point1_type;
@@ -167,12 +167,15 @@ public:
typedef typename cs_tag<TurnPoint>::type cs_tag;
typedef side_calculator<cs_tag, Point1, Point2> side_calculator_type;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
typedef side_calculator<cs_tag, Point1, Point2, side_strategy_type> side_calculator_type;
intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
IntersectionStrategy const& intersection_strategy,
no_rescale_policy const& /*robust_policy*/)
: m_side_calc(pi, pj, pk, qi, qj, qk)
: m_side_calc(pi, pj, pk, qi, qj, qk,
intersection_strategy.get_side_strategy())
{}
inline Point1 const& pi() const { return m_side_calc.m_pi; }
@@ -203,40 +206,58 @@ template
typename Point1,
typename Point2,
typename TurnPoint,
typename IntersectionStrategy,
typename RobustPolicy
>
class intersection_info
: public intersection_info_base<Point1, Point2, TurnPoint, RobustPolicy>
: public intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, RobustPolicy>
{
typedef intersection_info_base<Point1, Point2, TurnPoint, RobustPolicy> base;
typedef typename intersection_strategies
<
typename base::cs_tag,
Point1,
Point2,
TurnPoint,
RobustPolicy
>::segment_intersection_strategy_type strategy;
typedef intersection_info_base<Point1, Point2, TurnPoint, IntersectionStrategy, RobustPolicy> base;
public:
typedef segment_intersection_points
<
TurnPoint,
typename geometry::segment_ratio_type
<
TurnPoint, RobustPolicy
>::type
> intersection_point_type;
// NOTE: formerly defined in intersection_strategies
typedef policies::relate::segments_tupled
<
policies::relate::segments_intersection_points
<
intersection_point_type
>,
policies::relate::segments_direction
> intersection_policy_type;
typedef IntersectionStrategy intersection_strategy_type;
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
typedef model::referring_segment<Point1 const> segment_type1;
typedef model::referring_segment<Point2 const> segment_type2;
typedef typename base::side_calculator_type side_calculator_type;
typedef typename strategy::return_type result_type;
typedef typename intersection_policy_type::return_type result_type;
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
Point2 const& qi, Point2 const& qj, Point2 const& qk,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
: base(pi, pj, pk, qi, qj, qk, robust_policy)
, m_result(strategy::apply(segment_type1(pi, pj),
segment_type2(qi, qj),
robust_policy,
base::rpi(), base::rpj(),
base::rqi(), base::rqj()))
: base(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy)
, m_result(intersection_strategy.apply(
segment_type1(pi, pj),
segment_type2(qi, qj),
intersection_policy_type(),
robust_policy,
base::rpi(), base::rpj(),
base::rqi(), base::rqj()))
, m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
{}
@@ -244,6 +265,16 @@ public:
inline i_info_type const& i_info() const { return m_result.template get<0>(); }
inline d_info_type const& d_info() const { return m_result.template get<1>(); }
inline intersection_strategy_type const& get_intersection_strategy() const
{
return m_intersection_strategy;
}
inline side_strategy_type get_side_strategy() const
{
return m_intersection_strategy.get_side_strategy();
}
// TODO: it's more like is_spike_ip_p
inline bool is_spike_p() const
{
@@ -307,17 +338,18 @@ private:
{
typedef model::referring_segment<Point const> seg;
typedef intersection_strategies
<
typename base::cs_tag, Point, Point, Point, RobustPolicy
> si;
// no need to calcualte direction info
typedef policies::relate::segments_intersection_points
<
intersection_point_type
> policy_type;
typename policy_type::return_type const result
= m_intersection_strategy.apply(seg(i, j), seg(j, k),
policy_type(),
m_robust_policy);
typedef typename si::segment_intersection_strategy_type strategy;
typename strategy::return_type result
= strategy::apply(seg(i, j), seg(j, k), m_robust_policy);
return result.template get<0>().count == 2;
return result.count == 2;
}
template <std::size_t OpId>
@@ -344,6 +376,7 @@ private:
}
result_type m_result;
IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
};

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -41,6 +41,7 @@ struct get_turn_info_linear_areal
typename Point1,
typename Point2,
typename TurnInfo,
typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
@@ -50,13 +51,19 @@ struct get_turn_info_linear_areal
bool is_p_first, bool is_p_last,
bool is_q_first, bool is_q_last,
TurnInfo const& tp_model,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
inters_info;
typedef intersection_info
<
Point1, Point2,
typename TurnInfo::point_type,
IntersectionStrategy,
RobustPolicy
> inters_info;
inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy);
char const method = inters.d_info().how;
@@ -108,9 +115,11 @@ struct get_turn_info_linear_areal
<
typename inters_info::cs_tag,
typename inters_info::robust_point2_type,
typename inters_info::robust_point1_type
typename inters_info::robust_point1_type,
typename inters_info::side_strategy_type
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
inters.rpi(), inters.rpj(), inters.rpk());
inters.rpi(), inters.rpj(), inters.rpk(),
inters.get_side_strategy());
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
tp, inters.i_info(), inters.d_info(),
swapped_side_calc);
@@ -747,6 +756,9 @@ struct get_turn_info_linear_areal
}
else
{
typedef typename IntersectionInfo::robust_point1_type rp1_type;
typedef typename IntersectionInfo::robust_point2_type rp2_type;
method_type replaced_method = method_touch_interior;
if ( ip0.is_qj )
@@ -754,11 +766,12 @@ struct get_turn_info_linear_areal
side_calculator
<
typename IntersectionInfo::cs_tag,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point2_type,
typename IntersectionInfo::robust_point2_type
rp1_type, rp2_type,
typename IntersectionInfo::side_strategy_type,
rp2_type
> side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
inters.rqi(), inters.rqj(), inters.rqk());
inters.rqi(), inters.rqj(), inters.rqk(),
inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
@@ -773,16 +786,13 @@ struct get_turn_info_linear_areal
side_calculator
<
typename IntersectionInfo::cs_tag,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point2_type,
typename IntersectionInfo::robust_point2_type,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point2_type,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point2_type
rp1_type, rp2_type,
typename IntersectionInfo::side_strategy_type,
rp2_type, rp1_type, rp1_type,
rp2_type, rp1_type, rp2_type
> side_calc(inters.rqi(), inters.rpi(), inters.rpj(),
inters.rqi(), inters.rpi(), inters.rqj());
inters.rqi(), inters.rpi(), inters.rqj(),
inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
@@ -832,9 +842,11 @@ struct get_turn_info_linear_areal
typename IntersectionInfo::cs_tag,
typename IntersectionInfo::robust_point1_type,
typename IntersectionInfo::robust_point2_type,
typename IntersectionInfo::side_strategy_type,
typename IntersectionInfo::robust_point2_type
> side_calc(inters.rqi(), inters.rpj(), inters.rpi(),
inters.rqi(), inters.rqj(), inters.rqk());
inters.rqi(), inters.rqj(), inters.rqk(),
inters.get_side_strategy());
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);

View File

@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 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)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_LL_HPP
@@ -36,6 +36,7 @@ struct get_turn_info_linear_linear
typename Point1,
typename Point2,
typename TurnInfo,
typename IntersectionStrategy,
typename RobustPolicy,
typename OutputIterator
>
@@ -45,13 +46,19 @@ struct get_turn_info_linear_linear
bool is_p_first, bool is_p_last,
bool is_q_first, bool is_q_last,
TurnInfo const& tp_model,
IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
inters_info;
typedef intersection_info
<
Point1, Point2,
typename TurnInfo::point_type,
IntersectionStrategy,
RobustPolicy
> inters_info;
inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy);
inters_info inters(pi, pj, pk, qi, qj, qk, strategy, robust_policy);
char const method = inters.d_info().how;
@@ -103,9 +110,11 @@ struct get_turn_info_linear_linear
<
typename inters_info::cs_tag,
typename inters_info::robust_point2_type,
typename inters_info::robust_point1_type
typename inters_info::robust_point1_type,
typename inters_info::side_strategy_type
> swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(),
inters.rpi(), inters.rpj(), inters.rpk());
inters.rpi(), inters.rpj(), inters.rpk(),
inters.get_side_strategy());
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
tp, inters.i_info(), inters.d_info(),

View File

@@ -3,15 +3,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2016.
// Modifications copyright (c) 2014, 2016 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2016, 2017.
// Modifications copyright (c) 2014-2017 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)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
@@ -174,11 +174,12 @@ class get_turns_in_sections
public :
// Returns true if terminated, false if interrupted
template <typename Turns, typename RobustPolicy, typename InterruptPolicy>
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline bool apply(
int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
bool skip_larger,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
@@ -295,7 +296,8 @@ public :
TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
is_1_first, is_1_last, is_2_first, is_2_last,
ti, robust_policy, std::back_inserter(turns));
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
if (InterruptPolicy::enabled)
{
@@ -381,9 +383,10 @@ template
<
typename Geometry1, typename Geometry2,
bool Reverse1, bool Reverse2,
typename Turns,
typename TurnPolicy,
typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename InterruptPolicy
>
struct section_visitor
@@ -392,16 +395,20 @@ struct section_visitor
Geometry1 const& m_geometry1;
int m_source_id2;
Geometry2 const& m_geometry2;
IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_rescale_policy;
Turns& m_turns;
InterruptPolicy& m_interrupt_policy;
section_visitor(int id1, Geometry1 const& g1,
int id2, Geometry2 const& g2,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& ip)
int id2, Geometry2 const& g2,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& ip)
: m_source_id1(id1), m_geometry1(g1)
, m_source_id2(id2), m_geometry2(g2)
, m_intersection_strategy(intersection_strategy)
, m_rescale_policy(robust_policy)
, m_turns(turns)
, m_interrupt_policy(ip)
@@ -423,6 +430,7 @@ struct section_visitor
m_source_id1, m_geometry1, sec1,
m_source_id2, m_geometry2, sec2,
false,
m_intersection_strategy,
m_rescale_policy,
m_turns, m_interrupt_policy);
}
@@ -441,10 +449,11 @@ class get_turns_generic
{
public:
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Geometry1 const& geometry1,
int source_id2, Geometry2 const& geometry2,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
@@ -475,15 +484,19 @@ public:
<
Geometry1, Geometry2,
Reverse1, Reverse2,
Turns, TurnPolicy, RobustPolicy, InterruptPolicy
> visitor(source_id1, geometry1, source_id2, geometry2, robust_policy, turns, interrupt_policy);
TurnPolicy,
IntersectionStrategy, RobustPolicy,
Turns, InterruptPolicy
> visitor(source_id1, geometry1, source_id2, geometry2,
intersection_strategy, robust_policy,
turns, interrupt_policy);
geometry::partition
<
box_type,
detail::section::get_section_box,
detail::section::overlaps_section_box
>::apply(sec1, sec2, visitor);
box_type
>::apply(sec1, sec2, visitor,
detail::section::get_section_box(),
detail::section::overlaps_section_box());
}
};
@@ -518,10 +531,11 @@ struct get_turns_cs
>::type iterator_type;
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Range const& range,
int source_id2, Box const& box,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
@@ -593,8 +607,10 @@ struct get_turns_cs
// NOTE: some dummy values could be passed below since this would be called only for Polygons and Boxes
index == 0,
size_type(index) == segments_count1,
intersection_strategy,
robust_policy,
turns, interrupt_policy);
turns,
interrupt_policy);
// Future performance enhancement:
// return if told by the interrupt policy
}
@@ -622,7 +638,7 @@ private:
else return 0;
}
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2,
// Points from a range:
point_type const& rp0,
@@ -635,6 +651,7 @@ private:
box_point_type const& bp3,
bool const is_range_first,
bool const is_range_last,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
// Output
Turns& turns,
@@ -653,25 +670,29 @@ private:
TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
is_range_first, is_range_last,
true, false,
ti, robust_policy, std::back_inserter(turns));
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
is_range_first, is_range_last,
false, false,
ti, robust_policy, std::back_inserter(turns));
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
is_range_first, is_range_last,
false, false,
ti, robust_policy, std::back_inserter(turns));
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
is_range_first, is_range_last,
false, true,
ti, robust_policy, std::back_inserter(turns));
ti, intersection_strategy, robust_policy,
std::back_inserter(turns));
if (InterruptPolicy::enabled)
{
@@ -691,12 +712,14 @@ template
>
struct get_turns_polygon_cs
{
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Polygon const& polygon,
int source_id2, Box const& box,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy,
Turns& turns,
InterruptPolicy& interrupt_policy,
signed_size_type multi_index = -1)
{
typedef typename geometry::ring_type<Polygon>::type ring_type;
@@ -711,8 +734,10 @@ struct get_turns_polygon_cs
intersector_type::apply(
source_id1, geometry::exterior_ring(polygon),
source_id2, box,
intersection_strategy,
robust_policy,
turns, interrupt_policy,
turns,
interrupt_policy,
multi_index, -1);
signed_size_type i = 0;
@@ -725,6 +750,7 @@ struct get_turns_polygon_cs
intersector_type::apply(
source_id1, *it,
source_id2, box,
intersection_strategy,
robust_policy,
turns, interrupt_policy,
multi_index, i);
@@ -742,12 +768,14 @@ template
>
struct get_turns_multi_polygon_cs
{
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Multi const& multi,
int source_id2, Box const& box,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy)
Turns& turns,
InterruptPolicy& interrupt_policy)
{
typedef typename boost::range_iterator
<
@@ -766,7 +794,8 @@ struct get_turns_multi_polygon_cs
Reverse, ReverseBox,
TurnPolicy
>::apply(source_id1, *it, source_id2, box,
robust_policy, turns, interrupt_policy, i);
intersection_strategy, robust_policy,
turns, interrupt_policy, i);
}
}
};
@@ -918,13 +947,13 @@ template
>
struct get_turns_reversed
{
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(
int source_id1, Geometry1 const& g1,
int source_id2, Geometry2 const& g2,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline void apply(int source_id1, Geometry1 const& g1,
int source_id2, Geometry2 const& g2,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
{
get_turns
<
@@ -932,8 +961,9 @@ struct get_turns_reversed
Geometry2, Geometry1,
Reverse2, Reverse1,
TurnPolicy
>::apply(source_id2, g2, source_id1, g1, robust_policy,
turns, interrupt_policy);
>::apply(source_id2, g2, source_id1, g1,
intersection_strategy, robust_policy,
turns, interrupt_policy);
}
};
@@ -951,6 +981,7 @@ struct get_turns_reversed
\tparam Turns type of turn-container (e.g. vector of "intersection/turn point"'s)
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param intersection_strategy segments intersection strategy
\param robust_policy policy to handle robustness issues
\param turns container which will contain turn points
\param interrupt_policy policy determining if process is stopped
@@ -962,15 +993,17 @@ template
typename AssignPolicy,
typename Geometry1,
typename Geometry2,
typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename InterruptPolicy
>
inline void get_turns(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
Geometry2 const& geometry2,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
{
concepts::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
@@ -996,11 +1029,11 @@ inline void get_turns(Geometry1 const& geometry1,
Reverse1, Reverse2,
TurnPolicy
>
>::type::apply(
0, geometry1,
1, geometry2,
robust_policy,
turns, interrupt_policy);
>::type::apply(0, geometry1,
1, geometry2,
intersection_strategy,
robust_policy,
turns, interrupt_policy);
}
#if defined(_MSC_VER)

View File

@@ -2,10 +2,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// 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
@@ -71,7 +72,7 @@ struct intersection_segment_segment_point
Segment2 const& segment2,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& )
Strategy const& strategy)
{
typedef typename point_type<PointOut>::type point_type;
@@ -106,16 +107,15 @@ struct intersection_segment_segment_point
>::type
> intersection_return_type;
typedef strategy::intersection::relate_cartesian_segments
typedef policies::relate::segments_intersection_points
<
policies::relate::segments_intersection_points
<
intersection_return_type
>
> policy;
intersection_return_type
> policy_type;
intersection_return_type is = policy::apply(segment1, segment2,
robust_policy, pi_rob, pj_rob, qi_rob, qj_rob);
intersection_return_type
is = strategy.apply(segment1, segment2,
policy_type(), robust_policy,
pi_rob, pj_rob, qi_rob, qj_rob);
for (std::size_t i = 0; i < is.count; i++)
{
@@ -134,13 +134,14 @@ struct intersection_linestring_linestring_point
<
typename Linestring1, typename Linestring2,
typename RobustPolicy,
typename OutputIterator, typename Strategy
typename OutputIterator,
typename Strategy
>
static inline OutputIterator apply(Linestring1 const& linestring1,
Linestring2 const& linestring2,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& )
Strategy const& strategy)
{
typedef typename point_type<PointOut>::type point_type;
@@ -151,7 +152,8 @@ struct intersection_linestring_linestring_point
> turn_info;
std::deque<turn_info> turns;
geometry::get_intersection_points(linestring1, linestring2, robust_policy, turns);
geometry::get_intersection_points(linestring1, linestring2,
robust_policy, turns, strategy);
for (typename boost::range_iterator<std::deque<turn_info> const>::type
it = boost::begin(turns); it != boost::end(turns); ++it)
@@ -295,7 +297,7 @@ struct intersection_of_linestring_with_areal
static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& )
Strategy const& strategy)
{
if (boost::size(linestring) == 0)
{
@@ -325,7 +327,7 @@ struct intersection_of_linestring_with_areal
false,
(OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
detail::overlay::assign_null_policy
>(linestring, areal, robust_policy, turns, policy);
>(linestring, areal, strategy, robust_policy, turns, policy);
if (no_crossing_turns_or_empty(turns))
{
@@ -621,7 +623,7 @@ struct intersection_insert
static inline OutputIterator apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out, Strategy const& )
OutputIterator out, Strategy const& strategy)
{
typedef detail::overlay::turn_info
@@ -635,7 +637,7 @@ struct intersection_insert
geometry::get_turns
<
false, false, detail::overlay::assign_null_policy
>(geometry1, geometry2, robust_policy, turns, policy);
>(geometry1, geometry2, strategy, robust_policy, turns, policy);
for (typename std::vector<turn_info>::const_iterator it
= turns.begin(); it != turns.end(); ++it)
{
@@ -996,7 +998,11 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1,
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
typedef typename Strategy::rescale_policy_type rescale_policy_type;
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type rescale_policy_type;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
@@ -1037,22 +1043,13 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1,
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
typedef typename geometry::rescale_policy_type
typedef typename strategy::intersection::services::default_strategy
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type rescale_policy_type;
typedef intersection_strategies
<
typename cs_tag<GeometryOut>::type,
Geometry1,
Geometry2,
typename geometry::point_type<GeometryOut>::type,
rescale_policy_type
> strategy;
typename cs_tag<GeometryOut>::type
>::type strategy_type;
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
strategy());
strategy_type());
}
}} // namespace detail::intersection

View File

@@ -1,11 +1,12 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP
@@ -158,11 +159,13 @@ protected:
typename Turns,
typename LinearGeometry1,
typename LinearGeometry2,
typename IntersectionStrategy,
typename RobustPolicy
>
static inline void compute_turns(Turns& turns,
LinearGeometry1 const& linear1,
LinearGeometry2 const& linear2,
IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy)
{
turns.clear();
@@ -180,7 +183,7 @@ protected:
assign_policy
>,
RobustPolicy
>::apply(turns, linear1, linear2, interrupt_policy, robust_policy);
>::apply(turns, linear1, linear2, interrupt_policy, strategy, robust_policy);
}
@@ -237,7 +240,7 @@ public:
Linear2 const& linear2,
RobustPolicy const& robust_policy,
OutputIterator oit,
Strategy const& )
Strategy const& strategy)
{
typedef typename detail::relate::turns::get_turns
<
@@ -255,7 +258,7 @@ public:
typedef std::vector<turn_info> turns_container;
turns_container turns;
compute_turns(turns, linear1, linear2, robust_policy);
compute_turns(turns, linear1, linear2, strategy, robust_policy);
if ( turns.empty() )
{

View File

@@ -3,10 +3,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// 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
@@ -184,7 +185,7 @@ struct overlay
Geometry1 const& geometry1, Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& ,
Strategy const& strategy,
Visitor& visitor)
{
bool const is_empty1 = geometry::is_empty(geometry1);
@@ -233,7 +234,7 @@ std::cout << "get turns" << std::endl;
<
Reverse1, Reverse2,
detail::overlay::assign_null_policy
>(geometry1, geometry2, robust_policy, turns, policy);
>(geometry1, geometry2, strategy, robust_policy, turns, policy);
visitor.visit_turns(1, turns);
@@ -262,6 +263,7 @@ std::cout << "traverse" << std::endl;
traverse<Reverse1, Reverse2, Geometry1, Geometry2, OverlayType>::apply
(
geometry1, geometry2,
strategy,
robust_policy,
turns, rings,
clusters,

View File

@@ -1,12 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015, Oracle and/or its affiliates.
// Copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_LINEAR_HPP
@@ -69,12 +70,12 @@ struct point_linear_point
Linear const& linear,
RobustPolicy const&,
OutputIterator oit,
Strategy const&)
Strategy const& strategy)
{
action_selector_pl_l
<
PointOut, OverlayType
>::apply(point, Policy::apply(point, linear), oit);
>::apply(point, Policy::apply(point, linear, strategy), oit);
return oit;
}
};
@@ -95,7 +96,7 @@ struct multipoint_segment_point
Segment const& segment,
RobustPolicy const&,
OutputIterator oit,
Strategy const&)
Strategy const& strategy)
{
for (typename boost::range_iterator<MultiPoint const>::type
it = boost::begin(multipoint);
@@ -105,7 +106,7 @@ struct multipoint_segment_point
action_selector_pl_l
<
PointOut, OverlayType
>::apply(*it, Policy::apply(*it, segment), oit);
>::apply(*it, Policy::apply(*it, segment, strategy), oit);
}
return oit;
@@ -145,11 +146,14 @@ private:
}
};
template <typename OutputIterator>
template <typename OutputIterator, typename Strategy>
class item_visitor_type
{
public:
item_visitor_type(OutputIterator& oit) : m_oit(oit) {}
item_visitor_type(OutputIterator& oit, Strategy const& strategy)
: m_oit(oit)
, m_strategy(strategy)
{}
template <typename Item1, typename Item2>
inline void apply(Item1 const& item1, Item2 const& item2)
@@ -157,11 +161,12 @@ private:
action_selector_pl_l
<
PointOut, overlay_intersection
>::apply(item1, Policy::apply(item1, item2), m_oit);
>::apply(item1, Policy::apply(item1, item2, m_strategy), m_oit);
}
private:
OutputIterator& m_oit;
Strategy const& m_strategy;
};
// structs for partition -- end
@@ -189,12 +194,13 @@ private:
Linear const& m_linear;
};
template <typename OutputIterator>
template <typename OutputIterator, typename Strategy>
static inline OutputIterator get_common_points(MultiPoint const& multipoint,
Linear const& linear,
OutputIterator oit)
OutputIterator oit,
Strategy const& strategy)
{
item_visitor_type<OutputIterator> item_visitor(oit);
item_visitor_type<OutputIterator, Strategy> item_visitor(oit, strategy);
segment_range rng(linear);
@@ -203,10 +209,9 @@ private:
geometry::model::box
<
typename boost::range_value<MultiPoint>::type
>,
expand_box,
overlaps_box
>::apply(multipoint, rng, item_visitor);
>
>::apply(multipoint, rng, item_visitor,
expand_box(), overlaps_box());
return oit;
}
@@ -228,7 +233,8 @@ public:
// compute the common points
get_common_points(multipoint, linear,
std::back_inserter(common_points));
std::back_inserter(common_points),
strategy);
return multipoint_multipoint_point
<

View File

@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 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)
@@ -61,20 +66,25 @@ template
typename Geometry,
typename Turns,
typename TurnPolicy,
typename IntersectionStrategy,
typename RobustPolicy,
typename InterruptPolicy
>
struct self_section_visitor
{
Geometry const& m_geometry;
IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_rescale_policy;
Turns& m_turns;
InterruptPolicy& m_interrupt_policy;
inline self_section_visitor(Geometry const& g,
RobustPolicy const& rp,
Turns& turns, InterruptPolicy& ip)
IntersectionStrategy const& is,
RobustPolicy const& rp,
Turns& turns,
InterruptPolicy& ip)
: m_geometry(g)
, m_intersection_strategy(is)
, m_rescale_policy(rp)
, m_turns(turns)
, m_interrupt_policy(ip)
@@ -97,6 +107,7 @@ struct self_section_visitor
0, m_geometry, sec1,
0, m_geometry, sec2,
false,
m_intersection_strategy,
m_rescale_policy,
m_turns, m_interrupt_policy);
}
@@ -116,9 +127,10 @@ struct self_section_visitor
template<typename TurnPolicy>
struct get_turns
{
template <typename Geometry, typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename Geometry, typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline bool apply(
Geometry const& geometry,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns,
InterruptPolicy& interrupt_policy)
@@ -142,17 +154,17 @@ struct get_turns
self_section_visitor
<
Geometry,
Turns, TurnPolicy, RobustPolicy, InterruptPolicy
> visitor(geometry, robust_policy, turns, interrupt_policy);
Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy
> visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy);
try
{
geometry::partition
<
box_type,
detail::section::get_section_box,
detail::section::overlaps_section_box
>::apply(sec, visitor);
box_type
>::apply(sec, visitor,
detail::section::get_section_box(),
detail::section::overlaps_section_box());
}
catch(self_ip_exception const& )
{
@@ -208,9 +220,10 @@ struct self_get_turn_points
TurnPolicy
>
{
template <typename RobustPolicy, typename Turns, typename InterruptPolicy>
template <typename Strategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
static inline bool apply(
Box const& ,
Strategy const& ,
RobustPolicy const& ,
Turns& ,
InterruptPolicy& )
@@ -259,6 +272,7 @@ struct self_get_turn_points
\tparam Turns type of intersection container
(e.g. vector of "intersection/turn point"'s)
\param geometry geometry
\param strategy strategy to be used
\param robust_policy policy to handle robustness issues
\param turns container which will contain intersection points
\param interrupt_policy policy determining if process is stopped
@@ -268,13 +282,15 @@ template
<
typename AssignPolicy,
typename Geometry,
typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename InterruptPolicy
>
inline void self_turns(Geometry const& geometry,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy)
IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy,
Turns& turns, InterruptPolicy& interrupt_policy)
{
concepts::check<Geometry const>();
@@ -285,7 +301,7 @@ inline void self_turns(Geometry const& geometry,
typename tag<Geometry>::type,
Geometry,
turn_policy
>::apply(geometry, robust_policy, turns, interrupt_policy);
>::apply(geometry, strategy, robust_policy, turns, interrupt_policy);
}

View File

@@ -140,10 +140,10 @@ struct traversal
{
for (int i = 0; i < 2; i++)
{
turn_operation_type& op = turn.operations[i];
if (op.visited.none())
turn_operation_type& turn_op = turn.operations[i];
if (turn_op.visited.none())
{
op.visited.set_visited();
turn_op.visited.set_visited();
}
}
}

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, 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)
@@ -38,6 +42,7 @@ template
typename Geometry2,
typename Turns,
typename Clusters,
typename IntersectionStrategy,
typename RobustPolicy,
typename Visitor,
typename Backtrack
@@ -56,12 +61,14 @@ struct traversal_ring_creator
inline traversal_ring_creator(Geometry1 const& geometry1, Geometry2 const& geometry2,
Turns& turns, Clusters const& clusters,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy, Visitor& visitor)
: m_trav(geometry1, geometry2, turns, clusters, robust_policy,visitor)
, m_geometry1(geometry1)
, m_geometry2(geometry2)
, m_turns(turns)
, m_clusters(clusters)
, m_intersection_strategy(intersection_strategy)
, m_robust_policy(robust_policy)
, m_visitor(visitor)
{
@@ -280,7 +287,8 @@ struct traversal_ring_creator
rings, ring, m_turns, start_turn,
m_turns[turn_index].operations[op_index],
traverse_error,
m_geometry1, m_geometry2, m_robust_policy,
m_geometry1, m_geometry2,
m_intersection_strategy, m_robust_policy,
state, m_visitor);
}
}
@@ -314,6 +322,7 @@ private:
Geometry2 const& m_geometry2;
Turns& m_turns;
Clusters const& m_clusters;
IntersectionStrategy const& m_intersection_strategy;
RobustPolicy const& m_robust_policy;
Visitor& m_visitor;
};

View File

@@ -58,6 +58,7 @@ class traverse
public :
template
<
typename IntersectionStrategy,
typename RobustPolicy,
typename Turns,
typename Rings,
@@ -66,6 +67,7 @@ public :
>
static inline void apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy,
Turns& turns, Rings& rings,
Clusters& clusters,
@@ -88,10 +90,11 @@ public :
Reverse1, Reverse2, OverlayType,
Geometry1, Geometry2,
Turns, Clusters,
IntersectionStrategy,
RobustPolicy, Visitor,
Backtrack
> trav(geometry1, geometry2, turns, clusters,
robust_policy, visitor);
intersection_strategy, robust_policy, visitor);
std::size_t finalized_ring_size = boost::size(rings);

View File

@@ -2,10 +2,11 @@
// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// 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
@@ -47,13 +48,14 @@ inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
// Divide forward_range into three subsets: lower, upper and oversized
// (not-fitting)
// (lower == left or bottom, upper == right or top)
template <typename OverlapsPolicy, typename Box, typename IteratorVector>
template <typename Box, typename IteratorVector, typename OverlapsPolicy>
inline void divide_into_subsets(Box const& lower_box,
Box const& upper_box,
IteratorVector const& input,
IteratorVector& lower,
IteratorVector& upper,
IteratorVector& exceeding)
Box const& upper_box,
IteratorVector const& input,
IteratorVector& lower,
IteratorVector& upper,
IteratorVector& exceeding,
OverlapsPolicy const& overlaps_policy)
{
typedef typename boost::range_iterator
<
@@ -62,8 +64,8 @@ inline void divide_into_subsets(Box const& lower_box,
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
bool const lower_overlapping = OverlapsPolicy::apply(lower_box, **it);
bool const upper_overlapping = OverlapsPolicy::apply(upper_box, **it);
bool const lower_overlapping = overlaps_policy.apply(lower_box, **it);
bool const upper_overlapping = overlaps_policy.apply(upper_box, **it);
if (lower_overlapping && upper_overlapping)
{
@@ -87,23 +89,24 @@ inline void divide_into_subsets(Box const& lower_box,
template
<
typename ExpandPolicy,
typename Box,
typename IteratorVector
typename IteratorVector,
typename ExpandPolicy
>
inline void expand_with_elements(Box& total, IteratorVector const& input)
inline void expand_with_elements(Box& total, IteratorVector const& input,
ExpandPolicy const& expand_policy)
{
typedef typename boost::range_iterator<IteratorVector const>::type it_type;
for(it_type it = boost::begin(input); it != boost::end(input); ++it)
{
ExpandPolicy::apply(total, **it);
expand_policy.apply(total, **it);
}
}
// Match forward_range with itself
template <typename Policy, typename IteratorVector>
inline void handle_one(IteratorVector const& input, Policy& policy)
template <typename IteratorVector, typename VisitPolicy>
inline void handle_one(IteratorVector const& input, VisitPolicy& visitor)
{
if (boost::size(input) == 0)
{
@@ -118,7 +121,7 @@ inline void handle_one(IteratorVector const& input, Policy& policy)
it_type it2 = it1;
for (++it2; it2 != boost::end(input); ++it2)
{
policy.apply(**it1, **it2);
visitor.apply(**it1, **it2);
}
}
}
@@ -126,13 +129,13 @@ inline void handle_one(IteratorVector const& input, Policy& policy)
// Match forward range 1 with forward range 2
template
<
typename Policy,
typename IteratorVector1,
typename IteratorVector2
typename IteratorVector2,
typename VisitPolicy
>
inline void handle_two(IteratorVector1 const& input1,
IteratorVector2 const& input2,
Policy& policy)
IteratorVector2 const& input2,
VisitPolicy& visitor)
{
typedef typename boost::range_iterator
<
@@ -157,14 +160,14 @@ inline void handle_two(IteratorVector1 const& input1,
it2 != boost::end(input2);
++it2)
{
policy.apply(**it1, **it2);
visitor.apply(**it1, **it2);
}
}
}
template <typename IteratorVector>
inline bool recurse_ok(IteratorVector const& input,
std::size_t min_elements, std::size_t level)
std::size_t min_elements, std::size_t level)
{
return boost::size(input) >= min_elements
&& level < 100;
@@ -172,8 +175,8 @@ inline bool recurse_ok(IteratorVector const& input,
template <typename IteratorVector1, typename IteratorVector2>
inline bool recurse_ok(IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t min_elements, std::size_t level)
IteratorVector2 const& input2,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, min_elements, level);
@@ -186,103 +189,114 @@ template
typename IteratorVector3
>
inline bool recurse_ok(IteratorVector1 const& input1,
IteratorVector2 const& input2,
IteratorVector3 const& input3,
std::size_t min_elements, std::size_t level)
IteratorVector2 const& input2,
IteratorVector3 const& input3,
std::size_t min_elements, std::size_t level)
{
return boost::size(input1) >= min_elements
&& recurse_ok(input2, input3, min_elements, level);
}
template
<
int Dimension,
typename Box,
typename OverlapsPolicy1,
typename OverlapsPolicy2,
typename ExpandPolicy1,
typename ExpandPolicy2,
typename VisitBoxPolicy
>
template <int Dimension, typename Box>
class partition_two_ranges;
template
<
int Dimension,
typename Box,
typename OverlapsPolicy,
typename ExpandPolicy,
typename VisitBoxPolicy
>
template <int Dimension, typename Box>
class partition_one_range
{
template <typename IteratorVector>
static inline Box get_new_box(IteratorVector const& input)
template <typename IteratorVector, typename ExpandPolicy>
static inline Box get_new_box(IteratorVector const& input,
ExpandPolicy const& expand_policy)
{
Box box;
geometry::assign_inverse(box);
expand_with_elements<ExpandPolicy>(box, input);
expand_with_elements(box, input, expand_policy);
return box;
}
template <typename Policy, typename IteratorVector>
template
<
typename IteratorVector,
typename VisitPolicy,
typename ExpandPolicy,
typename OverlapsPolicy,
typename VisitBoxPolicy
>
static inline void next_level(Box const& box,
IteratorVector const& input,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
IteratorVector const& input,
std::size_t level, std::size_t min_elements,
VisitPolicy& visitor,
ExpandPolicy const& expand_policy,
OverlapsPolicy const& overlaps_policy,
VisitBoxPolicy& box_policy)
{
if (recurse_ok(input, min_elements, level))
{
partition_one_range
<
1 - Dimension,
Box,
OverlapsPolicy,
ExpandPolicy,
VisitBoxPolicy
>::apply(box, input, level + 1, min_elements, policy, box_policy);
<
1 - Dimension,
Box
>::apply(box, input, level + 1, min_elements,
visitor, expand_policy, overlaps_policy, box_policy);
}
else
{
handle_one(input, policy);
handle_one(input, visitor);
}
}
// Function to switch to two forward ranges if there are
// geometries exceeding the separation line
template <typename Policy, typename IteratorVector>
template
<
typename IteratorVector,
typename VisitPolicy,
typename ExpandPolicy,
typename OverlapsPolicy,
typename VisitBoxPolicy
>
static inline void next_level2(Box const& box,
IteratorVector const& input1,
IteratorVector const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
VisitPolicy& visitor,
ExpandPolicy const& expand_policy,
OverlapsPolicy const& overlaps_policy,
VisitBoxPolicy& box_policy)
{
if (recurse_ok(input1, input2, min_elements, level))
{
partition_two_ranges
<
1 - Dimension,
Box,
OverlapsPolicy, OverlapsPolicy,
ExpandPolicy, ExpandPolicy,
VisitBoxPolicy
>::apply(box, input1, input2, level + 1, min_elements,
policy, box_policy);
<
1 - Dimension, Box
>::apply(box, input1, input2, level + 1, min_elements,
visitor, expand_policy, overlaps_policy,
expand_policy, overlaps_policy, box_policy);
}
else
{
handle_two(input1, input2, policy);
handle_two(input1, input2, visitor);
}
}
public :
template <typename Policy, typename IteratorVector>
template
<
typename IteratorVector,
typename VisitPolicy,
typename ExpandPolicy,
typename OverlapsPolicy,
typename VisitBoxPolicy
>
static inline void apply(Box const& box,
IteratorVector const& input,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
IteratorVector const& input,
std::size_t level,
std::size_t min_elements,
VisitPolicy& visitor,
ExpandPolicy const& expand_policy,
OverlapsPolicy const& overlaps_policy,
VisitBoxPolicy& box_policy)
{
box_policy.apply(box, level);
@@ -290,101 +304,121 @@ public :
divide_box<Dimension>(box, lower_box, upper_box);
IteratorVector lower, upper, exceeding;
divide_into_subsets<OverlapsPolicy>(lower_box, upper_box,
input, lower, upper, exceeding);
divide_into_subsets(lower_box, upper_box,
input, lower, upper, exceeding,
overlaps_policy);
if (boost::size(exceeding) > 0)
{
// Get the box of exceeding-only
Box exceeding_box = get_new_box(exceeding);
Box exceeding_box = get_new_box(exceeding, expand_policy);
// Recursively do exceeding elements only, in next dimension they
// will probably be less exceeding within the new box
next_level(exceeding_box, exceeding, level, min_elements,
policy, box_policy);
visitor, expand_policy, overlaps_policy, box_policy);
// Switch to two forward ranges, combine exceeding with
// lower resp upper, but not lower/lower, upper/upper
next_level2(exceeding_box, exceeding, lower, level, min_elements,
policy, box_policy);
visitor, expand_policy, overlaps_policy, box_policy);
next_level2(exceeding_box, exceeding, upper, level, min_elements,
policy, box_policy);
visitor, expand_policy, overlaps_policy, box_policy);
}
// Recursively call operation both parts
next_level(lower_box, lower, level, min_elements, policy, box_policy);
next_level(upper_box, upper, level, min_elements, policy, box_policy);
next_level(lower_box, lower, level, min_elements,
visitor, expand_policy, overlaps_policy, box_policy);
next_level(upper_box, upper, level, min_elements,
visitor, expand_policy, overlaps_policy, box_policy);
}
};
template
<
int Dimension,
typename Box,
typename OverlapsPolicy1,
typename OverlapsPolicy2,
typename ExpandPolicy1,
typename ExpandPolicy2,
typename VisitBoxPolicy
typename Box
>
class partition_two_ranges
{
template
<
typename Policy,
typename IteratorVector1,
typename IteratorVector2
typename IteratorVector2,
typename VisitPolicy,
typename ExpandPolicy1,
typename OverlapsPolicy1,
typename ExpandPolicy2,
typename OverlapsPolicy2,
typename VisitBoxPolicy
>
static inline void next_level(Box const& box,
IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t level, std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
VisitPolicy& visitor,
ExpandPolicy1 const& expand_policy1,
OverlapsPolicy1 const& overlaps_policy1,
ExpandPolicy2 const& expand_policy2,
OverlapsPolicy2 const& overlaps_policy2,
VisitBoxPolicy& box_policy)
{
partition_two_ranges
<
1 - Dimension,
Box,
OverlapsPolicy1,
OverlapsPolicy2,
ExpandPolicy1,
ExpandPolicy2,
VisitBoxPolicy
1 - Dimension, Box
>::apply(box, input1, input2, level + 1, min_elements,
policy, box_policy);
visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
}
template <typename ExpandPolicy, typename IteratorVector>
static inline Box get_new_box(IteratorVector const& input)
template <typename IteratorVector, typename ExpandPolicy>
static inline Box get_new_box(IteratorVector const& input,
ExpandPolicy const& expand_policy)
{
Box box;
geometry::assign_inverse(box);
expand_with_elements<ExpandPolicy>(box, input);
expand_with_elements(box, input, expand_policy);
return box;
}
template <typename IteratorVector1, typename IteratorVector2>
template
<
typename IteratorVector1, typename IteratorVector2,
typename ExpandPolicy1, typename ExpandPolicy2
>
static inline Box get_new_box(IteratorVector1 const& input1,
IteratorVector2 const& input2)
IteratorVector2 const& input2,
ExpandPolicy1 const& expand_policy1,
ExpandPolicy2 const& expand_policy2)
{
Box box = get_new_box<ExpandPolicy1>(input1);
expand_with_elements<ExpandPolicy2>(box, input2);
Box box = get_new_box(input1, expand_policy1);
expand_with_elements(box, input2, expand_policy2);
return box;
}
public :
template
<
typename Policy,
typename IteratorVector1,
typename IteratorVector2
typename IteratorVector2,
typename VisitPolicy,
typename ExpandPolicy1,
typename OverlapsPolicy1,
typename ExpandPolicy2,
typename OverlapsPolicy2,
typename VisitBoxPolicy
>
static inline void apply(Box const& box,
IteratorVector1 const& input1,
IteratorVector2 const& input2,
std::size_t level,
std::size_t min_elements,
Policy& policy, VisitBoxPolicy& box_policy)
VisitPolicy& visitor,
ExpandPolicy1 const& expand_policy1,
OverlapsPolicy1 const& overlaps_policy1,
ExpandPolicy2 const& expand_policy2,
OverlapsPolicy2 const& overlaps_policy2,
VisitBoxPolicy& box_policy)
{
box_policy.apply(box, level);
@@ -393,10 +427,12 @@ public :
IteratorVector1 lower1, upper1, exceeding1;
IteratorVector2 lower2, upper2, exceeding2;
divide_into_subsets<OverlapsPolicy1>(lower_box, upper_box,
input1, lower1, upper1, exceeding1);
divide_into_subsets<OverlapsPolicy2>(lower_box, upper_box,
input2, lower2, upper2, exceeding2);
divide_into_subsets(lower_box, upper_box,
input1, lower1, upper1, exceeding1,
overlaps_policy1);
divide_into_subsets(lower_box, upper_box,
input2, lower2, upper2, exceeding2,
overlaps_policy2);
if (boost::size(exceeding1) > 0)
{
@@ -404,13 +440,15 @@ public :
if (recurse_ok(exceeding1, exceeding2, min_elements, level))
{
Box exceeding_box = get_new_box(exceeding1, exceeding2);
Box exceeding_box = get_new_box(exceeding1, exceeding2,
expand_policy1, expand_policy2);
next_level(exceeding_box, exceeding1, exceeding2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
}
else
{
handle_two(exceeding1, exceeding2, policy);
handle_two(exceeding1, exceeding2, visitor);
}
// All exceeding from 1 with lower and upper of 2:
@@ -419,16 +457,18 @@ public :
// the same combinations again and again)
if (recurse_ok(lower2, upper2, exceeding1, min_elements, level))
{
Box exceeding_box = get_new_box<ExpandPolicy1>(exceeding1);
Box exceeding_box = get_new_box(exceeding1, expand_policy1);
next_level(exceeding_box, exceeding1, lower2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
next_level(exceeding_box, exceeding1, upper2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
}
else
{
handle_two(exceeding1, lower2, policy);
handle_two(exceeding1, upper2, policy);
handle_two(exceeding1, lower2, visitor);
handle_two(exceeding1, upper2, visitor);
}
}
@@ -437,36 +477,40 @@ public :
// All exceeding from 2 with lower and upper of 1:
if (recurse_ok(lower1, upper1, exceeding2, min_elements, level))
{
Box exceeding_box = get_new_box<ExpandPolicy2>(exceeding2);
Box exceeding_box = get_new_box(exceeding2, expand_policy2);
next_level(exceeding_box, lower1, exceeding2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
next_level(exceeding_box, upper1, exceeding2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
}
else
{
handle_two(lower1, exceeding2, policy);
handle_two(upper1, exceeding2, policy);
handle_two(lower1, exceeding2, visitor);
handle_two(upper1, exceeding2, visitor);
}
}
if (recurse_ok(lower1, lower2, min_elements, level))
{
next_level(lower_box, lower1, lower2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
}
else
{
handle_two(lower1, lower2, policy);
handle_two(lower1, lower2, visitor);
}
if (recurse_ok(upper1, upper2, min_elements, level))
{
next_level(upper_box, upper1, upper2, level,
min_elements, policy, box_policy);
min_elements, visitor, expand_policy1, overlaps_policy1,
expand_policy2, overlaps_policy2, box_policy);
}
else
{
handle_two(upper1, upper2, policy);
handle_two(upper1, upper2, visitor);
}
}
};
@@ -493,46 +537,86 @@ struct include_all_policy
template
<
typename Box,
typename ExpandPolicy1,
typename OverlapsPolicy1,
typename ExpandPolicy2 = ExpandPolicy1,
typename OverlapsPolicy2 = OverlapsPolicy1,
typename IncludePolicy1 = detail::partition::include_all_policy,
typename IncludePolicy2 = detail::partition::include_all_policy,
typename VisitBoxPolicy = detail::partition::visit_no_policy
typename IncludePolicy2 = detail::partition::include_all_policy
>
class partition
{
static const std::size_t default_min_elements = 16;
template
<
typename ExpandPolicy,
typename IncludePolicy,
typename ForwardRange,
typename IteratorVector
typename IteratorVector,
typename ExpandPolicy
>
static inline void expand_to_range(ForwardRange const& forward_range,
Box& total, IteratorVector& iterator_vector)
Box& total,
IteratorVector& iterator_vector,
ExpandPolicy const& expand_policy)
{
for(typename boost::range_iterator<ForwardRange const>::type it
= boost::begin(forward_range);
for(typename boost::range_iterator<ForwardRange const>::type
it = boost::begin(forward_range);
it != boost::end(forward_range);
++it)
{
if (IncludePolicy::apply(*it))
{
ExpandPolicy::apply(total, *it);
expand_policy.apply(total, *it);
iterator_vector.push_back(it);
}
}
}
public :
template <typename ForwardRange, typename VisitPolicy>
public:
template
<
typename ForwardRange,
typename VisitPolicy,
typename ExpandPolicy,
typename OverlapsPolicy
>
static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
std::size_t min_elements = 16,
VisitBoxPolicy box_visitor = detail::partition::visit_no_policy()
)
VisitPolicy& visitor,
ExpandPolicy const& expand_policy,
OverlapsPolicy const& overlaps_policy)
{
apply(forward_range, visitor, expand_policy, overlaps_policy,
default_min_elements, detail::partition::visit_no_policy());
}
template
<
typename ForwardRange,
typename VisitPolicy,
typename ExpandPolicy,
typename OverlapsPolicy
>
static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
ExpandPolicy const& expand_policy,
OverlapsPolicy const& overlaps_policy,
std::size_t min_elements)
{
apply(forward_range, visitor, expand_policy, overlaps_policy,
min_elements, detail::partition::visit_no_policy());
}
template
<
typename ForwardRange,
typename VisitPolicy,
typename ExpandPolicy,
typename OverlapsPolicy,
typename VisitBoxPolicy
>
static inline void apply(ForwardRange const& forward_range,
VisitPolicy& visitor,
ExpandPolicy const& expand_policy,
OverlapsPolicy const& overlaps_policy,
std::size_t min_elements,
VisitBoxPolicy box_visitor)
{
typedef typename boost::range_iterator
<
@@ -544,17 +628,14 @@ public :
std::vector<iterator_type> iterator_vector;
Box total;
assign_inverse(total);
expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range,
total, iterator_vector);
expand_to_range<IncludePolicy1>(forward_range, total,
iterator_vector, expand_policy);
detail::partition::partition_one_range
<
0, Box,
OverlapsPolicy1,
ExpandPolicy1,
VisitBoxPolicy
0, Box
>::apply(total, iterator_vector, 0, min_elements,
visitor, box_visitor);
visitor, expand_policy, overlaps_policy, box_visitor);
}
else
{
@@ -575,15 +656,88 @@ public :
<
typename ForwardRange1,
typename ForwardRange2,
typename VisitPolicy
typename VisitPolicy,
typename ExpandPolicy1,
typename OverlapsPolicy1
>
static inline void apply(ForwardRange1 const& forward_range1,
ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
std::size_t min_elements = 16,
VisitBoxPolicy box_visitor
= detail::partition::visit_no_policy()
)
ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
ExpandPolicy1 const& expand_policy1,
OverlapsPolicy1 const& overlaps_policy1)
{
apply(forward_range1, forward_range2, visitor,
expand_policy1, overlaps_policy1, expand_policy1, overlaps_policy1,
default_min_elements, detail::partition::visit_no_policy());
}
template
<
typename ForwardRange1,
typename ForwardRange2,
typename VisitPolicy,
typename ExpandPolicy1,
typename OverlapsPolicy1,
typename ExpandPolicy2,
typename OverlapsPolicy2
>
static inline void apply(ForwardRange1 const& forward_range1,
ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
ExpandPolicy1 const& expand_policy1,
OverlapsPolicy1 const& overlaps_policy1,
ExpandPolicy2 const& expand_policy2,
OverlapsPolicy2 const& overlaps_policy2)
{
apply(forward_range1, forward_range2, visitor,
expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy2,
default_min_elements, detail::partition::visit_no_policy());
}
template
<
typename ForwardRange1,
typename ForwardRange2,
typename VisitPolicy,
typename ExpandPolicy1,
typename OverlapsPolicy1,
typename ExpandPolicy2,
typename OverlapsPolicy2
>
static inline void apply(ForwardRange1 const& forward_range1,
ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
ExpandPolicy1 const& expand_policy1,
OverlapsPolicy1 const& overlaps_policy1,
ExpandPolicy2 const& expand_policy2,
OverlapsPolicy2 const& overlaps_policy2,
std::size_t min_elements)
{
apply(forward_range1, forward_range2, visitor,
expand_policy1, overlaps_policy1, expand_policy2, overlaps_policy1,
min_elements, detail::partition::visit_no_policy());
}
template
<
typename ForwardRange1,
typename ForwardRange2,
typename VisitPolicy,
typename ExpandPolicy1,
typename OverlapsPolicy1,
typename ExpandPolicy2,
typename OverlapsPolicy2,
typename VisitBoxPolicy
>
static inline void apply(ForwardRange1 const& forward_range1,
ForwardRange2 const& forward_range2,
VisitPolicy& visitor,
ExpandPolicy1 const& expand_policy1,
OverlapsPolicy1 const& overlaps_policy1,
ExpandPolicy2 const& expand_policy2,
OverlapsPolicy2 const& overlaps_policy2,
std::size_t min_elements,
VisitBoxPolicy box_visitor)
{
typedef typename boost::range_iterator
<
@@ -602,17 +756,18 @@ public :
std::vector<iterator_type2> iterator_vector2;
Box total;
assign_inverse(total);
expand_to_range<ExpandPolicy1, IncludePolicy1>(forward_range1,
total, iterator_vector1);
expand_to_range<ExpandPolicy2, IncludePolicy2>(forward_range2,
total, iterator_vector2);
expand_to_range<IncludePolicy1>(forward_range1, total,
iterator_vector1, expand_policy1);
expand_to_range<IncludePolicy2>(forward_range2, total,
iterator_vector2, expand_policy2);
detail::partition::partition_two_ranges
<
0, Box, OverlapsPolicy1, OverlapsPolicy2,
ExpandPolicy1, ExpandPolicy2, VisitBoxPolicy
0, Box
>::apply(total, iterator_vector1, iterator_vector2,
0, min_elements, visitor, box_visitor);
0, min_elements, visitor, expand_policy1,
overlaps_policy1, expand_policy2, overlaps_policy2,
box_visitor);
}
else
{

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -40,12 +40,21 @@ namespace detail { namespace relate {
// Use the rtree in this case!
// may be used to set EI and EB for an Areal geometry for which no turns were generated
template <typename OtherAreal, typename Result, bool TransposeResult>
template
<
typename OtherAreal,
typename Result,
typename PointInArealStrategy,
bool TransposeResult
>
class no_turns_aa_pred
{
public:
no_turns_aa_pred(OtherAreal const& other_areal, Result & res)
no_turns_aa_pred(OtherAreal const& other_areal,
Result & res,
PointInArealStrategy const& point_in_areal_strategy)
: m_result(res)
, m_point_in_areal_strategy(point_in_areal_strategy)
, m_other_areal(other_areal)
, m_flags(0)
{
@@ -68,6 +77,8 @@ public:
template <typename Areal>
bool operator()(Areal const& areal)
{
using detail::within::point_in_geometry;
// if those flags are set nothing will change
if ( m_flags == 3 )
{
@@ -87,7 +98,9 @@ public:
// check if the areal is inside the other_areal
// TODO: This is O(N)
// Run in a loop O(NM) - optimize!
int const pig = detail::within::point_in_geometry(pt, m_other_areal);
int const pig = point_in_geometry(pt,
m_other_areal,
m_point_in_areal_strategy);
//BOOST_GEOMETRY_ASSERT( pig != 0 );
// inside
@@ -119,7 +132,9 @@ public:
// TODO: O(N)
// Optimize!
int const hpig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal);
int const hpig = point_in_geometry(range::front(range_ref),
m_other_areal,
m_point_in_areal_strategy);
// hole outside
if ( hpig < 0 )
@@ -155,7 +170,9 @@ public:
// TODO: O(N)
// Optimize!
int const hpig = detail::within::point_in_geometry(range::front(range_ref), m_other_areal);
int const hpig = point_in_geometry(range::front(range_ref),
m_other_areal,
m_point_in_areal_strategy);
// hole inside
if ( hpig > 0 )
@@ -174,6 +191,7 @@ public:
private:
Result & m_result;
PointInArealStrategy const& m_point_in_areal_strategy;
OtherAreal const& m_other_areal;
int m_flags;
};
@@ -191,8 +209,10 @@ struct areal_areal
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::type point2_type;
template <typename Result>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
template <typename Result, typename IntersectionStrategy>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
Result & result,
IntersectionStrategy const& intersection_strategy)
{
// TODO: If Areal geometry may have infinite size, change the following line:
@@ -208,16 +228,31 @@ struct areal_areal
interrupt_policy_areal_areal<Result> interrupt_policy(geometry1, geometry2, result);
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
no_turns_aa_pred<Geometry2, Result, false> pred1(geometry2, result);
typedef typename IntersectionStrategy::template point_in_geometry_strategy
<
Geometry1, Geometry2
>::type point_in_areal_strategy12_type;
point_in_areal_strategy12_type point_in_areal_strategy12
= intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
typedef typename IntersectionStrategy::template point_in_geometry_strategy
<
Geometry2, Geometry1
>::type point_in_areal_strategy21_type;
point_in_areal_strategy21_type point_in_areal_strategy21
= intersection_strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>();
no_turns_aa_pred<Geometry2, Result, point_in_areal_strategy12_type, false>
pred1(geometry2, result, point_in_areal_strategy12);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
no_turns_aa_pred<Geometry1, Result, true> pred2(geometry1, result);
no_turns_aa_pred<Geometry1, Result, point_in_areal_strategy21_type, true>
pred2(geometry1, result, point_in_areal_strategy21);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -256,7 +291,8 @@ struct areal_areal
{
// analyse rings for which turns were not generated
// or only i/i or u/u was generated
uncertain_rings_analyser<0, Result, Geometry1, Geometry2> rings_analyser(result, geometry1, geometry2);
uncertain_rings_analyser<0, Result, Geometry1, Geometry2, point_in_areal_strategy12_type>
rings_analyser(result, geometry1, geometry2, point_in_areal_strategy12);
analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
@@ -295,7 +331,8 @@ struct areal_areal
{
// analyse rings for which turns were not generated
// or only i/i or u/u was generated
uncertain_rings_analyser<1, Result, Geometry2, Geometry1> rings_analyser(result, geometry2, geometry1);
uncertain_rings_analyser<1, Result, Geometry2, Geometry1, point_in_areal_strategy21_type>
rings_analyser(result, geometry2, geometry1, point_in_areal_strategy21);
analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end());
//if ( result.interrupt )
@@ -565,7 +602,14 @@ struct areal_areal
analyser.apply(res);
}
template <std::size_t OpId, typename Result, typename Geometry, typename OtherGeometry>
template
<
std::size_t OpId,
typename Result,
typename Geometry,
typename OtherGeometry,
typename PointInArealStrategy
>
class uncertain_rings_analyser
{
static const bool transpose_result = OpId != 0;
@@ -574,10 +618,13 @@ struct areal_areal
public:
inline uncertain_rings_analyser(Result & result,
Geometry const& geom,
OtherGeometry const& other_geom)
: geometry(geom), other_geometry(other_geom)
OtherGeometry const& other_geom,
PointInArealStrategy const& point_in_areal_strategy)
: geometry(geom)
, other_geometry(other_geom)
, interrupt(result.interrupt) // just in case, could be false as well
, m_result(result)
, m_point_in_areal_strategy(point_in_areal_strategy)
, m_flags(0)
{
// check which relations must be analysed
@@ -624,7 +671,10 @@ struct areal_areal
// TODO: optimize! e.g. use spatial index
// O(N) - running it in a loop gives O(NM)
int const pig = detail::within::point_in_geometry(range::front(range_ref), other_geometry);
using detail::within::point_in_geometry;
int const pig = point_in_geometry(range::front(range_ref),
other_geometry,
m_point_in_areal_strategy);
//BOOST_GEOMETRY_ASSERT(pig != 0);
if ( pig > 0 )
@@ -713,6 +763,7 @@ struct areal_areal
private:
Result & m_result;
PointInArealStrategy const& m_point_in_areal_strategy;
int m_flags;
};

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,9 @@
#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/within.hpp>
namespace boost { namespace geometry {

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -29,6 +29,7 @@
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/relate.hpp>
namespace boost { namespace geometry {
@@ -186,18 +187,59 @@ struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
> type;
};
}} // namespace detail::relate
#endif // DOXYGEN_NO_DETAIL
namespace resolve_strategy {
struct relate
{
template <typename Geometry1, typename Geometry2, typename ResultHandler, typename Strategy>
static inline void apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
ResultHandler & handler,
Strategy const& strategy)
{
dispatch::relate
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, handler, strategy);
}
template <typename Geometry1, typename Geometry2, typename ResultHandler>
static inline void apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
ResultHandler & handler,
default_strategy)
{
typedef typename strategy::relate::services::default_strategy
<
Geometry1,
Geometry2
>::type strategy_type;
dispatch::relate
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, handler, strategy_type());
}
};
} // resolve_strategy
namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct relate
{
template <typename Mask>
template <typename Mask, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Mask const& mask)
Mask const& mask,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -210,11 +252,7 @@ struct relate
Mask
>::type handler(mask);
dispatch::relate
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, handler);
resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
return handler.result();
}
@@ -223,60 +261,64 @@ struct relate
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct relate<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Mask>
template <typename Mask, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
Geometry2 const& m_geometry2;
Mask const& m_mask;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2, Mask const& mask)
: m_geometry2(geometry2), m_mask(mask) {}
visitor(Geometry2 const& geometry2, Mask const& mask, Strategy const& strategy)
: m_geometry2(geometry2), m_mask(mask), m_strategy(strategy) {}
template <typename Geometry1>
bool operator()(Geometry1 const& geometry1) const
{
return relate<Geometry1, Geometry2>
::apply(geometry1, m_geometry2, m_mask);
::apply(geometry1, m_geometry2, m_mask, m_strategy);
}
};
template <typename Mask>
template <typename Mask, typename Strategy>
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2,
Mask const& mask)
Mask const& mask,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Mask>(geometry2, mask), geometry1);
return boost::apply_visitor(visitor<Mask, Strategy>(geometry2, mask, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct relate<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Mask>
template <typename Mask, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
Geometry1 const& m_geometry1;
Mask const& m_mask;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1, Mask const& mask)
: m_geometry1(geometry1), m_mask(mask) {}
visitor(Geometry1 const& geometry1, Mask const& mask, Strategy const& strategy)
: m_geometry1(geometry1), m_mask(mask), m_strategy(strategy) {}
template <typename Geometry2>
bool operator()(Geometry2 const& geometry2) const
{
return relate<Geometry1, Geometry2>
::apply(m_geometry1, geometry2, m_mask);
::apply(m_geometry1, geometry2, m_mask, m_strategy);
}
};
template <typename Mask>
template <typename Mask, typename Strategy>
static inline bool
apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Mask const& mask)
Mask const& mask,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Mask>(geometry1, mask), geometry2);
return boost::apply_visitor(visitor<Mask, Strategy>(geometry1, mask, strategy), geometry2);
}
};
@@ -289,35 +331,66 @@ struct relate<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Mask>
template <typename Mask, typename Strategy>
struct visitor : boost::static_visitor<bool>
{
Mask const& m_mask;
Strategy const& m_strategy;
visitor(Mask const& mask)
: m_mask(mask) {}
visitor(Mask const& mask, Strategy const& strategy)
: m_mask(mask), m_strategy(strategy) {}
template <typename Geometry1, typename Geometry2>
bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return relate<Geometry1, Geometry2>
::apply(geometry1, geometry2, m_mask);
::apply(geometry1, geometry2, m_mask, m_strategy);
}
};
template <typename Mask>
template <typename Mask, typename Strategy>
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Mask const& mask)
Mask const& mask,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Mask>(mask), geometry1, geometry2);
return boost::apply_visitor(visitor<Mask, Strategy>(mask, strategy), geometry1, geometry2);
}
};
} // namespace resolve_variant
/*!
\brief Checks relation between a pair of geometries defined by a mask.
\ingroup relate
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Mask An intersection model Mask type.
\tparam Strategy \tparam_strategy{Relate}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param mask An intersection model mask object.
\param strategy \param_strategy{relate}
\return true if the relation is compatible with the mask, false otherwise.
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/relate.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Mask, typename Strategy>
inline bool relate(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Mask const& mask,
Strategy const& strategy)
{
return resolve_variant::relate
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, mask, strategy);
}
/*!
\brief Checks relation between a pair of geometries defined by a mask.
\ingroup relate
@@ -340,7 +413,7 @@ inline bool relate(Geometry1 const& geometry1,
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, mask);
>::apply(geometry1, geometry2, mask, default_strategy());
}
}} // namespace boost::geometry

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -46,15 +46,24 @@ namespace detail { namespace relate {
// Use the rtree in this case!
// may be used to set IE and BE for a Linear geometry for which no turns were generated
template <typename Geometry2, typename Result, typename BoundaryChecker, bool TransposeResult>
template
<
typename Geometry2,
typename Result,
typename PointInArealStrategy,
typename BoundaryChecker,
bool TransposeResult
>
class no_turns_la_linestring_pred
{
public:
no_turns_la_linestring_pred(Geometry2 const& geometry2,
Result & res,
PointInArealStrategy const& point_in_areal_strategy,
BoundaryChecker const& boundary_checker)
: m_geometry2(geometry2)
, m_result(res)
, m_point_in_areal_strategy(point_in_areal_strategy)
, m_boundary_checker(boundary_checker)
, m_interrupt_flags(0)
{
@@ -98,7 +107,9 @@ public:
return false;
}
int const pig = detail::within::point_in_geometry(range::front(linestring), m_geometry2);
int const pig = detail::within::point_in_geometry(range::front(linestring),
m_geometry2,
m_point_in_areal_strategy);
//BOOST_GEOMETRY_ASSERT_MSG(pig != 0, "There should be no IPs");
if ( pig > 0 )
@@ -138,6 +149,7 @@ public:
private:
Geometry2 const& m_geometry2;
Result & m_result;
PointInArealStrategy const& m_point_in_areal_strategy;
BoundaryChecker const& m_boundary_checker;
unsigned m_interrupt_flags;
};
@@ -225,8 +237,10 @@ struct linear_areal
>
{};
template <typename Result>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
template <typename Result, typename IntersectionStrategy>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
Result & result,
IntersectionStrategy const& intersection_strategy)
{
// TODO: If Areal geometry may have infinite size, change the following line:
@@ -242,7 +256,7 @@ struct linear_areal
interrupt_policy_linear_areal<Geometry2, Result> interrupt_policy(geometry2, result);
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -251,9 +265,13 @@ struct linear_areal
<
Geometry2,
Result,
typename IntersectionStrategy::template point_in_geometry_strategy<Geometry1, Geometry2>::type,
boundary_checker<Geometry1>,
TransposeResult
> pred1(geometry2, result, boundary_checker1);
> pred1(geometry2,
result,
intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>(),
boundary_checker1);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -279,7 +297,8 @@ struct linear_areal
analyse_each_turn(result, analyser,
turns.begin(), turns.end(),
geometry1, geometry2,
boundary_checker1);
boundary_checker1,
intersection_strategy.get_side_strategy());
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -615,11 +634,13 @@ struct linear_areal
typename TurnIt,
typename Geometry,
typename OtherGeometry,
typename BoundaryChecker>
typename BoundaryChecker,
typename SideStrategy>
void apply(Result & res, TurnIt it,
Geometry const& geometry,
OtherGeometry const& other_geometry,
BoundaryChecker const& boundary_checker)
BoundaryChecker const& boundary_checker,
SideStrategy const& side_strategy)
{
overlay::operation_type op = it->operations[op_id].operation;
@@ -856,7 +877,8 @@ struct linear_areal
bool const from_inside = first_point
&& calculate_from_inside(geometry,
other_geometry,
*it);
*it,
side_strategy);
if ( from_inside )
update<interior, interior, '1', TransposeResult>(res);
@@ -956,7 +978,8 @@ struct linear_areal
bool const first_from_inside = first_point
&& calculate_from_inside(geometry,
other_geometry,
*it);
*it,
side_strategy);
if ( first_from_inside )
{
update<interior, interior, '1', TransposeResult>(res);
@@ -1144,10 +1167,11 @@ struct linear_areal
// check if the passed turn's segment of Linear geometry arrived
// from the inside or the outside of the Areal geometry
template <typename Turn>
template <typename Turn, typename SideStrategy>
static inline bool calculate_from_inside(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Turn const& turn)
Turn const& turn,
SideStrategy const& side_strategy)
{
typedef typename cs_tag<typename Turn::point_type>::type cs_tag;
@@ -1194,16 +1218,18 @@ struct linear_areal
boost::end(range2));
// Will this sequence of points be always correct?
overlay::side_calculator<cs_tag, point1_type, point2_type> side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it);
overlay::side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, side_strategy);
return calculate_from_inside_sides(side_calc);
}
else
{
point1_type new_qj;
point2_type new_qj;
geometry::convert(turn.point, new_qj);
overlay::side_calculator<cs_tag, point1_type, point2_type> side_calc(qi_conv, new_pj, pi, qi, new_qj, qj);
overlay::side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, side_strategy);
return calculate_from_inside_sides(side_calc);
}
@@ -1270,13 +1296,15 @@ struct linear_areal
typename Analyser,
typename Geometry,
typename OtherGeometry,
typename BoundaryChecker>
typename BoundaryChecker,
typename SideStrategy>
static inline void analyse_each_turn(Result & res,
Analyser & analyser,
TurnIt first, TurnIt last,
Geometry const& geometry,
OtherGeometry const& other_geometry,
BoundaryChecker const& boundary_checker)
BoundaryChecker const& boundary_checker,
SideStrategy const& side_strategy)
{
if ( first == last )
return;
@@ -1285,7 +1313,8 @@ struct linear_areal
{
analyser.apply(res, it,
geometry, other_geometry,
boundary_checker);
boundary_checker,
side_strategy);
if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
return;
@@ -1420,10 +1449,12 @@ struct areal_linear
static const bool interruption_enabled = linear_areal_type::interruption_enabled;
template <typename Result>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
template <typename Result, typename IntersectionStrategy>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
Result & result,
IntersectionStrategy const& intersection_strategy)
{
linear_areal_type::apply(geometry2, geometry1, result);
linear_areal_type::apply(geometry2, geometry1, result, intersection_strategy);
}
};

View File

@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 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)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_LINEAR_LINEAR_HPP
@@ -119,8 +119,10 @@ struct linear_linear
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::type point2_type;
template <typename Result>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
template <typename Result, typename IntersectionStrategy>
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
Result & result,
IntersectionStrategy const& intersection_strategy)
{
// The result should be FFFFFFFFF
relate::set<exterior, exterior, result_dimension<Geometry1>::value>(result);// FFFFFFFFd, d in [1,9] or T
@@ -138,7 +140,7 @@ struct linear_linear
Geometry1,
Geometry2,
detail::get_turns::get_turn_info_type<Geometry1, Geometry2, turns::assign_policy<true> >
>::apply(turns, geometry1, geometry2, interrupt_policy);
>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -37,10 +37,10 @@ struct point_geometry
static const bool interruption_enabled = true;
template <typename Result>
static inline void apply(Point const& point, Geometry const& geometry, Result & result)
template <typename Result, typename Strategy>
static inline void apply(Point const& point, Geometry const& geometry, Result & result, Strategy const& strategy)
{
int pig = detail::within::point_in_geometry(point, geometry);
int pig = detail::within::point_in_geometry(point, geometry, strategy);
if ( pig > 0 ) // within
{
@@ -95,10 +95,10 @@ struct geometry_point
static const bool interruption_enabled = true;
template <typename Result>
static inline void apply(Geometry const& geometry, Point const& point, Result & result)
template <typename Result, typename Strategy>
static inline void apply(Geometry const& geometry, Point const& point, Result & result, Strategy const& strategy)
{
point_geometry<Point, Geometry, true>::apply(point, geometry, result);
point_geometry<Point, Geometry, true>::apply(point, geometry, result, strategy);
}
};

View File

@@ -2,15 +2,15 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014.
// Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017, 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)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP
@@ -35,8 +35,10 @@ struct point_point
{
static const bool interruption_enabled = false;
template <typename Result>
static inline void apply(Point1 const& point1, Point2 const& point2, Result & result)
template <typename Result, typename Strategy>
static inline void apply(Point1 const& point1, Point2 const& point2,
Result & result,
Strategy const& /*strategy*/)
{
bool equal = detail::equals::equals_point_point(point1, point2);
if ( equal )
@@ -86,8 +88,10 @@ struct point_multipoint
{
static const bool interruption_enabled = false;
template <typename Result>
static inline void apply(Point const& point, MultiPoint const& multi_point, Result & result)
template <typename Result, typename Strategy>
static inline void apply(Point const& point, MultiPoint const& multi_point,
Result & result,
Strategy const& /*strategy*/)
{
if ( boost::empty(multi_point) )
{
@@ -122,10 +126,12 @@ struct multipoint_point
{
static const bool interruption_enabled = false;
template <typename Result>
static inline void apply(MultiPoint const& multi_point, Point const& point, Result & result)
template <typename Result, typename Strategy>
static inline void apply(MultiPoint const& multi_point, Point const& point,
Result & result,
Strategy const& strategy)
{
point_multipoint<Point, MultiPoint, true>::apply(point, multi_point, result);
point_multipoint<Point, MultiPoint, true>::apply(point, multi_point, result, strategy);
}
};
@@ -134,8 +140,10 @@ struct multipoint_multipoint
{
static const bool interruption_enabled = true;
template <typename Result>
static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2, Result & result)
template <typename Result, typename Strategy>
static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2,
Result & result,
Strategy const& /*strategy*/)
{
{
// TODO: throw on empty input?

View File

@@ -57,7 +57,8 @@ struct relate_impl
implemented_tag
>::type
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
typename detail::relate::result_handler_type
<
@@ -66,7 +67,7 @@ struct relate_impl
typename StaticMaskTrait<Geometry1, Geometry2>::type
>::type handler;
dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler);
dispatch::relate<Geometry1, Geometry2>::apply(g1, g2, handler, strategy);
return handler.result();
}

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -75,28 +75,35 @@ struct get_turns
{
detail::get_turns::no_interrupt_policy interrupt_policy;
apply(turns, geometry1, geometry2, interrupt_policy);
typename strategy::intersection::services::default_strategy
<
typename cs_tag<Geometry1>::type
>::type intersection_strategy;
apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
}
template <typename Turns, typename InterruptPolicy>
template <typename Turns, typename InterruptPolicy, typename IntersectionStrategy>
static inline void apply(Turns & turns,
Geometry1 const& geometry1,
Geometry2 const& geometry2,
InterruptPolicy & interrupt_policy)
InterruptPolicy & interrupt_policy,
IntersectionStrategy const& intersection_strategy)
{
RobustPolicy robust_policy = geometry::get_rescale_policy
<
RobustPolicy
>(geometry1, geometry2);
apply(turns, geometry1, geometry2, interrupt_policy, robust_policy);
apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy, robust_policy);
}
template <typename Turns, typename InterruptPolicy>
template <typename Turns, typename InterruptPolicy, typename IntersectionStrategy>
static inline void apply(Turns & turns,
Geometry1 const& geometry1,
Geometry2 const& geometry2,
InterruptPolicy & interrupt_policy,
IntersectionStrategy const& intersection_strategy,
RobustPolicy const& robust_policy)
{
static const bool reverse1 = detail::overlay::do_reverse
@@ -119,7 +126,8 @@ struct get_turns
reverse2,
GetTurnPolicy
>::apply(0, geometry1, 1, geometry2,
robust_policy, turns, interrupt_policy);
intersection_strategy, robust_policy,
turns, interrupt_policy);
}
};

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -35,16 +35,16 @@ struct result_handler_type<Geometry1, Geometry2, geometry::de9im::matrix, false>
}} // namespace detail::relate
#endif // DOXYGEN_NO_DETAIL
namespace resolve_variant
{
template <typename Geometry1, typename Geometry2>
struct relation
{
template <typename Matrix>
template <typename Matrix, typename Strategy>
static inline Matrix apply(Geometry1 const& geometry1,
Geometry2 const& geometry2)
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -57,11 +57,7 @@ struct relation
Matrix
>::type handler;
dispatch::relate
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, handler);
resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
return handler.result();
}
@@ -70,56 +66,60 @@ struct relation
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct relation<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Matrix>
template <typename Matrix, typename Strategy>
struct visitor : boost::static_visitor<Matrix>
{
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2)
: m_geometry2(geometry2) {}
visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2), m_strategy(strategy) {}
template <typename Geometry1>
Matrix operator()(Geometry1 const& geometry1) const
{
return relation<Geometry1, Geometry2>
::template apply<Matrix>(geometry1, m_geometry2);
::template apply<Matrix>(geometry1, m_geometry2, m_strategy);
}
};
template <typename Matrix>
template <typename Matrix, typename Strategy>
static inline Matrix
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2)
Geometry2 const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Matrix>(geometry2), geometry1);
return boost::apply_visitor(visitor<Matrix, Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct relation<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Matrix>
template <typename Matrix, typename Strategy>
struct visitor : boost::static_visitor<Matrix>
{
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1)
: m_geometry1(geometry1) {}
visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1), m_strategy(strategy) {}
template <typename Geometry2>
Matrix operator()(Geometry2 const& geometry2) const
{
return relation<Geometry1, Geometry2>
::template apply<Matrix>(m_geometry1, geometry2);
::template apply<Matrix>(m_geometry1, geometry2, m_strategy);
}
};
template <typename Matrix>
template <typename Matrix, typename Strategy>
static inline Matrix
apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Matrix>(geometry1), geometry2);
return boost::apply_visitor(visitor<Matrix, Strategy>(geometry1, strategy), geometry2);
}
};
@@ -134,30 +134,63 @@ struct relation
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Matrix>
template <typename Matrix, typename Strategy>
struct visitor : boost::static_visitor<Matrix>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy)
: m_strategy(strategy) {}
template <typename Geometry1, typename Geometry2>
Matrix operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return relation<Geometry1, Geometry2>
::template apply<Matrix>(geometry1, geometry2);
::template apply<Matrix>(geometry1, geometry2, m_strategy);
}
};
template <typename Matrix>
template <typename Matrix, typename Strategy>
static inline Matrix
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor<Matrix>(), geometry1, geometry2);
return boost::apply_visitor(visitor<Matrix, Strategy>(strategy), geometry1, geometry2);
}
};
} // namespace resolve_variant
/*!
\brief Calculates the relation between a pair of geometries as defined in DE-9IM.
\ingroup relation
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Relation}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{relation}
\return The DE-9IM matrix expressing the relation between geometries.
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/relation.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline de9im::matrix relation(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_variant::relation
<
Geometry1,
Geometry2
>::template apply<de9im::matrix>(geometry1, geometry2, strategy);
}
/*!
\brief Calculates the relation between a pair of geometries as defined in DE-9IM.
\ingroup relation
@@ -177,7 +210,7 @@ inline de9im::matrix relation(Geometry1 const& geometry1,
<
Geometry1,
Geometry2
>::template apply<de9im::matrix>(geometry1, geometry2);
>::template apply<de9im::matrix>(geometry1, geometry2, default_strategy());
}

View File

@@ -5,8 +5,10 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -15,8 +17,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_POINT_IN_GEOMETRY_HPP
@@ -35,8 +35,7 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/concepts/within_concept.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/relate.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
@@ -46,6 +45,7 @@ namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within {
// TODO: is this needed?
inline int check_result_type(int result)
{
@@ -83,50 +83,11 @@ int point_in_range(Point const& point, Range const& range, Strategy const& strat
template <typename Geometry, typename Point, typename Range>
inline int point_in_range(Point const& point, Range const& range)
{
typedef typename point_type<Point>::type point_type1;
typedef typename point_type<Geometry>::type point_type2;
typedef typename strategy::within::services::default_strategy
typedef typename strategy::point_in_geometry::services::default_strategy
<
typename tag<Point>::type,
typename tag<Geometry>::type,
typename tag<Point>::type,
typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::type, spherical_tag
>::type,
Point,
Geometry
Point, Geometry
>::type strategy_type;
typedef typename strategy::covered_by::services::default_strategy
<
typename tag<Point>::type,
typename tag<Geometry>::type,
typename tag<Point>::type,
typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::type, spherical_tag
>::type,
Point,
Geometry
>::type strategy_type2;
static const bool same_strategies = boost::is_same<strategy_type, strategy_type2>::value;
BOOST_MPL_ASSERT_MSG((same_strategies),
DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE,
(strategy_type, strategy_type2));
return point_in_range(point, range, strategy_type());
}
@@ -414,50 +375,11 @@ inline int point_in_geometry(Point const& point, Geometry const& geometry, Strat
template <typename Point, typename Geometry>
inline int point_in_geometry(Point const& point, Geometry const& geometry)
{
typedef typename point_type<Point>::type point_type1;
typedef typename point_type<Geometry>::type point_type2;
typedef typename strategy::within::services::default_strategy
typedef typename strategy::point_in_geometry::services::default_strategy
<
typename tag<Point>::type,
typename tag<Geometry>::type,
typename tag<Point>::type,
typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::type, spherical_tag
>::type,
Point,
Geometry
Point, Geometry
>::type strategy_type;
typedef typename strategy::covered_by::services::default_strategy
<
typename tag<Point>::type,
typename tag<Geometry>::type,
typename tag<Point>::type,
typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::type, spherical_tag
>::type,
Point,
Geometry
>::type strategy_type2;
static const bool same_strategies = boost::is_same<strategy_type, strategy_type2>::value;
BOOST_MPL_ASSERT_MSG((same_strategies),
DEFAULT_WITHIN_AND_COVERED_BY_STRATEGIES_NOT_COMPATIBLE,
(strategy_type, strategy_type2));
return point_in_geometry(point, geometry, strategy_type());
}

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, 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)
@@ -49,10 +53,10 @@ template
typename Strategy
>
inline OutputIterator difference_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& strategy)
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -93,25 +97,22 @@ template
typename OutputIterator
>
inline OutputIterator difference_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out)
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
OutputIterator out)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
concepts::check<GeometryOut>();
typedef intersection_strategies
typename strategy::relate::services::default_strategy
<
typename cs_tag<GeometryOut>::type,
Geometry1,
Geometry2,
typename geometry::point_type<GeometryOut>::type,
RobustPolicy
> strategy;
Geometry2
>::type strategy;
return difference_insert<GeometryOut>(geometry1, geometry2,
robust_policy, out, strategy());
robust_policy, out, strategy);
}
@@ -140,7 +141,8 @@ template
typename Collection
>
inline void difference(Geometry1 const& geometry1,
Geometry2 const& geometry2, Collection& output_collection)
Geometry2 const& geometry2,
Collection& output_collection)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
@@ -155,7 +157,8 @@ inline void difference(Geometry1 const& geometry1,
>::type rescale_policy_type;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
= geometry::get_rescale_policy<rescale_policy_type>(geometry1,
geometry2);
detail::difference::difference_insert<geometry_out>(
geometry1, geometry2, robust_policy,

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2014.
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -60,6 +60,29 @@ struct disjoint
: not_implemented<Geometry1, Geometry2>
{};
// If reversal is needed, perform it
template
<
typename Geometry1, typename Geometry2,
std::size_t DimensionCount,
typename Tag1, typename Tag2
>
struct disjoint<Geometry1, Geometry2, DimensionCount, Tag1, Tag2, true>
{
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
return disjoint
<
Geometry2, Geometry1,
DimensionCount,
Tag2, Tag1
>::apply(g2, g1, strategy);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2015, 2016.
// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2016, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -26,6 +26,7 @@
#include <vector>
#include <boost/range.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
@@ -40,7 +41,6 @@
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/not.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
// For trivial checks
@@ -65,6 +65,25 @@ namespace detail { namespace equals
{
template
<
std::size_t Dimension,
std::size_t DimensionCount
>
struct point_point
{
template <typename Point1, typename Point2, typename Strategy>
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
{
return ! detail::disjoint::point_point
<
Point1, Point2,
Dimension, DimensionCount
>::apply(point1, point2, strategy);
}
};
template
<
std::size_t Dimension,
@@ -72,23 +91,23 @@ template
>
struct box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
template <typename Box1, typename Box2, typename Strategy>
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
{
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|| !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
{
return false;
}
return box_box<Dimension + 1, DimensionCount>::apply(box1, box2);
return box_box<Dimension + 1, DimensionCount>::apply(box1, box2, strategy);
}
};
template <std::size_t DimensionCount>
struct box_box<DimensionCount, DimensionCount>
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& , Box2 const& )
template <typename Box1, typename Box2, typename Strategy>
static inline bool apply(Box1 const& , Box2 const& , Strategy const& )
{
return true;
}
@@ -97,8 +116,8 @@ struct box_box<DimensionCount, DimensionCount>
struct segment_segment
{
template <typename Segment1, typename Segment2>
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
template <typename Segment1, typename Segment2, typename Strategy>
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& )
{
return equals::equals_point_point(
indexed_point_view<Segment1 const, 0>(segment1),
@@ -141,33 +160,43 @@ struct length_check
};
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
struct collected_vector
{
typedef typename geometry::select_most_precise
<
typename select_coordinate_type
<
Geometry1, Geometry2
>::type,
double
>::type calculation_type;
typedef geometry::collected_vector
<
calculation_type,
Geometry1,
typename IntersectionStrategy::side_strategy_type
> type;
};
template <typename TrivialCheck>
struct equals_by_collection
{
template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const&)
{
if (! TrivialCheck::apply(geometry1, geometry2))
{
return false;
}
typedef typename geometry::select_most_precise
typedef typename collected_vector
<
typename select_coordinate_type
<
Geometry1, Geometry2
>::type,
double
>::type calculation_type;
Geometry1, Geometry2, Strategy
>::type collected_vector_type;
typedef geometry::collected_vector
<
calculation_type,
Geometry1
> collected_vector;
std::vector<collected_vector> c1, c2;
std::vector<collected_vector_type> c1, c2;
geometry::collect_vectors(c1, geometry1);
geometry::collect_vectors(c2, geometry2);
@@ -195,6 +224,53 @@ struct equals_by_relate
>
{};
// If collect_vectors which is a SideStrategy-dispatched optimization
// is implemented in a way consistent with the Intersection/Side Strategy
// then collect_vectors is used, otherwise relate is used.
// NOTE: the result could be coneptually different for invalid
// geometries in different coordinate systems because collect_vectors
// and relate treat invalid geometries differently.
template<typename TrivialCheck>
struct equals_by_collection_or_relate
{
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
typedef typename boost::is_base_of
<
nyi::not_implemented_tag,
typename collected_vector
<
Geometry1, Geometry2, Strategy
>::type
>::type enable_relate_type;
return apply(geometry1, geometry2, strategy, enable_relate_type());
}
private:
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy,
boost::false_type /*enable_relate*/)
{
return equals_by_collection<TrivialCheck>::apply(geometry1, geometry2, strategy);
}
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy,
boost::true_type /*enable_relate*/)
{
return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
}
};
}} // namespace detail::equals
#endif // DOXYGEN_NO_DETAIL
@@ -226,7 +302,8 @@ template
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
return equals
<
@@ -234,19 +311,30 @@ struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
Tag2, Tag1,
DimensionCount,
false
>::apply(g2, g1);
>::apply(g2, g1, strategy);
}
};
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
: geometry::detail::not_
<
detail::disjoint::point_point<P1, P2, 0, DimensionCount>
>
: detail::equals::point_point<0, DimensionCount>
{};
template <typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount, bool Reverse>
struct equals<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, DimensionCount, Reverse>
: detail::equals::equals_by_relate<MultiPoint1, MultiPoint2>
{};
template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
struct equals<MultiPoint, Point, multi_point_tag, point_tag, DimensionCount, Reverse>
: detail::equals::equals_by_relate<MultiPoint, Point>
{};
template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
struct equals<Point, MultiPoint, point_tag, multi_point_tag, DimensionCount, Reverse>
: detail::equals::equals_by_relate<Point, MultiPoint>
{};
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
@@ -256,19 +344,19 @@ struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
template <typename Ring1, typename Ring2, bool Reverse>
struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
: detail::equals::equals_by_collection<detail::equals::area_check>
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
template <typename Polygon1, typename Polygon2, bool Reverse>
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
: detail::equals::equals_by_collection<detail::equals::area_check>
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
template <typename Polygon, typename Ring, bool Reverse>
struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
: detail::equals::equals_by_collection<detail::equals::area_check>
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
@@ -290,7 +378,6 @@ struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reve
template <typename LineString1, typename LineString2, bool Reverse>
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
//: detail::equals::equals_by_collection<detail::equals::length_check>
: detail::equals::equals_by_relate<LineString1, LineString2>
{};
@@ -313,7 +400,7 @@ struct equals
2,
Reverse
>
: detail::equals::equals_by_collection<detail::equals::area_check>
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
@@ -325,7 +412,7 @@ struct equals
2,
Reverse
>
: detail::equals::equals_by_collection<detail::equals::area_check>
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
template <typename MultiPolygon, typename Ring, bool Reverse>
@@ -336,7 +423,7 @@ struct equals
2,
Reverse
>
: detail::equals::equals_by_collection<detail::equals::area_check>
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
{};
@@ -344,80 +431,129 @@ struct equals
#endif // DOXYGEN_NO_DISPATCH
namespace resolve_strategy
{
struct equals
{
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return dispatch::equals
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
default_strategy)
{
typedef typename strategy::relate::services::default_strategy
<
Geometry1,
Geometry2
>::type strategy_type;
return dispatch::equals
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy_type());
}
};
} // namespace resolve_strategy
namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct equals
{
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2)
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check_concepts_and_equal_dimensions
<
Geometry1 const,
Geometry2 const
>();
<
Geometry1 const,
Geometry2 const
>();
return dispatch::equals<Geometry1, Geometry2>
::apply(geometry1, geometry2);
return resolve_strategy::equals
::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2)
visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2)
, m_strategy(strategy)
{}
template <typename Geometry1>
inline bool operator()(Geometry1 const& geometry1) const
{
return equals<Geometry1, Geometry2>
::apply(geometry1, m_geometry2);
::apply(geometry1, m_geometry2, m_strategy);
}
};
template <typename Strategy>
static inline bool apply(
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2
Geometry2 const& geometry2,
Strategy const& strategy
)
{
return boost::apply_visitor(visitor(geometry2), geometry1);
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Strategy>
struct visitor: static_visitor<bool>
{
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1)
visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1)
, m_strategy(strategy)
{}
template <typename Geometry2>
inline bool operator()(Geometry2 const& geometry2) const
{
return equals<Geometry1, Geometry2>
::apply(m_geometry1, geometry2);
::apply(m_geometry1, geometry2, m_strategy);
}
};
template <typename Strategy>
static inline bool apply(
Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy
)
{
return boost::apply_visitor(visitor(geometry1), geometry2);
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -430,30 +566,70 @@ struct equals<
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
>
{
template <typename Strategy>
struct visitor: static_visitor<bool>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
inline bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return equals<Geometry1, Geometry2>
::apply(geometry1, geometry2);
::apply(geometry1, geometry2, m_strategy);
}
};
template <typename Strategy>
static inline bool apply(
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy
)
{
return boost::apply_visitor(visitor(), geometry1, geometry2);
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
} // namespace resolve_variant
/*!
\brief \brief_check{are spatially equal}
\details \details_check12{equals, is spatially equal}. Spatially equal means
that the same point set is included. A box can therefore be spatially equal
to a ring or a polygon, or a linestring can be spatially equal to a
multi-linestring or a segment. This only works theoretically, not all
combinations are implemented yet.
\ingroup equals
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Equals}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{equals}
\return \return_check2{are spatially equal}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/equals.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool equals(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_variant::equals
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
/*!
\brief \brief_check{are spatially equal}
\details \details_check12{equals, is spatially equal}. Spatially equal means
@@ -469,13 +645,12 @@ struct equals<
\return \return_check2{are spatially equal}
\qbk{[include reference/algorithms/equals.qbk]}
*/
template <typename Geometry1, typename Geometry2>
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
return resolve_variant::equals<Geometry1, Geometry2>
::apply(geometry1, geometry2);
::apply(geometry1, geometry2, default_strategy());
}

View File

@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2013-2014.
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -29,6 +30,8 @@
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/strategies/relate.hpp>
namespace boost { namespace geometry
{
@@ -52,6 +55,10 @@ inline bool intersects(Geometry const& geometry)
concepts::check<Geometry const>();
typedef typename geometry::point_type<Geometry>::type point_type;
typedef typename strategy::relate::services::default_strategy
<
Geometry, Geometry
>::type strategy_type;
typedef detail::no_rescale_policy rescale_policy_type;
typedef detail::overlay::turn_info
@@ -67,17 +74,44 @@ inline bool intersects(Geometry const& geometry)
detail::overlay::assign_null_policy
> turn_policy;
strategy_type strategy;
rescale_policy_type robust_policy;
detail::disjoint::disjoint_interrupt_policy policy;
detail::self_get_turn_points::get_turns
<
turn_policy
>::apply(geometry, robust_policy, turns, policy);
>::apply(geometry, strategy, robust_policy, turns, policy);
return policy.has_intersections;
}
/*!
\brief \brief_check2{have at least one intersection}
\ingroup intersects
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Intersects}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{intersects}
\return \return_check2{intersect each other}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/intersects.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool intersects(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
return ! geometry::disjoint(geometry1, geometry2, strategy);
}
/*!
\brief \brief_check2{have at least one intersection}
\ingroup intersects

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -113,8 +113,8 @@ struct box_box_loop<DimensionCount, DimensionCount>
struct box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& b1, Box2 const& b2)
template <typename Box1, typename Box2, typename Strategy>
static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
{
bool overlaps = true;
bool within1 = true;
@@ -137,7 +137,6 @@ struct box_box
}} // namespace detail::overlaps
#endif // DOXYGEN_NO_DETAIL
//struct not_implemented_for_this_geometry_type : public boost::false_type {};
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
@@ -170,6 +169,35 @@ struct overlaps<Box1, Box2, box_tag, box_tag>
#endif // DOXYGEN_NO_DISPATCH
/*!
\brief \brief_check2{overlap}
\ingroup overlaps
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Overlaps}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{overlaps}
\return \return_check2{overlap}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/overlaps.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool overlaps(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
return dispatch::overlaps
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, strategy);
}
/*!
\brief \brief_check2{overlap}
\ingroup overlaps
@@ -187,11 +215,17 @@ inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
typedef typename strategy::relate::services::default_strategy
<
Geometry1,
Geometry2
>::type strategy_type;
return dispatch::overlaps
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2);
>::apply(geometry1, geometry2, strategy_type());
}
}} // namespace boost::geometry

View File

@@ -2,10 +2,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// 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
@@ -276,14 +277,10 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
concepts::check<Geometry2 const>();
concepts::check<GeometryOut>();
typedef intersection_strategies
typedef typename strategy::intersection::services::default_strategy
<
typename cs_tag<GeometryOut>::type,
Geometry1,
Geometry2,
typename geometry::point_type<GeometryOut>::type,
RobustPolicy
> strategy_type;
typename cs_tag<GeometryOut>::type
>::type strategy_type;
return sym_difference_insert<GeometryOut>(geometry1, geometry2, robust_policy, out, strategy_type());
}

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -104,8 +104,8 @@ struct box_box_loop<DimensionCount, DimensionCount>
struct box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& b1, Box2 const& b2)
template <typename Box1, typename Box2, typename Strategy>
static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/)
{
BOOST_STATIC_ASSERT((boost::is_same
<
@@ -205,15 +205,17 @@ struct areal_interrupt_policy
}
};
template<typename Geometry>
template<typename Geometry, typename PointInRingStrategy>
struct check_each_ring_for_within
{
bool has_within;
Geometry const& m_geometry;
PointInRingStrategy const& m_strategy;
inline check_each_ring_for_within(Geometry const& g)
inline check_each_ring_for_within(Geometry const& g, PointInRingStrategy const& strategy)
: has_within(false)
, m_geometry(g)
, m_strategy(strategy)
{}
template <typename Range>
@@ -221,18 +223,31 @@ struct check_each_ring_for_within
{
typename geometry::point_type<Range>::type p;
geometry::point_on_border(p, range);
if ( !has_within && geometry::within(p, m_geometry) )
if ( !has_within && geometry::within(p, m_geometry, m_strategy) )
{
has_within = true;
}
}
};
template <typename FirstGeometry, typename SecondGeometry>
template <typename FirstGeometry, typename SecondGeometry, typename IntersectionStrategy>
inline bool rings_containing(FirstGeometry const& geometry1,
SecondGeometry const& geometry2)
SecondGeometry const& geometry2,
IntersectionStrategy const& strategy)
{
check_each_ring_for_within<FirstGeometry> checker(geometry1);
// NOTE: This strategy could be defined inside IntersectionStrategy
typedef typename IntersectionStrategy::template point_in_geometry_strategy
<
FirstGeometry, SecondGeometry
>::type point_in_ring_strategy_type;
point_in_ring_strategy_type point_in_ring_strategy
= strategy.template get_point_in_geometry_strategy<FirstGeometry, SecondGeometry>();
check_each_ring_for_within
<
FirstGeometry, point_in_ring_strategy_type
> checker(geometry1, point_in_ring_strategy);
geometry::detail::for_each_range(geometry2, checker);
return checker.has_within;
}
@@ -240,8 +255,10 @@ inline bool rings_containing(FirstGeometry const& geometry1,
template <typename Geometry1, typename Geometry2>
struct areal_areal
{
static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
template <typename IntersectionStrategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
IntersectionStrategy const& strategy)
{
typedef detail::no_rescale_policy rescale_policy_type;
typedef typename geometry::point_type<Geometry1>::type point_type;
@@ -259,11 +276,11 @@ struct areal_areal
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
detail::overlay::assign_null_policy
>(geometry1, geometry2, robust_policy, turns, policy);
>(geometry1, geometry2, strategy, robust_policy, turns, policy);
return policy.result()
&& ! geometry::detail::touches::rings_containing(geometry1, geometry2)
&& ! geometry::detail::touches::rings_containing(geometry2, geometry1);
&& ! geometry::detail::touches::rings_containing(geometry1, geometry2, strategy)
&& ! geometry::detail::touches::rings_containing(geometry2, geometry1, strategy);
}
};
@@ -271,10 +288,10 @@ struct areal_areal
struct use_point_in_geometry
{
template <typename Point, typename Geometry>
static inline bool apply(Point const& point, Geometry const& geometry)
template <typename Point, typename Geometry, typename Strategy>
static inline bool apply(Point const& point, Geometry const& geometry, Strategy const& strategy)
{
return detail::within::point_in_geometry(point, geometry) == 0;
return detail::within::point_in_geometry(point, geometry, strategy) == 0;
}
};
@@ -288,7 +305,8 @@ namespace dispatch {
template
<
typename Geometry1, typename Geometry2,
typename Geometry1,
typename Geometry2,
typename Tag1 = typename tag<Geometry1>::type,
typename Tag2 = typename tag<Geometry2>::type,
typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type,
@@ -309,18 +327,30 @@ template
struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
: touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
{
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
template <typename Strategy>
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
{
return touches<Geometry2, Geometry1>::apply(g2, g1);
return touches<Geometry2, Geometry1>::apply(g2, g1, strategy);
}
};
// P/P
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2>
struct touches<Geometry1, Geometry2, Tag1, Tag2, pointlike_tag, pointlike_tag, false>
template <typename Geometry1, typename Geometry2, typename Tag2>
struct touches<Geometry1, Geometry2, point_tag, Tag2, pointlike_tag, pointlike_tag, false>
{
static inline bool apply(Geometry1 const& , Geometry2 const& )
template <typename Strategy>
static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const&)
{
return false;
}
};
template <typename Geometry1, typename Geometry2, typename Tag2>
struct touches<Geometry1, Geometry2, multi_point_tag, Tag2, pointlike_tag, pointlike_tag, false>
{
template <typename Strategy>
static inline bool apply(Geometry1 const&, Geometry2 const&, Strategy const&)
{
return false;
}
@@ -403,66 +433,115 @@ struct touches<Areal1, Areal2, ring_tag, ring_tag, areal_tag, areal_tag, false>
#endif // DOXYGEN_NO_DISPATCH
namespace resolve_strategy
{
struct touches
{
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return dispatch::touches
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
default_strategy)
{
typedef typename strategy::relate::services::default_strategy
<
Geometry1,
Geometry2
>::type strategy_type;
return dispatch::touches
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy_type());
}
};
} // namespace resolve_strategy
namespace resolve_variant {
template <typename Geometry1, typename Geometry2>
struct touches
{
static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
template <typename Strategy>
static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
return dispatch::touches<Geometry1, Geometry2>
::apply(geometry1, geometry2);
return resolve_strategy::touches::apply(geometry1, geometry2, strategy);
}
};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
{
template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry2 const& m_geometry2;
Strategy const& m_strategy;
visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {}
visitor(Geometry2 const& geometry2, Strategy const& strategy)
: m_geometry2(geometry2)
, m_strategy(strategy)
{}
template <typename Geometry1>
bool operator()(Geometry1 const& geometry1) const
{
return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2);
return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy);
}
};
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2)
template <typename Strategy>
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(geometry2), geometry1);
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
}
};
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Geometry1 const& m_geometry1;
Strategy const& m_strategy;
visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {}
visitor(Geometry1 const& geometry1, Strategy const& strategy)
: m_geometry1(geometry1)
, m_strategy(strategy)
{}
template <typename Geometry2>
bool operator()(Geometry2 const& geometry2) const
{
return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2);
return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy);
}
};
static inline bool
apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
template <typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(geometry1), geometry2);
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
}
};
@@ -471,21 +550,29 @@ template <BOOST_VARIANT_ENUM_PARAMS(typename T1),
struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
{
template <typename Strategy>
struct visitor: boost::static_visitor<bool>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy)
: m_strategy(strategy)
{}
template <typename Geometry1, typename Geometry2>
bool operator()(Geometry1 const& geometry1,
Geometry2 const& geometry2) const
{
return touches<Geometry1, Geometry2>::apply(geometry1, geometry2);
return touches<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy);
}
};
static inline bool
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
template <typename Strategy>
static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(), geometry1, geometry2);
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
}
};
@@ -496,6 +583,10 @@ struct self_touches
{
concepts::check<Geometry const>();
typedef typename strategy::relate::services::default_strategy
<
Geometry, Geometry
>::type strategy_type;
typedef detail::no_rescale_policy rescale_policy_type;
typedef typename geometry::point_type<Geometry>::type point_type;
typedef detail::overlay::turn_info
@@ -511,11 +602,12 @@ struct self_touches
std::deque<turn_info> turns;
detail::touches::areal_interrupt_policy policy;
strategy_type strategy;
rescale_policy_type robust_policy;
detail::self_get_turn_points::get_turns
<
policy_type
>::apply(geometry, robust_policy, turns, policy);
>::apply(geometry, strategy, robust_policy, turns, policy);
return policy.result();
}
@@ -578,7 +670,35 @@ inline bool touches(Geometry const& geometry)
template <typename Geometry1, typename Geometry2>
inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
return resolve_variant::touches<Geometry1, Geometry2>::apply(geometry1, geometry2);
return resolve_variant::touches
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, default_strategy());
}
/*!
\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
\ingroup touches
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
\tparam Strategy \tparam_strategy{Touches}
\param geometry1 \param_geometry
\param geometry2 \param_geometry
\param strategy \param_strategy{touches}
\return \return_check2{touch each other}
\qbk{distinguish,with strategy}
\qbk{[include reference/algorithms/touches.qbk]}
*/
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool touches(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_variant::touches
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}

View File

@@ -2,10 +2,11 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// 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
@@ -214,14 +215,10 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
Geometry2
>::type rescale_policy_type;
typedef intersection_strategies
typename strategy::intersection::services::default_strategy
<
typename cs_tag<GeometryOut>::type,
Geometry1,
Geometry2,
typename geometry::point_type<GeometryOut>::type,
rescale_policy_type
> strategy;
typename cs_tag<GeometryOut>::type
>::type strategy;
rescale_policy_type robust_policy
= geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
@@ -229,7 +226,7 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
return dispatch::union_insert
<
Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, robust_policy, out, strategy());
>::apply(geometry1, geometry2, robust_policy, out, strategy);
}

View File

@@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2013, 2014.
// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@@ -14,8 +16,6 @@
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
@@ -52,6 +52,7 @@
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/relate.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
@@ -75,9 +76,13 @@ struct use_point_in_geometry
struct use_relate
{
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/)
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
return Strategy::apply(geometry1, geometry2);
typedef typename detail::de9im::static_mask_within_type
<
Geometry1, Geometry2
>::type within_mask;
return geometry::relate(geometry1, geometry2, within_mask(), strategy);
}
};
@@ -300,23 +305,8 @@ struct within
Geometry2 const& geometry2,
default_strategy)
{
typedef typename point_type<Geometry1>::type point_type1;
typedef typename point_type<Geometry2>::type point_type2;
typedef typename strategy::within::services::default_strategy
<
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
typename tag<Geometry1>::type,
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
typename tag_cast
<
typename cs_tag<point_type1>::type, spherical_tag
>::type,
typename tag_cast
<
typename cs_tag<point_type2>::type, spherical_tag
>::type,
Geometry1,
Geometry2
>::type strategy_type;
@@ -517,8 +507,9 @@ inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
}
*/
template<typename Geometry1, typename Geometry2, typename Strategy>
inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
Strategy const& strategy)
inline bool within(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return resolve_variant::within
<

View File

@@ -97,7 +97,7 @@ public:
CT const d = acos(cos_d); // [0, pi]
CT const sin_d = sin(d); // [-1, 1]
if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
{
CT const K = math::sqr(sin_lat1-sin_lat2);

View File

@@ -0,0 +1,578 @@
// Boost.Geometry
// Copyright (c) 2015-2016 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, 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_FORMULAS_AREA_FORMULAS_HPP
#define BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP
#include <boost/geometry/algorithms/detail/flattening.hpp>
#include <boost/math/special_functions/hypot.hpp>
namespace boost { namespace geometry { namespace formula
{
/*!
\brief Formulas for computing spherical and ellipsoidal polygon area.
The current class computes the area of the trapezoid defined by a segment
the two meridians passing by the endpoints and the equator.
\author See
- Danielsen JS, The area under the geodesic. Surv Rev 30(232):
6166, 1989
- Charles F.F Karney, Algorithms for geodesics, 2011
https://arxiv.org/pdf/1109.4448.pdf
*/
template <
typename CT,
std::size_t SeriesOrder = 2,
bool ExpandEpsN = true
>
class area_formulas
{
public:
//TODO: move the following to a more general space to be used by other
// classes as well
/*
Evaluate the polynomial in x using Horner's method.
*/
template <typename NT, typename IteratorType>
static inline NT horner_evaluate(NT x,
IteratorType begin,
IteratorType end)
{
NT result(0);
IteratorType it = end;
do
{
result = result * x + *--it;
}
while (it != begin);
return result;
}
/*
Clenshaw algorithm for summing trigonometric series
https://en.wikipedia.org/wiki/Clenshaw_algorithm
*/
template <typename NT, typename IteratorType>
static inline NT clenshaw_sum(NT cosx,
IteratorType begin,
IteratorType end)
{
IteratorType it = end;
bool odd = true;
CT b_k, b_k1(0), b_k2(0);
do
{
CT c_k = odd ? *--it : NT(0);
b_k = c_k + NT(2) * cosx * b_k1 - b_k2;
b_k2 = b_k1;
b_k1 = b_k;
odd = !odd;
}
while (it != begin);
return *begin + b_k1 * cosx - b_k2;
}
template<typename T>
static inline void normalize(T& x, T& y)
{
T h = boost::math::hypot(x, y);
x /= h;
y /= h;
}
/*
Generate and evaluate the series expansion of the following integral
I4 = -integrate( (t(ep2) - t(k2*sin(sigma1)^2)) / (ep2 - k2*sin(sigma1)^2)
* sin(sigma1)/2, sigma1, pi/2, sigma )
where
t(x) = sqrt(1+1/x)*asinh(sqrt(x)) + x
valid for ep2 and k2 small. We substitute k2 = 4 * eps / (1 - eps)^2
and ep2 = 4 * n / (1 - n)^2 and expand in eps and n.
The resulting sum of the series is of the form
sum(C4[l] * cos((2*l+1)*sigma), l, 0, maxpow-1) )
The above expansion is performed in Computer Algebra System Maxima.
The C++ code (that yields the function evaluate_coeffs_n below) is generated
by the following Maxima script and is based on script:
http://geographiclib.sourceforge.net/html/geod.mac
// Maxima script begin
taylordepth:5$
ataylor(expr,var,ord):=expand(ratdisrep(taylor(expr,var,0,ord)))$
jtaylor(expr,var1,var2,ord):=block([zz],expand(subst([zz=1],
ratdisrep(taylor(subst([var1=zz*var1,var2=zz*var2],expr),zz,0,ord)))))$
compute(maxpow):=block([int,t,intexp,area, x,ep2,k2],
maxpow:maxpow-1,
t : sqrt(1+1/x) * asinh(sqrt(x)) + x,
int:-(tf(ep2) - tf(k2*sin(sigma)^2)) / (ep2 - k2*sin(sigma)^2)
* sin(sigma)/2,
int:subst([tf(ep2)=subst([x=ep2],t),
tf(k2*sin(sigma)^2)=subst([x=k2*sin(sigma)^2],t)],
int),
int:subst([abs(sin(sigma))=sin(sigma)],int),
int:subst([k2=4*eps/(1-eps)^2,ep2=4*n/(1-n)^2],int),
intexp:jtaylor(int,n,eps,maxpow),
area:trigreduce(integrate(intexp,sigma)),
area:expand(area-subst(sigma=%pi/2,area)),
for i:0 thru maxpow do C4[i]:coeff(area,cos((2*i+1)*sigma)),
if expand(area-sum(C4[i]*cos((2*i+1)*sigma),i,0,maxpow)) # 0
then error("left over terms in I4"),
'done)$
printcode(maxpow):=
block([tab2:" ",tab3:" "],
print(" switch (SeriesOrder) {"),
for nn:1 thru maxpow do block([c],
print(concat(tab2,"case ",string(nn-1),":")),
c:0,
for m:0 thru nn-1 do block(
[q:jtaylor(subst([n=n],C4[m]),n,eps,nn-1),
linel:1200],
for j:m thru nn-1 do (
print(concat(tab3,"coeffs_n[",c,"] = ",
string(horner(coeff(q,eps,j))),";")),
c:c+1)
),
print(concat(tab3,"break;"))),
print(" }"),
'done)$
maxpow:6$
compute(maxpow)$
printcode(maxpow)$
// Maxima script end
In the resulting code we should replace each number x by CT(x)
e.g. using the following scirpt:
sed -e 's/[0-9]\+/CT(&)/g; s/\[CT(/\[/g; s/)\]/\]/g;
s/case\sCT(/case /g; s/):/:/g'
*/
static inline void evaluate_coeffs_n(CT n, CT coeffs_n[])
{
switch (SeriesOrder) {
case 0:
coeffs_n[0] = CT(2)/CT(3);
break;
case 1:
coeffs_n[0] = (CT(10)-CT(4)*n)/CT(15);
coeffs_n[1] = -CT(1)/CT(5);
coeffs_n[2] = CT(1)/CT(45);
break;
case 2:
coeffs_n[0] = (n*(CT(8)*n-CT(28))+CT(70))/CT(105);
coeffs_n[1] = (CT(16)*n-CT(7))/CT(35);
coeffs_n[2] = -CT(2)/CT(105);
coeffs_n[3] = (CT(7)-CT(16)*n)/CT(315);
coeffs_n[4] = -CT(2)/CT(105);
coeffs_n[5] = CT(4)/CT(525);
break;
case 3:
coeffs_n[0] = (n*(n*(CT(4)*n+CT(24))-CT(84))+CT(210))/CT(315);
coeffs_n[1] = ((CT(48)-CT(32)*n)*n-CT(21))/CT(105);
coeffs_n[2] = (-CT(32)*n-CT(6))/CT(315);
coeffs_n[3] = CT(11)/CT(315);
coeffs_n[4] = (n*(CT(32)*n-CT(48))+CT(21))/CT(945);
coeffs_n[5] = (CT(64)*n-CT(18))/CT(945);
coeffs_n[6] = -CT(1)/CT(105);
coeffs_n[7] = (CT(12)-CT(32)*n)/CT(1575);
coeffs_n[8] = -CT(8)/CT(1575);
coeffs_n[9] = CT(8)/CT(2205);
break;
case 4:
coeffs_n[0] = (n*(n*(n*(CT(16)*n+CT(44))+CT(264))-CT(924))+CT(2310))/CT(3465);
coeffs_n[1] = (n*(n*(CT(48)*n-CT(352))+CT(528))-CT(231))/CT(1155);
coeffs_n[2] = (n*(CT(1088)*n-CT(352))-CT(66))/CT(3465);
coeffs_n[3] = (CT(121)-CT(368)*n)/CT(3465);
coeffs_n[4] = CT(4)/CT(1155);
coeffs_n[5] = (n*((CT(352)-CT(48)*n)*n-CT(528))+CT(231))/CT(10395);
coeffs_n[6] = ((CT(704)-CT(896)*n)*n-CT(198))/CT(10395);
coeffs_n[7] = (CT(80)*n-CT(99))/CT(10395);
coeffs_n[8] = CT(4)/CT(1155);
coeffs_n[9] = (n*(CT(320)*n-CT(352))+CT(132))/CT(17325);
coeffs_n[10] = (CT(384)*n-CT(88))/CT(17325);
coeffs_n[11] = -CT(8)/CT(1925);
coeffs_n[12] = (CT(88)-CT(256)*n)/CT(24255);
coeffs_n[13] = -CT(16)/CT(8085);
coeffs_n[14] = CT(64)/CT(31185);
break;
case 5:
coeffs_n[0] = (n*(n*(n*(n*(CT(100)*n+CT(208))+CT(572))+CT(3432))-CT(12012))+CT(30030))
/CT(45045);
coeffs_n[1] = (n*(n*(n*(CT(64)*n+CT(624))-CT(4576))+CT(6864))-CT(3003))/CT(15015);
coeffs_n[2] = (n*((CT(14144)-CT(10656)*n)*n-CT(4576))-CT(858))/CT(45045);
coeffs_n[3] = ((-CT(224)*n-CT(4784))*n+CT(1573))/CT(45045);
coeffs_n[4] = (CT(1088)*n+CT(156))/CT(45045);
coeffs_n[5] = CT(97)/CT(15015);
coeffs_n[6] = (n*(n*((-CT(64)*n-CT(624))*n+CT(4576))-CT(6864))+CT(3003))/CT(135135);
coeffs_n[7] = (n*(n*(CT(5952)*n-CT(11648))+CT(9152))-CT(2574))/CT(135135);
coeffs_n[8] = (n*(CT(5792)*n+CT(1040))-CT(1287))/CT(135135);
coeffs_n[9] = (CT(468)-CT(2944)*n)/CT(135135);
coeffs_n[10] = CT(1)/CT(9009);
coeffs_n[11] = (n*((CT(4160)-CT(1440)*n)*n-CT(4576))+CT(1716))/CT(225225);
coeffs_n[12] = ((CT(4992)-CT(8448)*n)*n-CT(1144))/CT(225225);
coeffs_n[13] = (CT(1856)*n-CT(936))/CT(225225);
coeffs_n[14] = CT(8)/CT(10725);
coeffs_n[15] = (n*(CT(3584)*n-CT(3328))+CT(1144))/CT(315315);
coeffs_n[16] = (CT(1024)*n-CT(208))/CT(105105);
coeffs_n[17] = -CT(136)/CT(63063);
coeffs_n[18] = (CT(832)-CT(2560)*n)/CT(405405);
coeffs_n[19] = -CT(128)/CT(135135);
coeffs_n[20] = CT(128)/CT(99099);
break;
}
}
/*
Expand in k2 and ep2.
*/
static inline void evaluate_coeffs_ep(CT ep, CT coeffs_n[])
{
switch (SeriesOrder) {
case 0:
coeffs_n[0] = CT(2)/CT(3);
break;
case 1:
coeffs_n[0] = (CT(10)-ep)/CT(15);
coeffs_n[1] = -CT(1)/CT(20);
coeffs_n[2] = CT(1)/CT(180);
break;
case 2:
coeffs_n[0] = (ep*(CT(4)*ep-CT(7))+CT(70))/CT(105);
coeffs_n[1] = (CT(4)*ep-CT(7))/CT(140);
coeffs_n[2] = CT(1)/CT(42);
coeffs_n[3] = (CT(7)-CT(4)*ep)/CT(1260);
coeffs_n[4] = -CT(1)/CT(252);
coeffs_n[5] = CT(1)/CT(2100);
break;
case 3:
coeffs_n[0] = (ep*((CT(12)-CT(8)*ep)*ep-CT(21))+CT(210))/CT(315);
coeffs_n[1] = ((CT(12)-CT(8)*ep)*ep-CT(21))/CT(420);
coeffs_n[2] = (CT(3)-CT(2)*ep)/CT(126);
coeffs_n[3] = -CT(1)/CT(72);
coeffs_n[4] = (ep*(CT(8)*ep-CT(12))+CT(21))/CT(3780);
coeffs_n[5] = (CT(2)*ep-CT(3))/CT(756);
coeffs_n[6] = CT(1)/CT(360);
coeffs_n[7] = (CT(3)-CT(2)*ep)/CT(6300);
coeffs_n[8] = -CT(1)/CT(1800);
coeffs_n[9] = CT(1)/CT(17640);
break;
case 4:
coeffs_n[0] = (ep*(ep*(ep*(CT(64)*ep-CT(88))+CT(132))-CT(231))+CT(2310))/CT(3465);
coeffs_n[1] = (ep*(ep*(CT(64)*ep-CT(88))+CT(132))-CT(231))/CT(4620);
coeffs_n[2] = (ep*(CT(16)*ep-CT(22))+CT(33))/CT(1386);
coeffs_n[3] = (CT(8)*ep-CT(11))/CT(792);
coeffs_n[4] = CT(1)/CT(110);
coeffs_n[5] = (ep*((CT(88)-CT(64)*ep)*ep-CT(132))+CT(231))/CT(41580);
coeffs_n[6] = ((CT(22)-CT(16)*ep)*ep-CT(33))/CT(8316);
coeffs_n[7] = (CT(11)-CT(8)*ep)/CT(3960);
coeffs_n[8] = -CT(1)/CT(495);
coeffs_n[9] = (ep*(CT(16)*ep-CT(22))+CT(33))/CT(69300);
coeffs_n[10] = (CT(8)*ep-CT(11))/CT(19800);
coeffs_n[11] = CT(1)/CT(1925);
coeffs_n[12] = (CT(11)-CT(8)*ep)/CT(194040);
coeffs_n[13] = -CT(1)/CT(10780);
coeffs_n[14] = CT(1)/CT(124740);
break;
case 5:
coeffs_n[0] = (ep*(ep*(ep*((CT(832)-CT(640)*ep)*ep-CT(1144))+CT(1716))-CT(3003))+CT(30030))/CT(45045);
coeffs_n[1] = (ep*(ep*((CT(832)-CT(640)*ep)*ep-CT(1144))+CT(1716))-CT(3003))/CT(60060);
coeffs_n[2] = (ep*((CT(208)-CT(160)*ep)*ep-CT(286))+CT(429))/CT(18018);
coeffs_n[3] = ((CT(104)-CT(80)*ep)*ep-CT(143))/CT(10296);
coeffs_n[4] = (CT(13)-CT(10)*ep)/CT(1430);
coeffs_n[5] = -CT(1)/CT(156);
coeffs_n[6] = (ep*(ep*(ep*(CT(640)*ep-CT(832))+CT(1144))-CT(1716))+CT(3003))/CT(540540);
coeffs_n[7] = (ep*(ep*(CT(160)*ep-CT(208))+CT(286))-CT(429))/CT(108108);
coeffs_n[8] = (ep*(CT(80)*ep-CT(104))+CT(143))/CT(51480);
coeffs_n[9] = (CT(10)*ep-CT(13))/CT(6435);
coeffs_n[10] = CT(5)/CT(3276);
coeffs_n[11] = (ep*((CT(208)-CT(160)*ep)*ep-CT(286))+CT(429))/CT(900900);
coeffs_n[12] = ((CT(104)-CT(80)*ep)*ep-CT(143))/CT(257400);
coeffs_n[13] = (CT(13)-CT(10)*ep)/CT(25025);
coeffs_n[14] = -CT(1)/CT(2184);
coeffs_n[15] = (ep*(CT(80)*ep-CT(104))+CT(143))/CT(2522520);
coeffs_n[16] = (CT(10)*ep-CT(13))/CT(140140);
coeffs_n[17] = CT(5)/CT(45864);
coeffs_n[18] = (CT(13)-CT(10)*ep)/CT(1621620);
coeffs_n[19] = -CT(1)/CT(58968);
coeffs_n[20] = CT(1)/CT(792792);
break;
}
}
/*
Given the set of coefficients coeffs1[] evaluate on var2 and return
the set of coefficients coeffs2[]
*/
static inline void evaluate_coeffs_var2(CT var2,
CT coeffs1[],
CT coeffs2[]){
std::size_t begin(0), end(0);
for(std::size_t i = 0; i <= SeriesOrder; i++){
end = begin + SeriesOrder + 1 - i;
coeffs2[i] = ((i==0) ? CT(1) : pow(var2,int(i)))
* horner_evaluate(var2, coeffs1 + begin, coeffs1 + end);
begin = end;
}
}
/*
Compute the spherical excess of a geodesic (or shperical) segment
*/
template <
bool LongSegment,
typename PointOfSegment
>
static inline CT spherical(PointOfSegment const& p1,
PointOfSegment const& p2)
{
CT excess;
if(LongSegment) // not for segments parallel to equator
{
CT cbet1 = cos(geometry::get_as_radian<1>(p1));
CT sbet1 = sin(geometry::get_as_radian<1>(p1));
CT cbet2 = cos(geometry::get_as_radian<1>(p2));
CT sbet2 = sin(geometry::get_as_radian<1>(p2));
CT omg12 = geometry::get_as_radian<0>(p1)
- geometry::get_as_radian<0>(p2);
CT comg12 = cos(omg12);
CT somg12 = sin(omg12);
CT alp1 = atan2(cbet1 * sbet2
- sbet1 * cbet2 * comg12,
cbet2 * somg12);
CT alp2 = atan2(cbet1 * sbet2 * comg12
- sbet1 * cbet2,
cbet1 * somg12);
excess = alp2 - alp1;
} else {
// Trapezoidal formula
CT tan_lat1 =
tan(geometry::get_as_radian<1>(p1) / 2.0);
CT tan_lat2 =
tan(geometry::get_as_radian<1>(p2) / 2.0);
excess = CT(2.0)
* atan(((tan_lat1 + tan_lat2) / (CT(1) + tan_lat1 * tan_lat2))
* tan((geometry::get_as_radian<0>(p2)
- geometry::get_as_radian<0>(p1)) / 2));
}
return excess;
}
struct return_type_ellipsoidal
{
return_type_ellipsoidal()
: spherical_term(0),
ellipsoidal_term(0)
{}
CT spherical_term;
CT ellipsoidal_term;
};
/*
Compute the ellipsoidal correction of a geodesic (or shperical) segment
*/
template <
template <typename, bool, bool, bool, bool, bool> class Inverse,
//typename AzimuthStrategy,
typename PointOfSegment,
typename SpheroidConst
>
static inline return_type_ellipsoidal ellipsoidal(PointOfSegment const& p1,
PointOfSegment const& p2,
SpheroidConst spheroid_const)
{
return_type_ellipsoidal result;
// Azimuth Approximation
typedef Inverse<CT, false, true, true, false, false> inverse_type;
typedef typename inverse_type::result_type inverse_result;
inverse_result i_res = inverse_type::apply(get_as_radian<0>(p1),
get_as_radian<1>(p1),
get_as_radian<0>(p2),
get_as_radian<1>(p2),
spheroid_const.m_spheroid);
CT alp1 = i_res.azimuth;
CT alp2 = i_res.reverse_azimuth;
// Constants
CT const ep = spheroid_const.m_ep;
CT const f = geometry::detail::flattening<CT>(spheroid_const.m_spheroid);
CT const one_minus_f = CT(1) - f;
std::size_t const series_order_plus_one = SeriesOrder + 1;
std::size_t const series_order_plus_two = SeriesOrder + 2;
// Basic trigonometric computations
CT tan_bet1 = tan(get_as_radian<1>(p1)) * one_minus_f;
CT tan_bet2 = tan(get_as_radian<1>(p2)) * one_minus_f;
CT cos_bet1 = cos(atan(tan_bet1));
CT cos_bet2 = cos(atan(tan_bet2));
CT sin_bet1 = tan_bet1 * cos_bet1;
CT sin_bet2 = tan_bet2 * cos_bet2;
CT sin_alp1 = sin(alp1);
CT cos_alp1 = cos(alp1);
CT cos_alp2 = cos(alp2);
CT sin_alp0 = sin_alp1 * cos_bet1;
// Spherical term computation
CT sin_omg1 = sin_alp0 * sin_bet1;
CT cos_omg1 = cos_alp1 * cos_bet1;
CT sin_omg2 = sin_alp0 * sin_bet2;
CT cos_omg2 = cos_alp2 * cos_bet2;
CT cos_omg12 = cos_omg1 * cos_omg2 + sin_omg1 * sin_omg2;
CT excess;
bool meridian = get<0>(p2) - get<0>(p1) == CT(0)
|| get<1>(p1) == CT(90) || get<1>(p1) == -CT(90)
|| get<1>(p2) == CT(90) || get<1>(p2) == -CT(90);
if (!meridian && cos_omg12 > -CT(0.7)
&& sin_bet2 - sin_bet1 < CT(1.75)) // short segment
{
CT sin_omg12 = cos_omg1 * sin_omg2 - sin_omg1 * cos_omg2;
normalize(sin_omg12, cos_omg12);
CT cos_omg12p1 = CT(1) + cos_omg12;
CT cos_bet1p1 = CT(1) + cos_bet1;
CT cos_bet2p1 = CT(1) + cos_bet2;
excess = CT(2) * atan2(sin_omg12 * (sin_bet1 * cos_bet2p1 + sin_bet2 * cos_bet1p1),
cos_omg12p1 * (sin_bet1 * sin_bet2 + cos_bet1p1 * cos_bet2p1));
}
else
{
/*
CT sin_alp2 = sin(alp2);
CT sin_alp12 = sin_alp2 * cos_alp1 - cos_alp2 * sin_alp1;
CT cos_alp12 = cos_alp2 * cos_alp1 + sin_alp2 * sin_alp1;
excess = atan2(sin_alp12, cos_alp12);
*/
excess = alp2 - alp1;
}
result.spherical_term = excess;
// Ellipsoidal term computation (uses integral approximation)
CT cos_alp0 = math::sqrt(CT(1) - math::sqr(sin_alp0));
CT cos_sig1 = cos_alp1 * cos_bet1;
CT cos_sig2 = cos_alp2 * cos_bet2;
CT sin_sig1 = sin_bet1;
CT sin_sig2 = sin_bet2;
normalize(sin_sig1, cos_sig1);
normalize(sin_sig2, cos_sig2);
CT coeffs[SeriesOrder + 1];
const std::size_t coeffs_var_size = (series_order_plus_two
* series_order_plus_one) / 2;
CT coeffs_var[coeffs_var_size];
if(ExpandEpsN){ // expand by eps and n
CT k2 = math::sqr(ep * cos_alp0);
CT sqrt_k2_plus_one = math::sqrt(CT(1) + k2);
CT eps = (sqrt_k2_plus_one - CT(1)) / (sqrt_k2_plus_one + CT(1));
CT n = f / (CT(2) - f);
// Generate and evaluate the polynomials on n
// to get the series coefficients (that depend on eps)
evaluate_coeffs_n(n, coeffs_var);
// Generate and evaluate the polynomials on eps (i.e. var2 = eps)
// to get the final series coefficients
evaluate_coeffs_var2(eps, coeffs_var, coeffs);
}else{ // expand by k2 and ep
CT k2 = math::sqr(ep * cos_alp0);
CT ep2 = math::sqr(ep);
// Generate and evaluate the polynomials on ep2
evaluate_coeffs_ep(ep2, coeffs_var);
// Generate and evaluate the polynomials on k2 (i.e. var2 = k2)
evaluate_coeffs_var2(k2, coeffs_var, coeffs);
}
// Evaluate the trigonometric sum
CT I12 = clenshaw_sum(cos_sig2, coeffs, coeffs + series_order_plus_one)
- clenshaw_sum(cos_sig1, coeffs, coeffs + series_order_plus_one);
// The part of the ellipsodal correction that depends on
// point coordinates
result.ellipsoidal_term = cos_alp0 * sin_alp0 * I12;
return result;
}
// Keep track whenever a segment crosses the prime meridian
// First normalize to [0,360)
template <typename PointOfSegment, typename StateType>
static inline int crosses_prime_meridian(PointOfSegment const& p1,
PointOfSegment const& p2,
StateType& state)
{
CT const pi
= geometry::math::pi<CT>();
CT const two_pi
= geometry::math::two_pi<CT>();
CT p1_lon = get_as_radian<0>(p1)
- ( floor( get_as_radian<0>(p1) / two_pi )
* two_pi );
CT p2_lon = get_as_radian<0>(p2)
- ( floor( get_as_radian<0>(p2) / two_pi )
* two_pi );
CT max_lon = (std::max)(p1_lon, p2_lon);
CT min_lon = (std::min)(p1_lon, p2_lon);
if(max_lon > pi && min_lon < pi && max_lon - min_lon > pi)
{
state.m_crosses_prime_meridian++;
}
return state.m_crosses_prime_meridian;
}
};
}}} // namespace boost::geometry::formula
#endif // BOOST_GEOMETRY_FORMULAS_AREA_FORMULAS_HPP

View File

@@ -1,6 +1,7 @@
// Boost.Geometry
// Copyright (c) 2016, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -27,6 +28,18 @@ namespace boost { namespace geometry {
namespace formula {
template <typename T>
struct result_spherical
{
result_spherical()
: azimuth(0)
, reverse_azimuth(0)
{}
T azimuth;
T reverse_azimuth;
};
template <typename Point3d, typename PointSph>
static inline Point3d sph_to_cart3d(PointSph const& point_sph)
{
@@ -89,6 +102,47 @@ static inline int sph_side_value(Point3d1 const& norm, Point3d2 const& pt)
: -1; // d < 0
}
template <typename CT, bool ReverseAzimuth, typename T1, typename T2>
static inline result_spherical<CT> spherical_azimuth(T1 const& lon1,
T1 const& lat1,
T2 const& lon2,
T2 const& lat2)
{
typedef result_spherical<CT> result_type;
result_type result;
// http://williams.best.vwh.net/avform.htm#Crs
// https://en.wikipedia.org/wiki/Great-circle_navigation
CT dlon = lon2 - lon1;
CT cos_dlon = cos(dlon);
CT sin_dlon = sin(dlon);
CT cos_lat1 = cos(lat1);
CT cos_lat2 = cos(lat2);
CT sin_lat1 = sin(lat1);
CT sin_lat2 = sin(lat2);
// An optimization which should kick in often for Boxes
//if ( math::equals(dlon, ReturnType(0)) )
//if ( get<0>(p1) == get<0>(p2) )
//{
// return - sin(get_as_radian<1>(p1)) * cos_p2lat);
//}
// "An alternative formula, not requiring the pre-computation of d"
// In the formula below dlon is used as "d"
result.azimuth = atan2(sin_dlon * cos_lat2,
cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon);
if (ReverseAzimuth)
{
result.reverse_azimuth =
atan2(sin_dlon * cos_lat1,
sin_lat2 * cos_lat1 * cos_dlon - cos_lat2 * sin_lat1);
}
return result;
}
} // namespace formula
}} // namespace boost::geometry

View File

@@ -0,0 +1,148 @@
// Boost.Geometry
// Copyright (c) 2016-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// 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_FORMULAS_MAXIMUM_LATITUDE_HPP
#define BOOST_GEOMETRY_FORMULAS_MAXIMUM_LATITUDE_HPP
#include <boost/geometry/formulas/spherical.hpp>
#include <boost/geometry/algorithms/detail/flattening.hpp>
#include <boost/geometry/core/srs.hpp>
#include <boost/mpl/assert.hpp>
namespace boost { namespace geometry { namespace formula
{
/*!
\brief Algorithm to compute the vertex latitude of a geodesic segment. Vertex is
a point on the geodesic that maximizes (or minimizes) the latitude.
\author See
[Wood96] Wood - Vertex Latitudes on Ellipsoid Geodesics, SIAM Rev., 38(4),
637644, 1996
*/
template <typename CT>
class vertex_latitude_on_sphere
{
public:
template<typename T1, typename T2>
static inline CT apply(T1 const& lat1,
T2 const& alp1)
{
return std::acos( math::abs(cos(lat1) * sin(alp1)) );
}
};
template <typename CT>
class vertex_latitude_on_spheroid
{
public:
/*
* formula based on paper
* [Wood96] Wood - Vertex Latitudes on Ellipsoid Geodesics, SIAM Rev., 38(4),
* 637644, 1996
template <typename T1, typename T2, typename Spheroid>
static inline CT apply(T1 const& lat1,
T2 const& alp1,
Spheroid const& spheroid)
{
CT const f = detail::flattening<CT>(spheroid);
CT const e2 = f * (CT(2) - f);
CT const sin_alp1 = sin(alp1);
CT const sin2_lat1 = math::sqr(sin(lat1));
CT const cos2_lat1 = CT(1) - sin2_lat1;
CT const e2_sin2 = CT(1) - e2 * sin2_lat1;
CT const cos2_sin2 = cos2_lat1 * math::sqr(sin_alp1);
CT const vertex_lat = std::asin( math::sqrt((e2_sin2 - cos2_sin2)
/ (e2_sin2 - e2 * cos2_sin2)));
return vertex_lat;
}
*/
// simpler formula based on Clairaut relation for spheroids
template <typename T1, typename T2, typename Spheroid>
static inline CT apply(T1 const& lat1,
T2 const& alp1,
Spheroid const& spheroid)
{
CT const f = detail::flattening<CT>(spheroid);
CT const one_minus_f = (CT(1) - f);
//get the reduced latitude
CT const bet1 = atan( one_minus_f * tan(lat1) );
//apply Clairaut relation
CT const betv = vertex_latitude_on_sphere<CT>::apply(bet1, alp1);
//return the spheroid latitude
return atan( tan(betv) / one_minus_f );
}
/*
template <typename T>
inline static void sign_adjustment(CT lat1, CT lat2, CT vertex_lat, T& vrt_result)
{
// signbit returns a non-zero value (true) if the sign is negative;
// and zero (false) otherwise.
bool sign = std::signbit(std::abs(lat1) > std::abs(lat2) ? lat1 : lat2);
vrt_result.north = sign ? std::max(lat1, lat2) : vertex_lat;
vrt_result.south = sign ? vertex_lat * CT(-1) : std::min(lat1, lat2);
}
template <typename T>
inline static bool vertex_on_segment(CT alp1, CT alp2, CT lat1, CT lat2, T& vrt_result)
{
CT const half_pi = math::pi<CT>() / CT(2);
// if the segment does not contain the vertex of the geodesic
// then return the endpoint of max (min) latitude
if ((alp1 < half_pi && alp2 < half_pi)
|| (alp1 > half_pi && alp2 > half_pi))
{
vrt_result.north = std::max(lat1, lat2);
vrt_result.south = std::min(lat1, lat2);
return false;
}
return true;
}
*/
};
template <typename CT, typename CS_Tag>
struct vertex_latitude
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM, (types<CS_Tag>)
);
};
template <typename CT>
struct vertex_latitude<CT, spherical_equatorial_tag>
: vertex_latitude_on_sphere<CT>
{};
template <typename CT>
struct vertex_latitude<CT, geographic_tag>
: vertex_latitude_on_spheroid<CT>
{};
}}} // namespace boost::geometry::formula
#endif // BOOST_GEOMETRY_FORMULAS_MAXIMUM_LATITUDE_HPP

View File

@@ -0,0 +1,62 @@
// Boost.Geometry Index
//
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
//
// 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_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP
#include <algorithm>
namespace boost { namespace geometry { namespace index { namespace detail {
// See https://svn.boost.org/trac/boost/ticket/12861
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800
// https://gcc.gnu.org/develop.html#timeline
// 20120920 4.7.2 - no bug
// 20130322 4.8.0 - no bug
// 20130411 4.7.3 - no bug
// 20130531 4.8.1 - no bug
// 20131016 4.8.2 - bug
// 20140422 4.9.0 - fixed
// 20140522 4.8.3 - fixed
// 20140612 4.7.4 - fixed
// 20140716 4.9.1 - fixed
#if defined(__GLIBCXX__) && (__GLIBCXX__ == 20131016)
#warning "std::nth_element replaced with std::sort, libstdc++ bug workaround.";
template <typename RandomIt>
void nth_element(RandomIt first, RandomIt , RandomIt last)
{
std::sort(first, last);
}
template <typename RandomIt, typename Compare>
void nth_element(RandomIt first, RandomIt , RandomIt last, Compare comp)
{
std::sort(first, last, comp);
}
#else
template <typename RandomIt>
void nth_element(RandomIt first, RandomIt nth, RandomIt last)
{
std::nth_element(first, nth, last);
}
template <typename RandomIt, typename Compare>
void nth_element(RandomIt first, RandomIt nth, RandomIt last, Compare comp)
{
std::nth_element(first, nth, last, comp);
}
#endif
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP

View File

@@ -2,7 +2,7 @@
//
// R-tree initial packing
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
@@ -67,7 +68,7 @@ struct nth_element_and_half_boxes
{
if ( I == dim_index )
{
std::nth_element(first, median, last, point_entries_comparer<I>());
index::detail::nth_element(first, median, last, point_entries_comparer<I>());
geometry::convert(box, left);
geometry::convert(box, right);

View File

@@ -2,7 +2,7 @@
//
// R-tree R*-tree next node choosing algorithm implementation
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,6 +17,7 @@
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/algorithms/intersection_content.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
@@ -112,7 +113,7 @@ private:
first_n_children_count = overlap_cost_threshold;
// rearrange by content_diff
// in order to calculate nearly minimum overlap cost
std::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less);
index::detail::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less);
}
// calculate minimum or nearly minimum overlap cost

View File

@@ -2,7 +2,7 @@
//
// R-tree R*-tree split algorithm implementation
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,8 +12,9 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
#include <boost/geometry/index/detail/algorithms/intersection_content.hpp>
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
#include <boost/geometry/index/detail/algorithms/margin.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
#include <boost/geometry/index/detail/bounded_view.hpp>
@@ -122,8 +123,9 @@ struct choose_split_axis_and_index_for_corner
// {
// typename Elements::iterator f = elements_copy.begin() + index_first;
// typename Elements::iterator l = elements_copy.begin() + index_last;
// std::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// std::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// // NOTE: for stdlibc++ shipped with gcc 4.8.2 std::nth_element is replaced with std::sort anyway
// index::detail::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// index::detail::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// std::sort(f, l, elements_less); // MAY THROW, BASIC (copy)
// }
@@ -349,7 +351,7 @@ struct nth_element
typedef typename tag<indexable_type>::type indexable_tag;
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, I> less(tr);
std::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
index::detail::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
}
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -42,6 +42,15 @@ struct equals<T, void>
}
};
template <typename T>
struct equals<T *, void>
{
inline static bool apply(const T * v1, const T * v2)
{
return v1 == v2;
}
};
template <typename Tuple, size_t I, size_t N>
struct tuple_equals
{

View File

@@ -11,8 +11,14 @@
#ifndef BOOST_GEOMETRY_INDEX_PARAMETERS_HPP
#define BOOST_GEOMETRY_INDEX_PARAMETERS_HPP
#include <limits>
#include <boost/mpl/assert.hpp>
#include <boost/geometry/index/detail/exception.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail {

View File

@@ -203,7 +203,7 @@ inline void check_end(Iterator& it,
{
if (it != end)
{
throw read_wkt_exception("Too much tokens", it, end, wkt);
throw read_wkt_exception("Too many tokens", it, end, wkt);
}
}

Some files were not shown because too many files have changed in this diff Show More