Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing input combinations in intersection() and introduction of tupled-output. #650

Merged
merged 23 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
aacdefa
[index][util] Move tuples metafunctions from index to util.
awulkiew Nov 15, 2019
b31bec2
[util][srs] Move tuples metafunctions from srs to util.
awulkiew Nov 16, 2019
fa5ce6d
[util][tuples] Add support for std::pair and std::tuple.
awulkiew Nov 16, 2019
7efff6a
[test][util][tuples] Add tests.
awulkiew Nov 18, 2019
1be86ab
Merge branch 'develop' into feature/setops_output
awulkiew Nov 18, 2019
9096a9b
[algorithms] Add tupled_output helper utils.
awulkiew Nov 27, 2019
d7e440c
[test][algorithms] Add tests for tupled_output helper utils.
awulkiew Nov 27, 2019
e6b1f6e
[algorithms] Allow passing tupled output geometries into intersection…
awulkiew Nov 27, 2019
51323cc
[setops] Add support for tupled output in intersection for PointLike …
awulkiew Dec 6, 2019
bc11d62
[setops] Add support for tupled output in intersection PointLike/Linear.
awulkiew Jan 8, 2020
6315347
[overlay] Add support for PointLike/Areal combinations, incl. tupled …
awulkiew Jan 18, 2020
2727dfe
[test][intersection] Add test cases for PointLike/Areal combinations.
awulkiew Jan 18, 2020
c6ccd93
[algorithms][core][util] Define BOOST_GEOMETRY_CXX11_TUPLE and use it…
awulkiew Jan 19, 2020
adfff22
[test][intersection] Add tests for tupled outputs.
awulkiew Jan 19, 2020
8320ec4
[intersection][overlay] Add support for tupled output in intersection…
awulkiew Jan 20, 2020
5f544fd
[test][intersection] Add test cases for tupled-output of L/A.
awulkiew Jan 20, 2020
7e7e9af
[overlay] Add missing template keywords.
awulkiew Jan 20, 2020
07e7c38
[overlay] Fix unused typedef warning.
awulkiew Jan 20, 2020
5372e6b
[intersection] Add tupled-output support for A/A combination.
awulkiew Jan 23, 2020
07abb6a
[test][intersection] Add test cases for tupled-output of A/A combinat…
awulkiew Jan 23, 2020
7beb993
[test][difference] Add test cases for P/A combinations.
awulkiew Jan 23, 2020
b8cbefb
[intersection] Remove unused typedef.
awulkiew Jan 23, 2020
2b74e42
Merge branch 'develop' into feature/setops_output
awulkiew Mar 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
348 changes: 348 additions & 0 deletions include/boost/geometry/algorithms/detail/intersection/areal_areal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
// Boost.Geometry

// Copyright (c) 2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html

#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP


#include <boost/core/ignore_unused.hpp>

#include <boost/geometry/algorithms/detail/intersection/interface.hpp>


namespace boost { namespace geometry
{

#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace intersection
{


template
<
typename GeometryOut,
typename OutTag = typename detail::intersection::tag
<
typename geometry::detail::output_geometry_value
<
GeometryOut
>::type
>::type
>
struct intersection_areal_areal_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the trailing _ ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because below the name intersection_areal_areal was already used. The original one. And I needed to distinguish between the original behavior and the handling of Tuples. Would you prefer a different name?

{
template
<
typename Areal1,
typename Areal2,
typename RobustPolicy,
typename Strategy
>
static inline void apply(Areal1 const& areal1,
Areal2 const& areal2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
geometry::dispatch::intersection_insert
<
Areal1, Areal2,
typename boost::range_value<GeometryOut>::type,
overlay_intersection
>::apply(areal1, areal2, robust_policy,
geometry::range::back_inserter(geometry_out),
strategy);
}
};

// TODO: Ideally this should be done in one call of intersection_insert
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is missing for this? Is more work on intersection_insert needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation for Areal/Areal calls intersection_insert for other combinations several times. This means that partition is called and then turns are analysed several times. However, overlay stuff called by the old/basic Areal/Areal implementation (when the output is MultiPolygon instead of tuple) has all of the information needed to generate the result in one call, so to generate Areal + Linear + PointLike output.

I decided to not modify it mainly because it could interfere with @barendgehrels work on rescaling. The code is also more complex than in case of Linear geometries, with enriching turns, storing states in turns and visitors which are not clear to me. So I'd prefer to leave it to @barendgehrels or do it when he's done with rescaling. Maybe rewrite it, maybe for C++11/14, etc. In short, it was simpler this way.

// just like it's done for all other combinations
template <typename TupledOut>
struct intersection_areal_areal_<TupledOut, tupled_output_tag>
{
template
<
typename Areal1,
typename Areal2,
typename RobustPolicy,
typename Strategy
>
static inline void apply(Areal1 const& areal1,
Areal2 const& areal2,
RobustPolicy const& robust_policy,
TupledOut& geometry_out,
Strategy const& strategy)
{
typedef typename geometry::detail::output_geometry_value
<
TupledOut
>::type single_out;

boost::ignore_unused
<
detail::intersection::expect_output_pla
<
Areal1, Areal2, single_out
>
>();

typedef geometry::detail::output_geometry_access
<
single_out, polygon_tag, polygon_tag
> areal;
typedef geometry::detail::output_geometry_access
<
single_out, linestring_tag, linestring_tag
> linear;
typedef geometry::detail::output_geometry_access
<
single_out, point_tag, point_tag
> pointlike;

typedef typename geometry::tuples::element
<
areal::index, TupledOut
>::type areal_out_type;
typedef typename geometry::tuples::element
<
pointlike::index, TupledOut
>::type pointlike_out_type;

// NOTE: The same robust_policy is used in each call of
// intersection_insert. Is that correct?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and hopefully we will get rid of it...


// A * A -> A
call_intersection(areal1, areal2, robust_policy,
areal::get(geometry_out),
strategy);

bool const is_areal_empty = boost::empty(areal::get(geometry_out));
TupledOut temp_out;

// L * L -> (L, P)
call_intersection(geometry::detail::boundary_view<Areal1 const>(areal1),
geometry::detail::boundary_view<Areal2 const>(areal2),
robust_policy,
! is_areal_empty
? temp_out
: geometry_out,
strategy);

if (! is_areal_empty)
{
// NOTE: the original areal geometry could be used instead of boundary here
// however this results in static assert failure related to rescale policy
typedef geometry::detail::boundary_view
<
areal_out_type const
> areal_out_boundary_type;

areal_out_boundary_type areal_out_boundary(areal::get(geometry_out));

// L - L -> L
call_difference(linear::get(temp_out),
areal_out_boundary,
robust_policy,
linear::get(geometry_out),
strategy);

// P - L -> P
call_difference(pointlike::get(temp_out),
areal_out_boundary,
robust_policy,
pointlike::get(geometry_out),
strategy.template get_point_in_geometry_strategy
<
pointlike_out_type,
areal_out_boundary_type
>());
}

return;
}

private:
template
<
typename Geometry1,
typename Geometry2,
typename RobustPolicy,
typename GeometryOut,
typename Strategy
>
static inline void call_intersection(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
geometry::dispatch::intersection_insert
<
Geometry1,
Geometry2,
typename geometry::detail::output_geometry_value
<
GeometryOut
>::type,
overlay_intersection
>::apply(geometry1,
geometry2,
robust_policy,
geometry::detail::output_geometry_back_inserter(geometry_out),
strategy);
}

template
<
typename Geometry1,
typename Geometry2,
typename RobustPolicy,
typename GeometryOut,
typename Strategy
>
static inline void call_difference(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
geometry::dispatch::intersection_insert
<
Geometry1,
Geometry2,
typename boost::range_value<GeometryOut>::type,
overlay_difference
>::apply(geometry1,
geometry2,
robust_policy,
geometry::range::back_inserter(geometry_out),
strategy);
}
};


struct intersection_areal_areal
{
template
<
typename Areal1,
typename Areal2,
typename RobustPolicy,
typename GeometryOut,
typename Strategy
>
static inline bool apply(Areal1 const& areal1,
Areal2 const& areal2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
intersection_areal_areal_
<
GeometryOut
>::apply(areal1, areal2, robust_policy, geometry_out, strategy);

return true;
}
};


}} // namespace detail::intersection
#endif // DOXYGEN_NO_DETAIL


#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{


template
<
typename Polygon1, typename Polygon2
>
struct intersection
<
Polygon1, Polygon2,
polygon_tag, polygon_tag,
false
>
: detail::intersection::intersection_areal_areal
{};

template
<
typename Polygon, typename Ring
>
struct intersection
<
Polygon, Ring,
polygon_tag, ring_tag,
false
>
: detail::intersection::intersection_areal_areal
{};

template
<
typename Ring1, typename Ring2
>
struct intersection
<
Ring1, Ring2,
ring_tag, ring_tag,
false
>
: detail::intersection::intersection_areal_areal
{};

template
<
typename Polygon, typename MultiPolygon
>
struct intersection
<
Polygon, MultiPolygon,
polygon_tag, multi_polygon_tag,
false
>
: detail::intersection::intersection_areal_areal
{};

template
<
typename MultiPolygon, typename Ring
>
struct intersection
<
MultiPolygon, Ring,
multi_polygon_tag, ring_tag,
false
>
: detail::intersection::intersection_areal_areal
{};

template
<
typename MultiPolygon1, typename MultiPolygon2
>
struct intersection
<
MultiPolygon1, MultiPolygon2,
multi_polygon_tag, multi_polygon_tag,
false
>
: detail::intersection::intersection_areal_areal
{};


} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

}} // namespace boost::geometry

#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP


#include <boost/geometry/algorithms/detail/intersection/areal_areal.hpp>
#include <boost/geometry/algorithms/detail/intersection/box_box.hpp>
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <boost/variant/variant_fwd.hpp>

#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
#include <boost/geometry/algorithms/detail/tupled_output.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/util/range.hpp>
Expand Down Expand Up @@ -50,14 +51,18 @@ struct intersection
GeometryOut& geometry_out,
Strategy const& strategy)
{
typedef typename boost::range_value<GeometryOut>::type OneOut;
typedef typename geometry::detail::output_geometry_value
<
GeometryOut
>::type SingleOut;

intersection_insert
<
Geometry1, Geometry2, OneOut,
Geometry1, Geometry2, SingleOut,
overlay_intersection
>::apply(geometry1, geometry2, robust_policy,
range::back_inserter(geometry_out), strategy);
geometry::detail::output_geometry_back_inserter(geometry_out),
strategy);

return true;
}
Expand Down
Loading