mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 05:24:02 +00:00
Merge branch 'develop' into feature/azimuth
This commit is contained in:
commit
ae33a8dc0c
7
.github/workflows/minimal-clang.yml
vendored
7
.github/workflows/minimal-clang.yml
vendored
@ -92,8 +92,11 @@ jobs:
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421
|
||||
sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
|
||||
# Required for compilers not available in ubuntu latest
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main"
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe"
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ bionic main"
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ bionic universe"
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt -q -y update
|
||||
sudo apt -q -y install clang-${{ matrix.version }} g++-multilib
|
||||
|
4
.github/workflows/minimal-gcc.yml
vendored
4
.github/workflows/minimal-gcc.yml
vendored
@ -80,9 +80,11 @@ jobs:
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
# gcc-4.8 is not available in Bionic anymore
|
||||
# Required for compilers not available in ubuntu latest
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main"
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe"
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ bionic main"
|
||||
sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ bionic universe"
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt -q -y update
|
||||
sudo apt -q -y install g++-${{ matrix.version }} g++-${{ matrix.version }}-multilib
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 
|
||||
|
||||
Boost.Geometry, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), defines concepts, primitives and algorithms for solving geometry problems.
|
||||
Boost.Geometry, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), defines concepts, primitives and algorithms for solving geometry problems. Boost.Geometry is a C++14 header-only library.
|
||||
|
||||
[](http://www.boost.org/LICENSE_1_0.txt)
|
||||
[](http://boost.org/libs/geometry)
|
||||
|
@ -14,6 +14,7 @@ test-suite boost-geometry-extensions-algorithms
|
||||
[ run distance_info.cpp ]
|
||||
[ run connect.cpp ]
|
||||
# [ run offset.cpp ]
|
||||
[ run parse.cpp ]
|
||||
[ run midpoints.cpp ]
|
||||
# [ run selected.cpp ]
|
||||
;
|
||||
|
219
extensions/test/algorithms/parse.cpp
Normal file
219
extensions/test/algorithms/parse.cpp
Normal file
@ -0,0 +1,219 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2021 Joni Kerkelä, Oulu, Finland.
|
||||
// Copyright (c) 2021 Ayush Gupta, Gujarat, India
|
||||
|
||||
// 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)
|
||||
|
||||
#include <string>
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/extensions/algorithms/parse.hpp>
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
#include <test_common/test_point.hpp>
|
||||
|
||||
using namespace boost::geometry;
|
||||
|
||||
template <typename Geometry, typename T>
|
||||
void test_parse(std::string const& coordinate_1,
|
||||
std::string const& coordinate_2,
|
||||
T expected_result_coord_1,
|
||||
T expected_result_coord_2)
|
||||
{
|
||||
Geometry geometry;
|
||||
geometry = parse<Geometry>(coordinate_1, coordinate_2);
|
||||
BOOST_CHECK_CLOSE(((double)bg::get<0>(geometry)), expected_result_coord_1, 1.0e-4);
|
||||
BOOST_CHECK_CLOSE(((double)bg::get<1>(geometry)), expected_result_coord_2, 1.0e-4);
|
||||
|
||||
parse(geometry, coordinate_1, coordinate_2);
|
||||
BOOST_CHECK_CLOSE(((double)bg::get<0>(geometry)), expected_result_coord_1, 1.0e-4);
|
||||
BOOST_CHECK_CLOSE(((double)bg::get<1>(geometry)), expected_result_coord_2, 1.0e-4);
|
||||
}
|
||||
|
||||
template <typename P, typename S>
|
||||
void test_parse_with_parse_strategy(std::string const& coordinate_1, std::string const& coordinate_2,
|
||||
double expected_result_coord_1, double expected_result_coord_2, S const& strategy)
|
||||
{
|
||||
P p;
|
||||
parse<P, S>(p, coordinate_1, coordinate_2, strategy);
|
||||
BOOST_CHECK_CLOSE(((double)bg::get<0>(p)), expected_result_coord_1, 1.0e-4);
|
||||
BOOST_CHECK_CLOSE(((double)bg::get<1>(p)), expected_result_coord_2, 1.0e-4);
|
||||
}
|
||||
|
||||
template <typename P, typename T>
|
||||
void test_parse_with_point_and_parse_strategy(std::string const& coordinate_1, std::string const& coordinate_2,
|
||||
double expected_result_coord_1, double expected_result_coord_2, T const& parser)
|
||||
{
|
||||
test_parse_with_parse_strategy<P, T>(coordinate_1,
|
||||
coordinate_2, expected_result_coord_1, expected_result_coord_2, parser);
|
||||
}
|
||||
|
||||
template <typename P, bool as_radian>
|
||||
void test_all_complex_dms_strategy()
|
||||
{
|
||||
typedef typename coordinate_type<P>::type coord_t;
|
||||
using parser_t = projections::detail::dms_parser<coord_t, as_radian, 'w', 'e', 'n', 's'>;
|
||||
|
||||
// with minutes
|
||||
double expected_dms_result1 = as_radian ? 5.166666666 * bg::math::d2r<double>() : 5.166666666;
|
||||
double expected_dms_result2 = as_radian ? -5.166666666 * bg::math::d2r<double>() : -5.166666666;
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5d10E"), std::string("5d10N"),
|
||||
expected_dms_result1, expected_dms_result2, parser_t());
|
||||
|
||||
// with minutes and indicator
|
||||
double expected_dms_result3 = as_radian ? (5.16666666 * bg::math::d2r<double>()) : 5.16666666;
|
||||
double expected_dms_result4 = as_radian ? -(5.16666666 * bg::math::d2r<double>()) : -5.16666666;
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5d10'E"), std::string("5d10'N"),
|
||||
expected_dms_result3, expected_dms_result4, parser_t());
|
||||
|
||||
// with minutes/seconds
|
||||
double expected_dms_result5 = as_radian ? (5.1680555555 * bg::math::d2r<double>()) : 5.1680555555;
|
||||
double expected_dms_result6 = as_radian ? -(5.16805555555 * bg::math::d2r<double>()) : -5.16805555555;
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5d10'05E"), std::string("5d10'05N"),
|
||||
expected_dms_result5, expected_dms_result6, parser_t());
|
||||
|
||||
// with seconds only
|
||||
double sec = 1 / 3600.0;
|
||||
double expected_dms_result7 = as_radian ? ((5 + sec) * bg::math::d2r<double>()) : (5 + sec);
|
||||
double expected_dms_result8 = as_radian ? -((5 + sec) * bg::math::d2r<double>()) : -(5 + sec);
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5d1\"E"), std::string("5d1\"N"),
|
||||
expected_dms_result7, expected_dms_result8, parser_t());
|
||||
|
||||
// with spaces and signs
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5d 1\" E"), std::string("5d 1\" N"),
|
||||
expected_dms_result7, expected_dms_result8, parser_t());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("+5d 1\" E"), std::string("+5d 1\" N"),
|
||||
expected_dms_result7, expected_dms_result8, parser_t());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("-5d 1\" E"), std::string("-5d 1\" N"),
|
||||
-expected_dms_result7, -expected_dms_result8, parser_t());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5d 10' 05 E"), std::string("5d 10' 05 N"),
|
||||
expected_dms_result5, expected_dms_result6, parser_t());
|
||||
|
||||
// in radians
|
||||
double expected_dms_result9 = as_radian ? 5.15 : (5.15 * bg::math::r2d<double>());
|
||||
double expected_dms_result10 = as_radian ? -5.15 : -(5.15 * bg::math::r2d<double>());
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5.15RE"), std::string("5.15RN"),
|
||||
expected_dms_result9, expected_dms_result10, parser_t());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t>(std::string("5.15R E"), std::string("5.15R N"),
|
||||
expected_dms_result9, expected_dms_result10, parser_t());
|
||||
|
||||
// test with random characters in strategy(for generality check)
|
||||
using parser_t1 = bg::projections::detail::dms_parser<coord_t, true, 'A', 'B', 'C', 'D', 'm', 's', 'o', 'p'>;
|
||||
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("45o 30m 30s A"), std::string("120o 30m 45s D"),
|
||||
-2.1033408163, 0.7942705942, parser_t1());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("1.75p c"), std::string("5o 40m 55s b"),
|
||||
0.0991686810, -1.7500000000, parser_t1());
|
||||
|
||||
// creating another strategy with returning value as degree
|
||||
using parser_t2 = bg::projections::detail::dms_parser<coord_t, false>; // return value in degree and rest parameters as default value.
|
||||
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t2>(std::string("80d 45' 30\"S"), std::string("150d 30' 30\"E"),
|
||||
150.5083333333, -80.7583333333, parser_t2());
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t2>(std::string("15d 10' 20\"N"), std::string("2.75r W"),
|
||||
-157.5633261332, 15.1722222222, parser_t2());
|
||||
|
||||
}
|
||||
|
||||
template <typename P, bool as_radian>
|
||||
void test_all_with_simple_dms_strategy()
|
||||
{
|
||||
using coord_t = typename coordinate_type<P>::type;
|
||||
|
||||
double generic_expected_result1 = as_radian ? 2 * bg::math::d2r<double>() : 2;
|
||||
double generic_expected_result2 = as_radian ? -4 * bg::math::d2r<double>() : -4;
|
||||
|
||||
using parser_t1 = projections::detail::dms_parser<coord_t, as_radian, 'w', 'e', 'n', 's'>;
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("2e"), std::string("4n"),
|
||||
generic_expected_result1, generic_expected_result2, parser_t1());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("2w"), std::string("4s"),
|
||||
generic_expected_result2, generic_expected_result1, parser_t1());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("2w"), std::string("4e"),
|
||||
2 * generic_expected_result1, generic_expected_result1, parser_t1());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("2s"), std::string("4n"),
|
||||
-(generic_expected_result1), generic_expected_result2, parser_t1());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t1>(std::string("4n"), std::string("2s"),
|
||||
-(generic_expected_result1), generic_expected_result2, parser_t1());
|
||||
|
||||
using parser_t2 = projections::detail::dms_parser<coord_t, as_radian, 'n', 'o', 'z', 'w'>;
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t2>(std::string("2o"), std::string("4z"),
|
||||
generic_expected_result1, generic_expected_result2, parser_t2());
|
||||
|
||||
using parser_t3 = projections::detail::dms_parser<coord_t, as_radian, 'W', 'E', 'N', 'S'>;
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t3>(std::string("4N"), std::string("2S"),
|
||||
-(generic_expected_result1), generic_expected_result2, parser_t3());
|
||||
|
||||
test_parse_with_point_and_parse_strategy<P, parser_t3>(std::string("4n"), std::string("2s"),
|
||||
-(generic_expected_result1), generic_expected_result2, parser_t3());
|
||||
|
||||
}
|
||||
|
||||
template<typename Geometry>
|
||||
void test_all_without_strategy()
|
||||
{
|
||||
using T = typename bg::coordinate_type<Geometry>::type;
|
||||
T const d2r = math::d2r<T>();
|
||||
|
||||
test_parse<Geometry, T>(std::string("1E"), std::string("2N"), 1 * d2r, 2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1W"), std::string("2S"), -1 * d2r, -2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1E"), std::string("2N"), 1 * d2r, 2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1W"), std::string("2S"), -1 * d2r, -2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1W"), std::string("2S"), -1 * d2r, -2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1W"), std::string("2S"), -1 * d2r, -2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1W"), std::string("2S"), -1 * d2r, -2 * d2r);
|
||||
test_parse<Geometry, T>(std::string("1W"), std::string("2S"), -1 * d2r, -2 * d2r);
|
||||
|
||||
// tests for dms strings, values returned in radian(default strategy).
|
||||
test_parse<Geometry, T>(std::string("45d 30' 30\" N"), std::string("120D 30'45\"W"), -2.1033408163, 0.7942705942);
|
||||
test_parse<Geometry, T>(std::string("32D45' 57\"n"), std::string("170d 10' 25\"E"), 2.9700910868, 0.5718719189);
|
||||
test_parse<Geometry, T>(std::string("5d38'40\"S"), std::string("168D 10' 20\"w"), -2.9351602461, -0.0985141822);
|
||||
test_parse<Geometry, T>(std::string("72D 20'45\"s"), std::string("5d 40' 55\"e"), 0.0991686810, -1.2626735329);
|
||||
|
||||
// test for radian and dms strings combined returning values in degree.
|
||||
test_parse<Geometry, T>(std::string("2.5r N"), std::string("0.75r E"), 0.7500000000, 2.5000000000);
|
||||
test_parse<Geometry, T>(std::string("1.25r S"), std::string("120D 30' 45\"w"), -2.1033408163, -1.2500000000);
|
||||
}
|
||||
|
||||
void test_without_strategy()
|
||||
{
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::spherical<bg::degree>>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::spherical<bg::radian>>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree>>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::radian>>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::geographic<bg::degree>>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::geographic<bg::radian>>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::undefined>>();
|
||||
test_all_without_strategy<bg::model::point<double, 2, bg::cs::cartesian>>();
|
||||
}
|
||||
void test_all()
|
||||
{
|
||||
test_without_strategy();
|
||||
test_all_with_simple_dms_strategy<bg::model::point<double, 2, bg::cs::geographic<bg::degree> >, false>();
|
||||
test_all_with_simple_dms_strategy<bg::model::point<double, 2, bg::cs::geographic<bg::radian> >, true>();
|
||||
test_all_complex_dms_strategy<bg::model::point<double, 2, bg::cs::geographic<bg::degree> >, false>();
|
||||
test_all_complex_dms_strategy<bg::model::point<double, 2, bg::cs::geographic<bg::radian> >, true>();
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_all();
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2017-2020.
|
||||
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2017-2021.
|
||||
// Modifications copyright (c) 2017-2021 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
|
||||
@ -242,22 +242,23 @@ 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 strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<GeometryIn>::type
|
||||
>::type intersection_strategy;
|
||||
GeometryIn, GeometryIn
|
||||
>::type strategies;
|
||||
|
||||
rescale_policy_type rescale_policy
|
||||
= boost::geometry::get_rescale_policy<rescale_policy_type>(
|
||||
box, intersection_strategy);
|
||||
box, strategies);
|
||||
|
||||
detail::buffer::buffer_inserter<polygon_type>(geometry_in, range::back_inserter(geometry_out),
|
||||
detail::buffer::buffer_inserter<polygon_type>(geometry_in,
|
||||
range::back_inserter(geometry_out),
|
||||
distance_strategy,
|
||||
side_strategy,
|
||||
join_strategy,
|
||||
end_strategy,
|
||||
point_strategy,
|
||||
intersection_strategy,
|
||||
strategies,
|
||||
rescale_policy);
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014-2020.
|
||||
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -65,9 +67,14 @@ struct crosses
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct crosses
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@ -75,21 +82,50 @@ struct crosses
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return dispatch::crosses<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
return dispatch::crosses
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct crosses<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
//using strategies::crosses::services::strategy_converter;
|
||||
using strategies::relate::services::strategy_converter;
|
||||
return crosses
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct crosses<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
//typedef typename strategies::crosses::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy_type());
|
||||
return crosses
|
||||
<
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -106,7 +142,10 @@ namespace resolve_variant
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_strategy::crosses::apply(geometry1, geometry2, strategy);
|
||||
return resolve_strategy::crosses
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2017-2020.
|
||||
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2017-2021.
|
||||
// Modifications copyright (c) 2017-2021 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,
|
||||
@ -921,7 +921,7 @@ template
|
||||
typename JoinStrategy,
|
||||
typename EndStrategy,
|
||||
typename PointStrategy,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategies,
|
||||
typename RobustPolicy,
|
||||
typename VisitPiecesPolicy
|
||||
>
|
||||
@ -931,7 +931,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,
|
||||
Strategies const& strategies,
|
||||
RobustPolicy const& robust_policy,
|
||||
VisitPiecesPolicy& visit_pieces_policy
|
||||
)
|
||||
@ -941,11 +941,11 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
|
||||
typedef detail::buffer::buffered_piece_collection
|
||||
<
|
||||
typename geometry::ring_type<GeometryOutput>::type,
|
||||
IntersectionStrategy,
|
||||
Strategies,
|
||||
DistanceStrategy,
|
||||
RobustPolicy
|
||||
> collection_type;
|
||||
collection_type collection(intersection_strategy, distance_strategy, robust_policy);
|
||||
collection_type collection(strategies, distance_strategy, robust_policy);
|
||||
collection_type const& const_collection = collection;
|
||||
|
||||
bool const areal = util::is_areal<GeometryInput>::value;
|
||||
@ -962,7 +962,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
|
||||
>::apply(geometry_input, collection,
|
||||
distance_strategy, side_strategy, join_strategy,
|
||||
end_strategy, point_strategy,
|
||||
robust_policy, intersection_strategy.get_side_strategy());
|
||||
robust_policy, strategies.side()); // pass strategies?
|
||||
|
||||
collection.get_turns();
|
||||
if (BOOST_GEOMETRY_CONDITION(areal))
|
||||
@ -1029,7 +1029,7 @@ template
|
||||
typename JoinStrategy,
|
||||
typename EndStrategy,
|
||||
typename PointStrategy,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategies,
|
||||
typename RobustPolicy
|
||||
>
|
||||
inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out,
|
||||
@ -1038,14 +1038,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,
|
||||
Strategies const& strategies,
|
||||
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,
|
||||
intersection_strategy, robust_policy, visitor);
|
||||
strategies, robust_policy, visitor);
|
||||
}
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
@ -193,30 +193,37 @@ struct buffer_less
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct piece_get_box
|
||||
{
|
||||
explicit piece_get_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Piece>
|
||||
static inline void apply(Box& total, Piece const& piece)
|
||||
inline void apply(Box& total, Piece const& piece) const
|
||||
{
|
||||
assert_coordinate_type_equal(total, piece.m_piece_border.m_envelope);
|
||||
typedef typename strategy::expand::services::default_strategy
|
||||
<
|
||||
box_tag, typename cs_tag<Box>::type
|
||||
>::type expand_strategy_type;
|
||||
|
||||
if (piece.m_piece_border.m_has_envelope)
|
||||
{
|
||||
geometry::expand(total, piece.m_piece_border.m_envelope,
|
||||
expand_strategy_type());
|
||||
m_strategy);
|
||||
}
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct piece_overlaps_box
|
||||
{
|
||||
explicit piece_overlaps_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Piece>
|
||||
static inline bool apply(Box const& box, Piece const& piece)
|
||||
inline bool apply(Box const& box, Piece const& piece) const
|
||||
{
|
||||
assert_coordinate_type_equal(box, piece.m_piece_border.m_envelope);
|
||||
|
||||
@ -235,34 +242,45 @@ struct piece_overlaps_box
|
||||
}
|
||||
|
||||
return ! geometry::detail::disjoint::disjoint_box_box(box, piece.m_piece_border.m_envelope,
|
||||
DisjointBoxBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct turn_get_box
|
||||
{
|
||||
explicit turn_get_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Turn>
|
||||
static inline void apply(Box& total, Turn const& turn)
|
||||
inline void apply(Box& total, Turn const& turn) const
|
||||
{
|
||||
typedef typename strategy::expand::services::default_strategy
|
||||
<
|
||||
point_tag, typename cs_tag<Box>::type
|
||||
>::type expand_strategy_type;
|
||||
assert_coordinate_type_equal(total, turn.point);
|
||||
geometry::expand(total, turn.point, expand_strategy_type());
|
||||
geometry::expand(total, turn.point, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct turn_overlaps_box
|
||||
{
|
||||
explicit turn_overlaps_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Turn>
|
||||
static inline bool apply(Box const& box, Turn const& turn)
|
||||
inline bool apply(Box const& box, Turn const& turn) const
|
||||
{
|
||||
assert_coordinate_type_equal(turn.point, box);
|
||||
return ! geometry::detail::disjoint::disjoint_point_box(turn.point, box,
|
||||
DisjointPointBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
struct enriched_map_buffer_include_policy
|
||||
|
@ -3,8 +3,8 @@
|
||||
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2016-2020.
|
||||
// Modifications copyright (c) 2016-2020 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2016-2021.
|
||||
// Modifications copyright (c) 2016-2021 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,7 +117,7 @@ namespace detail { namespace buffer
|
||||
template
|
||||
<
|
||||
typename Ring,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename DistanceStrategy,
|
||||
typename RobustPolicy
|
||||
>
|
||||
@ -131,27 +131,6 @@ struct buffered_piece_collection
|
||||
|
||||
typedef geometry::model::box<point_type> box_type;
|
||||
|
||||
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
|
||||
typedef typename IntersectionStrategy::envelope_strategy_type envelope_strategy_type;
|
||||
typedef typename IntersectionStrategy::expand_strategy_type expand_strategy_type;
|
||||
|
||||
typedef typename IntersectionStrategy::template area_strategy
|
||||
<
|
||||
point_type
|
||||
>::type area_strategy_type;
|
||||
|
||||
typedef typename area_strategy_type::template result_type
|
||||
<
|
||||
point_type
|
||||
>::type area_result_type;
|
||||
|
||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy
|
||||
<
|
||||
point_type,
|
||||
clockwise_ring_type
|
||||
>::type point_in_geometry_strategy_type;
|
||||
|
||||
|
||||
typedef buffer_turn_info
|
||||
<
|
||||
point_type,
|
||||
@ -232,23 +211,23 @@ struct buffered_piece_collection
|
||||
{}
|
||||
|
||||
inline original_ring(clockwise_ring_type const& ring,
|
||||
bool is_interior, bool has_interiors,
|
||||
envelope_strategy_type const& envelope_strategy,
|
||||
expand_strategy_type const& expand_strategy)
|
||||
bool is_interior, bool has_interiors,
|
||||
Strategy const& strategy)
|
||||
: m_ring(ring)
|
||||
, m_is_interior(is_interior)
|
||||
, m_has_interiors(has_interiors)
|
||||
{
|
||||
geometry::envelope(m_ring, m_box, envelope_strategy);
|
||||
geometry::envelope(m_ring, m_box, strategy);
|
||||
|
||||
// create monotonic sections in x-dimension
|
||||
// The dimension is critical because the direction is later used
|
||||
// in the optimization for within checks using winding strategy
|
||||
// and this strategy is scanning in x direction.
|
||||
typedef std::integer_sequence<std::size_t, 0> dimensions;
|
||||
geometry::sectionalize<false, dimensions>(m_ring,
|
||||
detail::no_rescale_policy(), m_sections,
|
||||
envelope_strategy, expand_strategy);
|
||||
geometry::sectionalize
|
||||
<
|
||||
false, dimensions
|
||||
>(m_ring, detail::no_rescale_policy(), m_sections, strategy);
|
||||
}
|
||||
|
||||
clockwise_ring_type m_ring;
|
||||
@ -295,31 +274,18 @@ struct buffered_piece_collection
|
||||
|
||||
cluster_type m_clusters;
|
||||
|
||||
IntersectionStrategy m_intersection_strategy;
|
||||
Strategy m_strategy;
|
||||
DistanceStrategy m_distance_strategy;
|
||||
side_strategy_type m_side_strategy;
|
||||
area_strategy_type m_area_strategy;
|
||||
envelope_strategy_type m_envelope_strategy;
|
||||
expand_strategy_type m_expand_strategy;
|
||||
point_in_geometry_strategy_type m_point_in_geometry_strategy;
|
||||
|
||||
RobustPolicy const& m_robust_policy;
|
||||
|
||||
buffered_piece_collection(IntersectionStrategy const& intersection_strategy,
|
||||
buffered_piece_collection(Strategy const& strategy,
|
||||
DistanceStrategy const& distance_strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
: m_first_piece_index(-1)
|
||||
, m_deflate(false)
|
||||
, m_has_deflated(false)
|
||||
, m_intersection_strategy(intersection_strategy)
|
||||
, m_strategy(strategy)
|
||||
, m_distance_strategy(distance_strategy)
|
||||
, m_side_strategy(intersection_strategy.get_side_strategy())
|
||||
, m_area_strategy(intersection_strategy
|
||||
.template get_area_strategy<point_type>())
|
||||
, m_envelope_strategy(intersection_strategy.get_envelope_strategy())
|
||||
, m_expand_strategy(intersection_strategy.get_expand_strategy())
|
||||
, m_point_in_geometry_strategy(intersection_strategy
|
||||
.template get_point_in_geometry_strategy<point_type, clockwise_ring_type>())
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
@ -393,8 +359,7 @@ struct buffered_piece_collection
|
||||
it != boost::end(m_linear_end_points);
|
||||
++it)
|
||||
{
|
||||
if (detail::equals::equals_point_point(turn.point, *it,
|
||||
m_intersection_strategy.get_equals_point_point_strategy()))
|
||||
if (detail::equals::equals_point_point(turn.point, *it, m_strategy))
|
||||
{
|
||||
turn.is_linear_end_point = true;
|
||||
}
|
||||
@ -468,20 +433,11 @@ struct buffered_piece_collection
|
||||
// Check if a turn is inside any of the originals
|
||||
inline void check_turn_in_original()
|
||||
{
|
||||
typedef turn_in_original_overlaps_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_point_box_strategy_type
|
||||
> turn_in_original_overlaps_box_type;
|
||||
typedef original_overlaps_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_box_box_strategy_type
|
||||
> original_overlaps_box_type;
|
||||
|
||||
turn_in_original_visitor
|
||||
<
|
||||
turn_vector_type,
|
||||
point_in_geometry_strategy_type
|
||||
> visitor(m_turns, m_point_in_geometry_strategy);
|
||||
Strategy
|
||||
> visitor(m_turns, m_strategy);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
@ -489,8 +445,10 @@ struct buffered_piece_collection
|
||||
include_turn_policy,
|
||||
detail::partition::include_all_policy
|
||||
>::apply(m_turns, original_rings, visitor,
|
||||
turn_get_box(), turn_in_original_overlaps_box_type(),
|
||||
original_get_box(), original_overlaps_box_type());
|
||||
turn_get_box<Strategy>(m_strategy),
|
||||
turn_in_original_overlaps_box<Strategy>(m_strategy),
|
||||
original_get_box<Strategy>(m_strategy),
|
||||
original_overlaps_box<Strategy>(m_strategy));
|
||||
|
||||
bool const deflate = m_distance_strategy.negative();
|
||||
|
||||
@ -560,10 +518,11 @@ struct buffered_piece_collection
|
||||
}
|
||||
|
||||
// Calculate envelopes for piece borders
|
||||
border.get_properties_of_border(pc.type == geometry::strategy::buffer::buffered_point, pc.m_center);
|
||||
border.get_properties_of_border(pc.type == geometry::strategy::buffer::buffered_point,
|
||||
pc.m_center, m_strategy);
|
||||
if (! pc.is_flat_end && ! pc.is_flat_start)
|
||||
{
|
||||
border.get_properties_of_offsetted_ring_part(m_side_strategy);
|
||||
border.get_properties_of_offsetted_ring_part(m_strategy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -580,28 +539,19 @@ struct buffered_piece_collection
|
||||
piece_vector_type,
|
||||
buffered_ring_collection<buffered_ring<Ring> >,
|
||||
turn_vector_type,
|
||||
IntersectionStrategy,
|
||||
Strategy,
|
||||
RobustPolicy
|
||||
> visitor(m_pieces, offsetted_rings, m_turns,
|
||||
m_intersection_strategy, m_robust_policy);
|
||||
m_strategy, m_robust_policy);
|
||||
|
||||
typedef detail::section::get_section_box
|
||||
<
|
||||
typename IntersectionStrategy::expand_box_strategy_type
|
||||
> get_section_box_type;
|
||||
typedef detail::section::overlaps_section_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_box_box_strategy_type
|
||||
> overlaps_section_box_type;
|
||||
detail::sectionalize::enlarge_sections(monotonic_sections, m_strategy);
|
||||
|
||||
detail::sectionalize::enlarge_sections(monotonic_sections,
|
||||
m_envelope_strategy);
|
||||
geometry::partition
|
||||
<
|
||||
robust_box_type
|
||||
>::apply(monotonic_sections, visitor,
|
||||
get_section_box_type(),
|
||||
overlaps_section_box_type());
|
||||
detail::section::get_section_box<Strategy>(m_strategy),
|
||||
detail::section::overlaps_section_box<Strategy>(m_strategy));
|
||||
}
|
||||
|
||||
update_turn_administration();
|
||||
@ -614,21 +564,14 @@ struct buffered_piece_collection
|
||||
turn_vector_type, piece_vector_type, DistanceStrategy
|
||||
> visitor(m_turns, m_pieces, m_distance_strategy);
|
||||
|
||||
typedef turn_overlaps_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_point_box_strategy_type
|
||||
> turn_overlaps_box_type;
|
||||
typedef piece_overlaps_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_box_box_strategy_type
|
||||
> piece_overlaps_box_type;
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box_type
|
||||
>::apply(m_turns, m_pieces, visitor,
|
||||
turn_get_box(), turn_overlaps_box_type(),
|
||||
piece_get_box(), piece_overlaps_box_type());
|
||||
turn_get_box<Strategy>(m_strategy),
|
||||
turn_overlaps_box<Strategy>(m_strategy),
|
||||
piece_get_box<Strategy>(m_strategy),
|
||||
piece_overlaps_box<Strategy>(m_strategy));
|
||||
}
|
||||
}
|
||||
|
||||
@ -771,7 +714,7 @@ struct buffered_piece_collection
|
||||
original_rings.back()
|
||||
= original_ring(clockwise_ring,
|
||||
is_interior, has_interiors,
|
||||
m_envelope_strategy, m_expand_strategy);
|
||||
m_strategy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,6 +813,7 @@ struct buffered_piece_collection
|
||||
boost::begin(ring) + pc.first_seg_id.segment_index,
|
||||
boost::begin(ring) + pc.beyond_last_segment_index,
|
||||
m_robust_policy,
|
||||
m_strategy,
|
||||
ring_id, 10);
|
||||
}
|
||||
|
||||
@ -1042,7 +986,7 @@ struct buffered_piece_collection
|
||||
enrich_intersection_points<false, false, overlay_buffer>(m_turns,
|
||||
m_clusters, offsetted_rings, offsetted_rings,
|
||||
m_robust_policy,
|
||||
m_intersection_strategy);
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
// Discards all rings which do have not-OK intersection points only.
|
||||
@ -1067,8 +1011,6 @@ struct buffered_piece_collection
|
||||
|
||||
inline bool point_coveredby_original(point_type const& point)
|
||||
{
|
||||
typedef typename IntersectionStrategy::disjoint_point_box_strategy_type d_pb_strategy_type;
|
||||
|
||||
signed_size_type count_in_original = 0;
|
||||
|
||||
// Check of the robust point of this outputted ring is in
|
||||
@ -1085,16 +1027,13 @@ struct buffered_piece_collection
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (detail::disjoint::disjoint_point_box(point,
|
||||
original.m_box,
|
||||
d_pb_strategy_type()))
|
||||
if (detail::disjoint::disjoint_point_box(point, original.m_box,m_strategy))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int const geometry_code
|
||||
= detail::within::point_in_geometry(point,
|
||||
original.m_ring, m_point_in_geometry_strategy);
|
||||
= detail::within::point_in_geometry(point, original.m_ring, m_strategy);
|
||||
|
||||
if (geometry_code == -1)
|
||||
{
|
||||
@ -1133,7 +1072,7 @@ struct buffered_piece_collection
|
||||
buffered_ring<Ring>& ring = *it;
|
||||
if (! ring.has_intersections()
|
||||
&& boost::size(ring) > 0u
|
||||
&& geometry::area(ring, m_area_strategy) < 0)
|
||||
&& geometry::area(ring, m_strategy) < 0)
|
||||
{
|
||||
if (! point_coveredby_original(geometry::range::front(ring)))
|
||||
{
|
||||
@ -1173,7 +1112,7 @@ struct buffered_piece_collection
|
||||
traversed_rings.clear();
|
||||
buffer_overlay_visitor visitor;
|
||||
traverser::apply(offsetted_rings, offsetted_rings,
|
||||
m_intersection_strategy, m_robust_policy,
|
||||
m_strategy, m_robust_policy,
|
||||
m_turns, traversed_rings,
|
||||
turn_info_per_ring,
|
||||
m_clusters, visitor);
|
||||
@ -1202,7 +1141,14 @@ struct buffered_piece_collection
|
||||
template <typename GeometryOutput, typename OutputIterator>
|
||||
inline OutputIterator assign(OutputIterator out) const
|
||||
{
|
||||
typedef detail::overlay::ring_properties<point_type, area_result_type> properties;
|
||||
typedef typename geometry::area_result
|
||||
<
|
||||
buffered_ring<Ring>, Strategy
|
||||
>::type area_result_type;
|
||||
typedef detail::overlay::ring_properties
|
||||
<
|
||||
point_type, area_result_type
|
||||
> properties;
|
||||
|
||||
std::map<ring_identifier, properties> selected;
|
||||
|
||||
@ -1218,7 +1164,7 @@ struct buffered_piece_collection
|
||||
if (! it->has_intersections()
|
||||
&& ! it->is_untouched_outside_original)
|
||||
{
|
||||
properties p = properties(*it, m_area_strategy);
|
||||
properties p = properties(*it, m_strategy);
|
||||
if (p.valid)
|
||||
{
|
||||
ring_identifier id(0, index, -1);
|
||||
@ -1234,7 +1180,7 @@ struct buffered_piece_collection
|
||||
it != boost::end(traversed_rings);
|
||||
++it, ++index)
|
||||
{
|
||||
properties p = properties(*it, m_area_strategy);
|
||||
properties p = properties(*it, m_strategy);
|
||||
if (p.valid)
|
||||
{
|
||||
ring_identifier id(2, index, -1);
|
||||
@ -1243,9 +1189,9 @@ struct buffered_piece_collection
|
||||
}
|
||||
|
||||
detail::overlay::assign_parents<overlay_buffer>(offsetted_rings, traversed_rings,
|
||||
selected, m_intersection_strategy);
|
||||
selected, m_strategy);
|
||||
return detail::overlay::add_rings<GeometryOutput>(selected, offsetted_rings, traversed_rings, out,
|
||||
m_area_strategy);
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -117,7 +117,7 @@ template
|
||||
typename Pieces,
|
||||
typename Rings,
|
||||
typename Turns,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy
|
||||
>
|
||||
class piece_turn_visitor
|
||||
@ -125,7 +125,7 @@ class piece_turn_visitor
|
||||
Pieces const& m_pieces;
|
||||
Rings const& m_rings;
|
||||
Turns& m_turns;
|
||||
IntersectionStrategy const& m_intersection_strategy;
|
||||
Strategy const& m_strategy;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
|
||||
template <typename Piece>
|
||||
@ -271,7 +271,7 @@ class piece_turn_visitor
|
||||
|
||||
turn_policy::apply(unique_sub_range1, unique_sub_range2,
|
||||
the_model,
|
||||
m_intersection_strategy,
|
||||
m_strategy,
|
||||
m_robust_policy,
|
||||
std::back_inserter(m_turns));
|
||||
}
|
||||
@ -283,12 +283,12 @@ public:
|
||||
piece_turn_visitor(Pieces const& pieces,
|
||||
Rings const& ring_collection,
|
||||
Turns& turns,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
: m_pieces(pieces)
|
||||
, m_rings(ring_collection)
|
||||
, m_turns(turns)
|
||||
, m_intersection_strategy(intersection_strategy)
|
||||
, m_strategy(strategy)
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
@ -307,7 +307,7 @@ public:
|
||||
|| is_on_same_convex_ring(piece1, piece2)
|
||||
|| detail::disjoint::disjoint_box_box(section1.bounding_box,
|
||||
section2.bounding_box,
|
||||
m_intersection_strategy.get_disjoint_box_box_strategy()) )
|
||||
m_strategy) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -167,9 +167,11 @@ struct piece_border
|
||||
return result;
|
||||
}
|
||||
|
||||
void get_properties_of_border(bool is_point_buffer, Point const& center)
|
||||
template <typename Strategy>
|
||||
void get_properties_of_border(bool is_point_buffer, Point const& center,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
m_has_envelope = calculate_envelope(m_envelope);
|
||||
m_has_envelope = calculate_envelope(m_envelope, strategy);
|
||||
if (m_has_envelope)
|
||||
{
|
||||
// Take roundings into account, enlarge box
|
||||
@ -182,8 +184,8 @@ struct piece_border
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SideStrategy>
|
||||
void get_properties_of_offsetted_ring_part(SideStrategy const& strategy)
|
||||
template <typename Strategy>
|
||||
void get_properties_of_offsetted_ring_part(Strategy const& strategy)
|
||||
{
|
||||
if (! ring_or_original_empty())
|
||||
{
|
||||
@ -209,16 +211,16 @@ struct piece_border
|
||||
m_originals[m_original_size++] = point;
|
||||
}
|
||||
|
||||
template <typename Box>
|
||||
bool calculate_envelope(Box& envelope) const
|
||||
template <typename Box, typename Strategy>
|
||||
bool calculate_envelope(Box& envelope, Strategy const& strategy) const
|
||||
{
|
||||
geometry::assign_inverse(envelope);
|
||||
if (ring_or_original_empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
expand_envelope(envelope, m_ring->begin() + m_begin, m_ring->begin() + m_end);
|
||||
expand_envelope(envelope, m_originals.begin(), m_originals.begin() + m_original_size);
|
||||
expand_envelope(envelope, m_ring->begin() + m_begin, m_ring->begin() + m_end, strategy);
|
||||
expand_envelope(envelope, m_originals.begin(), m_originals.begin() + m_original_size, strategy);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -333,8 +335,8 @@ private :
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TurnPoint, typename Strategy, typename State>
|
||||
bool step(TurnPoint const& point, Point const& p1, Point const& p2, Strategy const & strategy,
|
||||
template <typename TurnPoint, typename TiRStrategy, typename State>
|
||||
bool step(TurnPoint const& point, Point const& p1, Point const& p2, TiRStrategy const & strategy,
|
||||
geometry::strategy::buffer::place_on_ring_type place_on_ring, State& state) const
|
||||
{
|
||||
// A step between original/offsetted ring is always convex
|
||||
@ -357,22 +359,17 @@ private :
|
||||
return strategy.apply(point, p1, p2, dm, place_on_ring, state);
|
||||
}
|
||||
|
||||
template <typename It, typename Box>
|
||||
void expand_envelope(Box& envelope, It begin, It end) const
|
||||
template <typename It, typename Box, typename Strategy>
|
||||
void expand_envelope(Box& envelope, It begin, It end, Strategy const& strategy) const
|
||||
{
|
||||
typedef typename strategy::expand::services::default_strategy
|
||||
<
|
||||
point_tag, typename cs_tag<Box>::type
|
||||
>::type expand_strategy_type;
|
||||
|
||||
for (It it = begin; it != end; ++it)
|
||||
{
|
||||
geometry::expand(envelope, *it, expand_strategy_type());
|
||||
geometry::expand(envelope, *it, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SideStrategy>
|
||||
bool is_convex(SideStrategy const& strategy) const
|
||||
template <typename Strategy>
|
||||
bool is_convex(Strategy const& strategy) const
|
||||
{
|
||||
if (ring_or_original_empty())
|
||||
{
|
||||
@ -416,8 +413,8 @@ private :
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename It, typename SideStrategy>
|
||||
bool is_convex(Point& previous, Point& current, It begin, It end, SideStrategy const& strategy) const
|
||||
template <typename It, typename Strategy>
|
||||
bool is_convex(Point& previous, Point& current, It begin, It end, Strategy const& strategy) const
|
||||
{
|
||||
for (It it = begin; it != end; ++it)
|
||||
{
|
||||
@ -429,19 +426,16 @@ private :
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename SideStrategy>
|
||||
bool is_convex(Point& previous, Point& current, Point const& next, SideStrategy const& strategy) const
|
||||
template <typename Strategy>
|
||||
bool is_convex(Point& previous, Point& current, Point const& next, Strategy const& strategy) const
|
||||
{
|
||||
typename SideStrategy::equals_point_point_strategy_type const
|
||||
eq_pp_strategy = strategy.get_equals_point_point_strategy();
|
||||
|
||||
int const side = strategy.apply(previous, current, next);
|
||||
int const side = strategy.side().apply(previous, current, next);
|
||||
if (side == 1)
|
||||
{
|
||||
// Next is on the left side of clockwise ring: piece is not convex
|
||||
return false;
|
||||
}
|
||||
if (! equals::equals_point_point(current, next, eq_pp_strategy))
|
||||
if (! equals::equals_point_point(current, next, strategy))
|
||||
{
|
||||
previous = current;
|
||||
current = next;
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2016, 2018.
|
||||
// Modifications copyright (c) 2016-2018 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2016-2020.
|
||||
// Modifications copyright (c) 2016-2020 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -31,31 +31,40 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace buffer
|
||||
{
|
||||
|
||||
|
||||
template <typename Strategy>
|
||||
struct original_get_box
|
||||
{
|
||||
explicit original_get_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Original>
|
||||
static inline void apply(Box& total, Original const& original)
|
||||
inline void apply(Box& total, Original const& original) const
|
||||
{
|
||||
assert_coordinate_type_equal(total, original.m_box);
|
||||
typedef typename strategy::expand::services::default_strategy
|
||||
<
|
||||
box_tag, typename cs_tag<Box>::type
|
||||
>::type expand_strategy_type;
|
||||
|
||||
geometry::expand(total, original.m_box, expand_strategy_type());
|
||||
geometry::expand(total, original.m_box, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct original_overlaps_box
|
||||
{
|
||||
explicit original_overlaps_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Original>
|
||||
static inline bool apply(Box const& box, Original const& original)
|
||||
inline bool apply(Box const& box, Original const& original) const
|
||||
{
|
||||
assert_coordinate_type_equal(box, original.m_box);
|
||||
return ! detail::disjoint::disjoint_box_box(box, original.m_box,
|
||||
DisjointBoxBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
struct include_turn_policy
|
||||
@ -67,11 +76,15 @@ struct include_turn_policy
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct turn_in_original_overlaps_box
|
||||
{
|
||||
explicit turn_in_original_overlaps_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Turn>
|
||||
static inline bool apply(Box const& box, Turn const& turn)
|
||||
inline bool apply(Box const& box, Turn const& turn) const
|
||||
{
|
||||
if (! turn.is_turn_traversable || turn.within_original)
|
||||
{
|
||||
@ -80,8 +93,10 @@ struct turn_in_original_overlaps_box
|
||||
}
|
||||
|
||||
return ! geometry::detail::disjoint::disjoint_point_box(
|
||||
turn.point, box, DisjointPointBoxStrategy());
|
||||
turn.point, box, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
//! Check if specified is in range of specified iterators
|
||||
@ -210,13 +225,13 @@ inline int point_in_original(Point const& point, Original const& original,
|
||||
}
|
||||
|
||||
|
||||
template <typename Turns, typename PointInGeometryStrategy>
|
||||
template <typename Turns, typename Strategy>
|
||||
class turn_in_original_visitor
|
||||
{
|
||||
public:
|
||||
turn_in_original_visitor(Turns& turns, PointInGeometryStrategy const& strategy)
|
||||
turn_in_original_visitor(Turns& turns, Strategy const& strategy)
|
||||
: m_mutable_turns(turns)
|
||||
, m_point_in_geometry_strategy(strategy)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Turn, typename Original>
|
||||
@ -234,13 +249,14 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (geometry::disjoint(turn.point, original.m_box))
|
||||
if (geometry::disjoint(turn.point, original.m_box, m_strategy))
|
||||
{
|
||||
// Skip all disjoint
|
||||
return true;
|
||||
}
|
||||
|
||||
int const code = point_in_original(turn.point, original, m_point_in_geometry_strategy);
|
||||
int const code = point_in_original(turn.point, original,
|
||||
m_strategy.relate(turn.point, original.m_ring));
|
||||
|
||||
if (code == -1)
|
||||
{
|
||||
@ -277,7 +293,7 @@ public:
|
||||
|
||||
private :
|
||||
Turns& m_mutable_turns;
|
||||
PointInGeometryStrategy const& m_point_in_geometry_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
|
||||
|
@ -54,13 +54,11 @@ private:
|
||||
QueryRangeIterator& qit_min,
|
||||
Distance& dist_min)
|
||||
{
|
||||
typedef strategy::index::services::from_strategy
|
||||
<
|
||||
Strategy
|
||||
> index_strategy_from;
|
||||
using strategies::index::services::strategy_converter;
|
||||
typedef index::parameters
|
||||
<
|
||||
index::linear<8>, typename index_strategy_from::type
|
||||
index::linear<8>,
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
> index_parameters_type;
|
||||
typedef index::rtree<RTreeValueType, index_parameters_type> rtree_type;
|
||||
|
||||
@ -73,7 +71,7 @@ private:
|
||||
// create -- packing algorithm
|
||||
rtree_type rt(rtree_first, rtree_last,
|
||||
index_parameters_type(index::linear<8>(),
|
||||
index_strategy_from::get(strategy)));
|
||||
strategy_converter<Strategy>::get(strategy)));
|
||||
|
||||
RTreeValueType t_v;
|
||||
bool first = true;
|
||||
|
@ -4,8 +4,8 @@
|
||||
// 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, 2017, 2019.
|
||||
// Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -66,8 +66,7 @@ struct covered_by<Point, Box, point_tag, box_tag>
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
::boost::ignore_unused(strategy);
|
||||
return strategy.apply(point, box);
|
||||
return strategy.covered_by(point, box).apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
@ -78,8 +77,7 @@ struct covered_by<Box1, Box2, box_tag, box_tag>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
::boost::ignore_unused(strategy);
|
||||
return strategy.apply(box1, box2);
|
||||
return strategy.covered_by(box1, box2).apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4,9 +4,8 @@
|
||||
// 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, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2013-2021.
|
||||
// Modifications copyright (c) 2013-2021 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
|
||||
@ -30,6 +29,8 @@
|
||||
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -56,9 +57,14 @@ struct covered_by
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct covered_by
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@ -68,23 +74,49 @@ struct covered_by
|
||||
concepts::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1,
|
||||
geometry2,
|
||||
strategy);
|
||||
return dispatch::covered_by
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct covered_by<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
return covered_by
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct covered_by<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::covered_by::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return covered_by::apply(geometry1, geometry2, strategy_type());
|
||||
return covered_by
|
||||
<
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -101,7 +133,7 @@ struct covered_by
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_strategy::covered_by
|
||||
return resolve_strategy::covered_by<Strategy>
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
@ -60,13 +60,9 @@ inline bool rings_containing(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: This will be removed when IntersectionStrategy is replaced with
|
||||
// UmbrellaStrategy
|
||||
auto const pgs = strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>();
|
||||
|
||||
return geometry::detail::any_range_of(geometry2, [&](auto const& range)
|
||||
{
|
||||
return point_on_border_covered_by(range, geometry1, pgs);
|
||||
return point_on_border_covered_by(range, geometry1, strategy);
|
||||
});
|
||||
}
|
||||
|
||||
@ -116,11 +112,9 @@ struct areal_box
|
||||
Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: This will be removed when UmbrellaStrategy is supported
|
||||
auto const ds = strategy.get_disjoint_segment_box_strategy();
|
||||
if (! geometry::all_segments_of(areal, [&](auto const& s)
|
||||
{
|
||||
return disjoint_segment_box::apply(s, box, ds);
|
||||
return disjoint_segment_box::apply(s, box, strategy);
|
||||
}) )
|
||||
{
|
||||
return false;
|
||||
@ -129,8 +123,7 @@ struct areal_box
|
||||
// If there is no intersection of any segment and box,
|
||||
// the box might be located inside areal geometry
|
||||
|
||||
if ( point_on_border_covered_by(box, areal,
|
||||
strategy.template get_point_in_geometry_strategy<Box, Areal>()) )
|
||||
if ( point_on_border_covered_by(box, areal, strategy) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -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-2018.
|
||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, 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
|
||||
@ -43,8 +43,23 @@ namespace detail { namespace disjoint
|
||||
\note Is used from other algorithms, declared separately
|
||||
to avoid circular references
|
||||
*/
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const&)
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, typename Strategy,
|
||||
std::enable_if_t<strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
typedef decltype(strategy.disjoint(box1, box2)) strategy_type;
|
||||
return strategy_type::apply(box1, box2);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2, typename Strategy,
|
||||
std::enable_if_t<! strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const& )
|
||||
{
|
||||
return Strategy::apply(box1, box2);
|
||||
}
|
||||
@ -63,9 +78,10 @@ template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct disjoint<Box1, Box2, DimensionCount, box_tag, box_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
return Strategy::apply(box1, box2);
|
||||
typedef decltype(strategy.disjoint(box1, box2)) strategy_type;
|
||||
return strategy_type::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2021.
|
||||
// Modifications copyright (c) 2013-2021, 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
|
||||
@ -32,7 +32,10 @@
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/disjoint.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -41,9 +44,14 @@ namespace boost { namespace geometry
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct disjoint
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@ -53,13 +61,35 @@ struct disjoint
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct disjoint<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
return dispatch::disjoint
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct disjoint<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::disjoint::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type strategy_type;
|
||||
@ -88,7 +118,10 @@ struct disjoint
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return resolve_strategy::disjoint::apply(geometry1, geometry2, strategy);
|
||||
return resolve_strategy::disjoint
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ struct disjoint_no_intersections_policy
|
||||
point1_type p;
|
||||
geometry::point_on_border(p, g1);
|
||||
|
||||
return !geometry::covered_by(p, g2, strategy);
|
||||
return ! geometry::covered_by(p, g2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -120,9 +120,7 @@ struct disjoint_linear_areal
|
||||
return false;
|
||||
}
|
||||
|
||||
return NoIntersectionsPolicy
|
||||
::apply(g1, g2,
|
||||
strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>());
|
||||
return NoIntersectionsPolicy::apply(g1, g2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -195,8 +193,7 @@ public:
|
||||
typename point_type<Segment>::type p;
|
||||
detail::assign_point_from_index<0>(segment, p);
|
||||
|
||||
return !geometry::covered_by(p, polygon,
|
||||
strategy.template get_point_in_geometry_strategy<Segment, Polygon>());
|
||||
return ! geometry::covered_by(p, polygon, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -235,8 +232,7 @@ struct disjoint_segment_areal<Segment, Ring, ring_tag>
|
||||
typename point_type<Segment>::type p;
|
||||
detail::assign_point_from_index<0>(segment, p);
|
||||
|
||||
return !geometry::covered_by(p, ring,
|
||||
strategy.template get_point_in_geometry_strategy<Segment, Ring>());
|
||||
return ! geometry::covered_by(p, ring, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -65,8 +65,8 @@ struct disjoint_segment
|
||||
|
||||
detail::segment_as_subrange<Segment1> sub_range1(segment1);
|
||||
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
||||
intersection_return_type is = strategy.apply(sub_range1, sub_range2,
|
||||
intersection_policy());
|
||||
intersection_return_type is = strategy.relate().apply(sub_range1, sub_range2,
|
||||
intersection_policy());
|
||||
|
||||
return is.count == 0;
|
||||
}
|
||||
|
@ -58,8 +58,7 @@ struct disjoint_point_segment_or_box<Segment, segment_tag>
|
||||
return dispatch::disjoint
|
||||
<
|
||||
Point, Segment
|
||||
>::apply(point, segment,
|
||||
strategy.template get_point_in_geometry_strategy<Point, Segment>());
|
||||
>::apply(point, segment, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,8 +71,7 @@ struct disjoint_point_segment_or_box<Box, box_tag>
|
||||
return dispatch::disjoint
|
||||
<
|
||||
Point, Box
|
||||
>::apply(point, box,
|
||||
strategy.get_disjoint_point_box_strategy());
|
||||
>::apply(point, box, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -125,72 +125,78 @@ template <typename MultiPoint, typename Linear>
|
||||
class multipoint_linear
|
||||
{
|
||||
private:
|
||||
template <typename ExpandPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_point
|
||||
{
|
||||
explicit expand_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
void apply(Box& total, Point const& point) const
|
||||
{
|
||||
geometry::expand(total, point, ExpandPointBoxStrategy());
|
||||
geometry::expand(total, point, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename EnvelopeStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_segment
|
||||
{
|
||||
explicit expand_box_segment(EnvelopeStrategy const& strategy)
|
||||
explicit expand_box_segment(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Segment>
|
||||
inline void apply(Box& total, Segment const& segment) const
|
||||
void apply(Box& total, Segment const& segment) const
|
||||
{
|
||||
geometry::expand(total,
|
||||
geometry::return_envelope<Box>(segment, m_strategy),
|
||||
// TEMP - envelope umbrella strategy also contains
|
||||
// expand strategies
|
||||
strategies::envelope::services::strategy_converter
|
||||
<
|
||||
EnvelopeStrategy
|
||||
>::get(m_strategy));
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
EnvelopeStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
explicit overlaps_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
bool apply(Box const& box, Point const& point) const
|
||||
{
|
||||
// The default strategy is enough in this case
|
||||
return ! detail::disjoint::disjoint_point_box(point, box,
|
||||
DisjointPointBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_segment
|
||||
{
|
||||
explicit overlaps_box_segment(DisjointStrategy const& strategy)
|
||||
explicit overlaps_box_segment(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Segment>
|
||||
inline bool apply(Box const& box, Segment const& segment) const
|
||||
bool apply(Box const& box, Segment const& segment) const
|
||||
{
|
||||
return ! dispatch::disjoint<Segment, Box>::apply(segment, box, m_strategy);
|
||||
}
|
||||
|
||||
DisjointStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename PtSegStrategy>
|
||||
template <typename Strategy>
|
||||
class item_visitor_type
|
||||
{
|
||||
public:
|
||||
item_visitor_type(PtSegStrategy const& strategy)
|
||||
item_visitor_type(Strategy const& strategy)
|
||||
: m_intersection_found(false)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
@ -211,7 +217,7 @@ private:
|
||||
|
||||
private:
|
||||
bool m_intersection_found;
|
||||
PtSegStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
// structs for partition -- end
|
||||
|
||||
@ -245,11 +251,6 @@ public:
|
||||
{
|
||||
item_visitor_type<Strategy> visitor(strategy);
|
||||
|
||||
typedef typename Strategy::expand_point_strategy_type expand_point_strategy_type;
|
||||
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
|
||||
typedef typename Strategy::disjoint_strategy_type disjoint_strategy_type;
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type disjoint_pb_strategy_type;
|
||||
|
||||
// TODO: disjoint Segment/Box may be called in partition multiple times
|
||||
// possibly for non-cartesian segments which could be slow. We should consider
|
||||
// passing a range of bounding boxes of segments after calculating them once.
|
||||
@ -259,16 +260,17 @@ public:
|
||||
<
|
||||
geometry::model::box<typename point_type<MultiPoint>::type>
|
||||
>::apply(multipoint, segment_range(linear), visitor,
|
||||
expand_box_point<expand_point_strategy_type>(),
|
||||
overlaps_box_point<disjoint_pb_strategy_type>(),
|
||||
expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
|
||||
overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
|
||||
expand_box_point<Strategy>(strategy),
|
||||
overlaps_box_point<Strategy>(strategy),
|
||||
expand_box_segment<Strategy>(strategy),
|
||||
overlaps_box_segment<Strategy>(strategy));
|
||||
|
||||
return ! visitor.intersection_found();
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Linear const& linear, MultiPoint const& multipoint, Strategy const& strategy)
|
||||
static inline bool apply(Linear const& linear, MultiPoint const& multipoint,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return apply(multipoint, linear, strategy);
|
||||
}
|
||||
@ -284,21 +286,19 @@ public:
|
||||
SingleGeometry const& single_geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type;
|
||||
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
|
||||
box2_type box2;
|
||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
||||
geometry::envelope(single_geometry, box2, strategy);
|
||||
geometry::detail::expand_by_epsilon(box2);
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type())
|
||||
if (! detail::disjoint::disjoint_point_box(*it, box2, strategy)
|
||||
&& ! dispatch::disjoint<point1_type, SingleGeometry>::apply(*it, single_geometry, strategy))
|
||||
{
|
||||
return false;
|
||||
@ -309,7 +309,8 @@ public:
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(SingleGeometry const& single_geometry, MultiPoint const& multi_point, Strategy const& strategy)
|
||||
static inline bool apply(SingleGeometry const& single_geometry, MultiPoint const& multi_point,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return apply(multi_point, single_geometry, strategy);
|
||||
}
|
||||
@ -320,56 +321,77 @@ template <typename MultiPoint, typename MultiGeometry>
|
||||
class multi_point_multi_geometry
|
||||
{
|
||||
private:
|
||||
template <typename ExpandPointStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_point
|
||||
{
|
||||
explicit expand_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
void apply(Box& total, Point const& point) const
|
||||
{
|
||||
geometry::expand(total, point, ExpandPointStrategy());
|
||||
geometry::expand(total, point, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename ExpandBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_box_pair
|
||||
{
|
||||
explicit expand_box_box_pair(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename BoxPair>
|
||||
inline void apply(Box& total, BoxPair const& box_pair) const
|
||||
void apply(Box& total, BoxPair const& box_pair) const
|
||||
{
|
||||
geometry::expand(total, box_pair.first, ExpandBoxStrategy());
|
||||
geometry::expand(total, box_pair.first, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
explicit overlaps_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
bool apply(Box const& box, Point const& point) const
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
return ! detail::disjoint::disjoint_point_box(point, box,
|
||||
DisjointPointBoxStrategy());
|
||||
return ! detail::disjoint::disjoint_point_box(point, box, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_box_pair
|
||||
{
|
||||
explicit overlaps_box_box_pair(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename BoxPair>
|
||||
inline bool apply(Box const& box, BoxPair const& box_pair) const
|
||||
bool apply(Box const& box, BoxPair const& box_pair) const
|
||||
{
|
||||
// The default strategy is enough for Box/Box
|
||||
return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
|
||||
DisjointBoxBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename PtSegStrategy>
|
||||
template <typename Strategy>
|
||||
class item_visitor_type
|
||||
{
|
||||
public:
|
||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||
PtSegStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
: m_intersection_found(false)
|
||||
, m_multi_geometry(multi_geometry)
|
||||
, m_strategy(strategy)
|
||||
@ -378,14 +400,15 @@ private:
|
||||
template <typename Point, typename BoxPair>
|
||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
||||
{
|
||||
typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pb_strategy_type;
|
||||
|
||||
typedef typename boost::range_value<MultiGeometry>::type single_type;
|
||||
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! m_intersection_found
|
||||
&& ! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pb_strategy_type())
|
||||
&& ! dispatch::disjoint<Point, single_type>::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy))
|
||||
&& ! detail::disjoint::disjoint_point_box(point, box_pair.first, m_strategy)
|
||||
&& ! dispatch::disjoint
|
||||
<
|
||||
Point, single_type
|
||||
>::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy))
|
||||
{
|
||||
m_intersection_found = true;
|
||||
return false;
|
||||
@ -398,7 +421,7 @@ private:
|
||||
private:
|
||||
bool m_intersection_found;
|
||||
MultiGeometry const& m_multi_geometry;
|
||||
PtSegStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
// structs for partition -- end
|
||||
|
||||
@ -411,53 +434,26 @@ public:
|
||||
typedef model::box<point1_type> box1_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
std::size_t count2 = boost::size(multi_geometry);
|
||||
std::vector<box_pair_type> boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, envelope_strategy);
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
item_visitor_type<Strategy> visitor(multi_geometry, strategy);
|
||||
|
||||
typedef expand_box_point
|
||||
<
|
||||
typename Strategy::expand_point_strategy_type
|
||||
> expand_box_point_type;
|
||||
typedef overlaps_box_point
|
||||
<
|
||||
typename Strategy::disjoint_point_box_strategy_type
|
||||
> overlaps_box_point_type;
|
||||
typedef expand_box_box_pair
|
||||
<
|
||||
// TEMP - envelope umbrella strategy also contains
|
||||
// expand strategies
|
||||
decltype(strategies::envelope::services::strategy_converter
|
||||
<
|
||||
typename Strategy::envelope_strategy_type
|
||||
>::get(strategy.get_envelope_strategy())
|
||||
.expand(std::declval<box1_type>(),
|
||||
std::declval<box2_type>()))
|
||||
> expand_box_box_pair_type;
|
||||
typedef overlaps_box_box_pair
|
||||
<
|
||||
typename Strategy::disjoint_box_box_strategy_type
|
||||
> overlaps_box_box_pair_type;
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box1_type
|
||||
>::apply(multi_point, boxes, visitor,
|
||||
expand_box_point_type(),
|
||||
overlaps_box_point_type(),
|
||||
expand_box_box_pair_type(),
|
||||
overlaps_box_box_pair_type());
|
||||
expand_box_point<Strategy>(strategy),
|
||||
overlaps_box_point<Strategy>(strategy),
|
||||
expand_box_box_pair<Strategy>(strategy),
|
||||
overlaps_box_box_pair<Strategy>(strategy));
|
||||
|
||||
return ! visitor.intersection_found();
|
||||
}
|
||||
|
@ -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-2018.
|
||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, 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
|
||||
@ -41,8 +41,26 @@ namespace detail { namespace disjoint
|
||||
/*!
|
||||
\brief Internal utility function to detect if point/box are disjoint
|
||||
*/
|
||||
template <typename Point, typename Box, typename Strategy>
|
||||
inline bool disjoint_point_box(Point const& point, Box const& box, Strategy const& )
|
||||
template
|
||||
<
|
||||
typename Point, typename Box, typename Strategy,
|
||||
std::enable_if_t<strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool disjoint_point_box(Point const& point, Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef decltype(strategy.covered_by(point, box)) strategy_type;
|
||||
// ! covered_by(point, box)
|
||||
return ! strategy_type::apply(point, box);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Point, typename Box, typename Strategy,
|
||||
std::enable_if_t<! strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool disjoint_point_box(Point const& point, Box const& box,
|
||||
Strategy const& )
|
||||
{
|
||||
// ! covered_by(point, box)
|
||||
return ! Strategy::apply(point, box);
|
||||
@ -62,10 +80,12 @@ template <typename Point, typename Box, std::size_t DimensionCount>
|
||||
struct disjoint<Point, Box, DimensionCount, point_tag, box_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& )
|
||||
static inline bool apply(Point const& point, Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef decltype(strategy.covered_by(point, box)) strategy_type;
|
||||
// ! covered_by(point, box)
|
||||
return ! Strategy::apply(point, box);
|
||||
return ! strategy_type::apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, 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,11 +22,14 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/disjoint.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
|
||||
@ -46,10 +49,28 @@ namespace detail { namespace disjoint
|
||||
\brief Internal utility function to detect of points are disjoint
|
||||
\note To avoid circular references
|
||||
*/
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename Strategy,
|
||||
std::enable_if_t<strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
// ! within(point1, point2)
|
||||
return ! strategy_type::apply(point1, point2);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename Strategy,
|
||||
std::enable_if_t<! strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
{
|
||||
// ! within(point1, point2)
|
||||
return ! Strategy::apply(point1, point2);
|
||||
}
|
||||
|
||||
@ -68,9 +89,11 @@ struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return ! Strategy::apply(point1, point2);
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
// ! within(point1, point2)
|
||||
return ! strategy_type::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -247,7 +247,7 @@ struct disjoint_segment_box
|
||||
Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return strategy.apply(segment, box);
|
||||
return strategy.disjoint(segment, box).apply(segment, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/tags.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
|
||||
@ -164,8 +165,12 @@ struct point_to_ring
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: pass strategy
|
||||
if (within::within_point_geometry(point, ring,
|
||||
strategy.get_point_in_geometry_strategy()))
|
||||
auto const s = strategies::relate::services::strategy_converter
|
||||
<
|
||||
decltype(strategy.get_point_in_geometry_strategy())
|
||||
>::get(strategy.get_point_in_geometry_strategy());
|
||||
|
||||
if (within::within_point_geometry(point, ring, s))
|
||||
{
|
||||
return return_type(0);
|
||||
}
|
||||
@ -207,11 +212,15 @@ private:
|
||||
InteriorRingIterator last,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TEMP: pass strategy
|
||||
auto const s = strategies::relate::services::strategy_converter
|
||||
<
|
||||
decltype(strategy.get_point_in_geometry_strategy())
|
||||
>::get(strategy.get_point_in_geometry_strategy());
|
||||
|
||||
for (InteriorRingIterator it = first; it != last; ++it)
|
||||
{
|
||||
// TODO: pass strategy
|
||||
if (within::within_point_geometry(point, *it,
|
||||
strategy.get_point_in_geometry_strategy()))
|
||||
if (within::within_point_geometry(point, *it, s))
|
||||
{
|
||||
// the point is inside a polygon hole, so its distance
|
||||
// to the polygon its distance to the polygon's
|
||||
@ -240,9 +249,13 @@ public:
|
||||
Polygon const& polygon,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: pass strategy
|
||||
if (! within::covered_by_point_geometry(point, exterior_ring(polygon),
|
||||
strategy.get_point_in_geometry_strategy()))
|
||||
// TEMP: pass strategy
|
||||
auto const s = strategies::relate::services::strategy_converter
|
||||
<
|
||||
decltype(strategy.get_point_in_geometry_strategy())
|
||||
>::get(strategy.get_point_in_geometry_strategy());
|
||||
|
||||
if (! within::covered_by_point_geometry(point, exterior_ring(polygon), s))
|
||||
{
|
||||
// the point is outside the exterior ring, so its distance
|
||||
// to the polygon is its distance to the polygon's exterior ring
|
||||
@ -340,8 +353,12 @@ struct point_to_multigeometry<Point, MultiPolygon, Strategy, true>
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: pass strategy
|
||||
if (within::covered_by_point_geometry(point, multipolygon,
|
||||
strategy.get_point_in_geometry_strategy()))
|
||||
auto const s = strategies::relate::services::strategy_converter
|
||||
<
|
||||
decltype(strategy.get_point_in_geometry_strategy())
|
||||
>::get(strategy.get_point_in_geometry_strategy());
|
||||
|
||||
if (within::covered_by_point_geometry(point, multipolygon, s))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,17 +58,20 @@ namespace detail { namespace distance
|
||||
{
|
||||
|
||||
|
||||
// TODO: Take strategy
|
||||
template <typename Segment, typename Box>
|
||||
inline bool intersects_segment_box(Segment const& segment, Box const& box)
|
||||
template <typename Segment, typename Box, typename Strategy>
|
||||
inline bool intersects_segment_box(Segment const& segment, Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename strategy::disjoint::services::default_strategy
|
||||
// TODO: pass strategy
|
||||
auto const s = strategies::relate::services::strategy_converter
|
||||
<
|
||||
Segment, Box
|
||||
>::type strategy_type;
|
||||
// This is the only strategy defined in distance segment/box
|
||||
// strategies that carries the information about the spheroid
|
||||
// so use it for now.
|
||||
decltype(strategy.get_side_strategy())
|
||||
>::get(strategy.get_side_strategy());
|
||||
|
||||
return ! detail::disjoint::disjoint_segment_box::apply(segment, box,
|
||||
strategy_type());
|
||||
return ! detail::disjoint::disjoint_segment_box::apply(segment, box, s);
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +117,7 @@ public:
|
||||
Strategy const& strategy,
|
||||
bool check_intersection = true)
|
||||
{
|
||||
if (check_intersection && intersects_segment_box(segment, box))
|
||||
if (check_intersection && intersects_segment_box(segment, box, strategy))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -229,7 +232,7 @@ public:
|
||||
Strategy const& strategy,
|
||||
bool check_intersection = true)
|
||||
{
|
||||
if (check_intersection && intersects_segment_box(segment, box))
|
||||
if (check_intersection && intersects_segment_box(segment, box, strategy))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,9 +64,11 @@ template
|
||||
struct point_point
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return Strategy::apply(point1, point2);
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
return strategy_type::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
@ -107,25 +109,22 @@ struct segment_segment
|
||||
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typename Strategy::point_in_point_strategy_type const&
|
||||
pt_pt_strategy = strategy.get_point_in_point_strategy();
|
||||
|
||||
return equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
? equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
: ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -138,15 +137,13 @@ struct area_check
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::area(geometry1,
|
||||
strategy.template get_area_strategy<Geometry1>()),
|
||||
geometry::area(geometry2,
|
||||
strategy.template get_area_strategy<Geometry2>()));
|
||||
return geometry::math::equals(geometry::area(geometry1, strategy),
|
||||
geometry::area(geometry2, strategy));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct length_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
@ -154,16 +151,14 @@ struct length_check
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::length(geometry1,
|
||||
strategy.template get_distance_strategy<Geometry1>()),
|
||||
geometry::length(geometry2,
|
||||
strategy.template get_distance_strategy<Geometry2>()));
|
||||
return geometry::math::equals(geometry::length(geometry1, strategy),
|
||||
geometry::length(geometry2, strategy));
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
struct collected_vector
|
||||
{
|
||||
typedef typename geometry::select_most_precise
|
||||
@ -179,7 +174,7 @@ struct collected_vector
|
||||
<
|
||||
calculation_type,
|
||||
Geometry1,
|
||||
typename IntersectionStrategy::side_strategy_type
|
||||
decltype(std::declval<Strategy>().side())
|
||||
> type;
|
||||
};
|
||||
|
||||
|
@ -5,9 +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, 2017, 2019.
|
||||
// Modifications copyright (c) 2014-2019 Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2014-2021.
|
||||
// Modifications copyright (c) 2014-2021 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
|
||||
|
||||
@ -30,13 +29,16 @@
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -94,9 +96,14 @@ struct equals<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, Dimensio
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct equals
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@ -106,13 +113,35 @@ struct equals
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct equals<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct equals<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
@ -145,7 +174,9 @@ struct equals
|
||||
>();
|
||||
|
||||
return resolve_strategy::equals
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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-2018.
|
||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, 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,6 +22,11 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@ -33,7 +38,23 @@ namespace detail { namespace equals
|
||||
\brief Internal utility function to detect of points are disjoint
|
||||
\note To avoid circular references
|
||||
*/
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename Strategy,
|
||||
std::enable_if_t<strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
return strategy_type::apply(point1, point2);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename Strategy,
|
||||
std::enable_if_t<! strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
{
|
||||
|
@ -136,27 +136,6 @@ inline bool has_self_intersections(Geometry const& geometry,
|
||||
return false;
|
||||
}
|
||||
|
||||
// For backward compatibility
|
||||
template <typename Geometry>
|
||||
inline bool has_self_intersections(Geometry const& geometry,
|
||||
bool throw_on_self_intersection = true)
|
||||
{
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
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, strategy);
|
||||
|
||||
return has_self_intersections(geometry, strategy, robust_policy,
|
||||
throw_on_self_intersection);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::overlay
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2020, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2020-2021, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
@ -109,10 +109,6 @@ struct intersection_areal_areal_<TupledOut, tupled_output_tag>
|
||||
<
|
||||
areal::index, TupledOut
|
||||
>::type areal_out_type;
|
||||
typedef typename geometry::tuples::element
|
||||
<
|
||||
pointlike::index, TupledOut
|
||||
>::type pointlike_out_type;
|
||||
|
||||
// NOTE: The same robust_policy is used in each call of
|
||||
// intersection_insert. Is that correct?
|
||||
@ -157,11 +153,7 @@ struct intersection_areal_areal_<TupledOut, tupled_output_tag>
|
||||
areal_out_boundary,
|
||||
robust_policy,
|
||||
pointlike::get(geometry_out),
|
||||
strategy.template get_point_in_geometry_strategy
|
||||
<
|
||||
pointlike_out_type,
|
||||
areal_out_boundary_type
|
||||
>());
|
||||
strategy);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2017, 2019.
|
||||
// Modifications copyright (c) 2014-2019, Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2014-2020.
|
||||
// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -23,6 +22,8 @@
|
||||
#include <boost/geometry/algorithms/detail/tupled_output.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
@ -108,14 +109,18 @@ struct intersection
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct intersection
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
typename GeometryOut
|
||||
>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
@ -140,7 +145,34 @@ struct intersection
|
||||
>::apply(geometry1, geometry2, robust_policy, geometry_out,
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct intersection<Strategy, false>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename GeometryOut
|
||||
>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut & geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
return intersection
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2, geometry_out,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct intersection<default_strategy, false>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
@ -152,28 +184,15 @@ struct intersection
|
||||
GeometryOut & geometry_out,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename geometry::rescale_overlay_policy_type
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::cs_tag<Geometry1>::type
|
||||
>::type rescale_policy_type;
|
||||
|
||||
typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type strategy;
|
||||
>::type strategy_type;
|
||||
|
||||
rescale_policy_type robust_policy
|
||||
= geometry::get_rescale_policy<rescale_policy_type>(
|
||||
geometry1, geometry2, strategy);
|
||||
|
||||
return dispatch::intersection
|
||||
return intersection
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, robust_policy, geometry_out,
|
||||
strategy);
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, geometry_out, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -195,10 +214,10 @@ struct intersection
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return resolve_strategy::intersection::apply(geometry1,
|
||||
geometry2,
|
||||
geometry_out,
|
||||
strategy);
|
||||
return resolve_strategy::intersection
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, geometry_out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, 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
|
||||
@ -30,7 +30,7 @@
|
||||
#include <boost/geometry/policies/disjoint_interrupt_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -48,7 +48,7 @@ struct self_intersects
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2021, 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
|
||||
@ -22,7 +22,6 @@
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_simple/failure_policy.hpp>
|
||||
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.hpp>
|
||||
|
||||
@ -38,54 +37,36 @@ namespace detail { namespace is_simple
|
||||
{
|
||||
|
||||
|
||||
template <typename Ring, typename CSTag>
|
||||
struct is_simple_ring
|
||||
template <typename Ring, typename Strategy>
|
||||
inline bool is_simple_ring(Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
static inline bool apply(Ring const& ring)
|
||||
{
|
||||
simplicity_failure_policy policy;
|
||||
return ! boost::empty(ring)
|
||||
&& ! detail::is_valid::has_duplicates
|
||||
<
|
||||
Ring, geometry::closure<Ring>::value, CSTag
|
||||
>::apply(ring, policy);
|
||||
}
|
||||
};
|
||||
simplicity_failure_policy policy;
|
||||
return ! boost::empty(ring)
|
||||
&& ! detail::is_valid::has_duplicates
|
||||
<
|
||||
Ring, geometry::closure<Ring>::value
|
||||
>::apply(ring, policy, strategy);
|
||||
}
|
||||
|
||||
|
||||
template <typename Polygon, typename CSTag>
|
||||
class is_simple_polygon
|
||||
template <typename InteriorRings, typename Strategy>
|
||||
inline bool are_simple_interior_rings(InteriorRings const& interior_rings,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
private:
|
||||
template <typename InteriorRings>
|
||||
static inline
|
||||
bool are_simple_interior_rings(InteriorRings const& interior_rings)
|
||||
{
|
||||
return
|
||||
detail::check_iterator_range
|
||||
<
|
||||
is_simple_ring
|
||||
<
|
||||
typename boost::range_value<InteriorRings>::type,
|
||||
CSTag
|
||||
>
|
||||
>::apply(boost::begin(interior_rings),
|
||||
boost::end(interior_rings));
|
||||
}
|
||||
auto const end = boost::end(interior_rings);
|
||||
return std::find_if(boost::begin(interior_rings), end,
|
||||
[&](auto const& r)
|
||||
{
|
||||
return ! is_simple_ring(r, strategy);
|
||||
}) == end; // non-simple ring not found
|
||||
// allow empty ring
|
||||
}
|
||||
|
||||
public:
|
||||
static inline bool apply(Polygon const& polygon)
|
||||
{
|
||||
return
|
||||
is_simple_ring
|
||||
<
|
||||
typename ring_type<Polygon>::type,
|
||||
CSTag
|
||||
>::apply(exterior_ring(polygon))
|
||||
&&
|
||||
are_simple_interior_rings(geometry::interior_rings(polygon));
|
||||
}
|
||||
};
|
||||
template <typename Polygon, typename Strategy>
|
||||
inline bool is_simple_polygon(Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return is_simple_ring(geometry::exterior_ring(polygon), strategy)
|
||||
&& are_simple_interior_rings(geometry::interior_rings(polygon), strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::is_simple
|
||||
@ -107,13 +88,9 @@ template <typename Ring>
|
||||
struct is_simple<Ring, ring_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Ring const& ring, Strategy const&)
|
||||
static inline bool apply(Ring const& ring, Strategy const& strategy)
|
||||
{
|
||||
return detail::is_simple::is_simple_ring
|
||||
<
|
||||
Ring,
|
||||
typename Strategy::cs_tag
|
||||
>::apply(ring);
|
||||
return detail::is_simple::is_simple_ring(ring, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -125,13 +102,9 @@ template <typename Polygon>
|
||||
struct is_simple<Polygon, polygon_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Polygon const& polygon, Strategy const&)
|
||||
static inline bool apply(Polygon const& polygon, Strategy const& strategy)
|
||||
{
|
||||
return detail::is_simple::is_simple_polygon
|
||||
<
|
||||
Polygon,
|
||||
typename Strategy::cs_tag
|
||||
>::apply(polygon);
|
||||
return detail::is_simple::is_simple_polygon(polygon, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -144,18 +117,14 @@ template <typename MultiPolygon>
|
||||
struct is_simple<MultiPolygon, multi_polygon_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPolygon const& multipolygon, Strategy const&)
|
||||
static inline bool apply(MultiPolygon const& multipolygon, Strategy const& strategy)
|
||||
{
|
||||
return
|
||||
detail::check_iterator_range
|
||||
<
|
||||
detail::is_simple::is_simple_polygon
|
||||
<
|
||||
typename boost::range_value<MultiPolygon>::type,
|
||||
typename Strategy::cs_tag
|
||||
>,
|
||||
true // allow empty multi-polygon
|
||||
>::apply(boost::begin(multipolygon), boost::end(multipolygon));
|
||||
auto const end = boost::end(multipolygon);
|
||||
return std::find_if(boost::begin(multipolygon), end,
|
||||
[&](auto const& po) {
|
||||
return ! detail::is_simple::is_simple_polygon(po, strategy);
|
||||
}) == end; // non-simple polygon not found
|
||||
// allow empty multi-polygon
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2020, 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
|
||||
@ -20,7 +20,8 @@
|
||||
#include <boost/geometry/algorithms/dispatch/is_simple.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -29,23 +30,47 @@ namespace boost { namespace geometry
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct is_simple
|
||||
{
|
||||
template <typename Geometry, typename Strategy>
|
||||
template <typename Geometry>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::is_simple<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct is_simple<Strategy, false>
|
||||
{
|
||||
template <typename Geometry>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
return dispatch::is_simple
|
||||
<
|
||||
Geometry
|
||||
>::apply(geometry, strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_simple<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
default_strategy)
|
||||
{
|
||||
// NOTE: Currently the strategy is only used for Linear geometries
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Geometry>::type
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::is_simple<Geometry>::apply(geometry, strategy_type());
|
||||
@ -65,7 +90,7 @@ struct is_simple
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
return resolve_strategy::is_simple::apply(geometry, strategy);
|
||||
return resolve_strategy::is_simple<Strategy>::apply(geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -221,8 +221,7 @@ inline bool has_self_intersections(Linear const& linear, Strategy const& strateg
|
||||
|
||||
typedef is_acceptable_turn
|
||||
<
|
||||
Linear,
|
||||
typename Strategy::equals_point_point_strategy_type
|
||||
Linear, Strategy
|
||||
> is_acceptable_turn_type;
|
||||
|
||||
is_acceptable_turn_type predicate(linear);
|
||||
@ -259,12 +258,12 @@ struct is_simple_linestring
|
||||
return ! boost::empty(linestring)
|
||||
&& ! detail::is_valid::has_duplicates
|
||||
<
|
||||
Linestring, closed, typename Strategy::cs_tag
|
||||
>::apply(linestring, policy)
|
||||
Linestring, closed
|
||||
>::apply(linestring, policy, strategy)
|
||||
&& ! detail::is_valid::has_spikes
|
||||
<
|
||||
Linestring, closed
|
||||
>::apply(linestring, policy, strategy.get_side_strategy());
|
||||
>::apply(linestring, policy, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ template <typename MultiPoint>
|
||||
struct is_simple_multipoint
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multipoint, Strategy const&)
|
||||
static inline bool apply(MultiPoint const& multipoint, Strategy const& strategy)
|
||||
{
|
||||
typedef typename Strategy::cs_tag cs_tag;
|
||||
typedef geometry::less
|
||||
@ -61,10 +61,10 @@ struct is_simple_multipoint
|
||||
std::sort(boost::begin(mp), boost::end(mp), less_type());
|
||||
|
||||
simplicity_failure_policy policy;
|
||||
return !detail::is_valid::has_duplicates
|
||||
return ! detail::is_valid::has_duplicates
|
||||
<
|
||||
MultiPoint, closed, cs_tag
|
||||
>::apply(mp, policy);
|
||||
MultiPoint, closed
|
||||
>::apply(mp, policy, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -33,11 +33,12 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace is_valid
|
||||
{
|
||||
|
||||
template <typename Range, closure_selector Closure, typename CSTag>
|
||||
template <typename Range, closure_selector Closure>
|
||||
struct has_duplicates
|
||||
{
|
||||
template <typename VisitPolicy>
|
||||
static inline bool apply(Range const& range, VisitPolicy& visitor)
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
static inline bool apply(Range const& range, VisitPolicy& visitor,
|
||||
Strategy const& )
|
||||
{
|
||||
boost::ignore_unused(visitor);
|
||||
|
||||
@ -58,7 +59,7 @@ struct has_duplicates
|
||||
<
|
||||
typename boost::range_value<Range>::type,
|
||||
-1,
|
||||
CSTag
|
||||
typename Strategy::cs_tag
|
||||
> equal;
|
||||
|
||||
const_iterator it = boost::const_begin(view);
|
||||
|
@ -45,64 +45,27 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace is_valid
|
||||
{
|
||||
|
||||
template <typename Point, typename Strategy>
|
||||
struct equal_to
|
||||
{
|
||||
Point const& m_point;
|
||||
|
||||
equal_to(Point const& point)
|
||||
: m_point(point)
|
||||
{}
|
||||
|
||||
template <typename OtherPoint>
|
||||
inline bool operator()(OtherPoint const& other) const
|
||||
{
|
||||
return geometry::detail::equals::equals_point_point(m_point, other, Strategy());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Strategy>
|
||||
struct not_equal_to
|
||||
{
|
||||
Point const& m_point;
|
||||
|
||||
not_equal_to(Point const& point)
|
||||
: m_point(point)
|
||||
{}
|
||||
|
||||
template <typename OtherPoint>
|
||||
inline bool operator()(OtherPoint const& other) const
|
||||
{
|
||||
return ! geometry::detail::equals::equals_point_point(other, m_point, Strategy());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename Range, closure_selector Closure>
|
||||
struct has_spikes
|
||||
{
|
||||
template <typename Iterator, typename SideStrategy>
|
||||
template <typename Iterator, typename Strategy>
|
||||
static inline Iterator find_different_from_first(Iterator first,
|
||||
Iterator last,
|
||||
SideStrategy const& )
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef not_equal_to
|
||||
<
|
||||
typename point_type<Range>::type,
|
||||
typename SideStrategy::equals_point_point_strategy_type
|
||||
> not_equal;
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(first != last);
|
||||
|
||||
Iterator second = first;
|
||||
++second;
|
||||
return std::find_if(second, last, not_equal(*first));
|
||||
if (first == last)
|
||||
return last;
|
||||
auto const& front = *first;
|
||||
++first;
|
||||
return std::find_if(first, last, [&](auto const& pt) {
|
||||
return ! equals::equals_point_point(pt, front, strategy);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename View, typename VisitPolicy, typename SideStrategy>
|
||||
template <typename View, typename VisitPolicy, typename Strategy>
|
||||
static inline bool apply_at_closure(View const& view, VisitPolicy& visitor,
|
||||
SideStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
bool is_linear)
|
||||
{
|
||||
boost::ignore_unused(visitor);
|
||||
@ -119,10 +82,9 @@ struct has_spikes
|
||||
|
||||
iterator next = find_different_from_first(cur, boost::end(view),
|
||||
strategy);
|
||||
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
|
||||
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy.side()))
|
||||
{
|
||||
return
|
||||
! visitor.template apply<failure_spikes>(is_linear, *cur);
|
||||
return ! visitor.template apply<failure_spikes>(is_linear, *cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -131,9 +93,9 @@ struct has_spikes
|
||||
}
|
||||
|
||||
|
||||
template <typename VisitPolicy, typename SideStrategy>
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
static inline bool apply(Range const& range, VisitPolicy& visitor,
|
||||
SideStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused(visitor);
|
||||
|
||||
@ -169,7 +131,7 @@ struct has_spikes
|
||||
// in is_spike_or_equal, but this order calls the side
|
||||
// strategy in the way to correctly detect the spikes,
|
||||
// also in geographic cases going over the pole
|
||||
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
|
||||
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy.side()))
|
||||
{
|
||||
return
|
||||
! visitor.template apply<failure_spikes>(is_linestring, *cur);
|
||||
@ -179,9 +141,8 @@ struct has_spikes
|
||||
next = find_different_from_first(cur, boost::end(view), strategy);
|
||||
}
|
||||
|
||||
if (geometry::detail::equals::
|
||||
equals_point_point(range::front(view), range::back(view),
|
||||
strategy.get_equals_point_point_strategy()))
|
||||
if (equals::equals_point_point(range::front(view), range::back(view),
|
||||
strategy))
|
||||
{
|
||||
return apply_at_closure(view, visitor, strategy, is_linestring);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace detail { namespace is_valid
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename CSTag
|
||||
typename CSTag // TODO: remove
|
||||
>
|
||||
class has_valid_self_turns
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2020, 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
|
||||
@ -25,7 +25,8 @@
|
||||
#include <boost/geometry/policies/is_valid/failing_reason_policy.hpp>
|
||||
#include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -34,9 +35,14 @@ namespace boost { namespace geometry
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct is_valid
|
||||
{
|
||||
template <typename Geometry, typename VisitPolicy, typename Strategy>
|
||||
template <typename Geometry, typename VisitPolicy>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
VisitPolicy& visitor,
|
||||
Strategy const& strategy)
|
||||
@ -44,18 +50,41 @@ struct is_valid
|
||||
return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct is_valid<Strategy, false>
|
||||
{
|
||||
template <typename Geometry, typename VisitPolicy>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
VisitPolicy& visitor,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
return dispatch::is_valid
|
||||
<
|
||||
Geometry
|
||||
>::apply(geometry, visitor,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_valid<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry, typename VisitPolicy>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
VisitPolicy& visitor,
|
||||
default_strategy)
|
||||
{
|
||||
// NOTE: Currently the strategy is only used for Areal geometries
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Geometry>::type
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy_type());
|
||||
return dispatch::is_valid<Geometry>::apply(geometry, visitor,
|
||||
strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -74,7 +103,10 @@ struct is_valid
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
return resolve_strategy::is_valid::apply(geometry, visitor, strategy);
|
||||
return resolve_strategy::is_valid
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry, visitor, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -64,15 +64,8 @@ struct is_valid_linestring
|
||||
|
||||
std::size_t num_distinct = detail::num_distinct_consecutive_points
|
||||
<
|
||||
Linestring,
|
||||
3u,
|
||||
true,
|
||||
not_equal_to
|
||||
<
|
||||
typename point_type<Linestring>::type,
|
||||
typename Strategy::equals_point_point_strategy_type
|
||||
>
|
||||
>::apply(linestring);
|
||||
Linestring, 3u, true
|
||||
>::apply(linestring, strategy);
|
||||
|
||||
if (num_distinct < 2u)
|
||||
{
|
||||
@ -93,8 +86,7 @@ struct is_valid_linestring
|
||||
return ! has_spikes
|
||||
<
|
||||
Linestring, closed
|
||||
>::apply(linestring, visitor,
|
||||
strategy.get_side_strategy());
|
||||
>::apply(linestring, visitor, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -118,14 +118,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
// prepare strategies
|
||||
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
|
||||
envelope_strategy_type const envelope_strategy
|
||||
= strategy.get_envelope_strategy();
|
||||
typedef typename Strategy::disjoint_box_box_strategy_type disjoint_box_box_strategy_type;
|
||||
disjoint_box_box_strategy_type const disjoint_strategy
|
||||
= strategy.get_disjoint_box_box_strategy();
|
||||
|
||||
// call partition to check if polygons are disjoint from each other
|
||||
typename base::template item_visitor_type<Strategy> item_visitor(strategy);
|
||||
|
||||
@ -133,15 +125,8 @@ private:
|
||||
<
|
||||
geometry::model::box<typename point_type<MultiPolygon>::type>
|
||||
>::apply(polygon_iterators, item_visitor,
|
||||
typename base::template expand_box
|
||||
<
|
||||
envelope_strategy_type
|
||||
>(envelope_strategy),
|
||||
typename base::template overlaps_box
|
||||
<
|
||||
envelope_strategy_type,
|
||||
disjoint_box_box_strategy_type
|
||||
>(envelope_strategy, disjoint_strategy));
|
||||
typename base::template expand_box<Strategy>(strategy),
|
||||
typename base::template overlaps_box<Strategy>(strategy));
|
||||
|
||||
if (item_visitor.items_overlap)
|
||||
{
|
||||
|
@ -185,10 +185,10 @@ protected:
|
||||
};
|
||||
|
||||
// structs for partition -- start
|
||||
template <typename EnvelopeStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box
|
||||
{
|
||||
explicit expand_box(EnvelopeStrategy const& strategy)
|
||||
explicit expand_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
@ -197,46 +197,38 @@ protected:
|
||||
{
|
||||
geometry::expand(total,
|
||||
item.get_envelope(m_strategy),
|
||||
// TEMP - envelope umbrella strategy also contains
|
||||
// expand strategies
|
||||
strategies::envelope::services::strategy_converter
|
||||
<
|
||||
EnvelopeStrategy
|
||||
>::get(m_strategy));
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
EnvelopeStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename EnvelopeStrategy, typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box
|
||||
{
|
||||
explicit overlaps_box(EnvelopeStrategy const& envelope_strategy,
|
||||
DisjointBoxBoxStrategy const& disjoint_strategy)
|
||||
: m_envelope_strategy(envelope_strategy)
|
||||
, m_disjoint_strategy(disjoint_strategy)
|
||||
explicit overlaps_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Iterator>
|
||||
inline bool apply(Box const& box, partition_item<Iterator, Box> const& item) const
|
||||
{
|
||||
return ! geometry::disjoint(item.get_envelope(m_envelope_strategy),
|
||||
return ! geometry::disjoint(item.get_envelope(m_strategy),
|
||||
box,
|
||||
m_disjoint_strategy);
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
EnvelopeStrategy const& m_envelope_strategy;
|
||||
DisjointBoxBoxStrategy const& m_disjoint_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
|
||||
template <typename WithinStrategy>
|
||||
template <typename Strategy>
|
||||
struct item_visitor_type
|
||||
{
|
||||
bool items_overlap;
|
||||
WithinStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
explicit item_visitor_type(WithinStrategy const& strategy)
|
||||
explicit item_visitor_type(Strategy const& strategy)
|
||||
: items_overlap(false)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
@ -299,14 +291,6 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// prepare strategy
|
||||
typedef typename std::iterator_traits<RingIterator>::value_type inter_ring_type;
|
||||
typename Strategy::template point_in_geometry_strategy
|
||||
<
|
||||
inter_ring_type, ExteriorRing
|
||||
>::type const in_exterior_strategy
|
||||
= strategy.template get_point_in_geometry_strategy<inter_ring_type, ExteriorRing>();
|
||||
|
||||
signed_size_type ring_index = 0;
|
||||
for (RingIterator it = rings_first; it != rings_beyond;
|
||||
++it, ++ring_index)
|
||||
@ -314,7 +298,7 @@ protected:
|
||||
// do not examine interior rings that have turns with the
|
||||
// exterior ring
|
||||
if (ring_indices.find(ring_index) == ring_indices.end()
|
||||
&& ! geometry::covered_by(range::front(*it), exterior_ring, in_exterior_strategy))
|
||||
&& ! geometry::covered_by(range::front(*it), exterior_ring, strategy))
|
||||
{
|
||||
return visitor.template apply<failure_interior_rings_outside>();
|
||||
}
|
||||
@ -342,14 +326,6 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// prepare strategies
|
||||
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
|
||||
envelope_strategy_type const envelope_strategy
|
||||
= strategy.get_envelope_strategy();
|
||||
typedef typename Strategy::disjoint_box_box_strategy_type disjoint_box_box_strategy_type;
|
||||
disjoint_box_box_strategy_type const disjoint_strategy
|
||||
= strategy.get_disjoint_box_box_strategy();
|
||||
|
||||
// call partition to check if interior rings are disjoint from
|
||||
// each other
|
||||
item_visitor_type<Strategy> item_visitor(strategy);
|
||||
@ -358,15 +334,8 @@ protected:
|
||||
<
|
||||
box_type
|
||||
>::apply(ring_iterators, item_visitor,
|
||||
expand_box
|
||||
<
|
||||
envelope_strategy_type
|
||||
>(envelope_strategy),
|
||||
overlaps_box
|
||||
<
|
||||
envelope_strategy_type,
|
||||
disjoint_box_box_strategy_type
|
||||
>(envelope_strategy, disjoint_strategy));
|
||||
expand_box<Strategy>(strategy),
|
||||
overlaps_box<Strategy>(strategy));
|
||||
|
||||
if (item_visitor.items_overlap)
|
||||
{
|
||||
|
@ -92,21 +92,7 @@ struct is_topologically_closed<Ring, closed>
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename ResultType, bool IsInteriorRing /* false */>
|
||||
struct ring_area_predicate
|
||||
{
|
||||
typedef std::greater<ResultType> type;
|
||||
};
|
||||
|
||||
template <typename ResultType>
|
||||
struct ring_area_predicate<ResultType, true>
|
||||
{
|
||||
typedef std::less<ResultType> type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// TODO: use calculate_point_order here
|
||||
template <typename Ring, bool IsInteriorRing>
|
||||
struct is_properly_oriented
|
||||
{
|
||||
@ -122,25 +108,15 @@ struct is_properly_oriented
|
||||
geometry::closure<Ring>::value
|
||||
> ring_area_type;
|
||||
|
||||
typedef typename Strategy::template area_strategy
|
||||
std::conditional_t
|
||||
<
|
||||
Ring
|
||||
>::type::template result_type<Ring>::type area_result_type;
|
||||
|
||||
typename ring_area_predicate
|
||||
<
|
||||
area_result_type, IsInteriorRing
|
||||
>::type predicate;
|
||||
IsInteriorRing, std::less<>, std::greater<>
|
||||
> predicate;
|
||||
|
||||
// Check area
|
||||
area_result_type const zero = 0;
|
||||
area_result_type const area
|
||||
= ring_area_type::apply(ring,
|
||||
// TEMP - in the future (umbrella) strategy will be passed here
|
||||
geometry::strategies::area::services::strategy_converter
|
||||
<
|
||||
decltype(strategy.template get_area_strategy<Ring>())
|
||||
>::get(strategy.template get_area_strategy<Ring>()));
|
||||
auto const area = ring_area_type::apply(ring, strategy);
|
||||
decltype(area) const zero = 0;
|
||||
|
||||
if (predicate(area, zero))
|
||||
{
|
||||
return visitor.template apply<no_failure>();
|
||||
@ -166,8 +142,6 @@ struct is_valid_ring
|
||||
static inline bool apply(Ring const& ring, VisitPolicy& visitor,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename Strategy::cs_tag cs_tag;
|
||||
|
||||
// return invalid if any of the following condition holds:
|
||||
// (a) the ring's point coordinates are not invalid (e.g., NaN)
|
||||
// (b) the ring's size is below the minimal one
|
||||
@ -199,13 +173,8 @@ struct is_valid_ring
|
||||
view_type const view(ring);
|
||||
if (detail::num_distinct_consecutive_points
|
||||
<
|
||||
view_type, 4u, true,
|
||||
not_equal_to
|
||||
<
|
||||
typename point_type<Ring>::type,
|
||||
typename Strategy::equals_point_point_strategy_type
|
||||
>
|
||||
>::apply(view)
|
||||
view_type, 4u, true
|
||||
>::apply(view, strategy)
|
||||
< 4u)
|
||||
{
|
||||
return
|
||||
@ -213,9 +182,9 @@ struct is_valid_ring
|
||||
}
|
||||
|
||||
return
|
||||
is_topologically_closed<Ring, closure>::apply(ring, visitor, strategy.get_equals_point_point_strategy())
|
||||
&& ! has_duplicates<Ring, closure, cs_tag>::apply(ring, visitor)
|
||||
&& ! has_spikes<Ring, closure>::apply(ring, visitor, strategy.get_side_strategy())
|
||||
is_topologically_closed<Ring, closure>::apply(ring, visitor, strategy)
|
||||
&& ! has_duplicates<Ring, closure>::apply(ring, visitor, strategy)
|
||||
&& ! has_spikes<Ring, closure>::apply(ring, visitor, strategy)
|
||||
&& (! CheckSelfIntersections
|
||||
|| has_valid_self_turns<Ring, typename Strategy::cs_tag>::apply(ring, visitor, strategy))
|
||||
&& is_properly_oriented<Ring, IsInteriorRing>::apply(ring, visitor, strategy);
|
||||
|
@ -45,10 +45,8 @@ template <typename Segment>
|
||||
struct is_valid<Segment, segment_tag>
|
||||
{
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
static inline bool apply(Segment const& segment, VisitPolicy& visitor, Strategy const&)
|
||||
static inline bool apply(Segment const& segment, VisitPolicy& visitor, Strategy const& strategy)
|
||||
{
|
||||
typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
|
||||
|
||||
boost::ignore_unused(visitor);
|
||||
|
||||
typename point_type<Segment>::type p[2];
|
||||
@ -62,8 +60,7 @@ struct is_valid<Segment, segment_tag>
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (! geometry::detail::equals::equals_point_point(
|
||||
p[0], p[1], eq_pp_strategy_type()))
|
||||
else if (! detail::equals::equals_point_point(p[0], p[1], strategy))
|
||||
{
|
||||
return visitor.template apply<no_failure>();
|
||||
}
|
||||
|
@ -41,12 +41,12 @@ template
|
||||
<
|
||||
typename Range,
|
||||
std::size_t MaximumNumber,
|
||||
bool AllowDuplicates /* true */,
|
||||
typename NotEqualTo
|
||||
bool AllowDuplicates /* true */
|
||||
>
|
||||
struct num_distinct_consecutive_points
|
||||
{
|
||||
static inline std::size_t apply(Range const& range)
|
||||
template <typename Strategy>
|
||||
static inline std::size_t apply(Range const& range, Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_iterator<Range const>::type iterator;
|
||||
|
||||
@ -58,26 +58,28 @@ struct num_distinct_consecutive_points
|
||||
}
|
||||
|
||||
iterator current = boost::begin(range);
|
||||
iterator const end = boost::end(range);
|
||||
std::size_t counter(0);
|
||||
do
|
||||
{
|
||||
++counter;
|
||||
iterator next = std::find_if(current,
|
||||
boost::end(range),
|
||||
NotEqualTo(*current));
|
||||
iterator next = std::find_if(current, end, [&](auto const& pt) {
|
||||
return ! equals::equals_point_point(pt, *current, strategy);
|
||||
});
|
||||
current = next;
|
||||
}
|
||||
while ( current != boost::end(range) && counter <= MaximumNumber );
|
||||
while ( current != end && counter <= MaximumNumber );
|
||||
|
||||
return counter;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Range, std::size_t MaximumNumber, typename NotEqualTo>
|
||||
struct num_distinct_consecutive_points<Range, MaximumNumber, false, NotEqualTo>
|
||||
template <typename Range, std::size_t MaximumNumber>
|
||||
struct num_distinct_consecutive_points<Range, MaximumNumber, false>
|
||||
{
|
||||
static inline std::size_t apply(Range const& range)
|
||||
template <typename Strategy>
|
||||
static inline std::size_t apply(Range const& range, Strategy const&)
|
||||
{
|
||||
std::size_t const size = boost::size(range);
|
||||
return (size < MaximumNumber) ? size : MaximumNumber;
|
||||
|
@ -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, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014-2021.
|
||||
// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -28,7 +28,9 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -60,6 +62,68 @@ struct overlaps
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct overlaps
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct overlaps<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct overlaps<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::overlaps
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check2{overlap}
|
||||
\ingroup overlaps
|
||||
@ -82,10 +146,9 @@ inline bool overlaps(Geometry1 const& geometry1,
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return dispatch::overlaps
|
||||
return resolve_strategy::overlaps
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
@ -111,17 +174,10 @@ 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
|
||||
return resolve_strategy::overlaps
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
default_strategy
|
||||
>::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
@ -87,22 +87,17 @@ template
|
||||
typename Geometry2,
|
||||
typename RingCollection,
|
||||
typename OutputIterator,
|
||||
typename AreaStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator add_rings(SelectionMap const& map,
|
||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
RingCollection const& collection,
|
||||
OutputIterator out,
|
||||
AreaStrategy const& area_strategy,
|
||||
Strategy const& strategy,
|
||||
add_rings_error_handling error_handling = add_rings_ignore_unordered)
|
||||
{
|
||||
typedef typename SelectionMap::const_iterator iterator;
|
||||
typedef typename AreaStrategy::template result_type
|
||||
<
|
||||
GeometryOut
|
||||
>::type area_type;
|
||||
|
||||
area_type const zero = 0;
|
||||
std::size_t const min_num_points = core_detail::closure::minimum_ring_size
|
||||
<
|
||||
geometry::closure
|
||||
@ -146,7 +141,9 @@ inline OutputIterator add_rings(SelectionMap const& map,
|
||||
// everything is figured out yet (sum of positive/negative rings)
|
||||
if (geometry::num_points(result) >= min_num_points)
|
||||
{
|
||||
area_type const area = geometry::area(result, area_strategy);
|
||||
typedef typename geometry::area_result<GeometryOut, Strategy>::type area_type;
|
||||
area_type const area = geometry::area(result, strategy);
|
||||
area_type const zero = 0;
|
||||
// Ignore if area is 0
|
||||
if (! math::equals(area, zero))
|
||||
{
|
||||
@ -174,16 +171,16 @@ template
|
||||
typename Geometry,
|
||||
typename RingCollection,
|
||||
typename OutputIterator,
|
||||
typename AreaStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator add_rings(SelectionMap const& map,
|
||||
Geometry const& geometry,
|
||||
RingCollection const& collection,
|
||||
OutputIterator out,
|
||||
AreaStrategy const& area_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Geometry empty;
|
||||
return add_rings<GeometryOut>(map, geometry, empty, collection, out, area_strategy);
|
||||
return add_rings<GeometryOut>(map, geometry, empty, collection, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,9 +40,9 @@ inline void append_with_duplicates(Range& range, Point const& point)
|
||||
geometry::append(range, point);
|
||||
}
|
||||
|
||||
template <typename Range, typename Point, typename EqPPStrategy>
|
||||
template <typename Range, typename Point, typename Strategy>
|
||||
inline void append_no_duplicates(Range& range, Point const& point,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if ( boost::empty(range)
|
||||
|| ! geometry::detail::equals::equals_point_point(geometry::range::back(range),
|
||||
|
@ -41,11 +41,11 @@ namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
// TODO: move this / rename this
|
||||
template <typename Point1, typename Point2, typename EqualsStrategy, typename RobustPolicy>
|
||||
template <typename Point1, typename Point2, typename Strategy, typename RobustPolicy>
|
||||
inline bool points_equal_or_close(Point1 const& point1,
|
||||
Point2 const& point2,
|
||||
EqualsStrategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
Point2 const& point2,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
if (detail::equals::equals_point_point(point1, point2, strategy))
|
||||
{
|
||||
@ -79,10 +79,10 @@ inline bool points_equal_or_close(Point1 const& point1,
|
||||
}
|
||||
|
||||
|
||||
template <typename Range, typename Point, typename SideStrategy, typename RobustPolicy>
|
||||
template <typename Range, typename Point, typename Strategy, typename RobustPolicy>
|
||||
inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
||||
SideStrategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
std::cout << " add: ("
|
||||
@ -93,8 +93,7 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
||||
// for geometries >= 3 points.
|
||||
// So we have to check the first potential duplicate differently
|
||||
if ( boost::size(range) == 1
|
||||
&& points_equal_or_close(*(boost::begin(range)), point,
|
||||
strategy.get_equals_point_point_strategy(),
|
||||
&& points_equal_or_close(*(boost::begin(range)), point, strategy,
|
||||
robust_policy) )
|
||||
{
|
||||
return;
|
||||
@ -111,7 +110,7 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
||||
&& point_is_spike_or_equal(point,
|
||||
*(boost::end(range) - 3),
|
||||
*(boost::end(range) - 2),
|
||||
strategy,
|
||||
strategy.side(), // TODO: Pass strategy?
|
||||
robust_policy))
|
||||
{
|
||||
// Use the Concept/traits, so resize and append again
|
||||
@ -120,10 +119,10 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Range, typename Point, typename SideStrategy, typename RobustPolicy>
|
||||
template <typename Range, typename Point, typename Strategy, typename RobustPolicy>
|
||||
inline void append_no_collinear(Range& range, Point const& point,
|
||||
SideStrategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
// Stricter version, not allowing any point in a linear row
|
||||
// (spike, continuation or same point)
|
||||
@ -133,7 +132,7 @@ inline void append_no_collinear(Range& range, Point const& point,
|
||||
// So we have to check the first potential duplicate differently
|
||||
if ( boost::size(range) == 1
|
||||
&& points_equal_or_close(*(boost::begin(range)), point,
|
||||
strategy.get_equals_point_point_strategy(),
|
||||
strategy,
|
||||
robust_policy) )
|
||||
{
|
||||
return;
|
||||
@ -150,7 +149,7 @@ inline void append_no_collinear(Range& range, Point const& point,
|
||||
&& point_is_collinear(point,
|
||||
*(boost::end(range) - 3),
|
||||
*(boost::end(range) - 2),
|
||||
strategy,
|
||||
strategy.side(), // TODO: Pass strategy?
|
||||
robust_policy))
|
||||
{
|
||||
// Use the Concept/traits, so resize and append again
|
||||
@ -159,10 +158,10 @@ inline void append_no_collinear(Range& range, Point const& point,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Range, typename SideStrategy, typename RobustPolicy>
|
||||
template <typename Range, typename Strategy, typename RobustPolicy>
|
||||
inline void clean_closing_dups_and_spikes(Range& range,
|
||||
SideStrategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
std::size_t const minsize
|
||||
= core_detail::closure::minimum_ring_size
|
||||
@ -195,7 +194,9 @@ inline void clean_closing_dups_and_spikes(Range& range,
|
||||
|
||||
// Check if closing point is a spike (this is so if the second point is
|
||||
// considered as collinear w.r.t. the last segment)
|
||||
if (point_is_collinear(*second, *ultimate, *first, strategy, robust_policy))
|
||||
if (point_is_collinear(*second, *ultimate, *first,
|
||||
strategy.side(), // TODO: Pass strategy?
|
||||
robust_policy))
|
||||
{
|
||||
range::erase(range, first);
|
||||
if (BOOST_GEOMETRY_CONDITION(closed))
|
||||
|
@ -127,27 +127,39 @@ struct ring_info_helper
|
||||
};
|
||||
|
||||
|
||||
template <typename BoxExpandStrategy>
|
||||
template <typename Strategy>
|
||||
struct ring_info_helper_get_box
|
||||
{
|
||||
ring_info_helper_get_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename InputItem>
|
||||
static inline void apply(Box& total, InputItem const& item)
|
||||
inline void apply(Box& total, InputItem const& item) const
|
||||
{
|
||||
assert_coordinate_type_equal(total, item.envelope);
|
||||
geometry::expand(total, item.envelope, BoxExpandStrategy());
|
||||
geometry::expand(total, item.envelope, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct ring_info_helper_overlaps_box
|
||||
{
|
||||
ring_info_helper_overlaps_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename InputItem>
|
||||
static inline bool apply(Box const& box, InputItem const& item)
|
||||
inline bool apply(Box const& box, InputItem const& item) const
|
||||
{
|
||||
assert_coordinate_type_equal(box, item.envelope);
|
||||
return ! geometry::detail::disjoint::disjoint_box_box(
|
||||
box, item.envelope, DisjointBoxBoxStrategy());
|
||||
box, item.envelope, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
// Segments intersection Strategy
|
||||
@ -196,8 +208,7 @@ struct assign_visitor
|
||||
{
|
||||
ring_info_type& inner_in_map = m_ring_map[inner.id];
|
||||
|
||||
if (geometry::covered_by(inner_in_map.point, outer.envelope,
|
||||
typename Strategy::disjoint_point_box_strategy_type())
|
||||
if (geometry::covered_by(inner_in_map.point, outer.envelope, m_strategy)
|
||||
&& within_selected_input(inner_in_map, inner.id, outer.id,
|
||||
m_geometry1, m_geometry2, m_collection,
|
||||
m_strategy)
|
||||
@ -244,10 +255,10 @@ inline void assign_parents(Geometry1 const& geometry1,
|
||||
typedef typename RingMap::mapped_type ring_info_type;
|
||||
typedef typename ring_info_type::point_type point_type;
|
||||
typedef model::box<point_type> box_type;
|
||||
typedef typename Strategy::template area_strategy
|
||||
typedef typename geometry::area_result
|
||||
<
|
||||
point_type
|
||||
>::type::template result_type<point_type>::type area_result_type;
|
||||
point_type, Strategy // TODO: point_type is technically incorrect
|
||||
>::type area_result_type;
|
||||
|
||||
typedef typename RingMap::iterator map_iterator_type;
|
||||
|
||||
@ -273,15 +284,15 @@ inline void assign_parents(Geometry1 const& geometry1,
|
||||
{
|
||||
case 0 :
|
||||
geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
|
||||
item.envelope, strategy.get_envelope_strategy());
|
||||
item.envelope, strategy);
|
||||
break;
|
||||
case 1 :
|
||||
geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
|
||||
item.envelope, strategy.get_envelope_strategy());
|
||||
item.envelope, strategy);
|
||||
break;
|
||||
case 2 :
|
||||
geometry::envelope(get_ring<void>::apply(it->first, collection),
|
||||
item.envelope, strategy.get_envelope_strategy());
|
||||
item.envelope, strategy);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -336,19 +347,12 @@ inline void assign_parents(Geometry1 const& geometry1,
|
||||
Strategy
|
||||
> visitor(geometry1, geometry2, collection, ring_map, strategy, check_for_orientation);
|
||||
|
||||
typedef ring_info_helper_get_box
|
||||
<
|
||||
typename Strategy::expand_box_strategy_type
|
||||
> expand_box_type;
|
||||
typedef ring_info_helper_overlaps_box
|
||||
<
|
||||
typename Strategy::disjoint_box_box_strategy_type
|
||||
> overlaps_box_type;
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box_type
|
||||
>::apply(vector, visitor, expand_box_type(), overlaps_box_type());
|
||||
>::apply(vector, visitor,
|
||||
ring_info_helper_get_box<Strategy>(strategy),
|
||||
ring_info_helper_overlaps_box<Strategy>(strategy));
|
||||
}
|
||||
|
||||
if (check_for_orientation)
|
||||
|
@ -61,14 +61,14 @@ struct copy_segments_ring
|
||||
<
|
||||
typename Ring,
|
||||
typename SegmentIdentifier,
|
||||
typename SideStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename RangeOut
|
||||
>
|
||||
static inline void apply(Ring const& ring,
|
||||
SegmentIdentifier const& seg_id,
|
||||
signed_size_type to_index,
|
||||
SideStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
RangeOut& current_output)
|
||||
{
|
||||
@ -125,10 +125,10 @@ class copy_segments_linestring
|
||||
{
|
||||
private:
|
||||
// remove spikes
|
||||
template <typename RangeOut, typename Point, typename SideStrategy, typename RobustPolicy>
|
||||
template <typename RangeOut, typename Point, typename Strategy, typename RobustPolicy>
|
||||
static inline void append_to_output(RangeOut& current_output,
|
||||
Point const& point,
|
||||
SideStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
std::true_type const&)
|
||||
{
|
||||
@ -138,14 +138,14 @@ private:
|
||||
}
|
||||
|
||||
// keep spikes
|
||||
template <typename RangeOut, typename Point, typename SideStrategy, typename RobustPolicy>
|
||||
template <typename RangeOut, typename Point, typename Strategy, typename RobustPolicy>
|
||||
static inline void append_to_output(RangeOut& current_output,
|
||||
Point const& point,
|
||||
SideStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const&,
|
||||
std::false_type const&)
|
||||
{
|
||||
detail::overlay::append_no_duplicates(current_output, point, strategy.get_equals_point_point_strategy());
|
||||
detail::overlay::append_no_duplicates(current_output, point, strategy);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -524,7 +524,7 @@ inline void enrich_intersection_points(Turns& turns,
|
||||
detail::overlay::enrich_sort<Reverse1, Reverse2>(
|
||||
mit->second, turns,
|
||||
geometry1, geometry2,
|
||||
robust_policy, strategy.get_side_strategy());
|
||||
robust_policy, strategy.side()); // TODO: pass strategy
|
||||
}
|
||||
|
||||
for (typename mapped_vector_type::iterator mit
|
||||
@ -554,7 +554,7 @@ inline void enrich_intersection_points(Turns& turns,
|
||||
Reverse2,
|
||||
OverlayType
|
||||
>(clusters, turns, target_operation,
|
||||
geometry1, geometry2, strategy.get_side_strategy());
|
||||
geometry1, geometry2, strategy.side()); // TODO: pass strategy
|
||||
|
||||
detail::overlay::cleanup_clusters(turns, clusters);
|
||||
}
|
||||
|
@ -62,11 +62,11 @@ template
|
||||
typename Operation,
|
||||
typename LineString,
|
||||
typename Polygon,
|
||||
typename PtInPolyStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline bool last_covered_by(Turn const& /*turn*/, Operation const& op,
|
||||
LineString const& linestring, Polygon const& polygon,
|
||||
PtInPolyStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::covered_by(range::at(linestring, op.seg_id.segment_index), polygon, strategy);
|
||||
}
|
||||
@ -78,12 +78,12 @@ template
|
||||
typename Operation,
|
||||
typename LineString,
|
||||
typename Polygon,
|
||||
typename PtInPolyStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline bool is_leaving(Turn const& turn, Operation const& op,
|
||||
bool entered, bool first,
|
||||
LineString const& linestring, Polygon const& polygon,
|
||||
PtInPolyStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (op.operation == operation_union)
|
||||
{
|
||||
@ -104,12 +104,12 @@ template
|
||||
typename Operation,
|
||||
typename LineString,
|
||||
typename Polygon,
|
||||
typename PtInPolyStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline bool is_staying_inside(Turn const& turn, Operation const& op,
|
||||
bool entered, bool first,
|
||||
LineString const& linestring, Polygon const& polygon,
|
||||
PtInPolyStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (turn.method == method_crosses)
|
||||
{
|
||||
@ -132,11 +132,11 @@ template
|
||||
typename Operation,
|
||||
typename Linestring,
|
||||
typename Polygon,
|
||||
typename PtInPolyStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline bool was_entered(Turn const& turn, Operation const& op, bool first,
|
||||
Linestring const& linestring, Polygon const& polygon,
|
||||
PtInPolyStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (first && (turn.method == method_collinear || turn.method == method_equal))
|
||||
{
|
||||
@ -234,7 +234,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
|
||||
{
|
||||
// On enter, append the intersection point and remember starting point
|
||||
// TODO: we don't check on spikes for linestrings (?). Consider this.
|
||||
detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy());
|
||||
detail::overlay::append_no_duplicates(current_piece, point, strategy);
|
||||
segment_id = operation.seg_id;
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
|
||||
<
|
||||
false, RemoveSpikes
|
||||
>::apply(linestring, segment_id, index, strategy, robust_policy, current_piece);
|
||||
detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy());
|
||||
detail::overlay::append_no_duplicates(current_piece, point, strategy);
|
||||
if (::boost::size(current_piece) > 1)
|
||||
{
|
||||
*out++ = current_piece;
|
||||
@ -431,14 +431,6 @@ public :
|
||||
|
||||
typedef following::action_selector<OverlayType, RemoveSpikes> action;
|
||||
|
||||
typedef typename Strategy::cs_tag cs_tag;
|
||||
|
||||
typename Strategy::template point_in_geometry_strategy
|
||||
<
|
||||
LineString, Polygon
|
||||
>::type const pt_in_poly_strategy
|
||||
= strategy.template get_point_in_geometry_strategy<LineString, Polygon>();
|
||||
|
||||
// Sort intersection points on segments-along-linestring, and distance
|
||||
// (like in enrich is done for poly/poly)
|
||||
// sort turns by Linear seg_id, then by fraction, then
|
||||
@ -446,7 +438,8 @@ public :
|
||||
// for different ring id: c, i, u, x
|
||||
typedef relate::turns::less
|
||||
<
|
||||
0, relate::turns::less_op_linear_areal_single<0>, cs_tag
|
||||
0, relate::turns::less_op_linear_areal_single<0>,
|
||||
typename Strategy::cs_tag
|
||||
> turn_less;
|
||||
std::sort(boost::begin(turns), boost::end(turns), turn_less());
|
||||
|
||||
@ -460,13 +453,13 @@ public :
|
||||
{
|
||||
turn_operation_iterator_type iit = boost::begin(it->operations);
|
||||
|
||||
if (following::was_entered(*it, *iit, first, linestring, polygon, pt_in_poly_strategy))
|
||||
if (following::was_entered(*it, *iit, first, linestring, polygon, strategy))
|
||||
{
|
||||
debug_traverse(*it, *iit, "-> Was entered");
|
||||
entered = true;
|
||||
}
|
||||
|
||||
if (following::is_staying_inside(*it, *iit, entered, first, linestring, polygon, pt_in_poly_strategy))
|
||||
if (following::is_staying_inside(*it, *iit, entered, first, linestring, polygon, strategy))
|
||||
{
|
||||
debug_traverse(*it, *iit, "-> Staying inside");
|
||||
|
||||
@ -482,7 +475,7 @@ public :
|
||||
strategy, robust_policy,
|
||||
linear::get(out));
|
||||
}
|
||||
else if (following::is_leaving(*it, *iit, entered, first, linestring, polygon, pt_in_poly_strategy))
|
||||
else if (following::is_leaving(*it, *iit, entered, first, linestring, polygon, strategy))
|
||||
{
|
||||
debug_traverse(*it, *iit, "-> Leaving");
|
||||
|
||||
|
@ -73,7 +73,7 @@ struct get_turn_without_info
|
||||
> policy_type;
|
||||
|
||||
typename policy_type::return_type const result
|
||||
= strategy.apply(range_p, range_q, policy_type());
|
||||
= strategy.relate().apply(range_p, range_q, policy_type());
|
||||
|
||||
for (std::size_t i = 0; i < result.count; i++)
|
||||
{
|
||||
|
@ -3,8 +3,8 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2015, 2017, 2018, 2019.
|
||||
// Modifications copyright (c) 2015-2019 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2015-2020.
|
||||
// Modifications copyright (c) 2015-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
|
||||
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
@ -28,9 +27,6 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_distance_measure.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp>
|
||||
|
||||
// Silence warning C4127: conditional expression is constant
|
||||
@ -131,15 +127,7 @@ struct base_turn_handler
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
typename UniqueSubRange1::point_type,
|
||||
typename UniqueSubRange2::point_type
|
||||
>::type coordinate_type;
|
||||
|
||||
typedef detail::distance_measure<coordinate_type> dm_type;
|
||||
|
||||
dm_type const dm = get_distance_measure(range_p.at(range_index), range_p.at(range_index + 1), range_q.at(point_index));
|
||||
auto const dm = get_distance_measure(range_p.at(range_index), range_p.at(range_index + 1), range_q.at(point_index));
|
||||
return dm.measure == 0 ? 0 : dm.measure > 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
@ -186,7 +174,8 @@ struct base_turn_handler
|
||||
{
|
||||
ti.method = method;
|
||||
|
||||
// For touch/touch interior always take the intersection point 0 (there is only one).
|
||||
// For touch/touch interior always take the intersection point 0
|
||||
// (usually there is only one - but if collinear is handled as touch, both could be taken).
|
||||
static int const index = 0;
|
||||
|
||||
geometry::convert(info.intersections[index], ti.point);
|
||||
@ -225,9 +214,8 @@ struct base_turn_handler
|
||||
{
|
||||
// TODO: use comparable distance for point-point instead - but that
|
||||
// causes currently cycling include problems
|
||||
typedef typename geometry::coordinate_type<Point1>::type ctype;
|
||||
ctype const dx = get<0>(a) - get<0>(b);
|
||||
ctype const dy = get<1>(a) - get<1>(b);
|
||||
auto const dx = get<0>(a) - get<0>(b);
|
||||
auto const dy = get<1>(a) - get<1>(b);
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
@ -259,19 +247,10 @@ struct base_turn_handler
|
||||
// pk/q2 is considered as collinear, but there might be
|
||||
// a tiny measurable difference. If so, use that.
|
||||
// Calculate pk // qj-qk
|
||||
typedef detail::distance_measure
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
typename UniqueSubRange1::point_type,
|
||||
typename UniqueSubRange2::point_type
|
||||
>::type
|
||||
> dm_type;
|
||||
|
||||
const bool p_closer =
|
||||
bool const p_closer =
|
||||
ti.operations[IndexP].remaining_distance
|
||||
< ti.operations[IndexQ].remaining_distance;
|
||||
dm_type const dm
|
||||
auto const dm
|
||||
= p_closer
|
||||
? get_distance_measure(range_q.at(index_q - 1),
|
||||
range_q.at(index_q), range_p.at(index_p))
|
||||
@ -282,8 +261,7 @@ struct base_turn_handler
|
||||
{
|
||||
// Not truely collinear, distinguish for union/intersection
|
||||
// If p goes left (positive), take that for a union
|
||||
|
||||
bool p_left = p_closer ? dm.is_positive() : dm.is_negative();
|
||||
bool const p_left = p_closer ? dm.is_positive() : dm.is_negative();
|
||||
|
||||
ti.operations[IndexP].operation = p_left
|
||||
? operation_union : operation_intersection;
|
||||
@ -347,14 +325,9 @@ struct touch_interior : public base_turn_handler
|
||||
// Therefore handle it as a normal touch (two segments arrive at the
|
||||
// intersection point). It currently checks for zero, but even a
|
||||
// distance a little bit larger would do.
|
||||
typedef typename geometry::coordinate_type
|
||||
<
|
||||
typename UniqueSubRange::point_type
|
||||
>::type coor_t;
|
||||
|
||||
coor_t const location = distance_measure(info.intersections[0], non_touching_range.at(1));
|
||||
coor_t const zero = 0;
|
||||
bool const result = math::equals(location, zero);
|
||||
auto const dm = distance_measure(info.intersections[0], non_touching_range.at(1));
|
||||
decltype(dm) const zero = 0;
|
||||
bool const result = math::equals(dm, zero);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -540,16 +513,8 @@ struct touch : public base_turn_handler
|
||||
// >----->P qj is LEFT of P1 and pi is LEFT of Q2
|
||||
// (the other way round is also possible)
|
||||
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
typename UniqueSubRange1::point_type,
|
||||
typename UniqueSubRange2::point_type
|
||||
>::type coordinate_type;
|
||||
|
||||
typedef detail::distance_measure<coordinate_type> dm_type;
|
||||
|
||||
dm_type const dm_qj_p1 = get_distance_measure(range_p.at(0), range_p.at(1), range_q.at(1));
|
||||
dm_type const dm_pi_q2 = get_distance_measure(range_q.at(1), range_q.at(2), range_p.at(0));
|
||||
auto const dm_qj_p1 = get_distance_measure(range_p.at(0), range_p.at(1), range_q.at(1));
|
||||
auto const dm_pi_q2 = get_distance_measure(range_q.at(1), range_q.at(2), range_p.at(0));
|
||||
|
||||
if (dm_qj_p1.measure > 0 && dm_pi_q2.measure > 0)
|
||||
{
|
||||
@ -564,8 +529,8 @@ struct touch : public base_turn_handler
|
||||
return true;
|
||||
}
|
||||
|
||||
dm_type const dm_pj_q1 = get_distance_measure(range_q.at(0), range_q.at(1), range_p.at(1));
|
||||
dm_type const dm_qi_p2 = get_distance_measure(range_p.at(1), range_p.at(2), range_q.at(0));
|
||||
auto const dm_pj_q1 = get_distance_measure(range_q.at(0), range_q.at(1), range_p.at(1));
|
||||
auto const dm_qi_p2 = get_distance_measure(range_p.at(1), range_p.at(2), range_q.at(0));
|
||||
|
||||
if (dm_pj_q1.measure > 0 && dm_qi_p2.measure > 0)
|
||||
{
|
||||
@ -813,17 +778,9 @@ struct equal : public base_turn_handler
|
||||
// They turn to the same side, or continue both collinearly
|
||||
// Without rescaling, to check for union/intersection,
|
||||
// try to check side values (without any thresholds)
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
typename UniqueSubRange1::point_type,
|
||||
typename UniqueSubRange2::point_type
|
||||
>::type coordinate_type;
|
||||
|
||||
typedef detail::distance_measure<coordinate_type> dm_type;
|
||||
|
||||
dm_type const dm_pk_q2
|
||||
auto const dm_pk_q2
|
||||
= get_distance_measure(range_q.at(1), range_q.at(2), range_p.at(2));
|
||||
dm_type const dm_qk_p2
|
||||
auto const dm_qk_p2
|
||||
= get_distance_measure(range_p.at(1), range_p.at(2), range_q.at(2));
|
||||
|
||||
if (dm_qk_p2.measure != dm_pk_q2.measure)
|
||||
@ -965,8 +922,57 @@ template
|
||||
>
|
||||
struct collinear : public base_turn_handler
|
||||
{
|
||||
template
|
||||
<
|
||||
typename IntersectionInfo,
|
||||
typename UniqueSubRange1,
|
||||
typename UniqueSubRange2,
|
||||
typename DirInfo
|
||||
>
|
||||
static bool handle_as_equal(IntersectionInfo const& info,
|
||||
UniqueSubRange1 const& range_p,
|
||||
UniqueSubRange2 const& range_q,
|
||||
DirInfo const& dir_info)
|
||||
{
|
||||
#if defined(BOOST_GEOMETRY_USE_RESCALING)
|
||||
return false;
|
||||
#endif
|
||||
int const arrival_p = dir_info.arrival[0];
|
||||
int const arrival_q = dir_info.arrival[1];
|
||||
if (arrival_p * arrival_q != -1 || info.count != 2)
|
||||
{
|
||||
// Code below assumes that either p or q arrives in the other segment
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const dm = distance_measure(info.intersections[1],
|
||||
arrival_p == 1 ? range_q.at(1) : range_p.at(1));
|
||||
decltype(dm) const zero = 0;
|
||||
return math::equals(dm, zero);
|
||||
}
|
||||
|
||||
/*
|
||||
arrival P pk//p1 qk//q1 product* case result
|
||||
Either P arrives within Q (arrival_p == -1) or Q arrives within P.
|
||||
|
||||
Typical situation:
|
||||
^q2
|
||||
/
|
||||
^q1
|
||||
/ ____ ip[1]
|
||||
//|p1 } this section of p/q is colllinear
|
||||
q0// | } ____ ip[0]
|
||||
/ |
|
||||
/ v
|
||||
p0 p2
|
||||
|
||||
P arrives (at p1) in segment Q (between q0 and q1).
|
||||
Therefore arrival_p == 1
|
||||
P (p2) goes to the right (-1). Follow P for intersection, or follow Q for union.
|
||||
Therefore if (arrival_p==1) and side_p==-1, result = iu
|
||||
|
||||
Complete table:
|
||||
|
||||
arrival P pk//p1 qk//q1 product case result
|
||||
1 1 1 CLL1 ui
|
||||
-1 1 -1 CLL2 iu
|
||||
1 1 1 CLR1 ui
|
||||
@ -980,7 +986,9 @@ struct collinear : public base_turn_handler
|
||||
1 0 0 CC1 cc
|
||||
-1 0 0 CC2 cc
|
||||
|
||||
*product = arrival * (pk//p1 or qk//q1)
|
||||
Resulting in the rule:
|
||||
The arrival-info multiplied by the relevant side delivers the result.
|
||||
product = arrival * (pk//p1 or qk//q1)
|
||||
|
||||
Stated otherwise:
|
||||
- if P arrives: look at turn P
|
||||
@ -989,13 +997,6 @@ struct collinear : public base_turn_handler
|
||||
- if P arrives and P turns right: intersection for P
|
||||
- if Q arrives and Q turns left: union for Q (=intersection for P)
|
||||
- if Q arrives and Q turns right: intersection for Q (=union for P)
|
||||
|
||||
ROBUSTNESS: p and q are collinear, so you would expect
|
||||
that side qk//p1 == pk//q1. But that is not always the case
|
||||
in near-epsilon ranges. Then decision logic is different.
|
||||
If p arrives, q is further, so the angle qk//p1 is (normally)
|
||||
more precise than pk//p1
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
@ -1016,9 +1017,9 @@ struct collinear : public base_turn_handler
|
||||
// Copy the intersection point in TO direction
|
||||
assign_point(ti, method_collinear, info, non_opposite_to_index(info));
|
||||
|
||||
int const arrival = dir_info.arrival[0];
|
||||
int const arrival_p = dir_info.arrival[0];
|
||||
// Should not be 0, this is checked before
|
||||
BOOST_GEOMETRY_ASSERT(arrival != 0);
|
||||
BOOST_GEOMETRY_ASSERT(arrival_p != 0);
|
||||
|
||||
bool const has_pk = ! range_p.is_last_segment();
|
||||
bool const has_qk = ! range_q.is_last_segment();
|
||||
@ -1026,19 +1027,15 @@ struct collinear : public base_turn_handler
|
||||
int const side_q = has_qk ? side.qk_wrt_q1() : 0;
|
||||
|
||||
// If p arrives, use p, else use q
|
||||
int const side_p_or_q = arrival == 1
|
||||
int const side_p_or_q = arrival_p == 1
|
||||
? side_p
|
||||
: side_q
|
||||
;
|
||||
|
||||
// See comments above,
|
||||
// resulting in a strange sort of mathematic rule here:
|
||||
// The arrival-info multiplied by the relevant side
|
||||
// delivers a consistent result.
|
||||
// Calculate product according to comments above.
|
||||
int const product = arrival_p * side_p_or_q;
|
||||
|
||||
int const product = arrival * side_p_or_q;
|
||||
|
||||
if(product == 0)
|
||||
if (product == 0)
|
||||
{
|
||||
both(ti, operation_continue);
|
||||
}
|
||||
@ -1186,11 +1183,11 @@ public:
|
||||
{
|
||||
TurnInfo tp = tp_model;
|
||||
|
||||
int const p_arrival = info.d_info().arrival[0];
|
||||
int const q_arrival = info.d_info().arrival[1];
|
||||
int const arrival_p = info.d_info().arrival[0];
|
||||
int const arrival_q = info.d_info().arrival[1];
|
||||
|
||||
// If P arrives within Q, there is a turn dependent on P
|
||||
if ( p_arrival == 1
|
||||
if ( arrival_p == 1
|
||||
&& ! range_p.is_last_segment()
|
||||
&& set_tp<0>(side.pk_wrt_p1(), tp, info.i_info()) )
|
||||
{
|
||||
@ -1200,7 +1197,7 @@ public:
|
||||
}
|
||||
|
||||
// If Q arrives within P, there is a turn dependent on Q
|
||||
if ( q_arrival == 1
|
||||
if ( arrival_q == 1
|
||||
&& ! range_q.is_last_segment()
|
||||
&& set_tp<1>(side.qk_wrt_q1(), tp, info.i_info()) )
|
||||
{
|
||||
@ -1212,8 +1209,8 @@ public:
|
||||
if (AssignPolicy::include_opposite)
|
||||
{
|
||||
// Handle cases not yet handled above
|
||||
if ((q_arrival == -1 && p_arrival == 0)
|
||||
|| (p_arrival == -1 && q_arrival == 0))
|
||||
if ((arrival_q == -1 && arrival_p == 0)
|
||||
|| (arrival_p == -1 && arrival_q == 0))
|
||||
{
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
@ -1396,7 +1393,7 @@ struct get_turn_info
|
||||
else
|
||||
{
|
||||
handler::template apply<1>(range_q, range_p, tp, inters.i_info(), inters.d_info(),
|
||||
inters.get_swapped_sides(), umbrella_strategy);
|
||||
inters.swapped_sides(), umbrella_strategy);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@ -1420,9 +1417,10 @@ struct get_turn_info
|
||||
// Collinear
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
|
||||
if ( inters.d_info().arrival[0] == 0 )
|
||||
if (inters.d_info().arrival[0] == 0
|
||||
|| collinear<TurnInfo>::handle_as_equal(inters.i_info(), range_p, range_q, inters.d_info()))
|
||||
{
|
||||
// Both segments arrive at the second intersection point
|
||||
handle_as_equal = true;
|
||||
}
|
||||
else
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -111,12 +111,16 @@ namespace detail { namespace overlay {
|
||||
class linear_intersections
|
||||
{
|
||||
public:
|
||||
template <typename Point1, typename Point2, typename IntersectionResult, typename EqPPStrategy>
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename IntersectionResult,
|
||||
typename Strategy
|
||||
>
|
||||
linear_intersections(Point1 const& pi,
|
||||
Point2 const& qi,
|
||||
IntersectionResult const& result,
|
||||
bool is_p_last, bool is_q_last,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
int arrival_a = result.direction.arrival[0];
|
||||
int arrival_b = result.direction.arrival[1];
|
||||
@ -237,7 +241,7 @@ struct get_turn_info_for_endpoint
|
||||
typename TurnInfo,
|
||||
typename IntersectionInfo,
|
||||
typename OutputIterator,
|
||||
typename EqPPStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline bool apply(UniqueSubRange1 const& range_p,
|
||||
UniqueSubRange2 const& range_q,
|
||||
@ -245,7 +249,7 @@ struct get_turn_info_for_endpoint
|
||||
IntersectionInfo const& inters,
|
||||
method_type /*method*/,
|
||||
OutputIterator out,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
std::size_t ip_count = inters.i_info().count;
|
||||
// no intersection points
|
||||
@ -398,8 +402,7 @@ struct get_turn_info_for_endpoint
|
||||
{
|
||||
boost::ignore_unused(ip_index, tp_model);
|
||||
|
||||
typename IntersectionInfo::side_strategy_type const& sides
|
||||
= inters.get_side_strategy();
|
||||
auto const strategy = inters.strategy();
|
||||
|
||||
if ( !first2 && !last2 )
|
||||
{
|
||||
@ -409,8 +412,8 @@ struct get_turn_info_for_endpoint
|
||||
// may this give false positives for INTs?
|
||||
typename IntersectionResult::point_type const&
|
||||
inters_pt = inters.i_info().intersections[ip_index];
|
||||
BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
|
||||
BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
|
||||
BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt, strategy));
|
||||
BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt, strategy));
|
||||
#endif
|
||||
if ( ip_i2 )
|
||||
{
|
||||
@ -421,6 +424,7 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
else if ( ip_j2 )
|
||||
{
|
||||
auto const sides = strategy.side();
|
||||
int const side_pj_q2 = sides.apply(range2.at(1), range2.at(2), range1.at(1));
|
||||
int const side_pj_q1 = sides.apply(range2.at(0), range2.at(1), range1.at(1));
|
||||
int const side_qk_q1 = sides.apply(range2.at(0), range2.at(1), range2.at(2));
|
||||
@ -460,8 +464,8 @@ struct get_turn_info_for_endpoint
|
||||
// may this give false positives for INTs?
|
||||
typename IntersectionResult::point_type const&
|
||||
inters_pt = inters.i_info().intersections[ip_index];
|
||||
BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt));
|
||||
BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt));
|
||||
BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt, strategy));
|
||||
BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt, strategy));
|
||||
#endif
|
||||
if ( ip_i2 )
|
||||
{
|
||||
@ -472,6 +476,7 @@ struct get_turn_info_for_endpoint
|
||||
}
|
||||
else if ( ip_j2 )
|
||||
{
|
||||
auto const sides = strategy.side();
|
||||
int const side_pi_q2 = sides.apply(range2.at(1), range2.at(2), range1.at(0));
|
||||
int const side_pi_q1 = sides.apply(range2.at(0), range2.at(1), range1.at(0));
|
||||
int const side_qk_q1 = sides.apply(range2.at(0), range2.at(1), range2.at(2));
|
||||
|
@ -44,20 +44,20 @@ struct turn_operation_linear
|
||||
|
||||
template
|
||||
<
|
||||
typename TurnPointCSTag,
|
||||
typename UniqueSubRange1,
|
||||
typename UniqueSubRange2,
|
||||
typename SideStrategy
|
||||
typename Strategy
|
||||
>
|
||||
struct side_calculator
|
||||
{
|
||||
typedef typename UniqueSubRange1::point_type point1_type;
|
||||
typedef typename UniqueSubRange2::point_type point2_type;
|
||||
typedef decltype(std::declval<Strategy>().side()) side_strategy_type;
|
||||
|
||||
inline side_calculator(UniqueSubRange1 const& range_p,
|
||||
UniqueSubRange2 const& range_q,
|
||||
SideStrategy const& side_strategy)
|
||||
: m_side_strategy(side_strategy)
|
||||
Strategy const& strategy)
|
||||
: m_side_strategy(strategy.side())
|
||||
, m_range_p(range_p)
|
||||
, m_range_q(range_q)
|
||||
{}
|
||||
@ -84,9 +84,8 @@ struct side_calculator
|
||||
inline point2_type const& get_qj() const { return m_range_q.at(1); }
|
||||
inline point2_type const& get_qk() const { return m_range_q.at(2); }
|
||||
|
||||
// Used side-strategy, owned by the calculator,
|
||||
// created from .get_side_strategy()
|
||||
SideStrategy m_side_strategy;
|
||||
// Used side-strategy, owned by the calculator
|
||||
side_strategy_type m_side_strategy;
|
||||
|
||||
// Used ranges - owned by get_turns or (for robust points) by intersection_info_base
|
||||
UniqueSubRange1 const& m_range_p;
|
||||
@ -259,16 +258,14 @@ public:
|
||||
typedef robust_subrange_adapter<robust_point1_type, UniqueSubRange1, RobustPolicy> robust_subrange1;
|
||||
typedef robust_subrange_adapter<robust_point2_type, UniqueSubRange2, RobustPolicy> robust_subrange2;
|
||||
|
||||
typedef typename cs_tag<TurnPoint>::type cs_tag;
|
||||
|
||||
typedef typename UmbrellaStrategy::side_strategy_type side_strategy_type;
|
||||
typedef side_calculator<cs_tag, robust_subrange1, robust_subrange2,
|
||||
side_strategy_type> side_calculator_type;
|
||||
typedef side_calculator
|
||||
<
|
||||
robust_subrange1, robust_subrange2, UmbrellaStrategy
|
||||
> side_calculator_type;
|
||||
|
||||
typedef side_calculator
|
||||
<
|
||||
cs_tag, robust_subrange2, robust_subrange1,
|
||||
side_strategy_type
|
||||
robust_subrange2, robust_subrange1, UmbrellaStrategy
|
||||
> robust_swapped_side_calculator_type;
|
||||
|
||||
intersection_info_base(UniqueSubRange1 const& range_p,
|
||||
@ -280,9 +277,9 @@ public:
|
||||
, m_robust_calc(range_p, range_q, robust_policy)
|
||||
, m_robust_range_p(range_p, m_robust_calc.m_rpi, m_robust_calc.m_rpj, robust_policy)
|
||||
, m_robust_range_q(range_q, m_robust_calc.m_rqi, m_robust_calc.m_rqj, robust_policy)
|
||||
, m_side_calc(m_robust_range_p, m_robust_range_q,
|
||||
umbrella_strategy.get_side_strategy())
|
||||
, m_result(umbrella_strategy.apply(range_p, range_q,
|
||||
, m_side_calc(m_robust_range_p, m_robust_range_q, umbrella_strategy)
|
||||
, m_swapped_side_calc(m_robust_range_q, m_robust_range_p, umbrella_strategy)
|
||||
, m_result(umbrella_strategy.relate().apply(range_p, range_q,
|
||||
intersection_policy_type(),
|
||||
m_robust_range_p, m_robust_range_q))
|
||||
{}
|
||||
@ -299,13 +296,9 @@ public:
|
||||
inline robust_point2_type const& rqk() const { return m_robust_calc.get_rqk(); }
|
||||
|
||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||
|
||||
robust_swapped_side_calculator_type get_swapped_sides() const
|
||||
inline robust_swapped_side_calculator_type const& swapped_sides() const
|
||||
{
|
||||
robust_swapped_side_calculator_type result(
|
||||
m_robust_range_q, m_robust_range_p,
|
||||
m_side_calc.m_side_strategy);
|
||||
return result;
|
||||
return m_swapped_side_calc;
|
||||
}
|
||||
|
||||
private :
|
||||
@ -319,6 +312,7 @@ private :
|
||||
robust_subrange1 m_robust_range_p;
|
||||
robust_subrange2 m_robust_range_q;
|
||||
side_calculator_type m_side_calc;
|
||||
robust_swapped_side_calculator_type m_swapped_side_calc;
|
||||
|
||||
protected :
|
||||
result_type m_result;
|
||||
@ -347,15 +341,14 @@ public:
|
||||
typedef typename UniqueSubRange1::point_type point1_type;
|
||||
typedef typename UniqueSubRange2::point_type point2_type;
|
||||
|
||||
typedef typename UmbrellaStrategy::cs_tag cs_tag;
|
||||
|
||||
typedef typename UmbrellaStrategy::side_strategy_type side_strategy_type;
|
||||
typedef side_calculator<cs_tag, UniqueSubRange1, UniqueSubRange2, side_strategy_type> side_calculator_type;
|
||||
typedef side_calculator
|
||||
<
|
||||
UniqueSubRange1, UniqueSubRange2, UmbrellaStrategy
|
||||
> side_calculator_type;
|
||||
|
||||
typedef side_calculator
|
||||
<
|
||||
cs_tag, UniqueSubRange2, UniqueSubRange1,
|
||||
side_strategy_type
|
||||
UniqueSubRange2, UniqueSubRange1, UmbrellaStrategy
|
||||
> swapped_side_calculator_type;
|
||||
|
||||
intersection_info_base(UniqueSubRange1 const& range_p,
|
||||
@ -364,9 +357,10 @@ public:
|
||||
no_rescale_policy const& )
|
||||
: m_range_p(range_p)
|
||||
, m_range_q(range_q)
|
||||
, m_side_calc(range_p, range_q,
|
||||
umbrella_strategy.get_side_strategy())
|
||||
, m_result(umbrella_strategy.apply(range_p, range_q, intersection_policy_type()))
|
||||
, m_side_calc(range_p, range_q, umbrella_strategy)
|
||||
, m_swapped_side_calc(range_q, range_p, umbrella_strategy)
|
||||
, m_result(umbrella_strategy.relate()
|
||||
.apply(range_p, range_q, intersection_policy_type()))
|
||||
{}
|
||||
|
||||
inline bool p_is_last_segment() const { return m_range_p.is_last_segment(); }
|
||||
@ -381,13 +375,9 @@ public:
|
||||
inline point2_type const& rqk() const { return m_side_calc.get_qk(); }
|
||||
|
||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||
|
||||
swapped_side_calculator_type get_swapped_sides() const
|
||||
inline swapped_side_calculator_type const& swapped_sides() const
|
||||
{
|
||||
swapped_side_calculator_type result(
|
||||
m_range_q, m_range_p,
|
||||
m_side_calc.m_side_strategy);
|
||||
return result;
|
||||
return m_swapped_side_calc;
|
||||
}
|
||||
|
||||
private :
|
||||
@ -397,6 +387,7 @@ private :
|
||||
|
||||
// Owned by this class
|
||||
side_calculator_type m_side_calc;
|
||||
swapped_side_calculator_type m_swapped_side_calc;
|
||||
|
||||
protected :
|
||||
result_type m_result;
|
||||
@ -422,8 +413,6 @@ public:
|
||||
typedef typename UniqueSubRange1::point_type point1_type;
|
||||
typedef typename UniqueSubRange2::point_type point2_type;
|
||||
|
||||
typedef UmbrellaStrategy intersection_strategy_type;
|
||||
typedef typename UmbrellaStrategy::side_strategy_type side_strategy_type;
|
||||
typedef typename UmbrellaStrategy::cs_tag cs_tag;
|
||||
|
||||
typedef typename base::side_calculator_type side_calculator_type;
|
||||
@ -437,7 +426,7 @@ public:
|
||||
UmbrellaStrategy const& umbrella_strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
: base(range_p, range_q, umbrella_strategy, robust_policy)
|
||||
, m_intersection_strategy(umbrella_strategy)
|
||||
, m_umbrella_strategy(umbrella_strategy)
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
@ -445,11 +434,6 @@ public:
|
||||
inline i_info_type const& i_info() const { return base::m_result.intersection_points; }
|
||||
inline d_info_type const& d_info() const { return base::m_result.direction; }
|
||||
|
||||
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
|
||||
{
|
||||
@ -524,6 +508,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
UmbrellaStrategy const& strategy() const
|
||||
{
|
||||
return m_umbrella_strategy;
|
||||
}
|
||||
|
||||
private:
|
||||
template <std::size_t OpId>
|
||||
bool is_ip_j() const
|
||||
@ -548,7 +537,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
UmbrellaStrategy const& m_intersection_strategy;
|
||||
UmbrellaStrategy const& m_umbrella_strategy;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
};
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -79,7 +79,7 @@ struct get_turn_info_linear_areal
|
||||
case 's' : // starts from the middle
|
||||
get_turn_info_for_endpoint<true, true>(range_p, range_q,
|
||||
tp_model, inters, method_none, out,
|
||||
umbrella_strategy.get_point_in_point_strategy());
|
||||
umbrella_strategy);
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
@ -89,7 +89,7 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
|
||||
tp_model, inters, method_touch_interior, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -109,7 +109,7 @@ struct get_turn_info_linear_areal
|
||||
// Swap p/q
|
||||
handler::template apply<1>(range_q, range_p,
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
inters.get_swapped_sides(), umbrella_strategy);
|
||||
inters.swapped_sides(), umbrella_strategy);
|
||||
}
|
||||
|
||||
if ( tp.operations[1].operation == operation_blocked )
|
||||
@ -124,7 +124,7 @@ struct get_turn_info_linear_areal
|
||||
// this function assumes that 'u' must be set for a spike
|
||||
calculate_spike_operation(tp.operations[0].operation,
|
||||
inters,
|
||||
umbrella_strategy.get_point_in_point_strategy());
|
||||
umbrella_strategy);
|
||||
|
||||
*out++ = tp;
|
||||
}
|
||||
@ -144,7 +144,7 @@ struct get_turn_info_linear_areal
|
||||
// Both touch (both arrive there)
|
||||
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
|
||||
tp_model, inters, method_touch, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -218,7 +218,7 @@ struct get_turn_info_linear_areal
|
||||
bool ignore_spike
|
||||
= calculate_spike_operation(tp.operations[0].operation,
|
||||
inters,
|
||||
umbrella_strategy.get_point_in_point_strategy());
|
||||
umbrella_strategy);
|
||||
|
||||
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|
||||
|| ignore_spike
|
||||
@ -234,7 +234,7 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
if ( get_turn_info_for_endpoint<true, true>(range_p, range_q,
|
||||
tp_model, inters, method_equal, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -279,7 +279,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
range_p, range_q,
|
||||
tp_model, inters, method_collinear, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -359,13 +359,13 @@ struct get_turn_info_linear_areal
|
||||
|
||||
if ( range_p.is_first_segment()
|
||||
&& equals::equals_point_point(range_p.at(0), tp.point,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
tp.operations[0].position = position_front;
|
||||
}
|
||||
else if ( range_p.is_last_segment()
|
||||
&& equals::equals_point_point(range_p.at(1), tp.point,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
tp.operations[0].position = position_back;
|
||||
}
|
||||
@ -392,10 +392,10 @@ struct get_turn_info_linear_areal
|
||||
|
||||
template <typename Operation,
|
||||
typename IntersectionInfo,
|
||||
typename EqPPStrategy>
|
||||
typename Strategy>
|
||||
static inline bool calculate_spike_operation(Operation & op,
|
||||
IntersectionInfo const& inters,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
bool is_p_spike = ( op == operation_union || op == operation_intersection )
|
||||
&& inters.is_spike_p();
|
||||
@ -415,7 +415,7 @@ struct get_turn_info_linear_areal
|
||||
// spike on the edge point
|
||||
// if it's already known that the spike is going out this musn't be checked
|
||||
if ( ! going_out
|
||||
&& detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
|
||||
&& equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
|
||||
{
|
||||
int const pk_q2 = inters.sides().pk_wrt_q2();
|
||||
going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
|
||||
@ -427,7 +427,7 @@ struct get_turn_info_linear_areal
|
||||
// spike on the edge point
|
||||
// if it's already known that the spike is going in this musn't be checked
|
||||
if ( ! going_in
|
||||
&& detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
|
||||
&& equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
|
||||
{
|
||||
int const pk_q2 = inters.sides().pk_wrt_q2();
|
||||
going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them
|
||||
@ -679,7 +679,7 @@ struct get_turn_info_linear_areal
|
||||
typename TurnInfo,
|
||||
typename IntersectionInfo,
|
||||
typename OutputIterator,
|
||||
typename EqPPStrategy>
|
||||
typename Strategy>
|
||||
static inline bool get_turn_info_for_endpoint(
|
||||
UniqueSubRange1 const& range_p,
|
||||
UniqueSubRange2 const& range_q,
|
||||
@ -687,7 +687,7 @@ struct get_turn_info_linear_areal
|
||||
IntersectionInfo const& inters,
|
||||
method_type /*method*/,
|
||||
OutputIterator out,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
namespace ov = overlay;
|
||||
typedef ov::get_turn_info_for_endpoint<EnableFirst, EnableLast> get_info_e;
|
||||
@ -705,9 +705,6 @@ struct get_turn_info_linear_areal
|
||||
return false;
|
||||
}
|
||||
|
||||
typename IntersectionInfo::side_strategy_type const& sides
|
||||
= inters.get_side_strategy();
|
||||
|
||||
linear_intersections intersections(range_p.at(0),
|
||||
range_q.at(0),
|
||||
inters.result(),
|
||||
@ -738,6 +735,8 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const sides = strategy.side();
|
||||
|
||||
// pi is the intersection point at qj or in the middle of q1
|
||||
// so consider segments
|
||||
// 1. pi at qj: qi-qj-pj and qi-qj-qk
|
||||
@ -807,6 +806,8 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
else //if ( result.template get<0>().count == 1 )
|
||||
{
|
||||
auto const sides = strategy.side();
|
||||
|
||||
// pj is the intersection point at qj or in the middle of q1
|
||||
// so consider segments
|
||||
// 1. pj at qj: qi-qj-pi and qi-qj-qk
|
||||
@ -863,14 +864,6 @@ struct get_turn_info_linear_areal
|
||||
// don't ignore anything for now
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2, typename IntersectionStrategy>
|
||||
static inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||
IntersectionStrategy const& strategy)
|
||||
{
|
||||
return detail::equals::equals_point_point(point1, point2,
|
||||
strategy.get_point_in_point_strategy());
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::overlay
|
||||
|
@ -75,7 +75,7 @@ struct get_turn_info_linear_linear
|
||||
get_turn_info_for_endpoint<true, true>
|
||||
::apply(range_p, range_q,
|
||||
tp_model, inters, method_none, out,
|
||||
umbrella_strategy.get_point_in_point_strategy());
|
||||
umbrella_strategy);
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
@ -86,7 +86,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<false, true>
|
||||
::apply(range_p, range_q,
|
||||
tp_model, inters, method_touch_interior, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -110,7 +110,7 @@ struct get_turn_info_linear_linear
|
||||
// Swap p/q
|
||||
policy::template apply<1>(range_q, range_p, tp,
|
||||
inters.i_info(), inters.d_info(),
|
||||
inters.get_swapped_sides(),
|
||||
inters.swapped_sides(),
|
||||
umbrella_strategy);
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<false, true>
|
||||
::apply(range_p, range_q,
|
||||
tp_model, inters, method_touch, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -278,7 +278,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<true, true>
|
||||
::apply(range_p, range_q,
|
||||
tp_model, inters, method_equal, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -333,7 +333,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<true, true>
|
||||
::apply(range_p, range_q,
|
||||
tp_model, inters, method_collinear, out,
|
||||
umbrella_strategy.get_point_in_point_strategy()) )
|
||||
umbrella_strategy) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@ -416,29 +416,26 @@ struct get_turn_info_linear_linear
|
||||
// degenerate points
|
||||
if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) )
|
||||
{
|
||||
typedef typename UmbrellaStrategy::point_in_point_strategy_type
|
||||
equals_strategy_type;
|
||||
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
|
||||
// if any, only one of those should be true
|
||||
if ( range_p.is_first_segment()
|
||||
&& equals::equals_point_point(range_p.at(0), tp.point, equals_strategy_type()) )
|
||||
&& equals::equals_point_point(range_p.at(0), tp.point, umbrella_strategy) )
|
||||
{
|
||||
tp.operations[0].position = position_front;
|
||||
}
|
||||
else if ( range_p.is_last_segment()
|
||||
&& equals::equals_point_point(range_p.at(1), tp.point, equals_strategy_type()) )
|
||||
&& equals::equals_point_point(range_p.at(1), tp.point, umbrella_strategy) )
|
||||
{
|
||||
tp.operations[0].position = position_back;
|
||||
}
|
||||
else if ( range_q.is_first_segment()
|
||||
&& equals::equals_point_point(range_q.at(0), tp.point, equals_strategy_type()) )
|
||||
&& equals::equals_point_point(range_q.at(0), tp.point, umbrella_strategy) )
|
||||
{
|
||||
tp.operations[1].position = position_front;
|
||||
}
|
||||
else if ( range_q.is_last_segment()
|
||||
&& equals::equals_point_point(range_q.at(1), tp.point, equals_strategy_type()) )
|
||||
&& equals::equals_point_point(range_q.at(1), tp.point, umbrella_strategy) )
|
||||
{
|
||||
tp.operations[1].position = position_back;
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2014-2020.
|
||||
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014-2021.
|
||||
// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -108,7 +108,7 @@ template
|
||||
typename Section,
|
||||
typename Point,
|
||||
typename CircularIterator,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy
|
||||
>
|
||||
struct unique_sub_range_from_section
|
||||
@ -118,16 +118,17 @@ struct unique_sub_range_from_section
|
||||
unique_sub_range_from_section(Section const& section, signed_size_type index,
|
||||
CircularIterator circular_iterator,
|
||||
Point const& previous, Point const& current,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
: m_section(section)
|
||||
, m_index(index)
|
||||
, m_previous_point(previous)
|
||||
, m_current_point(current)
|
||||
, m_circular_iterator(circular_iterator)
|
||||
, m_point_retrieved(false)
|
||||
, m_robust_policy(robust_policy)
|
||||
{
|
||||
}
|
||||
: m_section(section)
|
||||
, m_index(index)
|
||||
, m_previous_point(previous)
|
||||
, m_current_point(current)
|
||||
, m_circular_iterator(circular_iterator)
|
||||
, m_point_retrieved(false)
|
||||
, m_strategy(strategy)
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
inline bool is_first_segment() const
|
||||
{
|
||||
@ -170,7 +171,6 @@ private :
|
||||
|
||||
inline void advance_to_non_duplicate_next(Point const& current, CircularIterator& circular_iterator) const
|
||||
{
|
||||
typedef typename IntersectionStrategy::point_in_point_strategy_type disjoint_strategy_type;
|
||||
typedef typename robust_point_type<Point, RobustPolicy>::type robust_point_type;
|
||||
robust_point_type current_robust_point;
|
||||
robust_point_type next_robust_point;
|
||||
@ -187,12 +187,9 @@ private :
|
||||
// So advance to the "non duplicate next"
|
||||
// (the check is defensive, to avoid endless loops)
|
||||
std::size_t check = 0;
|
||||
while(! detail::disjoint::disjoint_point_point
|
||||
(
|
||||
current_robust_point, next_robust_point,
|
||||
disjoint_strategy_type()
|
||||
)
|
||||
&& check++ < m_section.range_count)
|
||||
while (! detail::disjoint::disjoint_point_point(
|
||||
current_robust_point, next_robust_point, m_strategy)
|
||||
&& check++ < m_section.range_count)
|
||||
{
|
||||
circular_iterator++;
|
||||
geometry::recalculate(next_robust_point, *circular_iterator, m_robust_policy);
|
||||
@ -206,6 +203,7 @@ private :
|
||||
mutable CircularIterator m_circular_iterator;
|
||||
mutable Point m_point;
|
||||
mutable bool m_point_retrieved;
|
||||
Strategy m_strategy;
|
||||
RobustPolicy m_robust_policy;
|
||||
};
|
||||
|
||||
@ -276,12 +274,12 @@ class get_turns_in_sections
|
||||
|
||||
public :
|
||||
// Returns true if terminated, false if interrupted
|
||||
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
||||
template <typename Strategy, 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, bool skip_adjacent,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
@ -337,11 +335,11 @@ public :
|
||||
unique_sub_range_from_section
|
||||
<
|
||||
areal1, Section1, point1_type, circular1_iterator,
|
||||
IntersectionStrategy, RobustPolicy
|
||||
Strategy, RobustPolicy
|
||||
> unique_sub_range1(sec1, index1,
|
||||
circular1_iterator(begin_range_1, end_range_1, next1, true),
|
||||
*prev1, *it1,
|
||||
robust_policy);
|
||||
strategy, robust_policy);
|
||||
|
||||
signed_size_type index2 = sec2.begin_index;
|
||||
signed_size_type ndi2 = sec2.non_duplicate_index;
|
||||
@ -390,11 +388,11 @@ public :
|
||||
unique_sub_range_from_section
|
||||
<
|
||||
areal2, Section2, point2_type, circular2_iterator,
|
||||
IntersectionStrategy, RobustPolicy
|
||||
Strategy, RobustPolicy
|
||||
> unique_sub_range2(sec2, index2,
|
||||
circular2_iterator(begin_range_2, end_range_2, next2),
|
||||
*prev2, *it2,
|
||||
robust_policy);
|
||||
strategy, robust_policy);
|
||||
|
||||
typedef typename boost::range_value<Turns>::type turn_info;
|
||||
|
||||
@ -409,7 +407,7 @@ public :
|
||||
std::size_t const size_before = boost::size(turns);
|
||||
|
||||
TurnPolicy::apply(unique_sub_range1, unique_sub_range2,
|
||||
ti, intersection_strategy, robust_policy,
|
||||
ti, strategy, robust_policy,
|
||||
std::back_inserter(turns));
|
||||
|
||||
if (InterruptPolicy::enabled)
|
||||
@ -464,7 +462,7 @@ template
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2,
|
||||
typename TurnPolicy,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
@ -475,20 +473,20 @@ struct section_visitor
|
||||
Geometry1 const& m_geometry1;
|
||||
int m_source_id2;
|
||||
Geometry2 const& m_geometry2;
|
||||
IntersectionStrategy const& m_intersection_strategy;
|
||||
Strategy const& m_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,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& 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_strategy(strategy)
|
||||
, m_rescale_policy(robust_policy)
|
||||
, m_turns(turns)
|
||||
, m_interrupt_policy(ip)
|
||||
@ -499,7 +497,7 @@ struct section_visitor
|
||||
{
|
||||
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
|
||||
sec2.bounding_box,
|
||||
m_intersection_strategy.get_disjoint_box_box_strategy()))
|
||||
m_strategy) )
|
||||
{
|
||||
// false if interrupted
|
||||
return get_turns_in_sections
|
||||
@ -512,7 +510,7 @@ struct section_visitor
|
||||
>::apply(m_source_id1, m_geometry1, sec1,
|
||||
m_source_id2, m_geometry2, sec2,
|
||||
false, false,
|
||||
m_intersection_strategy,
|
||||
m_strategy,
|
||||
m_rescale_policy,
|
||||
m_turns, m_interrupt_policy);
|
||||
}
|
||||
@ -531,11 +529,11 @@ class get_turns_generic
|
||||
{
|
||||
|
||||
public:
|
||||
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
||||
template <typename Strategy, 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,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
@ -556,15 +554,10 @@ public:
|
||||
sections_type sec1, sec2;
|
||||
typedef std::integer_sequence<std::size_t, 0, 1> dimensions;
|
||||
|
||||
typename IntersectionStrategy::envelope_strategy_type const
|
||||
envelope_strategy = intersection_strategy.get_envelope_strategy();
|
||||
typename IntersectionStrategy::expand_strategy_type const
|
||||
expand_strategy = intersection_strategy.get_expand_strategy();
|
||||
|
||||
geometry::sectionalize<Reverse1, dimensions>(geometry1, robust_policy,
|
||||
sec1, envelope_strategy, expand_strategy, 0);
|
||||
sec1, strategy, 0);
|
||||
geometry::sectionalize<Reverse2, dimensions>(geometry2, robust_policy,
|
||||
sec2, envelope_strategy, expand_strategy, 1);
|
||||
sec2, strategy, 1);
|
||||
|
||||
// ... and then partition them, intersecting overlapping sections in visitor method
|
||||
section_visitor
|
||||
@ -572,27 +565,17 @@ public:
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2,
|
||||
TurnPolicy,
|
||||
IntersectionStrategy, RobustPolicy,
|
||||
Strategy, RobustPolicy,
|
||||
Turns, InterruptPolicy
|
||||
> visitor(source_id1, geometry1, source_id2, geometry2,
|
||||
intersection_strategy, robust_policy,
|
||||
turns, interrupt_policy);
|
||||
|
||||
typedef detail::section::get_section_box
|
||||
<
|
||||
typename IntersectionStrategy::expand_box_strategy_type
|
||||
> get_section_box_type;
|
||||
typedef detail::section::overlaps_section_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_box_box_strategy_type
|
||||
> overlaps_section_box_type;
|
||||
strategy, robust_policy, turns, interrupt_policy);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box_type
|
||||
>::apply(sec1, sec2, visitor,
|
||||
get_section_box_type(),
|
||||
overlaps_section_box_type());
|
||||
detail::section::get_section_box<Strategy>(strategy),
|
||||
detail::section::overlaps_section_box<Strategy>(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1094,10 +1077,10 @@ template
|
||||
>
|
||||
struct get_turns_reversed
|
||||
{
|
||||
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
||||
template <typename Strategy, 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,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
@ -1109,7 +1092,7 @@ struct get_turns_reversed
|
||||
Reverse2, Reverse1,
|
||||
TurnPolicy
|
||||
>::apply(source_id2, g2, source_id1, g1,
|
||||
intersection_strategy, robust_policy,
|
||||
strategy, robust_policy,
|
||||
turns, interrupt_policy);
|
||||
}
|
||||
};
|
||||
@ -1140,14 +1123,14 @@ template
|
||||
typename AssignPolicy,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
inline void get_turns(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy)
|
||||
@ -1178,7 +1161,7 @@ inline void get_turns(Geometry1 const& geometry1,
|
||||
>
|
||||
>::apply(0, geometry1,
|
||||
1, geometry2,
|
||||
intersection_strategy,
|
||||
strategy,
|
||||
robust_policy,
|
||||
turns, interrupt_policy);
|
||||
}
|
||||
|
@ -32,48 +32,6 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point, typename Geometry,
|
||||
typename Tag2 = typename geometry::tag<Geometry>::type
|
||||
>
|
||||
struct check_within_strategy
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename Strategy::template point_in_geometry_strategy<Point, Geometry>::type
|
||||
within(Strategy const& strategy)
|
||||
{
|
||||
return strategy.template get_point_in_geometry_strategy<Point, Geometry>();
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename Strategy::template point_in_geometry_strategy<Point, Geometry>::type
|
||||
covered_by(Strategy const& strategy)
|
||||
{
|
||||
return strategy.template get_point_in_geometry_strategy<Point, Geometry>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
struct check_within_strategy<Point, Geometry, box_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename Strategy::within_point_box_strategy_type
|
||||
within(Strategy const& )
|
||||
{
|
||||
return typename Strategy::within_point_box_strategy_type();
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename Strategy::covered_by_point_box_strategy_type
|
||||
covered_by(Strategy const&)
|
||||
{
|
||||
return typename Strategy::covered_by_point_box_strategy_type();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <overlay_type OverlayType>
|
||||
struct check_within
|
||||
{
|
||||
@ -86,14 +44,10 @@ struct check_within
|
||||
bool apply(Turn const& turn, Geometry0 const& geometry0,
|
||||
Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
|
||||
{
|
||||
typedef typename Turn::point_type point_type;
|
||||
|
||||
// Operations 0 and 1 have the same source index in self-turns
|
||||
return turn.operations[0].seg_id.source_index == 0
|
||||
? geometry::within(turn.point, geometry1,
|
||||
check_within_strategy<point_type, Geometry1>::within(strategy))
|
||||
: geometry::within(turn.point, geometry0,
|
||||
check_within_strategy<point_type, Geometry0>::within(strategy));
|
||||
? geometry::within(turn.point, geometry1, strategy)
|
||||
: geometry::within(turn.point, geometry0, strategy);
|
||||
}
|
||||
|
||||
};
|
||||
@ -110,15 +64,11 @@ struct check_within<overlay_difference>
|
||||
bool apply(Turn const& turn, Geometry0 const& geometry0,
|
||||
Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
|
||||
{
|
||||
typedef typename Turn::point_type point_type;
|
||||
|
||||
// difference = intersection(a, reverse(b))
|
||||
// therefore we should reverse the meaning of within for geometry1
|
||||
return turn.operations[0].seg_id.source_index == 0
|
||||
? ! geometry::covered_by(turn.point, geometry1,
|
||||
check_within_strategy<point_type, Geometry1>::covered_by(strategy))
|
||||
: geometry::within(turn.point, geometry0,
|
||||
check_within_strategy<point_type, Geometry0>::within(strategy));
|
||||
? ! geometry::covered_by(turn.point, geometry1, strategy)
|
||||
: geometry::within(turn.point, geometry0, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -49,6 +49,10 @@
|
||||
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
#include <boost/geometry/views/segment_view.hpp>
|
||||
#include <boost/geometry/views/detail/boundary_view.hpp>
|
||||
|
||||
@ -100,7 +104,7 @@ struct intersection_segment_segment_point
|
||||
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
||||
|
||||
intersection_return_type
|
||||
is = strategy.apply(sub_range1, sub_range2, policy_type());
|
||||
is = strategy.relate().apply(sub_range1, sub_range2, policy_type());
|
||||
|
||||
for (std::size_t i = 0; i < is.count; i++)
|
||||
{
|
||||
@ -1535,9 +1539,9 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1,
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type
|
||||
Geometry1, Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
|
||||
|
@ -147,13 +147,13 @@ protected:
|
||||
typename Turns,
|
||||
typename LinearGeometry1,
|
||||
typename LinearGeometry2,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy
|
||||
>
|
||||
static inline void compute_turns(Turns& turns,
|
||||
LinearGeometry1 const& linear1,
|
||||
LinearGeometry2 const& linear2,
|
||||
IntersectionStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
turns.clear();
|
||||
@ -182,14 +182,14 @@ protected:
|
||||
typename LinearGeometry1,
|
||||
typename LinearGeometry2,
|
||||
typename OutputIterator,
|
||||
typename IntersectionStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline OutputIterator
|
||||
sort_and_follow_turns(Turns& turns,
|
||||
LinearGeometry1 const& linear1,
|
||||
LinearGeometry2 const& linear2,
|
||||
OutputIterator oit,
|
||||
IntersectionStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// remove turns that have no added value
|
||||
turns::filter_continue_turns
|
||||
@ -217,7 +217,7 @@ protected:
|
||||
FollowIsolatedPoints,
|
||||
!EnableFilterContinueTurns || OverlayType == overlay_intersection
|
||||
>::apply(linear1, linear2, boost::begin(turns), boost::end(turns),
|
||||
oit, strategy.get_side_strategy());
|
||||
oit, strategy);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -197,20 +197,13 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
typedef std::deque
|
||||
<
|
||||
typename geometry::ring_type<GeometryOut>::type
|
||||
> ring_container_type;
|
||||
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type1;
|
||||
typedef typename geometry::ring_type<GeometryOut>::type ring_type;
|
||||
typedef std::deque<ring_type> ring_container_type;
|
||||
|
||||
typedef ring_properties
|
||||
<
|
||||
point_type1,
|
||||
typename Strategy::template area_strategy
|
||||
<
|
||||
point_type1
|
||||
>::type::template result_type<point_type1>::type
|
||||
typename geometry::point_type<ring_type>::type,
|
||||
typename geometry::area_result<ring_type, Strategy>::type
|
||||
> properties;
|
||||
|
||||
// Silence warning C4127: conditional expression is constant
|
||||
@ -239,8 +232,7 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
|
||||
select_rings<OverlayType>(geometry1, geometry2, empty, all_of_one_of_them, strategy);
|
||||
ring_container_type rings;
|
||||
assign_parents<OverlayType>(geometry1, geometry2, rings, all_of_one_of_them, strategy);
|
||||
return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out,
|
||||
strategy.template get_area_strategy<point_type1>());
|
||||
return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
@ -285,10 +277,8 @@ struct overlay
|
||||
> turn_info;
|
||||
typedef std::deque<turn_info> turn_container_type;
|
||||
|
||||
typedef std::deque
|
||||
<
|
||||
typename geometry::ring_type<GeometryOut>::type
|
||||
> ring_container_type;
|
||||
typedef typename geometry::ring_type<GeometryOut>::type ring_type;
|
||||
typedef std::deque<ring_type> ring_container_type;
|
||||
|
||||
// Define the clusters, mapping cluster_id -> turns
|
||||
typedef std::map
|
||||
@ -365,12 +355,10 @@ std::cout << "traverse" << std::endl;
|
||||
|
||||
get_ring_turn_info<OverlayType>(turn_info_per_ring, turns, clusters);
|
||||
|
||||
typedef typename Strategy::template area_strategy<point_type>::type area_strategy_type;
|
||||
|
||||
typedef ring_properties
|
||||
<
|
||||
point_type,
|
||||
typename area_strategy_type::template result_type<point_type>::type
|
||||
typename geometry::area_result<ring_type, Strategy>::type
|
||||
> properties;
|
||||
|
||||
// Select all rings which are NOT touched by any intersection point
|
||||
@ -379,7 +367,6 @@ std::cout << "traverse" << std::endl;
|
||||
selected_ring_properties, strategy);
|
||||
|
||||
// Add rings created during traversal
|
||||
area_strategy_type const area_strategy = strategy.template get_area_strategy<point_type>();
|
||||
{
|
||||
ring_identifier id(2, 0, -1);
|
||||
for (typename boost::range_iterator<ring_container_type>::type
|
||||
@ -387,7 +374,7 @@ std::cout << "traverse" << std::endl;
|
||||
it != boost::end(rings);
|
||||
++it)
|
||||
{
|
||||
selected_ring_properties[id] = properties(*it, area_strategy);
|
||||
selected_ring_properties[id] = properties(*it, strategy);
|
||||
selected_ring_properties[id].reversed = ReverseOut;
|
||||
id.multi_index++;
|
||||
}
|
||||
@ -404,7 +391,7 @@ std::cout << "traverse" << std::endl;
|
||||
// The result may be too big, so the area is negative. In this case either
|
||||
// it can be returned or an exception can be thrown.
|
||||
return add_rings<GeometryOut>(selected_ring_properties, geometry1, geometry2, rings, out,
|
||||
area_strategy,
|
||||
strategy,
|
||||
OverlayType == overlay_union ?
|
||||
#if defined(BOOST_GEOMETRY_UNION_THROW_INVALID_OUTPUT_EXCEPTION)
|
||||
add_rings_throw_if_reversed
|
||||
|
@ -63,44 +63,68 @@ template
|
||||
class multipoint_multipolygon_point
|
||||
{
|
||||
private:
|
||||
template <typename ExpandPointStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_point
|
||||
{
|
||||
explicit expand_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
inline void apply(Box& total, Point const& point) const
|
||||
{
|
||||
geometry::expand(total, point, ExpandPointStrategy());
|
||||
geometry::expand(total, point, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename ExpandBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_boxpair
|
||||
{
|
||||
explicit expand_box_boxpair(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box1, typename Box2, typename SizeT>
|
||||
static inline void apply(Box1& total, std::pair<Box2, SizeT> const& box_pair)
|
||||
inline void apply(Box1& total, std::pair<Box2, SizeT> const& box_pair) const
|
||||
{
|
||||
geometry::expand(total, box_pair.first, ExpandBoxStrategy());
|
||||
geometry::expand(total, box_pair.first, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
explicit overlaps_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
inline bool apply(Box const& box, Point const& point) const
|
||||
{
|
||||
return ! geometry::disjoint(point, box, DisjointPointBoxStrategy());
|
||||
return ! geometry::disjoint(point, box, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_boxpair
|
||||
{
|
||||
explicit overlaps_box_boxpair(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box1, typename Box2, typename SizeT>
|
||||
static inline bool apply(Box1 const& box, std::pair<Box2, SizeT> const& box_pair)
|
||||
inline bool apply(Box1 const& box, std::pair<Box2, SizeT> const& box_pair) const
|
||||
{
|
||||
return ! geometry::disjoint(box, box_pair.first, DisjointBoxBoxStrategy());
|
||||
return ! geometry::disjoint(box, box_pair.first, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
@ -137,10 +161,10 @@ private:
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Box, typename SizeT, typename EnvelopeStrategy>
|
||||
template <typename Iterator, typename Box, typename SizeT, typename Strategy>
|
||||
static inline void fill_box_pairs(Iterator first, Iterator last,
|
||||
std::vector<std::pair<Box, SizeT> > & box_pairs,
|
||||
EnvelopeStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
SizeT index = 0;
|
||||
for (; first != last; ++first, ++index)
|
||||
@ -172,29 +196,16 @@ private:
|
||||
|
||||
fill_box_pairs(boost::begin(multipolygon),
|
||||
boost::end(multipolygon),
|
||||
box_pairs,
|
||||
strategy.get_envelope_strategy());
|
||||
|
||||
// TEMP - envelope umbrella strategy also contains
|
||||
// expand strategies
|
||||
using expand_box_strategy_type = decltype(
|
||||
strategies::envelope::services::strategy_converter
|
||||
<
|
||||
typename Strategy::envelope_strategy_type
|
||||
>::get(strategy.get_envelope_strategy())
|
||||
.expand(std::declval<box_type>(), std::declval<box_type>()));
|
||||
typedef typename Strategy::disjoint_box_box_strategy_type disjoint_box_box_strategy_type;
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type disjoint_point_box_strategy_type;
|
||||
typedef typename Strategy::expand_point_strategy_type expand_point_strategy_type;
|
||||
box_pairs, strategy);
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box_type
|
||||
>::apply(multipoint, box_pairs, item_visitor,
|
||||
expand_box_point<expand_point_strategy_type>(),
|
||||
overlaps_box_point<disjoint_point_box_strategy_type>(),
|
||||
expand_box_boxpair<expand_box_strategy_type>(),
|
||||
overlaps_box_boxpair<disjoint_box_box_strategy_type>());
|
||||
expand_box_point<Strategy>(strategy),
|
||||
overlaps_box_point<Strategy>(strategy),
|
||||
expand_box_boxpair<Strategy>(strategy),
|
||||
overlaps_box_boxpair<Strategy>(strategy));
|
||||
|
||||
return oit;
|
||||
}
|
||||
|
@ -127,20 +127,26 @@ class multipoint_linear_point
|
||||
{
|
||||
private:
|
||||
// structs for partition -- start
|
||||
template <typename ExpandPointStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_point
|
||||
{
|
||||
expand_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
inline void apply(Box& total, Point const& point) const
|
||||
{
|
||||
geometry::expand(total, point, ExpandPointStrategy());
|
||||
geometry::expand(total, point, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename EnvelopeStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_segment
|
||||
{
|
||||
explicit expand_box_segment(EnvelopeStrategy const& strategy)
|
||||
explicit expand_box_segment(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
@ -149,31 +155,32 @@ private:
|
||||
{
|
||||
geometry::expand(total,
|
||||
geometry::return_envelope<Box>(segment, m_strategy),
|
||||
// TEMP - envelope umbrella strategy also contains
|
||||
// expand strategies
|
||||
strategies::envelope::services::strategy_converter
|
||||
<
|
||||
EnvelopeStrategy
|
||||
>::get(m_strategy));
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
EnvelopeStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
explicit overlaps_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
inline bool apply(Box const& box, Point const& point) const
|
||||
{
|
||||
return ! geometry::disjoint(point, box, DisjointPointBoxStrategy());
|
||||
return ! geometry::disjoint(point, box, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_segment
|
||||
{
|
||||
explicit overlaps_box_segment(DisjointStrategy const& strategy)
|
||||
explicit overlaps_box_segment(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
@ -183,7 +190,7 @@ private:
|
||||
return ! geometry::disjoint(segment, box, m_strategy);
|
||||
}
|
||||
|
||||
DisjointStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename OutputIterator, typename Strategy>
|
||||
@ -218,7 +225,7 @@ private:
|
||||
typedef geometry::segment_iterator<Linear const> const_iterator;
|
||||
typedef const_iterator iterator;
|
||||
|
||||
segment_range(Linear const& linear)
|
||||
explicit segment_range(Linear const& linear)
|
||||
: m_linear(linear)
|
||||
{}
|
||||
|
||||
@ -244,11 +251,6 @@ private:
|
||||
{
|
||||
item_visitor_type<OutputIterator, Strategy> item_visitor(oit, strategy);
|
||||
|
||||
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
|
||||
typedef typename Strategy::disjoint_strategy_type disjoint_strategy_type;
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type disjoint_point_box_strategy_type;
|
||||
typedef typename Strategy::expand_point_strategy_type expand_point_strategy_type;
|
||||
|
||||
// TODO: disjoint Segment/Box may be called in partition multiple times
|
||||
// possibly for non-cartesian segments which could be slow. We should consider
|
||||
// passing a range of bounding boxes of segments after calculating them once.
|
||||
@ -261,10 +263,10 @@ private:
|
||||
typename boost::range_value<MultiPoint>::type
|
||||
>
|
||||
>::apply(multipoint, segment_range(linear), item_visitor,
|
||||
expand_box_point<expand_point_strategy_type>(),
|
||||
overlaps_box_point<disjoint_point_box_strategy_type>(),
|
||||
expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
|
||||
overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
|
||||
expand_box_point<Strategy>(strategy),
|
||||
overlaps_box_point<Strategy>(strategy),
|
||||
expand_box_segment<Strategy>(strategy),
|
||||
overlaps_box_segment<Strategy>(strategy));
|
||||
|
||||
return oit;
|
||||
}
|
||||
|
@ -98,9 +98,9 @@ struct point_in_geometry_helper<Box, box_tag>
|
||||
{
|
||||
template <typename Point, typename Strategy>
|
||||
static inline int apply(Point const& point, Box const& box,
|
||||
Strategy const&)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::covered_by(point, box) ? 1 : -1;
|
||||
return geometry::covered_by(point, box, strategy) ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
@ -126,15 +126,9 @@ static inline int range_in_geometry(Geometry1 const& geometry1,
|
||||
++it;
|
||||
}
|
||||
|
||||
typename Strategy::template point_in_geometry_strategy
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type const in_strategy
|
||||
= strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
|
||||
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
result = point_in_geometry_helper<Geometry2>::apply(*it, geometry2, in_strategy);
|
||||
result = point_in_geometry_helper<Geometry2>::apply(*it, geometry2, strategy);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
@ -153,8 +147,7 @@ inline int range_in_geometry(Point1 const& first_point1,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// check a point on border of geometry1 first
|
||||
int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2,
|
||||
strategy.template get_point_in_geometry_strategy<Point1, Geometry2>());
|
||||
int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2, strategy);
|
||||
if (result == 0)
|
||||
{
|
||||
// if a point is on boundary of geometry2
|
||||
|
@ -56,8 +56,8 @@ struct ring_properties
|
||||
, parent_area(-1)
|
||||
{}
|
||||
|
||||
template <typename RingOrBox, typename AreaStrategy>
|
||||
inline ring_properties(RingOrBox const& ring_or_box, AreaStrategy const& strategy)
|
||||
template <typename RingOrBox, typename Strategy>
|
||||
inline ring_properties(RingOrBox const& ring_or_box, Strategy const& strategy)
|
||||
: reversed(false)
|
||||
, discarded(false)
|
||||
, parent_area(-1)
|
||||
|
@ -62,18 +62,18 @@ namespace dispatch
|
||||
template <typename Box>
|
||||
struct select_rings<box_tag, Box>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename Geometry, typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Box const& box, Geometry const& ,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy);
|
||||
}
|
||||
|
||||
template <typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Box const& box,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy);
|
||||
}
|
||||
@ -82,10 +82,10 @@ namespace dispatch
|
||||
template <typename Ring>
|
||||
struct select_rings<ring_tag, Ring>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename Geometry, typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Ring const& ring, Geometry const& ,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (boost::size(ring) > 0)
|
||||
{
|
||||
@ -93,10 +93,10 @@ namespace dispatch
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Ring const& ring,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (boost::size(ring) > 0)
|
||||
{
|
||||
@ -109,10 +109,10 @@ namespace dispatch
|
||||
template <typename Polygon>
|
||||
struct select_rings<polygon_tag, Polygon>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename Geometry, typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Polygon const& polygon, Geometry const& geometry,
|
||||
ring_identifier id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||
@ -129,10 +129,10 @@ namespace dispatch
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Polygon const& polygon,
|
||||
ring_identifier id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||
@ -153,10 +153,10 @@ namespace dispatch
|
||||
template <typename Multi>
|
||||
struct select_rings<multi_polygon_tag, Multi>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
template <typename Geometry, typename RingPropertyMap, typename Strategy>
|
||||
static inline void apply(Multi const& multi, Geometry const& geometry,
|
||||
ring_identifier id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
@ -321,16 +321,14 @@ inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
||||
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
||||
typedef typename geometry::point_type<Geometry2>::type point2_type;
|
||||
|
||||
|
||||
RingPropertyMap all_ring_properties;
|
||||
dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
|
||||
ring_identifier(0, -1, -1), all_ring_properties,
|
||||
strategy.template get_area_strategy<point1_type>());
|
||||
strategy);
|
||||
dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
|
||||
ring_identifier(1, -1, -1), all_ring_properties,
|
||||
strategy.template get_area_strategy<point2_type>());
|
||||
strategy);
|
||||
|
||||
update_ring_selection<OverlayType>(geometry1, geometry2, turn_info_per_ring,
|
||||
all_ring_properties, selected_ring_properties,
|
||||
@ -356,7 +354,7 @@ inline void select_rings(Geometry const& geometry,
|
||||
RingPropertyMap all_ring_properties;
|
||||
dispatch::select_rings<tag, Geometry>::apply(geometry,
|
||||
ring_identifier(0, -1, -1), all_ring_properties,
|
||||
strategy.template get_area_strategy<point_type>());
|
||||
strategy);
|
||||
|
||||
update_ring_selection<OverlayType>(geometry, geometry, turn_info_per_ring,
|
||||
all_ring_properties, selected_ring_properties,
|
||||
|
@ -63,14 +63,14 @@ template
|
||||
typename Geometry,
|
||||
typename Turns,
|
||||
typename TurnPolicy,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
struct self_section_visitor
|
||||
{
|
||||
Geometry const& m_geometry;
|
||||
IntersectionStrategy const& m_intersection_strategy;
|
||||
Strategy const& m_strategy;
|
||||
RobustPolicy const& m_rescale_policy;
|
||||
Turns& m_turns;
|
||||
InterruptPolicy& m_interrupt_policy;
|
||||
@ -78,14 +78,14 @@ struct self_section_visitor
|
||||
bool m_skip_adjacent;
|
||||
|
||||
inline self_section_visitor(Geometry const& g,
|
||||
IntersectionStrategy const& is,
|
||||
Strategy const& s,
|
||||
RobustPolicy const& rp,
|
||||
Turns& turns,
|
||||
InterruptPolicy& ip,
|
||||
int source_index,
|
||||
bool skip_adjacent)
|
||||
: m_geometry(g)
|
||||
, m_intersection_strategy(is)
|
||||
, m_strategy(s)
|
||||
, m_rescale_policy(rp)
|
||||
, m_turns(turns)
|
||||
, m_interrupt_policy(ip)
|
||||
@ -98,7 +98,7 @@ struct self_section_visitor
|
||||
{
|
||||
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
|
||||
sec2.bounding_box,
|
||||
m_intersection_strategy.get_disjoint_box_box_strategy())
|
||||
m_strategy)
|
||||
&& ! sec1.duplicate
|
||||
&& ! sec2.duplicate)
|
||||
{
|
||||
@ -112,7 +112,7 @@ struct self_section_visitor
|
||||
>::apply(m_source_index, m_geometry, sec1,
|
||||
m_source_index, m_geometry, sec2,
|
||||
false, m_skip_adjacent,
|
||||
m_intersection_strategy,
|
||||
m_strategy,
|
||||
m_rescale_policy,
|
||||
m_turns, m_interrupt_policy);
|
||||
}
|
||||
@ -127,10 +127,10 @@ struct self_section_visitor
|
||||
template <bool Reverse, typename TurnPolicy>
|
||||
struct get_turns
|
||||
{
|
||||
template <typename Geometry, typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
||||
template <typename Geometry, typename Strategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
||||
static inline bool apply(
|
||||
Geometry const& geometry,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy,
|
||||
@ -152,32 +152,23 @@ struct get_turns
|
||||
typedef std::integer_sequence<std::size_t, 0, 1> dimensions;
|
||||
|
||||
sections_type sec;
|
||||
geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy, sec,
|
||||
intersection_strategy.get_envelope_strategy(),
|
||||
intersection_strategy.get_expand_strategy());
|
||||
geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy,
|
||||
sec, strategy);
|
||||
|
||||
self_section_visitor
|
||||
<
|
||||
Reverse, Geometry,
|
||||
Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy
|
||||
> visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index, skip_adjacent);
|
||||
|
||||
typedef detail::section::get_section_box
|
||||
<
|
||||
typename IntersectionStrategy::expand_box_strategy_type
|
||||
> get_section_box_type;
|
||||
typedef detail::section::overlaps_section_box
|
||||
<
|
||||
typename IntersectionStrategy::disjoint_box_box_strategy_type
|
||||
> overlaps_section_box_type;
|
||||
Turns, TurnPolicy, Strategy, RobustPolicy, InterruptPolicy
|
||||
> visitor(geometry, strategy, robust_policy, turns, interrupt_policy,
|
||||
source_index, skip_adjacent);
|
||||
|
||||
// false if interrupted
|
||||
geometry::partition
|
||||
<
|
||||
box_type
|
||||
>::apply(sec, visitor,
|
||||
get_section_box_type(),
|
||||
overlaps_section_box_type());
|
||||
detail::section::get_section_box<Strategy>(strategy),
|
||||
detail::section::overlaps_section_box<Strategy>(strategy));
|
||||
|
||||
return ! interrupt_policy.has_intersections;
|
||||
}
|
||||
@ -340,13 +331,13 @@ template
|
||||
<
|
||||
typename AssignPolicy,
|
||||
typename Geometry,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
inline void self_turns(Geometry const& geometry,
|
||||
IntersectionStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy,
|
||||
|
@ -44,7 +44,7 @@ template
|
||||
typename Turns,
|
||||
typename TurnInfoMap,
|
||||
typename Clusters,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename Visitor,
|
||||
typename Backtrack
|
||||
@ -55,7 +55,8 @@ struct traversal_ring_creator
|
||||
<
|
||||
Reverse1, Reverse2, OverlayType,
|
||||
Geometry1, Geometry2, Turns, Clusters,
|
||||
RobustPolicy, typename IntersectionStrategy::side_strategy_type,
|
||||
RobustPolicy,
|
||||
decltype(std::declval<Strategy>().side()),
|
||||
Visitor
|
||||
> traversal_type;
|
||||
|
||||
@ -68,17 +69,16 @@ struct traversal_ring_creator
|
||||
inline traversal_ring_creator(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Turns& turns, TurnInfoMap& turn_info_map,
|
||||
Clusters const& clusters,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy, Visitor& visitor)
|
||||
: m_trav(geometry1, geometry2, turns, clusters,
|
||||
robust_policy, intersection_strategy.get_side_strategy(),
|
||||
visitor)
|
||||
robust_policy, strategy.side(), visitor)
|
||||
, m_geometry1(geometry1)
|
||||
, m_geometry2(geometry2)
|
||||
, m_turns(turns)
|
||||
, m_turn_info_map(turn_info_map)
|
||||
, m_clusters(clusters)
|
||||
, m_intersection_strategy(intersection_strategy)
|
||||
, m_strategy(strategy)
|
||||
, m_robust_policy(robust_policy)
|
||||
, m_visitor(visitor)
|
||||
{
|
||||
@ -113,15 +113,13 @@ struct traversal_ring_creator
|
||||
{
|
||||
geometry::copy_segments<Reverse1>(m_geometry1,
|
||||
previous_op.seg_id, to_vertex_index,
|
||||
m_intersection_strategy.get_side_strategy(),
|
||||
m_robust_policy, current_ring);
|
||||
m_strategy, m_robust_policy, current_ring);
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry::copy_segments<Reverse2>(m_geometry2,
|
||||
previous_op.seg_id, to_vertex_index,
|
||||
m_intersection_strategy.get_side_strategy(),
|
||||
m_robust_policy, current_ring);
|
||||
m_strategy, m_robust_policy, current_ring);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,8 +162,7 @@ struct traversal_ring_creator
|
||||
turn_type& current_turn = m_turns[turn_index];
|
||||
turn_operation_type& op = current_turn.operations[op_index];
|
||||
detail::overlay::append_no_collinear(current_ring, current_turn.point,
|
||||
m_intersection_strategy.get_side_strategy(),
|
||||
m_robust_policy);
|
||||
m_strategy, m_robust_policy);
|
||||
|
||||
// Register the visit
|
||||
m_trav.set_visited(current_turn, op);
|
||||
@ -182,8 +179,7 @@ struct traversal_ring_creator
|
||||
turn_operation_type& start_op = m_turns[start_turn_index].operations[start_op_index];
|
||||
|
||||
detail::overlay::append_no_collinear(ring, start_turn.point,
|
||||
m_intersection_strategy.get_side_strategy(),
|
||||
m_robust_policy);
|
||||
m_strategy, m_robust_policy);
|
||||
|
||||
signed_size_type current_turn_index = start_turn_index;
|
||||
int current_op_index = start_op_index;
|
||||
@ -286,9 +282,7 @@ struct traversal_ring_creator
|
||||
|
||||
if (geometry::num_points(ring) >= min_num_points)
|
||||
{
|
||||
clean_closing_dups_and_spikes(ring,
|
||||
m_intersection_strategy.get_side_strategy(),
|
||||
m_robust_policy);
|
||||
clean_closing_dups_and_spikes(ring, m_strategy, m_robust_policy);
|
||||
rings.push_back(ring);
|
||||
|
||||
m_trav.finalize_visit_info(m_turn_info_map);
|
||||
@ -297,14 +291,13 @@ struct traversal_ring_creator
|
||||
}
|
||||
else
|
||||
{
|
||||
Backtrack::apply(
|
||||
finalized_ring_size,
|
||||
rings, ring, m_turns, start_turn,
|
||||
m_turns[turn_index].operations[op_index],
|
||||
traverse_error,
|
||||
m_geometry1, m_geometry2,
|
||||
m_intersection_strategy, m_robust_policy,
|
||||
state, m_visitor);
|
||||
Backtrack::apply(finalized_ring_size,
|
||||
rings, ring, m_turns, start_turn,
|
||||
m_turns[turn_index].operations[op_index],
|
||||
traverse_error,
|
||||
m_geometry1, m_geometry2,
|
||||
m_strategy, m_robust_policy,
|
||||
state, m_visitor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,7 +406,7 @@ private:
|
||||
Turns& m_turns;
|
||||
TurnInfoMap& m_turn_info_map; // contains turn-info information per ring
|
||||
Clusters const& m_clusters;
|
||||
IntersectionStrategy const& m_intersection_strategy;
|
||||
Strategy const& m_strategy;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
Visitor& m_visitor;
|
||||
};
|
||||
|
@ -209,10 +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, typename IntersectionStrategy>
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Result & result,
|
||||
IntersectionStrategy const& intersection_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: If Areal geometry may have infinite size, change the following line:
|
||||
|
||||
@ -226,38 +226,25 @@ struct areal_areal
|
||||
typedef typename turns::get_turns
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::template turn_info_type<IntersectionStrategy>::type turn_type;
|
||||
>::template turn_info_type<Strategy>::type turn_type;
|
||||
std::vector<turn_type> turns;
|
||||
|
||||
interrupt_policy_areal_areal<Result> interrupt_policy(geometry1, geometry2, result);
|
||||
|
||||
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
|
||||
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, strategy);
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
return;
|
||||
|
||||
typedef typename IntersectionStrategy::cs_tag cs_tag;
|
||||
typedef typename Strategy::cs_tag cs_tag;
|
||||
|
||||
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);
|
||||
no_turns_aa_pred<Geometry2, Result, Strategy, false>
|
||||
pred1(geometry2, result, strategy);
|
||||
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, point_in_areal_strategy21_type, true>
|
||||
pred2(geometry1, result, point_in_areal_strategy21);
|
||||
no_turns_aa_pred<Geometry1, Result, Strategy, true>
|
||||
pred2(geometry1, result, strategy);
|
||||
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
return;
|
||||
@ -282,8 +269,7 @@ struct areal_areal
|
||||
{
|
||||
// analyse sorted turns
|
||||
turns_analyser<turn_type, 0> analyser;
|
||||
analyse_each_turn(result, analyser, turns.begin(), turns.end(),
|
||||
point_in_areal_strategy12.get_equals_point_point_strategy());
|
||||
analyse_each_turn(result, analyser, turns.begin(), turns.end(), strategy);
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
return;
|
||||
@ -297,8 +283,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, point_in_areal_strategy12_type>
|
||||
rings_analyser(result, geometry1, geometry2, point_in_areal_strategy12);
|
||||
uncertain_rings_analyser<0, Result, Geometry1, Geometry2, Strategy>
|
||||
rings_analyser(result, geometry1, geometry2, strategy);
|
||||
analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
@ -323,8 +309,7 @@ struct areal_areal
|
||||
{
|
||||
// analyse sorted turns
|
||||
turns_analyser<turn_type, 1> analyser;
|
||||
analyse_each_turn(result, analyser, turns.begin(), turns.end(),
|
||||
point_in_areal_strategy21.get_equals_point_point_strategy());
|
||||
analyse_each_turn(result, analyser, turns.begin(), turns.end(), strategy);
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
return;
|
||||
@ -338,8 +323,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, point_in_areal_strategy21_type>
|
||||
rings_analyser(result, geometry2, geometry1, point_in_areal_strategy21);
|
||||
uncertain_rings_analyser<1, Result, Geometry2, Geometry1, Strategy>
|
||||
rings_analyser(result, geometry2, geometry1, strategy);
|
||||
analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end());
|
||||
|
||||
//if ( result.interrupt )
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2018 Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -30,27 +30,29 @@ namespace detail { namespace relate {
|
||||
|
||||
enum boundary_query { boundary_front, boundary_back, boundary_any };
|
||||
|
||||
template <typename Geometry,
|
||||
typename WithinStrategy, // Point/Point equals (within) strategy
|
||||
typename Tag = typename geometry::tag<Geometry>::type>
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy,
|
||||
typename Tag = typename geometry::tag<Geometry>::type
|
||||
>
|
||||
class boundary_checker {};
|
||||
|
||||
template <typename Geometry, typename WithinStrategy>
|
||||
class boundary_checker<Geometry, WithinStrategy, linestring_tag>
|
||||
template <typename Geometry, typename Strategy>
|
||||
class boundary_checker<Geometry, Strategy, linestring_tag>
|
||||
{
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
public:
|
||||
typedef WithinStrategy equals_strategy_type;
|
||||
|
||||
boundary_checker(Geometry const& g)
|
||||
: has_boundary( boost::size(g) >= 2
|
||||
&& !detail::equals::equals_point_point(range::front(g),
|
||||
range::back(g),
|
||||
equals_strategy_type()) )
|
||||
boundary_checker(Geometry const& g, Strategy const& s)
|
||||
: m_has_boundary( boost::size(g) >= 2
|
||||
&& ! detail::equals::equals_point_point(range::front(g),
|
||||
range::back(g),
|
||||
s) )
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
||||
, geometry(g)
|
||||
, m_geometry(g)
|
||||
#endif
|
||||
, m_strategy(s)
|
||||
{}
|
||||
|
||||
template <boundary_query BoundaryQuery>
|
||||
@ -60,30 +62,34 @@ public:
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
||||
// may give false positives for INT
|
||||
BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
|
||||
&& detail::equals::equals_point_point(pt, range::front(geometry), WithinStrategy())
|
||||
&& detail::equals::equals_point_point(pt, range::front(m_geometry), m_strategy)
|
||||
|| (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
|
||||
&& detail::equals::equals_point_point(pt, range::back(geometry), WithinStrategy()) );
|
||||
&& detail::equals::equals_point_point(pt, range::back(m_geometry), m_strategy) );
|
||||
#endif
|
||||
return has_boundary;
|
||||
return m_has_boundary;
|
||||
}
|
||||
|
||||
Strategy const& strategy() const
|
||||
{
|
||||
return m_strategy;
|
||||
}
|
||||
|
||||
private:
|
||||
bool has_boundary;
|
||||
bool m_has_boundary;
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
||||
Geometry const& geometry;
|
||||
Geometry const& m_geometry;
|
||||
#endif
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename Geometry, typename WithinStrategy>
|
||||
class boundary_checker<Geometry, WithinStrategy, multi_linestring_tag>
|
||||
template <typename Geometry, typename Strategy>
|
||||
class boundary_checker<Geometry, Strategy, multi_linestring_tag>
|
||||
{
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
public:
|
||||
typedef WithinStrategy equals_strategy_type;
|
||||
|
||||
boundary_checker(Geometry const& g)
|
||||
: is_filled(false), geometry(g)
|
||||
boundary_checker(Geometry const& g, Strategy const& s)
|
||||
: m_is_filled(false), m_geometry(g), m_strategy(s)
|
||||
{}
|
||||
|
||||
// First call O(NlogN)
|
||||
@ -91,22 +97,22 @@ public:
|
||||
template <boundary_query BoundaryQuery>
|
||||
bool is_endpoint_boundary(point_type const& pt) const
|
||||
{
|
||||
typedef geometry::less<point_type, -1, typename WithinStrategy::cs_tag> less_type;
|
||||
typedef geometry::less<point_type, -1, typename Strategy::cs_tag> less_type;
|
||||
|
||||
typedef typename boost::range_size<Geometry>::type size_type;
|
||||
size_type multi_count = boost::size(geometry);
|
||||
size_type multi_count = boost::size(m_geometry);
|
||||
|
||||
if ( multi_count < 1 )
|
||||
return false;
|
||||
|
||||
if ( ! is_filled )
|
||||
if ( ! m_is_filled )
|
||||
{
|
||||
//boundary_points.clear();
|
||||
boundary_points.reserve(multi_count * 2);
|
||||
m_boundary_points.reserve(multi_count * 2);
|
||||
|
||||
typedef typename boost::range_iterator<Geometry const>::type multi_iterator;
|
||||
for ( multi_iterator it = boost::begin(geometry) ;
|
||||
it != boost::end(geometry) ; ++ it )
|
||||
for ( multi_iterator it = boost::begin(m_geometry) ;
|
||||
it != boost::end(m_geometry) ; ++ it )
|
||||
{
|
||||
typename boost::range_reference<Geometry const>::type
|
||||
ls = *it;
|
||||
@ -126,33 +132,33 @@ public:
|
||||
point_reference back_pt = range::back(ls);
|
||||
|
||||
// linear ring or point - no boundary
|
||||
if (! equals::equals_point_point(front_pt, back_pt, equals_strategy_type()))
|
||||
if (! equals::equals_point_point(front_pt, back_pt, m_strategy))
|
||||
{
|
||||
// do not add points containing NaN coordinates
|
||||
// because they cannot be reasonably compared, e.g. with MSVC
|
||||
// an assertion failure is reported in std::equal_range()
|
||||
if (! geometry::has_nan_coordinate(front_pt))
|
||||
{
|
||||
boundary_points.push_back(front_pt);
|
||||
m_boundary_points.push_back(front_pt);
|
||||
}
|
||||
if (! geometry::has_nan_coordinate(back_pt))
|
||||
{
|
||||
boundary_points.push_back(back_pt);
|
||||
m_boundary_points.push_back(back_pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(boundary_points.begin(),
|
||||
boundary_points.end(),
|
||||
std::sort(m_boundary_points.begin(),
|
||||
m_boundary_points.end(),
|
||||
less_type());
|
||||
|
||||
is_filled = true;
|
||||
m_is_filled = true;
|
||||
}
|
||||
|
||||
std::size_t equal_points_count
|
||||
= boost::size(
|
||||
std::equal_range(boundary_points.begin(),
|
||||
boundary_points.end(),
|
||||
std::equal_range(m_boundary_points.begin(),
|
||||
m_boundary_points.end(),
|
||||
pt,
|
||||
less_type())
|
||||
);
|
||||
@ -160,12 +166,18 @@ public:
|
||||
return equal_points_count % 2 != 0;// && equal_points_count > 0; // the number is odd and > 0
|
||||
}
|
||||
|
||||
private:
|
||||
mutable bool is_filled;
|
||||
// TODO: store references/pointers instead of points?
|
||||
mutable std::vector<point_type> boundary_points;
|
||||
Strategy const& strategy() const
|
||||
{
|
||||
return m_strategy;
|
||||
}
|
||||
|
||||
Geometry const& geometry;
|
||||
private:
|
||||
mutable bool m_is_filled;
|
||||
// TODO: store references/pointers instead of points?
|
||||
mutable std::vector<point_type> m_boundary_points;
|
||||
|
||||
Geometry const& m_geometry;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
}} // namespace detail::relate
|
||||
|
@ -341,9 +341,9 @@ private:
|
||||
std::vector<point_info> m_other_entry_points; // TODO: use map here or sorted vector?
|
||||
};
|
||||
|
||||
template <std::size_t OpId, typename Turn, typename EqPPStrategy>
|
||||
template <std::size_t OpId, typename Turn, typename Strategy>
|
||||
inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
segment_identifier const& prev_seg_id = prev_turn.operations[OpId].seg_id;
|
||||
segment_identifier const& curr_seg_id = curr_turn.operations[OpId].seg_id;
|
||||
|
@ -29,7 +29,8 @@
|
||||
#include <boost/geometry/core/topological_dimension.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
#include <boost/geometry/util/sequence.hpp>
|
||||
#include <boost/geometry/util/type_traits.hpp>
|
||||
|
||||
@ -161,9 +162,15 @@ struct result_handler_type<Geometry1, Geometry2, util::type_sequence<StaticMasks
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename ResultHandler, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2, typename ResultHandler>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
ResultHandler & handler,
|
||||
@ -175,14 +182,37 @@ struct relate
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, handler, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct relate<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename ResultHandler>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
ResultHandler & handler,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
dispatch::relate
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, handler,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct relate<default_strategy, false>
|
||||
{
|
||||
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
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
@ -220,7 +250,7 @@ struct relate
|
||||
Mask
|
||||
>::type handler(mask);
|
||||
|
||||
resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
|
||||
resolve_strategy::relate<Strategy>::apply(geometry1, geometry2, handler, strategy);
|
||||
|
||||
return handler.result();
|
||||
}
|
||||
|
@ -229,10 +229,10 @@ struct linear_areal
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Result, typename IntersectionStrategy>
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Result & result,
|
||||
IntersectionStrategy const& intersection_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: If Areal geometry may have infinite size, change the following line:
|
||||
|
||||
@ -243,38 +243,34 @@ struct linear_areal
|
||||
return;
|
||||
|
||||
// get and analyse turns
|
||||
typedef typename turn_info_type<Geometry1, Geometry2, IntersectionStrategy>::type turn_type;
|
||||
typedef typename turn_info_type<Geometry1, Geometry2, Strategy>::type turn_type;
|
||||
std::vector<turn_type> turns;
|
||||
|
||||
interrupt_policy_linear_areal<Geometry2, Result> interrupt_policy(geometry2, result);
|
||||
|
||||
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
|
||||
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy, strategy);
|
||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||
return;
|
||||
|
||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy<Geometry1, Geometry2>::type within_strategy_type;
|
||||
within_strategy_type const within_strategy = intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
|
||||
|
||||
typedef typename IntersectionStrategy::cs_tag cs_tag;
|
||||
typedef typename within_strategy_type::equals_point_point_strategy_type eq_pp_strategy_type;
|
||||
typedef typename Strategy::cs_tag cs_tag;
|
||||
|
||||
typedef boundary_checker
|
||||
<
|
||||
Geometry1,
|
||||
eq_pp_strategy_type
|
||||
Strategy
|
||||
> boundary_checker1_type;
|
||||
boundary_checker1_type boundary_checker1(geometry1);
|
||||
boundary_checker1_type boundary_checker1(geometry1, strategy);
|
||||
|
||||
no_turns_la_linestring_pred
|
||||
<
|
||||
Geometry2,
|
||||
Result,
|
||||
within_strategy_type,
|
||||
Strategy,
|
||||
boundary_checker1_type,
|
||||
TransposeResult
|
||||
> pred1(geometry2,
|
||||
result,
|
||||
within_strategy,
|
||||
strategy,
|
||||
boundary_checker1);
|
||||
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||
@ -302,7 +298,7 @@ struct linear_areal
|
||||
turns.begin(), turns.end(),
|
||||
geometry1, geometry2,
|
||||
boundary_checker1,
|
||||
intersection_strategy.get_side_strategy());
|
||||
strategy);
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||
return;
|
||||
@ -395,14 +391,12 @@ struct linear_areal
|
||||
typedef turns::less<1, turns::less_op_areal_linear<1>, cs_tag> less;
|
||||
std::sort(it, next, less());
|
||||
|
||||
eq_pp_strategy_type const eq_pp_strategy = within_strategy.get_equals_point_point_strategy();
|
||||
|
||||
// analyse
|
||||
areal_boundary_analyser<turn_type> analyser;
|
||||
for ( turn_iterator rit = it ; rit != next ; ++rit )
|
||||
{
|
||||
// if the analyser requests, break the search
|
||||
if ( !analyser.apply(it, rit, next, eq_pp_strategy) )
|
||||
if ( !analyser.apply(it, rit, next, strategy) )
|
||||
break;
|
||||
}
|
||||
|
||||
@ -626,18 +620,20 @@ struct linear_areal
|
||||
static const std::size_t other_op_id = 1;
|
||||
|
||||
template <typename TurnPointCSTag, typename PointP, typename PointQ,
|
||||
typename SideStrategy,
|
||||
typename Strategy,
|
||||
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
|
||||
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
|
||||
>
|
||||
struct la_side_calculator
|
||||
{
|
||||
typedef decltype(std::declval<Strategy>().side()) side_strategy_type;
|
||||
|
||||
inline la_side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
|
||||
Qi const& qi, Qj const& qj, Qk const& qk,
|
||||
SideStrategy const& side_strategy)
|
||||
Qi const& qi, Qj const& qj, Qk const& qk,
|
||||
Strategy const& strategy)
|
||||
: m_pi(pi), m_pj(pj), m_pk(pk)
|
||||
, m_qi(qi), m_qj(qj), m_qk(qk)
|
||||
, m_side_strategy(side_strategy)
|
||||
, m_side_strategy(strategy.side())
|
||||
{}
|
||||
|
||||
inline int pk_wrt_p1() const { return m_side_strategy.apply(m_pi, m_pj, m_pk); }
|
||||
@ -652,7 +648,7 @@ struct linear_areal
|
||||
Qj const& m_qj;
|
||||
Qk const& m_qk;
|
||||
|
||||
SideStrategy m_side_strategy;
|
||||
side_strategy_type m_side_strategy;
|
||||
};
|
||||
|
||||
|
||||
@ -672,12 +668,12 @@ struct linear_areal
|
||||
typename Geometry,
|
||||
typename OtherGeometry,
|
||||
typename BoundaryChecker,
|
||||
typename SideStrategy>
|
||||
typename Strategy>
|
||||
void apply(Result & res, TurnIt it,
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& other_geometry,
|
||||
BoundaryChecker const& boundary_checker,
|
||||
SideStrategy const& side_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
overlay::operation_type op = it->operations[op_id].operation;
|
||||
|
||||
@ -706,7 +702,7 @@ struct linear_areal
|
||||
// real exit point - may be multiple
|
||||
// we know that we entered and now we exit
|
||||
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
|
||||
side_strategy.get_equals_point_point_strategy()) )
|
||||
strategy) )
|
||||
{
|
||||
m_exit_watcher.reset_detected_exit();
|
||||
|
||||
@ -749,7 +745,7 @@ struct linear_areal
|
||||
if ( ( op == overlay::operation_intersection
|
||||
|| op == overlay::operation_continue )
|
||||
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
|
||||
side_strategy.get_equals_point_point_strategy()) )
|
||||
strategy) )
|
||||
{
|
||||
fake_enter_detected = true;
|
||||
}
|
||||
@ -770,7 +766,7 @@ struct linear_areal
|
||||
|| seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry
|
||||
|| ( m_previous_operation == overlay::operation_union
|
||||
&& ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
|
||||
side_strategy.get_equals_point_point_strategy()) )
|
||||
strategy) )
|
||||
)
|
||||
{
|
||||
update<interior, exterior, '1', TransposeResult>(res);
|
||||
@ -803,7 +799,7 @@ struct linear_areal
|
||||
|
||||
// real interior overlap
|
||||
if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
|
||||
side_strategy.get_equals_point_point_strategy()) )
|
||||
strategy) )
|
||||
{
|
||||
update<interior, interior, '1', TransposeResult>(res);
|
||||
m_interior_detected = false;
|
||||
@ -919,7 +915,7 @@ struct linear_areal
|
||||
&& calculate_from_inside(geometry,
|
||||
other_geometry,
|
||||
*it,
|
||||
side_strategy);
|
||||
strategy);
|
||||
|
||||
if ( from_inside )
|
||||
update<interior, interior, '1', TransposeResult>(res);
|
||||
@ -1020,7 +1016,7 @@ struct linear_areal
|
||||
&& calculate_from_inside(geometry,
|
||||
other_geometry,
|
||||
*it,
|
||||
side_strategy);
|
||||
strategy);
|
||||
if ( first_from_inside )
|
||||
{
|
||||
update<interior, interior, '1', TransposeResult>(res);
|
||||
@ -1208,11 +1204,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, typename SideStrategy>
|
||||
template <typename Turn, typename Strategy>
|
||||
static inline bool calculate_from_inside(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Turn const& turn,
|
||||
SideStrategy const& side_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename cs_tag<typename Turn::point_type>::type cs_tag;
|
||||
|
||||
@ -1242,7 +1238,7 @@ struct linear_areal
|
||||
point2_type const& qj = range::at(range2, q_seg_ij + 1);
|
||||
point1_type qi_conv;
|
||||
geometry::convert(qi, qi_conv);
|
||||
bool const is_ip_qj = equals::equals_point_point(turn.point, qj, side_strategy.get_equals_point_point_strategy());
|
||||
bool const is_ip_qj = equals::equals_point_point(turn.point, qj, strategy);
|
||||
// TODO: test this!
|
||||
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
|
||||
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
|
||||
@ -1257,11 +1253,11 @@ struct linear_areal
|
||||
range2_iterator qk_it = find_next_non_duplicated(boost::begin(range2),
|
||||
range::pos(range2, q_seg_jk),
|
||||
boost::end(range2),
|
||||
side_strategy.get_equals_point_point_strategy());
|
||||
strategy);
|
||||
|
||||
// Will this sequence of points be always correct?
|
||||
la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
|
||||
side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, side_strategy);
|
||||
la_side_calculator<cs_tag, point1_type, point2_type, Strategy>
|
||||
side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, strategy);
|
||||
|
||||
return calculate_from_inside_sides(side_calc);
|
||||
}
|
||||
@ -1270,16 +1266,16 @@ struct linear_areal
|
||||
point2_type new_qj;
|
||||
geometry::convert(turn.point, new_qj);
|
||||
|
||||
la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
|
||||
side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, side_strategy);
|
||||
la_side_calculator<cs_tag, point1_type, point2_type, Strategy>
|
||||
side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, strategy);
|
||||
|
||||
return calculate_from_inside_sides(side_calc);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename It, typename EqPPStrategy>
|
||||
template <typename It, typename Strategy>
|
||||
static inline It find_next_non_duplicated(It first, It current, It last,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT( current != last );
|
||||
|
||||
@ -1340,14 +1336,14 @@ struct linear_areal
|
||||
typename Geometry,
|
||||
typename OtherGeometry,
|
||||
typename BoundaryChecker,
|
||||
typename SideStrategy>
|
||||
typename Strategy>
|
||||
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,
|
||||
SideStrategy const& side_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if ( first == last )
|
||||
return;
|
||||
@ -1357,7 +1353,7 @@ struct linear_areal
|
||||
analyser.apply(res, it,
|
||||
geometry, other_geometry,
|
||||
boundary_checker,
|
||||
side_strategy);
|
||||
strategy);
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
|
||||
return;
|
||||
@ -1437,9 +1433,9 @@ struct linear_areal
|
||||
, m_previous_turn_ptr(NULL)
|
||||
{}
|
||||
|
||||
template <typename TurnIt, typename EqPPStrategy>
|
||||
template <typename TurnIt, typename Strategy>
|
||||
bool apply(TurnIt /*first*/, TurnIt it, TurnIt last,
|
||||
EqPPStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
overlay::operation_type op = it->operations[1].operation;
|
||||
|
||||
@ -1493,12 +1489,12 @@ struct areal_linear
|
||||
|
||||
static const bool interruption_enabled = linear_areal_type::interruption_enabled;
|
||||
|
||||
template <typename Result, typename IntersectionStrategy>
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Result & result,
|
||||
IntersectionStrategy const& intersection_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
linear_areal_type::apply(geometry2, geometry1, result, intersection_strategy);
|
||||
linear_areal_type::apply(geometry2, geometry1, result, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -42,8 +42,6 @@ namespace detail { namespace relate {
|
||||
template <typename Result, typename BoundaryChecker, bool TransposeResult>
|
||||
class disjoint_linestring_pred
|
||||
{
|
||||
typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
|
||||
|
||||
public:
|
||||
disjoint_linestring_pred(Result & res,
|
||||
BoundaryChecker const& boundary_checker)
|
||||
@ -83,7 +81,7 @@ public:
|
||||
if ( count == 2
|
||||
&& equals::equals_point_point(range::front(linestring),
|
||||
range::back(linestring),
|
||||
equals_strategy_type()) )
|
||||
m_boundary_checker.strategy()) )
|
||||
{
|
||||
update<interior, exterior, '0', TransposeResult>(m_result);
|
||||
}
|
||||
@ -122,12 +120,12 @@ struct linear_linear
|
||||
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
||||
typedef typename geometry::point_type<Geometry2>::type point2_type;
|
||||
|
||||
template <typename Result, typename IntersectionStrategy>
|
||||
template <typename Result, typename Strategy>
|
||||
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Result & result,
|
||||
IntersectionStrategy const& intersection_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename IntersectionStrategy::cs_tag cs_tag;
|
||||
typedef typename Strategy::cs_tag cs_tag;
|
||||
|
||||
// The result should be FFFFFFFFF
|
||||
relate::set<exterior, exterior, result_dimension<Geometry1>::value>(result);// FFFFFFFFd, d in [1,9] or T
|
||||
@ -138,7 +136,7 @@ struct linear_linear
|
||||
typedef typename turns::get_turns
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::template turn_info_type<IntersectionStrategy>::type turn_type;
|
||||
>::template turn_info_type<Strategy>::type turn_type;
|
||||
std::vector<turn_type> turns;
|
||||
|
||||
interrupt_policy_linear_linear<Result> interrupt_policy(result);
|
||||
@ -148,28 +146,20 @@ struct linear_linear
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
detail::get_turns::get_turn_info_type<Geometry1, Geometry2, turns::assign_policy<true> >
|
||||
>::apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy);
|
||||
>::apply(turns, geometry1, geometry2, interrupt_policy, strategy);
|
||||
|
||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||
return;
|
||||
|
||||
typedef boundary_checker
|
||||
<
|
||||
Geometry1,
|
||||
typename IntersectionStrategy::point_in_point_strategy_type
|
||||
> boundary_checker1_type;
|
||||
boundary_checker1_type boundary_checker1(geometry1);
|
||||
typedef boundary_checker<Geometry1, Strategy> boundary_checker1_type;
|
||||
boundary_checker1_type boundary_checker1(geometry1, strategy);
|
||||
disjoint_linestring_pred<Result, boundary_checker1_type, false> pred1(result, boundary_checker1);
|
||||
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||
return;
|
||||
|
||||
typedef boundary_checker
|
||||
<
|
||||
Geometry2,
|
||||
typename IntersectionStrategy::point_in_point_strategy_type
|
||||
> boundary_checker2_type;
|
||||
boundary_checker2_type boundary_checker2(geometry2);
|
||||
typedef boundary_checker<Geometry2, Strategy> boundary_checker2_type;
|
||||
boundary_checker2_type boundary_checker2(geometry2, strategy);
|
||||
disjoint_linestring_pred<Result, boundary_checker2_type, true> pred2(result, boundary_checker2);
|
||||
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
|
||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||
@ -292,8 +282,6 @@ struct linear_linear
|
||||
BoundaryChecker const& boundary_checker,
|
||||
OtherBoundaryChecker const& other_boundary_checker)
|
||||
{
|
||||
typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
|
||||
|
||||
overlay::operation_type const op = it->operations[op_id].operation;
|
||||
|
||||
segment_identifier const& seg_id = it->operations[op_id].seg_id;
|
||||
@ -345,7 +333,7 @@ struct linear_linear
|
||||
// we know that we entered and now we exit
|
||||
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
|
||||
*it,
|
||||
equals_strategy_type()) )
|
||||
boundary_checker.strategy()) )
|
||||
{
|
||||
m_exit_watcher.reset_detected_exit();
|
||||
|
||||
@ -368,7 +356,7 @@ struct linear_linear
|
||||
if ( op == overlay::operation_intersection
|
||||
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
|
||||
*it,
|
||||
equals_strategy_type()) )
|
||||
boundary_checker.strategy()) )
|
||||
{
|
||||
fake_enter_detected = true;
|
||||
}
|
||||
@ -668,14 +656,9 @@ struct linear_linear
|
||||
Geometry const& geometry,
|
||||
OtherGeometry const& other_geometry,
|
||||
BoundaryChecker const& boundary_checker,
|
||||
OtherBoundaryChecker const& /*other_boundary_checker*/,
|
||||
OtherBoundaryChecker const& other_boundary_checker,
|
||||
bool first_in_range)
|
||||
{
|
||||
typedef typename BoundaryChecker::equals_strategy_type
|
||||
equals_strategy1_type;
|
||||
typedef typename OtherBoundaryChecker::equals_strategy_type
|
||||
equals_strategy2_type;
|
||||
|
||||
typename detail::single_geometry_return_type<Geometry const>::type
|
||||
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
|
||||
typename detail::single_geometry_return_type<OtherGeometry const>::type
|
||||
@ -745,11 +728,11 @@ struct linear_linear
|
||||
bool const is_point1 = boost::size(ls1_ref) == 2
|
||||
&& equals::equals_point_point(range::front(ls1_ref),
|
||||
range::back(ls1_ref),
|
||||
equals_strategy1_type());
|
||||
boundary_checker.strategy());
|
||||
bool const is_point2 = boost::size(ls2_ref) == 2
|
||||
&& equals::equals_point_point(range::front(ls2_ref),
|
||||
range::back(ls2_ref),
|
||||
equals_strategy2_type());
|
||||
other_boundary_checker.strategy());
|
||||
|
||||
// if the second one is degenerated
|
||||
if ( !is_point1 && is_point2 )
|
||||
|
@ -50,21 +50,20 @@ namespace detail { namespace relate
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename EqPPStrategy,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct multi_point_geometry_eb
|
||||
{
|
||||
template <typename MultiPoint>
|
||||
template <typename MultiPoint, typename Strategy>
|
||||
static inline bool apply(MultiPoint const& ,
|
||||
detail::relate::topology_check<Geometry, EqPPStrategy> const& )
|
||||
detail::relate::topology_check<Geometry, Strategy> const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename EqPPStrategy>
|
||||
struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
||||
template <typename Geometry>
|
||||
struct multi_point_geometry_eb<Geometry, linestring_tag>
|
||||
{
|
||||
template <typename Points>
|
||||
struct boundary_visitor
|
||||
@ -74,26 +73,30 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
||||
, m_boundary_found(false)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
template <typename Point, typename Strategy>
|
||||
struct find_pred
|
||||
{
|
||||
find_pred(Point const& point)
|
||||
find_pred(Point const& point, Strategy const& strategy)
|
||||
: m_point(point)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Pt>
|
||||
bool operator()(Pt const& pt) const
|
||||
{
|
||||
return detail::equals::equals_point_point(pt, m_point, EqPPStrategy());
|
||||
return detail::equals::equals_point_point(pt, m_point, m_strategy);
|
||||
}
|
||||
|
||||
Point const& m_point;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
bool apply(Point const& boundary_point)
|
||||
template <typename Point, typename Strategy>
|
||||
bool apply(Point const& boundary_point, Strategy const& strategy)
|
||||
{
|
||||
if (std::find_if(m_points.begin(), m_points.end(), find_pred<Point>(boundary_point)) == m_points.end())
|
||||
if ( std::find_if(m_points.begin(), m_points.end(),
|
||||
find_pred<Point, Strategy>(boundary_point, strategy))
|
||||
== m_points.end() )
|
||||
{
|
||||
m_boundary_found = true;
|
||||
return false;
|
||||
@ -108,9 +111,9 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
||||
bool m_boundary_found;
|
||||
};
|
||||
|
||||
template <typename MultiPoint>
|
||||
template <typename MultiPoint, typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
detail::relate::topology_check<Geometry, EqPPStrategy> const& tc)
|
||||
detail::relate::topology_check<Geometry, Strategy> const& tc)
|
||||
{
|
||||
boundary_visitor<MultiPoint> visitor(multi_point);
|
||||
tc.for_each_boundary_point(visitor);
|
||||
@ -118,12 +121,9 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename EqPPStrategy>
|
||||
struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
|
||||
template <typename Geometry>
|
||||
struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
|
||||
{
|
||||
// TODO: CS-specific less compare strategy derived from EqPPStrategy
|
||||
typedef geometry::less<void, -1, typename EqPPStrategy::cs_tag> less_type;
|
||||
|
||||
template <typename Points>
|
||||
struct boundary_visitor
|
||||
{
|
||||
@ -132,10 +132,13 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
|
||||
, m_boundary_found(false)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
bool apply(Point const& boundary_point)
|
||||
template <typename Point, typename Strategy>
|
||||
bool apply(Point const& boundary_point, Strategy const&)
|
||||
{
|
||||
if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, less_type()))
|
||||
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type;
|
||||
|
||||
if (! std::binary_search(m_points.begin(), m_points.end(),
|
||||
boundary_point, less_type()) )
|
||||
{
|
||||
m_boundary_found = true;
|
||||
return false;
|
||||
@ -150,13 +153,15 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
|
||||
bool m_boundary_found;
|
||||
};
|
||||
|
||||
template <typename MultiPoint>
|
||||
template <typename MultiPoint, typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
detail::relate::topology_check<Geometry, EqPPStrategy> const& tc)
|
||||
detail::relate::topology_check<Geometry, Strategy> const& tc)
|
||||
{
|
||||
typedef typename boost::range_value<MultiPoint>::type point_type;
|
||||
typedef std::vector<point_type> points_type;
|
||||
points_type points(boost::begin(multi_point), boost::end(multi_point));
|
||||
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type;
|
||||
|
||||
points_type points(boost::begin(multi_point), boost::end(multi_point));
|
||||
std::sort(points.begin(), points.end(), less_type());
|
||||
|
||||
boundary_visitor<points_type> visitor(points);
|
||||
@ -179,11 +184,9 @@ struct multi_point_single_geometry
|
||||
{
|
||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type;
|
||||
|
||||
box2_type box2;
|
||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
||||
geometry::envelope(single_geometry, box2, strategy);
|
||||
geometry::detail::expand_by_epsilon(box2);
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
@ -197,7 +200,7 @@ struct multi_point_single_geometry
|
||||
}
|
||||
|
||||
// The default strategy is enough for Point/Box
|
||||
if (detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type()))
|
||||
if (detail::disjoint::disjoint_point_box(*it, box2, strategy))
|
||||
{
|
||||
relate::set<interior, exterior, '0', Transpose>(result);
|
||||
}
|
||||
@ -225,14 +228,12 @@ struct multi_point_single_geometry
|
||||
}
|
||||
}
|
||||
|
||||
typedef detail::relate::topology_check
|
||||
<
|
||||
SingleGeometry, eq_pp_strategy_type
|
||||
> tc_t;
|
||||
typedef detail::relate::topology_check<SingleGeometry, Strategy> tc_t;
|
||||
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
||||
{
|
||||
tc_t tc(single_geometry);
|
||||
tc_t tc(single_geometry, strategy);
|
||||
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
&& tc.has_interior() )
|
||||
@ -245,10 +246,7 @@ struct multi_point_single_geometry
|
||||
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
||||
&& tc.has_boundary() )
|
||||
{
|
||||
if (multi_point_geometry_eb
|
||||
<
|
||||
SingleGeometry, eq_pp_strategy_type
|
||||
>::apply(multi_point, tc))
|
||||
if (multi_point_geometry_eb<SingleGeometry>::apply(multi_point, tc))
|
||||
{
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
@ -266,62 +264,88 @@ struct multi_point_single_geometry
|
||||
template <typename MultiPoint, typename MultiGeometry, bool Transpose>
|
||||
class multi_point_multi_geometry_ii_ib
|
||||
{
|
||||
template <typename ExpandPointStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_point
|
||||
{
|
||||
expand_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
inline void apply(Box& total, Point const& point) const
|
||||
{
|
||||
geometry::expand(total, point, ExpandPointStrategy());
|
||||
geometry::expand(total, point, m_strategy);
|
||||
}
|
||||
|
||||
private:
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename ExpandBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct expand_box_box_pair
|
||||
{
|
||||
expand_box_box_pair(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename BoxPair>
|
||||
static inline void apply(Box& total, BoxPair const& box_pair)
|
||||
inline void apply(Box& total, BoxPair const& box_pair) const
|
||||
{
|
||||
geometry::expand(total, box_pair.first, ExpandBoxStrategy());
|
||||
geometry::expand(total, box_pair.first, m_strategy);
|
||||
}
|
||||
|
||||
private:
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
overlaps_box_point(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
inline bool apply(Box const& box, Point const& point) const
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
return ! detail::disjoint::disjoint_point_box(point, box,
|
||||
DisjointPointBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
private:
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_box_box_pair
|
||||
{
|
||||
overlaps_box_box_pair(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename BoxPair>
|
||||
static inline bool apply(Box const& box, BoxPair const& box_pair)
|
||||
inline bool apply(Box const& box, BoxPair const& box_pair) const
|
||||
{
|
||||
// The default strategy is enough for Box/Box
|
||||
return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
|
||||
DisjointBoxBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
private:
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename Result, typename PtSegStrategy>
|
||||
template <typename Result, typename Strategy>
|
||||
class item_visitor_type
|
||||
{
|
||||
typedef typename PtSegStrategy::equals_point_point_strategy_type pp_strategy_type;
|
||||
typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pp_strategy_type;
|
||||
typedef detail::relate::topology_check<MultiGeometry, pp_strategy_type> topology_check_type;
|
||||
typedef detail::relate::topology_check<MultiGeometry, Strategy> topology_check_type;
|
||||
|
||||
public:
|
||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||
topology_check_type const& tc,
|
||||
Result & result,
|
||||
PtSegStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
: m_multi_geometry(multi_geometry)
|
||||
, m_tc(tc)
|
||||
, m_result(result)
|
||||
@ -332,7 +356,7 @@ class multi_point_multi_geometry_ii_ib
|
||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pp_strategy_type()))
|
||||
if (! detail::disjoint::disjoint_point_box(point, box_pair.first, m_strategy) )
|
||||
{
|
||||
typename boost::range_value<MultiGeometry>::type const&
|
||||
single = range::at(m_multi_geometry, box_pair.second);
|
||||
@ -371,7 +395,7 @@ class multi_point_multi_geometry_ii_ib
|
||||
MultiGeometry const& m_multi_geometry;
|
||||
topology_check_type const& m_tc;
|
||||
Result & m_result;
|
||||
PtSegStrategy const& m_strategy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
public:
|
||||
@ -387,46 +411,21 @@ public:
|
||||
std::vector<box_pair_type> const& boxes,
|
||||
detail::relate::topology_check
|
||||
<
|
||||
MultiGeometry,
|
||||
typename Strategy::equals_point_point_strategy_type
|
||||
MultiGeometry, Strategy
|
||||
> const& tc,
|
||||
Result & result,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
item_visitor_type<Result, Strategy> visitor(multi_geometry, tc, result, strategy);
|
||||
|
||||
typedef expand_box_point
|
||||
<
|
||||
typename Strategy::expand_point_strategy_type
|
||||
> expand_box_point_type;
|
||||
typedef overlaps_box_point
|
||||
<
|
||||
typename Strategy::disjoint_point_box_strategy_type
|
||||
> overlaps_box_point_type;
|
||||
typedef expand_box_box_pair
|
||||
<
|
||||
// TEMP - envelope umbrella strategy also contains
|
||||
// expand strategies
|
||||
decltype(strategies::envelope::services::strategy_converter
|
||||
<
|
||||
typename Strategy::envelope_strategy_type
|
||||
>::get(strategy.get_envelope_strategy())
|
||||
.expand(std::declval<box1_type>(),
|
||||
std::declval<box2_type>()))
|
||||
> expand_box_box_pair_type;
|
||||
typedef overlaps_box_box_pair
|
||||
<
|
||||
typename Strategy::disjoint_box_box_strategy_type
|
||||
> overlaps_box_box_pair_type;
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box1_type
|
||||
>::apply(multi_point, boxes, visitor,
|
||||
expand_box_point_type(),
|
||||
overlaps_box_point_type(),
|
||||
expand_box_box_pair_type(),
|
||||
overlaps_box_box_pair_type());
|
||||
expand_box_point<Strategy>(strategy),
|
||||
overlaps_box_point<Strategy>(strategy),
|
||||
expand_box_box_pair<Strategy>(strategy),
|
||||
overlaps_box_box_pair<Strategy>(strategy));
|
||||
}
|
||||
|
||||
};
|
||||
@ -451,23 +450,18 @@ struct multi_point_multi_geometry_ii_ib_ie
|
||||
std::vector<box_pair_type> const& boxes,
|
||||
detail::relate::topology_check
|
||||
<
|
||||
MultiGeometry,
|
||||
typename Strategy::equals_point_point_strategy_type
|
||||
MultiGeometry, Strategy
|
||||
> const& tc,
|
||||
Result & result,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef strategy::index::services::from_strategy
|
||||
<
|
||||
Strategy
|
||||
> index_strategy_from;
|
||||
typedef index::parameters
|
||||
<
|
||||
index::rstar<4>, typename index_strategy_from::type
|
||||
index::rstar<4>, Strategy
|
||||
> index_parameters_type;
|
||||
index::rtree<box_pair_type, index_parameters_type>
|
||||
rtree(boxes.begin(), boxes.end(),
|
||||
index_parameters_type(index::rstar<4>(), index_strategy_from::get(strategy)));
|
||||
index_parameters_type(index::rstar<4>(), strategy));
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
@ -537,22 +531,17 @@ struct multi_point_multi_geometry
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
|
||||
typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
std::size_t count2 = boost::size(multi_geometry);
|
||||
std::vector<box_pair_type> boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, envelope_strategy);
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
typedef detail::relate::topology_check<MultiGeometry, eq_pp_strategy_type> tc_t;
|
||||
tc_t tc(multi_geometry);
|
||||
typedef detail::relate::topology_check<MultiGeometry, Strategy> tc_t;
|
||||
tc_t tc(multi_geometry, strategy);
|
||||
|
||||
if ( relate::may_update<interior, interior, '0', Transpose>(result)
|
||||
|| relate::may_update<interior, boundary, '0', Transpose>(result)
|
||||
@ -590,10 +579,7 @@ struct multi_point_multi_geometry
|
||||
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
||||
&& tc.has_boundary() )
|
||||
{
|
||||
if (multi_point_geometry_eb
|
||||
<
|
||||
MultiGeometry, eq_pp_strategy_type
|
||||
>::apply(multi_point, tc))
|
||||
if (multi_point_geometry_eb<MultiGeometry>::apply(multi_point, tc))
|
||||
{
|
||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -60,11 +60,8 @@ struct point_geometry
|
||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||
return;
|
||||
|
||||
typedef detail::relate::topology_check
|
||||
<
|
||||
Geometry,
|
||||
typename Strategy::equals_point_point_strategy_type
|
||||
> tc_t;
|
||||
typedef detail::relate::topology_check<Geometry, Strategy> tc_t;
|
||||
|
||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
||||
{
|
||||
@ -79,7 +76,7 @@ struct point_geometry
|
||||
else
|
||||
{
|
||||
// check if there is a boundary in Geometry
|
||||
tc_t tc(geometry);
|
||||
tc_t tc(geometry, strategy);
|
||||
if ( tc.has_interior() )
|
||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||
if ( tc.has_boundary() )
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -28,15 +28,18 @@ namespace detail { namespace relate {
|
||||
|
||||
// TODO: change the name for e.g. something with the word "exterior"
|
||||
|
||||
template <typename Geometry,
|
||||
typename EqPPStrategy,
|
||||
typename Tag = typename geometry::tag<Geometry>::type>
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Strategy,
|
||||
typename Tag = typename geometry::tag<Geometry>::type
|
||||
>
|
||||
struct topology_check
|
||||
: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
//template <typename Point>
|
||||
//struct topology_check<Point, point_tag>
|
||||
//template <typename Point, typename Strategy>
|
||||
//struct topology_check<Point, Strategy, point_tag>
|
||||
//{
|
||||
// static const char interior = '0';
|
||||
// static const char boundary = 'F';
|
||||
@ -49,14 +52,15 @@ struct topology_check
|
||||
// topology_check(Point const&, IgnoreBoundaryPoint const&) {}
|
||||
//};
|
||||
|
||||
template <typename Linestring, typename EqPPStrategy>
|
||||
struct topology_check<Linestring, EqPPStrategy, linestring_tag>
|
||||
template <typename Linestring, typename Strategy>
|
||||
struct topology_check<Linestring, Strategy, linestring_tag>
|
||||
{
|
||||
static const char interior = '1';
|
||||
static const char boundary = '0';
|
||||
|
||||
topology_check(Linestring const& ls)
|
||||
topology_check(Linestring const& ls, Strategy const& strategy)
|
||||
: m_ls(ls)
|
||||
, m_strategy(strategy)
|
||||
, m_is_initialized(false)
|
||||
{}
|
||||
|
||||
@ -87,8 +91,8 @@ struct topology_check<Linestring, EqPPStrategy, linestring_tag>
|
||||
init();
|
||||
if (m_has_boundary)
|
||||
{
|
||||
if (visitor.apply(range::front(m_ls)))
|
||||
visitor.apply(range::back(m_ls));
|
||||
if (visitor.apply(range::front(m_ls), m_strategy))
|
||||
visitor.apply(range::back(m_ls), m_strategy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,26 +108,29 @@ private:
|
||||
m_has_boundary = count > 1
|
||||
&& ! detail::equals::equals_point_point(range::front(m_ls),
|
||||
range::back(m_ls),
|
||||
EqPPStrategy());
|
||||
m_strategy);
|
||||
|
||||
m_is_initialized = true;
|
||||
}
|
||||
|
||||
Linestring const& m_ls;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
mutable bool m_is_initialized;
|
||||
|
||||
mutable bool m_has_interior;
|
||||
mutable bool m_has_boundary;
|
||||
};
|
||||
|
||||
template <typename MultiLinestring, typename EqPPStrategy>
|
||||
struct topology_check<MultiLinestring, EqPPStrategy, multi_linestring_tag>
|
||||
template <typename MultiLinestring, typename Strategy>
|
||||
struct topology_check<MultiLinestring, Strategy, multi_linestring_tag>
|
||||
{
|
||||
static const char interior = '1';
|
||||
static const char boundary = '0';
|
||||
|
||||
topology_check(MultiLinestring const& mls)
|
||||
topology_check(MultiLinestring const& mls, Strategy const& strategy)
|
||||
: m_mls(mls)
|
||||
, m_strategy(strategy)
|
||||
, m_is_initialized(false)
|
||||
{}
|
||||
|
||||
@ -163,7 +170,7 @@ struct topology_check<MultiLinestring, EqPPStrategy, multi_linestring_tag>
|
||||
}
|
||||
|
||||
private:
|
||||
typedef geometry::less<void, -1, typename EqPPStrategy::cs_tag> less_type;
|
||||
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type;
|
||||
|
||||
void init() const
|
||||
{
|
||||
@ -198,7 +205,7 @@ private:
|
||||
point_reference back_pt = range::back(ls);
|
||||
|
||||
// don't store boundaries of linear rings, this doesn't change anything
|
||||
if (! equals::equals_point_point(front_pt, back_pt, EqPPStrategy()))
|
||||
if (! equals::equals_point_point(front_pt, back_pt, m_strategy))
|
||||
{
|
||||
// do not add points containing NaN coordinates
|
||||
// because they cannot be reasonably compared, e.g. with MSVC
|
||||
@ -236,7 +243,7 @@ private:
|
||||
}
|
||||
|
||||
template <typename It>
|
||||
static inline bool find_odd_count(It first, It last)
|
||||
inline bool find_odd_count(It first, It last) const
|
||||
{
|
||||
interrupting_visitor visitor;
|
||||
for_each_boundary_point(first, last, visitor);
|
||||
@ -248,7 +255,7 @@ private:
|
||||
bool found;
|
||||
interrupting_visitor() : found(false) {}
|
||||
template <typename Point>
|
||||
bool apply(Point const&)
|
||||
bool apply(Point const&, Strategy const&)
|
||||
{
|
||||
found = true;
|
||||
return false;
|
||||
@ -256,7 +263,7 @@ private:
|
||||
};
|
||||
|
||||
template <typename It, typename Visitor>
|
||||
static void for_each_boundary_point(It first, It last, Visitor& visitor)
|
||||
void for_each_boundary_point(It first, It last, Visitor& visitor) const
|
||||
{
|
||||
if ( first == last )
|
||||
return;
|
||||
@ -267,12 +274,12 @@ private:
|
||||
for ( ; first != last ; ++first, ++prev )
|
||||
{
|
||||
// the end of the equal points subrange
|
||||
if ( ! equals::equals_point_point(*first, *prev, EqPPStrategy()) )
|
||||
if ( ! equals::equals_point_point(*first, *prev, m_strategy) )
|
||||
{
|
||||
// odd count -> boundary
|
||||
if ( count % 2 != 0 )
|
||||
{
|
||||
if (! visitor.apply(*prev))
|
||||
if (! visitor.apply(*prev, m_strategy))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -289,12 +296,14 @@ private:
|
||||
// odd count -> boundary
|
||||
if ( count % 2 != 0 )
|
||||
{
|
||||
visitor.apply(*prev);
|
||||
visitor.apply(*prev, m_strategy);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
MultiLinestring const& m_mls;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
mutable bool m_is_initialized;
|
||||
|
||||
mutable bool m_has_interior;
|
||||
@ -313,25 +322,25 @@ struct topology_check_areal
|
||||
static bool has_boundary() { return true; }
|
||||
};
|
||||
|
||||
template <typename Ring, typename EqPPStrategy>
|
||||
struct topology_check<Ring, EqPPStrategy, ring_tag>
|
||||
template <typename Ring, typename Strategy>
|
||||
struct topology_check<Ring, Strategy, ring_tag>
|
||||
: topology_check_areal
|
||||
{
|
||||
topology_check(Ring const&) {}
|
||||
topology_check(Ring const&, Strategy const&) {}
|
||||
};
|
||||
|
||||
template <typename Polygon, typename EqPPStrategy>
|
||||
struct topology_check<Polygon, EqPPStrategy, polygon_tag>
|
||||
template <typename Polygon, typename Strategy>
|
||||
struct topology_check<Polygon, Strategy, polygon_tag>
|
||||
: topology_check_areal
|
||||
{
|
||||
topology_check(Polygon const&) {}
|
||||
topology_check(Polygon const&, Strategy const&) {}
|
||||
};
|
||||
|
||||
template <typename MultiPolygon, typename EqPPStrategy>
|
||||
struct topology_check<MultiPolygon, EqPPStrategy, multi_polygon_tag>
|
||||
template <typename MultiPolygon, typename Strategy>
|
||||
struct topology_check<MultiPolygon, Strategy, multi_polygon_tag>
|
||||
: topology_check_areal
|
||||
{
|
||||
topology_check(MultiPolygon const&) {}
|
||||
topology_check(MultiPolygon const&, Strategy const&) {}
|
||||
|
||||
template <typename Point>
|
||||
static bool check_boundary_point(Point const& ) { return true; }
|
||||
|
@ -84,43 +84,28 @@ struct get_turns
|
||||
> type;
|
||||
};
|
||||
|
||||
template <typename Turns>
|
||||
static inline void apply(Turns & turns,
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2)
|
||||
{
|
||||
detail::get_turns::no_interrupt_policy 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, typename IntersectionStrategy>
|
||||
template <typename Turns, typename InterruptPolicy, typename Strategy>
|
||||
static inline void apply(Turns & turns,
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
InterruptPolicy & interrupt_policy,
|
||||
IntersectionStrategy const& intersection_strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename robust_policy_type<IntersectionStrategy>::type robust_policy_t;
|
||||
typedef typename robust_policy_type<Strategy>::type robust_policy_t;
|
||||
|
||||
robust_policy_t robust_policy
|
||||
= geometry::get_rescale_policy<robust_policy_t>(
|
||||
geometry1, geometry2, intersection_strategy);
|
||||
geometry1, geometry2, strategy);
|
||||
|
||||
apply(turns, geometry1, geometry2, interrupt_policy, intersection_strategy, robust_policy);
|
||||
apply(turns, geometry1, geometry2, interrupt_policy, strategy, robust_policy);
|
||||
}
|
||||
|
||||
template <typename Turns, typename InterruptPolicy, typename IntersectionStrategy, typename RobustPolicy>
|
||||
template <typename Turns, typename InterruptPolicy, typename Strategy, typename RobustPolicy>
|
||||
static inline void apply(Turns & turns,
|
||||
Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
InterruptPolicy & interrupt_policy,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
static const bool reverse1 = detail::overlay::do_reverse
|
||||
@ -143,7 +128,7 @@ struct get_turns
|
||||
reverse2,
|
||||
GetTurnPolicy
|
||||
>::apply(0, geometry1, 1, geometry2,
|
||||
intersection_strategy, robust_policy,
|
||||
strategy, robust_policy,
|
||||
turns, interrupt_policy);
|
||||
}
|
||||
};
|
||||
|
@ -57,7 +57,10 @@ struct relation
|
||||
Matrix
|
||||
>::type handler;
|
||||
|
||||
resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
|
||||
resolve_strategy::relate
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, handler, strategy);
|
||||
|
||||
return handler.result();
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2018.
|
||||
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2018-2020.
|
||||
// Modifications copyright (c) 2018-2020, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -26,28 +26,39 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace section
|
||||
{
|
||||
|
||||
template <typename ExpandBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct get_section_box
|
||||
{
|
||||
get_section_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Section>
|
||||
static inline void apply(Box& total, Section const& section)
|
||||
inline void apply(Box& total, Section const& section) const
|
||||
{
|
||||
assert_coordinate_type_equal(total, section.bounding_box);
|
||||
geometry::expand(total, section.bounding_box,
|
||||
ExpandBoxStrategy());
|
||||
geometry::expand(total, section.bounding_box, m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
template <typename Strategy>
|
||||
struct overlaps_section_box
|
||||
{
|
||||
overlaps_section_box(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Section>
|
||||
static inline bool apply(Box const& box, Section const& section)
|
||||
inline bool apply(Box const& box, Section const& section) const
|
||||
{
|
||||
assert_coordinate_type_equal(box, section.bounding_box);
|
||||
return ! detail::disjoint::disjoint_box_box(box, section.bounding_box,
|
||||
DisjointBoxBoxStrategy());
|
||||
m_strategy);
|
||||
}
|
||||
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
||||
@ -336,9 +337,9 @@ struct assign_loop<T, Count, Count>
|
||||
template <typename CSTag>
|
||||
struct box_first_in_section
|
||||
{
|
||||
template <typename Box, typename Point, typename EnvelopeStrategy>
|
||||
template <typename Box, typename Point, typename Strategy>
|
||||
static inline void apply(Box & box, Point const& prev, Point const& curr,
|
||||
EnvelopeStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
geometry::model::referring_segment<Point const> seg(prev, curr);
|
||||
geometry::envelope(seg, box, strategy);
|
||||
@ -348,12 +349,12 @@ struct box_first_in_section
|
||||
template <>
|
||||
struct box_first_in_section<cartesian_tag>
|
||||
{
|
||||
template <typename Box, typename Point, typename ExpandStrategy>
|
||||
template <typename Box, typename Point, typename Strategy>
|
||||
static inline void apply(Box & box, Point const& prev, Point const& curr,
|
||||
ExpandStrategy const& )
|
||||
Strategy const& strategy)
|
||||
{
|
||||
geometry::envelope(prev, box);
|
||||
geometry::expand(box, curr);
|
||||
geometry::envelope(prev, box, strategy);
|
||||
geometry::expand(box, curr, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -374,9 +375,9 @@ struct box_next_in_section<cartesian_tag>
|
||||
{
|
||||
template <typename Box, typename Point, typename Strategy>
|
||||
static inline void apply(Box & box, Point const& , Point const& curr,
|
||||
Strategy const& )
|
||||
Strategy const& strategy)
|
||||
{
|
||||
geometry::expand(box, curr);
|
||||
geometry::expand(box, curr, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@ -391,50 +392,17 @@ struct sectionalize_part
|
||||
static const std::size_t dimension_count
|
||||
= util::sequence_size<DimensionVector>::value;
|
||||
|
||||
template
|
||||
<
|
||||
typename Iterator,
|
||||
typename RobustPolicy,
|
||||
typename Sections
|
||||
>
|
||||
static inline void apply(Sections& sections,
|
||||
Iterator begin, Iterator end,
|
||||
RobustPolicy const& robust_policy,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
typedef typename strategy::envelope::services::default_strategy
|
||||
<
|
||||
segment_tag,
|
||||
typename cs_tag<typename Sections::box_type>::type
|
||||
>::type envelope_strategy_type;
|
||||
|
||||
typedef typename strategy::expand::services::default_strategy
|
||||
<
|
||||
segment_tag,
|
||||
typename cs_tag<typename Sections::box_type>::type
|
||||
>::type expand_strategy_type;
|
||||
|
||||
apply(sections, begin, end,
|
||||
robust_policy,
|
||||
envelope_strategy_type(),
|
||||
expand_strategy_type(),
|
||||
ring_id, max_count);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Iterator,
|
||||
typename RobustPolicy,
|
||||
typename Sections,
|
||||
typename EnvelopeStrategy,
|
||||
typename ExpandStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline void apply(Sections& sections,
|
||||
Iterator begin, Iterator end,
|
||||
RobustPolicy const& robust_policy,
|
||||
EnvelopeStrategy const& envelope_strategy,
|
||||
ExpandStrategy const& expand_strategy,
|
||||
Strategy const& strategy,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
@ -448,10 +416,10 @@ struct sectionalize_part
|
||||
);
|
||||
|
||||
typedef typename geometry::robust_point_type
|
||||
<
|
||||
Point,
|
||||
RobustPolicy
|
||||
>::type robust_point_type;
|
||||
<
|
||||
Point,
|
||||
RobustPolicy
|
||||
>::type robust_point_type;
|
||||
|
||||
std::size_t const count = std::distance(begin, end);
|
||||
if (count == 0)
|
||||
@ -552,14 +520,14 @@ struct sectionalize_part
|
||||
// In cartesian this is envelope of previous point expanded with current point
|
||||
// in non-cartesian this is envelope of a segment
|
||||
box_first_in_section<typename cs_tag<robust_point_type>::type>
|
||||
::apply(section.bounding_box, previous_robust_point, current_robust_point, envelope_strategy);
|
||||
::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// In cartesian this is expand with current point
|
||||
// in non-cartesian this is expand with a segment
|
||||
box_next_in_section<typename cs_tag<robust_point_type>::type>
|
||||
::apply(section.bounding_box, previous_robust_point, current_robust_point, expand_strategy);
|
||||
::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy);
|
||||
}
|
||||
|
||||
section.end_index = index + 1;
|
||||
@ -605,23 +573,21 @@ struct sectionalize_range
|
||||
typename Range,
|
||||
typename RobustPolicy,
|
||||
typename Sections,
|
||||
typename EnvelopeStrategy,
|
||||
typename ExpandStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline void apply(Range const& range,
|
||||
RobustPolicy const& robust_policy,
|
||||
Sections& sections,
|
||||
EnvelopeStrategy const& envelope_strategy,
|
||||
ExpandStrategy const& expand_strategy,
|
||||
Strategy const& strategy,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
typedef typename closeable_view<Range const, Closure>::type cview_type;
|
||||
typedef typename reversible_view
|
||||
<
|
||||
cview_type const,
|
||||
Reverse ? iterate_reverse : iterate_forward
|
||||
>::type view_type;
|
||||
<
|
||||
cview_type const,
|
||||
Reverse ? iterate_reverse : iterate_forward
|
||||
>::type view_type;
|
||||
|
||||
cview_type cview(range);
|
||||
view_type view(cview);
|
||||
@ -641,7 +607,7 @@ struct sectionalize_range
|
||||
|
||||
sectionalize_part<Point, DimensionVector>::apply(sections,
|
||||
boost::begin(view), boost::end(view),
|
||||
robust_policy, envelope_strategy, expand_strategy,
|
||||
robust_policy, strategy,
|
||||
ring_id, max_count);
|
||||
}
|
||||
};
|
||||
@ -658,27 +624,24 @@ struct sectionalize_polygon
|
||||
typename Polygon,
|
||||
typename RobustPolicy,
|
||||
typename Sections,
|
||||
typename EnvelopeStrategy,
|
||||
typename ExpandStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline void apply(Polygon const& poly,
|
||||
RobustPolicy const& robust_policy,
|
||||
Sections& sections,
|
||||
EnvelopeStrategy const& envelope_strategy,
|
||||
ExpandStrategy const& expand_strategy,
|
||||
Strategy const& strategy,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
typedef typename point_type<Polygon>::type point_type;
|
||||
typedef sectionalize_range
|
||||
<
|
||||
closure<Polygon>::value, Reverse,
|
||||
point_type, DimensionVector
|
||||
> per_range;
|
||||
<
|
||||
closure<Polygon>::value, Reverse, point_type, DimensionVector
|
||||
> per_range;
|
||||
|
||||
ring_id.ring_index = -1;
|
||||
per_range::apply(exterior_ring(poly), robust_policy, sections,
|
||||
envelope_strategy, expand_strategy, ring_id, max_count);
|
||||
strategy, ring_id, max_count);
|
||||
|
||||
ring_id.ring_index++;
|
||||
typename interior_return_type<Polygon const>::type
|
||||
@ -687,7 +650,7 @@ struct sectionalize_polygon
|
||||
it = boost::begin(rings); it != boost::end(rings); ++it, ++ring_id.ring_index)
|
||||
{
|
||||
per_range::apply(*it, robust_policy, sections,
|
||||
envelope_strategy, expand_strategy, ring_id, max_count);
|
||||
strategy, ring_id, max_count);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -700,14 +663,12 @@ struct sectionalize_box
|
||||
typename Box,
|
||||
typename RobustPolicy,
|
||||
typename Sections,
|
||||
typename EnvelopeStrategy,
|
||||
typename ExpandStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline void apply(Box const& box,
|
||||
RobustPolicy const& robust_policy,
|
||||
Sections& sections,
|
||||
EnvelopeStrategy const& envelope_strategy,
|
||||
ExpandStrategy const& expand_strategy,
|
||||
Strategy const& strategy,
|
||||
ring_identifier const& ring_id, std::size_t max_count)
|
||||
{
|
||||
typedef typename point_type<Box>::type point_type;
|
||||
@ -735,13 +696,10 @@ struct sectionalize_box
|
||||
// NOTE: Use cartesian envelope strategy in all coordinate systems
|
||||
// because edges of a box are not geodesic segments
|
||||
sectionalize_range
|
||||
<
|
||||
closed, false,
|
||||
point_type,
|
||||
DimensionVector
|
||||
>::apply(points, robust_policy, sections,
|
||||
envelope_strategy, expand_strategy,
|
||||
ring_id, max_count);
|
||||
<
|
||||
closed, false, point_type, DimensionVector
|
||||
>::apply(points, robust_policy, sections,
|
||||
strategy, ring_id, max_count);
|
||||
}
|
||||
};
|
||||
|
||||
@ -753,14 +711,12 @@ struct sectionalize_multi
|
||||
typename MultiGeometry,
|
||||
typename RobustPolicy,
|
||||
typename Sections,
|
||||
typename EnvelopeStrategy,
|
||||
typename ExpandStrategy
|
||||
typename Strategy
|
||||
>
|
||||
static inline void apply(MultiGeometry const& multi,
|
||||
RobustPolicy const& robust_policy,
|
||||
Sections& sections,
|
||||
EnvelopeStrategy const& envelope_strategy,
|
||||
ExpandStrategy const& expand_strategy,
|
||||
Strategy const& strategy,
|
||||
ring_identifier ring_id,
|
||||
std::size_t max_count)
|
||||
{
|
||||
@ -771,7 +727,7 @@ struct sectionalize_multi
|
||||
++it, ++ring_id.multi_index)
|
||||
{
|
||||
Policy::apply(*it, robust_policy, sections,
|
||||
envelope_strategy, expand_strategy,
|
||||
strategy,
|
||||
ring_id, max_count);
|
||||
}
|
||||
}
|
||||
@ -983,7 +939,7 @@ struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionVec
|
||||
\param geometry geometry to create sections from
|
||||
\param robust_policy policy to handle robustness issues
|
||||
\param sections structure with sections
|
||||
\param envelope_strategy strategy for envelope calculation
|
||||
\param strategy strategy for envelope calculation
|
||||
\param expand_strategy strategy for partitions
|
||||
\param source_index index to assign to the ring_identifiers
|
||||
\param max_count maximal number of points per section
|
||||
@ -997,19 +953,15 @@ template
|
||||
typename Geometry,
|
||||
typename Sections,
|
||||
typename RobustPolicy,
|
||||
typename EnvelopeStrategy,
|
||||
typename ExpandStrategy
|
||||
typename Strategy
|
||||
>
|
||||
inline void sectionalize(Geometry const& geometry,
|
||||
RobustPolicy const& robust_policy,
|
||||
Sections& sections,
|
||||
EnvelopeStrategy const& envelope_strategy,
|
||||
ExpandStrategy const& expand_strategy,
|
||||
Strategy const& strategy,
|
||||
int source_index = 0,
|
||||
std::size_t max_count = 10)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((! std::is_fundamental<EnvelopeStrategy>::value));
|
||||
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename boost::range_value<Sections>::type section_type;
|
||||
@ -1044,10 +996,10 @@ inline void sectionalize(Geometry const& geometry,
|
||||
Reverse,
|
||||
DimensionVector
|
||||
>::apply(geometry, robust_policy, sections,
|
||||
envelope_strategy, expand_strategy,
|
||||
strategy,
|
||||
ring_id, max_count);
|
||||
|
||||
detail::sectionalize::enlarge_sections(sections, envelope_strategy);
|
||||
detail::sectionalize::enlarge_sections(sections, strategy);
|
||||
}
|
||||
|
||||
|
||||
@ -1065,29 +1017,17 @@ inline void sectionalize(Geometry const& geometry,
|
||||
int source_index = 0,
|
||||
std::size_t max_count = 10)
|
||||
{
|
||||
typedef typename strategy::envelope::services::default_strategy
|
||||
typedef typename strategies::envelope::services::default_strategy
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
typename cs_tag<Geometry>::type
|
||||
>::type envelope_strategy_type;
|
||||
|
||||
typedef typename strategy::expand::services::default_strategy
|
||||
<
|
||||
std::conditional_t
|
||||
<
|
||||
std::is_same<typename tag<Geometry>::type, box_tag>::value,
|
||||
box_tag,
|
||||
segment_tag
|
||||
>,
|
||||
typename cs_tag<Geometry>::type
|
||||
>::type expand_strategy_type;
|
||||
Geometry,
|
||||
model::box<typename point_type<Geometry>::type>
|
||||
>::type strategy_type;
|
||||
|
||||
boost::geometry::sectionalize
|
||||
<
|
||||
Reverse, DimensionVector
|
||||
>(geometry, robust_policy, sections,
|
||||
envelope_strategy_type(),
|
||||
expand_strategy_type(),
|
||||
strategy_type(),
|
||||
source_index, max_count);
|
||||
}
|
||||
|
||||
|
@ -212,29 +212,24 @@ inline bool point_on_border_within(Geometry1 const& geometry1,
|
||||
&& geometry::within(pt, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename FirstGeometry, typename SecondGeometry, typename IntersectionStrategy>
|
||||
template <typename FirstGeometry, typename SecondGeometry, typename Strategy>
|
||||
inline bool rings_containing(FirstGeometry const& geometry1,
|
||||
SecondGeometry const& geometry2,
|
||||
IntersectionStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// TODO: This will be removed when IntersectionStrategy is replaced with
|
||||
// UmbrellaStrategy
|
||||
auto const point_in_ring_strategy
|
||||
= strategy.template get_point_in_geometry_strategy<FirstGeometry, SecondGeometry>();
|
||||
|
||||
return geometry::detail::any_range_of(geometry2, [&](auto const& range)
|
||||
{
|
||||
return point_on_border_within(range, geometry1, point_in_ring_strategy);
|
||||
return point_on_border_within(range, geometry1, strategy);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct areal_areal
|
||||
{
|
||||
template <typename IntersectionStrategy>
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
IntersectionStrategy const& strategy)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||
@ -411,7 +406,7 @@ struct self_touches
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
@ -419,18 +414,19 @@ struct self_touches
|
||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> policy_type;
|
||||
|
||||
std::deque<turn_info> turns;
|
||||
detail::touches::areal_interrupt_policy policy;
|
||||
strategy_type strategy;
|
||||
// TODO: skip_adjacent should be set to false
|
||||
detail::self_get_turn_points::get_turns
|
||||
<
|
||||
false, policy_type
|
||||
>::apply(geometry, strategy, detail::no_rescale_policy(), turns, policy, 0, true);
|
||||
<
|
||||
false, policy_type
|
||||
>::apply(geometry, strategy, detail::no_rescale_policy(),
|
||||
turns, policy, 0, true);
|
||||
|
||||
return policy.result();
|
||||
}
|
||||
|
@ -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, 2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2021.
|
||||
// Modifications copyright (c) 2013-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -35,7 +35,8 @@
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -84,9 +85,14 @@ struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct touches
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@ -96,13 +102,35 @@ struct touches
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct touches<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
return dispatch::touches
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct touches<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
@ -129,7 +157,10 @@ struct touches
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return resolve_strategy::touches::apply(geometry1, geometry2, strategy);
|
||||
return resolve_strategy::touches
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -88,8 +88,7 @@ struct within<Point, Box, point_tag, box_tag>
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused(strategy);
|
||||
return strategy.apply(point, box);
|
||||
return strategy.within(point, box).apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
@ -100,8 +99,7 @@ struct within<Box1, Box2, box_tag, box_tag>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
boost::ignore_unused(strategy);
|
||||
return strategy.apply(box1, box2);
|
||||
return strategy.within(box1, box2).apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4,9 +4,8 @@
|
||||
// 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, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2013-2021.
|
||||
// Modifications copyright (c) 2013-2021 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
|
||||
@ -34,7 +33,8 @@
|
||||
#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/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -63,30 +63,63 @@ struct within
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct within
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::within::check<Geometry1, Geometry2, Strategy>();
|
||||
|
||||
return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
return dispatch::within
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct within<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
return within
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct within<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::within::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy_type());
|
||||
return within
|
||||
<
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,9 +141,10 @@ struct within
|
||||
concepts::check<Geometry2 const>();
|
||||
assert_dimension_equal<Geometry1, Geometry2>();
|
||||
|
||||
return resolve_strategy::within::apply(geometry1,
|
||||
geometry2,
|
||||
strategy);
|
||||
return resolve_strategy::within
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2017-2020, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -54,10 +53,12 @@ struct multi_point_point
|
||||
Point const& point,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
auto const s = strategy.relate(multi_point, point);
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
if (! strategy.apply(*it, point))
|
||||
if (! s.apply(*it, point))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -126,11 +127,9 @@ struct multi_point_single_geometry
|
||||
|
||||
// Create envelope of geometry
|
||||
box2_type box;
|
||||
geometry::envelope(linear_or_areal, box, strategy.get_envelope_strategy());
|
||||
geometry::envelope(linear_or_areal, box, strategy);
|
||||
geometry::detail::expand_by_epsilon(box);
|
||||
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type point_in_box_type;
|
||||
|
||||
// Test each Point with envelope and then geometry if needed
|
||||
// If in the exterior, break
|
||||
bool result = false;
|
||||
@ -138,8 +137,10 @@ struct multi_point_single_geometry
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
int in_val = 0;
|
||||
typedef decltype(strategy.covered_by(*it, box)) point_in_box_type;
|
||||
|
||||
int in_val = 0;
|
||||
|
||||
// exterior of box and of geometry
|
||||
if (! point_in_box_type::apply(*it, box)
|
||||
|| (in_val = point_in_geometry(*it, linear_or_areal, strategy)) < 0)
|
||||
@ -173,9 +174,6 @@ struct multi_point_multi_geometry
|
||||
typedef model::box<point2_type> box2_type;
|
||||
static const bool is_linear = util::is_linear<LinearOrAreal>::value;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
// TODO: box pairs could be constructed on the fly, inside the rtree
|
||||
|
||||
// Prepare range of envelopes and ids
|
||||
@ -185,23 +183,16 @@ struct multi_point_multi_geometry
|
||||
box_pair_vector boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(linear_or_areal, boxes[i].first, envelope_strategy);
|
||||
geometry::envelope(linear_or_areal, boxes[i].first, strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
// Create R-tree
|
||||
typedef strategy::index::services::from_strategy
|
||||
<
|
||||
Strategy
|
||||
> index_strategy_from;
|
||||
typedef index::parameters
|
||||
<
|
||||
index::rstar<4>, typename index_strategy_from::type
|
||||
> index_parameters_type;
|
||||
typedef index::parameters<index::rstar<4>, Strategy> index_parameters_type;
|
||||
index::rtree<box_pair_type, index_parameters_type>
|
||||
rtree(boxes.begin(), boxes.end(),
|
||||
index_parameters_type(index::rstar<4>(), index_strategy_from::get(strategy)));
|
||||
index_parameters_type(index::rstar<4>(), strategy));
|
||||
|
||||
// For each point find overlapping envelopes and test corresponding single geometries
|
||||
// If a point is in the exterior break
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, 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
|
||||
@ -34,8 +33,6 @@
|
||||
|
||||
#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/relate.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
#include <boost/geometry/views/detail/normalized_view.hpp>
|
||||
@ -45,32 +42,13 @@ namespace boost { namespace geometry {
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace within {
|
||||
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
inline bool equals_point_point(Point1 const& p1, Point2 const& p2, Strategy const& strategy)
|
||||
{
|
||||
return equals::equals_point_point(p1, p2, strategy.get_equals_point_point_strategy());
|
||||
}
|
||||
|
||||
// TODO: is this needed?
|
||||
inline int check_result_type(int result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T check_result_type(T result)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Point, typename Range, typename Strategy> inline
|
||||
int point_in_range(Point const& point, Range const& range, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused(strategy);
|
||||
typename Strategy::state_type state;
|
||||
|
||||
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||
typename Strategy::state_type state;
|
||||
iterator_type it = boost::begin(range);
|
||||
iterator_type end = boost::end(range);
|
||||
|
||||
@ -82,18 +60,7 @@ int point_in_range(Point const& point, Range const& range, Strategy const& strat
|
||||
}
|
||||
}
|
||||
|
||||
return check_result_type(strategy.result(state));
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Point, typename Range>
|
||||
inline int point_in_range(Point const& point, Range const& range)
|
||||
{
|
||||
typedef typename strategy::point_in_geometry::services::default_strategy
|
||||
<
|
||||
Point, Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
return point_in_range(point, range, strategy_type());
|
||||
return strategy.result(state);
|
||||
}
|
||||
|
||||
}} // namespace detail::within
|
||||
@ -117,8 +84,8 @@ struct point_in_geometry<Point2, point_tag>
|
||||
template <typename Point1, typename Strategy> static inline
|
||||
int apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused(strategy);
|
||||
return strategy.apply(point1, point2) ? 1 : -1;
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
return strategy_type::apply(point1, point2) ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
@ -128,24 +95,23 @@ struct point_in_geometry<Segment, segment_tag>
|
||||
template <typename Point, typename Strategy> static inline
|
||||
int apply(Point const& point, Segment const& segment, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused(strategy);
|
||||
|
||||
typedef typename geometry::point_type<Segment>::type point_type;
|
||||
point_type p0, p1;
|
||||
// TODO: don't copy points
|
||||
detail::assign_point_from_index<0>(segment, p0);
|
||||
detail::assign_point_from_index<1>(segment, p1);
|
||||
|
||||
typename Strategy::state_type state;
|
||||
strategy.apply(point, p0, p1, state);
|
||||
int r = detail::within::check_result_type(strategy.result(state));
|
||||
auto const s = strategy.relate(point, segment);
|
||||
typename decltype(s)::state_type state;
|
||||
s.apply(point, p0, p1, state);
|
||||
int r = s.result(state);
|
||||
|
||||
if ( r != 0 )
|
||||
return -1; // exterior
|
||||
|
||||
// if the point is equal to the one of the terminal points
|
||||
if ( detail::within::equals_point_point(point, p0, strategy)
|
||||
|| detail::within::equals_point_point(point, p1, strategy) )
|
||||
if ( detail::equals::equals_point_point(point, p0, strategy)
|
||||
|| detail::equals::equals_point_point(point, p1, strategy) )
|
||||
return 0; // boundary
|
||||
else
|
||||
return 1; // interior
|
||||
@ -162,24 +128,37 @@ struct point_in_geometry<Linestring, linestring_tag>
|
||||
std::size_t count = boost::size(linestring);
|
||||
if ( count > 1 )
|
||||
{
|
||||
if ( detail::within::point_in_range(point, linestring, strategy) != 0 )
|
||||
if ( detail::within::point_in_range(point, linestring,
|
||||
strategy.relate(point, linestring)) != 0 )
|
||||
{
|
||||
return -1; // exterior
|
||||
}
|
||||
|
||||
typedef typename boost::range_value<Linestring>::type point_type;
|
||||
point_type const& front = range::front(linestring);
|
||||
point_type const& back = range::back(linestring);
|
||||
|
||||
// if the linestring doesn't have a boundary
|
||||
if (detail::within::equals_point_point(range::front(linestring), range::back(linestring), strategy))
|
||||
if ( detail::equals::equals_point_point(front, back, strategy) )
|
||||
{
|
||||
return 1; // interior
|
||||
}
|
||||
// else if the point is equal to the one of the terminal points
|
||||
else if (detail::within::equals_point_point(point, range::front(linestring), strategy)
|
||||
|| detail::within::equals_point_point(point, range::back(linestring), strategy))
|
||||
else if ( detail::equals::equals_point_point(point, front, strategy)
|
||||
|| detail::equals::equals_point_point(point, back, strategy) )
|
||||
{
|
||||
return 0; // boundary
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // interior
|
||||
}
|
||||
}
|
||||
// TODO: for now degenerated linestrings are ignored
|
||||
// throw an exception here?
|
||||
/*else if ( count == 1 )
|
||||
{
|
||||
if ( detail::equals::equals_point_point(point, range::front(linestring)) )
|
||||
if ( detail::equals::equals_point_point(point, front, strategy) )
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
@ -202,7 +181,8 @@ struct point_in_geometry<Ring, ring_tag>
|
||||
}
|
||||
|
||||
detail::normalized_view<Ring const> view(ring);
|
||||
return detail::within::point_in_range(point, view, strategy);
|
||||
return detail::within::point_in_range(point, view,
|
||||
strategy.relate(point, ring));
|
||||
}
|
||||
};
|
||||
|
||||
@ -309,12 +289,12 @@ struct point_in_geometry<Geometry, multi_linestring_tag>
|
||||
point_type const& back = range::back(*it);
|
||||
|
||||
// is closed_ring - no boundary
|
||||
if ( detail::within::equals_point_point(front, back, strategy) )
|
||||
if ( detail::equals::equals_point_point(front, back, strategy) )
|
||||
continue;
|
||||
|
||||
// is point on boundary
|
||||
if ( detail::within::equals_point_point(point, front, strategy)
|
||||
|| detail::within::equals_point_point(point, back, strategy) )
|
||||
if ( detail::equals::equals_point_point(point, front, strategy)
|
||||
|| detail::equals::equals_point_point(point, back, strategy) )
|
||||
{
|
||||
++boundaries;
|
||||
}
|
||||
@ -371,41 +351,18 @@ inline int point_in_geometry(Point const& point, Geometry const& geometry, Strat
|
||||
return detail_dispatch::within::point_in_geometry<Geometry>::apply(point, geometry, strategy);
|
||||
}
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
inline int point_in_geometry(Point const& point, Geometry const& geometry)
|
||||
{
|
||||
typedef typename strategy::point_in_geometry::services::default_strategy
|
||||
<
|
||||
Point, Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
return point_in_geometry(point, geometry, strategy_type());
|
||||
}
|
||||
|
||||
template <typename Point, typename Geometry, typename Strategy>
|
||||
inline bool within_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return point_in_geometry(point, geometry, strategy) > 0;
|
||||
}
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
inline bool within_point_geometry(Point const& point, Geometry const& geometry)
|
||||
{
|
||||
return point_in_geometry(point, geometry) > 0;
|
||||
}
|
||||
|
||||
template <typename Point, typename Geometry, typename Strategy>
|
||||
inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
return point_in_geometry(point, geometry, strategy) >= 0;
|
||||
}
|
||||
|
||||
template <typename Point, typename Geometry>
|
||||
inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry)
|
||||
{
|
||||
return point_in_geometry(point, geometry) >= 0;
|
||||
}
|
||||
|
||||
}} // namespace detail::within
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2017, 2019, 2020.
|
||||
// This file was modified by Oracle on 2017-2020.
|
||||
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@ -23,6 +23,8 @@
|
||||
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
@ -253,7 +255,7 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
@ -270,15 +272,14 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct difference
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection,
|
||||
typename Strategy
|
||||
>
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
@ -294,25 +295,46 @@ struct difference
|
||||
geometry::detail::output_geometry_back_inserter(output_collection),
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
>
|
||||
template <typename Strategy>
|
||||
struct difference<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
difference
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2, output_collection,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct difference<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
apply(geometry1, geometry2, output_collection, strategy_type());
|
||||
difference
|
||||
<
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, output_collection, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -331,9 +353,10 @@ struct difference
|
||||
Collection& output_collection,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
resolve_strategy::difference::apply(geometry1, geometry2,
|
||||
output_collection,
|
||||
strategy);
|
||||
resolve_strategy::difference
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, output_collection, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2015, 2017, 2019, 2020.
|
||||
// This file was modified by Oracle on 2015-2020.
|
||||
// Modifications copyright (c) 2015-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
@ -29,7 +29,8 @@
|
||||
#include <boost/geometry/geometries/multi_polygon.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
|
||||
@ -497,9 +498,9 @@ template
|
||||
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2, OutputIterator out)
|
||||
{
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type
|
||||
Geometry1, Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
|
||||
@ -511,15 +512,14 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct sym_difference
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection,
|
||||
typename Strategy
|
||||
>
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
@ -535,13 +535,31 @@ struct sym_difference
|
||||
geometry::detail::output_geometry_back_inserter(output_collection),
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
>
|
||||
template <typename Strategy>
|
||||
struct sym_difference<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
sym_difference
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2, output_collection,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct sym_difference<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
@ -552,7 +570,10 @@ struct sym_difference
|
||||
Geometry1, Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
apply(geometry1, geometry2, output_collection, strategy_type());
|
||||
sym_difference
|
||||
<
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, output_collection, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -571,9 +592,10 @@ struct sym_difference
|
||||
Collection& output_collection,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
resolve_strategy::sym_difference::apply(geometry1, geometry2,
|
||||
output_collection,
|
||||
strategy);
|
||||
resolve_strategy::sym_difference
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, output_collection, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,13 +18,15 @@
|
||||
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>
|
||||
@ -349,9 +351,9 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
|
||||
concepts::check<Geometry2 const>();
|
||||
geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
|
||||
|
||||
typename strategy::intersection::services::default_strategy
|
||||
typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type
|
||||
Geometry1, Geometry2
|
||||
>::type strategy;
|
||||
|
||||
typedef typename geometry::rescale_overlay_policy_type
|
||||
@ -377,15 +379,14 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
|
||||
|
||||
namespace resolve_strategy {
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct union_
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection,
|
||||
typename Strategy
|
||||
>
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
@ -414,25 +415,46 @@ struct union_
|
||||
geometry::detail::output_geometry_back_inserter(output_collection),
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
>
|
||||
template <typename Strategy>
|
||||
struct union_<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
union_
|
||||
<
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry1, geometry2, output_collection,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct union_<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||
static inline void apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection & output_collection,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
apply(geometry1, geometry2, output_collection, strategy_type());
|
||||
union_
|
||||
<
|
||||
strategy_type
|
||||
>::apply(geometry1, geometry2, output_collection, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -462,9 +484,10 @@ struct union_
|
||||
>::type
|
||||
>::apply();
|
||||
|
||||
resolve_strategy::union_::apply(geometry1, geometry2,
|
||||
output_collection,
|
||||
strategy);
|
||||
resolve_strategy::union_
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, output_collection, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -433,7 +433,7 @@ struct dissolver_generic
|
||||
|
||||
// There are less then 16 elements, handle them quadraticly
|
||||
|
||||
int n = boost::size(output_collection);
|
||||
std::size_t n = boost::size(output_collection);
|
||||
|
||||
for(iterator_type it1 = boost::begin(index_vector);
|
||||
it1 != boost::end(index_vector);
|
||||
@ -520,7 +520,7 @@ struct dissolver_generic
|
||||
boost::end(output_collection)),
|
||||
helper_vector,
|
||||
strategy,
|
||||
n, 1);
|
||||
static_cast<int>(n), 1);
|
||||
|
||||
return changed;
|
||||
}
|
||||
@ -577,8 +577,8 @@ struct dissolver_generic
|
||||
|
||||
std::vector<output_type> unioned_collection;
|
||||
|
||||
int size = 0, previous_size = 0;
|
||||
int n = 0;
|
||||
std::size_t size = 0, previous_size = 0;
|
||||
std::size_t n = 0;
|
||||
|
||||
bool changed = false;
|
||||
while(divide_and_conquer<1>
|
||||
|
@ -418,6 +418,72 @@ struct dissolve<Polygon, PolygonOut, Reverse, polygon_tag, polygon_tag>
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct dissolve
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry, typename RescalePolicy, typename OutputIterator,
|
||||
typename Strategy, typename Visitor
|
||||
>
|
||||
static inline OutputIterator apply(Geometry const& geometry,
|
||||
RescalePolicy const& rescale_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy,
|
||||
Visitor& visitor)
|
||||
{
|
||||
dispatch::dissolve
|
||||
<
|
||||
Geometry,
|
||||
GeometryOut,
|
||||
detail::overlay::do_reverse
|
||||
<
|
||||
geometry::point_order<Geometry>::value
|
||||
>::value
|
||||
>::apply(geometry, rescale_policy, out, strategy, visitor);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename GeometryOut, typename Strategy>
|
||||
struct dissolve<GeometryOut, Strategy, false>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry, typename RescalePolicy, typename OutputIterator,
|
||||
typename Strategy, typename Visitor
|
||||
>
|
||||
static inline OutputIterator apply(Geometry const& geometry,
|
||||
RescalePolicy const& rescale_policy,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy,
|
||||
Visitor& visitor)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
dispatch::dissolve
|
||||
<
|
||||
Geometry,
|
||||
GeometryOut,
|
||||
detail::overlay::do_reverse
|
||||
<
|
||||
geometry::point_order<Geometry>::value
|
||||
>::value
|
||||
>::apply(geometry, rescale_policy, out,
|
||||
strategy_converter<Strategy>::get(strategy),
|
||||
visitor);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
/*!
|
||||
\brief Removes self intersections from a geometry
|
||||
@ -449,9 +515,10 @@ inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
||||
concepts::check<GeometryOut>();
|
||||
|
||||
typedef typename geometry::rescale_policy_type
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type
|
||||
>::type rescale_policy_type;
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type,
|
||||
typename Strategy::cs_tag
|
||||
>::type rescale_policy_type;
|
||||
|
||||
rescale_policy_type robust_policy
|
||||
= geometry::get_rescale_policy<rescale_policy_type>(
|
||||
@ -459,15 +526,10 @@ inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
||||
|
||||
detail::overlay::overlay_null_visitor visitor;
|
||||
|
||||
return dispatch::dissolve
|
||||
<
|
||||
Geometry,
|
||||
GeometryOut,
|
||||
detail::overlay::do_reverse
|
||||
return resolve_strategy::dissolve
|
||||
<
|
||||
geometry::point_order<Geometry>::value
|
||||
>::value
|
||||
>::apply(geometry, robust_policy, out, strategy, visitor);
|
||||
GeometryOut, Strategy
|
||||
>::apply(geometry, robust_policy, out, strategy, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -492,9 +554,9 @@ template
|
||||
inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Geometry>::type
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
return dissolve_inserter<GeometryOut>(geometry, out, strategy_type());
|
||||
@ -517,9 +579,10 @@ inline void dissolve(Geometry const& geometry, Collection& output_collection,
|
||||
concepts::check<geometry_out>();
|
||||
|
||||
typedef typename geometry::rescale_policy_type
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type
|
||||
>::type rescale_policy_type;
|
||||
<
|
||||
typename geometry::point_type<Geometry>::type,
|
||||
typename Strategy::cs_tag
|
||||
>::type rescale_policy_type;
|
||||
|
||||
rescale_policy_type robust_policy
|
||||
= geometry::get_rescale_policy<rescale_policy_type>(
|
||||
@ -527,17 +590,12 @@ inline void dissolve(Geometry const& geometry, Collection& output_collection,
|
||||
|
||||
detail::overlay::overlay_null_visitor visitor;
|
||||
|
||||
dispatch::dissolve
|
||||
<
|
||||
Geometry,
|
||||
geometry_out,
|
||||
detail::overlay::do_reverse
|
||||
return resolve_strategy::dissolve
|
||||
<
|
||||
geometry::point_order<Geometry>::value
|
||||
>::value
|
||||
>::apply(geometry, robust_policy,
|
||||
std::back_inserter(output_collection),
|
||||
strategy, visitor);
|
||||
geometry_out, Strategy
|
||||
>::apply(geometry, robust_policy,
|
||||
std::back_inserter(output_collection),
|
||||
strategy, visitor);
|
||||
}
|
||||
|
||||
template
|
||||
@ -547,9 +605,9 @@ template
|
||||
>
|
||||
inline void dissolve(Geometry const& geometry, Collection& output_collection)
|
||||
{
|
||||
typedef typename strategy::intersection::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Geometry>::type
|
||||
Geometry, Geometry
|
||||
>::type strategy_type;
|
||||
|
||||
dissolve(geometry, output_collection, strategy_type());
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user