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 INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain Jamfile text svneol=native#text/plain
Jamroot 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 Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain Makefile* text svneol=native#text/plain
README 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 ### Test results
@ | Build | Coverage | Regression Branch | Build | Coverage | Regression | Documentation
------------|---------------|----------------|------------ ------------|---------------|----------------|------------|--------------
**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) <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)
**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) **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 ### Directories

View File

@ -31,7 +31,7 @@ explicit make_qbk ;
boostbook geometry boostbook geometry
: geometry.qbk : geometry.qbk
: <dependency>Jamfile.v2 : <dependency>Jamfile
<dependency>quickref.xml <dependency>quickref.xml
# <dependency>generated/point.qbk # <dependency>generated/point.qbk
<xsl:param>chunk.section.depth=4 <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 __boost_geometry__ uses __boost_bb__, a text-based system for developing and
testing software, to configure, build and execute unit tests and example 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. files.
For gcc, flag [^-Wno-long-long] can be used to surpress some warnings 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 SEARCH_INCLUDES = YES
INCLUDE_PATH = INCLUDE_PATH =
INCLUDE_FILE_PATTERNS = INCLUDE_FILE_PATTERNS =
PREDEFINED = BOOST_CONCEPT_REQUIRES(x)= \ PREDEFINED = BOOST_CONCEPT_REQUIRES(x) \
BOOST_CONCEPT_ASSERT(x) = \ BOOST_CONCEPT_ASSERT(x) \
BOOST_STATIC_ASSERT(x) = \ BOOST_STATIC_ASSERT(x) \
DOXYGEN_SHOULD_SKIP_THIS \ DOXYGEN_SHOULD_SKIP_THIS \
DOXYGEN_NO_DISPATCH \ DOXYGEN_NO_DISPATCH \
DOXYGEN_NO_IMPL \ 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/convert.cpp]
[import src/examples/algorithms/convex_hull.cpp] [import src/examples/algorithms/convex_hull.cpp]
[import src/examples/algorithms/correct.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.cpp]
[import src/examples/algorithms/densify_strategy.cpp] [import src/examples/algorithms/densify_strategy.cpp]
[import src/examples/algorithms/discrete_frechet_distance.cpp] [import src/examples/algorithms/discrete_frechet_distance.cpp]
[import src/examples/algorithms/discrete_frechet_distance_strategy.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.cpp]
[import src/examples/algorithms/discrete_hausdorff_distance_strategy.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/distance.cpp]
[import src/examples/algorithms/difference.cpp] [import src/examples/algorithms/difference.cpp]
[import src/examples/algorithms/envelope.cpp] [import src/examples/algorithms/envelope.cpp]
@ -66,18 +69,25 @@
[import src/examples/algorithms/num_interior_rings.cpp] [import src/examples/algorithms/num_interior_rings.cpp]
[import src/examples/algorithms/num_points.cpp] [import src/examples/algorithms/num_points.cpp]
[import src/examples/algorithms/num_segments.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/relate.cpp]
[import src/examples/algorithms/relation.cpp] [import src/examples/algorithms/relation.cpp]
[import src/examples/algorithms/reverse.cpp] [import src/examples/algorithms/reverse.cpp]
[import src/examples/algorithms/return_envelope.cpp] [import src/examples/algorithms/return_envelope.cpp]
[import src/examples/algorithms/simplify.cpp] [import src/examples/algorithms/simplify.cpp]
[import src/examples/algorithms/sym_difference.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.cpp]
[import src/examples/algorithms/transform_with_strategy.cpp] [import src/examples/algorithms/transform_with_strategy.cpp]
[import src/examples/algorithms/union.cpp] [import src/examples/algorithms/union.cpp]
[import src/examples/algorithms/unique.cpp] [import src/examples/algorithms/unique.cpp]
[import src/examples/algorithms/within.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_type.cpp]
[import src/examples/core/coordinate_system.cpp] [import src/examples/core/coordinate_system.cpp]
[import src/examples/core/coordinate_dimension.cpp] [import src/examples/core/coordinate_dimension.cpp]
@ -103,6 +113,7 @@
[import src/examples/geometries/multi_point.cpp] [import src/examples/geometries/multi_point.cpp]
[import src/examples/geometries/multi_polygon.cpp] [import src/examples/geometries/multi_polygon.cpp]
[import src/examples/geometries/point_xy.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/point.cpp]
[import src/examples/geometries/polygon.cpp] [import src/examples/geometries/polygon.cpp]
[import src/examples/geometries/ring.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 index.qbk
: :
<dependency>Jamfile.v2 <dependency>Jamfile
<dependency>generated/rtree.qbk <dependency>generated/rtree.qbk
<format>html <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" , "relation", "reverse","simplify", "sym_difference", "touches"
, "transform", "union", "unique", "within"] , "transform", "union", "unique", "within"]
arithmetic = ["cross_product"]
access_functions = ["get", "set", "exterior_ring", "interior_rings" access_functions = ["get", "set", "exterior_ring", "interior_rings"
, "num_points", "num_interior_rings", "num_geometries"] , "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("d2_1_1point__xy", "point_xy")
model_to_quickbook2("d3_1_1point__xyz", "point_xyz")
group_to_quickbook("arithmetic") group_to_quickbook("arithmetic")
group_to_quickbook("dsv") group_to_quickbook("dsv")

View File

@ -87,6 +87,7 @@
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="geometry.reference.models.model_point">point</link></member> <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_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> <member><link linkend="geometry.reference.models.model_multi_point">multi_point</link></member>
</simplelist> </simplelist>
</entry> </entry>

View File

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

View File

@ -13,6 +13,3 @@
[heading Examples] [heading Examples]
[point_xy] [point_xy]
[point_xy_output] [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 boostbook fruit
: fruit.qbk : fruit.qbk
: <dependency>Jamfile.v2 : <dependency>Jamfile
<dependency>generated/apple.qbk <dependency>generated/apple.qbk
<dependency>generated/rose.qbk <dependency>generated/rose.qbk
<dependency>generated/grouped.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 linestring : linestring.cpp ;
exe point : point.cpp ; exe point : point.cpp ;
exe point_xy : point_xy.cpp ; exe point_xy : point_xy.cpp ;
exe point_xyz : point_xyz.cpp ;
exe polygon : polygon.cpp ; exe polygon : polygon.cpp ;
exe multi_linestring : multi_linestring.cpp ; exe multi_linestring : multi_linestring.cpp ;
exe multi_point : multi_point.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} \return \return_check2{crosses}
\qbk{[include reference/algorithms/crosses.qbk]} \qbk{[include reference/algorithms/crosses.qbk]}
\qbk{
[heading Examples]
[crosses]
[crosses_output]
}
*/ */
template <typename Geometry1, typename Geometry2> template <typename Geometry1, typename Geometry2>
inline bool crosses(Geometry1 const& geometry1, Geometry2 const& 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, collection, distance,
side_strategy, join_strategy, end_strategy, point_strategy, side_strategy, join_strategy, end_strategy, point_strategy,
robust_policy, strategy); robust_policy, strategy);
collection.finish_ring(code); collection.finish_ring(code, ring, false, false);
return code; return code;
} }
}; };
@ -810,7 +810,7 @@ private:
join_strategy, end_strategy, point_strategy, join_strategy, end_strategy, point_strategy,
robust_policy, 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, join_strategy, end_strategy, point_strategy,
robust_policy, strategy); robust_policy, strategy);
collection.finish_ring(code, false, collection.finish_ring(code, exterior_ring(polygon), false,
geometry::num_interior_rings(polygon) > 0u); 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, typename geometry::ring_type<GeometryOutput>::type,
IntersectionStrategy, IntersectionStrategy,
DistanceStrategy,
RobustPolicy RobustPolicy
> collection_type; > collection_type;
collection_type collection(intersection_strategy, robust_policy); collection_type collection(intersection_strategy, distance_strategy, robust_policy);
collection_type const& const_collection = collection; collection_type const& const_collection = collection;
bool const areal = boost::is_same bool const areal = boost::is_same
@ -972,11 +973,11 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
end_strategy, point_strategy, end_strategy, point_strategy,
robust_policy, intersection_strategy.get_side_strategy()); robust_policy, intersection_strategy.get_side_strategy());
collection.get_turns(distance_strategy); collection.get_turns();
collection.classify_turns(); collection.classify_turns();
if (BOOST_GEOMETRY_CONDITION(areal)) 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 // 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 std::size_t turn_index; // TODO: this might go if partition can operate on non-const input
RobustPoint robust_point; 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 inline RobustPoint const& get_robust_point() const
{ {
#if defined(BOOST_GEOMETRY_BUFFER_ENLARGED_CLUSTERS)
return mapped_robust_point;
#endif
return robust_point; return robust_point;
} }
@ -183,32 +175,21 @@ struct buffer_turn_info
std::size_t count_within; std::size_t count_within;
bool within_original; 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 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_offsetted;
std::size_t count_on_helper; std::size_t count_on_helper;
std::size_t count_within_near_offsetted; 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() inline buffer_turn_info()
: turn_index(0) : turn_index(0)
, location(location_ok) , location(location_ok)
, count_within(0) , count_within(0)
, within_original(false) , within_original(false)
, count_on_original_boundary(0)
, count_in_original(0) , count_in_original(0)
, count_on_offsetted(0) , count_on_offsetted(0)
, count_on_helper(0) , count_on_helper(0)
, count_within_near_offsetted(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/buffered_ring.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp> #include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
#include <boost/geometry/algorithms/detail/overlay/cluster_info.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/get_piece_turns.hpp>
#include <boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp> #include <boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp>
#include <boost/geometry/algorithms/detail/buffer/turn_in_original_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/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/traverse.hpp> #include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.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/partition.hpp>
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp> #include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
#include <boost/geometry/algorithms/detail/sections/section_box_policies.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> #include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
{ {
@ -67,13 +67,6 @@ namespace boost { namespace geometry
namespace detail { namespace buffer namespace detail { namespace buffer
{ {
enum segment_relation_code
{
segment_relation_on_left,
segment_relation_on_right,
segment_relation_within,
segment_relation_disjoint
};
/* /*
* Terminology * 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 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::point_type<Ring>::type point_type;
typedef typename geometry::coordinate_type<Ring>::type coordinate_type; typedef typename geometry::coordinate_type<Ring>::type coordinate_type;
typedef typename geometry::robust_point_type typedef typename geometry::robust_point_type
@ -250,8 +244,6 @@ struct buffered_piece_collection
robust_box_type robust_envelope; robust_box_type robust_envelope;
robust_box_type robust_offsetted_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_point_type robust_center;
robust_comparable_radius_type robust_min_comparable_radius; robust_comparable_radius_type robust_min_comparable_radius;
robust_comparable_radius_type robust_max_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; typedef geometry::sections<robust_box_type, 1> sections_type;
inline robust_original() // Creates an empty instance
inline original_ring()
: m_is_interior(false) : 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, bool is_interior, bool has_interiors,
envelope_strategy_type const& envelope_strategy, envelope_strategy_type const& envelope_strategy,
expand_strategy_type const& expand_strategy) expand_strategy_type const& expand_strategy)
@ -323,9 +315,11 @@ struct buffered_piece_collection
bool m_deflate; bool m_deflate;
bool m_has_deflated; bool m_has_deflated;
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; // indexed by multi_index // Offsetted rings, and representations of original ring(s)
std::vector<robust_original> robust_originals; // robust representation of the original(s) // both indexed by multi_index
robust_ring_type current_robust_ring; buffered_ring_collection<buffered_ring<Ring> > offsetted_rings;
std::vector<original_ring> original_rings;
buffered_ring_collection<Ring> traversed_rings; buffered_ring_collection<Ring> traversed_rings;
segment_identifier current_segment_id; segment_identifier current_segment_id;
@ -344,6 +338,7 @@ struct buffered_piece_collection
cluster_type m_clusters; cluster_type m_clusters;
IntersectionStrategy m_intersection_strategy; IntersectionStrategy m_intersection_strategy;
DistanceStrategy m_distance_strategy;
side_strategy_type m_side_strategy; side_strategy_type m_side_strategy;
area_strategy_type m_area_strategy; area_strategy_type m_area_strategy;
envelope_strategy_type m_envelope_strategy; envelope_strategy_type m_envelope_strategy;
@ -353,20 +348,14 @@ struct buffered_piece_collection
robust_area_strategy_type m_robust_area_strategy; robust_area_strategy_type m_robust_area_strategy;
RobustPolicy const& m_robust_policy; 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, buffered_piece_collection(IntersectionStrategy const& intersection_strategy,
DistanceStrategy const& distance_strategy,
RobustPolicy const& robust_policy) RobustPolicy const& robust_policy)
: m_first_piece_index(-1) : m_first_piece_index(-1)
, m_deflate(false) , m_deflate(false)
, m_has_deflated(false) , m_has_deflated(false)
, m_intersection_strategy(intersection_strategy) , m_intersection_strategy(intersection_strategy)
, m_distance_strategy(distance_strategy)
, m_side_strategy(intersection_strategy.get_side_strategy()) , m_side_strategy(intersection_strategy.get_side_strategy())
, m_area_strategy(intersection_strategy , m_area_strategy(intersection_strategy
.template get_area_strategy<point_type>()) .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() inline void classify_turns()
{ {
for (typename boost::range_iterator<turn_vector_type>::type it = 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()
inline void check_remaining_points(DistanceStrategy const& distance_strategy)
{ {
// Check if a turn is inside any of the originals // Check if a turn is inside any of the originals
@ -671,11 +502,11 @@ struct buffered_piece_collection
robust_box_type, robust_box_type,
include_turn_policy, include_turn_policy,
detail::partition::include_all_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(), turn_get_box(), turn_in_original_ovelaps_box_type(),
original_get_box(), 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 = for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++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 inline void update_turn_administration()
{
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()
{ {
// Add rescaled turn points to corresponding pieces // Add rescaled turn points to corresponding pieces
// (after this, each turn occurs twice)
std::size_t index = 0; std::size_t index = 0;
for (typename boost::range_iterator<turn_vector_type>::type it = for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it, ++index) boost::begin(m_turns); it != boost::end(m_turns); ++it, ++index)
{ {
geometry::recalculate(it->robust_point, it->point, m_robust_policy); 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; 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()
inline void get_turns(DistanceStrategy const& distance_strategy)
{ {
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 // Calculate the turns
piece_turn_visitor piece_turn_visitor
@ -948,6 +685,8 @@ struct buffered_piece_collection
typename IntersectionStrategy::disjoint_box_box_strategy_type typename IntersectionStrategy::disjoint_box_box_strategy_type
> overlaps_section_box_type; > overlaps_section_box_type;
detail::sectionalize::enlarge_sections(monotonic_sections,
m_envelope_strategy);
geometry::partition geometry::partition
< <
robust_box_type robust_box_type
@ -956,7 +695,7 @@ struct buffered_piece_collection
overlaps_section_box_type()); overlaps_section_box_type());
} }
insert_rescaled_piece_turns(); update_turn_administration();
reverse_negative_robust_rings(); reverse_negative_robust_rings();
@ -974,7 +713,7 @@ struct buffered_piece_collection
point_in_geometry_strategy_type, point_in_geometry_strategy_type,
side_strategy_type side_strategy_type
> visitor(m_turns, m_pieces, > visitor(m_turns, m_pieces,
distance_strategy, m_distance_strategy,
m_point_in_geometry_strategy, m_point_in_geometry_strategy,
m_side_strategy); m_side_strategy);
@ -999,14 +738,14 @@ struct buffered_piece_collection
inline void start_new_ring(bool deflate) 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.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.ring_index = -1;
current_segment_id.segment_index = 0; current_segment_id.segment_index = 0;
offsetted_rings.resize(n + 1); 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_first_piece_index = static_cast<signed_size_type>(boost::size(m_pieces));
m_deflate = deflate; m_deflate = deflate;
@ -1025,32 +764,15 @@ struct buffered_piece_collection
&& m_pieces.back().first_seg_id.multi_index && m_pieces.back().first_seg_id.multi_index
== current_segment_id.multi_index) == current_segment_id.multi_index)
{ {
m_pieces.erase(m_pieces.end() - 1); m_pieces.pop_back();
} }
while (! monotonic_sections.empty() offsetted_rings.pop_back();
&& monotonic_sections.back().ring_id.multi_index original_rings.pop_back();
== current_segment_id.multi_index)
{
monotonic_sections.erase(monotonic_sections.end() - 1);
}
offsetted_rings.erase(offsetted_rings.end() - 1);
current_robust_ring.clear();
m_first_piece_index = -1; 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, inline void update_last_point(point_type const& p,
buffered_ring<Ring>& ring) buffered_ring<Ring>& ring)
{ {
@ -1079,43 +801,84 @@ struct buffered_piece_collection
m_robust_policy); m_robust_policy);
} }
inline void finish_ring(strategy::buffer::result_code code, inline bool finish_ring(strategy::buffer::result_code code)
bool is_interior = false, bool has_interiors = false)
{ {
if (code == strategy::buffer::result_error_numerical) if (code == strategy::buffer::result_error_numerical)
{ {
abort_ring(); abort_ring();
return; return false;
} }
if (m_first_piece_index == -1) 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; return;
} }
if (m_first_piece_index < static_cast<signed_size_type>(boost::size(m_pieces))) if (! input_ring.empty())
{ {
// If piece was added // Assign the ring to the original_ring collection
// Reassign left-of-first and right-of-last // For rescaling, it is recalculated. Without rescaling, it
geometry::range::at(m_pieces, m_first_piece_index).left_index // is just assigning (note that this Ring type is the
= static_cast<signed_size_type>(boost::size(m_pieces)) - 1; // GeometryOut type, which might differ from the input ring type)
geometry::range::back(m_pieces).right_index = m_first_piece_index; geometry::model::ring<robust_point_type> adapted_ring;
}
m_first_piece_index = -1;
update_closing_point(); typedef detail::normalized_view<InputRing const> view_type;
view_type const view(input_ring);
if (! current_robust_ring.empty()) for (typename boost::range_iterator<view_type const>::type it =
{ boost::begin(view); it != boost::end(view); ++it)
BOOST_GEOMETRY_ASSERT {
( robust_point_type adapted_point;
geometry::equals(current_robust_ring.front(), geometry::recalculate(adapted_point, *it, m_robust_policy);
current_robust_ring.back()) adapted_ring.push_back(adapted_point);
); }
robust_originals.push_back( original_rings.back()
robust_original(current_robust_ring, = original_ring(adapted_ring,
is_interior, has_interiors, m_envelope_strategy, m_expand_strategy)); 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 // This indicates an error situation: an earlier piece was empty
// It currently does not happen // It currently does not happen
// std::cout << "EMPTY " << pc.type << " " << pc.index << " " << pc.first_seg_id.multi_index << std::endl;
pc.offsetted_count = 0; pc.offsetted_count = 0;
return; 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) #if defined(BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS)
pc.helper_points.push_back(point); pc.helper_points.push_back(point);
@ -1212,17 +974,18 @@ struct buffered_piece_collection
robust_point_type rob_point; robust_point_type rob_point;
geometry::recalculate(rob_point, point, m_robust_policy); geometry::recalculate(rob_point, point, m_robust_policy);
pc.robust_ring.push_back(rob_point); pc.robust_ring.push_back(rob_point);
return rob_point;
} }
// TODO: this is shared with sectionalize, move to somewhere else (assign?) template <typename Box>
template <typename Box, typename Value> static inline void enlarge_box(Box& box)
inline void enlarge_box(Box& box, Value value)
{ {
geometry::set<0, 0>(box, geometry::get<0, 0>(box) - value); #if defined(BOOST_GEOMETRY_USE_RESCALING)
geometry::set<0, 1>(box, geometry::get<0, 1>(box) - value); // Enlarge the box by 1 pixel, or 1 unit
geometry::set<1, 0>(box, geometry::get<1, 0>(box) + value); detail::buffer::buffer_box(box, 1, box);
geometry::set<1, 1>(box, geometry::get<1, 1>(box) + value); #else
// Enlarge the box just a bit
detail::buffer::buffer_box(box, 0.001, box);
#endif
} }
inline void calculate_robust_envelope(piece& pc) 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]); geometry::expand(pc.robust_offsetted_envelope, pc.robust_ring[i]);
} }
// Take roundings into account, enlarge boxes with 1 integer // Take roundings into account, enlarge boxes
enlarge_box(pc.robust_envelope, 1); enlarge_box(pc.robust_envelope);
enlarge_box(pc.robust_offsetted_envelope, 1); 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 typedef geometry::detail::sectionalize::sectionalize_part
< <
point_type, point_type,
@ -1259,7 +1019,7 @@ struct buffered_piece_collection
// Create a ring-identifier. The source-index is the piece index // 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 multi_index is as in this collection (the ring), but not used here
// The ring_index is not used // 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, sectionalizer::apply(monotonic_sections,
boost::begin(ring) + pc.first_seg_id.segment_index, boost::begin(ring) + pc.first_seg_id.segment_index,
@ -1272,7 +1032,6 @@ struct buffered_piece_collection
{ {
init_rescale_piece(pc, 0u); init_rescale_piece(pc, 0u);
calculate_robust_envelope(pc); calculate_robust_envelope(pc);
sectionalize(pc);
} }
inline void finish_piece(piece& pc, inline void finish_piece(piece& pc,
@ -1287,12 +1046,9 @@ struct buffered_piece_collection
} }
add_helper_point(pc, point1); 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); add_helper_point(pc, point3);
calculate_robust_envelope(pc); calculate_robust_envelope(pc);
sectionalize(pc);
current_robust_ring.push_back(mid_point);
} }
inline void finish_piece(piece& pc, inline void finish_piece(piece& pc,
@ -1303,24 +1059,10 @@ struct buffered_piece_collection
{ {
init_rescale_piece(pc, 4u); init_rescale_piece(pc, 4u);
add_helper_point(pc, point1); add_helper_point(pc, point1);
robust_point_type mid_point2 = add_helper_point(pc, point2); add_helper_point(pc, point2);
robust_point_type mid_point1 = add_helper_point(pc, point3); add_helper_point(pc, point3);
add_helper_point(pc, point4); add_helper_point(pc, point4);
sectionalize(pc);
calculate_robust_envelope(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> 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> template <typename Range>
inline void add_piece(strategy::buffer::piece_type type, Range const& range, inline void add_piece(strategy::buffer::piece_type type, Range const& range,
@ -1358,17 +1108,6 @@ struct buffered_piece_collection
finish_piece(pc); 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> template <typename Range>
inline void add_piece(strategy::buffer::piece_type type, inline void add_piece(strategy::buffer::piece_type type,
point_type const& p, Range const& range) 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> template <typename EndcapStrategy, typename Range>
inline void add_endcap(EndcapStrategy const& strategy, Range const& range, inline void add_endcap(EndcapStrategy const& strategy, Range const& range,
point_type const& end_point) point_type const& end_point)
@ -1470,12 +1220,16 @@ struct buffered_piece_collection
// any of the robust original rings // any of the robust original rings
// This can go quadratic if the input has many rings, and there // This can go quadratic if the input has many rings, and there
// are many untouched deflated rings around // are many untouched deflated rings around
for (typename std::vector<robust_original>::const_iterator it for (typename std::vector<original_ring>::const_iterator it
= robust_originals.begin(); = original_rings.begin();
it != robust_originals.end(); it != original_rings.end();
++it) ++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, if (detail::disjoint::disjoint_point_box(any_point,
original.m_box, original.m_box,
d_pb_strategy_type())) d_pb_strategy_type()))
@ -1536,15 +1290,6 @@ struct buffered_piece_collection
inline void block_turns() 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 = for (typename boost::range_iterator<turn_vector_type>::type it =
boost::begin(m_turns); it != boost::end(m_turns); ++it) boost::begin(m_turns); it != boost::end(m_turns); ++it)
{ {

View File

@ -212,9 +212,13 @@ public:
{} {}
template <typename Turn, typename Original> 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) if (turn.location != location_ok || turn.within_original)
{ {

View File

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

View File

@ -217,7 +217,11 @@ struct covered_by<
\note The default strategy is used for covered_by detection \note The default strategy is used for covered_by detection
\qbk{[include reference/algorithms/covered_by.qbk]} \qbk{[include reference/algorithms/covered_by.qbk]}
\qbk{
[heading Examples]
[covered_by]
[covered_by_output]
}
*/ */
template<typename Geometry1, typename Geometry2> template<typename Geometry1, typename Geometry2>
inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& 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} \return \return_check2{are disjoint}
\qbk{[include reference/algorithms/disjoint.qbk]} \qbk{[include reference/algorithms/disjoint.qbk]}
\qbk{
[heading Examples]
[disjoint]
[disjoint_output]
}
*/ */
template <typename Geometry1, typename Geometry2> template <typename Geometry1, typename Geometry2>
inline bool disjoint(Geometry1 const& geometry1, 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} \return \return_check2{overlap}
\qbk{[include reference/algorithms/overlaps.qbk]} \qbk{[include reference/algorithms/overlaps.qbk]}
\qbk{
[heading Examples]
[overlaps]
[overlaps_output]
}
*/ */
template <typename Geometry1, typename Geometry2> template <typename Geometry1, typename Geometry2>
inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2) inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)

View File

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

View File

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

View File

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

View File

@ -31,7 +31,6 @@
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp> #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/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.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/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/util/condition.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) ++op_it)
{ {
turn_operation_type const& op = *op_it; turn_operation_type const& op = *op_it;
ring_identifier const ring_id ring_identifier const ring_id = ring_id_by_seg_id(op.seg_id);
(
op.seg_id.source_index,
op.seg_id.multi_index,
op.seg_id.ring_index
);
if (! is_self_turn<OverlayType>(turn) 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/signed_size_type.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -95,7 +96,18 @@ struct segment_identifier
signed_size_type piece_index; 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 }} // namespace boost::geometry

View File

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

View File

@ -35,12 +35,6 @@ namespace boost { namespace geometry
namespace detail { namespace overlay 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 template
< <
bool Reverse1, bool Reverse1,

View File

@ -261,6 +261,11 @@ struct self_touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
\qbk{distinguish,one geometry} \qbk{distinguish,one geometry}
\qbk{[def __one_parameter__]} \qbk{[def __one_parameter__]}
\qbk{[include reference/algorithms/touches.qbk]} \qbk{[include reference/algorithms/touches.qbk]}
\qbk{
[heading Examples]
[touches_one_geometry]
[touches_one_geometry_output]
}
*/ */
template <typename Geometry> template <typename Geometry>
inline bool touches(Geometry const& geometry) inline bool touches(Geometry const& geometry)
@ -280,6 +285,11 @@ inline bool touches(Geometry const& geometry)
\qbk{distinguish,two geometries} \qbk{distinguish,two geometries}
\qbk{[include reference/algorithms/touches.qbk]} \qbk{[include reference/algorithms/touches.qbk]}
\qbk{
[heading Examples]
[touches_two_geometries]
[touches_two_geometries_output]
}
*/ */
template <typename Geometry1, typename Geometry2> template <typename Geometry1, typename Geometry2>
inline bool touches(Geometry1 const& geometry1, Geometry2 const& 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/math.hpp>
#include <boost/geometry/util/order_as_direction.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/multi_point.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.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} \return \return_calc{perimeter}
\qbk{[include reference/algorithms/perimeter.qbk]} \qbk{[include reference/algorithms/perimeter.qbk]}
\qbk{
[heading Example]
[perimeter]
[perimeter_output]
}
*/ */
template<typename Geometry> template<typename Geometry>
inline typename default_length_result<Geometry>::type perimeter( inline typename default_length_result<Geometry>::type perimeter(

View File

@ -90,7 +90,8 @@ struct cross_product<3>
\param p1 first vector \param p1 first vector
\param p2 second vector \param p2 second vector
\return the cross product vector \return the cross product vector
*/
*/
template <typename ResultP, typename P1, typename P2> template <typename ResultP, typename P1, typename P2>
inline ResultP cross_product(P1 const& p1, P2 const& 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 p1 first vector
\param p2 second vector \param p2 second vector
\return the cross product vector \return the cross product vector
\qbk{[heading Examples]}
\qbk{[cross_product] [cross_product_output]}
*/ */
template <typename P> template <typename P>
inline P cross_product(P const& p1, P const& p2) 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 p1 first point
\param p2 second point \param p2 second point
\return the dot product \return the dot product
\qbk{[heading Examples]}
\qbk{[dot_product] [dot_product_output]}
*/ */
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
inline typename select_coordinate_type<Point1, Point2>::type dot_product( 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) 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 // 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_minus_cos_d = c1 - cos_d;
CT const one_plus_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) ? CT const H = math::equals(one_minus_cos_d, c0) ?
c0 : c0 :
@ -124,7 +125,7 @@ public:
if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) 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)) if (math::equals(sin_d, c0))
{ {
// T = inf // T = inf
@ -140,16 +141,26 @@ public:
// The most correct way of fixing it is to handle antipodal regions // The most correct way of fixing it is to handle antipodal regions
// correctly and consistently across all formulas. // correctly and consistently across all formulas.
// Set azimuth to 0 unless the first endpoint is the north pole // points very close
if (! math::equals(sin_lat1, c1)) if (cos_d >= c0)
{ {
result.azimuth = c0; result.azimuth = c0;
result.reverse_azimuth = pi; result.reverse_azimuth = c0;
} }
// antipodal points
else else
{ {
result.azimuth = pi; // Set azimuth to 0 unless the first endpoint is the north pole
result.reverse_azimuth = 0; if (! math::equals(sin_lat1, c1))
{
result.azimuth = c0;
result.reverse_azimuth = pi;
}
else
{
result.azimuth = pi;
result.reverse_azimuth = c0;
}
} }
} }
else else

View File

@ -97,24 +97,6 @@ class karney_inverse
public: public:
typedef result_inverse<CT> result_type; 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> template <typename T1, typename T2, typename Spheroid>
static inline result_type apply(T1 const& lo1, static inline result_type apply(T1 const& lo1,
@ -123,6 +105,21 @@ public:
T2 const& la2, T2 const& la2,
Spheroid const& spheroid) 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; result_type result;
CT lat1 = la1; CT lat1 = la1;
@ -145,7 +142,7 @@ public:
CT const tol_bisection = tol0 * tol2; CT const tol_bisection = tol0 * tol2;
CT const etol2 = c0_1 * 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)()); CT tiny = std::sqrt((std::numeric_limits<CT>::min)());
@ -164,7 +161,7 @@ public:
lon12_error = (c180 - lon12) - lon12_sign * lon12_error; lon12_error = (c180 - lon12) - lon12_sign * lon12_error;
// Convert to radians. // Convert to radians.
CT lam12 = lon12 * math::d2r<CT>(); CT lam12 = lon12 * d2r;
CT sin_lam12; CT sin_lam12;
CT cos_lam12; CT cos_lam12;
@ -268,8 +265,8 @@ public:
CT sin_sigma2 = sin_beta2; CT sin_sigma2 = sin_beta2;
CT cos_sigma2 = cos_alpha2 * cos_beta2; CT cos_sigma2 = cos_alpha2 * cos_beta2;
CT sigma12 = std::atan2((std::max)(CT(0), cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), CT sigma12 = std::atan2((std::max)(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2),
cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2);
CT dummy; CT dummy;
meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1,
@ -401,7 +398,7 @@ public:
CT nsin_alpha1 = sin_alpha1 * cos_diff_alpha1 + CT nsin_alpha1 = sin_alpha1 * cos_diff_alpha1 +
cos_alpha1 * sin_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; cos_alpha1 = cos_alpha1 * cos_diff_alpha1 - sin_alpha1 * sin_diff_alpha1;
sin_alpha1 = nsin_alpha1; sin_alpha1 = nsin_alpha1;
@ -468,12 +465,12 @@ public:
{ {
if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) 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)) 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> template <typename CoeffsC1>
static inline void meridian_length(CT epsilon, CT ep2, CT sigma12, static inline void meridian_length(CT const& epsilon, CT const& ep2, CT const& sigma12,
CT sin_sigma1, CT cos_sigma1, CT dn1, CT const& sin_sigma1, CT const& cos_sigma1, CT const& dn1,
CT sin_sigma2, CT cos_sigma2, CT dn2, CT const& sin_sigma2, CT const& cos_sigma2, CT const& dn2,
CT cos_beta1, CT cos_beta2, CT const& cos_beta1, CT const& cos_beta2,
CT& s12x, CT& m12x, CT& m0, CT& s12x, CT& m12x, CT& m0,
CT& M12, CT& M21, CT& M12, CT& M21,
CoeffsC1 coeffs_C1) CoeffsC1 const& coeffs_C1)
{ {
static CT const c1 = 1;
CT A12x = 0, J12 = 0; CT A12x = 0, J12 = 0;
CT expansion_A1, expansion_A2; CT expansion_A1, expansion_A2;
@ -578,14 +577,24 @@ public:
cos_alpha2 and function value is sig12. cos_alpha2 and function value is sig12.
*/ */
template <typename CoeffsC1> template <typename CoeffsC1>
static inline CT newton_start(CT sin_beta1, CT cos_beta1, CT dn1, static inline CT newton_start(CT const& sin_beta1, CT const& cos_beta1, CT const& dn1,
CT sin_beta2, CT cos_beta2, CT dn2, CT const& sin_beta2, CT const& cos_beta2, CT dn2,
CT lam12, CT sin_lam12, CT cos_lam12, CT const& lam12, CT const& sin_lam12, CT const& cos_lam12,
CT& sin_alpha1, CT& cos_alpha1, CT& sin_alpha1, CT& cos_alpha1,
CT& sin_alpha2, CT& cos_alpha2, CT& sin_alpha2, CT& cos_alpha2,
CT& dnm, CoeffsC1 coeffs_C1, CT ep2, CT& dnm, CoeffsC1 const& coeffs_C1, CT const& ep2,
CT tol1, CT tol2, CT etol2, CT n, CT f) 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 one_minus_f = c1 - f;
CT const x_thresh = c1000 * tol2; CT const x_thresh = c1000 * tol2;
@ -646,7 +655,7 @@ public:
// Skip astroid calculation if too eccentric. // Skip astroid calculation if too eccentric.
else if (std::abs(n) > c0_1 || else if (std::abs(n) > c0_1 ||
cos_sigma12 >= c0 || cos_sigma12 >= c0 ||
sin_sigma12 >= c6 * std::abs(n) * math::pi<CT>() * sin_sigma12 >= c6 * std::abs(n) * pi *
math::sqr(cos_beta1)) math::sqr(cos_beta1))
{ {
// Nothing to do, zeroth order spherical approximation will do. // 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()); 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; beta_scale = lambda_scale * cos_beta1;
x = lam12x / lambda_scale; x = lam12x / lambda_scale;
@ -682,15 +691,16 @@ public:
CT beta12a = atan2(sin_beta12a, cos_beta12a); CT beta12a = atan2(sin_beta12a, cos_beta12a);
CT m12b, m0, dummy; CT m12b, m0, dummy;
meridian_length(n, ep2, math::pi<CT>() + beta12a, meridian_length(n, ep2, pi + beta12a,
sin_beta1, -cos_beta1, dn1, sin_beta1, -cos_beta1, dn1,
sin_beta2, cos_beta2, dn2, sin_beta2, cos_beta2, dn2,
cos_beta1, cos_beta2, dummy, cos_beta1, cos_beta2, dummy,
m12b, m0, dummy, dummy, coeffs_C1); m12b, m0, dummy, dummy, coeffs_C1);
x = -c1 + m12b / (cos_beta1 * cos_beta2 * m0 * math::pi<CT>()); x = -c1 + m12b / (cos_beta1 * cos_beta2 * m0 * pi);
beta_scale = x < -c0_01 ? sin_beta12a / x : beta_scale = x < -c0_01
-f * math::sqr(cos_beta1) * math::pi<CT>(); ? sin_beta12a / x
: -f * math::sqr(cos_beta1) * pi;
lambda_scale = beta_scale / cos_beta1; lambda_scale = beta_scale / cos_beta1;
y = lam12x / lambda_scale; y = lam12x / lambda_scale;
@ -701,7 +711,7 @@ public:
// Strip near cut. // Strip near cut.
if (f >= c0) 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)); cos_alpha1 = - math::sqrt(c1 - math::sqr(sin_alpha1));
} }
else else
@ -713,7 +723,7 @@ public:
else else
{ {
// Solve the astroid problem. // Solve the astroid problem.
CT k = astroid(x, y); CT k = astroid(CT(x), y);
CT omega12a = lambda_scale * (f >= c0 ? -x * k / CT omega12a = lambda_scale * (f >= c0 ? -x * k /
(c1 + k) : -y * (c1 + k) / k); (c1 + k) : -y * (c1 + k) / k);
@ -750,8 +760,15 @@ public:
Geodesics on an ellipsoid of revolution, Charles F.F Karney, Geodesics on an ellipsoid of revolution, Charles F.F Karney,
https://arxiv.org/abs/1102.1215 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 k;
CT p = math::sqr(x); CT p = math::sqr(x);
@ -815,19 +832,23 @@ public:
} }
template <typename CoeffsC1> template <typename CoeffsC1>
static inline CT lambda12(CT sin_beta1, CT cos_beta1, CT dn1, static inline CT lambda12(CT const& sin_beta1, CT const& cos_beta1, CT const& dn1,
CT sin_beta2, CT cos_beta2, CT dn2, CT const& sin_beta2, CT const& cos_beta2, CT const& dn2,
CT sin_alpha1, CT cos_alpha1, CT const& sin_alpha1, CT cos_alpha1,
CT sin_lam120, CT cos_lam120, CT const& sin_lam120, CT const& cos_lam120,
CT& sin_alpha2, CT& cos_alpha2, CT& sin_alpha2, CT& cos_alpha2,
CT& sigma12, CT& sigma12,
CT& sin_sigma1, CT& cos_sigma1, CT& sin_sigma1, CT& cos_sigma1,
CT& sin_sigma2, CT& cos_sigma2, CT& sin_sigma2, CT& cos_sigma2,
CT& eps, CT& diff_omega12, CT& eps, CT& diff_omega12,
bool diffp, CT& diff_lam12, bool diffp, CT& diff_lam12,
CT f, CT n, CT ep2, CT tiny, CT const& f, CT const& n, CT const& ep2, CT const& tiny,
CoeffsC1 coeffs_C1) 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; CT const one_minus_f = c1 - f;
if (sin_beta1 == c0 && cos_alpha1 == c0) if (sin_beta1 == c0 && cos_alpha1 == c0)
@ -878,11 +899,11 @@ public:
// sig12 = sig2 - sig1, limit to [0, pi]. // 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); cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2);
// omg12 = omg2 - omg1, limit to [0, pi]. // 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; cos_omega12 = cos_omega1 * cos_omega2 + sin_omega1 * sin_omega2;
// eta = omg12 - lam120. // 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 // 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> template <typename MembersHolder>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear_tag> 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 MembersHolder::node node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node; typedef typename MembersHolder::internal_node internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; typedef typename MembersHolder::leaf leaf;
template <typename Node> template <typename Node>
static inline void apply(Node & n, static inline void apply(Node & n,
Node & second_node, Node & second_node,
Box & box1, box_type & box1,
Box & box2, box_type & box2,
parameters_type const& parameters, parameters_type const& parameters,
Translator const& translator, translator_type const& translator,
Allocators & allocators) allocators_type & allocators)
{ {
typedef typename rtree::elements_type<Node>::type elements_type; typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type; typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type; typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
typedef typename index::detail::default_content_result<Box>::type content_type; typedef typename index::detail::default_content_result<box_type>::type content_type;
typename index::detail::strategy_type<parameters_type>::type const& typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters); strategy = index::detail::get_strategy(parameters);
@ -414,8 +417,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
else else
{ {
// calculate enlarged boxes and areas // calculate enlarged boxes and areas
Box enlarged_box1(box1); box_type enlarged_box1(box1);
Box enlarged_box2(box2); box_type enlarged_box2(box2);
index::detail::expand(enlarged_box1, indexable, strategy); index::detail::expand(enlarged_box1, indexable, strategy);
index::detail::expand(enlarged_box2, indexable, strategy); index::detail::expand(enlarged_box2, indexable, strategy);
content_type enlarged_content1 = index::detail::content(enlarged_box1); content_type enlarged_content1 = index::detail::content(enlarged_box1);
@ -452,7 +455,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
elements1.clear(); elements1.clear();
elements2.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(); //elements_copy.clear();
BOOST_RETHROW // RETHROW, BASIC 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_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.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/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/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.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 // 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 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 MembersHolder::internal_node internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; 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_type & allocators)
inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
{ {
subtree_destroyer dummy(element.second, allocators); detail::rtree::visitors::destroy<MembersHolder>::apply(element.second, allocators);
element.second = 0; 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 // 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 struct destroy_elements
{ {
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::allocators_type allocators_type;
template <typename Range> 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); apply(boost::begin(elements), boost::end(elements), allocators);
} }
template <typename It> 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_< typedef boost::mpl::bool_<
boost::is_same< boost::is_same<
Value, typename std::iterator_traits<It>::value_type value_type, typename std::iterator_traits<It>::value_type
>::value >::value
> is_range_of_values; > is_range_of_values;
@ -145,37 +150,38 @@ struct destroy_elements
private: private:
template <typename It> 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*/) boost::mpl::bool_<false> const& /*is_range_of_values*/)
{ {
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
for ( ; first != last ; ++first ) for ( ; first != last ; ++first )
{ {
subtree_destroyer dummy(first->second, allocators); detail::rtree::visitors::destroy<MembersHolder>::apply(first->second, allocators);
first->second = 0; first->second = 0;
} }
} }
template <typename It> 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*/) boost::mpl::bool_<true> const& /*is_range_of_values*/)
{} {}
}; };
// clears node, deletes all subtrees stored in node // 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 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 MembersHolder::node node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node; typedef typename MembersHolder::internal_node internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; 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); rtree::apply_visitor(ilv, node);
if ( ilv.result ) 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(); rtree::elements(internal_node).clear();
} }
inline static void apply(leaf & leaf, Allocators &) inline static void apply(leaf & leaf, allocators_type &)
{ {
rtree::elements(leaf).clear(); rtree::elements(leaf).clear();
} }
}; };
*/
template <typename Container, typename Iterator> template <typename Container, typename Iterator>
void move_from_back(Container & container, Iterator it) void move_from_back(Container & container, Iterator it)

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