Merge branch 'develop' into feature/setops_output

This commit is contained in:
Adam Wulkiewicz 2020-03-24 14:38:46 +01:00
commit 2b74e42436
206 changed files with 3681 additions and 2117 deletions

2
.gitattributes vendored
View File

@ -79,7 +79,7 @@ COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain

104
.github/workflows/documentation.yml vendored Normal file
View File

@ -0,0 +1,104 @@
##############################################################################
# GitHub Actions Workflow for Boost.Geometry to build documentation
#
# Copyright (c) 2020 Mateusz Loskot <mateusz@loskot.net>
#
# 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)
##############################################################################
name: documentation
on:
push:
branches:
- develop
- master
pull_request:
paths:
- '.github/workflows/documentation.yml'
- 'doc/**'
- 'index.html'
- 'Jamfile*'
- 'meta/libraries.json'
jobs:
build:
name: Build documentation
runs-on: ubuntu-latest
steps:
- name: Set up environment
id: setenv
run: |
if [[ "$GITHUB_REF" == *master ]]; then
echo "::set-env name=BOOST_BRANCH::master"
else
echo "::set-env name=BOOST_BRANCH::develop"
fi
echo "::set-env name=BOOST_SELF::$(basename $GITHUB_WORKSPACE)"
echo "::set-env name=BOOST_ROOT::$GITHUB_WORKSPACE/boost-root"
echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)"
echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root"
- name: Clone boostorg/boost
run: |
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git $BOOST_ROOT
cd $BOOST_ROOT
git submodule update -q --init libs/headers
git submodule update -q --init tools/boost_install
git submodule update -q --init tools/boostbook
git submodule update -q --init tools/boostdep
git submodule update -q --init tools/build
git submodule update -q --init tools/quickbook
mkdir -p libs/$BOOST_SELF
- uses: actions/checkout@v2
with:
path: ${{ steps.setenv.outputs.boost_root }}/libs/${{ steps.setenv.outputs.boost_self }}
- name: Run tools/boostdep/depinst/depinst.py
run: |
cd $BOOST_ROOT
python tools/boostdep/depinst/depinst.py ../tools/quickbook
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools $BOOST_SELF
- name: Bootstrap boostorg/boost
run: |
gcc --version
cd $BOOST_ROOT
./bootstrap.sh --with-toolset=gcc
./b2 headers
test -f /usr/local/bin/b2 && rm -rf /usr/local/bin/b2
test -f /usr/local/bin/bjam && rm -rf /usr/local/bin/bjam
sudo cp $BOOST_ROOT/b2 /usr/local/bin/
ls -l /usr/local/bin/b2
b2 -v
- name: Install tools/quickbook
run: |
sudo apt-get -q -y --no-install-suggests --no-install-recommends install docbook-xml docbook-xsl doxygen xsltproc
echo "# $HOME/user-config.jam" > $HOME/user-config.jam
echo "using doxygen ;" >> $HOME/user-config.jam
echo -e "using boostbook\n : /usr/share/xml/docbook/stylesheet/nwalsh\n : /usr/share/xml/docbook/schema/dtd/4.2\n ;" >> $HOME/user-config.jam
echo "using xsltproc ;" >> $HOME/user-config.jam
test -f $HOME/user-config.jam && cat $HOME/user-config.jam
- name: Install libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk
run: |
cd $BOOST_ROOT
$BOOST_ROOT/b2 variant=release libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk
test -f /usr/local/bin/doxygen_xml2qbk && rm -rf /usr/local/bin/doxygen_xml2qbk
sudo cp $BOOST_ROOT/dist/bin/doxygen_xml2qbk /usr/local/bin/
ls -l /usr/local/bin/b2
doxygen_xml2qbk --version
- name: Build libs/geometry/doc/src/examples
run: |
cd $BOOST_ROOT
$BOOST_ROOT/b2 libs/geometry/doc/src/examples
- name: Run libs/geometry/doc/make_qbk.py
run: |
cd $BOOST_ROOT
cd libs/geometry/doc
python ./make_qbk.py

122
.github/workflows/minimal-clang.yml vendored Normal file
View File

@ -0,0 +1,122 @@
##############################################################################
# GitHub Actions Workflow for Boost.Geometry to build minimal tests with Clang
#
# Copyright (c) 2020 Mateusz Loskot <mateusz@loskot.net>
#
# 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)
##############################################################################
name: clang-test-minimal
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.b2_toolset }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
b2_toolset: [
clang-3.9,
clang-4.0,
clang-5.0,
clang-6.0,
clang-7,
clang-8,
clang-9,
clang-10
]
include:
- b2_toolset: clang-3.9
b2_cxxstd: 03,11
version: "3.9"
- b2_toolset: clang-4.0
b2_cxxstd: 03,11
version: "4.0"
- b2_toolset: clang-5.0
b2_cxxstd: 03,11,14
version: "5.0"
- b2_toolset: clang-6.0
b2_cxxstd: 03,11,14
version: "6.0"
- b2_toolset: clang-7
b2_cxxstd: 03,11,14,17
version: "7"
- b2_toolset: clang-8
b2_cxxstd: 03,11,14,17
version: "8"
- b2_toolset: clang-9
b2_cxxstd: 03,11,14,17,2a
version: "9"
- b2_toolset: clang-10
b2_cxxstd: 03,11,14,17,2a
version: "10"
steps:
- name: Set up environment
id: setenv
run: |
if [[ "$GITHUB_REF" == *master ]]; then
echo "::set-env name=BOOST_BRANCH::master"
else
echo "::set-env name=BOOST_BRANCH::develop"
fi
echo "::set-env name=BOOST_SELF::$(basename $GITHUB_WORKSPACE)"
echo "::set-env name=BOOST_ROOT::$GITHUB_WORKSPACE/boost-root"
echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)"
echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root"
- name: Clone boostorg/boost
run: |
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git $BOOST_ROOT
cd $BOOST_ROOT
git submodule update -q --init libs/headers
git submodule update -q --init tools/boost_install
git submodule update -q --init tools/boostdep
git submodule update -q --init tools/build
mkdir -p libs/$BOOST_SELF
- uses: actions/checkout@v2
with:
path: ${{ steps.setenv.outputs.boost_root }}/libs/${{ steps.setenv.outputs.boost_self }}
- name: Run tools/boostdep/depinst/depinst.py
run: |
cd $BOOST_ROOT
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools $BOOST_SELF
- name: Install
run: |
sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main"
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt -q -y update
sudo apt -q -y install clang-${{ matrix.version }} g++-multilib
- name: Bootstrap boostorg/boost
run: |
gcc --version
cd $BOOST_ROOT
./bootstrap.sh --with-toolset=gcc
./b2 headers
test -f /usr/local/bin/b2 && rm -rf /usr/local/bin/b2
test -f /usr/local/bin/bjam && rm -rf /usr/local/bin/bjam
sudo cp $BOOST_ROOT/b2 /usr/local/bin/
ls -l /usr/local/bin/b2
b2 -v
- name: Set up clang toolset in ~/user-config.jam
run: |
export CXX_NAME=clang++-${{ matrix.version }}
echo ${CXX_NAME}
echo "# $HOME/user-config.jam" > $HOME/user-config.jam
echo "using clang : : $(which clang++-${{ matrix.version }}) ;" > ${HOME}/user-config.jam
test -f $HOME/user-config.jam && cat $HOME/user-config.jam
- name: Build libs/geometry/test//minimal
run: |
cd $BOOST_ROOT
$BOOST_ROOT/b2 toolset=clang cxxstd=${{ matrix.b2_cxxstd }} variant=debug,release address-model=32,64 libs/geometry/test//minimal

112
.github/workflows/minimal-gcc.yml vendored Normal file
View File

@ -0,0 +1,112 @@
##############################################################################
# GitHub Actions Workflow for Boost.Geometry to build minimal tests with GCC
#
# Copyright (c) 2020 Mateusz Loskot <mateusz@loskot.net>
#
# 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)
##############################################################################
name: gcc-test-minimal
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.b2_toolset }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
b2_toolset: [
gcc-4.8,
gcc-4.9,
gcc-5,
gcc-6,
gcc-7,
gcc-8,
gcc-9
]
include:
- b2_toolset: gcc-4.8
b2_cxxstd: 03,11
version: "4.8"
- b2_toolset: gcc-4.9
b2_cxxstd: 03,11
version: "4.9"
- b2_toolset: gcc-5
b2_cxxstd: 03,11,14
version: "5"
- b2_toolset: gcc-6
b2_cxxstd: 03,11,14
version: "6"
- b2_toolset: gcc-7
b2_cxxstd: 03,11,14,17
version: "7"
- b2_toolset: gcc-8
b2_cxxstd: 03,11,14,17
version: "8"
- b2_toolset: gcc-9
b2_cxxstd: 03,11,14,17,2a
version: "9"
steps:
- name: Set up environment
id: setenv
run: |
if [[ "$GITHUB_REF" == *master ]]; then
echo "::set-env name=BOOST_BRANCH::master"
else
echo "::set-env name=BOOST_BRANCH::develop"
fi
echo "::set-env name=BOOST_SELF::$(basename $GITHUB_WORKSPACE)"
echo "::set-env name=BOOST_ROOT::$GITHUB_WORKSPACE/boost-root"
echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)"
echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root"
- name: Clone boostorg/boost
run: |
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git $BOOST_ROOT
cd $BOOST_ROOT
git submodule update -q --init libs/headers
git submodule update -q --init tools/boost_install
git submodule update -q --init tools/boostdep
git submodule update -q --init tools/build
mkdir -p libs/$BOOST_SELF
- uses: actions/checkout@v2
with:
path: ${{ steps.setenv.outputs.boost_root }}/libs/${{ steps.setenv.outputs.boost_self }}
- name: Run tools/boostdep/depinst/depinst.py
run: |
cd $BOOST_ROOT
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools $BOOST_SELF
- name: Install
run: |
# gcc-4.8 is not available in Bionic anymore
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 -y ppa:ubuntu-toolchain-r/test
sudo apt -q -y update
sudo apt -q -y install g++-${{ matrix.version }} g++-${{ matrix.version }}-multilib
- name: Bootstrap boostorg/boost
run: |
gcc --version
cd $BOOST_ROOT
./bootstrap.sh --with-toolset=gcc
./b2 headers
test -f /usr/local/bin/b2 && rm -rf /usr/local/bin/b2
test -f /usr/local/bin/bjam && rm -rf /usr/local/bin/bjam
sudo cp $BOOST_ROOT/b2 /usr/local/bin/
ls -l /usr/local/bin/b2
b2 -v
- name: Build libs/geometry/test//minimal
run: |
cd $BOOST_ROOT
$BOOST_ROOT/b2 toolset=${{ matrix.b2_toolset }} cxxstd=${{ matrix.b2_cxxstd }} variant=debug,release address-model=32,64 libs/geometry/test//minimal

80
.github/workflows/minimal-msvc.yml vendored Normal file
View File

@ -0,0 +1,80 @@
##############################################################################
# GitHub Actions Workflow for Boost.Geometry to build minimal tests with MSVC
#
# Copyright (c) 2020 Mateusz Loskot <mateusz@loskot.net>
#
# 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)
##############################################################################
name: msvc-test-minimal
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.b2_toolset }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
# TODO: Waiting for msvc-14.0, msvc-14.1
# https://github.com/actions/virtual-environments/issues/68#issuecomment-596817066
b2_toolset: [
msvc-14.2
]
include:
- b2_toolset: msvc-14.2
b2_cxxstd: 14,17,2a
steps:
- name: Set up environment
id: setenv
shell: pwsh
run: |
if ("$GITHUB_REF" -contains "master") {
echo "::set-env name=BOOST_BRANCH::master"
} else {
echo "::set-env name=BOOST_BRANCH::develop"
}
echo "::set-env name=BOOST_SELF::$((Get-Item $env:GITHUB_WORKSPACE).BaseName)"
echo "::set-env name=BOOST_ROOT::$env:GITHUB_WORKSPACE\boost-root"
echo "::set-output name=boost_self::$((Get-Item $env:GITHUB_WORKSPACE).BaseName)"
echo "::set-output name=boost_root::$env:GITHUB_WORKSPACE\boost-root"
- name: Clone boostorg/boost
shell: pwsh
run: |
git clone -b $env:BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git $env:BOOST_ROOT
cd $env:BOOST_ROOT
git submodule update -q --init libs/headers
git submodule update -q --init tools/boost_install
git submodule update -q --init tools/boostdep
git submodule update -q --init tools/build
New-Item -Path libs\$env:BOOST_SELF -ItemType Directory -ErrorAction SilentlyContinue
- uses: actions/checkout@v2
with:
path: ${{ steps.setenv.outputs.boost_root }}/libs/${{ steps.setenv.outputs.boost_self }}
- name: Run tools/boostdep/depinst/depinst.py
shell: pwsh
run: |
cd $env:BOOST_ROOT
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools $env:BOOST_SELF
- name: Bootstrap boostorg/boost
shell: pwsh
run: |
cd $env:BOOST_ROOT
.\bootstrap.bat --with-toolset=msvc
.\b2 headers
.\b2 -v
- name: Build libs/geometry/test//minimal
shell: pwsh
run: |
cd $env:BOOST_ROOT
.\b2 toolset=${{ matrix.b2_toolset }} cxxstd=${{ matrix.b2_cxxstd }} variant=debug,release address-model=32,64 libs/geometry/test//minimal

View File

View File

@ -10,10 +10,10 @@ Boost.Geometry, part of collection of the [Boost C++ Libraries](http://github.co
### Test results
@ | Build | Coverage | Regression
------------|---------------|----------------|------------
**master** | [![status](https://circleci.com/gh/boostorg/geometry/tree/master.svg?style=shield)](https://circleci.com/gh/boostorg/geometry/tree/master) | [![status](https://coveralls.io/repos/github/boostorg/geometry/badge.svg?branch=master)](https://coveralls.io/github/boostorg/geometry?branch=master) | [![geometry](https://img.shields.io/badge/-geometry-4480cc.png)](http://www.boost.org/development/tests/master/developer/geometry.html) [![index](https://img.shields.io/badge/-index-4480cc.png)](http://www.boost.org/development/tests/master/developer/geometry-index.html)
**develop** | [![status](https://circleci.com/gh/boostorg/geometry/tree/develop.svg?style=shield)](https://circleci.com/gh/boostorg/geometry/tree/develop) | [![status](https://coveralls.io/repos/github/boostorg/geometry/badge.svg?branch=develop)](https://coveralls.io/github/boostorg/geometry?branch=develop) | [![geometry](https://img.shields.io/badge/-geometry-4480cc.png)](http://www.boost.org/development/tests/develop/developer/geometry.html) [![index](https://img.shields.io/badge/-index-4480cc.png)](http://www.boost.org/development/tests/develop/developer/geometry-index.html) [![extensions](https://img.shields.io/badge/-extensions-4480cc.png)](http://www.boost.org/development/tests/develop/developer/geometry-extensions.html)
Branch | Build | Coverage | Regression | Documentation
------------|---------------|----------------|------------|--------------
**develop** | [![status](https://circleci.com/gh/boostorg/geometry/tree/develop.svg?style=shield)](https://circleci.com/gh/boostorg/geometry/tree/develop) <br> [![status](https://github.com/boostorg/geometry/workflows/clang-test-minimal/badge.svg?branch=develop)](https://github.com/boostorg/geometry/actions?query=branch:develop+workflow:clang-test-minimal) <br> [![status](https://github.com/boostorg/geometry/workflows/gcc-test-minimal/badge.svg?branch=develop)](https://github.com/boostorg/geometry/actions?query=branch:develop+workflow:gcc-test-minimal) <br> [![status](https://github.com/boostorg/geometry/workflows/msvc-test-minimal/badge.svg?branch=develop)](https://github.com/boostorg/geometry/actions?query=branch:develop+workflow:msvc-test-minimal) | [![status](https://coveralls.io/repos/github/boostorg/geometry/badge.svg?branch=develop)](https://coveralls.io/github/boostorg/geometry?branch=develop) | [![geometry](https://img.shields.io/badge/-geometry-4480cc.png)](http://www.boost.org/development/tests/develop/developer/geometry.html) [![index](https://img.shields.io/badge/-index-4480cc.png)](http://www.boost.org/development/tests/develop/developer/geometry-index.html) [![extensions](https://img.shields.io/badge/-extensions-4480cc.png)](http://www.boost.org/development/tests/develop/developer/geometry-extensions.html) | [![](https://github.com/boostorg/geometry/workflows/documentation/badge.svg?branch=develop)](https://github.com/boostorg/geometry/actions?query=branch:develop+workflow:documentation)
**master** | [![status](https://circleci.com/gh/boostorg/geometry/tree/master.svg?style=shield)](https://circleci.com/gh/boostorg/geometry/tree/master) <br> [![status](https://github.com/boostorg/geometry/workflows/clang-test-minimal/badge.svg?branch=master)](https://github.com/boostorg/geometry/actions?query=branch:master+workflow:clang-test-minimal) <br> [![status](https://github.com/boostorg/geometry/workflows/gcc-test-minimal/badge.svg?branch=master)](https://github.com/boostorg/geometry/actions?query=branch:master+workflow:gcc-test-minimal) <br> [![status](https://github.com/boostorg/geometry/workflows/msvc-test-minimal/badge.svg?branch=master)](https://github.com/boostorg/geometry/actions?query=branch:master+workflow:msvc-test-minimal) | [![status](https://coveralls.io/repos/github/boostorg/geometry/badge.svg?branch=master)](https://coveralls.io/github/boostorg/geometry?branch=master) | [![geometry](https://img.shields.io/badge/-geometry-4480cc.png)](http://www.boost.org/development/tests/master/developer/geometry.html) [![index](https://img.shields.io/badge/-index-4480cc.png)](http://www.boost.org/development/tests/master/developer/geometry-index.html) | [![](https://github.com/boostorg/geometry/workflows/documentation/badge.svg?branch=master)](https://github.com/boostorg/geometry/actions?query=branch:master+workflow:documentation)
### Directories

View File

@ -31,7 +31,7 @@ explicit make_qbk ;
boostbook geometry
: geometry.qbk
: <dependency>Jamfile.v2
: <dependency>Jamfile
<dependency>quickref.xml
# <dependency>generated/point.qbk
<xsl:param>chunk.section.depth=4

View File

@ -83,7 +83,7 @@ compilers:
__boost_geometry__ uses __boost_bb__, a text-based system for developing and
testing software, to configure, build and execute unit tests and example
programs. The build configuration is provided as a collection of `Jamfile.v2`
programs. The build configuration is provided as a collection of `Jamfile`
files.
For gcc, flag [^-Wno-long-long] can be used to surpress some warnings

View File

@ -314,9 +314,9 @@ EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = BOOST_CONCEPT_REQUIRES(x)= \
BOOST_CONCEPT_ASSERT(x) = \
BOOST_STATIC_ASSERT(x) = \
PREDEFINED = BOOST_CONCEPT_REQUIRES(x) \
BOOST_CONCEPT_ASSERT(x) \
BOOST_STATIC_ASSERT(x) \
DOXYGEN_SHOULD_SKIP_THIS \
DOXYGEN_NO_DISPATCH \
DOXYGEN_NO_IMPL \

2
doc/doxy/doxygen_output/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
html_by_doxygen/
xml/

1
doc/generated/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.qbk

2
doc/html/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
geometry/
geometry_HTML.manifest

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -31,12 +31,15 @@
[import src/examples/algorithms/convert.cpp]
[import src/examples/algorithms/convex_hull.cpp]
[import src/examples/algorithms/correct.cpp]
[import src/examples/algorithms/covered_by.cpp]
[import src/examples/algorithms/crosses.cpp]
[import src/examples/algorithms/densify.cpp]
[import src/examples/algorithms/densify_strategy.cpp]
[import src/examples/algorithms/discrete_frechet_distance.cpp]
[import src/examples/algorithms/discrete_frechet_distance_strategy.cpp]
[import src/examples/algorithms/discrete_hausdorff_distance.cpp]
[import src/examples/algorithms/discrete_hausdorff_distance_strategy.cpp]
[import src/examples/algorithms/disjoint.cpp]
[import src/examples/algorithms/distance.cpp]
[import src/examples/algorithms/difference.cpp]
[import src/examples/algorithms/envelope.cpp]
@ -66,18 +69,25 @@
[import src/examples/algorithms/num_interior_rings.cpp]
[import src/examples/algorithms/num_points.cpp]
[import src/examples/algorithms/num_segments.cpp]
[import src/examples/algorithms/overlaps.cpp]
[import src/examples/algorithms/perimeter.cpp]
[import src/examples/algorithms/relate.cpp]
[import src/examples/algorithms/relation.cpp]
[import src/examples/algorithms/reverse.cpp]
[import src/examples/algorithms/return_envelope.cpp]
[import src/examples/algorithms/simplify.cpp]
[import src/examples/algorithms/sym_difference.cpp]
[import src/examples/algorithms/touches_one_geometry.cpp]
[import src/examples/algorithms/touches_two_geometries.cpp]
[import src/examples/algorithms/transform.cpp]
[import src/examples/algorithms/transform_with_strategy.cpp]
[import src/examples/algorithms/union.cpp]
[import src/examples/algorithms/unique.cpp]
[import src/examples/algorithms/within.cpp]
[import src/examples/arithmetic/cross_product.cpp]
[import src/examples/arithmetic/dot_product.cpp]
[import src/examples/core/coordinate_type.cpp]
[import src/examples/core/coordinate_system.cpp]
[import src/examples/core/coordinate_dimension.cpp]
@ -103,6 +113,7 @@
[import src/examples/geometries/multi_point.cpp]
[import src/examples/geometries/multi_polygon.cpp]
[import src/examples/geometries/point_xy.cpp]
[import src/examples/geometries/point_xyz.cpp]
[import src/examples/geometries/point.cpp]
[import src/examples/geometries/polygon.cpp]
[import src/examples/geometries/ring.cpp]

2
doc/index/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
html_by_doxygen/
xml/

View File

@ -15,7 +15,7 @@ boostbook geometry_index-doc
:
index.qbk
:
<dependency>Jamfile.v2
<dependency>Jamfile
<dependency>generated/rtree.qbk
<format>html

1
doc/index/generated/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.qbk

View File

@ -106,6 +106,8 @@ algorithms = ["append", "assign", "make", "clear"
, "relation", "reverse","simplify", "sym_difference", "touches"
, "transform", "union", "unique", "within"]
arithmetic = ["cross_product"]
access_functions = ["get", "set", "exterior_ring", "interior_rings"
, "num_points", "num_interior_rings", "num_geometries"]
@ -190,6 +192,7 @@ for i in views:
model_to_quickbook2("d2_1_1point__xy", "point_xy")
model_to_quickbook2("d3_1_1point__xyz", "point_xyz")
group_to_quickbook("arithmetic")
group_to_quickbook("dsv")

View File

@ -87,6 +87,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="geometry.reference.models.model_point">point</link></member>
<member><link linkend="geometry.reference.models.model_d2_point_xy">point_xy</link></member>
<member><link linkend="geometry.reference.models.model_d3_point_xyz">point_xyz</link></member>
<member><link linkend="geometry.reference.models.model_multi_point">multi_point</link></member>
</simplelist>
</entry>

View File

@ -312,6 +312,7 @@
[include generated/point.qbk]
[include generated/point_xy.qbk]
[include generated/point_xyz.qbk]
[include generated/linestring.qbk]
[include generated/polygon.qbk]
[include generated/multi_point.qbk]

View File

@ -13,6 +13,3 @@
[heading Examples]
[point_xy]
[point_xy_output]
[include reference/geometries/point_assign_warning.qbk]

View File

@ -0,0 +1,13 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
=============================================================================/]
[heading Examples]
[point_xyz]
[point_xyz_output]

View File

@ -17,7 +17,7 @@ import quickbook ;
boostbook fruit
: fruit.qbk
: <dependency>Jamfile.v2
: <dependency>Jamfile
<dependency>generated/apple.qbk
<dependency>generated/rose.qbk
<dependency>generated/grouped.qbk

View File

@ -0,0 +1,70 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[covered_by
//` Checks if the first geometry is inside or on border the second geometry
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Checks if the first geometry is inside or on border the second geometry.
bg::model::polygon<bg::model::d2::point_xy<double> > poly1;
bg::read_wkt("POLYGON((0 2,0 3,2 4,1 2,0 2))", poly1);
bg::model::polygon<bg::model::d2::point_xy<double> > poly2;
bg::read_wkt("POLYGON((0 4,3 4,2 2,0 1,0 4))", poly2);
bool check_covered = bg::covered_by(poly1, poly2);
if (check_covered) {
std::cout << "Covered: Yes" << std::endl;
} else {
std::cout << "Covered: No" << std::endl;
}
bg::model::polygon<bg::model::d2::point_xy<double> > poly3;
bg::read_wkt("POLYGON((-1 -1,-3 -4,-7 -7,-4 -3,-1 -1))", poly3);
check_covered = bg::covered_by(poly1, poly3);
if (check_covered) {
std::cout << "Covered: Yes" << std::endl;
} else {
std::cout << "Covered: No" << std::endl;
}
// This should return true since both polygons are same, so they are lying on each other.
check_covered = bg::covered_by(poly1, poly1);
if (check_covered) {
std::cout << "Covered: Yes" << std::endl;
} else {
std::cout << "Covered: No" << std::endl;
}
return 0;
}
//]
//[covered_by_output
/*`
Output:
[pre
Covered: Yes
[$img/algorithms/covered_by.png]
Covered: No
Covered: Yes
]
*/
//]

View File

@ -0,0 +1,62 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[crosses
//` Checks if two geometries crosses
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Checks if the two geometries (here, a polygon and a linestring) crosses or not.
bg::model::polygon<bg::model::d2::point_xy<double> > poly;
bg::read_wkt("POLYGON((0 0,0 3,3 3,3 0,0 0))", poly);
bg::model::linestring<bg::model::d2::point_xy<double> > line1;
bg::read_wkt("LINESTRING(1 1,2 2,4 4)", line1);
bool check_crosses = bg::crosses(poly, line1);
if (check_crosses) {
std::cout << "Crosses: Yes" << std::endl;
} else {
std::cout << "Crosses: No" << std::endl;
}
// Edge case: linestring just touches the polygon but doesn't crosses it.
bg::model::linestring<bg::model::d2::point_xy<double> > line2;
bg::read_wkt("LINESTRING(1 1,1 2,1 3)", line2);
check_crosses = bg::crosses(poly, line2);
if (check_crosses) {
std::cout << "Crosses: Yes" << std::endl;
} else {
std::cout << "Crosses: No" << std::endl;
}
return 0;
}
//]
//[crosses_output
/*`
Output:
[pre
Crosses: Yes
Crosses: No
[$img/algorithms/crosses.png]
]
*/
//]

View File

@ -0,0 +1,61 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[disjoint
//` Checks if two geometries are disjoint
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Checks if two geometries are disjoint, which means that two geometries have zero intersection.
bg::model::polygon<bg::model::d2::point_xy<double> > poly1;
bg::read_wkt("POLYGON((0 2,-2 0,-4 2,-2 4,0 2))", poly1);
bg::model::polygon<bg::model::d2::point_xy<double> > poly2;
bg::read_wkt("POLYGON((2 2,4 4,6 2,4 0,2 2))", poly2);
bool check_disjoint = bg::disjoint(poly1, poly2);
if (check_disjoint) {
std::cout << "Disjoint: Yes" << std::endl;
} else {
std::cout << "Disjoint: No" << std::endl;
}
bg::model::polygon<bg::model::d2::point_xy<double> > poly3;
bg::read_wkt("POLYGON((0 2,2 4,4 2,2 0,0 2))", poly3);
check_disjoint = bg::disjoint(poly1, poly3);
if (check_disjoint) {
std::cout << "Disjoint: Yes" << std::endl;
} else {
std::cout << "Disjoint: No" << std::endl;
}
return 0;
}
//]
//[disjoint_output
/*`
Output:
[pre
Disjoint: Yes
Disjoint: No
[$img/algorithms/disjoint.png]
]
*/
//]

View File

@ -0,0 +1,61 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[overlaps
//` Checks if two geometries overlap
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Checks if the two geometries overlaps or not.
bg::model::polygon<bg::model::d2::point_xy<double> > poly1;
bg::read_wkt("POLYGON((0 0,0 4,4 4,4 0,0 0))", poly1);
bg::model::polygon<bg::model::d2::point_xy<double> > poly2;
bg::read_wkt("POLYGON((2 2,2 6,6 7,6 1,2 2))", poly2);
bool check_overlap = bg::overlaps(poly1, poly2);
if (check_overlap) {
std::cout << "Overlaps: Yes" << std::endl;
} else {
std::cout << "Overlaps: No" << std::endl;
}
bg::model::polygon<bg::model::d2::point_xy<double> > poly3;
bg::read_wkt("POLYGON((-1 -1,-3 -4,-7 -7,-4 -3,-1 -1))", poly3);
check_overlap = bg::overlaps(poly1, poly3);
if (check_overlap) {
std::cout << "Overlaps: Yes" << std::endl;
} else {
std::cout << "Overlaps: No" << std::endl;
}
return 0;
}
//]
//[overlaps_output
/*`
Output:
[pre
Overlaps: Yes
[$img/algorithms/overlaps.png]
Overlaps: No
]
*/
//]

View File

@ -0,0 +1,42 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[perimeter
//` Calculate the perimeter of a polygon
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Calculate the perimeter of a cartesian polygon
bg::model::polygon<bg::model::d2::point_xy<double> > poly;
bg::read_wkt("POLYGON((0 0,3 4,5 -5,-2 -4, 0 0))", poly);
double perimeter = bg::perimeter(poly);
std::cout << "Perimeter: " << perimeter << std::endl;
return 0;
}
//]
//[perimeter_output
/*`
Output:
[pre
Perimeter: 25.7627
]
*/
//]

View File

@ -0,0 +1,59 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[touches_one_geometry
//` Checks if a geometry has at least one touching point (self-tangency)
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Checks if the geometry has self-tangency.
bg::model::polygon<bg::model::d2::point_xy<double> > poly1;
bg::read_wkt("POLYGON((0 0,0 3,2 3,2 2,1 2,1 1,2 1,2 2,3 2,3 0,0 0))", poly1);
bool check_touches = bg::touches(poly1);
if (check_touches) {
std::cout << "Touches: Yes" << std::endl;
} else {
std::cout << "Touches: No" << std::endl;
}
bg::model::polygon<bg::model::d2::point_xy<double> > poly2;
bg::read_wkt("POLYGON((0 0,0 4,4 4,4 0,2 3,0 0))", poly2);
check_touches = bg::touches(poly2);
if (check_touches) {
std::cout << "Touches: Yes" << std::endl;
} else {
std::cout << "Touches: No" << std::endl;
}
return 0;
}
//]
//[touches_one_geometry_output
/*`
Output:
[pre
Touches: Yes
[$img/algorithms/touches_one_geometry.png]
Touches: No
]
*/
//]

View File

@ -0,0 +1,61 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[touches_two_geometries
//` Checks if two geometries have at least one touching point (tangent - non overlapping)
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
// Checks if the two geometries touch
bg::model::polygon<bg::model::d2::point_xy<double> > poly1;
bg::read_wkt("POLYGON((0 0,0 4,4 4,4 0,0 0))", poly1);
bg::model::polygon<bg::model::d2::point_xy<double> > poly2;
bg::read_wkt("POLYGON((0 0,0 -4,-4 -4,-4 0,0 0))", poly2);
bool check_touches = bg::touches(poly1, poly2);
if (check_touches) {
std::cout << "Touches: Yes" << std::endl;
} else {
std::cout << "Touches: No" << std::endl;
}
bg::model::polygon<bg::model::d2::point_xy<double> > poly3;
bg::read_wkt("POLYGON((1 1,0 -4,-4 -4,-4 0,1 1))", poly3);
check_touches = bg::touches(poly1, poly3);
if (check_touches) {
std::cout << "Touches: Yes" << std::endl;
} else {
std::cout << "Touches: No" << std::endl;
}
return 0;
}
//]
//[touches_two_geometries_output
/*`
Output:
[pre
Touches: Yes
[$img/algorithms/touches_two_geometries.png]
Touches: No
]
*/
//]

View File

@ -0,0 +1,57 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2020, Aditya Mohan
// 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)
//[cross_product
//` Calculate the cross product of two points
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/arithmetic/cross_product.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
int main()
{
//Example 1 2D Vector
bg::model::point<double, 2, bg::cs::cartesian> p1(7.0, 2.0);
bg::model::point<double, 2, bg::cs::cartesian> p2(4.0, 5.0);
bg::model::point<double, 2, bg::cs::cartesian> r1;
r1 = bg::cross_product(p1,p2);
std::cout << "Cross Product 1: "<< r1.get<0>() << std::endl; //Note that the second point (r1.get<1>) would be undefined in this case
//Example 2 - 3D Vector
bg::model::point<double, 3, bg::cs::cartesian> p3(4.0, 6.0, 5.0);
bg::model::point<double, 3, bg::cs::cartesian> p4(7.0, 2.0, 3.0);
bg::model::point<double, 3, bg::cs::cartesian> r2;
r2 = bg::cross_product(p3,p4);
std::cout << "Cross Product 2: ("<< r2.get<0>() <<","<< r2.get<1>() <<","<< r2.get<2>() << ")"<< std::endl;
return 0;
}
//]
//[cross_product_output
/*`
Output:
[pre
Cross Product 1: 27
Cross Product 2: (8,23,-34)
]
*/
//]

View File

@ -0,0 +1,66 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2020, Aditya Mohan
// 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)
//[dot_product
//` Calculate the dot product of two points
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/arithmetic/dot_product.hpp>
#include <boost/geometry/geometries/adapted/boost_array.hpp>
namespace bg = boost::geometry; /*< Convenient namespace alias >*/
BOOST_GEOMETRY_REGISTER_BOOST_ARRAY_CS(cs::cartesian)
int main()
{
double dp1,dp2,dp3,dp4;
bg::model::point<double, 3, bg::cs::cartesian> point1(1.0, 2.0, 3.0);
bg::model::point<double, 3, bg::cs::cartesian> point2(4.0, 5.0, 6.0);
//Example 1
dp1 = bg::dot_product(point1, point2);
std::cout << "Dot Product 1: "<< dp1 << std::endl;
bg::model::point<double, 2, bg::cs::cartesian> point3(3.0, 2.0);
bg::model::point<double, 2, bg::cs::cartesian> point4(4.0, 7.0);
//Example 2
dp2 = bg::dot_product(point3, point4);
std::cout << "Dot Product 2: "<< dp2 << std::endl;
boost::array<double, 2> a = {1, 2};
boost::array<double, 2> b = {2, 3};
//Example 3
dp3 = bg::dot_product(a, b);
std::cout << "Dot Product 3: "<< dp3 << std::endl;
return 0;
}
//]
//[dot_product_output
/*`
Output:
[pre
Dot Product 1: 32
Dot Product 2: 26
Dot Product 3: 8
]
*/
//]

View File

@ -17,6 +17,7 @@ exe box : box.cpp ;
exe linestring : linestring.cpp ;
exe point : point.cpp ;
exe point_xy : point_xy.cpp ;
exe point_xyz : point_xyz.cpp ;
exe polygon : polygon.cpp ;
exe multi_linestring : multi_linestring.cpp ;
exe multi_point : multi_point.cpp ;

View File

@ -0,0 +1,46 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// QuickBook Example
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
//[point_xyz
//` Declaration and use of the Boost.Geometry model::d3::point_xyz, modelling the Point Concept
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xyz.hpp>
namespace bg = boost::geometry;
int main()
{
bg::model::d3::point_xyz<double> point1;
bg::model::d3::point_xyz<double> point2(3, 4, 5); /*< Construct, assigning coordinates. >*/
bg::set<0>(point1, 1.0); /*< Set a coordinate, generic. >*/
point1.y(2.0); /*< Set a coordinate, class-specific ([*Note]: prefer `bg::set()`). >*/
point1.z(4.0);
double x = bg::get<0>(point1); /*< Get a coordinate, generic. >*/
double y = point1.y(); /*< Get a coordinate, class-specific ([*Note]: prefer `bg::get()`). >*/
double z = point1.z();
std::cout << x << ", " << y << ", " << z << std::endl;
return 0;
}
//]
//[point_xyz_output
/*`
Output:
[pre
1, 2, 4
]
*/
//]

View File

@ -252,6 +252,11 @@ inline bool crosses(Geometry1 const& geometry1,
\return \return_check2{crosses}
\qbk{[include reference/algorithms/crosses.qbk]}
\qbk{
[heading Examples]
[crosses]
[crosses_output]
}
*/
template <typename Geometry1, typename Geometry2>
inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2)

View File

@ -612,7 +612,7 @@ struct buffer_inserter<ring_tag, RingInput, RingOutput>
collection, distance,
side_strategy, join_strategy, end_strategy, point_strategy,
robust_policy, strategy);
collection.finish_ring(code);
collection.finish_ring(code, ring, false, false);
return code;
}
};
@ -810,7 +810,7 @@ private:
join_strategy, end_strategy, point_strategy,
robust_policy, strategy);
collection.finish_ring(code, is_interior);
collection.finish_ring(code, *it, is_interior, false);
}
}
@ -874,7 +874,7 @@ public:
join_strategy, end_strategy, point_strategy,
robust_policy, strategy);
collection.finish_ring(code, false,
collection.finish_ring(code, exterior_ring(polygon), false,
geometry::num_interior_rings(polygon) > 0u);
}
@ -947,9 +947,10 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
<
typename geometry::ring_type<GeometryOutput>::type,
IntersectionStrategy,
DistanceStrategy,
RobustPolicy
> collection_type;
collection_type collection(intersection_strategy, robust_policy);
collection_type collection(intersection_strategy, distance_strategy, robust_policy);
collection_type const& const_collection = collection;
bool const areal = boost::is_same
@ -972,11 +973,11 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
end_strategy, point_strategy,
robust_policy, intersection_strategy.get_side_strategy());
collection.get_turns(distance_strategy);
collection.get_turns();
collection.classify_turns();
if (BOOST_GEOMETRY_CONDITION(areal))
{
collection.check_remaining_points(distance_strategy);
collection.check_remaining_points();
}
// Visit the piece collection. This does nothing (by default), but

View File

@ -162,17 +162,9 @@ struct buffer_turn_info
std::size_t turn_index; // TODO: this might go if partition can operate on non-const input
RobustPoint robust_point;
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
// Will (most probably) be removed later
RobustPoint mapped_robust_point; // alas... we still need to adapt our points, offsetting them 1 integer to be co-located with neighbours
#endif
inline RobustPoint const& get_robust_point() const
{
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
return mapped_robust_point;
#endif
return robust_point;
}
@ -183,32 +175,21 @@ struct buffer_turn_info
std::size_t count_within;
bool within_original;
std::size_t count_on_original_boundary;
signed_size_type count_in_original; // increased by +1 for in ext.ring, -1 for int.ring
std::size_t count_on_offsetted;
std::size_t count_on_helper;
std::size_t count_within_near_offsetted;
bool remove_on_multi;
// Obsolete:
std::size_t count_on_occupied;
std::size_t count_on_multi;
inline buffer_turn_info()
: turn_index(0)
, location(location_ok)
, count_within(0)
, within_original(false)
, count_on_original_boundary(0)
, count_in_original(0)
, count_on_offsetted(0)
, count_on_helper(0)
, count_within_near_offsetted(0)
, remove_on_multi(false)
, count_on_occupied(0)
, count_on_multi(0)
{}
};

View File

@ -37,6 +37,7 @@
#include <boost/geometry/algorithms/detail/buffer/buffered_ring.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
#include <boost/geometry/algorithms/detail/overlay/cluster_info.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_box.hpp>
#include <boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp>
#include <boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp>
#include <boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp>
@ -51,14 +52,13 @@
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/occupation_info.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
#include <boost/geometry/algorithms/detail/sections/section_box_policies.hpp>
#include <boost/geometry/views/detail/normalized_view.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
{
@ -67,13 +67,6 @@ namespace boost { namespace geometry
namespace detail { namespace buffer
{
enum segment_relation_code
{
segment_relation_on_left,
segment_relation_on_right,
segment_relation_within,
segment_relation_disjoint
};
/*
* Terminology
@ -119,14 +112,15 @@ enum segment_relation_code
*/
template <typename Ring, typename IntersectionStrategy, typename RobustPolicy>
template
<
typename Ring,
typename IntersectionStrategy,
typename DistanceStrategy,
typename RobustPolicy
>
struct buffered_piece_collection
{
typedef buffered_piece_collection
<
Ring, IntersectionStrategy, RobustPolicy
> this_type;
typedef typename geometry::point_type<Ring>::type point_type;
typedef typename geometry::coordinate_type<Ring>::type coordinate_type;
typedef typename geometry::robust_point_type
@ -250,8 +244,6 @@ struct buffered_piece_collection
robust_box_type robust_envelope;
robust_box_type robust_offsetted_envelope;
std::vector<robust_turn> robust_turns; // Used only in insert_rescaled_piece_turns - we might use a map instead
robust_point_type robust_center;
robust_comparable_radius_type robust_min_comparable_radius;
robust_comparable_radius_type robust_max_comparable_radius;
@ -277,17 +269,17 @@ struct buffered_piece_collection
}
};
struct robust_original
struct original_ring
{
typedef robust_ring_type original_robust_ring_type;
typedef geometry::sections<robust_box_type, 1> sections_type;
inline robust_original()
// Creates an empty instance
inline original_ring()
: m_is_interior(false)
, m_has_interiors(true)
, m_has_interiors(false)
{}
inline robust_original(robust_ring_type const& ring,
inline original_ring(robust_ring_type const& ring,
bool is_interior, bool has_interiors,
envelope_strategy_type const& envelope_strategy,
expand_strategy_type const& expand_strategy)
@ -323,9 +315,11 @@ struct buffered_piece_collection
bool m_deflate;
bool m_has_deflated;
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; // indexed by multi_index
std::vector<robust_original> robust_originals; // robust representation of the original(s)
robust_ring_type current_robust_ring;
// Offsetted rings, and representations of original ring(s)
// both indexed by multi_index
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings;
std::vector<original_ring> original_rings;
buffered_ring_collection<Ring> traversed_rings;
segment_identifier current_segment_id;
@ -344,6 +338,7 @@ struct buffered_piece_collection
cluster_type m_clusters;
IntersectionStrategy m_intersection_strategy;
DistanceStrategy m_distance_strategy;
side_strategy_type m_side_strategy;
area_strategy_type m_area_strategy;
envelope_strategy_type m_envelope_strategy;
@ -353,20 +348,14 @@ struct buffered_piece_collection
robust_area_strategy_type m_robust_area_strategy;
RobustPolicy const& m_robust_policy;
struct redundant_turn
{
inline bool operator()(buffer_turn_info_type const& turn) const
{
return turn.remove_on_multi;
}
};
buffered_piece_collection(IntersectionStrategy const& intersection_strategy,
DistanceStrategy const& distance_strategy,
RobustPolicy const& robust_policy)
: m_first_piece_index(-1)
, m_deflate(false)
, m_has_deflated(false)
, m_intersection_strategy(intersection_strategy)
, m_distance_strategy(distance_strategy)
, m_side_strategy(intersection_strategy.get_side_strategy())
, m_area_strategy(intersection_strategy
.template get_area_strategy<point_type>())
@ -381,163 +370,6 @@ struct buffered_piece_collection
{}
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
// Will (most probably) be removed later
template <typename OccupationMap>
inline void adapt_mapped_robust_point(OccupationMap const& map,
buffer_turn_info_type& turn, int distance) const
{
for (int x = -distance; x <= distance; x++)
{
for (int y = -distance; y <= distance; y++)
{
robust_point_type rp = turn.robust_point;
geometry::set<0>(rp, geometry::get<0>(rp) + x);
geometry::set<1>(rp, geometry::get<1>(rp) + y);
if (map.find(rp) != map.end())
{
turn.mapped_robust_point = rp;
return;
}
}
}
}
#endif
inline void get_occupation(
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
int distance = 0
#endif
)
{
typedef occupation_info<angle_info<robust_point_type, coordinate_type> >
buffer_occupation_info;
typedef std::map
<
robust_point_type,
buffer_occupation_info,
geometry::less<robust_point_type>
> occupation_map_type;
occupation_map_type occupation_map;
// 1: Add all intersection points to occupation map
typedef typename boost::range_iterator<turn_vector_type>::type
iterator_type;
for (iterator_type it = boost::begin(m_turns);
it != boost::end(m_turns);
++it)
{
if (it->location == location_ok)
{
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
if (distance > 0 && ! occupation_map.empty())
{
adapt_mapped_robust_point(occupation_map, *it, distance);
}
#endif
occupation_map[it->get_robust_point()].count++;
}
}
// Remove all points with one or more u/u points from the map
// (Alternatively, we could NOT do this here and change all u/u
// behaviour in overlay. Currently nothing is done: each polygon is
// just followed there. We could also always switch polygons there. For
// buffer behaviour, where 3 pieces might meet of which 2 (or more) form
// a u/u turn, this last option would have been better, probably).
for (iterator_type it = boost::begin(m_turns);
it != boost::end(m_turns);
++it)
{
if (it->both(detail::overlay::operation_union))
{
typename occupation_map_type::iterator mit =
occupation_map.find(it->get_robust_point());
if (mit != occupation_map.end())
{
occupation_map.erase(mit);
}
}
}
// 2: Remove all points from map which has only one
typename occupation_map_type::iterator it = occupation_map.begin();
while (it != occupation_map.end())
{
if (it->second.count <= 1)
{
typename occupation_map_type::iterator to_erase = it;
++it;
occupation_map.erase(to_erase);
}
else
{
++it;
}
}
if (occupation_map.empty())
{
return;
}
// 3: Add vectors (incoming->intersection-point,
// intersection-point -> outgoing)
// for all (co-located) points still present in the map
for (iterator_type tit = boost::begin(m_turns);
tit != boost::end(m_turns);
++tit)
{
typename occupation_map_type::iterator mit =
occupation_map.find(tit->get_robust_point());
if (mit != occupation_map.end())
{
buffer_occupation_info& info = mit->second;
for (int i = 0; i < 2; i++)
{
add_incoming_and_outgoing_angles(tit->get_robust_point(), *tit,
m_pieces,
i, tit->operations[i].seg_id,
info);
}
tit->count_on_multi++;
}
}
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
// X: Check rounding issues
if (distance == 0)
{
for (typename occupation_map_type::const_iterator it = occupation_map.begin();
it != occupation_map.end(); ++it)
{
if (it->second.has_rounding_issues(it->first))
{
if(distance == 0)
{
get_occupation(distance + 1);
return;
}
}
}
}
#endif
// Get left turns from all clusters
for (typename occupation_map_type::iterator mit = occupation_map.begin();
mit != occupation_map.end(); ++mit)
{
mit->second.get_left_turns(mit->first, m_turns, m_side_strategy);
}
}
inline void classify_turns()
{
for (typename boost::range_iterator<turn_vector_type>::type it =
@ -646,8 +478,7 @@ struct buffered_piece_collection
}
}
template <typename DistanceStrategy>
inline void check_remaining_points(DistanceStrategy const& distance_strategy)
inline void check_remaining_points()
{
// Check if a turn is inside any of the originals
@ -671,11 +502,11 @@ struct buffered_piece_collection
robust_box_type,
include_turn_policy,
detail::partition::include_all_policy
>::apply(m_turns, robust_originals, visitor,
>::apply(m_turns, original_rings, visitor,
turn_get_box(), turn_in_original_ovelaps_box_type(),
original_get_box(), original_ovelaps_box_type());
bool const deflate = distance_strategy.negative();
bool const deflate = m_distance_strategy.negative();
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it)
@ -703,100 +534,15 @@ struct buffered_piece_collection
}
}
inline bool assert_indices_in_robust_rings() const
{
geometry::equal_to<robust_point_type> comparator;
for (typename boost::range_iterator<turn_vector_type const>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it)
{
for (int i = 0; i < 2; i++)
{
robust_point_type const &p1
= m_pieces[it->operations[i].piece_index].robust_ring
[it->operations[i].index_in_robust_ring];
robust_point_type const &p2 = it->robust_point;
if (! comparator(p1, p2))
{
return false;
}
}
}
return true;
}
inline void insert_rescaled_piece_turns()
inline void update_turn_administration()
{
// Add rescaled turn points to corresponding pieces
// (after this, each turn occurs twice)
std::size_t index = 0;
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it, ++index)
{
geometry::recalculate(it->robust_point, it->point, m_robust_policy);
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
it->mapped_robust_point = it->robust_point;
#endif
robust_turn turn;
it->turn_index = index;
turn.turn_index = index;
turn.point = it->robust_point;
for (int i = 0; i < 2; i++)
{
turn.operation_index = i;
turn.seg_id = it->operations[i].seg_id;
turn.fraction = it->operations[i].fraction;
piece& pc = m_pieces[it->operations[i].piece_index];
pc.robust_turns.push_back(turn);
// Take into account for the box (intersection points should fall inside,
// but in theory they can be one off because of rounding
geometry::expand(pc.robust_envelope, it->robust_point);
geometry::expand(pc.robust_offsetted_envelope, it->robust_point);
}
}
if (! use_side_of_intersection<typename geometry::cs_tag<point_type>::type>::value)
{
// Insert all rescaled turn-points into these rings, to form a
// reliable integer-based ring. All turns can be compared (inside) to this
// rings to see if they are inside.
for (typename boost::range_iterator<piece_vector_type>::type
it = boost::begin(m_pieces); it != boost::end(m_pieces); ++it)
{
piece& pc = *it;
signed_size_type piece_segment_index = pc.first_seg_id.segment_index;
if (! pc.robust_turns.empty())
{
if (pc.robust_turns.size() > 1u)
{
std::sort(pc.robust_turns.begin(), pc.robust_turns.end(), buffer_operation_less());
}
// Walk through them, in reverse to insert at right index
signed_size_type index_offset = static_cast<signed_size_type>(pc.robust_turns.size()) - 1;
for (typename boost::range_reverse_iterator<const std::vector<robust_turn> >::type
rit = boost::const_rbegin(pc.robust_turns);
rit != boost::const_rend(pc.robust_turns);
++rit, --index_offset)
{
signed_size_type const index_in_vector = 1 + rit->seg_id.segment_index - piece_segment_index;
BOOST_GEOMETRY_ASSERT
(
index_in_vector > 0
&& index_in_vector < pc.offsetted_count
);
pc.robust_ring.insert(boost::begin(pc.robust_ring) + index_in_vector, rit->point);
pc.offsetted_count++;
m_turns[rit->turn_index].operations[rit->operation_index].index_in_robust_ring = index_in_vector + index_offset;
}
}
}
BOOST_GEOMETRY_ASSERT(assert_indices_in_robust_rings());
}
}
@ -916,17 +662,8 @@ struct buffered_piece_collection
}
}
template <typename DistanceStrategy>
inline void get_turns(DistanceStrategy const& distance_strategy)
inline void get_turns()
{
for(typename boost::range_iterator<sections_type>::type it
= boost::begin(monotonic_sections);
it != boost::end(monotonic_sections);
++it)
{
enlarge_box(it->bounding_box, 1);
}
{
// Calculate the turns
piece_turn_visitor
@ -948,6 +685,8 @@ struct buffered_piece_collection
typename IntersectionStrategy::disjoint_box_box_strategy_type
> overlaps_section_box_type;
detail::sectionalize::enlarge_sections(monotonic_sections,
m_envelope_strategy);
geometry::partition
<
robust_box_type
@ -956,7 +695,7 @@ struct buffered_piece_collection
overlaps_section_box_type());
}
insert_rescaled_piece_turns();
update_turn_administration();
reverse_negative_robust_rings();
@ -974,7 +713,7 @@ struct buffered_piece_collection
point_in_geometry_strategy_type,
side_strategy_type
> visitor(m_turns, m_pieces,
distance_strategy,
m_distance_strategy,
m_point_in_geometry_strategy,
m_side_strategy);
@ -999,14 +738,14 @@ struct buffered_piece_collection
inline void start_new_ring(bool deflate)
{
signed_size_type const n = static_cast<signed_size_type>(offsetted_rings.size());
std::size_t const n = offsetted_rings.size();
current_segment_id.source_index = 0;
current_segment_id.multi_index = n;
current_segment_id.multi_index = static_cast<signed_size_type>(n);
current_segment_id.ring_index = -1;
current_segment_id.segment_index = 0;
offsetted_rings.resize(n + 1);
current_robust_ring.clear();
original_rings.resize(n + 1);
m_first_piece_index = static_cast<signed_size_type>(boost::size(m_pieces));
m_deflate = deflate;
@ -1025,32 +764,15 @@ struct buffered_piece_collection
&& m_pieces.back().first_seg_id.multi_index
== current_segment_id.multi_index)
{
m_pieces.erase(m_pieces.end() - 1);
m_pieces.pop_back();
}
while (! monotonic_sections.empty()
&& monotonic_sections.back().ring_id.multi_index
== current_segment_id.multi_index)
{
monotonic_sections.erase(monotonic_sections.end() - 1);
}
offsetted_rings.erase(offsetted_rings.end() - 1);
current_robust_ring.clear();
offsetted_rings.pop_back();
original_rings.pop_back();
m_first_piece_index = -1;
}
inline void update_closing_point()
{
BOOST_GEOMETRY_ASSERT(! offsetted_rings.empty());
buffered_ring<Ring>& added = offsetted_rings.back();
if (! boost::empty(added))
{
range::back(added) = range::front(added);
}
}
inline void update_last_point(point_type const& p,
buffered_ring<Ring>& ring)
{
@ -1079,43 +801,84 @@ struct buffered_piece_collection
m_robust_policy);
}
inline void finish_ring(strategy::buffer::result_code code,
bool is_interior = false, bool has_interiors = false)
inline bool finish_ring(strategy::buffer::result_code code)
{
if (code == strategy::buffer::result_error_numerical)
{
abort_ring();
return;
return false;
}
if (m_first_piece_index == -1)
{
return false;
}
// Casted version
std::size_t const first_piece_index
= static_cast<std::size_t>(m_first_piece_index);
signed_size_type const last_piece_index
= static_cast<signed_size_type>(boost::size(m_pieces)) - 1;
if (first_piece_index < boost::size(m_pieces))
{
// If pieces were added,
// reassign left-of-first and right-of-last
geometry::range::at(m_pieces, first_piece_index).left_index
= last_piece_index;
geometry::range::back(m_pieces).right_index = m_first_piece_index;
}
buffered_ring<Ring>& added = offsetted_rings.back();
if (! boost::empty(added))
{
// Make sure the closing point is identical (they are calculated
// separately by different pieces)
range::back(added) = range::front(added);
}
for (std::size_t i = first_piece_index; i < boost::size(m_pieces); i++)
{
sectionalize(m_pieces[i], added);
}
m_first_piece_index = -1;
return true;
}
template <typename InputRing>
inline void finish_ring(strategy::buffer::result_code code,
InputRing const& input_ring,
bool is_interior, bool has_interiors)
{
if (! finish_ring(code))
{
return;
}
if (m_first_piece_index < static_cast<signed_size_type>(boost::size(m_pieces)))
if (! input_ring.empty())
{
// If piece was added
// Reassign left-of-first and right-of-last
geometry::range::at(m_pieces, m_first_piece_index).left_index
= static_cast<signed_size_type>(boost::size(m_pieces)) - 1;
geometry::range::back(m_pieces).right_index = m_first_piece_index;
}
m_first_piece_index = -1;
// Assign the ring to the original_ring collection
// For rescaling, it is recalculated. Without rescaling, it
// is just assigning (note that this Ring type is the
// GeometryOut type, which might differ from the input ring type)
geometry::model::ring<robust_point_type> adapted_ring;
update_closing_point();
typedef detail::normalized_view<InputRing const> view_type;
view_type const view(input_ring);
if (! current_robust_ring.empty())
{
BOOST_GEOMETRY_ASSERT
(
geometry::equals(current_robust_ring.front(),
current_robust_ring.back())
);
for (typename boost::range_iterator<view_type const>::type it =
boost::begin(view); it != boost::end(view); ++it)
{
robust_point_type adapted_point;
geometry::recalculate(adapted_point, *it, m_robust_policy);
adapted_ring.push_back(adapted_point);
}
robust_originals.push_back(
robust_original(current_robust_ring,
is_interior, has_interiors, m_envelope_strategy, m_expand_strategy));
original_rings.back()
= original_ring(adapted_ring,
is_interior, has_interiors,
m_envelope_strategy, m_expand_strategy);
}
}
@ -1174,7 +937,6 @@ struct buffered_piece_collection
{
// This indicates an error situation: an earlier piece was empty
// It currently does not happen
// std::cout << "EMPTY " << pc.type << " " << pc.index << " " << pc.first_seg_id.multi_index << std::endl;
pc.offsetted_count = 0;
return;
}
@ -1203,7 +965,7 @@ struct buffered_piece_collection
}
}
inline robust_point_type add_helper_point(piece& pc, const point_type& point)
inline void add_helper_point(piece& pc, const point_type& point)
{
#if defined(BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS)
pc.helper_points.push_back(point);
@ -1212,17 +974,18 @@ struct buffered_piece_collection
robust_point_type rob_point;
geometry::recalculate(rob_point, point, m_robust_policy);
pc.robust_ring.push_back(rob_point);
return rob_point;
}
// TODO: this is shared with sectionalize, move to somewhere else (assign?)
template <typename Box, typename Value>
inline void enlarge_box(Box& box, Value value)
template <typename Box>
static inline void enlarge_box(Box& box)
{
geometry::set<0, 0>(box, geometry::get<0, 0>(box) - value);
geometry::set<0, 1>(box, geometry::get<0, 1>(box) - value);
geometry::set<1, 0>(box, geometry::get<1, 0>(box) + value);
geometry::set<1, 1>(box, geometry::get<1, 1>(box) + value);
#if defined(BOOST_GEOMETRY_USE_RESCALING)
// Enlarge the box by 1 pixel, or 1 unit
detail::buffer::buffer_box(box, 1, box);
#else
// Enlarge the box just a bit
detail::buffer::buffer_box(box, 0.001, box);
#endif
}
inline void calculate_robust_envelope(piece& pc)
@ -1240,16 +1003,13 @@ struct buffered_piece_collection
geometry::expand(pc.robust_offsetted_envelope, pc.robust_ring[i]);
}
// Take roundings into account, enlarge boxes with 1 integer
enlarge_box(pc.robust_envelope, 1);
enlarge_box(pc.robust_offsetted_envelope, 1);
// Take roundings into account, enlarge boxes
enlarge_box(pc.robust_envelope);
enlarge_box(pc.robust_offsetted_envelope);
}
inline void sectionalize(piece& pc)
inline void sectionalize(piece const& pc, buffered_ring<Ring> const& ring)
{
buffered_ring<Ring> const& ring = offsetted_rings.back();
typedef geometry::detail::sectionalize::sectionalize_part
<
point_type,
@ -1259,7 +1019,7 @@ struct buffered_piece_collection
// Create a ring-identifier. The source-index is the piece index
// The multi_index is as in this collection (the ring), but not used here
// The ring_index is not used
ring_identifier ring_id(pc.index, pc.first_seg_id.multi_index, -1);
ring_identifier const ring_id(pc.index, pc.first_seg_id.multi_index, -1);
sectionalizer::apply(monotonic_sections,
boost::begin(ring) + pc.first_seg_id.segment_index,
@ -1272,7 +1032,6 @@ struct buffered_piece_collection
{
init_rescale_piece(pc, 0u);
calculate_robust_envelope(pc);
sectionalize(pc);
}
inline void finish_piece(piece& pc,
@ -1287,12 +1046,9 @@ struct buffered_piece_collection
}
add_helper_point(pc, point1);
robust_point_type mid_point = add_helper_point(pc, point2);
add_helper_point(pc, point2);
add_helper_point(pc, point3);
calculate_robust_envelope(pc);
sectionalize(pc);
current_robust_ring.push_back(mid_point);
}
inline void finish_piece(piece& pc,
@ -1303,24 +1059,10 @@ struct buffered_piece_collection
{
init_rescale_piece(pc, 4u);
add_helper_point(pc, point1);
robust_point_type mid_point2 = add_helper_point(pc, point2);
robust_point_type mid_point1 = add_helper_point(pc, point3);
add_helper_point(pc, point2);
add_helper_point(pc, point3);
add_helper_point(pc, point4);
sectionalize(pc);
calculate_robust_envelope(pc);
// Add mid-points in other order to current helper_ring
current_robust_ring.push_back(mid_point1);
current_robust_ring.push_back(mid_point2);
}
inline void add_piece(strategy::buffer::piece_type type, point_type const& p,
point_type const& b1, point_type const& b2)
{
piece& pc = create_piece(type, false);
add_point(b1);
pc.last_segment_index = add_point(b2);
finish_piece(pc, b2, p, b1);
}
template <typename Range>
@ -1344,6 +1086,14 @@ struct buffered_piece_collection
}
}
inline void add_piece(strategy::buffer::piece_type type, point_type const& p,
point_type const& b1, point_type const& b2)
{
piece& pc = create_piece(type, false);
add_point(b1);
pc.last_segment_index = add_point(b2);
finish_piece(pc, b2, p, b1);
}
template <typename Range>
inline void add_piece(strategy::buffer::piece_type type, Range const& range,
@ -1358,17 +1108,6 @@ struct buffered_piece_collection
finish_piece(pc);
}
template <typename Range>
inline void add_side_piece(point_type const& p1, point_type const& p2,
Range const& range, bool first)
{
BOOST_GEOMETRY_ASSERT(boost::size(range) >= 2u);
piece& pc = create_piece(strategy::buffer::buffered_segment, ! first);
add_range_to_piece(pc, range, first);
finish_piece(pc, range.back(), p2, p1, range.front());
}
template <typename Range>
inline void add_piece(strategy::buffer::piece_type type,
point_type const& p, Range const& range)
@ -1386,6 +1125,17 @@ struct buffered_piece_collection
}
}
template <typename Range>
inline void add_side_piece(point_type const& p1, point_type const& p2,
Range const& range, bool first)
{
BOOST_GEOMETRY_ASSERT(boost::size(range) >= 2u);
piece& pc = create_piece(strategy::buffer::buffered_segment, ! first);
add_range_to_piece(pc, range, first);
finish_piece(pc, range.back(), p2, p1, range.front());
}
template <typename EndcapStrategy, typename Range>
inline void add_endcap(EndcapStrategy const& strategy, Range const& range,
point_type const& end_point)
@ -1470,12 +1220,16 @@ struct buffered_piece_collection
// any of the robust original rings
// This can go quadratic if the input has many rings, and there
// are many untouched deflated rings around
for (typename std::vector<robust_original>::const_iterator it
= robust_originals.begin();
it != robust_originals.end();
for (typename std::vector<original_ring>::const_iterator it
= original_rings.begin();
it != original_rings.end();
++it)
{
robust_original const& original = *it;
original_ring const& original = *it;
if (original.m_ring.empty())
{
continue;
}
if (detail::disjoint::disjoint_point_box(any_point,
original.m_box,
d_pb_strategy_type()))
@ -1536,15 +1290,6 @@ struct buffered_piece_collection
inline void block_turns()
{
// To fix left-turn issues like #rt_u13
// But currently it causes more other issues than it fixes
// m_turns.erase
// (
// std::remove_if(boost::begin(m_turns), boost::end(m_turns),
// redundant_turn()),
// boost::end(m_turns)
// );
for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it)
{

View File

@ -212,9 +212,13 @@ public:
{}
template <typename Turn, typename Original>
inline bool apply(Turn const& turn, Original const& original, bool first = true)
inline bool apply(Turn const& turn, Original const& original)
{
boost::ignore_unused(first);
if (boost::empty(original.m_ring))
{
// Skip empty rings
return true;
}
if (turn.location != location_ok || turn.within_original)
{

View File

@ -935,12 +935,8 @@ public:
switch(analyse_code)
{
case analyse_disjoint :
return true;
case analyse_on_offsetted :
mutable_turn.count_on_offsetted++; // value is not used anymore
return true;
case analyse_on_original_boundary :
mutable_turn.count_on_original_boundary++;
return true;
case analyse_within :
mutable_turn.count_within++;

View File

@ -217,7 +217,11 @@ struct covered_by<
\note The default strategy is used for covered_by detection
\qbk{[include reference/algorithms/covered_by.qbk]}
\qbk{
[heading Examples]
[covered_by]
[covered_by_output]
}
*/
template<typename Geometry1, typename Geometry2>
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)

View File

@ -228,6 +228,11 @@ inline bool disjoint(Geometry1 const& geometry1,
\return \return_check2{are disjoint}
\qbk{[include reference/algorithms/disjoint.qbk]}
\qbk{
[heading Examples]
[disjoint]
[disjoint_output]
}
*/
template <typename Geometry1, typename Geometry2>
inline bool disjoint(Geometry1 const& geometry1,

View File

@ -1,315 +0,0 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#include <set>
#include <vector>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
#include <boost/geometry/strategies/side.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
// TODO: move this to /util/
template <typename T>
inline std::pair<T, T> ordered_pair(T const& first, T const& second)
{
return first < second ? std::make_pair(first, second) : std::make_pair(second, first);
}
namespace left_turns
{
template <typename Vector>
inline int get_quadrant(Vector const& vector)
{
// Return quadrant as layouted in the code below:
// 3 | 0
// -----
// 2 | 1
return geometry::get<1>(vector) >= 0
? (geometry::get<0>(vector) < 0 ? 3 : 0)
: (geometry::get<0>(vector) < 0 ? 2 : 1)
;
}
template <typename Vector>
inline int squared_length(Vector const& vector)
{
return geometry::get<0>(vector) * geometry::get<0>(vector)
+ geometry::get<1>(vector) * geometry::get<1>(vector)
;
}
template <typename Point, typename SideStrategy>
struct angle_less
{
typedef Point vector_type;
angle_less(Point const& origin, SideStrategy const& strategy)
: m_origin(origin)
, m_strategy(strategy)
{}
template <typename Angle>
inline bool operator()(Angle const& p, Angle const& q) const
{
// Vector origin -> p and origin -> q
vector_type pv = p.point;
vector_type qv = q.point;
geometry::subtract_point(pv, m_origin);
geometry::subtract_point(qv, m_origin);
int const quadrant_p = get_quadrant(pv);
int const quadrant_q = get_quadrant(qv);
if (quadrant_p != quadrant_q)
{
return quadrant_p < quadrant_q;
}
// Same quadrant, check if p is located left of q
int const side = m_strategy.apply(m_origin, q.point, p.point);
if (side != 0)
{
return side == 1;
}
// Collinear, check if one is incoming, incoming angles come first
if (p.incoming != q.incoming)
{
return int(p.incoming) < int(q.incoming);
}
// Same quadrant/side/direction, return longest first
// TODO: maybe not necessary, decide this
int const length_p = squared_length(pv);
int const length_q = squared_length(qv);
if (length_p != length_q)
{
return squared_length(pv) > squared_length(qv);
}
// They are still the same. Just compare on seg_id
return p.seg_id < q.seg_id;
}
private:
Point m_origin;
SideStrategy m_strategy;
};
template <typename Point, typename SideStrategy>
struct angle_equal_to
{
typedef Point vector_type;
inline angle_equal_to(Point const& origin, SideStrategy const& strategy)
: m_origin(origin)
, m_strategy(strategy)
{}
template <typename Angle>
inline bool operator()(Angle const& p, Angle const& q) const
{
// Vector origin -> p and origin -> q
vector_type pv = p.point;
vector_type qv = q.point;
geometry::subtract_point(pv, m_origin);
geometry::subtract_point(qv, m_origin);
if (get_quadrant(pv) != get_quadrant(qv))
{
return false;
}
// Same quadrant, check if p/q are collinear
int const side = m_strategy.apply(m_origin, q.point, p.point);
return side == 0;
}
private:
Point m_origin;
SideStrategy m_strategy;
};
template <typename AngleCollection, typename Turns>
inline void get_left_turns(AngleCollection const& sorted_angles,
Turns& turns)
{
std::set<std::size_t> good_incoming;
std::set<std::size_t> good_outgoing;
for (typename boost::range_iterator<AngleCollection const>::type it =
sorted_angles.begin(); it != sorted_angles.end(); ++it)
{
if (!it->blocked)
{
if (it->incoming)
{
good_incoming.insert(it->turn_index);
}
else
{
good_outgoing.insert(it->turn_index);
}
}
}
if (good_incoming.empty() || good_outgoing.empty())
{
return;
}
for (typename boost::range_iterator<AngleCollection const>::type it =
sorted_angles.begin(); it != sorted_angles.end(); ++it)
{
if (good_incoming.count(it->turn_index) == 0
|| good_outgoing.count(it->turn_index) == 0)
{
turns[it->turn_index].remove_on_multi = true;
}
}
}
//! Returns the number of clusters
template <typename Point, typename AngleCollection, typename SideStrategy>
inline std::size_t assign_cluster_indices(AngleCollection& sorted, Point const& origin,
SideStrategy const& strategy)
{
// Assign same cluster_index for all turns in same direction
BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u);
angle_equal_to<Point, SideStrategy> comparator(origin, strategy);
typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
std::size_t cluster_index = 0;
it->cluster_index = cluster_index;
typename boost::range_iterator<AngleCollection>::type previous = it++;
for (; it != sorted.end(); ++it)
{
if (!comparator(*previous, *it))
{
cluster_index++;
previous = it;
}
it->cluster_index = cluster_index;
}
return cluster_index + 1;
}
template <typename AngleCollection>
inline void block_turns(AngleCollection& sorted, std::size_t cluster_size)
{
BOOST_GEOMETRY_ASSERT(boost::size(sorted) >= 4u && cluster_size > 0);
std::vector<std::pair<bool, bool> > directions;
for (std::size_t i = 0; i < cluster_size; i++)
{
directions.push_back(std::make_pair(false, false));
}
for (typename boost::range_iterator<AngleCollection const>::type it = sorted.begin();
it != sorted.end(); ++it)
{
if (it->incoming)
{
directions[it->cluster_index].first = true;
}
else
{
directions[it->cluster_index].second = true;
}
}
for (typename boost::range_iterator<AngleCollection>::type it = sorted.begin();
it != sorted.end(); ++it)
{
std::size_t const cluster_index = it->cluster_index;
std::size_t const previous_index
= cluster_index == 0 ? cluster_size - 1 : cluster_index - 1;
std::size_t const next_index
= cluster_index + 1 >= cluster_size ? 0 : cluster_index + 1;
if (directions[cluster_index].first
&& directions[cluster_index].second)
{
it->blocked = true;
}
else if (!directions[cluster_index].first
&& directions[cluster_index].second
&& directions[previous_index].second)
{
// Only outgoing, previous was also outgoing: block this one
it->blocked = true;
}
else if (directions[cluster_index].first
&& !directions[cluster_index].second
&& !directions[previous_index].first
&& directions[previous_index].second)
{
// Only incoming, previous was only outgoing: block this one
it->blocked = true;
}
else if (directions[cluster_index].first
&& !directions[cluster_index].second
&& directions[next_index].first
&& !directions[next_index].second)
{
// Only incoming, next also incoming, block this one
it->blocked = true;
}
}
}
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
template <typename AngleCollection, typename Point>
inline bool has_rounding_issues(AngleCollection const& angles, Point const& origin)
{
for (typename boost::range_iterator<AngleCollection const>::type it =
angles.begin(); it != angles.end(); ++it)
{
// Vector origin -> p and origin -> q
typedef Point vector_type;
vector_type v = it->point;
geometry::subtract_point(v, origin);
return geometry::math::abs(geometry::get<0>(v)) <= 1
|| geometry::math::abs(geometry::get<1>(v)) <= 1
;
}
return false;
}
#endif
} // namespace left_turns
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP

View File

@ -1,219 +0,0 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
#include <algorithm>
#include <boost/range.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
#include <boost/geometry/algorithms/detail/get_left_turns.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename Point, typename T>
struct angle_info
{
typedef T angle_type;
typedef Point point_type;
segment_identifier seg_id;
std::size_t turn_index;
int operation_index;
std::size_t cluster_index;
Point intersection_point;
Point point; // either incoming or outgoing point
bool incoming;
bool blocked;
bool included;
inline angle_info()
: blocked(false)
, included(false)
{}
};
template <typename AngleInfo>
class occupation_info
{
public :
typedef std::vector<AngleInfo> collection_type;
std::size_t count;
inline occupation_info()
: count(0)
{}
template <typename RobustPoint>
inline void add(RobustPoint const& incoming_point,
RobustPoint const& outgoing_point,
RobustPoint const& intersection_point,
std::size_t turn_index, int operation_index,
segment_identifier const& seg_id)
{
geometry::equal_to<RobustPoint> comparator;
if (comparator(incoming_point, intersection_point))
{
return;
}
if (comparator(outgoing_point, intersection_point))
{
return;
}
AngleInfo info;
info.seg_id = seg_id;
info.turn_index = turn_index;
info.operation_index = operation_index;
info.intersection_point = intersection_point;
{
info.point = incoming_point;
info.incoming = true;
m_angles.push_back(info);
}
{
info.point = outgoing_point;
info.incoming = false;
m_angles.push_back(info);
}
}
template <typename RobustPoint, typename Turns, typename SideStrategy>
inline void get_left_turns(RobustPoint const& origin, Turns& turns,
SideStrategy const& strategy)
{
typedef detail::left_turns::angle_less
<
typename AngleInfo::point_type,
SideStrategy
> angle_less;
// Sort on angle
std::sort(m_angles.begin(), m_angles.end(), angle_less(origin, strategy));
// Group same-angled elements
std::size_t cluster_size = detail::left_turns::assign_cluster_indices(m_angles, origin);
// Block all turns on the right side of any turn
detail::left_turns::block_turns(m_angles, cluster_size);
detail::left_turns::get_left_turns(m_angles, turns);
}
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
template <typename RobustPoint>
inline bool has_rounding_issues(RobustPoint const& origin) const
{
return detail::left_turns::has_rounding_issues(angles, origin);
}
#endif
private :
collection_type m_angles; // each turn splitted in incoming/outgoing vectors
};
template<typename Pieces>
inline void move_index(Pieces const& pieces, signed_size_type& index, signed_size_type& piece_index, int direction)
{
BOOST_GEOMETRY_ASSERT(direction == 1 || direction == -1);
BOOST_GEOMETRY_ASSERT(
piece_index >= 0
&& piece_index < static_cast<signed_size_type>(boost::size(pieces)) );
BOOST_GEOMETRY_ASSERT(
index >= 0
&& index < static_cast<signed_size_type>(boost::size(pieces[piece_index].robust_ring)));
// NOTE: both index and piece_index must be in valid range
// this means that then they could be of type std::size_t
// if the code below was refactored
index += direction;
if (direction == -1 && index < 0)
{
piece_index--;
if (piece_index < 0)
{
piece_index = boost::size(pieces) - 1;
}
index = boost::size(pieces[piece_index].robust_ring) - 1;
}
if (direction == 1
&& index >= static_cast<signed_size_type>(boost::size(pieces[piece_index].robust_ring)))
{
piece_index++;
if (piece_index >= static_cast<signed_size_type>(boost::size(pieces)))
{
piece_index = 0;
}
index = 0;
}
}
template
<
typename RobustPoint,
typename Turn,
typename Pieces,
typename Info
>
inline void add_incoming_and_outgoing_angles(
RobustPoint const& intersection_point, // rescaled
Turn const& turn,
Pieces const& pieces, // using rescaled offsets of it
int operation_index,
segment_identifier seg_id,
Info& info)
{
segment_identifier real_seg_id = seg_id;
geometry::equal_to<RobustPoint> comparator;
// Move backward and forward
RobustPoint direction_points[2];
for (int i = 0; i < 2; i++)
{
signed_size_type index = turn.operations[operation_index].index_in_robust_ring;
signed_size_type piece_index = turn.operations[operation_index].piece_index;
while(comparator(pieces[piece_index].robust_ring[index], intersection_point))
{
move_index(pieces, index, piece_index, i == 0 ? -1 : 1);
}
direction_points[i] = pieces[piece_index].robust_ring[index];
}
info.add(direction_points[0], direction_points[1], intersection_point,
turn.turn_index, operation_index, real_seg_id);
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP

View File

@ -99,6 +99,11 @@ inline bool overlaps(Geometry1 const& geometry1,
\return \return_check2{overlap}
\qbk{[include reference/algorithms/overlaps.qbk]}
\qbk{
[heading Examples]
[overlaps]
[overlaps_output]
}
*/
template <typename Geometry1, typename Geometry2>
inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)

View File

@ -26,7 +26,6 @@
#include <boost/range/value_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
namespace boost { namespace geometry

View File

@ -18,7 +18,6 @@
#include <boost/range/algorithm/reverse.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/core/tags.hpp>

View File

@ -14,6 +14,7 @@
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/arithmetic/infinite_line_functions.hpp>
#include <boost/geometry/algorithms/detail/make/make.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <cmath>

View File

@ -31,7 +31,6 @@
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/util/condition.hpp>

View File

@ -137,12 +137,7 @@ inline void get_ring_turn_info(TurnInfoMap& turn_info_map, Turns const& turns, C
++op_it)
{
turn_operation_type const& op = *op_it;
ring_identifier const ring_id
(
op.seg_id.source_index,
op.seg_id.multi_index,
op.seg_id.ring_index
);
ring_identifier const ring_id = ring_id_by_seg_id(op.seg_id);
if (! is_self_turn<OverlayType>(turn)
&& (

View File

@ -20,6 +20,7 @@
#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
namespace boost { namespace geometry
@ -95,7 +96,18 @@ struct segment_identifier
signed_size_type piece_index;
};
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace overlay
{
// Create a ring identifier from a segment identifier
inline ring_identifier ring_id_by_seg_id(segment_identifier const& seg_id)
{
return ring_identifier(seg_id.source_index, seg_id.multi_index, seg_id.ring_index);
}
}} // namespace detail::overlay
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry

View File

@ -148,12 +148,7 @@ public :
|| op.visited.started()
|| op.visited.finished() )
{
ring_identifier const ring_id
(
op.seg_id.source_index,
op.seg_id.multi_index,
op.seg_id.ring_index
);
ring_identifier const ring_id = ring_id_by_seg_id(op.seg_id);
turn_info_map[ring_id].has_traversed_turn = true;
if (op.operation == operation_continue)
@ -162,11 +157,7 @@ public :
// as traversed too
turn_operation_type& other_op = turn.operations[1 - i];
ring_identifier const other_ring_id
(
other_op.seg_id.source_index,
other_op.seg_id.multi_index,
other_op.seg_id.ring_index
);
= ring_id_by_seg_id(other_op.seg_id);
turn_info_map[other_ring_id].has_traversed_turn = true;
}
}

View File

@ -35,12 +35,6 @@ namespace boost { namespace geometry
namespace detail { namespace overlay
{
// Generic function (is this used somewhere else too?)
inline ring_identifier ring_id_by_seg_id(segment_identifier const& seg_id)
{
return ring_identifier(seg_id.source_index, seg_id.multi_index, seg_id.ring_index);
}
template
<
bool Reverse1,

View File

@ -261,6 +261,11 @@ struct self_touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
\qbk{distinguish,one geometry}
\qbk{[def __one_parameter__]}
\qbk{[include reference/algorithms/touches.qbk]}
\qbk{
[heading Examples]
[touches_one_geometry]
[touches_one_geometry_output]
}
*/
template <typename Geometry>
inline bool touches(Geometry const& geometry)
@ -280,6 +285,11 @@ inline bool touches(Geometry const& geometry)
\qbk{distinguish,two geometries}
\qbk{[include reference/algorithms/touches.qbk]}
\qbk{
[heading Examples]
[touches_two_geometries]
[touches_two_geometries_output]
}
*/
template <typename Geometry1, typename Geometry2>
inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)

View File

@ -38,8 +38,6 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/order_as_direction.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/algorithms/detail/within/multi_point.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>

View File

@ -192,6 +192,11 @@ struct perimeter<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
\return \return_calc{perimeter}
\qbk{[include reference/algorithms/perimeter.qbk]}
\qbk{
[heading Example]
[perimeter]
[perimeter_output]
}
*/
template<typename Geometry>
inline typename default_length_result<Geometry>::type perimeter(

View File

@ -90,7 +90,8 @@ struct cross_product<3>
\param p1 first vector
\param p2 second vector
\return the cross product vector
*/
*/
template <typename ResultP, typename P1, typename P2>
inline ResultP cross_product(P1 const& p1, P2 const& p2)
{
@ -110,6 +111,9 @@ inline ResultP cross_product(P1 const& p1, P2 const& p2)
\param p1 first vector
\param p2 second vector
\return the cross product vector
\qbk{[heading Examples]}
\qbk{[cross_product] [cross_product_output]}
*/
template <typename P>
inline P cross_product(P const& p1, P const& p2)

View File

@ -64,6 +64,10 @@ struct dot_product_maker<P1, P2, DimensionCount, DimensionCount>
\param p1 first point
\param p2 second point
\return the dot product
\qbk{[heading Examples]}
\qbk{[dot_product] [dot_product_output]}
*/
template <typename Point1, typename Point2>
inline typename select_coordinate_type<Point1, Point2>::type dot_product(

View File

@ -2,7 +2,7 @@
// Copyright (c) 2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2015-2017 Oracle and/or its affiliates.
// Copyright (c) 2015-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -106,7 +106,8 @@ public:
CT const one_minus_cos_d = c1 - cos_d;
CT const one_plus_cos_d = c1 + cos_d;
// cos_d = 1 or cos_d = -1 means that the points are antipodal
// cos_d = 1 means that the points are very close
// cos_d = -1 means that the points are antipodal
CT const H = math::equals(one_minus_cos_d, c0) ?
c0 :
@ -124,7 +125,7 @@ public:
if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) )
{
// sin_d = 0 <=> antipodal points (incl. poles)
// sin_d = 0 <=> antipodal points (incl. poles) or very close
if (math::equals(sin_d, c0))
{
// T = inf
@ -140,16 +141,26 @@ public:
// The most correct way of fixing it is to handle antipodal regions
// correctly and consistently across all formulas.
// Set azimuth to 0 unless the first endpoint is the north pole
if (! math::equals(sin_lat1, c1))
// points very close
if (cos_d >= c0)
{
result.azimuth = c0;
result.reverse_azimuth = pi;
result.reverse_azimuth = c0;
}
// antipodal points
else
{
result.azimuth = pi;
result.reverse_azimuth = 0;
// Set azimuth to 0 unless the first endpoint is the north pole
if (! math::equals(sin_lat1, c1))
{
result.azimuth = c0;
result.reverse_azimuth = pi;
}
else
{
result.azimuth = pi;
result.reverse_azimuth = c0;
}
}
}
else

View File

@ -97,24 +97,6 @@ class karney_inverse
public:
typedef result_inverse<CT> result_type;
static CT constexpr c0 = 0;
static CT constexpr c0_001 = 0.001;
static CT constexpr c0_01 = 0.01;
static CT constexpr c0_1 = 0.1;
static CT constexpr c0_5 = 0.5;
static CT constexpr c1 = 1;
static CT constexpr c2 = 2;
static CT constexpr c3 = 3;
static CT constexpr c4 = 4;
static CT constexpr c6 = 6;
static CT constexpr c8 = 8;
static CT constexpr c10 = 10;
static CT constexpr c16 = 16;
static CT constexpr c20 = 20;
static CT constexpr c90 = 90;
static CT constexpr c180 = 180;
static CT constexpr c200 = 200;
static CT constexpr c1000 = 1000;
template <typename T1, typename T2, typename Spheroid>
static inline result_type apply(T1 const& lo1,
@ -123,6 +105,21 @@ public:
T2 const& la2,
Spheroid const& spheroid)
{
static CT const c0 = 0;
static CT const c0_001 = 0.001;
static CT const c0_1 = 0.1;
static CT const c1 = 1;
static CT const c2 = 2;
static CT const c3 = 3;
static CT const c8 = 8;
static CT const c16 = 16;
static CT const c90 = 90;
static CT const c180 = 180;
static CT const c200 = 200;
static CT const pi = math::pi<CT>();
static CT const d2r = math::d2r<CT>();
static CT const r2d = math::r2d<CT>();
result_type result;
CT lat1 = la1;
@ -145,7 +142,7 @@ public:
CT const tol_bisection = tol0 * tol2;
CT const etol2 = c0_1 * tol2 /
sqrt((std::max)(CT(0.001), std::abs(f)) * (std::min)(CT(1), CT(1) - f / CT(2)) / c2);
sqrt((std::max)(c0_001, std::abs(f)) * (std::min)(c1, c1 - f / c2) / c2);
CT tiny = std::sqrt((std::numeric_limits<CT>::min)());
@ -164,7 +161,7 @@ public:
lon12_error = (c180 - lon12) - lon12_sign * lon12_error;
// Convert to radians.
CT lam12 = lon12 * math::d2r<CT>();
CT lam12 = lon12 * d2r;
CT sin_lam12;
CT cos_lam12;
@ -268,8 +265,8 @@ public:
CT sin_sigma2 = sin_beta2;
CT cos_sigma2 = cos_alpha2 * cos_beta2;
CT sigma12 = std::atan2((std::max)(CT(0), cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2),
cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2);
CT sigma12 = std::atan2((std::max)(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2),
cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2);
CT dummy;
meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1,
@ -401,7 +398,7 @@ public:
CT nsin_alpha1 = sin_alpha1 * cos_diff_alpha1 +
cos_alpha1 * sin_diff_alpha1;
if (nsin_alpha1 > c0 && std::abs(diff_alpha1) < math::pi<CT>())
if (nsin_alpha1 > c0 && std::abs(diff_alpha1) < pi)
{
cos_alpha1 = cos_alpha1 * cos_diff_alpha1 - sin_alpha1 * sin_diff_alpha1;
sin_alpha1 = nsin_alpha1;
@ -468,12 +465,12 @@ public:
{
if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth))
{
result.azimuth = atan2(sin_alpha1, cos_alpha1) * math::r2d<CT>();
result.azimuth = atan2(sin_alpha1, cos_alpha1) * r2d;
}
if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth))
{
result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2) * math::r2d<CT>();
result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2) * r2d;
}
}
@ -486,14 +483,16 @@ public:
}
template <typename CoeffsC1>
static inline void meridian_length(CT epsilon, CT ep2, CT sigma12,
CT sin_sigma1, CT cos_sigma1, CT dn1,
CT sin_sigma2, CT cos_sigma2, CT dn2,
CT cos_beta1, CT cos_beta2,
static inline void meridian_length(CT const& epsilon, CT const& ep2, CT const& sigma12,
CT const& sin_sigma1, CT const& cos_sigma1, CT const& dn1,
CT const& sin_sigma2, CT const& cos_sigma2, CT const& dn2,
CT const& cos_beta1, CT const& cos_beta2,
CT& s12x, CT& m12x, CT& m0,
CT& M12, CT& M21,
CoeffsC1 coeffs_C1)
CoeffsC1 const& coeffs_C1)
{
static CT const c1 = 1;
CT A12x = 0, J12 = 0;
CT expansion_A1, expansion_A2;
@ -578,14 +577,24 @@ public:
cos_alpha2 and function value is sig12.
*/
template <typename CoeffsC1>
static inline CT newton_start(CT sin_beta1, CT cos_beta1, CT dn1,
CT sin_beta2, CT cos_beta2, CT dn2,
CT lam12, CT sin_lam12, CT cos_lam12,
static inline CT newton_start(CT const& sin_beta1, CT const& cos_beta1, CT const& dn1,
CT const& sin_beta2, CT const& cos_beta2, CT dn2,
CT const& lam12, CT const& sin_lam12, CT const& cos_lam12,
CT& sin_alpha1, CT& cos_alpha1,
CT& sin_alpha2, CT& cos_alpha2,
CT& dnm, CoeffsC1 coeffs_C1, CT ep2,
CT tol1, CT tol2, CT etol2, CT n, CT f)
CT& dnm, CoeffsC1 const& coeffs_C1, CT const& ep2,
CT const& tol1, CT const& tol2, CT const& etol2, CT const& n, CT const& f)
{
static CT const c0 = 0;
static CT const c0_01 = 0.01;
static CT const c0_1 = 0.1;
static CT const c0_5 = 0.5;
static CT const c1 = 1;
static CT const c2 = 2;
static CT const c6 = 6;
static CT const c1000 = 1000;
static CT const pi = math::pi<CT>();
CT const one_minus_f = c1 - f;
CT const x_thresh = c1000 * tol2;
@ -646,7 +655,7 @@ public:
// Skip astroid calculation if too eccentric.
else if (std::abs(n) > c0_1 ||
cos_sigma12 >= c0 ||
sin_sigma12 >= c6 * std::abs(n) * math::pi<CT>() *
sin_sigma12 >= c6 * std::abs(n) * pi *
math::sqr(cos_beta1))
{
// Nothing to do, zeroth order spherical approximation will do.
@ -670,7 +679,7 @@ public:
CT const A3 = math::horner_evaluate(eps, coeffs_A3.begin(), coeffs_A3.end());
lambda_scale = f * cos_beta1 * A3 * math::pi<CT>();
lambda_scale = f * cos_beta1 * A3 * pi;
beta_scale = lambda_scale * cos_beta1;
x = lam12x / lambda_scale;
@ -682,15 +691,16 @@ public:
CT beta12a = atan2(sin_beta12a, cos_beta12a);
CT m12b, m0, dummy;
meridian_length(n, ep2, math::pi<CT>() + beta12a,
meridian_length(n, ep2, pi + beta12a,
sin_beta1, -cos_beta1, dn1,
sin_beta2, cos_beta2, dn2,
cos_beta1, cos_beta2, dummy,
m12b, m0, dummy, dummy, coeffs_C1);
x = -c1 + m12b / (cos_beta1 * cos_beta2 * m0 * math::pi<CT>());
beta_scale = x < -c0_01 ? sin_beta12a / x :
-f * math::sqr(cos_beta1) * math::pi<CT>();
x = -c1 + m12b / (cos_beta1 * cos_beta2 * m0 * pi);
beta_scale = x < -c0_01
? sin_beta12a / x
: -f * math::sqr(cos_beta1) * pi;
lambda_scale = beta_scale / cos_beta1;
y = lam12x / lambda_scale;
@ -701,7 +711,7 @@ public:
// Strip near cut.
if (f >= c0)
{
sin_alpha1 = (std::min)(CT(1), -CT(x));
sin_alpha1 = (std::min)(c1, -CT(x));
cos_alpha1 = - math::sqrt(c1 - math::sqr(sin_alpha1));
}
else
@ -713,7 +723,7 @@ public:
else
{
// Solve the astroid problem.
CT k = astroid(x, y);
CT k = astroid(CT(x), y);
CT omega12a = lambda_scale * (f >= c0 ? -x * k /
(c1 + k) : -y * (c1 + k) / k);
@ -750,8 +760,15 @@ public:
Geodesics on an ellipsoid of revolution, Charles F.F Karney,
https://arxiv.org/abs/1102.1215
*/
static inline CT astroid(CT x, CT y)
static inline CT astroid(CT const& x, CT const& y)
{
static CT const c0 = 0;
static CT const c1 = 1;
static CT const c2 = 2;
static CT const c3 = 3;
static CT const c4 = 4;
static CT const c6 = 6;
CT k;
CT p = math::sqr(x);
@ -815,19 +832,23 @@ public:
}
template <typename CoeffsC1>
static inline CT lambda12(CT sin_beta1, CT cos_beta1, CT dn1,
CT sin_beta2, CT cos_beta2, CT dn2,
CT sin_alpha1, CT cos_alpha1,
CT sin_lam120, CT cos_lam120,
static inline CT lambda12(CT const& sin_beta1, CT const& cos_beta1, CT const& dn1,
CT const& sin_beta2, CT const& cos_beta2, CT const& dn2,
CT const& sin_alpha1, CT cos_alpha1,
CT const& sin_lam120, CT const& cos_lam120,
CT& sin_alpha2, CT& cos_alpha2,
CT& sigma12,
CT& sin_sigma1, CT& cos_sigma1,
CT& sin_sigma2, CT& cos_sigma2,
CT& eps, CT& diff_omega12,
bool diffp, CT& diff_lam12,
CT f, CT n, CT ep2, CT tiny,
CoeffsC1 coeffs_C1)
CT const& f, CT const& n, CT const& ep2, CT const& tiny,
CoeffsC1 const& coeffs_C1)
{
static CT const c0 = 0;
static CT const c1 = 1;
static CT const c2 = 2;
CT const one_minus_f = c1 - f;
if (sin_beta1 == c0 && cos_alpha1 == c0)
@ -878,11 +899,11 @@ public:
// sig12 = sig2 - sig1, limit to [0, pi].
sigma12 = atan2((std::max)(CT(0), cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2),
sigma12 = atan2((std::max)(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2),
cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2);
// omg12 = omg2 - omg1, limit to [0, pi].
sin_omega12 = (std::max)(CT(0), cos_omega1 * sin_omega2 - sin_omega1 * cos_omega2);
sin_omega12 = (std::max)(c0, cos_omega1 * sin_omega2 - sin_omega1 * cos_omega2);
cos_omega12 = cos_omega1 * cos_omega2 + sin_omega1 * sin_omega2;
// eta = omg12 - lam120.

View File

@ -0,0 +1,137 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2020 Digvijay Janartha, Hamirpur, 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)
#ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_XYZ_HPP
#define BOOST_GEOMETRY_GEOMETRIES_POINT_XYZ_HPP
#include <cstddef>
#include <boost/config.hpp>
#include <boost/mpl/int.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/geometries/point.hpp>
namespace boost { namespace geometry
{
namespace model { namespace d3
{
/*!
\brief 3D point in Cartesian coordinate system
\tparam CoordinateType numeric type, for example, double, float, int
\tparam CoordinateSystem coordinate system, defaults to cs::cartesian
\qbk{[include reference/geometries/point_xyz.qbk]}
\qbk{before.synopsis,
[heading Model of]
[link geometry.reference.concepts.concept_point Point Concept]
}
\qbk{[include reference/geometries/point_assign_warning.qbk]}
*/
template<typename CoordinateType, typename CoordinateSystem = cs::cartesian>
class point_xyz : public model::point<CoordinateType, 3, CoordinateSystem>
{
public:
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
/// \constructor_default_no_init
point_xyz() = default;
#else
/// \constructor_default_no_init
inline point_xyz()
{}
#endif
/// Constructor with x/y/z values
inline point_xyz(CoordinateType const& x, CoordinateType const& y, CoordinateType const& z)
: model::point<CoordinateType, 3, CoordinateSystem>(x, y, z)
{}
/// Get x-value
inline CoordinateType const& x() const
{ return this->template get<0>(); }
/// Get y-value
inline CoordinateType const& y() const
{ return this->template get<1>(); }
/// Get z-value
inline CoordinateType const& z() const
{ return this->template get<2>(); }
/// Set x-value
inline void x(CoordinateType const& v)
{ this->template set<0>(v); }
/// Set y-value
inline void y(CoordinateType const& v)
{ this->template set<1>(v); }
/// Set z-value
inline void z(CoordinateType const& v)
{ this->template set<2>(v); }
};
}} // namespace model::d3
// Adapt the point_xyz to the concept
#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
namespace traits
{
template <typename CoordinateType, typename CoordinateSystem>
struct tag<model::d3::point_xyz<CoordinateType, CoordinateSystem> >
{
typedef point_tag type;
};
template<typename CoordinateType, typename CoordinateSystem>
struct coordinate_type<model::d3::point_xyz<CoordinateType, CoordinateSystem> >
{
typedef CoordinateType type;
};
template<typename CoordinateType, typename CoordinateSystem>
struct coordinate_system<model::d3::point_xyz<CoordinateType, CoordinateSystem> >
{
typedef CoordinateSystem type;
};
template<typename CoordinateType, typename CoordinateSystem>
struct dimension<model::d3::point_xyz<CoordinateType, CoordinateSystem> >
: boost::mpl::int_<3>
{};
template<typename CoordinateType, typename CoordinateSystem, std::size_t Dimension>
struct access<model::d3::point_xyz<CoordinateType, CoordinateSystem>, Dimension >
{
static inline CoordinateType get(
model::d3::point_xyz<CoordinateType, CoordinateSystem> const& p)
{
return p.template get<Dimension>();
}
static inline void set(model::d3::point_xyz<CoordinateType, CoordinateSystem>& p,
CoordinateType const& value)
{
p.template set<Dimension>(value);
}
};
} // namespace traits
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_GEOMETRIES_POINT_XYZ_HPP

View File

@ -322,28 +322,31 @@ inline void pick_seeds(Elements const& elements,
// from void split_node(node_pointer const& n, node_pointer& n1, node_pointer& n2) const
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, linear_tag>
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
template <typename Node>
static inline void apply(Node & n,
Node & second_node,
Box & box1,
Box & box2,
box_type & box1,
box_type & box2,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
@ -414,8 +417,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
else
{
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
box_type enlarged_box1(box1);
box_type enlarged_box2(box2);
index::detail::expand(enlarged_box1, indexable, strategy);
index::detail::expand(enlarged_box2, indexable, strategy);
content_type enlarged_content1 = index::detail::content(enlarged_box1);
@ -452,7 +455,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_copy, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_copy, allocators);
//elements_copy.clear();
BOOST_RETHROW // RETHROW, BASIC

View File

@ -31,10 +31,9 @@
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
@ -102,41 +101,47 @@ inline Box values_box(FwdIter first, FwdIter last, Translator const& tr,
}
// destroys subtree if the element is internal node's element
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
struct destroy_element
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
inline static void apply(typename internal_node::elements_type::value_type & element,
allocators_type & allocators)
{
subtree_destroyer dummy(element.second, allocators);
detail::rtree::visitors::destroy<MembersHolder>::apply(element.second, allocators);
element.second = 0;
}
inline static void apply(typename leaf::elements_type::value_type &, Allocators &) {}
inline static void apply(typename leaf::elements_type::value_type &,
allocators_type &)
{}
};
// destroys stored subtrees if internal node's elements are passed
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
struct destroy_elements
{
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::allocators_type allocators_type;
template <typename Range>
inline static void apply(Range & elements, Allocators & allocators)
inline static void apply(Range & elements, allocators_type & allocators)
{
apply(boost::begin(elements), boost::end(elements), allocators);
}
template <typename It>
inline static void apply(It first, It last, Allocators & allocators)
inline static void apply(It first, It last, allocators_type & allocators)
{
typedef boost::mpl::bool_<
boost::is_same<
Value, typename std::iterator_traits<It>::value_type
value_type, typename std::iterator_traits<It>::value_type
>::value
> is_range_of_values;
@ -145,37 +150,38 @@ struct destroy_elements
private:
template <typename It>
inline static void apply_dispatch(It first, It last, Allocators & allocators,
inline static void apply_dispatch(It first, It last, allocators_type & allocators,
boost::mpl::bool_<false> const& /*is_range_of_values*/)
{
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
for ( ; first != last ; ++first )
{
subtree_destroyer dummy(first->second, allocators);
detail::rtree::visitors::destroy<MembersHolder>::apply(first->second, allocators);
first->second = 0;
}
}
template <typename It>
inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/,
inline static void apply_dispatch(It /*first*/, It /*last*/, allocators_type & /*allocators*/,
boost::mpl::bool_<true> const& /*is_range_of_values*/)
{}
};
// clears node, deletes all subtrees stored in node
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
/*
template <typename MembersHolder>
struct clear_node
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline static void apply(node & node, Allocators & allocators)
inline static void apply(node & node, allocators_type & allocators)
{
rtree::visitors::is_leaf<Value, Options, Box, Allocators> ilv;
rtree::visitors::is_leaf<MembersHolder> ilv;
rtree::apply_visitor(ilv, node);
if ( ilv.result )
{
@ -187,17 +193,18 @@ struct clear_node
}
}
inline static void apply(internal_node & internal_node, Allocators & allocators)
inline static void apply(internal_node & internal_node, allocators_type & allocators)
{
destroy_elements<Value, Options, Translator, Box, Allocators>::apply(rtree::elements(internal_node), allocators);
destroy_elements<MembersHolder>::apply(rtree::elements(internal_node), allocators);
rtree::elements(internal_node).clear();
}
inline static void apply(leaf & leaf, Allocators &)
inline static void apply(leaf & leaf, allocators_type &)
{
rtree::elements(leaf).clear();
}
};
*/
template <typename Container, typename Iterator>
void move_from_back(Container & container, Iterator it)

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