mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-12 05:51:47 +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
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421
|
# Required for compilers not available in ubuntu latest
|
||||||
sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
|
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 add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
sudo apt -q -y update
|
sudo apt -q -y update
|
||||||
sudo apt -q -y install clang-${{ matrix.version }} g++-multilib
|
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
|
- name: Install
|
||||||
run: |
|
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 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/ 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 add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
sudo apt -q -y update
|
sudo apt -q -y update
|
||||||
sudo apt -q -y install g++-${{ matrix.version }} g++-${{ matrix.version }}-multilib
|
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://www.boost.org/LICENSE_1_0.txt)
|
||||||
[](http://boost.org/libs/geometry)
|
[](http://boost.org/libs/geometry)
|
||||||
|
@ -14,6 +14,7 @@ test-suite boost-geometry-extensions-algorithms
|
|||||||
[ run distance_info.cpp ]
|
[ run distance_info.cpp ]
|
||||||
[ run connect.cpp ]
|
[ run connect.cpp ]
|
||||||
# [ run offset.cpp ]
|
# [ run offset.cpp ]
|
||||||
|
[ run parse.cpp ]
|
||||||
[ run midpoints.cpp ]
|
[ run midpoints.cpp ]
|
||||||
# [ run selected.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) 2008-2012 Bruno Lalande, Paris, France.
|
||||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2017-2020.
|
// This file was modified by Oracle on 2017-2021.
|
||||||
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
|
// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates.
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
// 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::envelope(geometry_in, box);
|
||||||
geometry::buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy));
|
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
|
GeometryIn, GeometryIn
|
||||||
>::type intersection_strategy;
|
>::type strategies;
|
||||||
|
|
||||||
rescale_policy_type rescale_policy
|
rescale_policy_type rescale_policy
|
||||||
= boost::geometry::get_rescale_policy<rescale_policy_type>(
|
= 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,
|
distance_strategy,
|
||||||
side_strategy,
|
side_strategy,
|
||||||
join_strategy,
|
join_strategy,
|
||||||
end_strategy,
|
end_strategy,
|
||||||
point_strategy,
|
point_strategy,
|
||||||
intersection_strategy,
|
strategies,
|
||||||
rescale_policy);
|
rescale_policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2014, 2017.
|
// This file was modified by Oracle on 2014-2020.
|
||||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
|
||||||
|
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -31,6 +31,8 @@
|
|||||||
#include <boost/geometry/core/access.hpp>
|
#include <boost/geometry/core/access.hpp>
|
||||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -65,9 +67,14 @@ struct crosses
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct crosses
|
struct crosses
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
@ -75,21 +82,50 @@ struct crosses
|
|||||||
concepts::check<Geometry1 const>();
|
concepts::check<Geometry1 const>();
|
||||||
concepts::check<Geometry2 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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
//typedef typename strategies::crosses::services::default_strategy
|
||||||
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
>::type strategy_type;
|
>::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,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
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.
|
// Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2017-2020.
|
// This file was modified by Oracle on 2017-2021.
|
||||||
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
|
// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates.
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
@ -921,7 +921,7 @@ template
|
|||||||
typename JoinStrategy,
|
typename JoinStrategy,
|
||||||
typename EndStrategy,
|
typename EndStrategy,
|
||||||
typename PointStrategy,
|
typename PointStrategy,
|
||||||
typename IntersectionStrategy,
|
typename Strategies,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename VisitPiecesPolicy
|
typename VisitPiecesPolicy
|
||||||
>
|
>
|
||||||
@ -931,7 +931,7 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
|
|||||||
JoinStrategy const& join_strategy,
|
JoinStrategy const& join_strategy,
|
||||||
EndStrategy const& end_strategy,
|
EndStrategy const& end_strategy,
|
||||||
PointStrategy const& point_strategy,
|
PointStrategy const& point_strategy,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategies const& strategies,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
VisitPiecesPolicy& visit_pieces_policy
|
VisitPiecesPolicy& visit_pieces_policy
|
||||||
)
|
)
|
||||||
@ -941,11 +941,11 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
|
|||||||
typedef detail::buffer::buffered_piece_collection
|
typedef detail::buffer::buffered_piece_collection
|
||||||
<
|
<
|
||||||
typename geometry::ring_type<GeometryOutput>::type,
|
typename geometry::ring_type<GeometryOutput>::type,
|
||||||
IntersectionStrategy,
|
Strategies,
|
||||||
DistanceStrategy,
|
DistanceStrategy,
|
||||||
RobustPolicy
|
RobustPolicy
|
||||||
> collection_type;
|
> 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;
|
collection_type const& const_collection = collection;
|
||||||
|
|
||||||
bool const areal = util::is_areal<GeometryInput>::value;
|
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,
|
>::apply(geometry_input, collection,
|
||||||
distance_strategy, side_strategy, join_strategy,
|
distance_strategy, side_strategy, join_strategy,
|
||||||
end_strategy, point_strategy,
|
end_strategy, point_strategy,
|
||||||
robust_policy, intersection_strategy.get_side_strategy());
|
robust_policy, strategies.side()); // pass strategies?
|
||||||
|
|
||||||
collection.get_turns();
|
collection.get_turns();
|
||||||
if (BOOST_GEOMETRY_CONDITION(areal))
|
if (BOOST_GEOMETRY_CONDITION(areal))
|
||||||
@ -1029,7 +1029,7 @@ template
|
|||||||
typename JoinStrategy,
|
typename JoinStrategy,
|
||||||
typename EndStrategy,
|
typename EndStrategy,
|
||||||
typename PointStrategy,
|
typename PointStrategy,
|
||||||
typename IntersectionStrategy,
|
typename Strategies,
|
||||||
typename RobustPolicy
|
typename RobustPolicy
|
||||||
>
|
>
|
||||||
inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator out,
|
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,
|
JoinStrategy const& join_strategy,
|
||||||
EndStrategy const& end_strategy,
|
EndStrategy const& end_strategy,
|
||||||
PointStrategy const& point_strategy,
|
PointStrategy const& point_strategy,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategies const& strategies,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
detail::buffer::visit_pieces_default_policy visitor;
|
detail::buffer::visit_pieces_default_policy visitor;
|
||||||
buffer_inserter<GeometryOutput>(geometry_input, out,
|
buffer_inserter<GeometryOutput>(geometry_input, out,
|
||||||
distance_strategy, side_strategy, join_strategy,
|
distance_strategy, side_strategy, join_strategy,
|
||||||
end_strategy, point_strategy,
|
end_strategy, point_strategy,
|
||||||
intersection_strategy, robust_policy, visitor);
|
strategies, robust_policy, visitor);
|
||||||
}
|
}
|
||||||
#endif // DOXYGEN_NO_DETAIL
|
#endif // DOXYGEN_NO_DETAIL
|
||||||
|
|
||||||
|
@ -193,30 +193,37 @@ struct buffer_less
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Strategy>
|
||||||
struct piece_get_box
|
struct piece_get_box
|
||||||
{
|
{
|
||||||
|
explicit piece_get_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Piece>
|
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);
|
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)
|
if (piece.m_piece_border.m_has_envelope)
|
||||||
{
|
{
|
||||||
geometry::expand(total, piece.m_piece_border.m_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
|
struct piece_overlaps_box
|
||||||
{
|
{
|
||||||
|
explicit piece_overlaps_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Piece>
|
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);
|
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,
|
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
|
struct turn_get_box
|
||||||
{
|
{
|
||||||
|
explicit turn_get_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Turn>
|
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);
|
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
|
struct turn_overlaps_box
|
||||||
{
|
{
|
||||||
|
explicit turn_overlaps_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Turn>
|
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);
|
assert_coordinate_type_equal(turn.point, box);
|
||||||
return ! geometry::detail::disjoint::disjoint_point_box(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
|
struct enriched_map_buffer_include_policy
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2016-2020.
|
// This file was modified by Oracle on 2016-2021.
|
||||||
// Modifications copyright (c) 2016-2020 Oracle and/or its affiliates.
|
// Modifications copyright (c) 2016-2021 Oracle and/or its affiliates.
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
@ -117,7 +117,7 @@ namespace detail { namespace buffer
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Ring,
|
typename Ring,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename DistanceStrategy,
|
typename DistanceStrategy,
|
||||||
typename RobustPolicy
|
typename RobustPolicy
|
||||||
>
|
>
|
||||||
@ -131,27 +131,6 @@ struct buffered_piece_collection
|
|||||||
|
|
||||||
typedef geometry::model::box<point_type> box_type;
|
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
|
typedef buffer_turn_info
|
||||||
<
|
<
|
||||||
point_type,
|
point_type,
|
||||||
@ -232,23 +211,23 @@ struct buffered_piece_collection
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
inline original_ring(clockwise_ring_type const& ring,
|
inline original_ring(clockwise_ring_type const& ring,
|
||||||
bool is_interior, bool has_interiors,
|
bool is_interior, bool has_interiors,
|
||||||
envelope_strategy_type const& envelope_strategy,
|
Strategy const& strategy)
|
||||||
expand_strategy_type const& expand_strategy)
|
|
||||||
: m_ring(ring)
|
: m_ring(ring)
|
||||||
, m_is_interior(is_interior)
|
, m_is_interior(is_interior)
|
||||||
, m_has_interiors(has_interiors)
|
, 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
|
// create monotonic sections in x-dimension
|
||||||
// The dimension is critical because the direction is later used
|
// The dimension is critical because the direction is later used
|
||||||
// in the optimization for within checks using winding strategy
|
// in the optimization for within checks using winding strategy
|
||||||
// and this strategy is scanning in x direction.
|
// and this strategy is scanning in x direction.
|
||||||
typedef std::integer_sequence<std::size_t, 0> dimensions;
|
typedef std::integer_sequence<std::size_t, 0> dimensions;
|
||||||
geometry::sectionalize<false, dimensions>(m_ring,
|
geometry::sectionalize
|
||||||
detail::no_rescale_policy(), m_sections,
|
<
|
||||||
envelope_strategy, expand_strategy);
|
false, dimensions
|
||||||
|
>(m_ring, detail::no_rescale_policy(), m_sections, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
clockwise_ring_type m_ring;
|
clockwise_ring_type m_ring;
|
||||||
@ -295,31 +274,18 @@ struct buffered_piece_collection
|
|||||||
|
|
||||||
cluster_type m_clusters;
|
cluster_type m_clusters;
|
||||||
|
|
||||||
IntersectionStrategy m_intersection_strategy;
|
Strategy m_strategy;
|
||||||
DistanceStrategy m_distance_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;
|
RobustPolicy const& m_robust_policy;
|
||||||
|
|
||||||
buffered_piece_collection(IntersectionStrategy const& intersection_strategy,
|
buffered_piece_collection(Strategy const& strategy,
|
||||||
DistanceStrategy const& distance_strategy,
|
DistanceStrategy const& distance_strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
: m_first_piece_index(-1)
|
: m_first_piece_index(-1)
|
||||||
, m_deflate(false)
|
, m_deflate(false)
|
||||||
, m_has_deflated(false)
|
, m_has_deflated(false)
|
||||||
, m_intersection_strategy(intersection_strategy)
|
, m_strategy(strategy)
|
||||||
, m_distance_strategy(distance_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)
|
, m_robust_policy(robust_policy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -393,8 +359,7 @@ struct buffered_piece_collection
|
|||||||
it != boost::end(m_linear_end_points);
|
it != boost::end(m_linear_end_points);
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
if (detail::equals::equals_point_point(turn.point, *it,
|
if (detail::equals::equals_point_point(turn.point, *it, m_strategy))
|
||||||
m_intersection_strategy.get_equals_point_point_strategy()))
|
|
||||||
{
|
{
|
||||||
turn.is_linear_end_point = true;
|
turn.is_linear_end_point = true;
|
||||||
}
|
}
|
||||||
@ -468,20 +433,11 @@ struct buffered_piece_collection
|
|||||||
// Check if a turn is inside any of the originals
|
// Check if a turn is inside any of the originals
|
||||||
inline void check_turn_in_original()
|
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_in_original_visitor
|
||||||
<
|
<
|
||||||
turn_vector_type,
|
turn_vector_type,
|
||||||
point_in_geometry_strategy_type
|
Strategy
|
||||||
> visitor(m_turns, m_point_in_geometry_strategy);
|
> visitor(m_turns, m_strategy);
|
||||||
|
|
||||||
geometry::partition
|
geometry::partition
|
||||||
<
|
<
|
||||||
@ -489,8 +445,10 @@ struct buffered_piece_collection
|
|||||||
include_turn_policy,
|
include_turn_policy,
|
||||||
detail::partition::include_all_policy
|
detail::partition::include_all_policy
|
||||||
>::apply(m_turns, original_rings, visitor,
|
>::apply(m_turns, original_rings, visitor,
|
||||||
turn_get_box(), turn_in_original_overlaps_box_type(),
|
turn_get_box<Strategy>(m_strategy),
|
||||||
original_get_box(), original_overlaps_box_type());
|
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();
|
bool const deflate = m_distance_strategy.negative();
|
||||||
|
|
||||||
@ -560,10 +518,11 @@ struct buffered_piece_collection
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate envelopes for piece borders
|
// 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)
|
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,
|
piece_vector_type,
|
||||||
buffered_ring_collection<buffered_ring<Ring> >,
|
buffered_ring_collection<buffered_ring<Ring> >,
|
||||||
turn_vector_type,
|
turn_vector_type,
|
||||||
IntersectionStrategy,
|
Strategy,
|
||||||
RobustPolicy
|
RobustPolicy
|
||||||
> visitor(m_pieces, offsetted_rings, m_turns,
|
> visitor(m_pieces, offsetted_rings, m_turns,
|
||||||
m_intersection_strategy, m_robust_policy);
|
m_strategy, m_robust_policy);
|
||||||
|
|
||||||
typedef detail::section::get_section_box
|
detail::sectionalize::enlarge_sections(monotonic_sections, m_strategy);
|
||||||
<
|
|
||||||
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_envelope_strategy);
|
|
||||||
geometry::partition
|
geometry::partition
|
||||||
<
|
<
|
||||||
robust_box_type
|
robust_box_type
|
||||||
>::apply(monotonic_sections, visitor,
|
>::apply(monotonic_sections, visitor,
|
||||||
get_section_box_type(),
|
detail::section::get_section_box<Strategy>(m_strategy),
|
||||||
overlaps_section_box_type());
|
detail::section::overlaps_section_box<Strategy>(m_strategy));
|
||||||
}
|
}
|
||||||
|
|
||||||
update_turn_administration();
|
update_turn_administration();
|
||||||
@ -614,21 +564,14 @@ struct buffered_piece_collection
|
|||||||
turn_vector_type, piece_vector_type, DistanceStrategy
|
turn_vector_type, piece_vector_type, DistanceStrategy
|
||||||
> visitor(m_turns, m_pieces, m_distance_strategy);
|
> 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
|
geometry::partition
|
||||||
<
|
<
|
||||||
box_type
|
box_type
|
||||||
>::apply(m_turns, m_pieces, visitor,
|
>::apply(m_turns, m_pieces, visitor,
|
||||||
turn_get_box(), turn_overlaps_box_type(),
|
turn_get_box<Strategy>(m_strategy),
|
||||||
piece_get_box(), piece_overlaps_box_type());
|
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_rings.back()
|
||||||
= original_ring(clockwise_ring,
|
= original_ring(clockwise_ring,
|
||||||
is_interior, has_interiors,
|
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.first_seg_id.segment_index,
|
||||||
boost::begin(ring) + pc.beyond_last_segment_index,
|
boost::begin(ring) + pc.beyond_last_segment_index,
|
||||||
m_robust_policy,
|
m_robust_policy,
|
||||||
|
m_strategy,
|
||||||
ring_id, 10);
|
ring_id, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,7 +986,7 @@ struct buffered_piece_collection
|
|||||||
enrich_intersection_points<false, false, overlay_buffer>(m_turns,
|
enrich_intersection_points<false, false, overlay_buffer>(m_turns,
|
||||||
m_clusters, offsetted_rings, offsetted_rings,
|
m_clusters, offsetted_rings, offsetted_rings,
|
||||||
m_robust_policy,
|
m_robust_policy,
|
||||||
m_intersection_strategy);
|
m_strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discards all rings which do have not-OK intersection points only.
|
// 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)
|
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;
|
signed_size_type count_in_original = 0;
|
||||||
|
|
||||||
// Check of the robust point of this outputted ring is in
|
// Check of the robust point of this outputted ring is in
|
||||||
@ -1085,16 +1027,13 @@ struct buffered_piece_collection
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (detail::disjoint::disjoint_point_box(point,
|
if (detail::disjoint::disjoint_point_box(point, original.m_box,m_strategy))
|
||||||
original.m_box,
|
|
||||||
d_pb_strategy_type()))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int const geometry_code
|
int const geometry_code
|
||||||
= detail::within::point_in_geometry(point,
|
= detail::within::point_in_geometry(point, original.m_ring, m_strategy);
|
||||||
original.m_ring, m_point_in_geometry_strategy);
|
|
||||||
|
|
||||||
if (geometry_code == -1)
|
if (geometry_code == -1)
|
||||||
{
|
{
|
||||||
@ -1133,7 +1072,7 @@ struct buffered_piece_collection
|
|||||||
buffered_ring<Ring>& ring = *it;
|
buffered_ring<Ring>& ring = *it;
|
||||||
if (! ring.has_intersections()
|
if (! ring.has_intersections()
|
||||||
&& boost::size(ring) > 0u
|
&& 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)))
|
if (! point_coveredby_original(geometry::range::front(ring)))
|
||||||
{
|
{
|
||||||
@ -1173,7 +1112,7 @@ struct buffered_piece_collection
|
|||||||
traversed_rings.clear();
|
traversed_rings.clear();
|
||||||
buffer_overlay_visitor visitor;
|
buffer_overlay_visitor visitor;
|
||||||
traverser::apply(offsetted_rings, offsetted_rings,
|
traverser::apply(offsetted_rings, offsetted_rings,
|
||||||
m_intersection_strategy, m_robust_policy,
|
m_strategy, m_robust_policy,
|
||||||
m_turns, traversed_rings,
|
m_turns, traversed_rings,
|
||||||
turn_info_per_ring,
|
turn_info_per_ring,
|
||||||
m_clusters, visitor);
|
m_clusters, visitor);
|
||||||
@ -1202,7 +1141,14 @@ struct buffered_piece_collection
|
|||||||
template <typename GeometryOutput, typename OutputIterator>
|
template <typename GeometryOutput, typename OutputIterator>
|
||||||
inline OutputIterator assign(OutputIterator out) const
|
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;
|
std::map<ring_identifier, properties> selected;
|
||||||
|
|
||||||
@ -1218,7 +1164,7 @@ struct buffered_piece_collection
|
|||||||
if (! it->has_intersections()
|
if (! it->has_intersections()
|
||||||
&& ! it->is_untouched_outside_original)
|
&& ! it->is_untouched_outside_original)
|
||||||
{
|
{
|
||||||
properties p = properties(*it, m_area_strategy);
|
properties p = properties(*it, m_strategy);
|
||||||
if (p.valid)
|
if (p.valid)
|
||||||
{
|
{
|
||||||
ring_identifier id(0, index, -1);
|
ring_identifier id(0, index, -1);
|
||||||
@ -1234,7 +1180,7 @@ struct buffered_piece_collection
|
|||||||
it != boost::end(traversed_rings);
|
it != boost::end(traversed_rings);
|
||||||
++it, ++index)
|
++it, ++index)
|
||||||
{
|
{
|
||||||
properties p = properties(*it, m_area_strategy);
|
properties p = properties(*it, m_strategy);
|
||||||
if (p.valid)
|
if (p.valid)
|
||||||
{
|
{
|
||||||
ring_identifier id(2, index, -1);
|
ring_identifier id(2, index, -1);
|
||||||
@ -1243,9 +1189,9 @@ struct buffered_piece_collection
|
|||||||
}
|
}
|
||||||
|
|
||||||
detail::overlay::assign_parents<overlay_buffer>(offsetted_rings, traversed_rings,
|
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,
|
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 Pieces,
|
||||||
typename Rings,
|
typename Rings,
|
||||||
typename Turns,
|
typename Turns,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy
|
typename RobustPolicy
|
||||||
>
|
>
|
||||||
class piece_turn_visitor
|
class piece_turn_visitor
|
||||||
@ -125,7 +125,7 @@ class piece_turn_visitor
|
|||||||
Pieces const& m_pieces;
|
Pieces const& m_pieces;
|
||||||
Rings const& m_rings;
|
Rings const& m_rings;
|
||||||
Turns& m_turns;
|
Turns& m_turns;
|
||||||
IntersectionStrategy const& m_intersection_strategy;
|
Strategy const& m_strategy;
|
||||||
RobustPolicy const& m_robust_policy;
|
RobustPolicy const& m_robust_policy;
|
||||||
|
|
||||||
template <typename Piece>
|
template <typename Piece>
|
||||||
@ -271,7 +271,7 @@ class piece_turn_visitor
|
|||||||
|
|
||||||
turn_policy::apply(unique_sub_range1, unique_sub_range2,
|
turn_policy::apply(unique_sub_range1, unique_sub_range2,
|
||||||
the_model,
|
the_model,
|
||||||
m_intersection_strategy,
|
m_strategy,
|
||||||
m_robust_policy,
|
m_robust_policy,
|
||||||
std::back_inserter(m_turns));
|
std::back_inserter(m_turns));
|
||||||
}
|
}
|
||||||
@ -283,12 +283,12 @@ public:
|
|||||||
piece_turn_visitor(Pieces const& pieces,
|
piece_turn_visitor(Pieces const& pieces,
|
||||||
Rings const& ring_collection,
|
Rings const& ring_collection,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
: m_pieces(pieces)
|
: m_pieces(pieces)
|
||||||
, m_rings(ring_collection)
|
, m_rings(ring_collection)
|
||||||
, m_turns(turns)
|
, m_turns(turns)
|
||||||
, m_intersection_strategy(intersection_strategy)
|
, m_strategy(strategy)
|
||||||
, m_robust_policy(robust_policy)
|
, m_robust_policy(robust_policy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -307,7 +307,7 @@ public:
|
|||||||
|| is_on_same_convex_ring(piece1, piece2)
|
|| is_on_same_convex_ring(piece1, piece2)
|
||||||
|| detail::disjoint::disjoint_box_box(section1.bounding_box,
|
|| detail::disjoint::disjoint_box_box(section1.bounding_box,
|
||||||
section2.bounding_box,
|
section2.bounding_box,
|
||||||
m_intersection_strategy.get_disjoint_box_box_strategy()) )
|
m_strategy) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -167,9 +167,11 @@ struct piece_border
|
|||||||
return result;
|
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)
|
if (m_has_envelope)
|
||||||
{
|
{
|
||||||
// Take roundings into account, enlarge box
|
// Take roundings into account, enlarge box
|
||||||
@ -182,8 +184,8 @@ struct piece_border
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename SideStrategy>
|
template <typename Strategy>
|
||||||
void get_properties_of_offsetted_ring_part(SideStrategy const& strategy)
|
void get_properties_of_offsetted_ring_part(Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if (! ring_or_original_empty())
|
if (! ring_or_original_empty())
|
||||||
{
|
{
|
||||||
@ -209,16 +211,16 @@ struct piece_border
|
|||||||
m_originals[m_original_size++] = point;
|
m_originals[m_original_size++] = point;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Box>
|
template <typename Box, typename Strategy>
|
||||||
bool calculate_envelope(Box& envelope) const
|
bool calculate_envelope(Box& envelope, Strategy const& strategy) const
|
||||||
{
|
{
|
||||||
geometry::assign_inverse(envelope);
|
geometry::assign_inverse(envelope);
|
||||||
if (ring_or_original_empty())
|
if (ring_or_original_empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
expand_envelope(envelope, m_ring->begin() + m_begin, m_ring->begin() + m_end);
|
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);
|
expand_envelope(envelope, m_originals.begin(), m_originals.begin() + m_original_size, strategy);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,8 +335,8 @@ private :
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TurnPoint, typename Strategy, typename State>
|
template <typename TurnPoint, typename TiRStrategy, typename State>
|
||||||
bool step(TurnPoint const& point, Point const& p1, Point const& p2, Strategy const & strategy,
|
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
|
geometry::strategy::buffer::place_on_ring_type place_on_ring, State& state) const
|
||||||
{
|
{
|
||||||
// A step between original/offsetted ring is always convex
|
// 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);
|
return strategy.apply(point, p1, p2, dm, place_on_ring, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename It, typename Box>
|
template <typename It, typename Box, typename Strategy>
|
||||||
void expand_envelope(Box& envelope, It begin, It end) const
|
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)
|
for (It it = begin; it != end; ++it)
|
||||||
{
|
{
|
||||||
geometry::expand(envelope, *it, expand_strategy_type());
|
geometry::expand(envelope, *it, strategy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename SideStrategy>
|
template <typename Strategy>
|
||||||
bool is_convex(SideStrategy const& strategy) const
|
bool is_convex(Strategy const& strategy) const
|
||||||
{
|
{
|
||||||
if (ring_or_original_empty())
|
if (ring_or_original_empty())
|
||||||
{
|
{
|
||||||
@ -416,8 +413,8 @@ private :
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename It, typename SideStrategy>
|
template <typename It, typename Strategy>
|
||||||
bool is_convex(Point& previous, Point& current, It begin, It end, SideStrategy const& strategy) const
|
bool is_convex(Point& previous, Point& current, It begin, It end, Strategy const& strategy) const
|
||||||
{
|
{
|
||||||
for (It it = begin; it != end; ++it)
|
for (It it = begin; it != end; ++it)
|
||||||
{
|
{
|
||||||
@ -429,19 +426,16 @@ private :
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename SideStrategy>
|
template <typename Strategy>
|
||||||
bool is_convex(Point& previous, Point& current, Point const& next, SideStrategy const& strategy) const
|
bool is_convex(Point& previous, Point& current, Point const& next, Strategy const& strategy) const
|
||||||
{
|
{
|
||||||
typename SideStrategy::equals_point_point_strategy_type const
|
int const side = strategy.side().apply(previous, current, next);
|
||||||
eq_pp_strategy = strategy.get_equals_point_point_strategy();
|
|
||||||
|
|
||||||
int const side = strategy.apply(previous, current, next);
|
|
||||||
if (side == 1)
|
if (side == 1)
|
||||||
{
|
{
|
||||||
// Next is on the left side of clockwise ring: piece is not convex
|
// Next is on the left side of clockwise ring: piece is not convex
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (! equals::equals_point_point(current, next, eq_pp_strategy))
|
if (! equals::equals_point_point(current, next, strategy))
|
||||||
{
|
{
|
||||||
previous = current;
|
previous = current;
|
||||||
current = next;
|
current = next;
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2016, 2018.
|
// This file was modified by Oracle on 2016-2020.
|
||||||
// Modifications copyright (c) 2016-2018 Oracle and/or its affiliates.
|
// Modifications copyright (c) 2016-2020 Oracle and/or its affiliates.
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
@ -31,31 +31,40 @@ namespace boost { namespace geometry
|
|||||||
namespace detail { namespace buffer
|
namespace detail { namespace buffer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Strategy>
|
||||||
struct original_get_box
|
struct original_get_box
|
||||||
{
|
{
|
||||||
|
explicit original_get_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Original>
|
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);
|
assert_coordinate_type_equal(total, original.m_box);
|
||||||
typedef typename strategy::expand::services::default_strategy
|
geometry::expand(total, original.m_box, m_strategy);
|
||||||
<
|
|
||||||
box_tag, typename cs_tag<Box>::type
|
|
||||||
>::type expand_strategy_type;
|
|
||||||
|
|
||||||
geometry::expand(total, original.m_box, expand_strategy_type());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DisjointBoxBoxStrategy>
|
template <typename Strategy>
|
||||||
struct original_overlaps_box
|
struct original_overlaps_box
|
||||||
{
|
{
|
||||||
|
explicit original_overlaps_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Original>
|
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);
|
assert_coordinate_type_equal(box, original.m_box);
|
||||||
return ! detail::disjoint::disjoint_box_box(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
|
struct include_turn_policy
|
||||||
@ -67,11 +76,15 @@ struct include_turn_policy
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DisjointPointBoxStrategy>
|
template <typename Strategy>
|
||||||
struct turn_in_original_overlaps_box
|
struct turn_in_original_overlaps_box
|
||||||
{
|
{
|
||||||
|
explicit turn_in_original_overlaps_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Turn>
|
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)
|
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(
|
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
|
//! 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
|
class turn_in_original_visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
turn_in_original_visitor(Turns& turns, PointInGeometryStrategy const& strategy)
|
turn_in_original_visitor(Turns& turns, Strategy const& strategy)
|
||||||
: m_mutable_turns(turns)
|
: m_mutable_turns(turns)
|
||||||
, m_point_in_geometry_strategy(strategy)
|
, m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Turn, typename Original>
|
template <typename Turn, typename Original>
|
||||||
@ -234,13 +249,14 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometry::disjoint(turn.point, original.m_box))
|
if (geometry::disjoint(turn.point, original.m_box, m_strategy))
|
||||||
{
|
{
|
||||||
// Skip all disjoint
|
// Skip all disjoint
|
||||||
return true;
|
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)
|
if (code == -1)
|
||||||
{
|
{
|
||||||
@ -277,7 +293,7 @@ public:
|
|||||||
|
|
||||||
private :
|
private :
|
||||||
Turns& m_mutable_turns;
|
Turns& m_mutable_turns;
|
||||||
PointInGeometryStrategy const& m_point_in_geometry_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,13 +54,11 @@ private:
|
|||||||
QueryRangeIterator& qit_min,
|
QueryRangeIterator& qit_min,
|
||||||
Distance& dist_min)
|
Distance& dist_min)
|
||||||
{
|
{
|
||||||
typedef strategy::index::services::from_strategy
|
using strategies::index::services::strategy_converter;
|
||||||
<
|
|
||||||
Strategy
|
|
||||||
> index_strategy_from;
|
|
||||||
typedef index::parameters
|
typedef index::parameters
|
||||||
<
|
<
|
||||||
index::linear<8>, typename index_strategy_from::type
|
index::linear<8>,
|
||||||
|
decltype(strategy_converter<Strategy>::get(strategy))
|
||||||
> index_parameters_type;
|
> index_parameters_type;
|
||||||
typedef index::rtree<RTreeValueType, index_parameters_type> rtree_type;
|
typedef index::rtree<RTreeValueType, index_parameters_type> rtree_type;
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ private:
|
|||||||
// create -- packing algorithm
|
// create -- packing algorithm
|
||||||
rtree_type rt(rtree_first, rtree_last,
|
rtree_type rt(rtree_first, rtree_last,
|
||||||
index_parameters_type(index::linear<8>(),
|
index_parameters_type(index::linear<8>(),
|
||||||
index_strategy_from::get(strategy)));
|
strategy_converter<Strategy>::get(strategy)));
|
||||||
|
|
||||||
RTreeValueType t_v;
|
RTreeValueType t_v;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2017, 2019.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -66,8 +66,7 @@ struct covered_by<Point, Box, point_tag, box_tag>
|
|||||||
template <typename Strategy>
|
template <typename Strategy>
|
||||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
::boost::ignore_unused(strategy);
|
return strategy.covered_by(point, box).apply(point, box);
|
||||||
return strategy.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)
|
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
assert_dimension_equal<Box1, Box2>();
|
assert_dimension_equal<Box1, Box2>();
|
||||||
::boost::ignore_unused(strategy);
|
return strategy.covered_by(box1, box2).apply(box1, box2);
|
||||||
return strategy.apply(box1, box2);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
|
// This file was modified by Oracle on 2013-2021.
|
||||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
// 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/point_in_box.hpp>
|
||||||
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
|
#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -56,9 +57,14 @@ struct covered_by
|
|||||||
|
|
||||||
namespace resolve_strategy {
|
namespace resolve_strategy {
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct covered_by
|
struct covered_by
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
@ -68,23 +74,49 @@ struct covered_by
|
|||||||
concepts::check<Geometry2 const>();
|
concepts::check<Geometry2 const>();
|
||||||
assert_dimension_equal<Geometry1, Geometry2>();
|
assert_dimension_equal<Geometry1, Geometry2>();
|
||||||
|
|
||||||
return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1,
|
return dispatch::covered_by
|
||||||
geometry2,
|
<
|
||||||
strategy);
|
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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::covered_by::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
>::type strategy_type;
|
>::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,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return resolve_strategy::covered_by
|
return resolve_strategy::covered_by<Strategy>
|
||||||
::apply(geometry1, geometry2, strategy);
|
::apply(geometry1, geometry2, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -60,13 +60,9 @@ inline bool rings_containing(Geometry1 const& geometry1,
|
|||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
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 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,
|
Box const& box,
|
||||||
Strategy const& strategy)
|
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)
|
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;
|
return false;
|
||||||
@ -129,8 +123,7 @@ struct areal_box
|
|||||||
// If there is no intersection of any segment and box,
|
// If there is no intersection of any segment and box,
|
||||||
// the box might be located inside areal geometry
|
// the box might be located inside areal geometry
|
||||||
|
|
||||||
if ( point_on_border_covered_by(box, areal,
|
if ( point_on_border_covered_by(box, areal, strategy) )
|
||||||
strategy.template get_point_in_geometry_strategy<Box, Areal>()) )
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013-2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
// Contributed and/or modified by Menelaos Karavelas, 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
|
\note Is used from other algorithms, declared separately
|
||||||
to avoid circular references
|
to avoid circular references
|
||||||
*/
|
*/
|
||||||
template <typename Box1, typename Box2, typename Strategy>
|
template
|
||||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const&)
|
<
|
||||||
|
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);
|
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>
|
struct disjoint<Box1, Box2, DimensionCount, box_tag, box_tag, false>
|
||||||
{
|
{
|
||||||
template <typename Strategy>
|
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) 2009-2014 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013-2017.
|
// This file was modified by Oracle on 2013-2021.
|
||||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
// Contributed and/or modified by Menelaos Karavelas, 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/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/disjoint.hpp>
|
||||||
|
#include <boost/geometry/strategies/relate/services.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace geometry
|
namespace boost { namespace geometry
|
||||||
@ -41,9 +44,14 @@ namespace boost { namespace geometry
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct disjoint
|
struct disjoint
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
@ -53,13 +61,35 @@ struct disjoint
|
|||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::apply(geometry1, geometry2, strategy);
|
>::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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::disjoint::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::type strategy_type;
|
>::type strategy_type;
|
||||||
@ -88,7 +118,10 @@ struct disjoint
|
|||||||
Geometry2 const
|
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;
|
point1_type p;
|
||||||
geometry::point_on_border(p, g1);
|
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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoIntersectionsPolicy
|
return NoIntersectionsPolicy::apply(g1, g2, strategy);
|
||||||
::apply(g1, g2,
|
|
||||||
strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,8 +193,7 @@ public:
|
|||||||
typename point_type<Segment>::type p;
|
typename point_type<Segment>::type p;
|
||||||
detail::assign_point_from_index<0>(segment, p);
|
detail::assign_point_from_index<0>(segment, p);
|
||||||
|
|
||||||
return !geometry::covered_by(p, polygon,
|
return ! geometry::covered_by(p, polygon, strategy);
|
||||||
strategy.template get_point_in_geometry_strategy<Segment, Polygon>());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,8 +232,7 @@ struct disjoint_segment_areal<Segment, Ring, ring_tag>
|
|||||||
typename point_type<Segment>::type p;
|
typename point_type<Segment>::type p;
|
||||||
detail::assign_point_from_index<0>(segment, p);
|
detail::assign_point_from_index<0>(segment, p);
|
||||||
|
|
||||||
return !geometry::covered_by(p, ring,
|
return ! geometry::covered_by(p, ring, strategy);
|
||||||
strategy.template get_point_in_geometry_strategy<Segment, Ring>());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ struct disjoint_segment
|
|||||||
|
|
||||||
detail::segment_as_subrange<Segment1> sub_range1(segment1);
|
detail::segment_as_subrange<Segment1> sub_range1(segment1);
|
||||||
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
||||||
intersection_return_type is = strategy.apply(sub_range1, sub_range2,
|
intersection_return_type is = strategy.relate().apply(sub_range1, sub_range2,
|
||||||
intersection_policy());
|
intersection_policy());
|
||||||
|
|
||||||
return is.count == 0;
|
return is.count == 0;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,7 @@ struct disjoint_point_segment_or_box<Segment, segment_tag>
|
|||||||
return dispatch::disjoint
|
return dispatch::disjoint
|
||||||
<
|
<
|
||||||
Point, Segment
|
Point, Segment
|
||||||
>::apply(point, segment,
|
>::apply(point, segment, strategy);
|
||||||
strategy.template get_point_in_geometry_strategy<Point, Segment>());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,8 +71,7 @@ struct disjoint_point_segment_or_box<Box, box_tag>
|
|||||||
return dispatch::disjoint
|
return dispatch::disjoint
|
||||||
<
|
<
|
||||||
Point, Box
|
Point, Box
|
||||||
>::apply(point, box,
|
>::apply(point, box, strategy);
|
||||||
strategy.get_disjoint_point_box_strategy());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,72 +125,78 @@ template <typename MultiPoint, typename Linear>
|
|||||||
class multipoint_linear
|
class multipoint_linear
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template <typename ExpandPointBoxStrategy>
|
template <typename Strategy>
|
||||||
struct expand_box_point
|
struct expand_box_point
|
||||||
{
|
{
|
||||||
|
explicit expand_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct expand_box_segment
|
||||||
{
|
{
|
||||||
explicit expand_box_segment(EnvelopeStrategy const& strategy)
|
explicit expand_box_segment(Strategy const& strategy)
|
||||||
: m_strategy(strategy)
|
: m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Segment>
|
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::expand(total,
|
||||||
geometry::return_envelope<Box>(segment, m_strategy),
|
geometry::return_envelope<Box>(segment, m_strategy),
|
||||||
// TEMP - envelope umbrella strategy also contains
|
m_strategy);
|
||||||
// expand strategies
|
|
||||||
strategies::envelope::services::strategy_converter
|
|
||||||
<
|
|
||||||
EnvelopeStrategy
|
|
||||||
>::get(m_strategy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvelopeStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DisjointPointBoxStrategy>
|
template <typename Strategy>
|
||||||
struct overlaps_box_point
|
struct overlaps_box_point
|
||||||
{
|
{
|
||||||
|
explicit overlaps_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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,
|
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
|
struct overlaps_box_segment
|
||||||
{
|
{
|
||||||
explicit overlaps_box_segment(DisjointStrategy const& strategy)
|
explicit overlaps_box_segment(Strategy const& strategy)
|
||||||
: m_strategy(strategy)
|
: m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Segment>
|
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);
|
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
|
class item_visitor_type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
item_visitor_type(PtSegStrategy const& strategy)
|
item_visitor_type(Strategy const& strategy)
|
||||||
: m_intersection_found(false)
|
: m_intersection_found(false)
|
||||||
, m_strategy(strategy)
|
, m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
@ -211,7 +217,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_intersection_found;
|
bool m_intersection_found;
|
||||||
PtSegStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
// structs for partition -- end
|
// structs for partition -- end
|
||||||
|
|
||||||
@ -245,11 +251,6 @@ public:
|
|||||||
{
|
{
|
||||||
item_visitor_type<Strategy> visitor(strategy);
|
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
|
// TODO: disjoint Segment/Box may be called in partition multiple times
|
||||||
// possibly for non-cartesian segments which could be slow. We should consider
|
// possibly for non-cartesian segments which could be slow. We should consider
|
||||||
// passing a range of bounding boxes of segments after calculating them once.
|
// 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>
|
geometry::model::box<typename point_type<MultiPoint>::type>
|
||||||
>::apply(multipoint, segment_range(linear), visitor,
|
>::apply(multipoint, segment_range(linear), visitor,
|
||||||
expand_box_point<expand_point_strategy_type>(),
|
expand_box_point<Strategy>(strategy),
|
||||||
overlaps_box_point<disjoint_pb_strategy_type>(),
|
overlaps_box_point<Strategy>(strategy),
|
||||||
expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
|
expand_box_segment<Strategy>(strategy),
|
||||||
overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
|
overlaps_box_segment<Strategy>(strategy));
|
||||||
|
|
||||||
return ! visitor.intersection_found();
|
return ! visitor.intersection_found();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Strategy>
|
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);
|
return apply(multipoint, linear, strategy);
|
||||||
}
|
}
|
||||||
@ -284,21 +286,19 @@ public:
|
|||||||
SingleGeometry const& single_geometry,
|
SingleGeometry const& single_geometry,
|
||||||
Strategy const& strategy)
|
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<MultiPoint>::type point1_type;
|
||||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||||
typedef model::box<point2_type> box2_type;
|
typedef model::box<point2_type> box2_type;
|
||||||
|
|
||||||
box2_type box2;
|
box2_type box2;
|
||||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
geometry::envelope(single_geometry, box2, strategy);
|
||||||
geometry::detail::expand_by_epsilon(box2);
|
geometry::detail::expand_by_epsilon(box2);
|
||||||
|
|
||||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||||
{
|
{
|
||||||
// The default strategy is enough for Point/Box
|
// 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))
|
&& ! dispatch::disjoint<point1_type, SingleGeometry>::apply(*it, single_geometry, strategy))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -309,7 +309,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Strategy>
|
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);
|
return apply(multi_point, single_geometry, strategy);
|
||||||
}
|
}
|
||||||
@ -320,56 +321,77 @@ template <typename MultiPoint, typename MultiGeometry>
|
|||||||
class multi_point_multi_geometry
|
class multi_point_multi_geometry
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template <typename ExpandPointStrategy>
|
template <typename Strategy>
|
||||||
struct expand_box_point
|
struct expand_box_point
|
||||||
{
|
{
|
||||||
|
explicit expand_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct expand_box_box_pair
|
||||||
{
|
{
|
||||||
|
explicit expand_box_box_pair(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename BoxPair>
|
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
|
struct overlaps_box_point
|
||||||
{
|
{
|
||||||
|
explicit overlaps_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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, m_strategy);
|
||||||
return ! detail::disjoint::disjoint_point_box(point, box,
|
|
||||||
DisjointPointBoxStrategy());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DisjointBoxBoxStrategy>
|
template <typename Strategy>
|
||||||
struct overlaps_box_box_pair
|
struct overlaps_box_box_pair
|
||||||
{
|
{
|
||||||
|
explicit overlaps_box_box_pair(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename BoxPair>
|
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,
|
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
|
class item_visitor_type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||||
PtSegStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
: m_intersection_found(false)
|
: m_intersection_found(false)
|
||||||
, m_multi_geometry(multi_geometry)
|
, m_multi_geometry(multi_geometry)
|
||||||
, m_strategy(strategy)
|
, m_strategy(strategy)
|
||||||
@ -378,14 +400,15 @@ private:
|
|||||||
template <typename Point, typename BoxPair>
|
template <typename Point, typename BoxPair>
|
||||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
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;
|
typedef typename boost::range_value<MultiGeometry>::type single_type;
|
||||||
|
|
||||||
// The default strategy is enough for Point/Box
|
// The default strategy is enough for Point/Box
|
||||||
if (! m_intersection_found
|
if (! m_intersection_found
|
||||||
&& ! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pb_strategy_type())
|
&& ! 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))
|
&& ! dispatch::disjoint
|
||||||
|
<
|
||||||
|
Point, single_type
|
||||||
|
>::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy))
|
||||||
{
|
{
|
||||||
m_intersection_found = true;
|
m_intersection_found = true;
|
||||||
return false;
|
return false;
|
||||||
@ -398,7 +421,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
bool m_intersection_found;
|
bool m_intersection_found;
|
||||||
MultiGeometry const& m_multi_geometry;
|
MultiGeometry const& m_multi_geometry;
|
||||||
PtSegStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
// structs for partition -- end
|
// structs for partition -- end
|
||||||
|
|
||||||
@ -411,53 +434,26 @@ public:
|
|||||||
typedef model::box<point1_type> box1_type;
|
typedef model::box<point1_type> box1_type;
|
||||||
typedef model::box<point2_type> box2_type;
|
typedef model::box<point2_type> box2_type;
|
||||||
typedef std::pair<box2_type, std::size_t> box_pair_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::size_t count2 = boost::size(multi_geometry);
|
||||||
std::vector<box_pair_type> boxes(count2);
|
std::vector<box_pair_type> boxes(count2);
|
||||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
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);
|
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||||
boxes[i].second = i;
|
boxes[i].second = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
item_visitor_type<Strategy> visitor(multi_geometry, strategy);
|
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
|
geometry::partition
|
||||||
<
|
<
|
||||||
box1_type
|
box1_type
|
||||||
>::apply(multi_point, boxes, visitor,
|
>::apply(multi_point, boxes, visitor,
|
||||||
expand_box_point_type(),
|
expand_box_point<Strategy>(strategy),
|
||||||
overlaps_box_point_type(),
|
overlaps_box_point<Strategy>(strategy),
|
||||||
expand_box_box_pair_type(),
|
expand_box_box_pair<Strategy>(strategy),
|
||||||
overlaps_box_box_pair_type());
|
overlaps_box_box_pair<Strategy>(strategy));
|
||||||
|
|
||||||
return ! visitor.intersection_found();
|
return ! visitor.intersection_found();
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
|
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013-2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
// Contributed and/or modified by Menelaos Karavelas, 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
|
\brief Internal utility function to detect if point/box are disjoint
|
||||||
*/
|
*/
|
||||||
template <typename Point, typename Box, typename Strategy>
|
template
|
||||||
inline bool disjoint_point_box(Point const& point, Box const& box, Strategy const& )
|
<
|
||||||
|
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)
|
// ! covered_by(point, box)
|
||||||
return ! Strategy::apply(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>
|
struct disjoint<Point, Box, DimensionCount, point_tag, box_tag, false>
|
||||||
{
|
{
|
||||||
template <typename Strategy>
|
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)
|
// ! 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) 2009-2015 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
|
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
// Contributed and/or modified by Menelaos Karavelas, 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
|
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include <boost/geometry/core/tags.hpp>
|
#include <boost/geometry/core/tags.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||||
|
|
||||||
|
#include <boost/geometry/strategies/detail.hpp>
|
||||||
|
|
||||||
// For backward compatibility
|
// For backward compatibility
|
||||||
#include <boost/geometry/strategies/disjoint.hpp>
|
#include <boost/geometry/strategies/disjoint.hpp>
|
||||||
#include <boost/geometry/strategies/cartesian/point_in_point.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
|
\brief Internal utility function to detect of points are disjoint
|
||||||
\note To avoid circular references
|
\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,
|
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2,
|
||||||
Strategy const& )
|
Strategy const& )
|
||||||
{
|
{
|
||||||
|
// ! within(point1, point2)
|
||||||
return ! Strategy::apply(point1, point2);
|
return ! Strategy::apply(point1, point2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,9 +89,11 @@ struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, false>
|
|||||||
{
|
{
|
||||||
template <typename Strategy>
|
template <typename Strategy>
|
||||||
static inline bool apply(Point1 const& point1, Point2 const& point2,
|
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,
|
Box const& box,
|
||||||
Strategy const& strategy)
|
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/distance.hpp>
|
||||||
#include <boost/geometry/strategies/tags.hpp>
|
#include <boost/geometry/strategies/tags.hpp>
|
||||||
|
#include <boost/geometry/strategies/relate/services.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/algorithms/assign.hpp>
|
#include <boost/geometry/algorithms/assign.hpp>
|
||||||
|
|
||||||
@ -164,8 +165,12 @@ struct point_to_ring
|
|||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// TODO: pass strategy
|
// TODO: pass strategy
|
||||||
if (within::within_point_geometry(point, ring,
|
auto const s = strategies::relate::services::strategy_converter
|
||||||
strategy.get_point_in_geometry_strategy()))
|
<
|
||||||
|
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);
|
return return_type(0);
|
||||||
}
|
}
|
||||||
@ -207,11 +212,15 @@ private:
|
|||||||
InteriorRingIterator last,
|
InteriorRingIterator last,
|
||||||
Strategy const& strategy)
|
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)
|
for (InteriorRingIterator it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
// TODO: pass strategy
|
if (within::within_point_geometry(point, *it, s))
|
||||||
if (within::within_point_geometry(point, *it,
|
|
||||||
strategy.get_point_in_geometry_strategy()))
|
|
||||||
{
|
{
|
||||||
// the point is inside a polygon hole, so its distance
|
// the point is inside a polygon hole, so its distance
|
||||||
// to the polygon its distance to the polygon's
|
// to the polygon its distance to the polygon's
|
||||||
@ -240,9 +249,13 @@ public:
|
|||||||
Polygon const& polygon,
|
Polygon const& polygon,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// TODO: pass strategy
|
// TEMP: pass strategy
|
||||||
if (! within::covered_by_point_geometry(point, exterior_ring(polygon),
|
auto const s = strategies::relate::services::strategy_converter
|
||||||
strategy.get_point_in_geometry_strategy()))
|
<
|
||||||
|
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
|
// the point is outside the exterior ring, so its distance
|
||||||
// to the polygon is its distance to the polygon's exterior ring
|
// 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)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// TODO: pass strategy
|
// TODO: pass strategy
|
||||||
if (within::covered_by_point_geometry(point, multipolygon,
|
auto const s = strategies::relate::services::strategy_converter
|
||||||
strategy.get_point_in_geometry_strategy()))
|
<
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -58,17 +58,20 @@ namespace detail { namespace distance
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// TODO: Take strategy
|
template <typename Segment, typename Box, typename Strategy>
|
||||||
template <typename Segment, typename Box>
|
inline bool intersects_segment_box(Segment const& segment, Box const& box,
|
||||||
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
|
// This is the only strategy defined in distance segment/box
|
||||||
>::type strategy_type;
|
// 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,
|
return ! detail::disjoint::disjoint_segment_box::apply(segment, box, s);
|
||||||
strategy_type());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -114,7 +117,7 @@ public:
|
|||||||
Strategy const& strategy,
|
Strategy const& strategy,
|
||||||
bool check_intersection = true)
|
bool check_intersection = true)
|
||||||
{
|
{
|
||||||
if (check_intersection && intersects_segment_box(segment, box))
|
if (check_intersection && intersects_segment_box(segment, box, strategy))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -229,7 +232,7 @@ public:
|
|||||||
Strategy const& strategy,
|
Strategy const& strategy,
|
||||||
bool check_intersection = true)
|
bool check_intersection = true)
|
||||||
{
|
{
|
||||||
if (check_intersection && intersects_segment_box(segment, box))
|
if (check_intersection && intersects_segment_box(segment, box, strategy))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,11 @@ template
|
|||||||
struct point_point
|
struct point_point
|
||||||
{
|
{
|
||||||
template <typename Point1, typename Point2, typename Strategy>
|
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,
|
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
|
||||||
Strategy const& strategy)
|
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(
|
return equals::equals_point_point(
|
||||||
indexed_point_view<Segment1 const, 0>(segment1),
|
indexed_point_view<Segment1 const, 0>(segment1),
|
||||||
indexed_point_view<Segment2 const, 0>(segment2),
|
indexed_point_view<Segment2 const, 0>(segment2),
|
||||||
pt_pt_strategy)
|
strategy)
|
||||||
? equals::equals_point_point(
|
? equals::equals_point_point(
|
||||||
indexed_point_view<Segment1 const, 1>(segment1),
|
indexed_point_view<Segment1 const, 1>(segment1),
|
||||||
indexed_point_view<Segment2 const, 1>(segment2),
|
indexed_point_view<Segment2 const, 1>(segment2),
|
||||||
pt_pt_strategy)
|
strategy)
|
||||||
: ( equals::equals_point_point(
|
: ( equals::equals_point_point(
|
||||||
indexed_point_view<Segment1 const, 0>(segment1),
|
indexed_point_view<Segment1 const, 0>(segment1),
|
||||||
indexed_point_view<Segment2 const, 1>(segment2),
|
indexed_point_view<Segment2 const, 1>(segment2),
|
||||||
pt_pt_strategy)
|
strategy)
|
||||||
&& equals::equals_point_point(
|
&& equals::equals_point_point(
|
||||||
indexed_point_view<Segment1 const, 1>(segment1),
|
indexed_point_view<Segment1 const, 1>(segment1),
|
||||||
indexed_point_view<Segment2 const, 0>(segment2),
|
indexed_point_view<Segment2 const, 0>(segment2),
|
||||||
pt_pt_strategy)
|
strategy)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -138,15 +137,13 @@ struct area_check
|
|||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return geometry::math::equals(
|
return geometry::math::equals(geometry::area(geometry1, strategy),
|
||||||
geometry::area(geometry1,
|
geometry::area(geometry2, strategy));
|
||||||
strategy.template get_area_strategy<Geometry1>()),
|
|
||||||
geometry::area(geometry2,
|
|
||||||
strategy.template get_area_strategy<Geometry2>()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
struct length_check
|
struct length_check
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||||
@ -154,16 +151,14 @@ struct length_check
|
|||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return geometry::math::equals(
|
return geometry::math::equals(geometry::length(geometry1, strategy),
|
||||||
geometry::length(geometry1,
|
geometry::length(geometry2, strategy));
|
||||||
strategy.template get_distance_strategy<Geometry1>()),
|
|
||||||
geometry::length(geometry2,
|
|
||||||
strategy.template get_distance_strategy<Geometry2>()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
|
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||||
struct collected_vector
|
struct collected_vector
|
||||||
{
|
{
|
||||||
typedef typename geometry::select_most_precise
|
typedef typename geometry::select_most_precise
|
||||||
@ -179,7 +174,7 @@ struct collected_vector
|
|||||||
<
|
<
|
||||||
calculation_type,
|
calculation_type,
|
||||||
Geometry1,
|
Geometry1,
|
||||||
typename IntersectionStrategy::side_strategy_type
|
decltype(std::declval<Strategy>().side())
|
||||||
> type;
|
> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,9 +5,8 @@
|
|||||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2014, 2015, 2016, 2017, 2019.
|
// This file was modified by Oracle on 2014-2021.
|
||||||
// Modifications copyright (c) 2014-2019 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
// Contributed and/or modified by Menelaos Karavelas, 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/coordinate_dimension.hpp>
|
||||||
#include <boost/geometry/core/reverse_dispatch.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/geometries/concepts/check.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -94,9 +96,14 @@ struct equals<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, Dimensio
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct equals
|
struct equals
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
@ -106,13 +113,35 @@ struct equals
|
|||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::apply(geometry1, geometry2, strategy);
|
>::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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
@ -145,7 +174,9 @@ struct equals
|
|||||||
>();
|
>();
|
||||||
|
|
||||||
return resolve_strategy::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) 2009-2014 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
|
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013-2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
// Contributed and/or modified by Menelaos Karavelas, 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
|
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <boost/geometry/strategies/detail.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace geometry
|
namespace boost { namespace geometry
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -33,7 +38,23 @@ namespace detail { namespace equals
|
|||||||
\brief Internal utility function to detect of points are disjoint
|
\brief Internal utility function to detect of points are disjoint
|
||||||
\note To avoid circular references
|
\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,
|
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||||
Strategy const& )
|
Strategy const& )
|
||||||
{
|
{
|
||||||
|
@ -136,27 +136,6 @@ inline bool has_self_intersections(Geometry const& geometry,
|
|||||||
return false;
|
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
|
}} // namespace detail::overlay
|
||||||
#endif // DOXYGEN_NO_DETAIL
|
#endif // DOXYGEN_NO_DETAIL
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Boost.Geometry
|
// 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
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Licensed under the Boost Software License version 1.0.
|
// Licensed under the Boost Software License version 1.0.
|
||||||
@ -109,10 +109,6 @@ struct intersection_areal_areal_<TupledOut, tupled_output_tag>
|
|||||||
<
|
<
|
||||||
areal::index, TupledOut
|
areal::index, TupledOut
|
||||||
>::type areal_out_type;
|
>::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
|
// NOTE: The same robust_policy is used in each call of
|
||||||
// intersection_insert. Is that correct?
|
// intersection_insert. Is that correct?
|
||||||
@ -157,11 +153,7 @@ struct intersection_areal_areal_<TupledOut, tupled_output_tag>
|
|||||||
areal_out_boundary,
|
areal_out_boundary,
|
||||||
robust_policy,
|
robust_policy,
|
||||||
pointlike::get(geometry_out),
|
pointlike::get(geometry_out),
|
||||||
strategy.template get_point_in_geometry_strategy
|
strategy);
|
||||||
<
|
|
||||||
pointlike_out_type,
|
|
||||||
areal_out_boundary_type
|
|
||||||
>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2014, 2017, 2019.
|
// This file was modified by Oracle on 2014-2020.
|
||||||
// Modifications copyright (c) 2014-2019, Oracle and/or its affiliates.
|
// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||||
|
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// 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/algorithms/detail/tupled_output.hpp>
|
||||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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/util/range.hpp>
|
||||||
|
|
||||||
|
|
||||||
@ -108,14 +109,18 @@ struct intersection
|
|||||||
|
|
||||||
namespace resolve_strategy {
|
namespace resolve_strategy {
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct intersection
|
struct intersection
|
||||||
{
|
{
|
||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Geometry1,
|
typename Geometry1,
|
||||||
typename Geometry2,
|
typename Geometry2,
|
||||||
typename GeometryOut,
|
typename GeometryOut
|
||||||
typename Strategy
|
|
||||||
>
|
>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
@ -140,7 +145,34 @@ struct intersection
|
|||||||
>::apply(geometry1, geometry2, robust_policy, geometry_out,
|
>::apply(geometry1, geometry2, robust_policy, geometry_out,
|
||||||
strategy);
|
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
|
template
|
||||||
<
|
<
|
||||||
typename Geometry1,
|
typename Geometry1,
|
||||||
@ -152,28 +184,15 @@ struct intersection
|
|||||||
GeometryOut & geometry_out,
|
GeometryOut & geometry_out,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename geometry::rescale_overlay_policy_type
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
|
||||||
Geometry1,
|
|
||||||
Geometry2,
|
|
||||||
typename geometry::cs_tag<Geometry1>::type
|
|
||||||
>::type rescale_policy_type;
|
|
||||||
|
|
||||||
typename strategy::relate::services::default_strategy
|
|
||||||
<
|
<
|
||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::type strategy;
|
>::type strategy_type;
|
||||||
|
|
||||||
rescale_policy_type robust_policy
|
return intersection
|
||||||
= geometry::get_rescale_policy<rescale_policy_type>(
|
|
||||||
geometry1, geometry2, strategy);
|
|
||||||
|
|
||||||
return dispatch::intersection
|
|
||||||
<
|
<
|
||||||
Geometry1,
|
strategy_type
|
||||||
Geometry2
|
>::apply(geometry1, geometry2, geometry_out, strategy_type());
|
||||||
>::apply(geometry1, geometry2, robust_policy, geometry_out,
|
|
||||||
strategy);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,10 +214,10 @@ struct intersection
|
|||||||
concepts::check<Geometry1 const>();
|
concepts::check<Geometry1 const>();
|
||||||
concepts::check<Geometry2 const>();
|
concepts::check<Geometry2 const>();
|
||||||
|
|
||||||
return resolve_strategy::intersection::apply(geometry1,
|
return resolve_strategy::intersection
|
||||||
geometry2,
|
<
|
||||||
geometry_out,
|
Strategy
|
||||||
strategy);
|
>::apply(geometry1, geometry2, geometry_out, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013-2017.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
// 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 Menelaos Karavelas, on behalf of Oracle
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, 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/disjoint_interrupt_policy.hpp>
|
||||||
#include <boost/geometry/policies/robustness/no_rescale_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
|
namespace boost { namespace geometry
|
||||||
@ -48,7 +48,7 @@ struct self_intersects
|
|||||||
concepts::check<Geometry const>();
|
concepts::check<Geometry const>();
|
||||||
|
|
||||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
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
|
Geometry, Geometry
|
||||||
>::type strategy_type;
|
>::type strategy_type;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
// 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 Menelaos Karavelas, on behalf of Oracle
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, 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/ring_type.hpp>
|
||||||
#include <boost/geometry/core/tags.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_simple/failure_policy.hpp>
|
||||||
#include <boost/geometry/algorithms/detail/is_valid/has_duplicates.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>
|
template <typename Ring, typename Strategy>
|
||||||
struct is_simple_ring
|
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)
|
||||||
simplicity_failure_policy policy;
|
&& ! detail::is_valid::has_duplicates
|
||||||
return ! boost::empty(ring)
|
<
|
||||||
&& ! detail::is_valid::has_duplicates
|
Ring, geometry::closure<Ring>::value
|
||||||
<
|
>::apply(ring, policy, strategy);
|
||||||
Ring, geometry::closure<Ring>::value, CSTag
|
}
|
||||||
>::apply(ring, policy);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
template <typename InteriorRings, typename Strategy>
|
||||||
template <typename Polygon, typename CSTag>
|
inline bool are_simple_interior_rings(InteriorRings const& interior_rings,
|
||||||
class is_simple_polygon
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
private:
|
auto const end = boost::end(interior_rings);
|
||||||
template <typename InteriorRings>
|
return std::find_if(boost::begin(interior_rings), end,
|
||||||
static inline
|
[&](auto const& r)
|
||||||
bool are_simple_interior_rings(InteriorRings const& interior_rings)
|
{
|
||||||
{
|
return ! is_simple_ring(r, strategy);
|
||||||
return
|
}) == end; // non-simple ring not found
|
||||||
detail::check_iterator_range
|
// allow empty ring
|
||||||
<
|
}
|
||||||
is_simple_ring
|
|
||||||
<
|
|
||||||
typename boost::range_value<InteriorRings>::type,
|
|
||||||
CSTag
|
|
||||||
>
|
|
||||||
>::apply(boost::begin(interior_rings),
|
|
||||||
boost::end(interior_rings));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
template <typename Polygon, typename Strategy>
|
||||||
static inline bool apply(Polygon const& polygon)
|
inline bool is_simple_polygon(Polygon const& polygon, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return
|
return is_simple_ring(geometry::exterior_ring(polygon), strategy)
|
||||||
is_simple_ring
|
&& are_simple_interior_rings(geometry::interior_rings(polygon), strategy);
|
||||||
<
|
}
|
||||||
typename ring_type<Polygon>::type,
|
|
||||||
CSTag
|
|
||||||
>::apply(exterior_ring(polygon))
|
|
||||||
&&
|
|
||||||
are_simple_interior_rings(geometry::interior_rings(polygon));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}} // namespace detail::is_simple
|
}} // namespace detail::is_simple
|
||||||
@ -107,13 +88,9 @@ template <typename Ring>
|
|||||||
struct is_simple<Ring, ring_tag>
|
struct is_simple<Ring, ring_tag>
|
||||||
{
|
{
|
||||||
template <typename Strategy>
|
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
|
return detail::is_simple::is_simple_ring(ring, strategy);
|
||||||
<
|
|
||||||
Ring,
|
|
||||||
typename Strategy::cs_tag
|
|
||||||
>::apply(ring);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,13 +102,9 @@ template <typename Polygon>
|
|||||||
struct is_simple<Polygon, polygon_tag>
|
struct is_simple<Polygon, polygon_tag>
|
||||||
{
|
{
|
||||||
template <typename Strategy>
|
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
|
return detail::is_simple::is_simple_polygon(polygon, strategy);
|
||||||
<
|
|
||||||
Polygon,
|
|
||||||
typename Strategy::cs_tag
|
|
||||||
>::apply(polygon);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,18 +117,14 @@ template <typename MultiPolygon>
|
|||||||
struct is_simple<MultiPolygon, multi_polygon_tag>
|
struct is_simple<MultiPolygon, multi_polygon_tag>
|
||||||
{
|
{
|
||||||
template <typename Strategy>
|
template <typename Strategy>
|
||||||
static inline bool apply(MultiPolygon const& multipolygon, Strategy const&)
|
static inline bool apply(MultiPolygon const& multipolygon, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return
|
auto const end = boost::end(multipolygon);
|
||||||
detail::check_iterator_range
|
return std::find_if(boost::begin(multipolygon), end,
|
||||||
<
|
[&](auto const& po) {
|
||||||
detail::is_simple::is_simple_polygon
|
return ! detail::is_simple::is_simple_polygon(po, strategy);
|
||||||
<
|
}) == end; // non-simple polygon not found
|
||||||
typename boost::range_value<MultiPolygon>::type,
|
// allow empty multi-polygon
|
||||||
typename Strategy::cs_tag
|
|
||||||
>,
|
|
||||||
true // allow empty multi-polygon
|
|
||||||
>::apply(boost::begin(multipolygon), boost::end(multipolygon));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
// 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 Menelaos Karavelas, on behalf of Oracle
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, 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/algorithms/dispatch/is_simple.hpp>
|
||||||
#include <boost/geometry/core/cs.hpp>
|
#include <boost/geometry/core/cs.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -29,23 +30,47 @@ namespace boost { namespace geometry
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct is_simple
|
struct is_simple
|
||||||
{
|
{
|
||||||
template <typename Geometry, typename Strategy>
|
template <typename Geometry>
|
||||||
static inline bool apply(Geometry const& geometry,
|
static inline bool apply(Geometry const& geometry,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return dispatch::is_simple<Geometry>::apply(geometry, 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>
|
template <typename Geometry>
|
||||||
static inline bool apply(Geometry const& geometry,
|
static inline bool apply(Geometry const& geometry,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
// NOTE: Currently the strategy is only used for Linear geometries
|
// 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;
|
>::type strategy_type;
|
||||||
|
|
||||||
return dispatch::is_simple<Geometry>::apply(geometry, strategy_type());
|
return dispatch::is_simple<Geometry>::apply(geometry, strategy_type());
|
||||||
@ -65,7 +90,7 @@ struct is_simple
|
|||||||
{
|
{
|
||||||
concepts::check<Geometry const>();
|
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
|
typedef is_acceptable_turn
|
||||||
<
|
<
|
||||||
Linear,
|
Linear, Strategy
|
||||||
typename Strategy::equals_point_point_strategy_type
|
|
||||||
> is_acceptable_turn_type;
|
> is_acceptable_turn_type;
|
||||||
|
|
||||||
is_acceptable_turn_type predicate(linear);
|
is_acceptable_turn_type predicate(linear);
|
||||||
@ -259,12 +258,12 @@ struct is_simple_linestring
|
|||||||
return ! boost::empty(linestring)
|
return ! boost::empty(linestring)
|
||||||
&& ! detail::is_valid::has_duplicates
|
&& ! detail::is_valid::has_duplicates
|
||||||
<
|
<
|
||||||
Linestring, closed, typename Strategy::cs_tag
|
Linestring, closed
|
||||||
>::apply(linestring, policy)
|
>::apply(linestring, policy, strategy)
|
||||||
&& ! detail::is_valid::has_spikes
|
&& ! detail::is_valid::has_spikes
|
||||||
<
|
<
|
||||||
Linestring, closed
|
Linestring, closed
|
||||||
>::apply(linestring, policy, strategy.get_side_strategy());
|
>::apply(linestring, policy, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ template <typename MultiPoint>
|
|||||||
struct is_simple_multipoint
|
struct is_simple_multipoint
|
||||||
{
|
{
|
||||||
template <typename Strategy>
|
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 typename Strategy::cs_tag cs_tag;
|
||||||
typedef geometry::less
|
typedef geometry::less
|
||||||
@ -61,10 +61,10 @@ struct is_simple_multipoint
|
|||||||
std::sort(boost::begin(mp), boost::end(mp), less_type());
|
std::sort(boost::begin(mp), boost::end(mp), less_type());
|
||||||
|
|
||||||
simplicity_failure_policy policy;
|
simplicity_failure_policy policy;
|
||||||
return !detail::is_valid::has_duplicates
|
return ! detail::is_valid::has_duplicates
|
||||||
<
|
<
|
||||||
MultiPoint, closed, cs_tag
|
MultiPoint, closed
|
||||||
>::apply(mp, policy);
|
>::apply(mp, policy, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,11 +33,12 @@ namespace boost { namespace geometry
|
|||||||
namespace detail { namespace is_valid
|
namespace detail { namespace is_valid
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename Range, closure_selector Closure, typename CSTag>
|
template <typename Range, closure_selector Closure>
|
||||||
struct has_duplicates
|
struct has_duplicates
|
||||||
{
|
{
|
||||||
template <typename VisitPolicy>
|
template <typename VisitPolicy, typename Strategy>
|
||||||
static inline bool apply(Range const& range, VisitPolicy& visitor)
|
static inline bool apply(Range const& range, VisitPolicy& visitor,
|
||||||
|
Strategy const& )
|
||||||
{
|
{
|
||||||
boost::ignore_unused(visitor);
|
boost::ignore_unused(visitor);
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ struct has_duplicates
|
|||||||
<
|
<
|
||||||
typename boost::range_value<Range>::type,
|
typename boost::range_value<Range>::type,
|
||||||
-1,
|
-1,
|
||||||
CSTag
|
typename Strategy::cs_tag
|
||||||
> equal;
|
> equal;
|
||||||
|
|
||||||
const_iterator it = boost::const_begin(view);
|
const_iterator it = boost::const_begin(view);
|
||||||
|
@ -45,64 +45,27 @@ namespace boost { namespace geometry
|
|||||||
namespace detail { namespace is_valid
|
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>
|
template <typename Range, closure_selector Closure>
|
||||||
struct has_spikes
|
struct has_spikes
|
||||||
{
|
{
|
||||||
template <typename Iterator, typename SideStrategy>
|
template <typename Iterator, typename Strategy>
|
||||||
static inline Iterator find_different_from_first(Iterator first,
|
static inline Iterator find_different_from_first(Iterator first,
|
||||||
Iterator last,
|
Iterator last,
|
||||||
SideStrategy const& )
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef not_equal_to
|
if (first == last)
|
||||||
<
|
return last;
|
||||||
typename point_type<Range>::type,
|
auto const& front = *first;
|
||||||
typename SideStrategy::equals_point_point_strategy_type
|
++first;
|
||||||
> not_equal;
|
return std::find_if(first, last, [&](auto const& pt) {
|
||||||
|
return ! equals::equals_point_point(pt, front, strategy);
|
||||||
BOOST_GEOMETRY_ASSERT(first != last);
|
});
|
||||||
|
|
||||||
Iterator second = first;
|
|
||||||
++second;
|
|
||||||
return std::find_if(second, last, not_equal(*first));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
static inline bool apply_at_closure(View const& view, VisitPolicy& visitor,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
bool is_linear)
|
bool is_linear)
|
||||||
{
|
{
|
||||||
boost::ignore_unused(visitor);
|
boost::ignore_unused(visitor);
|
||||||
@ -119,10 +82,9 @@ struct has_spikes
|
|||||||
|
|
||||||
iterator next = find_different_from_first(cur, boost::end(view),
|
iterator next = find_different_from_first(cur, boost::end(view),
|
||||||
strategy);
|
strategy);
|
||||||
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy))
|
if (detail::is_spike_or_equal(*next, *cur, *prev, strategy.side()))
|
||||||
{
|
{
|
||||||
return
|
return ! visitor.template apply<failure_spikes>(is_linear, *cur);
|
||||||
! visitor.template apply<failure_spikes>(is_linear, *cur);
|
|
||||||
}
|
}
|
||||||
else
|
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,
|
static inline bool apply(Range const& range, VisitPolicy& visitor,
|
||||||
SideStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
boost::ignore_unused(visitor);
|
boost::ignore_unused(visitor);
|
||||||
|
|
||||||
@ -169,7 +131,7 @@ struct has_spikes
|
|||||||
// in is_spike_or_equal, but this order calls the side
|
// in is_spike_or_equal, but this order calls the side
|
||||||
// strategy in the way to correctly detect the spikes,
|
// strategy in the way to correctly detect the spikes,
|
||||||
// also in geographic cases going over the pole
|
// 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
|
return
|
||||||
! visitor.template apply<failure_spikes>(is_linestring, *cur);
|
! 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);
|
next = find_different_from_first(cur, boost::end(view), strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometry::detail::equals::
|
if (equals::equals_point_point(range::front(view), range::back(view),
|
||||||
equals_point_point(range::front(view), range::back(view),
|
strategy))
|
||||||
strategy.get_equals_point_point_strategy()))
|
|
||||||
{
|
{
|
||||||
return apply_at_closure(view, visitor, strategy, is_linestring);
|
return apply_at_closure(view, visitor, strategy, is_linestring);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ namespace detail { namespace is_valid
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename CSTag
|
typename CSTag // TODO: remove
|
||||||
>
|
>
|
||||||
class has_valid_self_turns
|
class has_valid_self_turns
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Boost.Geometry
|
// 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 Menelaos Karavelas, on behalf of Oracle
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, 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/failing_reason_policy.hpp>
|
||||||
#include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
|
#include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -34,9 +35,14 @@ namespace boost { namespace geometry
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct is_valid
|
struct is_valid
|
||||||
{
|
{
|
||||||
template <typename Geometry, typename VisitPolicy, typename Strategy>
|
template <typename Geometry, typename VisitPolicy>
|
||||||
static inline bool apply(Geometry const& geometry,
|
static inline bool apply(Geometry const& geometry,
|
||||||
VisitPolicy& visitor,
|
VisitPolicy& visitor,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
@ -44,18 +50,41 @@ struct is_valid
|
|||||||
return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
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>
|
template <typename Geometry, typename VisitPolicy>
|
||||||
static inline bool apply(Geometry const& geometry,
|
static inline bool apply(Geometry const& geometry,
|
||||||
VisitPolicy& visitor,
|
VisitPolicy& visitor,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
// NOTE: Currently the strategy is only used for Areal geometries
|
// 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;
|
>::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>();
|
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
|
std::size_t num_distinct = detail::num_distinct_consecutive_points
|
||||||
<
|
<
|
||||||
Linestring,
|
Linestring, 3u, true
|
||||||
3u,
|
>::apply(linestring, strategy);
|
||||||
true,
|
|
||||||
not_equal_to
|
|
||||||
<
|
|
||||||
typename point_type<Linestring>::type,
|
|
||||||
typename Strategy::equals_point_point_strategy_type
|
|
||||||
>
|
|
||||||
>::apply(linestring);
|
|
||||||
|
|
||||||
if (num_distinct < 2u)
|
if (num_distinct < 2u)
|
||||||
{
|
{
|
||||||
@ -93,8 +86,7 @@ struct is_valid_linestring
|
|||||||
return ! has_spikes
|
return ! has_spikes
|
||||||
<
|
<
|
||||||
Linestring, closed
|
Linestring, closed
|
||||||
>::apply(linestring, visitor,
|
>::apply(linestring, visitor, strategy);
|
||||||
strategy.get_side_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
|
// call partition to check if polygons are disjoint from each other
|
||||||
typename base::template item_visitor_type<Strategy> item_visitor(strategy);
|
typename base::template item_visitor_type<Strategy> item_visitor(strategy);
|
||||||
|
|
||||||
@ -133,15 +125,8 @@ private:
|
|||||||
<
|
<
|
||||||
geometry::model::box<typename point_type<MultiPolygon>::type>
|
geometry::model::box<typename point_type<MultiPolygon>::type>
|
||||||
>::apply(polygon_iterators, item_visitor,
|
>::apply(polygon_iterators, item_visitor,
|
||||||
typename base::template expand_box
|
typename base::template expand_box<Strategy>(strategy),
|
||||||
<
|
typename base::template overlaps_box<Strategy>(strategy));
|
||||||
envelope_strategy_type
|
|
||||||
>(envelope_strategy),
|
|
||||||
typename base::template overlaps_box
|
|
||||||
<
|
|
||||||
envelope_strategy_type,
|
|
||||||
disjoint_box_box_strategy_type
|
|
||||||
>(envelope_strategy, disjoint_strategy));
|
|
||||||
|
|
||||||
if (item_visitor.items_overlap)
|
if (item_visitor.items_overlap)
|
||||||
{
|
{
|
||||||
|
@ -185,10 +185,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// structs for partition -- start
|
// structs for partition -- start
|
||||||
template <typename EnvelopeStrategy>
|
template <typename Strategy>
|
||||||
struct expand_box
|
struct expand_box
|
||||||
{
|
{
|
||||||
explicit expand_box(EnvelopeStrategy const& strategy)
|
explicit expand_box(Strategy const& strategy)
|
||||||
: m_strategy(strategy)
|
: m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -197,46 +197,38 @@ protected:
|
|||||||
{
|
{
|
||||||
geometry::expand(total,
|
geometry::expand(total,
|
||||||
item.get_envelope(m_strategy),
|
item.get_envelope(m_strategy),
|
||||||
// TEMP - envelope umbrella strategy also contains
|
m_strategy);
|
||||||
// expand strategies
|
|
||||||
strategies::envelope::services::strategy_converter
|
|
||||||
<
|
|
||||||
EnvelopeStrategy
|
|
||||||
>::get(m_strategy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvelopeStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename EnvelopeStrategy, typename DisjointBoxBoxStrategy>
|
template <typename Strategy>
|
||||||
struct overlaps_box
|
struct overlaps_box
|
||||||
{
|
{
|
||||||
explicit overlaps_box(EnvelopeStrategy const& envelope_strategy,
|
explicit overlaps_box(Strategy const& strategy)
|
||||||
DisjointBoxBoxStrategy const& disjoint_strategy)
|
: m_strategy(strategy)
|
||||||
: m_envelope_strategy(envelope_strategy)
|
|
||||||
, m_disjoint_strategy(disjoint_strategy)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Iterator>
|
template <typename Box, typename Iterator>
|
||||||
inline bool apply(Box const& box, partition_item<Iterator, Box> const& item) const
|
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,
|
box,
|
||||||
m_disjoint_strategy);
|
m_strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvelopeStrategy const& m_envelope_strategy;
|
Strategy const& m_strategy;
|
||||||
DisjointBoxBoxStrategy const& m_disjoint_strategy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename WithinStrategy>
|
template <typename Strategy>
|
||||||
struct item_visitor_type
|
struct item_visitor_type
|
||||||
{
|
{
|
||||||
bool items_overlap;
|
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)
|
: items_overlap(false)
|
||||||
, m_strategy(strategy)
|
, 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;
|
signed_size_type ring_index = 0;
|
||||||
for (RingIterator it = rings_first; it != rings_beyond;
|
for (RingIterator it = rings_first; it != rings_beyond;
|
||||||
++it, ++ring_index)
|
++it, ++ring_index)
|
||||||
@ -314,7 +298,7 @@ protected:
|
|||||||
// do not examine interior rings that have turns with the
|
// do not examine interior rings that have turns with the
|
||||||
// exterior ring
|
// exterior ring
|
||||||
if (ring_indices.find(ring_index) == ring_indices.end()
|
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>();
|
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
|
// call partition to check if interior rings are disjoint from
|
||||||
// each other
|
// each other
|
||||||
item_visitor_type<Strategy> item_visitor(strategy);
|
item_visitor_type<Strategy> item_visitor(strategy);
|
||||||
@ -358,15 +334,8 @@ protected:
|
|||||||
<
|
<
|
||||||
box_type
|
box_type
|
||||||
>::apply(ring_iterators, item_visitor,
|
>::apply(ring_iterators, item_visitor,
|
||||||
expand_box
|
expand_box<Strategy>(strategy),
|
||||||
<
|
overlaps_box<Strategy>(strategy));
|
||||||
envelope_strategy_type
|
|
||||||
>(envelope_strategy),
|
|
||||||
overlaps_box
|
|
||||||
<
|
|
||||||
envelope_strategy_type,
|
|
||||||
disjoint_box_box_strategy_type
|
|
||||||
>(envelope_strategy, disjoint_strategy));
|
|
||||||
|
|
||||||
if (item_visitor.items_overlap)
|
if (item_visitor.items_overlap)
|
||||||
{
|
{
|
||||||
|
@ -92,21 +92,7 @@ struct is_topologically_closed<Ring, closed>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: use calculate_point_order here
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Ring, bool IsInteriorRing>
|
template <typename Ring, bool IsInteriorRing>
|
||||||
struct is_properly_oriented
|
struct is_properly_oriented
|
||||||
{
|
{
|
||||||
@ -122,25 +108,15 @@ struct is_properly_oriented
|
|||||||
geometry::closure<Ring>::value
|
geometry::closure<Ring>::value
|
||||||
> ring_area_type;
|
> ring_area_type;
|
||||||
|
|
||||||
typedef typename Strategy::template area_strategy
|
std::conditional_t
|
||||||
<
|
<
|
||||||
Ring
|
IsInteriorRing, std::less<>, std::greater<>
|
||||||
>::type::template result_type<Ring>::type area_result_type;
|
> predicate;
|
||||||
|
|
||||||
typename ring_area_predicate
|
|
||||||
<
|
|
||||||
area_result_type, IsInteriorRing
|
|
||||||
>::type predicate;
|
|
||||||
|
|
||||||
// Check area
|
// Check area
|
||||||
area_result_type const zero = 0;
|
auto const area = ring_area_type::apply(ring, strategy);
|
||||||
area_result_type const area
|
decltype(area) const zero = 0;
|
||||||
= 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>()));
|
|
||||||
if (predicate(area, zero))
|
if (predicate(area, zero))
|
||||||
{
|
{
|
||||||
return visitor.template apply<no_failure>();
|
return visitor.template apply<no_failure>();
|
||||||
@ -166,8 +142,6 @@ struct is_valid_ring
|
|||||||
static inline bool apply(Ring const& ring, VisitPolicy& visitor,
|
static inline bool apply(Ring const& ring, VisitPolicy& visitor,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename Strategy::cs_tag cs_tag;
|
|
||||||
|
|
||||||
// return invalid if any of the following condition holds:
|
// return invalid if any of the following condition holds:
|
||||||
// (a) the ring's point coordinates are not invalid (e.g., NaN)
|
// (a) the ring's point coordinates are not invalid (e.g., NaN)
|
||||||
// (b) the ring's size is below the minimal one
|
// (b) the ring's size is below the minimal one
|
||||||
@ -199,13 +173,8 @@ struct is_valid_ring
|
|||||||
view_type const view(ring);
|
view_type const view(ring);
|
||||||
if (detail::num_distinct_consecutive_points
|
if (detail::num_distinct_consecutive_points
|
||||||
<
|
<
|
||||||
view_type, 4u, true,
|
view_type, 4u, true
|
||||||
not_equal_to
|
>::apply(view, strategy)
|
||||||
<
|
|
||||||
typename point_type<Ring>::type,
|
|
||||||
typename Strategy::equals_point_point_strategy_type
|
|
||||||
>
|
|
||||||
>::apply(view)
|
|
||||||
< 4u)
|
< 4u)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
@ -213,9 +182,9 @@ struct is_valid_ring
|
|||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
is_topologically_closed<Ring, closure>::apply(ring, visitor, strategy.get_equals_point_point_strategy())
|
is_topologically_closed<Ring, closure>::apply(ring, visitor, strategy)
|
||||||
&& ! has_duplicates<Ring, closure, cs_tag>::apply(ring, visitor)
|
&& ! has_duplicates<Ring, closure>::apply(ring, visitor, strategy)
|
||||||
&& ! has_spikes<Ring, closure>::apply(ring, visitor, strategy.get_side_strategy())
|
&& ! has_spikes<Ring, closure>::apply(ring, visitor, strategy)
|
||||||
&& (! CheckSelfIntersections
|
&& (! CheckSelfIntersections
|
||||||
|| has_valid_self_turns<Ring, typename Strategy::cs_tag>::apply(ring, visitor, strategy))
|
|| has_valid_self_turns<Ring, typename Strategy::cs_tag>::apply(ring, visitor, strategy))
|
||||||
&& is_properly_oriented<Ring, IsInteriorRing>::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>
|
struct is_valid<Segment, segment_tag>
|
||||||
{
|
{
|
||||||
template <typename VisitPolicy, typename Strategy>
|
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);
|
boost::ignore_unused(visitor);
|
||||||
|
|
||||||
typename point_type<Segment>::type p[2];
|
typename point_type<Segment>::type p[2];
|
||||||
@ -62,8 +60,7 @@ struct is_valid<Segment, segment_tag>
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (! geometry::detail::equals::equals_point_point(
|
else if (! detail::equals::equals_point_point(p[0], p[1], strategy))
|
||||||
p[0], p[1], eq_pp_strategy_type()))
|
|
||||||
{
|
{
|
||||||
return visitor.template apply<no_failure>();
|
return visitor.template apply<no_failure>();
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,12 @@ template
|
|||||||
<
|
<
|
||||||
typename Range,
|
typename Range,
|
||||||
std::size_t MaximumNumber,
|
std::size_t MaximumNumber,
|
||||||
bool AllowDuplicates /* true */,
|
bool AllowDuplicates /* true */
|
||||||
typename NotEqualTo
|
|
||||||
>
|
>
|
||||||
struct num_distinct_consecutive_points
|
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;
|
typedef typename boost::range_iterator<Range const>::type iterator;
|
||||||
|
|
||||||
@ -58,26 +58,28 @@ struct num_distinct_consecutive_points
|
|||||||
}
|
}
|
||||||
|
|
||||||
iterator current = boost::begin(range);
|
iterator current = boost::begin(range);
|
||||||
|
iterator const end = boost::end(range);
|
||||||
std::size_t counter(0);
|
std::size_t counter(0);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
++counter;
|
++counter;
|
||||||
iterator next = std::find_if(current,
|
iterator next = std::find_if(current, end, [&](auto const& pt) {
|
||||||
boost::end(range),
|
return ! equals::equals_point_point(pt, *current, strategy);
|
||||||
NotEqualTo(*current));
|
});
|
||||||
current = next;
|
current = next;
|
||||||
}
|
}
|
||||||
while ( current != boost::end(range) && counter <= MaximumNumber );
|
while ( current != end && counter <= MaximumNumber );
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename Range, std::size_t MaximumNumber, typename NotEqualTo>
|
template <typename Range, std::size_t MaximumNumber>
|
||||||
struct num_distinct_consecutive_points<Range, MaximumNumber, false, NotEqualTo>
|
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);
|
std::size_t const size = boost::size(range);
|
||||||
return (size < MaximumNumber) ? size : MaximumNumber;
|
return (size < MaximumNumber) ? size : MaximumNumber;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2014, 2015, 2017.
|
// This file was modified by Oracle on 2014-2021.
|
||||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -28,7 +28,9 @@
|
|||||||
|
|
||||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
#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
|
namespace boost { namespace geometry
|
||||||
@ -60,6 +62,68 @@ struct overlaps
|
|||||||
#endif // DOXYGEN_NO_DISPATCH
|
#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}
|
\brief \brief_check2{overlap}
|
||||||
\ingroup overlaps
|
\ingroup overlaps
|
||||||
@ -82,10 +146,9 @@ inline bool overlaps(Geometry1 const& geometry1,
|
|||||||
concepts::check<Geometry1 const>();
|
concepts::check<Geometry1 const>();
|
||||||
concepts::check<Geometry2 const>();
|
concepts::check<Geometry2 const>();
|
||||||
|
|
||||||
return dispatch::overlaps
|
return resolve_strategy::overlaps
|
||||||
<
|
<
|
||||||
Geometry1,
|
Strategy
|
||||||
Geometry2
|
|
||||||
>::apply(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<Geometry1 const>();
|
||||||
concepts::check<Geometry2 const>();
|
concepts::check<Geometry2 const>();
|
||||||
|
|
||||||
typedef typename strategy::relate::services::default_strategy
|
return resolve_strategy::overlaps
|
||||||
<
|
|
||||||
Geometry1,
|
|
||||||
Geometry2
|
|
||||||
>::type strategy_type;
|
|
||||||
|
|
||||||
return dispatch::overlaps
|
|
||||||
<
|
<
|
||||||
Geometry1,
|
default_strategy
|
||||||
Geometry2
|
>::apply(geometry1, geometry2, default_strategy());
|
||||||
>::apply(geometry1, geometry2, strategy_type());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace boost::geometry
|
}} // namespace boost::geometry
|
||||||
|
@ -87,22 +87,17 @@ template
|
|||||||
typename Geometry2,
|
typename Geometry2,
|
||||||
typename RingCollection,
|
typename RingCollection,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename AreaStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
inline OutputIterator add_rings(SelectionMap const& map,
|
inline OutputIterator add_rings(SelectionMap const& map,
|
||||||
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||||
RingCollection const& collection,
|
RingCollection const& collection,
|
||||||
OutputIterator out,
|
OutputIterator out,
|
||||||
AreaStrategy const& area_strategy,
|
Strategy const& strategy,
|
||||||
add_rings_error_handling error_handling = add_rings_ignore_unordered)
|
add_rings_error_handling error_handling = add_rings_ignore_unordered)
|
||||||
{
|
{
|
||||||
typedef typename SelectionMap::const_iterator iterator;
|
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
|
std::size_t const min_num_points = core_detail::closure::minimum_ring_size
|
||||||
<
|
<
|
||||||
geometry::closure
|
geometry::closure
|
||||||
@ -146,7 +141,9 @@ inline OutputIterator add_rings(SelectionMap const& map,
|
|||||||
// everything is figured out yet (sum of positive/negative rings)
|
// everything is figured out yet (sum of positive/negative rings)
|
||||||
if (geometry::num_points(result) >= min_num_points)
|
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
|
// Ignore if area is 0
|
||||||
if (! math::equals(area, zero))
|
if (! math::equals(area, zero))
|
||||||
{
|
{
|
||||||
@ -174,16 +171,16 @@ template
|
|||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename RingCollection,
|
typename RingCollection,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename AreaStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
inline OutputIterator add_rings(SelectionMap const& map,
|
inline OutputIterator add_rings(SelectionMap const& map,
|
||||||
Geometry const& geometry,
|
Geometry const& geometry,
|
||||||
RingCollection const& collection,
|
RingCollection const& collection,
|
||||||
OutputIterator out,
|
OutputIterator out,
|
||||||
AreaStrategy const& area_strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
Geometry empty;
|
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);
|
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,
|
inline void append_no_duplicates(Range& range, Point const& point,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if ( boost::empty(range)
|
if ( boost::empty(range)
|
||||||
|| ! geometry::detail::equals::equals_point_point(geometry::range::back(range),
|
|| ! geometry::detail::equals::equals_point_point(geometry::range::back(range),
|
||||||
|
@ -41,11 +41,11 @@ namespace detail { namespace overlay
|
|||||||
{
|
{
|
||||||
|
|
||||||
// TODO: move this / rename this
|
// 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,
|
inline bool points_equal_or_close(Point1 const& point1,
|
||||||
Point2 const& point2,
|
Point2 const& point2,
|
||||||
EqualsStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
if (detail::equals::equals_point_point(point1, point2, strategy))
|
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,
|
inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||||
std::cout << " add: ("
|
std::cout << " add: ("
|
||||||
@ -93,8 +93,7 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
|||||||
// for geometries >= 3 points.
|
// for geometries >= 3 points.
|
||||||
// So we have to check the first potential duplicate differently
|
// So we have to check the first potential duplicate differently
|
||||||
if ( boost::size(range) == 1
|
if ( boost::size(range) == 1
|
||||||
&& points_equal_or_close(*(boost::begin(range)), point,
|
&& points_equal_or_close(*(boost::begin(range)), point, strategy,
|
||||||
strategy.get_equals_point_point_strategy(),
|
|
||||||
robust_policy) )
|
robust_policy) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -111,7 +110,7 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
|
|||||||
&& point_is_spike_or_equal(point,
|
&& point_is_spike_or_equal(point,
|
||||||
*(boost::end(range) - 3),
|
*(boost::end(range) - 3),
|
||||||
*(boost::end(range) - 2),
|
*(boost::end(range) - 2),
|
||||||
strategy,
|
strategy.side(), // TODO: Pass strategy?
|
||||||
robust_policy))
|
robust_policy))
|
||||||
{
|
{
|
||||||
// Use the Concept/traits, so resize and append again
|
// 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,
|
inline void append_no_collinear(Range& range, Point const& point,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
// Stricter version, not allowing any point in a linear row
|
// Stricter version, not allowing any point in a linear row
|
||||||
// (spike, continuation or same point)
|
// (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
|
// So we have to check the first potential duplicate differently
|
||||||
if ( boost::size(range) == 1
|
if ( boost::size(range) == 1
|
||||||
&& points_equal_or_close(*(boost::begin(range)), point,
|
&& points_equal_or_close(*(boost::begin(range)), point,
|
||||||
strategy.get_equals_point_point_strategy(),
|
strategy,
|
||||||
robust_policy) )
|
robust_policy) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -150,7 +149,7 @@ inline void append_no_collinear(Range& range, Point const& point,
|
|||||||
&& point_is_collinear(point,
|
&& point_is_collinear(point,
|
||||||
*(boost::end(range) - 3),
|
*(boost::end(range) - 3),
|
||||||
*(boost::end(range) - 2),
|
*(boost::end(range) - 2),
|
||||||
strategy,
|
strategy.side(), // TODO: Pass strategy?
|
||||||
robust_policy))
|
robust_policy))
|
||||||
{
|
{
|
||||||
// Use the Concept/traits, so resize and append again
|
// 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,
|
inline void clean_closing_dups_and_spikes(Range& range,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
std::size_t const minsize
|
std::size_t const minsize
|
||||||
= core_detail::closure::minimum_ring_size
|
= 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
|
// Check if closing point is a spike (this is so if the second point is
|
||||||
// considered as collinear w.r.t. the last segment)
|
// 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);
|
range::erase(range, first);
|
||||||
if (BOOST_GEOMETRY_CONDITION(closed))
|
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
|
struct ring_info_helper_get_box
|
||||||
{
|
{
|
||||||
|
ring_info_helper_get_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename InputItem>
|
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);
|
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
|
struct ring_info_helper_overlaps_box
|
||||||
{
|
{
|
||||||
|
ring_info_helper_overlaps_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename InputItem>
|
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);
|
assert_coordinate_type_equal(box, item.envelope);
|
||||||
return ! geometry::detail::disjoint::disjoint_box_box(
|
return ! geometry::detail::disjoint::disjoint_box_box(
|
||||||
box, item.envelope, DisjointBoxBoxStrategy());
|
box, item.envelope, m_strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Segments intersection Strategy
|
// Segments intersection Strategy
|
||||||
@ -196,8 +208,7 @@ struct assign_visitor
|
|||||||
{
|
{
|
||||||
ring_info_type& inner_in_map = m_ring_map[inner.id];
|
ring_info_type& inner_in_map = m_ring_map[inner.id];
|
||||||
|
|
||||||
if (geometry::covered_by(inner_in_map.point, outer.envelope,
|
if (geometry::covered_by(inner_in_map.point, outer.envelope, m_strategy)
|
||||||
typename Strategy::disjoint_point_box_strategy_type())
|
|
||||||
&& within_selected_input(inner_in_map, inner.id, outer.id,
|
&& within_selected_input(inner_in_map, inner.id, outer.id,
|
||||||
m_geometry1, m_geometry2, m_collection,
|
m_geometry1, m_geometry2, m_collection,
|
||||||
m_strategy)
|
m_strategy)
|
||||||
@ -244,10 +255,10 @@ inline void assign_parents(Geometry1 const& geometry1,
|
|||||||
typedef typename RingMap::mapped_type ring_info_type;
|
typedef typename RingMap::mapped_type ring_info_type;
|
||||||
typedef typename ring_info_type::point_type point_type;
|
typedef typename ring_info_type::point_type point_type;
|
||||||
typedef model::box<point_type> box_type;
|
typedef model::box<point_type> box_type;
|
||||||
typedef typename Strategy::template area_strategy
|
typedef typename geometry::area_result
|
||||||
<
|
<
|
||||||
point_type
|
point_type, Strategy // TODO: point_type is technically incorrect
|
||||||
>::type::template result_type<point_type>::type area_result_type;
|
>::type area_result_type;
|
||||||
|
|
||||||
typedef typename RingMap::iterator map_iterator_type;
|
typedef typename RingMap::iterator map_iterator_type;
|
||||||
|
|
||||||
@ -273,15 +284,15 @@ inline void assign_parents(Geometry1 const& geometry1,
|
|||||||
{
|
{
|
||||||
case 0 :
|
case 0 :
|
||||||
geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
|
geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
|
||||||
item.envelope, strategy.get_envelope_strategy());
|
item.envelope, strategy);
|
||||||
break;
|
break;
|
||||||
case 1 :
|
case 1 :
|
||||||
geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
|
geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
|
||||||
item.envelope, strategy.get_envelope_strategy());
|
item.envelope, strategy);
|
||||||
break;
|
break;
|
||||||
case 2 :
|
case 2 :
|
||||||
geometry::envelope(get_ring<void>::apply(it->first, collection),
|
geometry::envelope(get_ring<void>::apply(it->first, collection),
|
||||||
item.envelope, strategy.get_envelope_strategy());
|
item.envelope, strategy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,19 +347,12 @@ inline void assign_parents(Geometry1 const& geometry1,
|
|||||||
Strategy
|
Strategy
|
||||||
> visitor(geometry1, geometry2, collection, ring_map, strategy, check_for_orientation);
|
> 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
|
geometry::partition
|
||||||
<
|
<
|
||||||
box_type
|
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)
|
if (check_for_orientation)
|
||||||
|
@ -61,14 +61,14 @@ struct copy_segments_ring
|
|||||||
<
|
<
|
||||||
typename Ring,
|
typename Ring,
|
||||||
typename SegmentIdentifier,
|
typename SegmentIdentifier,
|
||||||
typename SideStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename RangeOut
|
typename RangeOut
|
||||||
>
|
>
|
||||||
static inline void apply(Ring const& ring,
|
static inline void apply(Ring const& ring,
|
||||||
SegmentIdentifier const& seg_id,
|
SegmentIdentifier const& seg_id,
|
||||||
signed_size_type to_index,
|
signed_size_type to_index,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
RangeOut& current_output)
|
RangeOut& current_output)
|
||||||
{
|
{
|
||||||
@ -125,10 +125,10 @@ class copy_segments_linestring
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// remove spikes
|
// 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,
|
static inline void append_to_output(RangeOut& current_output,
|
||||||
Point const& point,
|
Point const& point,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
std::true_type const&)
|
std::true_type const&)
|
||||||
{
|
{
|
||||||
@ -138,14 +138,14 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// keep spikes
|
// 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,
|
static inline void append_to_output(RangeOut& current_output,
|
||||||
Point const& point,
|
Point const& point,
|
||||||
SideStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const&,
|
RobustPolicy const&,
|
||||||
std::false_type 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:
|
public:
|
||||||
|
@ -524,7 +524,7 @@ inline void enrich_intersection_points(Turns& turns,
|
|||||||
detail::overlay::enrich_sort<Reverse1, Reverse2>(
|
detail::overlay::enrich_sort<Reverse1, Reverse2>(
|
||||||
mit->second, turns,
|
mit->second, turns,
|
||||||
geometry1, geometry2,
|
geometry1, geometry2,
|
||||||
robust_policy, strategy.get_side_strategy());
|
robust_policy, strategy.side()); // TODO: pass strategy
|
||||||
}
|
}
|
||||||
|
|
||||||
for (typename mapped_vector_type::iterator mit
|
for (typename mapped_vector_type::iterator mit
|
||||||
@ -554,7 +554,7 @@ inline void enrich_intersection_points(Turns& turns,
|
|||||||
Reverse2,
|
Reverse2,
|
||||||
OverlayType
|
OverlayType
|
||||||
>(clusters, turns, target_operation,
|
>(clusters, turns, target_operation,
|
||||||
geometry1, geometry2, strategy.get_side_strategy());
|
geometry1, geometry2, strategy.side()); // TODO: pass strategy
|
||||||
|
|
||||||
detail::overlay::cleanup_clusters(turns, clusters);
|
detail::overlay::cleanup_clusters(turns, clusters);
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,11 @@ template
|
|||||||
typename Operation,
|
typename Operation,
|
||||||
typename LineString,
|
typename LineString,
|
||||||
typename Polygon,
|
typename Polygon,
|
||||||
typename PtInPolyStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
inline bool last_covered_by(Turn const& /*turn*/, Operation const& op,
|
inline bool last_covered_by(Turn const& /*turn*/, Operation const& op,
|
||||||
LineString const& linestring, Polygon const& polygon,
|
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);
|
return geometry::covered_by(range::at(linestring, op.seg_id.segment_index), polygon, strategy);
|
||||||
}
|
}
|
||||||
@ -78,12 +78,12 @@ template
|
|||||||
typename Operation,
|
typename Operation,
|
||||||
typename LineString,
|
typename LineString,
|
||||||
typename Polygon,
|
typename Polygon,
|
||||||
typename PtInPolyStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
inline bool is_leaving(Turn const& turn, Operation const& op,
|
inline bool is_leaving(Turn const& turn, Operation const& op,
|
||||||
bool entered, bool first,
|
bool entered, bool first,
|
||||||
LineString const& linestring, Polygon const& polygon,
|
LineString const& linestring, Polygon const& polygon,
|
||||||
PtInPolyStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if (op.operation == operation_union)
|
if (op.operation == operation_union)
|
||||||
{
|
{
|
||||||
@ -104,12 +104,12 @@ template
|
|||||||
typename Operation,
|
typename Operation,
|
||||||
typename LineString,
|
typename LineString,
|
||||||
typename Polygon,
|
typename Polygon,
|
||||||
typename PtInPolyStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
inline bool is_staying_inside(Turn const& turn, Operation const& op,
|
inline bool is_staying_inside(Turn const& turn, Operation const& op,
|
||||||
bool entered, bool first,
|
bool entered, bool first,
|
||||||
LineString const& linestring, Polygon const& polygon,
|
LineString const& linestring, Polygon const& polygon,
|
||||||
PtInPolyStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if (turn.method == method_crosses)
|
if (turn.method == method_crosses)
|
||||||
{
|
{
|
||||||
@ -132,11 +132,11 @@ template
|
|||||||
typename Operation,
|
typename Operation,
|
||||||
typename Linestring,
|
typename Linestring,
|
||||||
typename Polygon,
|
typename Polygon,
|
||||||
typename PtInPolyStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
inline bool was_entered(Turn const& turn, Operation const& op, bool first,
|
inline bool was_entered(Turn const& turn, Operation const& op, bool first,
|
||||||
Linestring const& linestring, Polygon const& polygon,
|
Linestring const& linestring, Polygon const& polygon,
|
||||||
PtInPolyStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if (first && (turn.method == method_collinear || turn.method == method_equal))
|
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
|
// On enter, append the intersection point and remember starting point
|
||||||
// TODO: we don't check on spikes for linestrings (?). Consider this.
|
// 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;
|
segment_id = operation.seg_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
|
|||||||
<
|
<
|
||||||
false, RemoveSpikes
|
false, RemoveSpikes
|
||||||
>::apply(linestring, segment_id, index, strategy, robust_policy, current_piece);
|
>::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)
|
if (::boost::size(current_piece) > 1)
|
||||||
{
|
{
|
||||||
*out++ = current_piece;
|
*out++ = current_piece;
|
||||||
@ -431,14 +431,6 @@ public :
|
|||||||
|
|
||||||
typedef following::action_selector<OverlayType, RemoveSpikes> action;
|
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
|
// Sort intersection points on segments-along-linestring, and distance
|
||||||
// (like in enrich is done for poly/poly)
|
// (like in enrich is done for poly/poly)
|
||||||
// sort turns by Linear seg_id, then by fraction, then
|
// sort turns by Linear seg_id, then by fraction, then
|
||||||
@ -446,7 +438,8 @@ public :
|
|||||||
// for different ring id: c, i, u, x
|
// for different ring id: c, i, u, x
|
||||||
typedef relate::turns::less
|
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;
|
> turn_less;
|
||||||
std::sort(boost::begin(turns), boost::end(turns), 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);
|
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");
|
debug_traverse(*it, *iit, "-> Was entered");
|
||||||
entered = true;
|
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");
|
debug_traverse(*it, *iit, "-> Staying inside");
|
||||||
|
|
||||||
@ -482,7 +475,7 @@ public :
|
|||||||
strategy, robust_policy,
|
strategy, robust_policy,
|
||||||
linear::get(out));
|
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");
|
debug_traverse(*it, *iit, "-> Leaving");
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ struct get_turn_without_info
|
|||||||
> policy_type;
|
> policy_type;
|
||||||
|
|
||||||
typename policy_type::return_type const result
|
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++)
|
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) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2015, 2017, 2018, 2019.
|
// This file was modified by Oracle on 2015-2020.
|
||||||
// Modifications copyright (c) 2015-2019 Oracle and/or its affiliates.
|
// Modifications copyright (c) 2015-2020 Oracle and/or its affiliates.
|
||||||
|
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// 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
|
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
|
||||||
#define 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/core/ignore_unused.hpp>
|
||||||
#include <boost/throw_exception.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/get_distance_measure.hpp>
|
||||||
#include <boost/geometry/algorithms/detail/overlay/turn_info.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>
|
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp>
|
||||||
|
|
||||||
// Silence warning C4127: conditional expression is constant
|
// Silence warning C4127: conditional expression is constant
|
||||||
@ -131,15 +127,7 @@ struct base_turn_handler
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef typename select_coordinate_type
|
auto const dm = get_distance_measure(range_p.at(range_index), range_p.at(range_index + 1), range_q.at(point_index));
|
||||||
<
|
|
||||||
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));
|
|
||||||
return dm.measure == 0 ? 0 : dm.measure > 0 ? 1 : -1;
|
return dm.measure == 0 ? 0 : dm.measure > 0 ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +174,8 @@ struct base_turn_handler
|
|||||||
{
|
{
|
||||||
ti.method = method;
|
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;
|
static int const index = 0;
|
||||||
|
|
||||||
geometry::convert(info.intersections[index], ti.point);
|
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
|
// TODO: use comparable distance for point-point instead - but that
|
||||||
// causes currently cycling include problems
|
// causes currently cycling include problems
|
||||||
typedef typename geometry::coordinate_type<Point1>::type ctype;
|
auto const dx = get<0>(a) - get<0>(b);
|
||||||
ctype const dx = get<0>(a) - get<0>(b);
|
auto const dy = get<1>(a) - get<1>(b);
|
||||||
ctype const dy = get<1>(a) - get<1>(b);
|
|
||||||
return dx * dx + dy * dy;
|
return dx * dx + dy * dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,19 +247,10 @@ struct base_turn_handler
|
|||||||
// pk/q2 is considered as collinear, but there might be
|
// pk/q2 is considered as collinear, but there might be
|
||||||
// a tiny measurable difference. If so, use that.
|
// a tiny measurable difference. If so, use that.
|
||||||
// Calculate pk // qj-qk
|
// Calculate pk // qj-qk
|
||||||
typedef detail::distance_measure
|
bool const p_closer =
|
||||||
<
|
|
||||||
typename select_coordinate_type
|
|
||||||
<
|
|
||||||
typename UniqueSubRange1::point_type,
|
|
||||||
typename UniqueSubRange2::point_type
|
|
||||||
>::type
|
|
||||||
> dm_type;
|
|
||||||
|
|
||||||
const bool p_closer =
|
|
||||||
ti.operations[IndexP].remaining_distance
|
ti.operations[IndexP].remaining_distance
|
||||||
< ti.operations[IndexQ].remaining_distance;
|
< ti.operations[IndexQ].remaining_distance;
|
||||||
dm_type const dm
|
auto const dm
|
||||||
= p_closer
|
= p_closer
|
||||||
? get_distance_measure(range_q.at(index_q - 1),
|
? get_distance_measure(range_q.at(index_q - 1),
|
||||||
range_q.at(index_q), range_p.at(index_p))
|
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
|
// Not truely collinear, distinguish for union/intersection
|
||||||
// If p goes left (positive), take that for a union
|
// If p goes left (positive), take that for a union
|
||||||
|
bool const p_left = p_closer ? dm.is_positive() : dm.is_negative();
|
||||||
bool p_left = p_closer ? dm.is_positive() : dm.is_negative();
|
|
||||||
|
|
||||||
ti.operations[IndexP].operation = p_left
|
ti.operations[IndexP].operation = p_left
|
||||||
? operation_union : operation_intersection;
|
? 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
|
// Therefore handle it as a normal touch (two segments arrive at the
|
||||||
// intersection point). It currently checks for zero, but even a
|
// intersection point). It currently checks for zero, but even a
|
||||||
// distance a little bit larger would do.
|
// distance a little bit larger would do.
|
||||||
typedef typename geometry::coordinate_type
|
auto const dm = distance_measure(info.intersections[0], non_touching_range.at(1));
|
||||||
<
|
decltype(dm) const zero = 0;
|
||||||
typename UniqueSubRange::point_type
|
bool const result = math::equals(dm, zero);
|
||||||
>::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);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,16 +513,8 @@ struct touch : public base_turn_handler
|
|||||||
// >----->P qj is LEFT of P1 and pi is LEFT of Q2
|
// >----->P qj is LEFT of P1 and pi is LEFT of Q2
|
||||||
// (the other way round is also possible)
|
// (the other way round is also possible)
|
||||||
|
|
||||||
typedef typename select_coordinate_type
|
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));
|
||||||
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));
|
|
||||||
|
|
||||||
if (dm_qj_p1.measure > 0 && dm_pi_q2.measure > 0)
|
if (dm_qj_p1.measure > 0 && dm_pi_q2.measure > 0)
|
||||||
{
|
{
|
||||||
@ -564,8 +529,8 @@ struct touch : public base_turn_handler
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_type const dm_pj_q1 = get_distance_measure(range_q.at(0), range_q.at(1), range_p.at(1));
|
auto 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_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)
|
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
|
// They turn to the same side, or continue both collinearly
|
||||||
// Without rescaling, to check for union/intersection,
|
// Without rescaling, to check for union/intersection,
|
||||||
// try to check side values (without any thresholds)
|
// try to check side values (without any thresholds)
|
||||||
typedef typename select_coordinate_type
|
auto const dm_pk_q2
|
||||||
<
|
|
||||||
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
|
|
||||||
= get_distance_measure(range_q.at(1), range_q.at(2), range_p.at(2));
|
= 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));
|
= get_distance_measure(range_p.at(1), range_p.at(2), range_q.at(2));
|
||||||
|
|
||||||
if (dm_qk_p2.measure != dm_pk_q2.measure)
|
if (dm_qk_p2.measure != dm_pk_q2.measure)
|
||||||
@ -965,8 +922,57 @@ template
|
|||||||
>
|
>
|
||||||
struct collinear : public base_turn_handler
|
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 CLL1 ui
|
||||||
-1 1 -1 CLL2 iu
|
-1 1 -1 CLL2 iu
|
||||||
1 1 1 CLR1 ui
|
1 1 1 CLR1 ui
|
||||||
@ -980,7 +986,9 @@ struct collinear : public base_turn_handler
|
|||||||
1 0 0 CC1 cc
|
1 0 0 CC1 cc
|
||||||
-1 0 0 CC2 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:
|
Stated otherwise:
|
||||||
- if P arrives: look at turn P
|
- 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 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 left: union for Q (=intersection for P)
|
||||||
- if Q arrives and Q turns right: intersection for Q (=union 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
|
template
|
||||||
<
|
<
|
||||||
@ -1016,9 +1017,9 @@ struct collinear : public base_turn_handler
|
|||||||
// Copy the intersection point in TO direction
|
// Copy the intersection point in TO direction
|
||||||
assign_point(ti, method_collinear, info, non_opposite_to_index(info));
|
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
|
// 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_pk = ! range_p.is_last_segment();
|
||||||
bool const has_qk = ! range_q.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;
|
int const side_q = has_qk ? side.qk_wrt_q1() : 0;
|
||||||
|
|
||||||
// If p arrives, use p, else use q
|
// 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_p
|
||||||
: side_q
|
: side_q
|
||||||
;
|
;
|
||||||
|
|
||||||
// See comments above,
|
// Calculate product according to comments above.
|
||||||
// resulting in a strange sort of mathematic rule here:
|
int const product = arrival_p * side_p_or_q;
|
||||||
// The arrival-info multiplied by the relevant side
|
|
||||||
// delivers a consistent result.
|
|
||||||
|
|
||||||
int const product = arrival * side_p_or_q;
|
if (product == 0)
|
||||||
|
|
||||||
if(product == 0)
|
|
||||||
{
|
{
|
||||||
both(ti, operation_continue);
|
both(ti, operation_continue);
|
||||||
}
|
}
|
||||||
@ -1186,11 +1183,11 @@ public:
|
|||||||
{
|
{
|
||||||
TurnInfo tp = tp_model;
|
TurnInfo tp = tp_model;
|
||||||
|
|
||||||
int const p_arrival = info.d_info().arrival[0];
|
int const arrival_p = info.d_info().arrival[0];
|
||||||
int const q_arrival = info.d_info().arrival[1];
|
int const arrival_q = info.d_info().arrival[1];
|
||||||
|
|
||||||
// If P arrives within Q, there is a turn dependent on P
|
// 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()
|
&& ! range_p.is_last_segment()
|
||||||
&& set_tp<0>(side.pk_wrt_p1(), tp, info.i_info()) )
|
&& 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 arrives within P, there is a turn dependent on Q
|
||||||
if ( q_arrival == 1
|
if ( arrival_q == 1
|
||||||
&& ! range_q.is_last_segment()
|
&& ! range_q.is_last_segment()
|
||||||
&& set_tp<1>(side.qk_wrt_q1(), tp, info.i_info()) )
|
&& set_tp<1>(side.qk_wrt_q1(), tp, info.i_info()) )
|
||||||
{
|
{
|
||||||
@ -1212,8 +1209,8 @@ public:
|
|||||||
if (AssignPolicy::include_opposite)
|
if (AssignPolicy::include_opposite)
|
||||||
{
|
{
|
||||||
// Handle cases not yet handled above
|
// Handle cases not yet handled above
|
||||||
if ((q_arrival == -1 && p_arrival == 0)
|
if ((arrival_q == -1 && arrival_p == 0)
|
||||||
|| (p_arrival == -1 && q_arrival == 0))
|
|| (arrival_p == -1 && arrival_q == 0))
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < 2; i++)
|
for (unsigned int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
@ -1396,7 +1393,7 @@ struct get_turn_info
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
handler::template apply<1>(range_q, range_p, tp, inters.i_info(), inters.d_info(),
|
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;
|
*out++ = tp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1420,9 +1417,10 @@ struct get_turn_info
|
|||||||
// Collinear
|
// Collinear
|
||||||
if ( ! inters.d_info().opposite )
|
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;
|
handle_as_equal = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -111,12 +111,16 @@ namespace detail { namespace overlay {
|
|||||||
class linear_intersections
|
class linear_intersections
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename Point1, typename Point2, typename IntersectionResult, typename EqPPStrategy>
|
template
|
||||||
|
<
|
||||||
|
typename Point1, typename Point2, typename IntersectionResult,
|
||||||
|
typename Strategy
|
||||||
|
>
|
||||||
linear_intersections(Point1 const& pi,
|
linear_intersections(Point1 const& pi,
|
||||||
Point2 const& qi,
|
Point2 const& qi,
|
||||||
IntersectionResult const& result,
|
IntersectionResult const& result,
|
||||||
bool is_p_last, bool is_q_last,
|
bool is_p_last, bool is_q_last,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
int arrival_a = result.direction.arrival[0];
|
int arrival_a = result.direction.arrival[0];
|
||||||
int arrival_b = result.direction.arrival[1];
|
int arrival_b = result.direction.arrival[1];
|
||||||
@ -237,7 +241,7 @@ struct get_turn_info_for_endpoint
|
|||||||
typename TurnInfo,
|
typename TurnInfo,
|
||||||
typename IntersectionInfo,
|
typename IntersectionInfo,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename EqPPStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
static inline bool apply(UniqueSubRange1 const& range_p,
|
static inline bool apply(UniqueSubRange1 const& range_p,
|
||||||
UniqueSubRange2 const& range_q,
|
UniqueSubRange2 const& range_q,
|
||||||
@ -245,7 +249,7 @@ struct get_turn_info_for_endpoint
|
|||||||
IntersectionInfo const& inters,
|
IntersectionInfo const& inters,
|
||||||
method_type /*method*/,
|
method_type /*method*/,
|
||||||
OutputIterator out,
|
OutputIterator out,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
std::size_t ip_count = inters.i_info().count;
|
std::size_t ip_count = inters.i_info().count;
|
||||||
// no intersection points
|
// no intersection points
|
||||||
@ -398,8 +402,7 @@ struct get_turn_info_for_endpoint
|
|||||||
{
|
{
|
||||||
boost::ignore_unused(ip_index, tp_model);
|
boost::ignore_unused(ip_index, tp_model);
|
||||||
|
|
||||||
typename IntersectionInfo::side_strategy_type const& sides
|
auto const strategy = inters.strategy();
|
||||||
= inters.get_side_strategy();
|
|
||||||
|
|
||||||
if ( !first2 && !last2 )
|
if ( !first2 && !last2 )
|
||||||
{
|
{
|
||||||
@ -409,8 +412,8 @@ struct get_turn_info_for_endpoint
|
|||||||
// may this give false positives for INTs?
|
// may this give false positives for INTs?
|
||||||
typename IntersectionResult::point_type const&
|
typename IntersectionResult::point_type const&
|
||||||
inters_pt = inters.i_info().intersections[ip_index];
|
inters_pt = inters.i_info().intersections[ip_index];
|
||||||
BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, 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));
|
BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt, strategy));
|
||||||
#endif
|
#endif
|
||||||
if ( ip_i2 )
|
if ( ip_i2 )
|
||||||
{
|
{
|
||||||
@ -421,6 +424,7 @@ struct get_turn_info_for_endpoint
|
|||||||
}
|
}
|
||||||
else if ( ip_j2 )
|
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_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_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));
|
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?
|
// may this give false positives for INTs?
|
||||||
typename IntersectionResult::point_type const&
|
typename IntersectionResult::point_type const&
|
||||||
inters_pt = inters.i_info().intersections[ip_index];
|
inters_pt = inters.i_info().intersections[ip_index];
|
||||||
BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, 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));
|
BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt, strategy));
|
||||||
#endif
|
#endif
|
||||||
if ( ip_i2 )
|
if ( ip_i2 )
|
||||||
{
|
{
|
||||||
@ -472,6 +476,7 @@ struct get_turn_info_for_endpoint
|
|||||||
}
|
}
|
||||||
else if ( ip_j2 )
|
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_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_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));
|
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
|
template
|
||||||
<
|
<
|
||||||
typename TurnPointCSTag,
|
|
||||||
typename UniqueSubRange1,
|
typename UniqueSubRange1,
|
||||||
typename UniqueSubRange2,
|
typename UniqueSubRange2,
|
||||||
typename SideStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
struct side_calculator
|
struct side_calculator
|
||||||
{
|
{
|
||||||
typedef typename UniqueSubRange1::point_type point1_type;
|
typedef typename UniqueSubRange1::point_type point1_type;
|
||||||
typedef typename UniqueSubRange2::point_type point2_type;
|
typedef typename UniqueSubRange2::point_type point2_type;
|
||||||
|
typedef decltype(std::declval<Strategy>().side()) side_strategy_type;
|
||||||
|
|
||||||
inline side_calculator(UniqueSubRange1 const& range_p,
|
inline side_calculator(UniqueSubRange1 const& range_p,
|
||||||
UniqueSubRange2 const& range_q,
|
UniqueSubRange2 const& range_q,
|
||||||
SideStrategy const& side_strategy)
|
Strategy const& strategy)
|
||||||
: m_side_strategy(side_strategy)
|
: m_side_strategy(strategy.side())
|
||||||
, m_range_p(range_p)
|
, m_range_p(range_p)
|
||||||
, m_range_q(range_q)
|
, 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_qj() const { return m_range_q.at(1); }
|
||||||
inline point2_type const& get_qk() const { return m_range_q.at(2); }
|
inline point2_type const& get_qk() const { return m_range_q.at(2); }
|
||||||
|
|
||||||
// Used side-strategy, owned by the calculator,
|
// Used side-strategy, owned by the calculator
|
||||||
// created from .get_side_strategy()
|
side_strategy_type m_side_strategy;
|
||||||
SideStrategy m_side_strategy;
|
|
||||||
|
|
||||||
// Used ranges - owned by get_turns or (for robust points) by intersection_info_base
|
// Used ranges - owned by get_turns or (for robust points) by intersection_info_base
|
||||||
UniqueSubRange1 const& m_range_p;
|
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_point1_type, UniqueSubRange1, RobustPolicy> robust_subrange1;
|
||||||
typedef robust_subrange_adapter<robust_point2_type, UniqueSubRange2, RobustPolicy> robust_subrange2;
|
typedef robust_subrange_adapter<robust_point2_type, UniqueSubRange2, RobustPolicy> robust_subrange2;
|
||||||
|
|
||||||
typedef typename cs_tag<TurnPoint>::type cs_tag;
|
typedef side_calculator
|
||||||
|
<
|
||||||
typedef typename UmbrellaStrategy::side_strategy_type side_strategy_type;
|
robust_subrange1, robust_subrange2, UmbrellaStrategy
|
||||||
typedef side_calculator<cs_tag, robust_subrange1, robust_subrange2,
|
> side_calculator_type;
|
||||||
side_strategy_type> side_calculator_type;
|
|
||||||
|
|
||||||
typedef side_calculator
|
typedef side_calculator
|
||||||
<
|
<
|
||||||
cs_tag, robust_subrange2, robust_subrange1,
|
robust_subrange2, robust_subrange1, UmbrellaStrategy
|
||||||
side_strategy_type
|
|
||||||
> robust_swapped_side_calculator_type;
|
> robust_swapped_side_calculator_type;
|
||||||
|
|
||||||
intersection_info_base(UniqueSubRange1 const& range_p,
|
intersection_info_base(UniqueSubRange1 const& range_p,
|
||||||
@ -280,9 +277,9 @@ public:
|
|||||||
, m_robust_calc(range_p, range_q, robust_policy)
|
, 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_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_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,
|
, m_side_calc(m_robust_range_p, m_robust_range_q, umbrella_strategy)
|
||||||
umbrella_strategy.get_side_strategy())
|
, m_swapped_side_calc(m_robust_range_q, m_robust_range_p, umbrella_strategy)
|
||||||
, m_result(umbrella_strategy.apply(range_p, range_q,
|
, m_result(umbrella_strategy.relate().apply(range_p, range_q,
|
||||||
intersection_policy_type(),
|
intersection_policy_type(),
|
||||||
m_robust_range_p, m_robust_range_q))
|
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 robust_point2_type const& rqk() const { return m_robust_calc.get_rqk(); }
|
||||||
|
|
||||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||||
|
inline robust_swapped_side_calculator_type const& swapped_sides() const
|
||||||
robust_swapped_side_calculator_type get_swapped_sides() const
|
|
||||||
{
|
{
|
||||||
robust_swapped_side_calculator_type result(
|
return m_swapped_side_calc;
|
||||||
m_robust_range_q, m_robust_range_p,
|
|
||||||
m_side_calc.m_side_strategy);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private :
|
private :
|
||||||
@ -319,6 +312,7 @@ private :
|
|||||||
robust_subrange1 m_robust_range_p;
|
robust_subrange1 m_robust_range_p;
|
||||||
robust_subrange2 m_robust_range_q;
|
robust_subrange2 m_robust_range_q;
|
||||||
side_calculator_type m_side_calc;
|
side_calculator_type m_side_calc;
|
||||||
|
robust_swapped_side_calculator_type m_swapped_side_calc;
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
result_type m_result;
|
result_type m_result;
|
||||||
@ -347,15 +341,14 @@ public:
|
|||||||
typedef typename UniqueSubRange1::point_type point1_type;
|
typedef typename UniqueSubRange1::point_type point1_type;
|
||||||
typedef typename UniqueSubRange2::point_type point2_type;
|
typedef typename UniqueSubRange2::point_type point2_type;
|
||||||
|
|
||||||
typedef typename UmbrellaStrategy::cs_tag cs_tag;
|
typedef side_calculator
|
||||||
|
<
|
||||||
typedef typename UmbrellaStrategy::side_strategy_type side_strategy_type;
|
UniqueSubRange1, UniqueSubRange2, UmbrellaStrategy
|
||||||
typedef side_calculator<cs_tag, UniqueSubRange1, UniqueSubRange2, side_strategy_type> side_calculator_type;
|
> side_calculator_type;
|
||||||
|
|
||||||
typedef side_calculator
|
typedef side_calculator
|
||||||
<
|
<
|
||||||
cs_tag, UniqueSubRange2, UniqueSubRange1,
|
UniqueSubRange2, UniqueSubRange1, UmbrellaStrategy
|
||||||
side_strategy_type
|
|
||||||
> swapped_side_calculator_type;
|
> swapped_side_calculator_type;
|
||||||
|
|
||||||
intersection_info_base(UniqueSubRange1 const& range_p,
|
intersection_info_base(UniqueSubRange1 const& range_p,
|
||||||
@ -364,9 +357,10 @@ public:
|
|||||||
no_rescale_policy const& )
|
no_rescale_policy const& )
|
||||||
: m_range_p(range_p)
|
: m_range_p(range_p)
|
||||||
, m_range_q(range_q)
|
, m_range_q(range_q)
|
||||||
, m_side_calc(range_p, range_q,
|
, m_side_calc(range_p, range_q, umbrella_strategy)
|
||||||
umbrella_strategy.get_side_strategy())
|
, m_swapped_side_calc(range_q, range_p, umbrella_strategy)
|
||||||
, m_result(umbrella_strategy.apply(range_p, range_q, intersection_policy_type()))
|
, 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(); }
|
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 point2_type const& rqk() const { return m_side_calc.get_qk(); }
|
||||||
|
|
||||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||||
|
inline swapped_side_calculator_type const& swapped_sides() const
|
||||||
swapped_side_calculator_type get_swapped_sides() const
|
|
||||||
{
|
{
|
||||||
swapped_side_calculator_type result(
|
return m_swapped_side_calc;
|
||||||
m_range_q, m_range_p,
|
|
||||||
m_side_calc.m_side_strategy);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private :
|
private :
|
||||||
@ -397,6 +387,7 @@ private :
|
|||||||
|
|
||||||
// Owned by this class
|
// Owned by this class
|
||||||
side_calculator_type m_side_calc;
|
side_calculator_type m_side_calc;
|
||||||
|
swapped_side_calculator_type m_swapped_side_calc;
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
result_type m_result;
|
result_type m_result;
|
||||||
@ -422,8 +413,6 @@ public:
|
|||||||
typedef typename UniqueSubRange1::point_type point1_type;
|
typedef typename UniqueSubRange1::point_type point1_type;
|
||||||
typedef typename UniqueSubRange2::point_type point2_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 UmbrellaStrategy::cs_tag cs_tag;
|
||||||
|
|
||||||
typedef typename base::side_calculator_type side_calculator_type;
|
typedef typename base::side_calculator_type side_calculator_type;
|
||||||
@ -437,7 +426,7 @@ public:
|
|||||||
UmbrellaStrategy const& umbrella_strategy,
|
UmbrellaStrategy const& umbrella_strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
: base(range_p, range_q, umbrella_strategy, 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)
|
, 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 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 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
|
// TODO: it's more like is_spike_ip_p
|
||||||
inline bool is_spike_p() const
|
inline bool is_spike_p() const
|
||||||
{
|
{
|
||||||
@ -524,6 +508,11 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UmbrellaStrategy const& strategy() const
|
||||||
|
{
|
||||||
|
return m_umbrella_strategy;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <std::size_t OpId>
|
template <std::size_t OpId>
|
||||||
bool is_ip_j() const
|
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;
|
RobustPolicy const& m_robust_policy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ struct get_turn_info_linear_areal
|
|||||||
case 's' : // starts from the middle
|
case 's' : // starts from the middle
|
||||||
get_turn_info_for_endpoint<true, true>(range_p, range_q,
|
get_turn_info_for_endpoint<true, true>(range_p, range_q,
|
||||||
tp_model, inters, method_none, out,
|
tp_model, inters, method_none, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy());
|
umbrella_strategy);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd' : // disjoint: never do anything
|
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,
|
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
|
||||||
tp_model, inters, method_touch_interior, out,
|
tp_model, inters, method_touch_interior, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ struct get_turn_info_linear_areal
|
|||||||
// Swap p/q
|
// Swap p/q
|
||||||
handler::template apply<1>(range_q, range_p,
|
handler::template apply<1>(range_q, range_p,
|
||||||
tp, inters.i_info(), inters.d_info(),
|
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 )
|
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
|
// this function assumes that 'u' must be set for a spike
|
||||||
calculate_spike_operation(tp.operations[0].operation,
|
calculate_spike_operation(tp.operations[0].operation,
|
||||||
inters,
|
inters,
|
||||||
umbrella_strategy.get_point_in_point_strategy());
|
umbrella_strategy);
|
||||||
|
|
||||||
*out++ = tp;
|
*out++ = tp;
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ struct get_turn_info_linear_areal
|
|||||||
// Both touch (both arrive there)
|
// Both touch (both arrive there)
|
||||||
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
|
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
|
||||||
tp_model, inters, method_touch, out,
|
tp_model, inters, method_touch, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ struct get_turn_info_linear_areal
|
|||||||
bool ignore_spike
|
bool ignore_spike
|
||||||
= calculate_spike_operation(tp.operations[0].operation,
|
= calculate_spike_operation(tp.operations[0].operation,
|
||||||
inters,
|
inters,
|
||||||
umbrella_strategy.get_point_in_point_strategy());
|
umbrella_strategy);
|
||||||
|
|
||||||
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|
||||||
|| ignore_spike
|
|| ignore_spike
|
||||||
@ -234,7 +234,7 @@ struct get_turn_info_linear_areal
|
|||||||
{
|
{
|
||||||
if ( get_turn_info_for_endpoint<true, true>(range_p, range_q,
|
if ( get_turn_info_for_endpoint<true, true>(range_p, range_q,
|
||||||
tp_model, inters, method_equal, out,
|
tp_model, inters, method_equal, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ struct get_turn_info_linear_areal
|
|||||||
if ( get_turn_info_for_endpoint<true, true>(
|
if ( get_turn_info_for_endpoint<true, true>(
|
||||||
range_p, range_q,
|
range_p, range_q,
|
||||||
tp_model, inters, method_collinear, out,
|
tp_model, inters, method_collinear, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -359,13 +359,13 @@ struct get_turn_info_linear_areal
|
|||||||
|
|
||||||
if ( range_p.is_first_segment()
|
if ( range_p.is_first_segment()
|
||||||
&& equals::equals_point_point(range_p.at(0), tp.point,
|
&& 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;
|
tp.operations[0].position = position_front;
|
||||||
}
|
}
|
||||||
else if ( range_p.is_last_segment()
|
else if ( range_p.is_last_segment()
|
||||||
&& equals::equals_point_point(range_p.at(1), tp.point,
|
&& 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;
|
tp.operations[0].position = position_back;
|
||||||
}
|
}
|
||||||
@ -392,10 +392,10 @@ struct get_turn_info_linear_areal
|
|||||||
|
|
||||||
template <typename Operation,
|
template <typename Operation,
|
||||||
typename IntersectionInfo,
|
typename IntersectionInfo,
|
||||||
typename EqPPStrategy>
|
typename Strategy>
|
||||||
static inline bool calculate_spike_operation(Operation & op,
|
static inline bool calculate_spike_operation(Operation & op,
|
||||||
IntersectionInfo const& inters,
|
IntersectionInfo const& inters,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
bool is_p_spike = ( op == operation_union || op == operation_intersection )
|
bool is_p_spike = ( op == operation_union || op == operation_intersection )
|
||||||
&& inters.is_spike_p();
|
&& inters.is_spike_p();
|
||||||
@ -415,7 +415,7 @@ struct get_turn_info_linear_areal
|
|||||||
// spike on the edge point
|
// spike on the edge point
|
||||||
// if it's already known that the spike is going out this musn't be checked
|
// if it's already known that the spike is going out this musn't be checked
|
||||||
if ( ! going_out
|
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();
|
int const pk_q2 = inters.sides().pk_wrt_q2();
|
||||||
going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
|
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
|
// spike on the edge point
|
||||||
// if it's already known that the spike is going in this musn't be checked
|
// if it's already known that the spike is going in this musn't be checked
|
||||||
if ( ! going_in
|
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();
|
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
|
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 TurnInfo,
|
||||||
typename IntersectionInfo,
|
typename IntersectionInfo,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename EqPPStrategy>
|
typename Strategy>
|
||||||
static inline bool get_turn_info_for_endpoint(
|
static inline bool get_turn_info_for_endpoint(
|
||||||
UniqueSubRange1 const& range_p,
|
UniqueSubRange1 const& range_p,
|
||||||
UniqueSubRange2 const& range_q,
|
UniqueSubRange2 const& range_q,
|
||||||
@ -687,7 +687,7 @@ struct get_turn_info_linear_areal
|
|||||||
IntersectionInfo const& inters,
|
IntersectionInfo const& inters,
|
||||||
method_type /*method*/,
|
method_type /*method*/,
|
||||||
OutputIterator out,
|
OutputIterator out,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
namespace ov = overlay;
|
namespace ov = overlay;
|
||||||
typedef ov::get_turn_info_for_endpoint<EnableFirst, EnableLast> get_info_e;
|
typedef ov::get_turn_info_for_endpoint<EnableFirst, EnableLast> get_info_e;
|
||||||
@ -705,9 +705,6 @@ struct get_turn_info_linear_areal
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typename IntersectionInfo::side_strategy_type const& sides
|
|
||||||
= inters.get_side_strategy();
|
|
||||||
|
|
||||||
linear_intersections intersections(range_p.at(0),
|
linear_intersections intersections(range_p.at(0),
|
||||||
range_q.at(0),
|
range_q.at(0),
|
||||||
inters.result(),
|
inters.result(),
|
||||||
@ -738,6 +735,8 @@ struct get_turn_info_linear_areal
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto const sides = strategy.side();
|
||||||
|
|
||||||
// pi is the intersection point at qj or in the middle of q1
|
// pi is the intersection point at qj or in the middle of q1
|
||||||
// so consider segments
|
// so consider segments
|
||||||
// 1. pi at qj: qi-qj-pj and qi-qj-qk
|
// 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 )
|
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
|
// pj is the intersection point at qj or in the middle of q1
|
||||||
// so consider segments
|
// so consider segments
|
||||||
// 1. pj at qj: qi-qj-pi and qi-qj-qk
|
// 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
|
// don't ignore anything for now
|
||||||
return false;
|
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
|
}} // namespace detail::overlay
|
||||||
|
@ -75,7 +75,7 @@ struct get_turn_info_linear_linear
|
|||||||
get_turn_info_for_endpoint<true, true>
|
get_turn_info_for_endpoint<true, true>
|
||||||
::apply(range_p, range_q,
|
::apply(range_p, range_q,
|
||||||
tp_model, inters, method_none, out,
|
tp_model, inters, method_none, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy());
|
umbrella_strategy);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd' : // disjoint: never do anything
|
case 'd' : // disjoint: never do anything
|
||||||
@ -86,7 +86,7 @@ struct get_turn_info_linear_linear
|
|||||||
if ( get_turn_info_for_endpoint<false, true>
|
if ( get_turn_info_for_endpoint<false, true>
|
||||||
::apply(range_p, range_q,
|
::apply(range_p, range_q,
|
||||||
tp_model, inters, method_touch_interior, out,
|
tp_model, inters, method_touch_interior, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ struct get_turn_info_linear_linear
|
|||||||
// Swap p/q
|
// Swap p/q
|
||||||
policy::template apply<1>(range_q, range_p, tp,
|
policy::template apply<1>(range_q, range_p, tp,
|
||||||
inters.i_info(), inters.d_info(),
|
inters.i_info(), inters.d_info(),
|
||||||
inters.get_swapped_sides(),
|
inters.swapped_sides(),
|
||||||
umbrella_strategy);
|
umbrella_strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ struct get_turn_info_linear_linear
|
|||||||
if ( get_turn_info_for_endpoint<false, true>
|
if ( get_turn_info_for_endpoint<false, true>
|
||||||
::apply(range_p, range_q,
|
::apply(range_p, range_q,
|
||||||
tp_model, inters, method_touch, out,
|
tp_model, inters, method_touch, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ struct get_turn_info_linear_linear
|
|||||||
if ( get_turn_info_for_endpoint<true, true>
|
if ( get_turn_info_for_endpoint<true, true>
|
||||||
::apply(range_p, range_q,
|
::apply(range_p, range_q,
|
||||||
tp_model, inters, method_equal, out,
|
tp_model, inters, method_equal, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -333,7 +333,7 @@ struct get_turn_info_linear_linear
|
|||||||
if ( get_turn_info_for_endpoint<true, true>
|
if ( get_turn_info_for_endpoint<true, true>
|
||||||
::apply(range_p, range_q,
|
::apply(range_p, range_q,
|
||||||
tp_model, inters, method_collinear, out,
|
tp_model, inters, method_collinear, out,
|
||||||
umbrella_strategy.get_point_in_point_strategy()) )
|
umbrella_strategy) )
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
@ -416,29 +416,26 @@ struct get_turn_info_linear_linear
|
|||||||
// degenerate points
|
// degenerate points
|
||||||
if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) )
|
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());
|
only_convert::apply(tp, inters.i_info());
|
||||||
|
|
||||||
// if any, only one of those should be true
|
// if any, only one of those should be true
|
||||||
if ( range_p.is_first_segment()
|
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;
|
tp.operations[0].position = position_front;
|
||||||
}
|
}
|
||||||
else if ( range_p.is_last_segment()
|
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;
|
tp.operations[0].position = position_back;
|
||||||
}
|
}
|
||||||
else if ( range_q.is_first_segment()
|
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;
|
tp.operations[1].position = position_front;
|
||||||
}
|
}
|
||||||
else if ( range_q.is_last_segment()
|
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;
|
tp.operations[1].position = position_back;
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2014-2020.
|
// This file was modified by Oracle on 2014-2021.
|
||||||
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ template
|
|||||||
typename Section,
|
typename Section,
|
||||||
typename Point,
|
typename Point,
|
||||||
typename CircularIterator,
|
typename CircularIterator,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy
|
typename RobustPolicy
|
||||||
>
|
>
|
||||||
struct unique_sub_range_from_section
|
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,
|
unique_sub_range_from_section(Section const& section, signed_size_type index,
|
||||||
CircularIterator circular_iterator,
|
CircularIterator circular_iterator,
|
||||||
Point const& previous, Point const& current,
|
Point const& previous, Point const& current,
|
||||||
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
: m_section(section)
|
: m_section(section)
|
||||||
, m_index(index)
|
, m_index(index)
|
||||||
, m_previous_point(previous)
|
, m_previous_point(previous)
|
||||||
, m_current_point(current)
|
, m_current_point(current)
|
||||||
, m_circular_iterator(circular_iterator)
|
, m_circular_iterator(circular_iterator)
|
||||||
, m_point_retrieved(false)
|
, m_point_retrieved(false)
|
||||||
, m_robust_policy(robust_policy)
|
, m_strategy(strategy)
|
||||||
{
|
, m_robust_policy(robust_policy)
|
||||||
}
|
{}
|
||||||
|
|
||||||
inline bool is_first_segment() const
|
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
|
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;
|
typedef typename robust_point_type<Point, RobustPolicy>::type robust_point_type;
|
||||||
robust_point_type current_robust_point;
|
robust_point_type current_robust_point;
|
||||||
robust_point_type next_robust_point;
|
robust_point_type next_robust_point;
|
||||||
@ -187,12 +187,9 @@ private :
|
|||||||
// So advance to the "non duplicate next"
|
// So advance to the "non duplicate next"
|
||||||
// (the check is defensive, to avoid endless loops)
|
// (the check is defensive, to avoid endless loops)
|
||||||
std::size_t check = 0;
|
std::size_t check = 0;
|
||||||
while(! detail::disjoint::disjoint_point_point
|
while (! detail::disjoint::disjoint_point_point(
|
||||||
(
|
current_robust_point, next_robust_point, m_strategy)
|
||||||
current_robust_point, next_robust_point,
|
&& check++ < m_section.range_count)
|
||||||
disjoint_strategy_type()
|
|
||||||
)
|
|
||||||
&& check++ < m_section.range_count)
|
|
||||||
{
|
{
|
||||||
circular_iterator++;
|
circular_iterator++;
|
||||||
geometry::recalculate(next_robust_point, *circular_iterator, m_robust_policy);
|
geometry::recalculate(next_robust_point, *circular_iterator, m_robust_policy);
|
||||||
@ -206,6 +203,7 @@ private :
|
|||||||
mutable CircularIterator m_circular_iterator;
|
mutable CircularIterator m_circular_iterator;
|
||||||
mutable Point m_point;
|
mutable Point m_point;
|
||||||
mutable bool m_point_retrieved;
|
mutable bool m_point_retrieved;
|
||||||
|
Strategy m_strategy;
|
||||||
RobustPolicy m_robust_policy;
|
RobustPolicy m_robust_policy;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -276,12 +274,12 @@ class get_turns_in_sections
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
// Returns true if terminated, false if interrupted
|
// 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(
|
static inline bool apply(
|
||||||
int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
|
int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
|
||||||
int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
|
int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
|
||||||
bool skip_larger, bool skip_adjacent,
|
bool skip_larger, bool skip_adjacent,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& interrupt_policy)
|
InterruptPolicy& interrupt_policy)
|
||||||
@ -337,11 +335,11 @@ public :
|
|||||||
unique_sub_range_from_section
|
unique_sub_range_from_section
|
||||||
<
|
<
|
||||||
areal1, Section1, point1_type, circular1_iterator,
|
areal1, Section1, point1_type, circular1_iterator,
|
||||||
IntersectionStrategy, RobustPolicy
|
Strategy, RobustPolicy
|
||||||
> unique_sub_range1(sec1, index1,
|
> unique_sub_range1(sec1, index1,
|
||||||
circular1_iterator(begin_range_1, end_range_1, next1, true),
|
circular1_iterator(begin_range_1, end_range_1, next1, true),
|
||||||
*prev1, *it1,
|
*prev1, *it1,
|
||||||
robust_policy);
|
strategy, robust_policy);
|
||||||
|
|
||||||
signed_size_type index2 = sec2.begin_index;
|
signed_size_type index2 = sec2.begin_index;
|
||||||
signed_size_type ndi2 = sec2.non_duplicate_index;
|
signed_size_type ndi2 = sec2.non_duplicate_index;
|
||||||
@ -390,11 +388,11 @@ public :
|
|||||||
unique_sub_range_from_section
|
unique_sub_range_from_section
|
||||||
<
|
<
|
||||||
areal2, Section2, point2_type, circular2_iterator,
|
areal2, Section2, point2_type, circular2_iterator,
|
||||||
IntersectionStrategy, RobustPolicy
|
Strategy, RobustPolicy
|
||||||
> unique_sub_range2(sec2, index2,
|
> unique_sub_range2(sec2, index2,
|
||||||
circular2_iterator(begin_range_2, end_range_2, next2),
|
circular2_iterator(begin_range_2, end_range_2, next2),
|
||||||
*prev2, *it2,
|
*prev2, *it2,
|
||||||
robust_policy);
|
strategy, robust_policy);
|
||||||
|
|
||||||
typedef typename boost::range_value<Turns>::type turn_info;
|
typedef typename boost::range_value<Turns>::type turn_info;
|
||||||
|
|
||||||
@ -409,7 +407,7 @@ public :
|
|||||||
std::size_t const size_before = boost::size(turns);
|
std::size_t const size_before = boost::size(turns);
|
||||||
|
|
||||||
TurnPolicy::apply(unique_sub_range1, unique_sub_range2,
|
TurnPolicy::apply(unique_sub_range1, unique_sub_range2,
|
||||||
ti, intersection_strategy, robust_policy,
|
ti, strategy, robust_policy,
|
||||||
std::back_inserter(turns));
|
std::back_inserter(turns));
|
||||||
|
|
||||||
if (InterruptPolicy::enabled)
|
if (InterruptPolicy::enabled)
|
||||||
@ -464,7 +462,7 @@ template
|
|||||||
typename Geometry1, typename Geometry2,
|
typename Geometry1, typename Geometry2,
|
||||||
bool Reverse1, bool Reverse2,
|
bool Reverse1, bool Reverse2,
|
||||||
typename TurnPolicy,
|
typename TurnPolicy,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Turns,
|
typename Turns,
|
||||||
typename InterruptPolicy
|
typename InterruptPolicy
|
||||||
@ -475,20 +473,20 @@ struct section_visitor
|
|||||||
Geometry1 const& m_geometry1;
|
Geometry1 const& m_geometry1;
|
||||||
int m_source_id2;
|
int m_source_id2;
|
||||||
Geometry2 const& m_geometry2;
|
Geometry2 const& m_geometry2;
|
||||||
IntersectionStrategy const& m_intersection_strategy;
|
Strategy const& m_strategy;
|
||||||
RobustPolicy const& m_rescale_policy;
|
RobustPolicy const& m_rescale_policy;
|
||||||
Turns& m_turns;
|
Turns& m_turns;
|
||||||
InterruptPolicy& m_interrupt_policy;
|
InterruptPolicy& m_interrupt_policy;
|
||||||
|
|
||||||
section_visitor(int id1, Geometry1 const& g1,
|
section_visitor(int id1, Geometry1 const& g1,
|
||||||
int id2, Geometry2 const& g2,
|
int id2, Geometry2 const& g2,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& ip)
|
InterruptPolicy& ip)
|
||||||
: m_source_id1(id1), m_geometry1(g1)
|
: m_source_id1(id1), m_geometry1(g1)
|
||||||
, m_source_id2(id2), m_geometry2(g2)
|
, m_source_id2(id2), m_geometry2(g2)
|
||||||
, m_intersection_strategy(intersection_strategy)
|
, m_strategy(strategy)
|
||||||
, m_rescale_policy(robust_policy)
|
, m_rescale_policy(robust_policy)
|
||||||
, m_turns(turns)
|
, m_turns(turns)
|
||||||
, m_interrupt_policy(ip)
|
, m_interrupt_policy(ip)
|
||||||
@ -499,7 +497,7 @@ struct section_visitor
|
|||||||
{
|
{
|
||||||
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
|
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
|
||||||
sec2.bounding_box,
|
sec2.bounding_box,
|
||||||
m_intersection_strategy.get_disjoint_box_box_strategy()))
|
m_strategy) )
|
||||||
{
|
{
|
||||||
// false if interrupted
|
// false if interrupted
|
||||||
return get_turns_in_sections
|
return get_turns_in_sections
|
||||||
@ -512,7 +510,7 @@ struct section_visitor
|
|||||||
>::apply(m_source_id1, m_geometry1, sec1,
|
>::apply(m_source_id1, m_geometry1, sec1,
|
||||||
m_source_id2, m_geometry2, sec2,
|
m_source_id2, m_geometry2, sec2,
|
||||||
false, false,
|
false, false,
|
||||||
m_intersection_strategy,
|
m_strategy,
|
||||||
m_rescale_policy,
|
m_rescale_policy,
|
||||||
m_turns, m_interrupt_policy);
|
m_turns, m_interrupt_policy);
|
||||||
}
|
}
|
||||||
@ -531,11 +529,11 @@ class get_turns_generic
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename IntersectionStrategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
template <typename Strategy, typename RobustPolicy, typename Turns, typename InterruptPolicy>
|
||||||
static inline void apply(
|
static inline void apply(
|
||||||
int source_id1, Geometry1 const& geometry1,
|
int source_id1, Geometry1 const& geometry1,
|
||||||
int source_id2, Geometry2 const& geometry2,
|
int source_id2, Geometry2 const& geometry2,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& interrupt_policy)
|
InterruptPolicy& interrupt_policy)
|
||||||
@ -556,15 +554,10 @@ public:
|
|||||||
sections_type sec1, sec2;
|
sections_type sec1, sec2;
|
||||||
typedef std::integer_sequence<std::size_t, 0, 1> dimensions;
|
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,
|
geometry::sectionalize<Reverse1, dimensions>(geometry1, robust_policy,
|
||||||
sec1, envelope_strategy, expand_strategy, 0);
|
sec1, strategy, 0);
|
||||||
geometry::sectionalize<Reverse2, dimensions>(geometry2, robust_policy,
|
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
|
// ... and then partition them, intersecting overlapping sections in visitor method
|
||||||
section_visitor
|
section_visitor
|
||||||
@ -572,27 +565,17 @@ public:
|
|||||||
Geometry1, Geometry2,
|
Geometry1, Geometry2,
|
||||||
Reverse1, Reverse2,
|
Reverse1, Reverse2,
|
||||||
TurnPolicy,
|
TurnPolicy,
|
||||||
IntersectionStrategy, RobustPolicy,
|
Strategy, RobustPolicy,
|
||||||
Turns, InterruptPolicy
|
Turns, InterruptPolicy
|
||||||
> visitor(source_id1, geometry1, source_id2, geometry2,
|
> visitor(source_id1, geometry1, source_id2, geometry2,
|
||||||
intersection_strategy, robust_policy,
|
strategy, robust_policy, turns, interrupt_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;
|
|
||||||
|
|
||||||
geometry::partition
|
geometry::partition
|
||||||
<
|
<
|
||||||
box_type
|
box_type
|
||||||
>::apply(sec1, sec2, visitor,
|
>::apply(sec1, sec2, visitor,
|
||||||
get_section_box_type(),
|
detail::section::get_section_box<Strategy>(strategy),
|
||||||
overlaps_section_box_type());
|
detail::section::overlaps_section_box<Strategy>(strategy));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1094,10 +1077,10 @@ template
|
|||||||
>
|
>
|
||||||
struct get_turns_reversed
|
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,
|
static inline void apply(int source_id1, Geometry1 const& g1,
|
||||||
int source_id2, Geometry2 const& g2,
|
int source_id2, Geometry2 const& g2,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& interrupt_policy)
|
InterruptPolicy& interrupt_policy)
|
||||||
@ -1109,7 +1092,7 @@ struct get_turns_reversed
|
|||||||
Reverse2, Reverse1,
|
Reverse2, Reverse1,
|
||||||
TurnPolicy
|
TurnPolicy
|
||||||
>::apply(source_id2, g2, source_id1, g1,
|
>::apply(source_id2, g2, source_id1, g1,
|
||||||
intersection_strategy, robust_policy,
|
strategy, robust_policy,
|
||||||
turns, interrupt_policy);
|
turns, interrupt_policy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1140,14 +1123,14 @@ template
|
|||||||
typename AssignPolicy,
|
typename AssignPolicy,
|
||||||
typename Geometry1,
|
typename Geometry1,
|
||||||
typename Geometry2,
|
typename Geometry2,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Turns,
|
typename Turns,
|
||||||
typename InterruptPolicy
|
typename InterruptPolicy
|
||||||
>
|
>
|
||||||
inline void get_turns(Geometry1 const& geometry1,
|
inline void get_turns(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& interrupt_policy)
|
InterruptPolicy& interrupt_policy)
|
||||||
@ -1178,7 +1161,7 @@ inline void get_turns(Geometry1 const& geometry1,
|
|||||||
>
|
>
|
||||||
>::apply(0, geometry1,
|
>::apply(0, geometry1,
|
||||||
1, geometry2,
|
1, geometry2,
|
||||||
intersection_strategy,
|
strategy,
|
||||||
robust_policy,
|
robust_policy,
|
||||||
turns, interrupt_policy);
|
turns, interrupt_policy);
|
||||||
}
|
}
|
||||||
|
@ -32,48 +32,6 @@ namespace boost { namespace geometry
|
|||||||
namespace detail { namespace overlay
|
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>
|
template <overlay_type OverlayType>
|
||||||
struct check_within
|
struct check_within
|
||||||
{
|
{
|
||||||
@ -86,14 +44,10 @@ struct check_within
|
|||||||
bool apply(Turn const& turn, Geometry0 const& geometry0,
|
bool apply(Turn const& turn, Geometry0 const& geometry0,
|
||||||
Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
|
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
|
// Operations 0 and 1 have the same source index in self-turns
|
||||||
return turn.operations[0].seg_id.source_index == 0
|
return turn.operations[0].seg_id.source_index == 0
|
||||||
? geometry::within(turn.point, geometry1,
|
? geometry::within(turn.point, geometry1, strategy)
|
||||||
check_within_strategy<point_type, Geometry1>::within(strategy))
|
: geometry::within(turn.point, geometry0, strategy);
|
||||||
: geometry::within(turn.point, geometry0,
|
|
||||||
check_within_strategy<point_type, Geometry0>::within(strategy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -110,15 +64,11 @@ struct check_within<overlay_difference>
|
|||||||
bool apply(Turn const& turn, Geometry0 const& geometry0,
|
bool apply(Turn const& turn, Geometry0 const& geometry0,
|
||||||
Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
|
Geometry1 const& geometry1, UmbrellaStrategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename Turn::point_type point_type;
|
|
||||||
|
|
||||||
// difference = intersection(a, reverse(b))
|
// difference = intersection(a, reverse(b))
|
||||||
// therefore we should reverse the meaning of within for geometry1
|
// therefore we should reverse the meaning of within for geometry1
|
||||||
return turn.operations[0].seg_id.source_index == 0
|
return turn.operations[0].seg_id.source_index == 0
|
||||||
? ! geometry::covered_by(turn.point, geometry1,
|
? ! geometry::covered_by(turn.point, geometry1, strategy)
|
||||||
check_within_strategy<point_type, Geometry1>::covered_by(strategy))
|
: geometry::within(turn.point, geometry0, strategy);
|
||||||
: geometry::within(turn.point, geometry0,
|
|
||||||
check_within_strategy<point_type, Geometry0>::within(strategy));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,6 +49,10 @@
|
|||||||
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
||||||
#include <boost/geometry/policies/robustness/get_rescale_policy.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/segment_view.hpp>
|
||||||
#include <boost/geometry/views/detail/boundary_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);
|
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
||||||
|
|
||||||
intersection_return_type
|
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++)
|
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<Geometry1 const>();
|
||||||
concepts::check<Geometry2 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;
|
>::type strategy_type;
|
||||||
|
|
||||||
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
|
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
|
||||||
|
@ -147,13 +147,13 @@ protected:
|
|||||||
typename Turns,
|
typename Turns,
|
||||||
typename LinearGeometry1,
|
typename LinearGeometry1,
|
||||||
typename LinearGeometry2,
|
typename LinearGeometry2,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy
|
typename RobustPolicy
|
||||||
>
|
>
|
||||||
static inline void compute_turns(Turns& turns,
|
static inline void compute_turns(Turns& turns,
|
||||||
LinearGeometry1 const& linear1,
|
LinearGeometry1 const& linear1,
|
||||||
LinearGeometry2 const& linear2,
|
LinearGeometry2 const& linear2,
|
||||||
IntersectionStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
turns.clear();
|
turns.clear();
|
||||||
@ -182,14 +182,14 @@ protected:
|
|||||||
typename LinearGeometry1,
|
typename LinearGeometry1,
|
||||||
typename LinearGeometry2,
|
typename LinearGeometry2,
|
||||||
typename OutputIterator,
|
typename OutputIterator,
|
||||||
typename IntersectionStrategy
|
typename Strategy
|
||||||
>
|
>
|
||||||
static inline OutputIterator
|
static inline OutputIterator
|
||||||
sort_and_follow_turns(Turns& turns,
|
sort_and_follow_turns(Turns& turns,
|
||||||
LinearGeometry1 const& linear1,
|
LinearGeometry1 const& linear1,
|
||||||
LinearGeometry2 const& linear2,
|
LinearGeometry2 const& linear2,
|
||||||
OutputIterator oit,
|
OutputIterator oit,
|
||||||
IntersectionStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// remove turns that have no added value
|
// remove turns that have no added value
|
||||||
turns::filter_continue_turns
|
turns::filter_continue_turns
|
||||||
@ -217,7 +217,7 @@ protected:
|
|||||||
FollowIsolatedPoints,
|
FollowIsolatedPoints,
|
||||||
!EnableFilterContinueTurns || OverlayType == overlay_intersection
|
!EnableFilterContinueTurns || OverlayType == overlay_intersection
|
||||||
>::apply(linear1, linear2, boost::begin(turns), boost::end(turns),
|
>::apply(linear1, linear2, boost::begin(turns), boost::end(turns),
|
||||||
oit, strategy.get_side_strategy());
|
oit, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -197,20 +197,13 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
|
|||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
OutputIterator out, Strategy const& strategy)
|
OutputIterator out, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef std::deque
|
typedef typename geometry::ring_type<GeometryOut>::type ring_type;
|
||||||
<
|
typedef std::deque<ring_type> ring_container_type;
|
||||||
typename geometry::ring_type<GeometryOut>::type
|
|
||||||
> ring_container_type;
|
|
||||||
|
|
||||||
typedef typename geometry::point_type<Geometry1>::type point_type1;
|
|
||||||
|
|
||||||
typedef ring_properties
|
typedef ring_properties
|
||||||
<
|
<
|
||||||
point_type1,
|
typename geometry::point_type<ring_type>::type,
|
||||||
typename Strategy::template area_strategy
|
typename geometry::area_result<ring_type, Strategy>::type
|
||||||
<
|
|
||||||
point_type1
|
|
||||||
>::type::template result_type<point_type1>::type
|
|
||||||
> properties;
|
> properties;
|
||||||
|
|
||||||
// Silence warning C4127: conditional expression is constant
|
// 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);
|
select_rings<OverlayType>(geometry1, geometry2, empty, all_of_one_of_them, strategy);
|
||||||
ring_container_type rings;
|
ring_container_type rings;
|
||||||
assign_parents<OverlayType>(geometry1, geometry2, rings, all_of_one_of_them, strategy);
|
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,
|
return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out, strategy);
|
||||||
strategy.template get_area_strategy<point_type1>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -285,10 +277,8 @@ struct overlay
|
|||||||
> turn_info;
|
> turn_info;
|
||||||
typedef std::deque<turn_info> turn_container_type;
|
typedef std::deque<turn_info> turn_container_type;
|
||||||
|
|
||||||
typedef std::deque
|
typedef typename geometry::ring_type<GeometryOut>::type ring_type;
|
||||||
<
|
typedef std::deque<ring_type> ring_container_type;
|
||||||
typename geometry::ring_type<GeometryOut>::type
|
|
||||||
> ring_container_type;
|
|
||||||
|
|
||||||
// Define the clusters, mapping cluster_id -> turns
|
// Define the clusters, mapping cluster_id -> turns
|
||||||
typedef std::map
|
typedef std::map
|
||||||
@ -365,12 +355,10 @@ std::cout << "traverse" << std::endl;
|
|||||||
|
|
||||||
get_ring_turn_info<OverlayType>(turn_info_per_ring, turns, clusters);
|
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
|
typedef ring_properties
|
||||||
<
|
<
|
||||||
point_type,
|
point_type,
|
||||||
typename area_strategy_type::template result_type<point_type>::type
|
typename geometry::area_result<ring_type, Strategy>::type
|
||||||
> properties;
|
> properties;
|
||||||
|
|
||||||
// Select all rings which are NOT touched by any intersection point
|
// Select all rings which are NOT touched by any intersection point
|
||||||
@ -379,7 +367,6 @@ std::cout << "traverse" << std::endl;
|
|||||||
selected_ring_properties, strategy);
|
selected_ring_properties, strategy);
|
||||||
|
|
||||||
// Add rings created during traversal
|
// Add rings created during traversal
|
||||||
area_strategy_type const area_strategy = strategy.template get_area_strategy<point_type>();
|
|
||||||
{
|
{
|
||||||
ring_identifier id(2, 0, -1);
|
ring_identifier id(2, 0, -1);
|
||||||
for (typename boost::range_iterator<ring_container_type>::type
|
for (typename boost::range_iterator<ring_container_type>::type
|
||||||
@ -387,7 +374,7 @@ std::cout << "traverse" << std::endl;
|
|||||||
it != boost::end(rings);
|
it != boost::end(rings);
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
selected_ring_properties[id] = properties(*it, area_strategy);
|
selected_ring_properties[id] = properties(*it, strategy);
|
||||||
selected_ring_properties[id].reversed = ReverseOut;
|
selected_ring_properties[id].reversed = ReverseOut;
|
||||||
id.multi_index++;
|
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
|
// 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.
|
// it can be returned or an exception can be thrown.
|
||||||
return add_rings<GeometryOut>(selected_ring_properties, geometry1, geometry2, rings, out,
|
return add_rings<GeometryOut>(selected_ring_properties, geometry1, geometry2, rings, out,
|
||||||
area_strategy,
|
strategy,
|
||||||
OverlayType == overlay_union ?
|
OverlayType == overlay_union ?
|
||||||
#if defined(BOOST_GEOMETRY_UNION_THROW_INVALID_OUTPUT_EXCEPTION)
|
#if defined(BOOST_GEOMETRY_UNION_THROW_INVALID_OUTPUT_EXCEPTION)
|
||||||
add_rings_throw_if_reversed
|
add_rings_throw_if_reversed
|
||||||
|
@ -63,44 +63,68 @@ template
|
|||||||
class multipoint_multipolygon_point
|
class multipoint_multipolygon_point
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template <typename ExpandPointStrategy>
|
template <typename Strategy>
|
||||||
struct expand_box_point
|
struct expand_box_point
|
||||||
{
|
{
|
||||||
|
explicit expand_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct expand_box_boxpair
|
||||||
{
|
{
|
||||||
|
explicit expand_box_boxpair(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box1, typename Box2, typename SizeT>
|
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
|
struct overlaps_box_point
|
||||||
{
|
{
|
||||||
|
explicit overlaps_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct overlaps_box_boxpair
|
||||||
{
|
{
|
||||||
|
explicit overlaps_box_boxpair(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box1, typename Box2, typename SizeT>
|
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>
|
template <typename OutputIterator, typename Strategy>
|
||||||
@ -137,10 +161,10 @@ private:
|
|||||||
Strategy const& m_strategy;
|
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,
|
static inline void fill_box_pairs(Iterator first, Iterator last,
|
||||||
std::vector<std::pair<Box, SizeT> > & box_pairs,
|
std::vector<std::pair<Box, SizeT> > & box_pairs,
|
||||||
EnvelopeStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
SizeT index = 0;
|
SizeT index = 0;
|
||||||
for (; first != last; ++first, ++index)
|
for (; first != last; ++first, ++index)
|
||||||
@ -172,29 +196,16 @@ private:
|
|||||||
|
|
||||||
fill_box_pairs(boost::begin(multipolygon),
|
fill_box_pairs(boost::begin(multipolygon),
|
||||||
boost::end(multipolygon),
|
boost::end(multipolygon),
|
||||||
box_pairs,
|
box_pairs, strategy);
|
||||||
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;
|
|
||||||
|
|
||||||
geometry::partition
|
geometry::partition
|
||||||
<
|
<
|
||||||
box_type
|
box_type
|
||||||
>::apply(multipoint, box_pairs, item_visitor,
|
>::apply(multipoint, box_pairs, item_visitor,
|
||||||
expand_box_point<expand_point_strategy_type>(),
|
expand_box_point<Strategy>(strategy),
|
||||||
overlaps_box_point<disjoint_point_box_strategy_type>(),
|
overlaps_box_point<Strategy>(strategy),
|
||||||
expand_box_boxpair<expand_box_strategy_type>(),
|
expand_box_boxpair<Strategy>(strategy),
|
||||||
overlaps_box_boxpair<disjoint_box_box_strategy_type>());
|
overlaps_box_boxpair<Strategy>(strategy));
|
||||||
|
|
||||||
return oit;
|
return oit;
|
||||||
}
|
}
|
||||||
|
@ -127,20 +127,26 @@ class multipoint_linear_point
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// structs for partition -- start
|
// structs for partition -- start
|
||||||
template <typename ExpandPointStrategy>
|
template <typename Strategy>
|
||||||
struct expand_box_point
|
struct expand_box_point
|
||||||
{
|
{
|
||||||
|
expand_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct expand_box_segment
|
||||||
{
|
{
|
||||||
explicit expand_box_segment(EnvelopeStrategy const& strategy)
|
explicit expand_box_segment(Strategy const& strategy)
|
||||||
: m_strategy(strategy)
|
: m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -149,31 +155,32 @@ private:
|
|||||||
{
|
{
|
||||||
geometry::expand(total,
|
geometry::expand(total,
|
||||||
geometry::return_envelope<Box>(segment, m_strategy),
|
geometry::return_envelope<Box>(segment, m_strategy),
|
||||||
// TEMP - envelope umbrella strategy also contains
|
m_strategy);
|
||||||
// expand strategies
|
|
||||||
strategies::envelope::services::strategy_converter
|
|
||||||
<
|
|
||||||
EnvelopeStrategy
|
|
||||||
>::get(m_strategy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvelopeStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DisjointPointBoxStrategy>
|
template <typename Strategy>
|
||||||
struct overlaps_box_point
|
struct overlaps_box_point
|
||||||
{
|
{
|
||||||
|
explicit overlaps_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct overlaps_box_segment
|
||||||
{
|
{
|
||||||
explicit overlaps_box_segment(DisjointStrategy const& strategy)
|
explicit overlaps_box_segment(Strategy const& strategy)
|
||||||
: m_strategy(strategy)
|
: m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -183,7 +190,7 @@ private:
|
|||||||
return ! geometry::disjoint(segment, box, m_strategy);
|
return ! geometry::disjoint(segment, box, m_strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisjointStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename OutputIterator, typename Strategy>
|
template <typename OutputIterator, typename Strategy>
|
||||||
@ -218,7 +225,7 @@ private:
|
|||||||
typedef geometry::segment_iterator<Linear const> const_iterator;
|
typedef geometry::segment_iterator<Linear const> const_iterator;
|
||||||
typedef const_iterator iterator;
|
typedef const_iterator iterator;
|
||||||
|
|
||||||
segment_range(Linear const& linear)
|
explicit segment_range(Linear const& linear)
|
||||||
: m_linear(linear)
|
: m_linear(linear)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -244,11 +251,6 @@ private:
|
|||||||
{
|
{
|
||||||
item_visitor_type<OutputIterator, Strategy> item_visitor(oit, strategy);
|
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
|
// TODO: disjoint Segment/Box may be called in partition multiple times
|
||||||
// possibly for non-cartesian segments which could be slow. We should consider
|
// possibly for non-cartesian segments which could be slow. We should consider
|
||||||
// passing a range of bounding boxes of segments after calculating them once.
|
// passing a range of bounding boxes of segments after calculating them once.
|
||||||
@ -261,10 +263,10 @@ private:
|
|||||||
typename boost::range_value<MultiPoint>::type
|
typename boost::range_value<MultiPoint>::type
|
||||||
>
|
>
|
||||||
>::apply(multipoint, segment_range(linear), item_visitor,
|
>::apply(multipoint, segment_range(linear), item_visitor,
|
||||||
expand_box_point<expand_point_strategy_type>(),
|
expand_box_point<Strategy>(strategy),
|
||||||
overlaps_box_point<disjoint_point_box_strategy_type>(),
|
overlaps_box_point<Strategy>(strategy),
|
||||||
expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
|
expand_box_segment<Strategy>(strategy),
|
||||||
overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
|
overlaps_box_segment<Strategy>(strategy));
|
||||||
|
|
||||||
return oit;
|
return oit;
|
||||||
}
|
}
|
||||||
|
@ -98,9 +98,9 @@ struct point_in_geometry_helper<Box, box_tag>
|
|||||||
{
|
{
|
||||||
template <typename Point, typename Strategy>
|
template <typename Point, typename Strategy>
|
||||||
static inline int apply(Point const& point, Box const& box,
|
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;
|
++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)
|
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)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
@ -153,8 +147,7 @@ inline int range_in_geometry(Point1 const& first_point1,
|
|||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// check a point on border of geometry1 first
|
// check a point on border of geometry1 first
|
||||||
int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2,
|
int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2, strategy);
|
||||||
strategy.template get_point_in_geometry_strategy<Point1, Geometry2>());
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
// if a point is on boundary of geometry2
|
// if a point is on boundary of geometry2
|
||||||
|
@ -56,8 +56,8 @@ struct ring_properties
|
|||||||
, parent_area(-1)
|
, parent_area(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename RingOrBox, typename AreaStrategy>
|
template <typename RingOrBox, typename Strategy>
|
||||||
inline ring_properties(RingOrBox const& ring_or_box, AreaStrategy const& strategy)
|
inline ring_properties(RingOrBox const& ring_or_box, Strategy const& strategy)
|
||||||
: reversed(false)
|
: reversed(false)
|
||||||
, discarded(false)
|
, discarded(false)
|
||||||
, parent_area(-1)
|
, parent_area(-1)
|
||||||
|
@ -62,18 +62,18 @@ namespace dispatch
|
|||||||
template <typename Box>
|
template <typename Box>
|
||||||
struct select_rings<box_tag, 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& ,
|
static inline void apply(Box const& box, Geometry const& ,
|
||||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box, 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,
|
static inline void apply(Box const& box,
|
||||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy);
|
ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy);
|
||||||
}
|
}
|
||||||
@ -82,10 +82,10 @@ namespace dispatch
|
|||||||
template <typename Ring>
|
template <typename Ring>
|
||||||
struct select_rings<ring_tag, 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& ,
|
static inline void apply(Ring const& ring, Geometry const& ,
|
||||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if (boost::size(ring) > 0)
|
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,
|
static inline void apply(Ring const& ring,
|
||||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if (boost::size(ring) > 0)
|
if (boost::size(ring) > 0)
|
||||||
{
|
{
|
||||||
@ -109,10 +109,10 @@ namespace dispatch
|
|||||||
template <typename Polygon>
|
template <typename Polygon>
|
||||||
struct select_rings<polygon_tag, 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,
|
static inline void apply(Polygon const& polygon, Geometry const& geometry,
|
||||||
ring_identifier id, RingPropertyMap& ring_properties,
|
ring_identifier id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
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,
|
static inline void apply(Polygon const& polygon,
|
||||||
ring_identifier id, RingPropertyMap& ring_properties,
|
ring_identifier id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||||
@ -153,10 +153,10 @@ namespace dispatch
|
|||||||
template <typename Multi>
|
template <typename Multi>
|
||||||
struct select_rings<multi_polygon_tag, 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,
|
static inline void apply(Multi const& multi, Geometry const& geometry,
|
||||||
ring_identifier id, RingPropertyMap& ring_properties,
|
ring_identifier id, RingPropertyMap& ring_properties,
|
||||||
AreaStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename boost::range_iterator
|
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<Geometry1>::type tag1;
|
||||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
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;
|
RingPropertyMap all_ring_properties;
|
||||||
dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
|
dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
|
||||||
ring_identifier(0, -1, -1), all_ring_properties,
|
ring_identifier(0, -1, -1), all_ring_properties,
|
||||||
strategy.template get_area_strategy<point1_type>());
|
strategy);
|
||||||
dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
|
dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
|
||||||
ring_identifier(1, -1, -1), all_ring_properties,
|
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,
|
update_ring_selection<OverlayType>(geometry1, geometry2, turn_info_per_ring,
|
||||||
all_ring_properties, selected_ring_properties,
|
all_ring_properties, selected_ring_properties,
|
||||||
@ -356,7 +354,7 @@ inline void select_rings(Geometry const& geometry,
|
|||||||
RingPropertyMap all_ring_properties;
|
RingPropertyMap all_ring_properties;
|
||||||
dispatch::select_rings<tag, Geometry>::apply(geometry,
|
dispatch::select_rings<tag, Geometry>::apply(geometry,
|
||||||
ring_identifier(0, -1, -1), all_ring_properties,
|
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,
|
update_ring_selection<OverlayType>(geometry, geometry, turn_info_per_ring,
|
||||||
all_ring_properties, selected_ring_properties,
|
all_ring_properties, selected_ring_properties,
|
||||||
|
@ -63,14 +63,14 @@ template
|
|||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename Turns,
|
typename Turns,
|
||||||
typename TurnPolicy,
|
typename TurnPolicy,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename InterruptPolicy
|
typename InterruptPolicy
|
||||||
>
|
>
|
||||||
struct self_section_visitor
|
struct self_section_visitor
|
||||||
{
|
{
|
||||||
Geometry const& m_geometry;
|
Geometry const& m_geometry;
|
||||||
IntersectionStrategy const& m_intersection_strategy;
|
Strategy const& m_strategy;
|
||||||
RobustPolicy const& m_rescale_policy;
|
RobustPolicy const& m_rescale_policy;
|
||||||
Turns& m_turns;
|
Turns& m_turns;
|
||||||
InterruptPolicy& m_interrupt_policy;
|
InterruptPolicy& m_interrupt_policy;
|
||||||
@ -78,14 +78,14 @@ struct self_section_visitor
|
|||||||
bool m_skip_adjacent;
|
bool m_skip_adjacent;
|
||||||
|
|
||||||
inline self_section_visitor(Geometry const& g,
|
inline self_section_visitor(Geometry const& g,
|
||||||
IntersectionStrategy const& is,
|
Strategy const& s,
|
||||||
RobustPolicy const& rp,
|
RobustPolicy const& rp,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& ip,
|
InterruptPolicy& ip,
|
||||||
int source_index,
|
int source_index,
|
||||||
bool skip_adjacent)
|
bool skip_adjacent)
|
||||||
: m_geometry(g)
|
: m_geometry(g)
|
||||||
, m_intersection_strategy(is)
|
, m_strategy(s)
|
||||||
, m_rescale_policy(rp)
|
, m_rescale_policy(rp)
|
||||||
, m_turns(turns)
|
, m_turns(turns)
|
||||||
, m_interrupt_policy(ip)
|
, m_interrupt_policy(ip)
|
||||||
@ -98,7 +98,7 @@ struct self_section_visitor
|
|||||||
{
|
{
|
||||||
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
|
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
|
||||||
sec2.bounding_box,
|
sec2.bounding_box,
|
||||||
m_intersection_strategy.get_disjoint_box_box_strategy())
|
m_strategy)
|
||||||
&& ! sec1.duplicate
|
&& ! sec1.duplicate
|
||||||
&& ! sec2.duplicate)
|
&& ! sec2.duplicate)
|
||||||
{
|
{
|
||||||
@ -112,7 +112,7 @@ struct self_section_visitor
|
|||||||
>::apply(m_source_index, m_geometry, sec1,
|
>::apply(m_source_index, m_geometry, sec1,
|
||||||
m_source_index, m_geometry, sec2,
|
m_source_index, m_geometry, sec2,
|
||||||
false, m_skip_adjacent,
|
false, m_skip_adjacent,
|
||||||
m_intersection_strategy,
|
m_strategy,
|
||||||
m_rescale_policy,
|
m_rescale_policy,
|
||||||
m_turns, m_interrupt_policy);
|
m_turns, m_interrupt_policy);
|
||||||
}
|
}
|
||||||
@ -127,10 +127,10 @@ struct self_section_visitor
|
|||||||
template <bool Reverse, typename TurnPolicy>
|
template <bool Reverse, typename TurnPolicy>
|
||||||
struct get_turns
|
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(
|
static inline bool apply(
|
||||||
Geometry const& geometry,
|
Geometry const& geometry,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& interrupt_policy,
|
InterruptPolicy& interrupt_policy,
|
||||||
@ -152,32 +152,23 @@ struct get_turns
|
|||||||
typedef std::integer_sequence<std::size_t, 0, 1> dimensions;
|
typedef std::integer_sequence<std::size_t, 0, 1> dimensions;
|
||||||
|
|
||||||
sections_type sec;
|
sections_type sec;
|
||||||
geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy, sec,
|
geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy,
|
||||||
intersection_strategy.get_envelope_strategy(),
|
sec, strategy);
|
||||||
intersection_strategy.get_expand_strategy());
|
|
||||||
|
|
||||||
self_section_visitor
|
self_section_visitor
|
||||||
<
|
<
|
||||||
Reverse, Geometry,
|
Reverse, Geometry,
|
||||||
Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy
|
Turns, TurnPolicy, Strategy, RobustPolicy, InterruptPolicy
|
||||||
> visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index, skip_adjacent);
|
> visitor(geometry, 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;
|
|
||||||
|
|
||||||
// false if interrupted
|
// false if interrupted
|
||||||
geometry::partition
|
geometry::partition
|
||||||
<
|
<
|
||||||
box_type
|
box_type
|
||||||
>::apply(sec, visitor,
|
>::apply(sec, visitor,
|
||||||
get_section_box_type(),
|
detail::section::get_section_box<Strategy>(strategy),
|
||||||
overlaps_section_box_type());
|
detail::section::overlaps_section_box<Strategy>(strategy));
|
||||||
|
|
||||||
return ! interrupt_policy.has_intersections;
|
return ! interrupt_policy.has_intersections;
|
||||||
}
|
}
|
||||||
@ -340,13 +331,13 @@ template
|
|||||||
<
|
<
|
||||||
typename AssignPolicy,
|
typename AssignPolicy,
|
||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Turns,
|
typename Turns,
|
||||||
typename InterruptPolicy
|
typename InterruptPolicy
|
||||||
>
|
>
|
||||||
inline void self_turns(Geometry const& geometry,
|
inline void self_turns(Geometry const& geometry,
|
||||||
IntersectionStrategy const& strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Turns& turns,
|
Turns& turns,
|
||||||
InterruptPolicy& interrupt_policy,
|
InterruptPolicy& interrupt_policy,
|
||||||
|
@ -44,7 +44,7 @@ template
|
|||||||
typename Turns,
|
typename Turns,
|
||||||
typename TurnInfoMap,
|
typename TurnInfoMap,
|
||||||
typename Clusters,
|
typename Clusters,
|
||||||
typename IntersectionStrategy,
|
typename Strategy,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Visitor,
|
typename Visitor,
|
||||||
typename Backtrack
|
typename Backtrack
|
||||||
@ -55,7 +55,8 @@ struct traversal_ring_creator
|
|||||||
<
|
<
|
||||||
Reverse1, Reverse2, OverlayType,
|
Reverse1, Reverse2, OverlayType,
|
||||||
Geometry1, Geometry2, Turns, Clusters,
|
Geometry1, Geometry2, Turns, Clusters,
|
||||||
RobustPolicy, typename IntersectionStrategy::side_strategy_type,
|
RobustPolicy,
|
||||||
|
decltype(std::declval<Strategy>().side()),
|
||||||
Visitor
|
Visitor
|
||||||
> traversal_type;
|
> traversal_type;
|
||||||
|
|
||||||
@ -68,17 +69,16 @@ struct traversal_ring_creator
|
|||||||
inline traversal_ring_creator(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
inline traversal_ring_creator(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||||
Turns& turns, TurnInfoMap& turn_info_map,
|
Turns& turns, TurnInfoMap& turn_info_map,
|
||||||
Clusters const& clusters,
|
Clusters const& clusters,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy, Visitor& visitor)
|
RobustPolicy const& robust_policy, Visitor& visitor)
|
||||||
: m_trav(geometry1, geometry2, turns, clusters,
|
: m_trav(geometry1, geometry2, turns, clusters,
|
||||||
robust_policy, intersection_strategy.get_side_strategy(),
|
robust_policy, strategy.side(), visitor)
|
||||||
visitor)
|
|
||||||
, m_geometry1(geometry1)
|
, m_geometry1(geometry1)
|
||||||
, m_geometry2(geometry2)
|
, m_geometry2(geometry2)
|
||||||
, m_turns(turns)
|
, m_turns(turns)
|
||||||
, m_turn_info_map(turn_info_map)
|
, m_turn_info_map(turn_info_map)
|
||||||
, m_clusters(clusters)
|
, m_clusters(clusters)
|
||||||
, m_intersection_strategy(intersection_strategy)
|
, m_strategy(strategy)
|
||||||
, m_robust_policy(robust_policy)
|
, m_robust_policy(robust_policy)
|
||||||
, m_visitor(visitor)
|
, m_visitor(visitor)
|
||||||
{
|
{
|
||||||
@ -113,15 +113,13 @@ struct traversal_ring_creator
|
|||||||
{
|
{
|
||||||
geometry::copy_segments<Reverse1>(m_geometry1,
|
geometry::copy_segments<Reverse1>(m_geometry1,
|
||||||
previous_op.seg_id, to_vertex_index,
|
previous_op.seg_id, to_vertex_index,
|
||||||
m_intersection_strategy.get_side_strategy(),
|
m_strategy, m_robust_policy, current_ring);
|
||||||
m_robust_policy, current_ring);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
geometry::copy_segments<Reverse2>(m_geometry2,
|
geometry::copy_segments<Reverse2>(m_geometry2,
|
||||||
previous_op.seg_id, to_vertex_index,
|
previous_op.seg_id, to_vertex_index,
|
||||||
m_intersection_strategy.get_side_strategy(),
|
m_strategy, m_robust_policy, current_ring);
|
||||||
m_robust_policy, current_ring);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +162,7 @@ struct traversal_ring_creator
|
|||||||
turn_type& current_turn = m_turns[turn_index];
|
turn_type& current_turn = m_turns[turn_index];
|
||||||
turn_operation_type& op = current_turn.operations[op_index];
|
turn_operation_type& op = current_turn.operations[op_index];
|
||||||
detail::overlay::append_no_collinear(current_ring, current_turn.point,
|
detail::overlay::append_no_collinear(current_ring, current_turn.point,
|
||||||
m_intersection_strategy.get_side_strategy(),
|
m_strategy, m_robust_policy);
|
||||||
m_robust_policy);
|
|
||||||
|
|
||||||
// Register the visit
|
// Register the visit
|
||||||
m_trav.set_visited(current_turn, op);
|
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];
|
turn_operation_type& start_op = m_turns[start_turn_index].operations[start_op_index];
|
||||||
|
|
||||||
detail::overlay::append_no_collinear(ring, start_turn.point,
|
detail::overlay::append_no_collinear(ring, start_turn.point,
|
||||||
m_intersection_strategy.get_side_strategy(),
|
m_strategy, m_robust_policy);
|
||||||
m_robust_policy);
|
|
||||||
|
|
||||||
signed_size_type current_turn_index = start_turn_index;
|
signed_size_type current_turn_index = start_turn_index;
|
||||||
int current_op_index = start_op_index;
|
int current_op_index = start_op_index;
|
||||||
@ -286,9 +282,7 @@ struct traversal_ring_creator
|
|||||||
|
|
||||||
if (geometry::num_points(ring) >= min_num_points)
|
if (geometry::num_points(ring) >= min_num_points)
|
||||||
{
|
{
|
||||||
clean_closing_dups_and_spikes(ring,
|
clean_closing_dups_and_spikes(ring, m_strategy, m_robust_policy);
|
||||||
m_intersection_strategy.get_side_strategy(),
|
|
||||||
m_robust_policy);
|
|
||||||
rings.push_back(ring);
|
rings.push_back(ring);
|
||||||
|
|
||||||
m_trav.finalize_visit_info(m_turn_info_map);
|
m_trav.finalize_visit_info(m_turn_info_map);
|
||||||
@ -297,14 +291,13 @@ struct traversal_ring_creator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backtrack::apply(
|
Backtrack::apply(finalized_ring_size,
|
||||||
finalized_ring_size,
|
rings, ring, m_turns, start_turn,
|
||||||
rings, ring, m_turns, start_turn,
|
m_turns[turn_index].operations[op_index],
|
||||||
m_turns[turn_index].operations[op_index],
|
traverse_error,
|
||||||
traverse_error,
|
m_geometry1, m_geometry2,
|
||||||
m_geometry1, m_geometry2,
|
m_strategy, m_robust_policy,
|
||||||
m_intersection_strategy, m_robust_policy,
|
state, m_visitor);
|
||||||
state, m_visitor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +406,7 @@ private:
|
|||||||
Turns& m_turns;
|
Turns& m_turns;
|
||||||
TurnInfoMap& m_turn_info_map; // contains turn-info information per ring
|
TurnInfoMap& m_turn_info_map; // contains turn-info information per ring
|
||||||
Clusters const& m_clusters;
|
Clusters const& m_clusters;
|
||||||
IntersectionStrategy const& m_intersection_strategy;
|
Strategy const& m_strategy;
|
||||||
RobustPolicy const& m_robust_policy;
|
RobustPolicy const& m_robust_policy;
|
||||||
Visitor& m_visitor;
|
Visitor& m_visitor;
|
||||||
};
|
};
|
||||||
|
@ -209,10 +209,10 @@ struct areal_areal
|
|||||||
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
||||||
typedef typename geometry::point_type<Geometry2>::type point2_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,
|
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||||
Result & result,
|
Result & result,
|
||||||
IntersectionStrategy const& intersection_strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// TODO: If Areal geometry may have infinite size, change the following line:
|
// TODO: If Areal geometry may have infinite size, change the following line:
|
||||||
|
|
||||||
@ -226,38 +226,25 @@ struct areal_areal
|
|||||||
typedef typename turns::get_turns
|
typedef typename turns::get_turns
|
||||||
<
|
<
|
||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::template turn_info_type<IntersectionStrategy>::type turn_type;
|
>::template turn_info_type<Strategy>::type turn_type;
|
||||||
std::vector<turn_type> turns;
|
std::vector<turn_type> turns;
|
||||||
|
|
||||||
interrupt_policy_areal_areal<Result> interrupt_policy(geometry1, geometry2, result);
|
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) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef typename IntersectionStrategy::cs_tag cs_tag;
|
typedef typename Strategy::cs_tag cs_tag;
|
||||||
|
|
||||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy
|
no_turns_aa_pred<Geometry2, Result, Strategy, false>
|
||||||
<
|
pred1(geometry2, result, strategy);
|
||||||
Geometry1, Geometry2
|
|
||||||
>::type point_in_areal_strategy12_type;
|
|
||||||
point_in_areal_strategy12_type point_in_areal_strategy12
|
|
||||||
= intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
|
|
||||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy
|
|
||||||
<
|
|
||||||
Geometry2, Geometry1
|
|
||||||
>::type point_in_areal_strategy21_type;
|
|
||||||
point_in_areal_strategy21_type point_in_areal_strategy21
|
|
||||||
= intersection_strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>();
|
|
||||||
|
|
||||||
no_turns_aa_pred<Geometry2, Result, point_in_areal_strategy12_type, false>
|
|
||||||
pred1(geometry2, result, point_in_areal_strategy12);
|
|
||||||
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
||||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
no_turns_aa_pred<Geometry1, Result, point_in_areal_strategy21_type, true>
|
no_turns_aa_pred<Geometry1, Result, Strategy, true>
|
||||||
pred2(geometry1, result, point_in_areal_strategy21);
|
pred2(geometry1, result, strategy);
|
||||||
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
|
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
|
||||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
return;
|
return;
|
||||||
@ -282,8 +269,7 @@ struct areal_areal
|
|||||||
{
|
{
|
||||||
// analyse sorted turns
|
// analyse sorted turns
|
||||||
turns_analyser<turn_type, 0> analyser;
|
turns_analyser<turn_type, 0> analyser;
|
||||||
analyse_each_turn(result, analyser, turns.begin(), turns.end(),
|
analyse_each_turn(result, analyser, turns.begin(), turns.end(), strategy);
|
||||||
point_in_areal_strategy12.get_equals_point_point_strategy());
|
|
||||||
|
|
||||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
return;
|
return;
|
||||||
@ -297,8 +283,8 @@ struct areal_areal
|
|||||||
{
|
{
|
||||||
// analyse rings for which turns were not generated
|
// analyse rings for which turns were not generated
|
||||||
// or only i/i or u/u was generated
|
// or only i/i or u/u was generated
|
||||||
uncertain_rings_analyser<0, Result, Geometry1, Geometry2, point_in_areal_strategy12_type>
|
uncertain_rings_analyser<0, Result, Geometry1, Geometry2, Strategy>
|
||||||
rings_analyser(result, geometry1, geometry2, point_in_areal_strategy12);
|
rings_analyser(result, geometry1, geometry2, strategy);
|
||||||
analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());
|
analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());
|
||||||
|
|
||||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
@ -323,8 +309,7 @@ struct areal_areal
|
|||||||
{
|
{
|
||||||
// analyse sorted turns
|
// analyse sorted turns
|
||||||
turns_analyser<turn_type, 1> analyser;
|
turns_analyser<turn_type, 1> analyser;
|
||||||
analyse_each_turn(result, analyser, turns.begin(), turns.end(),
|
analyse_each_turn(result, analyser, turns.begin(), turns.end(), strategy);
|
||||||
point_in_areal_strategy21.get_equals_point_point_strategy());
|
|
||||||
|
|
||||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
return;
|
return;
|
||||||
@ -338,8 +323,8 @@ struct areal_areal
|
|||||||
{
|
{
|
||||||
// analyse rings for which turns were not generated
|
// analyse rings for which turns were not generated
|
||||||
// or only i/i or u/u was generated
|
// or only i/i or u/u was generated
|
||||||
uncertain_rings_analyser<1, Result, Geometry2, Geometry1, point_in_areal_strategy21_type>
|
uncertain_rings_analyser<1, Result, Geometry2, Geometry1, Strategy>
|
||||||
rings_analyser(result, geometry2, geometry1, point_in_areal_strategy21);
|
rings_analyser(result, geometry2, geometry1, strategy);
|
||||||
analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end());
|
analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end());
|
||||||
|
|
||||||
//if ( result.interrupt )
|
//if ( result.interrupt )
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
// 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
|
// 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 };
|
enum boundary_query { boundary_front, boundary_back, boundary_any };
|
||||||
|
|
||||||
template <typename Geometry,
|
template
|
||||||
typename WithinStrategy, // Point/Point equals (within) strategy
|
<
|
||||||
typename Tag = typename geometry::tag<Geometry>::type>
|
typename Geometry,
|
||||||
|
typename Strategy,
|
||||||
|
typename Tag = typename geometry::tag<Geometry>::type
|
||||||
|
>
|
||||||
class boundary_checker {};
|
class boundary_checker {};
|
||||||
|
|
||||||
template <typename Geometry, typename WithinStrategy>
|
template <typename Geometry, typename Strategy>
|
||||||
class boundary_checker<Geometry, WithinStrategy, linestring_tag>
|
class boundary_checker<Geometry, Strategy, linestring_tag>
|
||||||
{
|
{
|
||||||
typedef typename point_type<Geometry>::type point_type;
|
typedef typename point_type<Geometry>::type point_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef WithinStrategy equals_strategy_type;
|
boundary_checker(Geometry const& g, Strategy const& s)
|
||||||
|
: m_has_boundary( boost::size(g) >= 2
|
||||||
boundary_checker(Geometry const& g)
|
&& ! detail::equals::equals_point_point(range::front(g),
|
||||||
: has_boundary( boost::size(g) >= 2
|
range::back(g),
|
||||||
&& !detail::equals::equals_point_point(range::front(g),
|
s) )
|
||||||
range::back(g),
|
|
||||||
equals_strategy_type()) )
|
|
||||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
||||||
, geometry(g)
|
, m_geometry(g)
|
||||||
#endif
|
#endif
|
||||||
|
, m_strategy(s)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <boundary_query BoundaryQuery>
|
template <boundary_query BoundaryQuery>
|
||||||
@ -60,30 +62,34 @@ public:
|
|||||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
||||||
// may give false positives for INT
|
// may give false positives for INT
|
||||||
BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
|
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)
|
|| (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
|
#endif
|
||||||
return has_boundary;
|
return m_has_boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
Strategy const& strategy() const
|
||||||
|
{
|
||||||
|
return m_strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool has_boundary;
|
bool m_has_boundary;
|
||||||
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
|
||||||
Geometry const& geometry;
|
Geometry const& m_geometry;
|
||||||
#endif
|
#endif
|
||||||
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Geometry, typename WithinStrategy>
|
template <typename Geometry, typename Strategy>
|
||||||
class boundary_checker<Geometry, WithinStrategy, multi_linestring_tag>
|
class boundary_checker<Geometry, Strategy, multi_linestring_tag>
|
||||||
{
|
{
|
||||||
typedef typename point_type<Geometry>::type point_type;
|
typedef typename point_type<Geometry>::type point_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef WithinStrategy equals_strategy_type;
|
boundary_checker(Geometry const& g, Strategy const& s)
|
||||||
|
: m_is_filled(false), m_geometry(g), m_strategy(s)
|
||||||
boundary_checker(Geometry const& g)
|
|
||||||
: is_filled(false), geometry(g)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// First call O(NlogN)
|
// First call O(NlogN)
|
||||||
@ -91,22 +97,22 @@ public:
|
|||||||
template <boundary_query BoundaryQuery>
|
template <boundary_query BoundaryQuery>
|
||||||
bool is_endpoint_boundary(point_type const& pt) const
|
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;
|
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 )
|
if ( multi_count < 1 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( ! is_filled )
|
if ( ! m_is_filled )
|
||||||
{
|
{
|
||||||
//boundary_points.clear();
|
//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;
|
typedef typename boost::range_iterator<Geometry const>::type multi_iterator;
|
||||||
for ( multi_iterator it = boost::begin(geometry) ;
|
for ( multi_iterator it = boost::begin(m_geometry) ;
|
||||||
it != boost::end(geometry) ; ++ it )
|
it != boost::end(m_geometry) ; ++ it )
|
||||||
{
|
{
|
||||||
typename boost::range_reference<Geometry const>::type
|
typename boost::range_reference<Geometry const>::type
|
||||||
ls = *it;
|
ls = *it;
|
||||||
@ -126,33 +132,33 @@ public:
|
|||||||
point_reference back_pt = range::back(ls);
|
point_reference back_pt = range::back(ls);
|
||||||
|
|
||||||
// linear ring or point - no boundary
|
// 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
|
// do not add points containing NaN coordinates
|
||||||
// because they cannot be reasonably compared, e.g. with MSVC
|
// because they cannot be reasonably compared, e.g. with MSVC
|
||||||
// an assertion failure is reported in std::equal_range()
|
// an assertion failure is reported in std::equal_range()
|
||||||
if (! geometry::has_nan_coordinate(front_pt))
|
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))
|
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(),
|
std::sort(m_boundary_points.begin(),
|
||||||
boundary_points.end(),
|
m_boundary_points.end(),
|
||||||
less_type());
|
less_type());
|
||||||
|
|
||||||
is_filled = true;
|
m_is_filled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t equal_points_count
|
std::size_t equal_points_count
|
||||||
= boost::size(
|
= boost::size(
|
||||||
std::equal_range(boundary_points.begin(),
|
std::equal_range(m_boundary_points.begin(),
|
||||||
boundary_points.end(),
|
m_boundary_points.end(),
|
||||||
pt,
|
pt,
|
||||||
less_type())
|
less_type())
|
||||||
);
|
);
|
||||||
@ -160,12 +166,18 @@ public:
|
|||||||
return equal_points_count % 2 != 0;// && equal_points_count > 0; // the number is odd and > 0
|
return equal_points_count % 2 != 0;// && equal_points_count > 0; // the number is odd and > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
Strategy const& strategy() const
|
||||||
mutable bool is_filled;
|
{
|
||||||
// TODO: store references/pointers instead of points?
|
return m_strategy;
|
||||||
mutable std::vector<point_type> boundary_points;
|
}
|
||||||
|
|
||||||
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
|
}} // namespace detail::relate
|
||||||
|
@ -341,9 +341,9 @@ private:
|
|||||||
std::vector<point_info> m_other_entry_points; // TODO: use map here or sorted vector?
|
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,
|
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& prev_seg_id = prev_turn.operations[OpId].seg_id;
|
||||||
segment_identifier const& curr_seg_id = curr_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/core/topological_dimension.hpp>
|
||||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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/sequence.hpp>
|
||||||
#include <boost/geometry/util/type_traits.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 {
|
namespace resolve_strategy {
|
||||||
|
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct relate
|
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,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
ResultHandler & handler,
|
ResultHandler & handler,
|
||||||
@ -175,14 +182,37 @@ struct relate
|
|||||||
Geometry2
|
Geometry2
|
||||||
>::apply(geometry1, geometry2, handler, strategy);
|
>::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>
|
template <typename Geometry1, typename Geometry2, typename ResultHandler>
|
||||||
static inline void apply(Geometry1 const& geometry1,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
ResultHandler & handler,
|
ResultHandler & handler,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
@ -220,7 +250,7 @@ struct relate
|
|||||||
Mask
|
Mask
|
||||||
>::type handler(mask);
|
>::type handler(mask);
|
||||||
|
|
||||||
resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
|
resolve_strategy::relate<Strategy>::apply(geometry1, geometry2, handler, strategy);
|
||||||
|
|
||||||
return handler.result();
|
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,
|
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||||
Result & result,
|
Result & result,
|
||||||
IntersectionStrategy const& intersection_strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
// TODO: If Areal geometry may have infinite size, change the following line:
|
// TODO: If Areal geometry may have infinite size, change the following line:
|
||||||
|
|
||||||
@ -243,38 +243,34 @@ struct linear_areal
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// get and analyse turns
|
// 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;
|
std::vector<turn_type> turns;
|
||||||
|
|
||||||
interrupt_policy_linear_areal<Geometry2, Result> interrupt_policy(geometry2, result);
|
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 ) )
|
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef typename IntersectionStrategy::template point_in_geometry_strategy<Geometry1, Geometry2>::type within_strategy_type;
|
typedef typename Strategy::cs_tag cs_tag;
|
||||||
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 boundary_checker
|
typedef boundary_checker
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
eq_pp_strategy_type
|
Strategy
|
||||||
> boundary_checker1_type;
|
> boundary_checker1_type;
|
||||||
boundary_checker1_type boundary_checker1(geometry1);
|
boundary_checker1_type boundary_checker1(geometry1, strategy);
|
||||||
|
|
||||||
no_turns_la_linestring_pred
|
no_turns_la_linestring_pred
|
||||||
<
|
<
|
||||||
Geometry2,
|
Geometry2,
|
||||||
Result,
|
Result,
|
||||||
within_strategy_type,
|
Strategy,
|
||||||
boundary_checker1_type,
|
boundary_checker1_type,
|
||||||
TransposeResult
|
TransposeResult
|
||||||
> pred1(geometry2,
|
> pred1(geometry2,
|
||||||
result,
|
result,
|
||||||
within_strategy,
|
strategy,
|
||||||
boundary_checker1);
|
boundary_checker1);
|
||||||
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
||||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||||
@ -302,7 +298,7 @@ struct linear_areal
|
|||||||
turns.begin(), turns.end(),
|
turns.begin(), turns.end(),
|
||||||
geometry1, geometry2,
|
geometry1, geometry2,
|
||||||
boundary_checker1,
|
boundary_checker1,
|
||||||
intersection_strategy.get_side_strategy());
|
strategy);
|
||||||
|
|
||||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||||
return;
|
return;
|
||||||
@ -395,14 +391,12 @@ struct linear_areal
|
|||||||
typedef turns::less<1, turns::less_op_areal_linear<1>, cs_tag> less;
|
typedef turns::less<1, turns::less_op_areal_linear<1>, cs_tag> less;
|
||||||
std::sort(it, next, less());
|
std::sort(it, next, less());
|
||||||
|
|
||||||
eq_pp_strategy_type const eq_pp_strategy = within_strategy.get_equals_point_point_strategy();
|
|
||||||
|
|
||||||
// analyse
|
// analyse
|
||||||
areal_boundary_analyser<turn_type> analyser;
|
areal_boundary_analyser<turn_type> analyser;
|
||||||
for ( turn_iterator rit = it ; rit != next ; ++rit )
|
for ( turn_iterator rit = it ; rit != next ; ++rit )
|
||||||
{
|
{
|
||||||
// if the analyser requests, break the search
|
// if the analyser requests, break the search
|
||||||
if ( !analyser.apply(it, rit, next, eq_pp_strategy) )
|
if ( !analyser.apply(it, rit, next, strategy) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,18 +620,20 @@ struct linear_areal
|
|||||||
static const std::size_t other_op_id = 1;
|
static const std::size_t other_op_id = 1;
|
||||||
|
|
||||||
template <typename TurnPointCSTag, typename PointP, typename PointQ,
|
template <typename TurnPointCSTag, typename PointP, typename PointQ,
|
||||||
typename SideStrategy,
|
typename Strategy,
|
||||||
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
|
typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
|
||||||
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
|
typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
|
||||||
>
|
>
|
||||||
struct la_side_calculator
|
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,
|
inline la_side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
|
||||||
Qi const& qi, Qj const& qj, Qk const& qk,
|
Qi const& qi, Qj const& qj, Qk const& qk,
|
||||||
SideStrategy const& side_strategy)
|
Strategy const& strategy)
|
||||||
: m_pi(pi), m_pj(pj), m_pk(pk)
|
: m_pi(pi), m_pj(pj), m_pk(pk)
|
||||||
, m_qi(qi), m_qj(qj), m_qk(qk)
|
, 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); }
|
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;
|
Qj const& m_qj;
|
||||||
Qk const& m_qk;
|
Qk const& m_qk;
|
||||||
|
|
||||||
SideStrategy m_side_strategy;
|
side_strategy_type m_side_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -672,12 +668,12 @@ struct linear_areal
|
|||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename OtherGeometry,
|
typename OtherGeometry,
|
||||||
typename BoundaryChecker,
|
typename BoundaryChecker,
|
||||||
typename SideStrategy>
|
typename Strategy>
|
||||||
void apply(Result & res, TurnIt it,
|
void apply(Result & res, TurnIt it,
|
||||||
Geometry const& geometry,
|
Geometry const& geometry,
|
||||||
OtherGeometry const& other_geometry,
|
OtherGeometry const& other_geometry,
|
||||||
BoundaryChecker const& boundary_checker,
|
BoundaryChecker const& boundary_checker,
|
||||||
SideStrategy const& side_strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
overlay::operation_type op = it->operations[op_id].operation;
|
overlay::operation_type op = it->operations[op_id].operation;
|
||||||
|
|
||||||
@ -706,7 +702,7 @@ struct linear_areal
|
|||||||
// real exit point - may be multiple
|
// real exit point - may be multiple
|
||||||
// we know that we entered and now we exit
|
// we know that we entered and now we exit
|
||||||
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
|
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();
|
m_exit_watcher.reset_detected_exit();
|
||||||
|
|
||||||
@ -749,7 +745,7 @@ struct linear_areal
|
|||||||
if ( ( op == overlay::operation_intersection
|
if ( ( op == overlay::operation_intersection
|
||||||
|| op == overlay::operation_continue )
|
|| op == overlay::operation_continue )
|
||||||
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
|
&& 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;
|
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
|
|| 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
|
|| ( m_previous_operation == overlay::operation_union
|
||||||
&& ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
|
&& ! 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);
|
update<interior, exterior, '1', TransposeResult>(res);
|
||||||
@ -803,7 +799,7 @@ struct linear_areal
|
|||||||
|
|
||||||
// real interior overlap
|
// real interior overlap
|
||||||
if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
|
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);
|
update<interior, interior, '1', TransposeResult>(res);
|
||||||
m_interior_detected = false;
|
m_interior_detected = false;
|
||||||
@ -919,7 +915,7 @@ struct linear_areal
|
|||||||
&& calculate_from_inside(geometry,
|
&& calculate_from_inside(geometry,
|
||||||
other_geometry,
|
other_geometry,
|
||||||
*it,
|
*it,
|
||||||
side_strategy);
|
strategy);
|
||||||
|
|
||||||
if ( from_inside )
|
if ( from_inside )
|
||||||
update<interior, interior, '1', TransposeResult>(res);
|
update<interior, interior, '1', TransposeResult>(res);
|
||||||
@ -1020,7 +1016,7 @@ struct linear_areal
|
|||||||
&& calculate_from_inside(geometry,
|
&& calculate_from_inside(geometry,
|
||||||
other_geometry,
|
other_geometry,
|
||||||
*it,
|
*it,
|
||||||
side_strategy);
|
strategy);
|
||||||
if ( first_from_inside )
|
if ( first_from_inside )
|
||||||
{
|
{
|
||||||
update<interior, interior, '1', TransposeResult>(res);
|
update<interior, interior, '1', TransposeResult>(res);
|
||||||
@ -1208,11 +1204,11 @@ struct linear_areal
|
|||||||
|
|
||||||
// check if the passed turn's segment of Linear geometry arrived
|
// check if the passed turn's segment of Linear geometry arrived
|
||||||
// from the inside or the outside of the Areal geometry
|
// 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,
|
static inline bool calculate_from_inside(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Turn const& turn,
|
Turn const& turn,
|
||||||
SideStrategy const& side_strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename cs_tag<typename Turn::point_type>::type cs_tag;
|
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);
|
point2_type const& qj = range::at(range2, q_seg_ij + 1);
|
||||||
point1_type qi_conv;
|
point1_type qi_conv;
|
||||||
geometry::convert(qi, 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!
|
// TODO: test this!
|
||||||
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
|
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
|
||||||
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
|
// 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),
|
range2_iterator qk_it = find_next_non_duplicated(boost::begin(range2),
|
||||||
range::pos(range2, q_seg_jk),
|
range::pos(range2, q_seg_jk),
|
||||||
boost::end(range2),
|
boost::end(range2),
|
||||||
side_strategy.get_equals_point_point_strategy());
|
strategy);
|
||||||
|
|
||||||
// Will this sequence of points be always correct?
|
// Will this sequence of points be always correct?
|
||||||
la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
|
la_side_calculator<cs_tag, point1_type, point2_type, Strategy>
|
||||||
side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, side_strategy);
|
side_calc(qi_conv, new_pj, pi, qi, qj, *qk_it, strategy);
|
||||||
|
|
||||||
return calculate_from_inside_sides(side_calc);
|
return calculate_from_inside_sides(side_calc);
|
||||||
}
|
}
|
||||||
@ -1270,16 +1266,16 @@ struct linear_areal
|
|||||||
point2_type new_qj;
|
point2_type new_qj;
|
||||||
geometry::convert(turn.point, new_qj);
|
geometry::convert(turn.point, new_qj);
|
||||||
|
|
||||||
la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
|
la_side_calculator<cs_tag, point1_type, point2_type, Strategy>
|
||||||
side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, side_strategy);
|
side_calc(qi_conv, new_pj, pi, qi, new_qj, qj, strategy);
|
||||||
|
|
||||||
return calculate_from_inside_sides(side_calc);
|
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,
|
static inline It find_next_non_duplicated(It first, It current, It last,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
BOOST_GEOMETRY_ASSERT( current != last );
|
BOOST_GEOMETRY_ASSERT( current != last );
|
||||||
|
|
||||||
@ -1340,14 +1336,14 @@ struct linear_areal
|
|||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename OtherGeometry,
|
typename OtherGeometry,
|
||||||
typename BoundaryChecker,
|
typename BoundaryChecker,
|
||||||
typename SideStrategy>
|
typename Strategy>
|
||||||
static inline void analyse_each_turn(Result & res,
|
static inline void analyse_each_turn(Result & res,
|
||||||
Analyser & analyser,
|
Analyser & analyser,
|
||||||
TurnIt first, TurnIt last,
|
TurnIt first, TurnIt last,
|
||||||
Geometry const& geometry,
|
Geometry const& geometry,
|
||||||
OtherGeometry const& other_geometry,
|
OtherGeometry const& other_geometry,
|
||||||
BoundaryChecker const& boundary_checker,
|
BoundaryChecker const& boundary_checker,
|
||||||
SideStrategy const& side_strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
if ( first == last )
|
if ( first == last )
|
||||||
return;
|
return;
|
||||||
@ -1357,7 +1353,7 @@ struct linear_areal
|
|||||||
analyser.apply(res, it,
|
analyser.apply(res, it,
|
||||||
geometry, other_geometry,
|
geometry, other_geometry,
|
||||||
boundary_checker,
|
boundary_checker,
|
||||||
side_strategy);
|
strategy);
|
||||||
|
|
||||||
if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
|
if ( BOOST_GEOMETRY_CONDITION( res.interrupt ) )
|
||||||
return;
|
return;
|
||||||
@ -1437,9 +1433,9 @@ struct linear_areal
|
|||||||
, m_previous_turn_ptr(NULL)
|
, m_previous_turn_ptr(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename TurnIt, typename EqPPStrategy>
|
template <typename TurnIt, typename Strategy>
|
||||||
bool apply(TurnIt /*first*/, TurnIt it, TurnIt last,
|
bool apply(TurnIt /*first*/, TurnIt it, TurnIt last,
|
||||||
EqPPStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
overlay::operation_type op = it->operations[1].operation;
|
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;
|
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,
|
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||||
Result & result,
|
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>
|
template <typename Result, typename BoundaryChecker, bool TransposeResult>
|
||||||
class disjoint_linestring_pred
|
class disjoint_linestring_pred
|
||||||
{
|
{
|
||||||
typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
disjoint_linestring_pred(Result & res,
|
disjoint_linestring_pred(Result & res,
|
||||||
BoundaryChecker const& boundary_checker)
|
BoundaryChecker const& boundary_checker)
|
||||||
@ -83,7 +81,7 @@ public:
|
|||||||
if ( count == 2
|
if ( count == 2
|
||||||
&& equals::equals_point_point(range::front(linestring),
|
&& equals::equals_point_point(range::front(linestring),
|
||||||
range::back(linestring),
|
range::back(linestring),
|
||||||
equals_strategy_type()) )
|
m_boundary_checker.strategy()) )
|
||||||
{
|
{
|
||||||
update<interior, exterior, '0', TransposeResult>(m_result);
|
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<Geometry1>::type point1_type;
|
||||||
typedef typename geometry::point_type<Geometry2>::type point2_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,
|
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||||
Result & result,
|
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
|
// The result should be FFFFFFFFF
|
||||||
relate::set<exterior, exterior, result_dimension<Geometry1>::value>(result);// FFFFFFFFd, d in [1,9] or T
|
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
|
typedef typename turns::get_turns
|
||||||
<
|
<
|
||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::template turn_info_type<IntersectionStrategy>::type turn_type;
|
>::template turn_info_type<Strategy>::type turn_type;
|
||||||
std::vector<turn_type> turns;
|
std::vector<turn_type> turns;
|
||||||
|
|
||||||
interrupt_policy_linear_linear<Result> interrupt_policy(result);
|
interrupt_policy_linear_linear<Result> interrupt_policy(result);
|
||||||
@ -148,28 +146,20 @@ struct linear_linear
|
|||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2,
|
Geometry2,
|
||||||
detail::get_turns::get_turn_info_type<Geometry1, Geometry2, turns::assign_policy<true> >
|
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 ) )
|
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef boundary_checker
|
typedef boundary_checker<Geometry1, Strategy> boundary_checker1_type;
|
||||||
<
|
boundary_checker1_type boundary_checker1(geometry1, strategy);
|
||||||
Geometry1,
|
|
||||||
typename IntersectionStrategy::point_in_point_strategy_type
|
|
||||||
> boundary_checker1_type;
|
|
||||||
boundary_checker1_type boundary_checker1(geometry1);
|
|
||||||
disjoint_linestring_pred<Result, boundary_checker1_type, false> pred1(result, boundary_checker1);
|
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);
|
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
|
||||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef boundary_checker
|
typedef boundary_checker<Geometry2, Strategy> boundary_checker2_type;
|
||||||
<
|
boundary_checker2_type boundary_checker2(geometry2, strategy);
|
||||||
Geometry2,
|
|
||||||
typename IntersectionStrategy::point_in_point_strategy_type
|
|
||||||
> boundary_checker2_type;
|
|
||||||
boundary_checker2_type boundary_checker2(geometry2);
|
|
||||||
disjoint_linestring_pred<Result, boundary_checker2_type, true> pred2(result, boundary_checker2);
|
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);
|
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
|
||||||
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
|
||||||
@ -292,8 +282,6 @@ struct linear_linear
|
|||||||
BoundaryChecker const& boundary_checker,
|
BoundaryChecker const& boundary_checker,
|
||||||
OtherBoundaryChecker const& other_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;
|
overlay::operation_type const op = it->operations[op_id].operation;
|
||||||
|
|
||||||
segment_identifier const& seg_id = it->operations[op_id].seg_id;
|
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
|
// we know that we entered and now we exit
|
||||||
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
|
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
|
||||||
*it,
|
*it,
|
||||||
equals_strategy_type()) )
|
boundary_checker.strategy()) )
|
||||||
{
|
{
|
||||||
m_exit_watcher.reset_detected_exit();
|
m_exit_watcher.reset_detected_exit();
|
||||||
|
|
||||||
@ -368,7 +356,7 @@ struct linear_linear
|
|||||||
if ( op == overlay::operation_intersection
|
if ( op == overlay::operation_intersection
|
||||||
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
|
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
|
||||||
*it,
|
*it,
|
||||||
equals_strategy_type()) )
|
boundary_checker.strategy()) )
|
||||||
{
|
{
|
||||||
fake_enter_detected = true;
|
fake_enter_detected = true;
|
||||||
}
|
}
|
||||||
@ -668,14 +656,9 @@ struct linear_linear
|
|||||||
Geometry const& geometry,
|
Geometry const& geometry,
|
||||||
OtherGeometry const& other_geometry,
|
OtherGeometry const& other_geometry,
|
||||||
BoundaryChecker const& boundary_checker,
|
BoundaryChecker const& boundary_checker,
|
||||||
OtherBoundaryChecker const& /*other_boundary_checker*/,
|
OtherBoundaryChecker const& other_boundary_checker,
|
||||||
bool first_in_range)
|
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
|
typename detail::single_geometry_return_type<Geometry const>::type
|
||||||
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
|
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
|
||||||
typename detail::single_geometry_return_type<OtherGeometry const>::type
|
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
|
bool const is_point1 = boost::size(ls1_ref) == 2
|
||||||
&& equals::equals_point_point(range::front(ls1_ref),
|
&& equals::equals_point_point(range::front(ls1_ref),
|
||||||
range::back(ls1_ref),
|
range::back(ls1_ref),
|
||||||
equals_strategy1_type());
|
boundary_checker.strategy());
|
||||||
bool const is_point2 = boost::size(ls2_ref) == 2
|
bool const is_point2 = boost::size(ls2_ref) == 2
|
||||||
&& equals::equals_point_point(range::front(ls2_ref),
|
&& equals::equals_point_point(range::front(ls2_ref),
|
||||||
range::back(ls2_ref),
|
range::back(ls2_ref),
|
||||||
equals_strategy2_type());
|
other_boundary_checker.strategy());
|
||||||
|
|
||||||
// if the second one is degenerated
|
// if the second one is degenerated
|
||||||
if ( !is_point1 && is_point2 )
|
if ( !is_point1 && is_point2 )
|
||||||
|
@ -50,21 +50,20 @@ namespace detail { namespace relate
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename EqPPStrategy,
|
|
||||||
typename Tag = typename tag<Geometry>::type
|
typename Tag = typename tag<Geometry>::type
|
||||||
>
|
>
|
||||||
struct multi_point_geometry_eb
|
struct multi_point_geometry_eb
|
||||||
{
|
{
|
||||||
template <typename MultiPoint>
|
template <typename MultiPoint, typename Strategy>
|
||||||
static inline bool apply(MultiPoint const& ,
|
static inline bool apply(MultiPoint const& ,
|
||||||
detail::relate::topology_check<Geometry, EqPPStrategy> const& )
|
detail::relate::topology_check<Geometry, Strategy> const& )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Geometry, typename EqPPStrategy>
|
template <typename Geometry>
|
||||||
struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
struct multi_point_geometry_eb<Geometry, linestring_tag>
|
||||||
{
|
{
|
||||||
template <typename Points>
|
template <typename Points>
|
||||||
struct boundary_visitor
|
struct boundary_visitor
|
||||||
@ -74,26 +73,30 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
|||||||
, m_boundary_found(false)
|
, m_boundary_found(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename Strategy>
|
||||||
struct find_pred
|
struct find_pred
|
||||||
{
|
{
|
||||||
find_pred(Point const& point)
|
find_pred(Point const& point, Strategy const& strategy)
|
||||||
: m_point(point)
|
: m_point(point)
|
||||||
|
, m_strategy(strategy)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Pt>
|
template <typename Pt>
|
||||||
bool operator()(Pt const& pt) const
|
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;
|
Point const& m_point;
|
||||||
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename Strategy>
|
||||||
bool apply(Point const& boundary_point)
|
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;
|
m_boundary_found = true;
|
||||||
return false;
|
return false;
|
||||||
@ -108,9 +111,9 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
|||||||
bool m_boundary_found;
|
bool m_boundary_found;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MultiPoint>
|
template <typename MultiPoint, typename Strategy>
|
||||||
static inline bool apply(MultiPoint const& multi_point,
|
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);
|
boundary_visitor<MultiPoint> visitor(multi_point);
|
||||||
tc.for_each_boundary_point(visitor);
|
tc.for_each_boundary_point(visitor);
|
||||||
@ -118,12 +121,9 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Geometry, typename EqPPStrategy>
|
template <typename Geometry>
|
||||||
struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
|
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>
|
template <typename Points>
|
||||||
struct boundary_visitor
|
struct boundary_visitor
|
||||||
{
|
{
|
||||||
@ -132,10 +132,13 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
|
|||||||
, m_boundary_found(false)
|
, m_boundary_found(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename Strategy>
|
||||||
bool apply(Point const& boundary_point)
|
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;
|
m_boundary_found = true;
|
||||||
return false;
|
return false;
|
||||||
@ -150,13 +153,15 @@ struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
|
|||||||
bool m_boundary_found;
|
bool m_boundary_found;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MultiPoint>
|
template <typename MultiPoint, typename Strategy>
|
||||||
static inline bool apply(MultiPoint const& multi_point,
|
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 typename boost::range_value<MultiPoint>::type point_type;
|
||||||
typedef std::vector<point_type> points_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());
|
std::sort(points.begin(), points.end(), less_type());
|
||||||
|
|
||||||
boundary_visitor<points_type> visitor(points);
|
boundary_visitor<points_type> visitor(points);
|
||||||
@ -179,11 +184,9 @@ struct multi_point_single_geometry
|
|||||||
{
|
{
|
||||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||||
typedef model::box<point2_type> box2_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;
|
box2_type box2;
|
||||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
geometry::envelope(single_geometry, box2, strategy);
|
||||||
geometry::detail::expand_by_epsilon(box2);
|
geometry::detail::expand_by_epsilon(box2);
|
||||||
|
|
||||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
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
|
// 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);
|
relate::set<interior, exterior, '0', Transpose>(result);
|
||||||
}
|
}
|
||||||
@ -225,14 +228,12 @@ struct multi_point_single_geometry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef detail::relate::topology_check
|
typedef detail::relate::topology_check<SingleGeometry, Strategy> tc_t;
|
||||||
<
|
|
||||||
SingleGeometry, eq_pp_strategy_type
|
|
||||||
> tc_t;
|
|
||||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||||
|| relate::may_update<exterior, boundary, tc_t::boundary, 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)
|
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||||
&& tc.has_interior() )
|
&& tc.has_interior() )
|
||||||
@ -245,10 +246,7 @@ struct multi_point_single_geometry
|
|||||||
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
||||||
&& tc.has_boundary() )
|
&& tc.has_boundary() )
|
||||||
{
|
{
|
||||||
if (multi_point_geometry_eb
|
if (multi_point_geometry_eb<SingleGeometry>::apply(multi_point, tc))
|
||||||
<
|
|
||||||
SingleGeometry, eq_pp_strategy_type
|
|
||||||
>::apply(multi_point, tc))
|
|
||||||
{
|
{
|
||||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
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>
|
template <typename MultiPoint, typename MultiGeometry, bool Transpose>
|
||||||
class multi_point_multi_geometry_ii_ib
|
class multi_point_multi_geometry_ii_ib
|
||||||
{
|
{
|
||||||
template <typename ExpandPointStrategy>
|
template <typename Strategy>
|
||||||
struct expand_box_point
|
struct expand_box_point
|
||||||
{
|
{
|
||||||
|
expand_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
struct expand_box_box_pair
|
||||||
{
|
{
|
||||||
|
expand_box_box_pair(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename BoxPair>
|
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
|
struct overlaps_box_point
|
||||||
{
|
{
|
||||||
|
overlaps_box_point(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Point>
|
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
|
// The default strategy is enough for Point/Box
|
||||||
return ! detail::disjoint::disjoint_point_box(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
|
struct overlaps_box_box_pair
|
||||||
{
|
{
|
||||||
|
overlaps_box_box_pair(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename BoxPair>
|
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
|
// The default strategy is enough for Box/Box
|
||||||
return ! detail::disjoint::disjoint_box_box(box_pair.first, 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
|
class item_visitor_type
|
||||||
{
|
{
|
||||||
typedef typename PtSegStrategy::equals_point_point_strategy_type pp_strategy_type;
|
typedef detail::relate::topology_check<MultiGeometry, Strategy> topology_check_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;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||||
topology_check_type const& tc,
|
topology_check_type const& tc,
|
||||||
Result & result,
|
Result & result,
|
||||||
PtSegStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
: m_multi_geometry(multi_geometry)
|
: m_multi_geometry(multi_geometry)
|
||||||
, m_tc(tc)
|
, m_tc(tc)
|
||||||
, m_result(result)
|
, m_result(result)
|
||||||
@ -332,7 +356,7 @@ class multi_point_multi_geometry_ii_ib
|
|||||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
inline bool apply(Point const& point, BoxPair const& box_pair)
|
||||||
{
|
{
|
||||||
// The default strategy is enough for Point/Box
|
// 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&
|
typename boost::range_value<MultiGeometry>::type const&
|
||||||
single = range::at(m_multi_geometry, box_pair.second);
|
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;
|
MultiGeometry const& m_multi_geometry;
|
||||||
topology_check_type const& m_tc;
|
topology_check_type const& m_tc;
|
||||||
Result & m_result;
|
Result & m_result;
|
||||||
PtSegStrategy const& m_strategy;
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -387,46 +411,21 @@ public:
|
|||||||
std::vector<box_pair_type> const& boxes,
|
std::vector<box_pair_type> const& boxes,
|
||||||
detail::relate::topology_check
|
detail::relate::topology_check
|
||||||
<
|
<
|
||||||
MultiGeometry,
|
MultiGeometry, Strategy
|
||||||
typename Strategy::equals_point_point_strategy_type
|
|
||||||
> const& tc,
|
> const& tc,
|
||||||
Result & result,
|
Result & result,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
item_visitor_type<Result, Strategy> visitor(multi_geometry, tc, result, 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
|
geometry::partition
|
||||||
<
|
<
|
||||||
box1_type
|
box1_type
|
||||||
>::apply(multi_point, boxes, visitor,
|
>::apply(multi_point, boxes, visitor,
|
||||||
expand_box_point_type(),
|
expand_box_point<Strategy>(strategy),
|
||||||
overlaps_box_point_type(),
|
overlaps_box_point<Strategy>(strategy),
|
||||||
expand_box_box_pair_type(),
|
expand_box_box_pair<Strategy>(strategy),
|
||||||
overlaps_box_box_pair_type());
|
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,
|
std::vector<box_pair_type> const& boxes,
|
||||||
detail::relate::topology_check
|
detail::relate::topology_check
|
||||||
<
|
<
|
||||||
MultiGeometry,
|
MultiGeometry, Strategy
|
||||||
typename Strategy::equals_point_point_strategy_type
|
|
||||||
> const& tc,
|
> const& tc,
|
||||||
Result & result,
|
Result & result,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef strategy::index::services::from_strategy
|
|
||||||
<
|
|
||||||
Strategy
|
|
||||||
> index_strategy_from;
|
|
||||||
typedef index::parameters
|
typedef index::parameters
|
||||||
<
|
<
|
||||||
index::rstar<4>, typename index_strategy_from::type
|
index::rstar<4>, Strategy
|
||||||
> index_parameters_type;
|
> index_parameters_type;
|
||||||
index::rtree<box_pair_type, index_parameters_type>
|
index::rtree<box_pair_type, index_parameters_type>
|
||||||
rtree(boxes.begin(), boxes.end(),
|
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;
|
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
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 model::box<point2_type> box2_type;
|
||||||
typedef std::pair<box2_type, std::size_t> box_pair_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::size_t count2 = boost::size(multi_geometry);
|
||||||
std::vector<box_pair_type> boxes(count2);
|
std::vector<box_pair_type> boxes(count2);
|
||||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
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);
|
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||||
boxes[i].second = i;
|
boxes[i].second = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef detail::relate::topology_check<MultiGeometry, eq_pp_strategy_type> tc_t;
|
typedef detail::relate::topology_check<MultiGeometry, Strategy> tc_t;
|
||||||
tc_t tc(multi_geometry);
|
tc_t tc(multi_geometry, strategy);
|
||||||
|
|
||||||
if ( relate::may_update<interior, interior, '0', Transpose>(result)
|
if ( relate::may_update<interior, interior, '0', Transpose>(result)
|
||||||
|| relate::may_update<interior, boundary, '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)
|
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
|
||||||
&& tc.has_boundary() )
|
&& tc.has_boundary() )
|
||||||
{
|
{
|
||||||
if (multi_point_geometry_eb
|
if (multi_point_geometry_eb<MultiGeometry>::apply(multi_point, tc))
|
||||||
<
|
|
||||||
MultiGeometry, eq_pp_strategy_type
|
|
||||||
>::apply(multi_point, tc))
|
|
||||||
{
|
{
|
||||||
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -60,11 +60,8 @@ struct point_geometry
|
|||||||
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef detail::relate::topology_check
|
typedef detail::relate::topology_check<Geometry, Strategy> tc_t;
|
||||||
<
|
|
||||||
Geometry,
|
|
||||||
typename Strategy::equals_point_point_strategy_type
|
|
||||||
> tc_t;
|
|
||||||
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|
||||||
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
|
||||||
{
|
{
|
||||||
@ -79,7 +76,7 @@ struct point_geometry
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// check if there is a boundary in Geometry
|
// check if there is a boundary in Geometry
|
||||||
tc_t tc(geometry);
|
tc_t tc(geometry, strategy);
|
||||||
if ( tc.has_interior() )
|
if ( tc.has_interior() )
|
||||||
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
relate::set<exterior, interior, tc_t::interior, Transpose>(result);
|
||||||
if ( tc.has_boundary() )
|
if ( tc.has_boundary() )
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
// 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
|
// 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"
|
// TODO: change the name for e.g. something with the word "exterior"
|
||||||
|
|
||||||
template <typename Geometry,
|
template
|
||||||
typename EqPPStrategy,
|
<
|
||||||
typename Tag = typename geometry::tag<Geometry>::type>
|
typename Geometry,
|
||||||
|
typename Strategy,
|
||||||
|
typename Tag = typename geometry::tag<Geometry>::type
|
||||||
|
>
|
||||||
struct topology_check
|
struct topology_check
|
||||||
: not_implemented<Tag>
|
: not_implemented<Tag>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
//template <typename Point>
|
//template <typename Point, typename Strategy>
|
||||||
//struct topology_check<Point, point_tag>
|
//struct topology_check<Point, Strategy, point_tag>
|
||||||
//{
|
//{
|
||||||
// static const char interior = '0';
|
// static const char interior = '0';
|
||||||
// static const char boundary = 'F';
|
// static const char boundary = 'F';
|
||||||
@ -49,14 +52,15 @@ struct topology_check
|
|||||||
// topology_check(Point const&, IgnoreBoundaryPoint const&) {}
|
// topology_check(Point const&, IgnoreBoundaryPoint const&) {}
|
||||||
//};
|
//};
|
||||||
|
|
||||||
template <typename Linestring, typename EqPPStrategy>
|
template <typename Linestring, typename Strategy>
|
||||||
struct topology_check<Linestring, EqPPStrategy, linestring_tag>
|
struct topology_check<Linestring, Strategy, linestring_tag>
|
||||||
{
|
{
|
||||||
static const char interior = '1';
|
static const char interior = '1';
|
||||||
static const char boundary = '0';
|
static const char boundary = '0';
|
||||||
|
|
||||||
topology_check(Linestring const& ls)
|
topology_check(Linestring const& ls, Strategy const& strategy)
|
||||||
: m_ls(ls)
|
: m_ls(ls)
|
||||||
|
, m_strategy(strategy)
|
||||||
, m_is_initialized(false)
|
, m_is_initialized(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -87,8 +91,8 @@ struct topology_check<Linestring, EqPPStrategy, linestring_tag>
|
|||||||
init();
|
init();
|
||||||
if (m_has_boundary)
|
if (m_has_boundary)
|
||||||
{
|
{
|
||||||
if (visitor.apply(range::front(m_ls)))
|
if (visitor.apply(range::front(m_ls), m_strategy))
|
||||||
visitor.apply(range::back(m_ls));
|
visitor.apply(range::back(m_ls), m_strategy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,26 +108,29 @@ private:
|
|||||||
m_has_boundary = count > 1
|
m_has_boundary = count > 1
|
||||||
&& ! detail::equals::equals_point_point(range::front(m_ls),
|
&& ! detail::equals::equals_point_point(range::front(m_ls),
|
||||||
range::back(m_ls),
|
range::back(m_ls),
|
||||||
EqPPStrategy());
|
m_strategy);
|
||||||
|
|
||||||
m_is_initialized = true;
|
m_is_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Linestring const& m_ls;
|
Linestring const& m_ls;
|
||||||
|
Strategy const& m_strategy;
|
||||||
|
|
||||||
mutable bool m_is_initialized;
|
mutable bool m_is_initialized;
|
||||||
|
|
||||||
mutable bool m_has_interior;
|
mutable bool m_has_interior;
|
||||||
mutable bool m_has_boundary;
|
mutable bool m_has_boundary;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MultiLinestring, typename EqPPStrategy>
|
template <typename MultiLinestring, typename Strategy>
|
||||||
struct topology_check<MultiLinestring, EqPPStrategy, multi_linestring_tag>
|
struct topology_check<MultiLinestring, Strategy, multi_linestring_tag>
|
||||||
{
|
{
|
||||||
static const char interior = '1';
|
static const char interior = '1';
|
||||||
static const char boundary = '0';
|
static const char boundary = '0';
|
||||||
|
|
||||||
topology_check(MultiLinestring const& mls)
|
topology_check(MultiLinestring const& mls, Strategy const& strategy)
|
||||||
: m_mls(mls)
|
: m_mls(mls)
|
||||||
|
, m_strategy(strategy)
|
||||||
, m_is_initialized(false)
|
, m_is_initialized(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -163,7 +170,7 @@ struct topology_check<MultiLinestring, EqPPStrategy, multi_linestring_tag>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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
|
void init() const
|
||||||
{
|
{
|
||||||
@ -198,7 +205,7 @@ private:
|
|||||||
point_reference back_pt = range::back(ls);
|
point_reference back_pt = range::back(ls);
|
||||||
|
|
||||||
// don't store boundaries of linear rings, this doesn't change anything
|
// 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
|
// do not add points containing NaN coordinates
|
||||||
// because they cannot be reasonably compared, e.g. with MSVC
|
// because they cannot be reasonably compared, e.g. with MSVC
|
||||||
@ -236,7 +243,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename It>
|
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;
|
interrupting_visitor visitor;
|
||||||
for_each_boundary_point(first, last, visitor);
|
for_each_boundary_point(first, last, visitor);
|
||||||
@ -248,7 +255,7 @@ private:
|
|||||||
bool found;
|
bool found;
|
||||||
interrupting_visitor() : found(false) {}
|
interrupting_visitor() : found(false) {}
|
||||||
template <typename Point>
|
template <typename Point>
|
||||||
bool apply(Point const&)
|
bool apply(Point const&, Strategy const&)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
return false;
|
return false;
|
||||||
@ -256,7 +263,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename It, typename Visitor>
|
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 )
|
if ( first == last )
|
||||||
return;
|
return;
|
||||||
@ -267,12 +274,12 @@ private:
|
|||||||
for ( ; first != last ; ++first, ++prev )
|
for ( ; first != last ; ++first, ++prev )
|
||||||
{
|
{
|
||||||
// the end of the equal points subrange
|
// 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
|
// odd count -> boundary
|
||||||
if ( count % 2 != 0 )
|
if ( count % 2 != 0 )
|
||||||
{
|
{
|
||||||
if (! visitor.apply(*prev))
|
if (! visitor.apply(*prev, m_strategy))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -289,12 +296,14 @@ private:
|
|||||||
// odd count -> boundary
|
// odd count -> boundary
|
||||||
if ( count % 2 != 0 )
|
if ( count % 2 != 0 )
|
||||||
{
|
{
|
||||||
visitor.apply(*prev);
|
visitor.apply(*prev, m_strategy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MultiLinestring const& m_mls;
|
MultiLinestring const& m_mls;
|
||||||
|
Strategy const& m_strategy;
|
||||||
|
|
||||||
mutable bool m_is_initialized;
|
mutable bool m_is_initialized;
|
||||||
|
|
||||||
mutable bool m_has_interior;
|
mutable bool m_has_interior;
|
||||||
@ -313,25 +322,25 @@ struct topology_check_areal
|
|||||||
static bool has_boundary() { return true; }
|
static bool has_boundary() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Ring, typename EqPPStrategy>
|
template <typename Ring, typename Strategy>
|
||||||
struct topology_check<Ring, EqPPStrategy, ring_tag>
|
struct topology_check<Ring, Strategy, ring_tag>
|
||||||
: topology_check_areal
|
: topology_check_areal
|
||||||
{
|
{
|
||||||
topology_check(Ring const&) {}
|
topology_check(Ring const&, Strategy const&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Polygon, typename EqPPStrategy>
|
template <typename Polygon, typename Strategy>
|
||||||
struct topology_check<Polygon, EqPPStrategy, polygon_tag>
|
struct topology_check<Polygon, Strategy, polygon_tag>
|
||||||
: topology_check_areal
|
: topology_check_areal
|
||||||
{
|
{
|
||||||
topology_check(Polygon const&) {}
|
topology_check(Polygon const&, Strategy const&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MultiPolygon, typename EqPPStrategy>
|
template <typename MultiPolygon, typename Strategy>
|
||||||
struct topology_check<MultiPolygon, EqPPStrategy, multi_polygon_tag>
|
struct topology_check<MultiPolygon, Strategy, multi_polygon_tag>
|
||||||
: topology_check_areal
|
: topology_check_areal
|
||||||
{
|
{
|
||||||
topology_check(MultiPolygon const&) {}
|
topology_check(MultiPolygon const&, Strategy const&) {}
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point>
|
||||||
static bool check_boundary_point(Point const& ) { return true; }
|
static bool check_boundary_point(Point const& ) { return true; }
|
||||||
|
@ -84,43 +84,28 @@ struct get_turns
|
|||||||
> type;
|
> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Turns>
|
template <typename Turns, typename InterruptPolicy, typename Strategy>
|
||||||
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>
|
|
||||||
static inline void apply(Turns & turns,
|
static inline void apply(Turns & turns,
|
||||||
Geometry1 const& geometry1,
|
Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
InterruptPolicy & interrupt_policy,
|
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
|
robust_policy_t robust_policy
|
||||||
= geometry::get_rescale_policy<robust_policy_t>(
|
= 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,
|
static inline void apply(Turns & turns,
|
||||||
Geometry1 const& geometry1,
|
Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
InterruptPolicy & interrupt_policy,
|
InterruptPolicy & interrupt_policy,
|
||||||
IntersectionStrategy const& intersection_strategy,
|
Strategy const& strategy,
|
||||||
RobustPolicy const& robust_policy)
|
RobustPolicy const& robust_policy)
|
||||||
{
|
{
|
||||||
static const bool reverse1 = detail::overlay::do_reverse
|
static const bool reverse1 = detail::overlay::do_reverse
|
||||||
@ -143,7 +128,7 @@ struct get_turns
|
|||||||
reverse2,
|
reverse2,
|
||||||
GetTurnPolicy
|
GetTurnPolicy
|
||||||
>::apply(0, geometry1, 1, geometry2,
|
>::apply(0, geometry1, 1, geometry2,
|
||||||
intersection_strategy, robust_policy,
|
strategy, robust_policy,
|
||||||
turns, interrupt_policy);
|
turns, interrupt_policy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -57,7 +57,10 @@ struct relation
|
|||||||
Matrix
|
Matrix
|
||||||
>::type handler;
|
>::type handler;
|
||||||
|
|
||||||
resolve_strategy::relate::apply(geometry1, geometry2, handler, strategy);
|
resolve_strategy::relate
|
||||||
|
<
|
||||||
|
Strategy
|
||||||
|
>::apply(geometry1, geometry2, handler, strategy);
|
||||||
|
|
||||||
return handler.result();
|
return handler.result();
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
|
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2018.
|
// This file was modified by Oracle on 2018-2020.
|
||||||
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
|
// Modifications copyright (c) 2018-2020, Oracle and/or its affiliates.
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
@ -26,28 +26,39 @@ namespace boost { namespace geometry
|
|||||||
namespace detail { namespace section
|
namespace detail { namespace section
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename ExpandBoxStrategy>
|
template <typename Strategy>
|
||||||
struct get_section_box
|
struct get_section_box
|
||||||
{
|
{
|
||||||
|
get_section_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Section>
|
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);
|
assert_coordinate_type_equal(total, section.bounding_box);
|
||||||
geometry::expand(total, section.bounding_box,
|
geometry::expand(total, section.bounding_box, m_strategy);
|
||||||
ExpandBoxStrategy());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Strategy const& m_strategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename DisjointBoxBoxStrategy>
|
template <typename Strategy>
|
||||||
struct overlaps_section_box
|
struct overlaps_section_box
|
||||||
{
|
{
|
||||||
|
overlaps_section_box(Strategy const& strategy)
|
||||||
|
: m_strategy(strategy)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename Box, typename Section>
|
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);
|
assert_coordinate_type_equal(box, section.bounding_box);
|
||||||
return ! detail::disjoint::disjoint_box_box(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/core/tags.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||||
|
#include <boost/geometry/geometries/box.hpp>
|
||||||
#include <boost/geometry/geometries/segment.hpp>
|
#include <boost/geometry/geometries/segment.hpp>
|
||||||
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
|
||||||
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
|
||||||
@ -336,9 +337,9 @@ struct assign_loop<T, Count, Count>
|
|||||||
template <typename CSTag>
|
template <typename CSTag>
|
||||||
struct box_first_in_section
|
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,
|
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::model::referring_segment<Point const> seg(prev, curr);
|
||||||
geometry::envelope(seg, box, strategy);
|
geometry::envelope(seg, box, strategy);
|
||||||
@ -348,12 +349,12 @@ struct box_first_in_section
|
|||||||
template <>
|
template <>
|
||||||
struct box_first_in_section<cartesian_tag>
|
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,
|
static inline void apply(Box & box, Point const& prev, Point const& curr,
|
||||||
ExpandStrategy const& )
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
geometry::envelope(prev, box);
|
geometry::envelope(prev, box, strategy);
|
||||||
geometry::expand(box, curr);
|
geometry::expand(box, curr, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -374,9 +375,9 @@ struct box_next_in_section<cartesian_tag>
|
|||||||
{
|
{
|
||||||
template <typename Box, typename Point, typename Strategy>
|
template <typename Box, typename Point, typename Strategy>
|
||||||
static inline void apply(Box & box, Point const& , Point const& curr,
|
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
|
static const std::size_t dimension_count
|
||||||
= util::sequence_size<DimensionVector>::value;
|
= 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
|
template
|
||||||
<
|
<
|
||||||
typename Iterator,
|
typename Iterator,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Sections,
|
typename Sections,
|
||||||
typename EnvelopeStrategy,
|
typename Strategy
|
||||||
typename ExpandStrategy
|
|
||||||
>
|
>
|
||||||
static inline void apply(Sections& sections,
|
static inline void apply(Sections& sections,
|
||||||
Iterator begin, Iterator end,
|
Iterator begin, Iterator end,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
EnvelopeStrategy const& envelope_strategy,
|
Strategy const& strategy,
|
||||||
ExpandStrategy const& expand_strategy,
|
|
||||||
ring_identifier ring_id,
|
ring_identifier ring_id,
|
||||||
std::size_t max_count)
|
std::size_t max_count)
|
||||||
{
|
{
|
||||||
@ -448,10 +416,10 @@ struct sectionalize_part
|
|||||||
);
|
);
|
||||||
|
|
||||||
typedef typename geometry::robust_point_type
|
typedef typename geometry::robust_point_type
|
||||||
<
|
<
|
||||||
Point,
|
Point,
|
||||||
RobustPolicy
|
RobustPolicy
|
||||||
>::type robust_point_type;
|
>::type robust_point_type;
|
||||||
|
|
||||||
std::size_t const count = std::distance(begin, end);
|
std::size_t const count = std::distance(begin, end);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
@ -552,14 +520,14 @@ struct sectionalize_part
|
|||||||
// In cartesian this is envelope of previous point expanded with current point
|
// In cartesian this is envelope of previous point expanded with current point
|
||||||
// in non-cartesian this is envelope of a segment
|
// in non-cartesian this is envelope of a segment
|
||||||
box_first_in_section<typename cs_tag<robust_point_type>::type>
|
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
|
else
|
||||||
{
|
{
|
||||||
// In cartesian this is expand with current point
|
// In cartesian this is expand with current point
|
||||||
// in non-cartesian this is expand with a segment
|
// in non-cartesian this is expand with a segment
|
||||||
box_next_in_section<typename cs_tag<robust_point_type>::type>
|
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;
|
section.end_index = index + 1;
|
||||||
@ -605,23 +573,21 @@ struct sectionalize_range
|
|||||||
typename Range,
|
typename Range,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Sections,
|
typename Sections,
|
||||||
typename EnvelopeStrategy,
|
typename Strategy
|
||||||
typename ExpandStrategy
|
|
||||||
>
|
>
|
||||||
static inline void apply(Range const& range,
|
static inline void apply(Range const& range,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Sections& sections,
|
Sections& sections,
|
||||||
EnvelopeStrategy const& envelope_strategy,
|
Strategy const& strategy,
|
||||||
ExpandStrategy const& expand_strategy,
|
|
||||||
ring_identifier ring_id,
|
ring_identifier ring_id,
|
||||||
std::size_t max_count)
|
std::size_t max_count)
|
||||||
{
|
{
|
||||||
typedef typename closeable_view<Range const, Closure>::type cview_type;
|
typedef typename closeable_view<Range const, Closure>::type cview_type;
|
||||||
typedef typename reversible_view
|
typedef typename reversible_view
|
||||||
<
|
<
|
||||||
cview_type const,
|
cview_type const,
|
||||||
Reverse ? iterate_reverse : iterate_forward
|
Reverse ? iterate_reverse : iterate_forward
|
||||||
>::type view_type;
|
>::type view_type;
|
||||||
|
|
||||||
cview_type cview(range);
|
cview_type cview(range);
|
||||||
view_type view(cview);
|
view_type view(cview);
|
||||||
@ -641,7 +607,7 @@ struct sectionalize_range
|
|||||||
|
|
||||||
sectionalize_part<Point, DimensionVector>::apply(sections,
|
sectionalize_part<Point, DimensionVector>::apply(sections,
|
||||||
boost::begin(view), boost::end(view),
|
boost::begin(view), boost::end(view),
|
||||||
robust_policy, envelope_strategy, expand_strategy,
|
robust_policy, strategy,
|
||||||
ring_id, max_count);
|
ring_id, max_count);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -658,27 +624,24 @@ struct sectionalize_polygon
|
|||||||
typename Polygon,
|
typename Polygon,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Sections,
|
typename Sections,
|
||||||
typename EnvelopeStrategy,
|
typename Strategy
|
||||||
typename ExpandStrategy
|
|
||||||
>
|
>
|
||||||
static inline void apply(Polygon const& poly,
|
static inline void apply(Polygon const& poly,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Sections& sections,
|
Sections& sections,
|
||||||
EnvelopeStrategy const& envelope_strategy,
|
Strategy const& strategy,
|
||||||
ExpandStrategy const& expand_strategy,
|
|
||||||
ring_identifier ring_id,
|
ring_identifier ring_id,
|
||||||
std::size_t max_count)
|
std::size_t max_count)
|
||||||
{
|
{
|
||||||
typedef typename point_type<Polygon>::type point_type;
|
typedef typename point_type<Polygon>::type point_type;
|
||||||
typedef sectionalize_range
|
typedef sectionalize_range
|
||||||
<
|
<
|
||||||
closure<Polygon>::value, Reverse,
|
closure<Polygon>::value, Reverse, point_type, DimensionVector
|
||||||
point_type, DimensionVector
|
> per_range;
|
||||||
> per_range;
|
|
||||||
|
|
||||||
ring_id.ring_index = -1;
|
ring_id.ring_index = -1;
|
||||||
per_range::apply(exterior_ring(poly), robust_policy, sections,
|
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++;
|
ring_id.ring_index++;
|
||||||
typename interior_return_type<Polygon const>::type
|
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)
|
it = boost::begin(rings); it != boost::end(rings); ++it, ++ring_id.ring_index)
|
||||||
{
|
{
|
||||||
per_range::apply(*it, robust_policy, sections,
|
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 Box,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Sections,
|
typename Sections,
|
||||||
typename EnvelopeStrategy,
|
typename Strategy
|
||||||
typename ExpandStrategy
|
|
||||||
>
|
>
|
||||||
static inline void apply(Box const& box,
|
static inline void apply(Box const& box,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Sections& sections,
|
Sections& sections,
|
||||||
EnvelopeStrategy const& envelope_strategy,
|
Strategy const& strategy,
|
||||||
ExpandStrategy const& expand_strategy,
|
|
||||||
ring_identifier const& ring_id, std::size_t max_count)
|
ring_identifier const& ring_id, std::size_t max_count)
|
||||||
{
|
{
|
||||||
typedef typename point_type<Box>::type point_type;
|
typedef typename point_type<Box>::type point_type;
|
||||||
@ -735,13 +696,10 @@ struct sectionalize_box
|
|||||||
// NOTE: Use cartesian envelope strategy in all coordinate systems
|
// NOTE: Use cartesian envelope strategy in all coordinate systems
|
||||||
// because edges of a box are not geodesic segments
|
// because edges of a box are not geodesic segments
|
||||||
sectionalize_range
|
sectionalize_range
|
||||||
<
|
<
|
||||||
closed, false,
|
closed, false, point_type, DimensionVector
|
||||||
point_type,
|
>::apply(points, robust_policy, sections,
|
||||||
DimensionVector
|
strategy, ring_id, max_count);
|
||||||
>::apply(points, robust_policy, sections,
|
|
||||||
envelope_strategy, expand_strategy,
|
|
||||||
ring_id, max_count);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -753,14 +711,12 @@ struct sectionalize_multi
|
|||||||
typename MultiGeometry,
|
typename MultiGeometry,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename Sections,
|
typename Sections,
|
||||||
typename EnvelopeStrategy,
|
typename Strategy
|
||||||
typename ExpandStrategy
|
|
||||||
>
|
>
|
||||||
static inline void apply(MultiGeometry const& multi,
|
static inline void apply(MultiGeometry const& multi,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Sections& sections,
|
Sections& sections,
|
||||||
EnvelopeStrategy const& envelope_strategy,
|
Strategy const& strategy,
|
||||||
ExpandStrategy const& expand_strategy,
|
|
||||||
ring_identifier ring_id,
|
ring_identifier ring_id,
|
||||||
std::size_t max_count)
|
std::size_t max_count)
|
||||||
{
|
{
|
||||||
@ -771,7 +727,7 @@ struct sectionalize_multi
|
|||||||
++it, ++ring_id.multi_index)
|
++it, ++ring_id.multi_index)
|
||||||
{
|
{
|
||||||
Policy::apply(*it, robust_policy, sections,
|
Policy::apply(*it, robust_policy, sections,
|
||||||
envelope_strategy, expand_strategy,
|
strategy,
|
||||||
ring_id, max_count);
|
ring_id, max_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -983,7 +939,7 @@ struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionVec
|
|||||||
\param geometry geometry to create sections from
|
\param geometry geometry to create sections from
|
||||||
\param robust_policy policy to handle robustness issues
|
\param robust_policy policy to handle robustness issues
|
||||||
\param sections structure with sections
|
\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 expand_strategy strategy for partitions
|
||||||
\param source_index index to assign to the ring_identifiers
|
\param source_index index to assign to the ring_identifiers
|
||||||
\param max_count maximal number of points per section
|
\param max_count maximal number of points per section
|
||||||
@ -997,19 +953,15 @@ template
|
|||||||
typename Geometry,
|
typename Geometry,
|
||||||
typename Sections,
|
typename Sections,
|
||||||
typename RobustPolicy,
|
typename RobustPolicy,
|
||||||
typename EnvelopeStrategy,
|
typename Strategy
|
||||||
typename ExpandStrategy
|
|
||||||
>
|
>
|
||||||
inline void sectionalize(Geometry const& geometry,
|
inline void sectionalize(Geometry const& geometry,
|
||||||
RobustPolicy const& robust_policy,
|
RobustPolicy const& robust_policy,
|
||||||
Sections& sections,
|
Sections& sections,
|
||||||
EnvelopeStrategy const& envelope_strategy,
|
Strategy const& strategy,
|
||||||
ExpandStrategy const& expand_strategy,
|
|
||||||
int source_index = 0,
|
int source_index = 0,
|
||||||
std::size_t max_count = 10)
|
std::size_t max_count = 10)
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT((! std::is_fundamental<EnvelopeStrategy>::value));
|
|
||||||
|
|
||||||
concepts::check<Geometry const>();
|
concepts::check<Geometry const>();
|
||||||
|
|
||||||
typedef typename boost::range_value<Sections>::type section_type;
|
typedef typename boost::range_value<Sections>::type section_type;
|
||||||
@ -1044,10 +996,10 @@ inline void sectionalize(Geometry const& geometry,
|
|||||||
Reverse,
|
Reverse,
|
||||||
DimensionVector
|
DimensionVector
|
||||||
>::apply(geometry, robust_policy, sections,
|
>::apply(geometry, robust_policy, sections,
|
||||||
envelope_strategy, expand_strategy,
|
strategy,
|
||||||
ring_id, max_count);
|
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,
|
int source_index = 0,
|
||||||
std::size_t max_count = 10)
|
std::size_t max_count = 10)
|
||||||
{
|
{
|
||||||
typedef typename strategy::envelope::services::default_strategy
|
typedef typename strategies::envelope::services::default_strategy
|
||||||
<
|
<
|
||||||
typename tag<Geometry>::type,
|
Geometry,
|
||||||
typename cs_tag<Geometry>::type
|
model::box<typename point_type<Geometry>::type>
|
||||||
>::type envelope_strategy_type;
|
>::type 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;
|
|
||||||
|
|
||||||
boost::geometry::sectionalize
|
boost::geometry::sectionalize
|
||||||
<
|
<
|
||||||
Reverse, DimensionVector
|
Reverse, DimensionVector
|
||||||
>(geometry, robust_policy, sections,
|
>(geometry, robust_policy, sections,
|
||||||
envelope_strategy_type(),
|
strategy_type(),
|
||||||
expand_strategy_type(),
|
|
||||||
source_index, max_count);
|
source_index, max_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,29 +212,24 @@ inline bool point_on_border_within(Geometry1 const& geometry1,
|
|||||||
&& geometry::within(pt, geometry2, strategy);
|
&& 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,
|
inline bool rings_containing(FirstGeometry const& geometry1,
|
||||||
SecondGeometry const& geometry2,
|
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 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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
struct areal_areal
|
struct areal_areal
|
||||||
{
|
{
|
||||||
template <typename IntersectionStrategy>
|
template <typename Strategy>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
IntersectionStrategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
typedef typename geometry::point_type<Geometry1>::type point_type;
|
typedef typename geometry::point_type<Geometry1>::type point_type;
|
||||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||||
@ -411,7 +406,7 @@ struct self_touches
|
|||||||
{
|
{
|
||||||
concepts::check<Geometry const>();
|
concepts::check<Geometry const>();
|
||||||
|
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry, Geometry
|
Geometry, Geometry
|
||||||
>::type strategy_type;
|
>::type strategy_type;
|
||||||
@ -419,18 +414,19 @@ struct self_touches
|
|||||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||||
|
|
||||||
typedef detail::overlay::get_turn_info
|
typedef detail::overlay::get_turn_info
|
||||||
<
|
<
|
||||||
detail::overlay::assign_null_policy
|
detail::overlay::assign_null_policy
|
||||||
> policy_type;
|
> policy_type;
|
||||||
|
|
||||||
std::deque<turn_info> turns;
|
std::deque<turn_info> turns;
|
||||||
detail::touches::areal_interrupt_policy policy;
|
detail::touches::areal_interrupt_policy policy;
|
||||||
strategy_type strategy;
|
strategy_type strategy;
|
||||||
// TODO: skip_adjacent should be set to false
|
// TODO: skip_adjacent should be set to false
|
||||||
detail::self_get_turn_points::get_turns
|
detail::self_get_turn_points::get_turns
|
||||||
<
|
<
|
||||||
false, policy_type
|
false, policy_type
|
||||||
>::apply(geometry, strategy, detail::no_rescale_policy(), turns, policy, 0, true);
|
>::apply(geometry, strategy, detail::no_rescale_policy(),
|
||||||
|
turns, policy, 0, true);
|
||||||
|
|
||||||
return policy.result();
|
return policy.result();
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||||
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017.
|
// This file was modified by Oracle on 2013-2021.
|
||||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
@ -35,7 +35,8 @@
|
|||||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -84,9 +85,14 @@ struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct touches
|
struct touches
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
@ -96,13 +102,35 @@ struct touches
|
|||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::apply(geometry1, geometry2, strategy);
|
>::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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
@ -129,7 +157,10 @@ struct touches
|
|||||||
concepts::check<Geometry1 const>();
|
concepts::check<Geometry1 const>();
|
||||||
concepts::check<Geometry2 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>
|
template <typename Strategy>
|
||||||
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
boost::ignore_unused(strategy);
|
return strategy.within(point, box).apply(point, box);
|
||||||
return strategy.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)
|
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
assert_dimension_equal<Box1, Box2>();
|
assert_dimension_equal<Box1, Box2>();
|
||||||
boost::ignore_unused(strategy);
|
return strategy.within(box1, box2).apply(box1, box2);
|
||||||
return strategy.apply(box1, box2);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||||
|
|
||||||
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
|
// This file was modified by Oracle on 2013-2021.
|
||||||
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
// 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/geometries/concepts/check.hpp>
|
||||||
#include <boost/geometry/strategies/concepts/within_concept.hpp>
|
#include <boost/geometry/strategies/concepts/within_concept.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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
|
namespace boost { namespace geometry
|
||||||
@ -63,30 +63,63 @@ struct within
|
|||||||
namespace resolve_strategy
|
namespace resolve_strategy
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct within
|
struct within
|
||||||
{
|
{
|
||||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
concepts::within::check<Geometry1, Geometry2, 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>
|
template <typename Geometry1, typename Geometry2>
|
||||||
static inline bool apply(Geometry1 const& geometry1,
|
static inline bool apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::within::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
>::type strategy_type;
|
>::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>();
|
concepts::check<Geometry2 const>();
|
||||||
assert_dimension_equal<Geometry1, Geometry2>();
|
assert_dimension_equal<Geometry1, Geometry2>();
|
||||||
|
|
||||||
return resolve_strategy::within::apply(geometry1,
|
return resolve_strategy::within
|
||||||
geometry2,
|
<
|
||||||
strategy);
|
Strategy
|
||||||
|
>::apply(geometry1, geometry2, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Boost.Geometry
|
// Boost.Geometry
|
||||||
|
|
||||||
// Copyright (c) 2017-2020, Oracle and/or its affiliates.
|
// Copyright (c) 2017-2020, Oracle and/or its affiliates.
|
||||||
|
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
@ -54,10 +53,12 @@ struct multi_point_point
|
|||||||
Point const& point,
|
Point const& point,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
|
auto const s = strategy.relate(multi_point, point);
|
||||||
|
|
||||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -126,11 +127,9 @@ struct multi_point_single_geometry
|
|||||||
|
|
||||||
// Create envelope of geometry
|
// Create envelope of geometry
|
||||||
box2_type box;
|
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);
|
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
|
// Test each Point with envelope and then geometry if needed
|
||||||
// If in the exterior, break
|
// If in the exterior, break
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@ -138,8 +137,10 @@ struct multi_point_single_geometry
|
|||||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
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
|
// exterior of box and of geometry
|
||||||
if (! point_in_box_type::apply(*it, box)
|
if (! point_in_box_type::apply(*it, box)
|
||||||
|| (in_val = point_in_geometry(*it, linear_or_areal, strategy)) < 0)
|
|| (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;
|
typedef model::box<point2_type> box2_type;
|
||||||
static const bool is_linear = util::is_linear<LinearOrAreal>::value;
|
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
|
// TODO: box pairs could be constructed on the fly, inside the rtree
|
||||||
|
|
||||||
// Prepare range of envelopes and ids
|
// Prepare range of envelopes and ids
|
||||||
@ -185,23 +183,16 @@ struct multi_point_multi_geometry
|
|||||||
box_pair_vector boxes(count2);
|
box_pair_vector boxes(count2);
|
||||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
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);
|
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||||
boxes[i].second = i;
|
boxes[i].second = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create R-tree
|
// Create R-tree
|
||||||
typedef strategy::index::services::from_strategy
|
typedef index::parameters<index::rstar<4>, Strategy> index_parameters_type;
|
||||||
<
|
|
||||||
Strategy
|
|
||||||
> index_strategy_from;
|
|
||||||
typedef index::parameters
|
|
||||||
<
|
|
||||||
index::rstar<4>, typename index_strategy_from::type
|
|
||||||
> index_parameters_type;
|
|
||||||
index::rtree<box_pair_type, index_parameters_type>
|
index::rtree<box_pair_type, index_parameters_type>
|
||||||
rtree(boxes.begin(), boxes.end(),
|
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
|
// For each point find overlapping envelopes and test corresponding single geometries
|
||||||
// If a point is in the exterior break
|
// If a point is in the exterior break
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
// This file was modified by Oracle on 2013-2020.
|
// This file was modified by Oracle on 2013-2020.
|
||||||
// Modifications copyright (c) 2013-2020, Oracle and/or its affiliates.
|
// 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 Adam Wulkiewicz, on behalf of Oracle
|
||||||
|
|
||||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
// 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/geometries/concepts/check.hpp>
|
||||||
#include <boost/geometry/strategies/concepts/within_concept.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/util/range.hpp>
|
||||||
#include <boost/geometry/views/detail/normalized_view.hpp>
|
#include <boost/geometry/views/detail/normalized_view.hpp>
|
||||||
@ -45,32 +42,13 @@ namespace boost { namespace geometry {
|
|||||||
#ifndef DOXYGEN_NO_DETAIL
|
#ifndef DOXYGEN_NO_DETAIL
|
||||||
namespace detail { namespace within {
|
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
|
template <typename Point, typename Range, typename Strategy> inline
|
||||||
int point_in_range(Point const& point, Range const& range, Strategy const& strategy)
|
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;
|
typedef typename boost::range_iterator<Range const>::type iterator_type;
|
||||||
typename Strategy::state_type state;
|
|
||||||
iterator_type it = boost::begin(range);
|
iterator_type it = boost::begin(range);
|
||||||
iterator_type end = boost::end(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));
|
return 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace detail::within
|
}} // namespace detail::within
|
||||||
@ -117,8 +84,8 @@ struct point_in_geometry<Point2, point_tag>
|
|||||||
template <typename Point1, typename Strategy> static inline
|
template <typename Point1, typename Strategy> static inline
|
||||||
int apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
|
int apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
boost::ignore_unused(strategy);
|
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||||
return strategy.apply(point1, point2) ? 1 : -1;
|
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
|
template <typename Point, typename Strategy> static inline
|
||||||
int apply(Point const& point, Segment const& segment, Strategy const& strategy)
|
int apply(Point const& point, Segment const& segment, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
boost::ignore_unused(strategy);
|
|
||||||
|
|
||||||
typedef typename geometry::point_type<Segment>::type point_type;
|
typedef typename geometry::point_type<Segment>::type point_type;
|
||||||
point_type p0, p1;
|
point_type p0, p1;
|
||||||
// TODO: don't copy points
|
// TODO: don't copy points
|
||||||
detail::assign_point_from_index<0>(segment, p0);
|
detail::assign_point_from_index<0>(segment, p0);
|
||||||
detail::assign_point_from_index<1>(segment, p1);
|
detail::assign_point_from_index<1>(segment, p1);
|
||||||
|
|
||||||
typename Strategy::state_type state;
|
auto const s = strategy.relate(point, segment);
|
||||||
strategy.apply(point, p0, p1, state);
|
typename decltype(s)::state_type state;
|
||||||
int r = detail::within::check_result_type(strategy.result(state));
|
s.apply(point, p0, p1, state);
|
||||||
|
int r = s.result(state);
|
||||||
|
|
||||||
if ( r != 0 )
|
if ( r != 0 )
|
||||||
return -1; // exterior
|
return -1; // exterior
|
||||||
|
|
||||||
// if the point is equal to the one of the terminal points
|
// if the point is equal to the one of the terminal points
|
||||||
if ( detail::within::equals_point_point(point, p0, strategy)
|
if ( detail::equals::equals_point_point(point, p0, strategy)
|
||||||
|| detail::within::equals_point_point(point, p1, strategy) )
|
|| detail::equals::equals_point_point(point, p1, strategy) )
|
||||||
return 0; // boundary
|
return 0; // boundary
|
||||||
else
|
else
|
||||||
return 1; // interior
|
return 1; // interior
|
||||||
@ -162,24 +128,37 @@ struct point_in_geometry<Linestring, linestring_tag>
|
|||||||
std::size_t count = boost::size(linestring);
|
std::size_t count = boost::size(linestring);
|
||||||
if ( count > 1 )
|
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
|
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 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
|
return 1; // interior
|
||||||
|
}
|
||||||
// else if the point is equal to the one of the terminal points
|
// 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)
|
else if ( detail::equals::equals_point_point(point, front, strategy)
|
||||||
|| detail::within::equals_point_point(point, range::back(linestring), strategy))
|
|| detail::equals::equals_point_point(point, back, strategy) )
|
||||||
|
{
|
||||||
return 0; // boundary
|
return 0; // boundary
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return 1; // interior
|
return 1; // interior
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: for now degenerated linestrings are ignored
|
// TODO: for now degenerated linestrings are ignored
|
||||||
// throw an exception here?
|
// throw an exception here?
|
||||||
/*else if ( count == 1 )
|
/*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;
|
return 1;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@ -202,7 +181,8 @@ struct point_in_geometry<Ring, ring_tag>
|
|||||||
}
|
}
|
||||||
|
|
||||||
detail::normalized_view<Ring const> view(ring);
|
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);
|
point_type const& back = range::back(*it);
|
||||||
|
|
||||||
// is closed_ring - no boundary
|
// is closed_ring - no boundary
|
||||||
if ( detail::within::equals_point_point(front, back, strategy) )
|
if ( detail::equals::equals_point_point(front, back, strategy) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// is point on boundary
|
// is point on boundary
|
||||||
if ( detail::within::equals_point_point(point, front, strategy)
|
if ( detail::equals::equals_point_point(point, front, strategy)
|
||||||
|| detail::within::equals_point_point(point, back, strategy) )
|
|| detail::equals::equals_point_point(point, back, strategy) )
|
||||||
{
|
{
|
||||||
++boundaries;
|
++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);
|
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>
|
template <typename Point, typename Geometry, typename Strategy>
|
||||||
inline bool within_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
inline bool within_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return point_in_geometry(point, geometry, strategy) > 0;
|
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>
|
template <typename Point, typename Geometry, typename Strategy>
|
||||||
inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
|
||||||
{
|
{
|
||||||
return point_in_geometry(point, geometry, strategy) >= 0;
|
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
|
}} // namespace detail::within
|
||||||
#endif // DOXYGEN_NO_DETAIL
|
#endif // DOXYGEN_NO_DETAIL
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
// 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.
|
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
|
||||||
|
|
||||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
// 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/algorithms/detail/overlay/intersection_insert.hpp>
|
||||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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/util/range.hpp>
|
||||||
|
|
||||||
|
|
||||||
@ -253,7 +255,7 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
|||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
OutputIterator out)
|
OutputIterator out)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
@ -270,15 +272,14 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
|
|||||||
|
|
||||||
namespace resolve_strategy {
|
namespace resolve_strategy {
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct difference
|
struct difference
|
||||||
{
|
{
|
||||||
template
|
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||||
<
|
|
||||||
typename Geometry1,
|
|
||||||
typename Geometry2,
|
|
||||||
typename Collection,
|
|
||||||
typename Strategy
|
|
||||||
>
|
|
||||||
static inline void apply(Geometry1 const& geometry1,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Collection & output_collection,
|
Collection & output_collection,
|
||||||
@ -294,25 +295,46 @@ struct difference
|
|||||||
geometry::detail::output_geometry_back_inserter(output_collection),
|
geometry::detail::output_geometry_back_inserter(output_collection),
|
||||||
strategy);
|
strategy);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template
|
template <typename Strategy>
|
||||||
<
|
struct difference<Strategy, false>
|
||||||
typename Geometry1,
|
{
|
||||||
typename Geometry2,
|
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||||
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,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Collection & output_collection,
|
Collection & output_collection,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
>::type strategy_type;
|
>::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,
|
Collection& output_collection,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
resolve_strategy::difference::apply(geometry1, geometry2,
|
resolve_strategy::difference
|
||||||
output_collection,
|
<
|
||||||
strategy);
|
Strategy
|
||||||
|
>::apply(geometry1, geometry2, output_collection, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
// 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.
|
// Modifications copyright (c) 2015-2020 Oracle and/or its affiliates.
|
||||||
|
|
||||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
// 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/geometries/multi_polygon.hpp>
|
||||||
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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>
|
#include <boost/geometry/util/range.hpp>
|
||||||
|
|
||||||
|
|
||||||
@ -497,9 +498,9 @@ template
|
|||||||
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2, OutputIterator out)
|
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;
|
>::type strategy_type;
|
||||||
|
|
||||||
return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, 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 {
|
namespace resolve_strategy {
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct sym_difference
|
struct sym_difference
|
||||||
{
|
{
|
||||||
template
|
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||||
<
|
|
||||||
typename Geometry1,
|
|
||||||
typename Geometry2,
|
|
||||||
typename Collection,
|
|
||||||
typename Strategy
|
|
||||||
>
|
|
||||||
static inline void apply(Geometry1 const& geometry1,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Collection & output_collection,
|
Collection & output_collection,
|
||||||
@ -535,13 +535,31 @@ struct sym_difference
|
|||||||
geometry::detail::output_geometry_back_inserter(output_collection),
|
geometry::detail::output_geometry_back_inserter(output_collection),
|
||||||
strategy);
|
strategy);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template
|
template <typename Strategy>
|
||||||
<
|
struct sym_difference<Strategy, false>
|
||||||
typename Geometry1,
|
{
|
||||||
typename Geometry2,
|
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||||
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,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Collection & output_collection,
|
Collection & output_collection,
|
||||||
@ -552,7 +570,10 @@ struct sym_difference
|
|||||||
Geometry1, Geometry2
|
Geometry1, Geometry2
|
||||||
>::type strategy_type;
|
>::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,
|
Collection& output_collection,
|
||||||
Strategy const& strategy)
|
Strategy const& strategy)
|
||||||
{
|
{
|
||||||
resolve_strategy::sym_difference::apply(geometry1, geometry2,
|
resolve_strategy::sym_difference
|
||||||
output_collection,
|
<
|
||||||
strategy);
|
Strategy
|
||||||
|
>::apply(geometry1, geometry2, output_collection, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,13 +18,15 @@
|
|||||||
|
|
||||||
#include <boost/range/value_type.hpp>
|
#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/point_order.hpp>
|
||||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||||
#include <boost/geometry/geometries/concepts/check.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/policies/robustness/get_rescale_policy.hpp>
|
||||||
#include <boost/geometry/strategies/default_strategy.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/util/range.hpp>
|
||||||
|
|
||||||
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>
|
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>
|
||||||
@ -349,9 +351,9 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
|
|||||||
concepts::check<Geometry2 const>();
|
concepts::check<Geometry2 const>();
|
||||||
geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
|
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;
|
>::type strategy;
|
||||||
|
|
||||||
typedef typename geometry::rescale_overlay_policy_type
|
typedef typename geometry::rescale_overlay_policy_type
|
||||||
@ -377,15 +379,14 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
|
|||||||
|
|
||||||
namespace resolve_strategy {
|
namespace resolve_strategy {
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
typename Strategy,
|
||||||
|
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||||
|
>
|
||||||
struct union_
|
struct union_
|
||||||
{
|
{
|
||||||
template
|
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||||
<
|
|
||||||
typename Geometry1,
|
|
||||||
typename Geometry2,
|
|
||||||
typename Collection,
|
|
||||||
typename Strategy
|
|
||||||
>
|
|
||||||
static inline void apply(Geometry1 const& geometry1,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Collection & output_collection,
|
Collection & output_collection,
|
||||||
@ -414,25 +415,46 @@ struct union_
|
|||||||
geometry::detail::output_geometry_back_inserter(output_collection),
|
geometry::detail::output_geometry_back_inserter(output_collection),
|
||||||
strategy);
|
strategy);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template
|
template <typename Strategy>
|
||||||
<
|
struct union_<Strategy, false>
|
||||||
typename Geometry1,
|
{
|
||||||
typename Geometry2,
|
template <typename Geometry1, typename Geometry2, typename Collection>
|
||||||
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,
|
static inline void apply(Geometry1 const& geometry1,
|
||||||
Geometry2 const& geometry2,
|
Geometry2 const& geometry2,
|
||||||
Collection & output_collection,
|
Collection & output_collection,
|
||||||
default_strategy)
|
default_strategy)
|
||||||
{
|
{
|
||||||
typedef typename strategy::relate::services::default_strategy
|
typedef typename strategies::relate::services::default_strategy
|
||||||
<
|
<
|
||||||
Geometry1,
|
Geometry1,
|
||||||
Geometry2
|
Geometry2
|
||||||
>::type strategy_type;
|
>::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
|
>::type
|
||||||
>::apply();
|
>::apply();
|
||||||
|
|
||||||
resolve_strategy::union_::apply(geometry1, geometry2,
|
resolve_strategy::union_
|
||||||
output_collection,
|
<
|
||||||
strategy);
|
Strategy
|
||||||
|
>::apply(geometry1, geometry2, output_collection, strategy);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ struct dissolver_generic
|
|||||||
|
|
||||||
// There are less then 16 elements, handle them quadraticly
|
// 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);
|
for(iterator_type it1 = boost::begin(index_vector);
|
||||||
it1 != boost::end(index_vector);
|
it1 != boost::end(index_vector);
|
||||||
@ -520,7 +520,7 @@ struct dissolver_generic
|
|||||||
boost::end(output_collection)),
|
boost::end(output_collection)),
|
||||||
helper_vector,
|
helper_vector,
|
||||||
strategy,
|
strategy,
|
||||||
n, 1);
|
static_cast<int>(n), 1);
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
@ -577,8 +577,8 @@ struct dissolver_generic
|
|||||||
|
|
||||||
std::vector<output_type> unioned_collection;
|
std::vector<output_type> unioned_collection;
|
||||||
|
|
||||||
int size = 0, previous_size = 0;
|
std::size_t size = 0, previous_size = 0;
|
||||||
int n = 0;
|
std::size_t n = 0;
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
while(divide_and_conquer<1>
|
while(divide_and_conquer<1>
|
||||||
|
@ -418,6 +418,72 @@ struct dissolve<Polygon, PolygonOut, Reverse, polygon_tag, polygon_tag>
|
|||||||
#endif // DOXYGEN_NO_DISPATCH
|
#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
|
\brief Removes self intersections from a geometry
|
||||||
@ -449,9 +515,10 @@ inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
|||||||
concepts::check<GeometryOut>();
|
concepts::check<GeometryOut>();
|
||||||
|
|
||||||
typedef typename geometry::rescale_policy_type
|
typedef typename geometry::rescale_policy_type
|
||||||
<
|
<
|
||||||
typename geometry::point_type<Geometry>::type
|
typename geometry::point_type<Geometry>::type,
|
||||||
>::type rescale_policy_type;
|
typename Strategy::cs_tag
|
||||||
|
>::type rescale_policy_type;
|
||||||
|
|
||||||
rescale_policy_type robust_policy
|
rescale_policy_type robust_policy
|
||||||
= geometry::get_rescale_policy<rescale_policy_type>(
|
= geometry::get_rescale_policy<rescale_policy_type>(
|
||||||
@ -459,15 +526,10 @@ inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
|||||||
|
|
||||||
detail::overlay::overlay_null_visitor visitor;
|
detail::overlay::overlay_null_visitor visitor;
|
||||||
|
|
||||||
return dispatch::dissolve
|
return resolve_strategy::dissolve
|
||||||
<
|
|
||||||
Geometry,
|
|
||||||
GeometryOut,
|
|
||||||
detail::overlay::do_reverse
|
|
||||||
<
|
<
|
||||||
geometry::point_order<Geometry>::value
|
GeometryOut, Strategy
|
||||||
>::value
|
>::apply(geometry, robust_policy, out, strategy, visitor);
|
||||||
>::apply(geometry, robust_policy, out, strategy, visitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -492,9 +554,9 @@ template
|
|||||||
inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
inline OutputIterator dissolve_inserter(Geometry const& geometry,
|
||||||
OutputIterator out)
|
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;
|
>::type strategy_type;
|
||||||
|
|
||||||
return dissolve_inserter<GeometryOut>(geometry, out, 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>();
|
concepts::check<geometry_out>();
|
||||||
|
|
||||||
typedef typename geometry::rescale_policy_type
|
typedef typename geometry::rescale_policy_type
|
||||||
<
|
<
|
||||||
typename geometry::point_type<Geometry>::type
|
typename geometry::point_type<Geometry>::type,
|
||||||
>::type rescale_policy_type;
|
typename Strategy::cs_tag
|
||||||
|
>::type rescale_policy_type;
|
||||||
|
|
||||||
rescale_policy_type robust_policy
|
rescale_policy_type robust_policy
|
||||||
= geometry::get_rescale_policy<rescale_policy_type>(
|
= 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;
|
detail::overlay::overlay_null_visitor visitor;
|
||||||
|
|
||||||
dispatch::dissolve
|
return resolve_strategy::dissolve
|
||||||
<
|
|
||||||
Geometry,
|
|
||||||
geometry_out,
|
|
||||||
detail::overlay::do_reverse
|
|
||||||
<
|
<
|
||||||
geometry::point_order<Geometry>::value
|
geometry_out, Strategy
|
||||||
>::value
|
>::apply(geometry, robust_policy,
|
||||||
>::apply(geometry, robust_policy,
|
std::back_inserter(output_collection),
|
||||||
std::back_inserter(output_collection),
|
strategy, visitor);
|
||||||
strategy, visitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template
|
template
|
||||||
@ -547,9 +605,9 @@ template
|
|||||||
>
|
>
|
||||||
inline void dissolve(Geometry const& geometry, Collection& output_collection)
|
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;
|
>::type strategy_type;
|
||||||
|
|
||||||
dissolve(geometry, output_collection, 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