mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 05:24:02 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into feature/shortest_points_new_strategies
This commit is contained in:
commit
ea0df6db82
34
example/with_external_libs/CMakeLists.txt
Normal file
34
example/with_external_libs/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
# Boost.Geometry
|
||||
# Example CMakeLists.txt building the Boost.Geometry with wxWidget example
|
||||
#
|
||||
# Copyright (c) 2021-2021 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
# 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)
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(with_external_libs)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# Set BOOST_ROOT in your environment (this is cmake default)
|
||||
find_package(Boost)
|
||||
|
||||
# Set WX_ROOT, similarly, also in your environment
|
||||
set(WX_ROOT $ENV{WX_ROOT})
|
||||
message(STATUS "Using wxWidgets from this folder: " $ENV{WX_ROOT})
|
||||
|
||||
# WX Widgets
|
||||
link_directories(${WX_ROOT}/lib)
|
||||
add_executable(wx x04_wxwidgets_world_mapper.cpp)
|
||||
target_include_directories(wx PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
target_include_directories(wx PRIVATE ${WX_ROOT}/include)
|
||||
target_include_directories(wx PRIVATE ${WX_ROOT}/include/wx-3.1)
|
||||
|
||||
# WX configuration (get the values using wx-config --cxxflags and wx-config --libs)
|
||||
target_compile_definitions(wx PRIVATE WXUSINGDLL __WXGTK2__ __WXGTK__)
|
||||
target_link_libraries(wx PRIVATE wx_gtk2u_html-3.1 wx_gtk2u_core-3.1 wx_baseu_net-3.1 wx_baseu-3.1)
|
||||
|
@ -1,115 +1,62 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Boost.Geometry
|
||||
//
|
||||
// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2010-2021 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// 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)
|
||||
//
|
||||
// wxWidgets World Mapper example
|
||||
//
|
||||
// It will show a basic wxWidgets window, displaying world countries,
|
||||
// highlighting the country under the mouse, and indicating position
|
||||
// of the mouse in latitude/longitude and in pixels.
|
||||
|
||||
// To compile this program:
|
||||
// Install wxWidgets (if not done before)
|
||||
// export BOOST_ROOT=.....
|
||||
// export WX_ROOT=.... (for example /home/myname/mylib/wxWidgets/Linux/x86_64)
|
||||
// mkdir build
|
||||
// cd build
|
||||
// cmake .. -G Ninja
|
||||
// ninja
|
||||
// If necessary, CMakeLists.txt should be adapted, the options for wx
|
||||
// are provided by "wx-config --cxxflags" and "... --libs"
|
||||
// and might need a change in CMakeLists.txt
|
||||
|
||||
// #define EXAMPLE_WX_USE_GRAPHICS_CONTEXT 1
|
||||
//#define EXAMPLE_WX_USE_GRAPHICS_CONTEXT 1
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
|
||||
#include <boost/geometry/geometry.hpp>
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/geometries/multi_geometries.hpp>
|
||||
#include <boost/geometry/geometries/multi_polygon.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/register/point.hpp>
|
||||
#include <boost/geometry/geometries/register/ring.hpp>
|
||||
#include <boost/geometry/extensions/algorithms/selected.hpp>
|
||||
|
||||
|
||||
// wxWidgets, if these headers are NOT found, adapt include path (and lib path)
|
||||
|
||||
#include "wx/wx.h"
|
||||
#include "wx/math.h"
|
||||
#include "wx/stockitem.h"
|
||||
|
||||
|
||||
#ifdef EXAMPLE_WX_USE_GRAPHICS_CONTEXT
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/dcgraph.h"
|
||||
#endif
|
||||
|
||||
typedef boost::geometry::model::d2::point_xy<double> point_2d;
|
||||
typedef boost::geometry::model::multi_polygon
|
||||
|
||||
using point_2d = boost::geometry::model::d2::point_xy<double>;
|
||||
using country_type = boost::geometry::model::multi_polygon
|
||||
<
|
||||
boost::geometry::model::polygon<point_2d>
|
||||
> country_type;
|
||||
>;
|
||||
|
||||
// Adapt wxWidgets points to Boost.Geometry points such that they can be used
|
||||
// in e.g. transformations (see below)
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D(wxPoint, int, cs::cartesian, x, y)
|
||||
BOOST_GEOMETRY_REGISTER_POINT_2D(wxRealPoint, double, cs::cartesian, x, y)
|
||||
|
||||
|
||||
// wxWidgets draws using wxPoint*, so we HAVE to use that.
|
||||
// Therefore have to make a wxPoint* array
|
||||
// 1) compatible with Boost.Geometry
|
||||
// 2) compatible with Boost.Range (required by Boost.Geometry)
|
||||
// 3) compatible with std::back_inserter (required by Boost.Geometry)
|
||||
|
||||
// For compatible 2):
|
||||
typedef std::pair<wxPoint*,wxPoint*> wxPointPointerPair;
|
||||
|
||||
// For compatible 1):
|
||||
BOOST_GEOMETRY_REGISTER_RING(wxPointPointerPair);
|
||||
|
||||
|
||||
// For compatible 3):
|
||||
// Specialize back_insert_iterator for the wxPointPointerPair
|
||||
// (has to be done within "namespace std")
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
class back_insert_iterator<wxPointPointerPair>
|
||||
{
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
typedef wxPointPointerPair container_type;
|
||||
|
||||
explicit back_insert_iterator(wxPointPointerPair& x)
|
||||
: current(boost::begin(x))
|
||||
, end(boost::end(x))
|
||||
{}
|
||||
|
||||
inline back_insert_iterator<wxPointPointerPair>&
|
||||
operator=(wxPoint const& value)
|
||||
{
|
||||
// Check if not passed beyond
|
||||
if (current != end)
|
||||
{
|
||||
*current++ = value;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Boiler-plate
|
||||
inline back_insert_iterator<wxPointPointerPair>& operator*() { return *this; }
|
||||
inline back_insert_iterator<wxPointPointerPair>& operator++() { return *this; }
|
||||
inline back_insert_iterator<wxPointPointerPair>& operator++(int) { return *this; }
|
||||
|
||||
private:
|
||||
boost::range_iterator<wxPointPointerPair>::type current, end;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read an ASCII file containing WKT's
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -161,26 +108,29 @@ private:
|
||||
void OnPaint(wxPaintEvent& );
|
||||
void OnMouseMove(wxMouseEvent&);
|
||||
|
||||
typedef boost::geometry::strategy::transform::map_transformer
|
||||
using map_transformer_type = boost::geometry::strategy::transform::map_transformer
|
||||
<
|
||||
double, 2, 2,
|
||||
true, true
|
||||
> map_transformer_type;
|
||||
>;
|
||||
|
||||
typedef boost::geometry::strategy::transform::inverse_transformer
|
||||
using inverse_transformer_type = boost::geometry::strategy::transform::inverse_transformer
|
||||
<
|
||||
double, 2, 2
|
||||
> inverse_transformer_type;
|
||||
>;
|
||||
|
||||
boost::shared_ptr<map_transformer_type> m_map_transformer;
|
||||
boost::shared_ptr<inverse_transformer_type> m_inverse_transformer;
|
||||
std::shared_ptr<map_transformer_type> m_map_transformer;
|
||||
std::shared_ptr<inverse_transformer_type> m_inverse_transformer;
|
||||
|
||||
boost::geometry::model::box<point_2d> m_box;
|
||||
std::vector<country_type> m_countries;
|
||||
int m_focus;
|
||||
int m_focus = -1;
|
||||
|
||||
wxBrush m_orange;
|
||||
wxFrame* m_owner;
|
||||
wxBrush m_orange = wxBrush(wxColour(255, 128, 0), wxBRUSHSTYLE_SOLID);
|
||||
wxBrush m_blue = wxBrush(wxColour(0, 128, 255), wxBRUSHSTYLE_SOLID);
|
||||
wxBrush m_green = wxBrush(wxColour(0, 255, 0), wxBRUSHSTYLE_SOLID);
|
||||
|
||||
wxFrame* m_owner = nullptr;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
@ -244,19 +194,14 @@ void HelloWorldFrame::OnCloseWindow(wxCloseEvent& )
|
||||
HelloWorldCanvas::HelloWorldCanvas(wxFrame *frame)
|
||||
: wxWindow(frame, wxID_ANY)
|
||||
, m_owner(frame)
|
||||
, m_focus(-1)
|
||||
{
|
||||
boost::geometry::assign_inverse(m_box);
|
||||
read_wkt("../data/world.wkt", m_countries, m_box);
|
||||
m_orange = wxBrush(wxColour(255, 128, 0), wxSOLID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
||||
{
|
||||
namespace bg = boost::geometry;
|
||||
|
||||
if (m_inverse_transformer)
|
||||
{
|
||||
// Boiler-plate wxWidgets code
|
||||
@ -264,19 +209,21 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
||||
PrepareDC(dc);
|
||||
m_owner->PrepareDC(dc);
|
||||
|
||||
// Transform the point to Lon/Lat
|
||||
// Transform the point opn the screen back to Lon/Lat
|
||||
point_2d point;
|
||||
bg::transform(event.GetPosition(), point, *m_inverse_transformer);
|
||||
boost::geometry::transform(event.GetPosition(), point,
|
||||
*m_inverse_transformer);
|
||||
|
||||
// Determine selected object
|
||||
int i = 0;
|
||||
int previous_focus = m_focus;
|
||||
m_focus = -1;
|
||||
BOOST_FOREACH(country_type const& country, m_countries)
|
||||
for (country_type const& country : m_countries)
|
||||
{
|
||||
if (bg::selected(country, point, 0))
|
||||
if (boost::geometry::within(point, country))
|
||||
{
|
||||
m_focus = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -287,7 +234,7 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
||||
// Undraw old focus
|
||||
if (previous_focus >= 0)
|
||||
{
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.SetBrush(m_green);
|
||||
DrawCountry(dc, m_countries[previous_focus]);
|
||||
}
|
||||
// Draw new focus
|
||||
@ -309,6 +256,11 @@ void HelloWorldCanvas::OnMouseMove(wxMouseEvent &event)
|
||||
|
||||
void HelloWorldCanvas::OnPaint(wxPaintEvent& )
|
||||
{
|
||||
if (m_countries.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(EXAMPLE_WX_USE_GRAPHICS_CONTEXT)
|
||||
wxPaintDC pdc(this);
|
||||
wxGCDC gdc(pdc);
|
||||
@ -340,11 +292,12 @@ void HelloWorldCanvas::DrawCountries(wxDC& dc)
|
||||
{
|
||||
namespace bg = boost::geometry;
|
||||
|
||||
dc.SetBackground(*wxLIGHT_GREY_BRUSH);
|
||||
dc.SetBackground(m_blue);
|
||||
dc.Clear();
|
||||
|
||||
BOOST_FOREACH(country_type const& country, m_countries)
|
||||
for (country_type const& country : m_countries)
|
||||
{
|
||||
dc.SetBrush(m_green);
|
||||
DrawCountry(dc, country);
|
||||
}
|
||||
if (m_focus != -1)
|
||||
@ -357,27 +310,23 @@ void HelloWorldCanvas::DrawCountries(wxDC& dc)
|
||||
|
||||
void HelloWorldCanvas::DrawCountry(wxDC& dc, country_type const& country)
|
||||
{
|
||||
namespace bg = boost::geometry;
|
||||
|
||||
BOOST_FOREACH(bg::model::polygon<point_2d> const& poly, country)
|
||||
for (auto const& poly : country)
|
||||
{
|
||||
// Use only exterior ring, holes are (for the moment) ignored. This would need
|
||||
// a holey-polygon compatible wx object
|
||||
// Use only exterior ring, holes are (for the moment) ignored.
|
||||
// This would need a holey-polygon compatible wx object
|
||||
|
||||
std::size_t n = boost::size(bg::exterior_ring(poly));
|
||||
|
||||
boost::scoped_array<wxPoint> points(new wxPoint[n]);
|
||||
|
||||
wxPointPointerPair pair = std::make_pair(points.get(), points.get() + n);
|
||||
bg::transform(bg::exterior_ring(poly), pair, *m_map_transformer);
|
||||
|
||||
dc.DrawPolygon(n, points.get());
|
||||
// Define a Boost.Geometry ring of wxPoints
|
||||
// Behind the scenes that is a vector, and a vector has .data(),
|
||||
// can be used for the *wxPoint pointer needed for wxWidget DrawPolygon
|
||||
boost::geometry::model::ring<wxPoint> ring;
|
||||
boost::geometry::transform(boost::geometry::exterior_ring(poly), ring,
|
||||
*m_map_transformer);
|
||||
dc.DrawPolygon(ring.size(), ring.data());
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE(HelloWorldFrame, wxFrame)
|
||||
EVT_CLOSE(HelloWorldFrame::OnCloseWindow)
|
||||
EVT_MENU(wxID_EXIT, HelloWorldFrame::OnExit)
|
||||
|
@ -1,23 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
|
||||
// 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)
|
||||
|
||||
|
||||
|
||||
wxWidgets World Mapper example
|
||||
|
||||
It will show a basic wxWidgets window, displaying world countries, highlighting the country under
|
||||
the mouse, and indicating position of the mouse in latitude/longitude and in pixels.
|
||||
|
||||
|
||||
To compile this program:
|
||||
|
||||
Install wxWidgets (if not done before)
|
||||
|
||||
Using Linux/gcc
|
||||
- check if installation is OK, http://wiki.wxwidgets.org/Installing_and_configuring_under_Ubuntu
|
||||
- compile using e.g. gcc -o x04_wxwidgets -I../../../.. x04_wxwidgets_world_mapper.cpp `wx-config --cxxflags` `wx-config --libs`
|
||||
|
@ -28,9 +28,6 @@
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
@ -41,15 +38,18 @@
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/centroid/translating_transformer.hpp>
|
||||
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/centroid/cartesian.hpp>
|
||||
@ -61,6 +61,7 @@
|
||||
|
||||
#include <boost/geometry/util/algorithm.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
|
||||
@ -540,9 +541,9 @@ struct centroid<default_strategy, false>
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
namespace resolve_dynamic {
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct centroid
|
||||
{
|
||||
template <typename Point, typename Strategy>
|
||||
@ -553,37 +554,22 @@ struct centroid
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct centroid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct centroid<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Point, typename Strategy>
|
||||
struct visitor: boost::static_visitor<void>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Point& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Point& m_out;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Point& out, Strategy const& strategy)
|
||||
: m_out(out), m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
void operator()(Geometry const& geometry) const
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
centroid<Geometry>::apply(geometry, m_out, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, typename Strategy>
|
||||
static inline void
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
Point& out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
boost::apply_visitor(visitor<Point, Strategy>(out, strategy), geometry);
|
||||
centroid<util::remove_cref_t<decltype(g)>>::apply(g, out, strategy);
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -604,10 +590,9 @@ struct centroid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
|
||||
*/
|
||||
template<typename Geometry, typename Point, typename Strategy>
|
||||
inline void centroid(Geometry const& geometry, Point& c,
|
||||
Strategy const& strategy)
|
||||
inline void centroid(Geometry const& geometry, Point& c, Strategy const& strategy)
|
||||
{
|
||||
resolve_variant::centroid<Geometry>::apply(geometry, c, strategy);
|
||||
resolve_dynamic::centroid<Geometry>::apply(geometry, c, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,8 +11,14 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP
|
||||
|
||||
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
@ -20,6 +26,8 @@
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/densify/cartesian.hpp>
|
||||
#include <boost/geometry/strategies/densify/geographic.hpp>
|
||||
@ -28,11 +36,6 @@
|
||||
#include <boost/geometry/util/condition.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@ -146,6 +149,15 @@ struct densify_ring<true, false>
|
||||
: densify_range<false>
|
||||
{};
|
||||
|
||||
struct densify_convert
|
||||
{
|
||||
template <typename GeometryIn, typename GeometryOut, typename T, typename Strategy>
|
||||
static void apply(GeometryIn const& in, GeometryOut &out,
|
||||
T const& , Strategy const& )
|
||||
{
|
||||
geometry::convert(in, out);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::densify
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
@ -167,6 +179,26 @@ struct densify
|
||||
: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename GeometryOut>
|
||||
struct densify<Geometry, GeometryOut, point_tag, point_tag>
|
||||
: geometry::detail::densify::densify_convert
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename GeometryOut>
|
||||
struct densify<Geometry, GeometryOut, segment_tag, segment_tag>
|
||||
: geometry::detail::densify::densify_convert
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename GeometryOut>
|
||||
struct densify<Geometry, GeometryOut, box_tag, box_tag>
|
||||
: geometry::detail::densify::densify_convert
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename GeometryOut>
|
||||
struct densify<Geometry, GeometryOut, multi_point_tag, multi_point_tag>
|
||||
: geometry::detail::densify::densify_convert
|
||||
{};
|
||||
|
||||
template <typename Geometry, typename GeometryOut>
|
||||
struct densify<Geometry, GeometryOut, linestring_tag, linestring_tag>
|
||||
: geometry::detail::densify::densify_range<>
|
||||
@ -328,9 +360,9 @@ struct densify<default_strategy, false>
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
namespace resolve_dynamic {
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct densify
|
||||
{
|
||||
template <typename Distance, typename Strategy>
|
||||
@ -346,43 +378,48 @@ struct densify
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct densify<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct densify<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Distance, typename Strategy>
|
||||
struct visitor: boost::static_visitor<void>
|
||||
{
|
||||
Distance const& m_max_distance;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Distance const& max_distance, Strategy const& strategy)
|
||||
: m_max_distance(max_distance)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
void operator()(Geometry const& geometry, Geometry& out) const
|
||||
{
|
||||
densify<Geometry>::apply(geometry, out, m_max_distance, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Distance, typename Strategy>
|
||||
static inline void
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& out,
|
||||
apply(Geometry const& geometry,
|
||||
Geometry& out,
|
||||
Distance const& max_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
boost::apply_visitor(
|
||||
visitor<Distance, Strategy>(max_distance, strategy),
|
||||
geometry,
|
||||
out
|
||||
);
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
using geom_t = util::remove_cref_t<decltype(g)>;
|
||||
geom_t o;
|
||||
densify<geom_t>::apply(g, o, max_distance, strategy);
|
||||
out = std::move(o);
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
template <typename Geometry>
|
||||
struct densify<Geometry, geometry_collection_tag>
|
||||
{
|
||||
template <typename Distance, typename Strategy>
|
||||
static inline void
|
||||
apply(Geometry const& geometry,
|
||||
Geometry& out,
|
||||
Distance const& max_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
using geom_t = util::remove_cref_t<decltype(g)>;
|
||||
geom_t o;
|
||||
densify<geom_t>::apply(g, o, max_distance, strategy);
|
||||
traits::emplace_back<Geometry>::apply(out, std::move(o));
|
||||
return true;
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -428,7 +465,7 @@ inline void densify(Geometry const& geometry,
|
||||
|
||||
geometry::clear(out);
|
||||
|
||||
resolve_variant::densify
|
||||
resolve_dynamic::densify
|
||||
<
|
||||
Geometry
|
||||
>::apply(geometry, out, max_distance, strategy);
|
||||
|
@ -120,14 +120,14 @@ public:
|
||||
decltype(strategies.distance(point, range))
|
||||
>::apply(strategies.distance(point, range));
|
||||
|
||||
auto it_pair = point_to_point_range::apply(point,
|
||||
boost::begin(range),
|
||||
boost::end(range),
|
||||
comparable_distance,
|
||||
cd_min);
|
||||
auto closest_segment = point_to_point_range::apply(point,
|
||||
boost::begin(range),
|
||||
boost::end(range),
|
||||
comparable_distance,
|
||||
cd_min);
|
||||
|
||||
auto closest_point = strategies.closest_points(point, range)
|
||||
.apply(point, it_pair->first, it_pair->second);
|
||||
.apply(point, *closest_segment.first, *closest_segment.second);
|
||||
|
||||
set_segment_from_points::apply(point, closest_point, shortest_seg);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ struct input_geometry_collection_proxy
|
||||
{
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
call_for_non_boxes(g, fun);
|
||||
input_geometry_collection_proxy::call_for_non_boxes(g, fun);
|
||||
return true;
|
||||
}, m_geometry);
|
||||
|
||||
@ -262,7 +262,7 @@ struct convex_hull<GeometryCollection, geometry_collection_tag>
|
||||
std::vector<ring_type> box_rings;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
add_ring_for_box(box_rings, g, strategy);
|
||||
convex_hull::add_ring_for_box(box_rings, g, strategy);
|
||||
return true;
|
||||
}, geometry);
|
||||
|
||||
|
@ -0,0 +1,237 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_COLLECTION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_GEOMETRY_COLLECTION_HPP
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/distance_result.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace distance
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry, typename GeometryCollection, typename Strategies>
|
||||
inline auto geometry_to_collection(Geometry const& geometry,
|
||||
GeometryCollection const& collection,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using result_t = typename geometry::distance_result<Geometry, GeometryCollection, Strategies>::type;
|
||||
result_t result = 0;
|
||||
bool is_first = true;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
result_t r = dispatch::distance
|
||||
<
|
||||
Geometry, util::remove_cref_t<decltype(g)>, Strategies
|
||||
>::apply(geometry, g, strategies);
|
||||
if (is_first)
|
||||
{
|
||||
result = r;
|
||||
is_first = false;
|
||||
}
|
||||
else if (r < result)
|
||||
{
|
||||
result = r;
|
||||
}
|
||||
return result > result_t(0);
|
||||
}, collection);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename GeometryCollection1, typename GeometryCollection2, typename Strategies>
|
||||
inline auto collection_to_collection(GeometryCollection1 const& collection1,
|
||||
GeometryCollection2 const& collection2,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
using result_t = typename geometry::distance_result<GeometryCollection1, GeometryCollection2, Strategies>::type;
|
||||
|
||||
using point1_t = typename geometry::point_type<GeometryCollection1>::type;
|
||||
using box1_t = model::box<point1_t>;
|
||||
using point2_t = typename geometry::point_type<GeometryCollection2>::type;
|
||||
using box2_t = model::box<point2_t>;
|
||||
|
||||
using rtree_value_t = std::pair<box1_t, typename boost::range_iterator<GeometryCollection1 const>::type>;
|
||||
using rtree_params_t = index::parameters<index::rstar<4>, Strategies>;
|
||||
using rtree_t = index::rtree<rtree_value_t, rtree_params_t>;
|
||||
|
||||
rtree_params_t rtree_params(index::rstar<4>(), strategies);
|
||||
rtree_t rtree(rtree_params);
|
||||
|
||||
// Build rtree of boxes and iterators of elements of GC1
|
||||
// TODO: replace this with visit_breadth_first_iterator to avoid creating an unnecessary container?
|
||||
{
|
||||
std::vector<rtree_value_t> values;
|
||||
visit_breadth_first_impl<true>::apply([&](auto & g1, auto it)
|
||||
{
|
||||
box1_t b1 = geometry::return_envelope<box1_t>(g1, strategies);
|
||||
geometry::detail::expand_by_epsilon(b1);
|
||||
values.emplace_back(b1, it);
|
||||
return true;
|
||||
}, collection1);
|
||||
rtree_t rt(values.begin(), values.end(), rtree_params);
|
||||
rtree = std::move(rt);
|
||||
}
|
||||
|
||||
result_t const zero = 0;
|
||||
auto const rtree_qend = rtree.qend();
|
||||
|
||||
result_t result = 0;
|
||||
bool is_first = true;
|
||||
visit_breadth_first([&](auto const& g2)
|
||||
{
|
||||
box2_t b2 = geometry::return_envelope<box2_t>(g2, strategies);
|
||||
geometry::detail::expand_by_epsilon(b2);
|
||||
|
||||
for (auto it = rtree.qbegin(index::nearest(b2, rtree.size())) ; it != rtree_qend ; ++it)
|
||||
{
|
||||
// If the distance between boxes is greater than or equal to previously found
|
||||
// distance between geometries then stop processing the current b2 because no
|
||||
// closer b1 will be found
|
||||
if (! is_first)
|
||||
{
|
||||
result_t const bd = dispatch::distance
|
||||
<
|
||||
box1_t, box2_t, Strategies
|
||||
>::apply(it->first, b2, strategies);
|
||||
if (bd >= result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Boxes are closer than the previously found distance (or it's the first time),
|
||||
// calculate the new distance between geometries and check if it's closer (or assign it).
|
||||
traits::iter_visit<GeometryCollection1>::apply([&](auto const& g1)
|
||||
{
|
||||
result_t const d = dispatch::distance
|
||||
<
|
||||
util::remove_cref_t<decltype(g1)>, util::remove_cref_t<decltype(g2)>,
|
||||
Strategies
|
||||
>::apply(g1, g2, strategies);
|
||||
if (is_first)
|
||||
{
|
||||
result = d;
|
||||
is_first = false;
|
||||
}
|
||||
else if (d < result)
|
||||
{
|
||||
result = d;
|
||||
}
|
||||
}, it->second);
|
||||
|
||||
// The smallest possible distance found, end searching.
|
||||
if (! is_first && result <= zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Just in case
|
||||
return is_first || result > zero;
|
||||
}, collection2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::distance
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry, typename GeometryCollection, typename Strategies, typename Tag1
|
||||
>
|
||||
struct distance
|
||||
<
|
||||
Geometry, GeometryCollection, Strategies,
|
||||
Tag1, geometry_collection_tag, void, false
|
||||
>
|
||||
{
|
||||
static inline auto apply(Geometry const& geometry,
|
||||
GeometryCollection const& collection,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
assert_dimension_equal<Geometry, GeometryCollection>();
|
||||
|
||||
return detail::distance::geometry_to_collection(geometry, collection, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryCollection, typename Geometry, typename Strategies, typename Tag2
|
||||
>
|
||||
struct distance
|
||||
<
|
||||
GeometryCollection, Geometry, Strategies,
|
||||
geometry_collection_tag, Tag2, void, false
|
||||
>
|
||||
{
|
||||
static inline auto apply(GeometryCollection const& collection,
|
||||
Geometry const& geometry,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
assert_dimension_equal<Geometry, GeometryCollection>();
|
||||
|
||||
return detail::distance::geometry_to_collection(geometry, collection, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryCollection1, typename GeometryCollection2, typename Strategies
|
||||
>
|
||||
struct distance
|
||||
<
|
||||
GeometryCollection1, GeometryCollection2, Strategies,
|
||||
geometry_collection_tag, geometry_collection_tag, void, false
|
||||
>
|
||||
{
|
||||
static inline auto apply(GeometryCollection1 const& collection1,
|
||||
GeometryCollection2 const& collection2,
|
||||
Strategies const& strategies)
|
||||
{
|
||||
assert_dimension_equal<GeometryCollection1, GeometryCollection2>();
|
||||
|
||||
// Build the rtree for the smaller GC (ignoring recursive GCs)
|
||||
return boost::size(collection1) <= boost::size(collection2)
|
||||
? detail::distance::collection_to_collection(collection1, collection2, strategies)
|
||||
: detail::distance::collection_to_collection(collection2, collection1, strategies);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
|
@ -7,9 +7,9 @@
|
||||
|
||||
// This file was modified by Oracle on 2014-2021.
|
||||
// Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@ -27,6 +27,7 @@
|
||||
#include <boost/geometry/algorithms/detail/distance/linear_to_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/linear_or_areal_to_areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/linear_to_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/geometry_collection.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/segment_to_segment.hpp>
|
||||
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
// This file was modified by Oracle on 2014-2021.
|
||||
// Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -28,6 +27,7 @@
|
||||
#include <boost/geometry/algorithms/dispatch/distance.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
@ -92,10 +92,9 @@ template
|
||||
struct distance
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
|
||||
apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
static inline auto apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::distance
|
||||
<
|
||||
@ -123,11 +122,9 @@ struct distance<Strategy, false>
|
||||
typename Geometry1, typename Geometry2, typename S,
|
||||
std::enable_if_t<is_strategy_converter_specialized<S>::value, int> = 0
|
||||
>
|
||||
static inline
|
||||
typename distance_result<Geometry1, Geometry2, S>::type
|
||||
apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
S const& strategy)
|
||||
static inline auto apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
S const& strategy)
|
||||
{
|
||||
typedef strategies::distance::services::strategy_converter<Strategy> converter;
|
||||
typedef decltype(converter::get(strategy)) strategy_type;
|
||||
@ -143,11 +140,9 @@ struct distance<Strategy, false>
|
||||
typename Geometry1, typename Geometry2, typename S,
|
||||
std::enable_if_t<! is_strategy_converter_specialized<S>::value, int> = 0
|
||||
>
|
||||
static inline
|
||||
typename distance_result<Geometry1, Geometry2, S>::type
|
||||
apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
S const& strategy)
|
||||
static inline auto apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
S const& strategy)
|
||||
{
|
||||
typedef strategies::distance::services::custom_strategy_converter
|
||||
<
|
||||
@ -166,11 +161,9 @@ template <>
|
||||
struct distance<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline
|
||||
typename distance_result<Geometry1, Geometry2, default_strategy>::type
|
||||
apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
static inline auto apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategies::distance::services::default_strategy
|
||||
<
|
||||
@ -187,18 +180,22 @@ struct distance<default_strategy, false>
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
namespace resolve_dynamic
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1 = typename geometry::tag<Geometry1>::type,
|
||||
typename Tag2 = typename geometry::tag<Geometry2>::type
|
||||
>
|
||||
struct distance
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
|
||||
apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
static inline auto apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_strategy::distance
|
||||
<
|
||||
@ -208,174 +205,72 @@ struct distance
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct distance<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
|
||||
struct distance<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor
|
||||
<
|
||||
typename distance_result
|
||||
<
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::type
|
||||
>
|
||||
static inline auto apply(DynamicGeometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
: m_geometry2(geometry2),
|
||||
m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
typename distance_result<Geometry1, Geometry2, Strategy>::type
|
||||
operator()(Geometry1 const& geometry1) const
|
||||
using result_t = typename geometry::distance_result<DynamicGeometry1, Geometry2, Strategy>::type;
|
||||
result_t result = 0;
|
||||
traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
|
||||
{
|
||||
return distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
Strategy
|
||||
>(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename distance_result
|
||||
<
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Geometry2,
|
||||
Strategy
|
||||
>::type
|
||||
apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
result = resolve_strategy::distance
|
||||
<
|
||||
Strategy
|
||||
>::apply(g1, geometry2, strategy);
|
||||
}, geometry1);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct distance<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
|
||||
struct distance<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor
|
||||
<
|
||||
typename distance_result
|
||||
<
|
||||
Geometry1,
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Strategy
|
||||
>::type
|
||||
>
|
||||
static inline auto apply(Geometry1 const& geometry1,
|
||||
DynamicGeometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1,
|
||||
Strategy const& strategy)
|
||||
: m_geometry1(geometry1),
|
||||
m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
typename distance_result<Geometry1, Geometry2, Strategy>::type
|
||||
operator()(Geometry2 const& geometry2) const
|
||||
using result_t = typename geometry::distance_result<Geometry1, DynamicGeometry2, Strategy>::type;
|
||||
result_t result = 0;
|
||||
traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
|
||||
{
|
||||
return distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
Strategy
|
||||
>(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename distance_result
|
||||
<
|
||||
Geometry1,
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
|
||||
Strategy
|
||||
>::type
|
||||
apply(
|
||||
Geometry1 const& geometry1,
|
||||
const variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
result = resolve_strategy::distance
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, g2, strategy);
|
||||
}, geometry2);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct distance
|
||||
<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
template <typename DynamicGeometry1, typename DynamicGeometry2>
|
||||
struct distance<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor
|
||||
<
|
||||
typename distance_result
|
||||
<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
|
||||
Strategy
|
||||
>::type
|
||||
>
|
||||
static inline auto apply(DynamicGeometry1 const& geometry1,
|
||||
DynamicGeometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
typename distance_result<Geometry1, Geometry2, Strategy>::type
|
||||
operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
|
||||
using result_t = typename geometry::distance_result<DynamicGeometry1, DynamicGeometry2, Strategy>::type;
|
||||
result_t result = 0;
|
||||
traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
|
||||
{
|
||||
return distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::template apply
|
||||
<
|
||||
Strategy
|
||||
>(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline typename distance_result
|
||||
<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
|
||||
Strategy
|
||||
>::type
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
result = resolve_strategy::distance
|
||||
<
|
||||
Strategy
|
||||
>::apply(g1, g2, strategy);
|
||||
}, geometry1, geometry2);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -415,10 +310,9 @@ for distance, it is probably so that there is no specialization
|
||||
for return_type<...> for your strategy.
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline typename distance_result<Geometry1, Geometry2, Strategy>::type
|
||||
distance(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
inline auto distance(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
@ -426,7 +320,7 @@ distance(Geometry1 const& geometry1,
|
||||
detail::throw_on_empty_input(geometry1);
|
||||
detail::throw_on_empty_input(geometry2);
|
||||
|
||||
return resolve_variant::distance
|
||||
return resolve_dynamic::distance
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
@ -448,13 +342,9 @@ distance(Geometry1 const& geometry1,
|
||||
\qbk{[include reference/algorithms/distance.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline typename default_distance_result<Geometry1, Geometry2>::type
|
||||
distance(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2)
|
||||
inline auto distance(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2)
|
||||
{
|
||||
concepts::check<Geometry1 const>();
|
||||
concepts::check<Geometry2 const>();
|
||||
|
||||
return geometry::distance(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,63 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2021, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Distributed under 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_ENVELOPE_GEOMETRY_COLLECTION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_GEOMETRY_COLLECTION_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Collection>
|
||||
struct envelope<Collection, geometry_collection_tag>
|
||||
{
|
||||
template <typename Geometry, typename Box, typename Strategy>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Box& mbr,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategy_t = decltype(strategy.envelope(geometry, mbr));
|
||||
using state_t = typename strategy_t::template multi_state<Box>;
|
||||
|
||||
state_t state;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
if (! geometry::is_empty(g))
|
||||
{
|
||||
Box b;
|
||||
envelope<util::remove_cref_t<decltype(g)>>::apply(g, b, strategy);
|
||||
state.apply(b);
|
||||
}
|
||||
return true;
|
||||
}, geometry);
|
||||
state.result(mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_GEOMETRY_COLLECTION_HPP
|
@ -6,9 +6,9 @@
|
||||
|
||||
// This file was modified by Oracle on 2015-2021.
|
||||
// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/geometry_collection.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/multipoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/point.hpp>
|
||||
|
@ -22,16 +22,14 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
|
||||
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
@ -39,6 +37,7 @@
|
||||
#include <boost/geometry/strategies/envelope/services.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -98,10 +97,10 @@ struct envelope<default_strategy, false>
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
namespace resolve_variant
|
||||
namespace resolve_dynamic
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct envelope
|
||||
{
|
||||
template <typename Box, typename Strategy>
|
||||
@ -117,38 +116,22 @@ struct envelope
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct envelope<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Box, typename Strategy>
|
||||
struct visitor: boost::static_visitor<void>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Box& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Box& m_box;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Box& box, Strategy const& strategy)
|
||||
: m_box(box)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
void operator()(Geometry const& geometry) const
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
envelope<Geometry>::apply(geometry, m_box, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, typename Strategy>
|
||||
static inline void
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
Box& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
boost::apply_visitor(visitor<Box, Strategy>(box, strategy), geometry);
|
||||
envelope<util::remove_cref_t<decltype(g)>>::apply(g, box, strategy);
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -172,7 +155,7 @@ struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template<typename Geometry, typename Box, typename Strategy>
|
||||
inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strategy)
|
||||
{
|
||||
resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
|
||||
resolve_dynamic::envelope<Geometry>::apply(geometry, mbr, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -193,7 +176,7 @@ inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strateg
|
||||
template<typename Geometry, typename Box>
|
||||
inline void envelope(Geometry const& geometry, Box& mbr)
|
||||
{
|
||||
resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
|
||||
resolve_dynamic::envelope<Geometry>::apply(geometry, mbr, default_strategy());
|
||||
}
|
||||
|
||||
|
||||
@ -219,7 +202,7 @@ template<typename Box, typename Geometry, typename Strategy>
|
||||
inline Box return_envelope(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
Box mbr;
|
||||
resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
|
||||
resolve_dynamic::envelope<Geometry>::apply(geometry, mbr, strategy);
|
||||
return mbr;
|
||||
}
|
||||
|
||||
@ -242,7 +225,7 @@ template<typename Box, typename Geometry>
|
||||
inline Box return_envelope(Geometry const& geometry)
|
||||
{
|
||||
Box mbr;
|
||||
resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
|
||||
resolve_dynamic::envelope<Geometry>::apply(geometry, mbr, default_strategy());
|
||||
return mbr;
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,6 @@
|
||||
|
||||
#include <boost/geometry/views/detail/closed_clockwise_view.hpp>
|
||||
|
||||
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
#include <boost/geometry/strategies/spherical/ssf.hpp>
|
||||
#include <boost/geometry/strategies/normalize.hpp>
|
||||
|
||||
@ -48,34 +46,17 @@
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
// Since these vectors (though ray would be a better name) are used in the
|
||||
// implementation of equals() for Areal geometries the internal representation
|
||||
// should be consistent with the side strategy.
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
typename Geometry,
|
||||
typename SideStrategy,
|
||||
typename CSTag = typename cs_tag<Geometry>::type
|
||||
>
|
||||
struct collected_vector
|
||||
: nyi::not_implemented_tag
|
||||
{};
|
||||
|
||||
// compatible with side_robust cartesian strategy
|
||||
template <typename T, typename Geometry, typename CT, typename CSTag>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry, strategy::side::side_robust<CT>, CSTag
|
||||
>
|
||||
template <typename T>
|
||||
struct collected_vector_cartesian
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
inline collected_vector()
|
||||
|
||||
inline collected_vector_cartesian()
|
||||
{}
|
||||
|
||||
inline collected_vector(T const& px, T const& py,
|
||||
T const& pdx, T const& pdy)
|
||||
inline collected_vector_cartesian(T const& px, T const& py,
|
||||
T const& pdx, T const& pdy)
|
||||
: x(px)
|
||||
, y(py)
|
||||
, dx(pdx)
|
||||
@ -85,7 +66,7 @@ struct collected_vector
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
inline collected_vector(Point const& p1, Point const& p2)
|
||||
inline collected_vector_cartesian(Point const& p1, Point const& p2)
|
||||
: x(get<0>(p1))
|
||||
, y(get<1>(p1))
|
||||
, dx(get<0>(p2) - x)
|
||||
@ -96,8 +77,7 @@ struct collected_vector
|
||||
|
||||
bool normalize()
|
||||
{
|
||||
T magnitude = math::sqrt(
|
||||
boost::numeric_cast<T>(dx * dx + dy * dy));
|
||||
T magnitude = math::sqrt(boost::numeric_cast<T>(dx * dx + dy * dy));
|
||||
|
||||
// NOTE: shouldn't here math::equals() be called?
|
||||
if (magnitude > 0)
|
||||
@ -111,7 +91,7 @@ struct collected_vector
|
||||
}
|
||||
|
||||
// For sorting
|
||||
inline bool operator<(collected_vector const& other) const
|
||||
inline bool operator<(collected_vector_cartesian const& other) const
|
||||
{
|
||||
if (math::equals(x, other.x))
|
||||
{
|
||||
@ -128,13 +108,13 @@ struct collected_vector
|
||||
return x < other.x;
|
||||
}
|
||||
|
||||
inline bool next_is_collinear(collected_vector const& other) const
|
||||
inline bool next_is_collinear(collected_vector_cartesian const& other) const
|
||||
{
|
||||
return same_direction(other);
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
inline bool operator==(collected_vector const& other) const
|
||||
inline bool operator==(collected_vector_cartesian const& other) const
|
||||
{
|
||||
return math::equals(x, other.x)
|
||||
&& math::equals(y, other.y)
|
||||
@ -142,7 +122,7 @@ struct collected_vector
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool same_direction(collected_vector const& other) const
|
||||
inline bool same_direction(collected_vector_cartesian const& other) const
|
||||
{
|
||||
// For high precision arithmetic, we have to be
|
||||
// more relaxed then using ==
|
||||
@ -157,49 +137,35 @@ private:
|
||||
//T dx_0, dy_0;
|
||||
};
|
||||
|
||||
template <typename T, typename Geometry, typename CT, typename CSTag>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry, strategy::side::side_by_triangle<CT>, CSTag
|
||||
>
|
||||
: collected_vector<T, Geometry, strategy::side::side_robust<CT>, CSTag>
|
||||
{};
|
||||
|
||||
// Compatible with spherical_side_formula which currently
|
||||
// is the default spherical_equatorial and geographic strategy
|
||||
// so CSTag is spherical_equatorial_tag or geographic_tag
|
||||
template <typename T, typename Geometry, typename CT, typename CSTag>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry, strategy::side::spherical_side_formula<CT>, CSTag
|
||||
>
|
||||
template <typename T, typename Point>
|
||||
struct collected_vector_spherical
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
typedef typename geometry::detail::cs_angular_units<Geometry>::type units_type;
|
||||
typedef model::point<T, 2, cs::spherical_equatorial<units_type> > point_type;
|
||||
|
||||
typedef model::point<T, 3, cs::cartesian> vector_type;
|
||||
|
||||
collected_vector()
|
||||
collected_vector_spherical()
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
collected_vector(Point const& p1, Point const& p2)
|
||||
collected_vector_spherical(Point const& p1, Point const& p2)
|
||||
: origin(get<0>(p1), get<1>(p1))
|
||||
{
|
||||
origin = detail::return_normalized<point_type>(
|
||||
origin = detail::return_normalized<Point>(
|
||||
origin,
|
||||
strategy::normalize::spherical_point());
|
||||
|
||||
using namespace geometry::formula;
|
||||
prev = sph_to_cart3d<vector_type>(p1);
|
||||
next = sph_to_cart3d<vector_type>(p2);
|
||||
direction = cross_product(prev, next);
|
||||
cross = direction = cross_product(prev, next);
|
||||
}
|
||||
|
||||
bool normalize()
|
||||
{
|
||||
T magnitude_sqr = dot_product(direction, direction);
|
||||
T const magnitude_sqr = dot_product(direction, direction);
|
||||
|
||||
// NOTE: shouldn't here math::equals() be called?
|
||||
if (magnitude_sqr > 0)
|
||||
@ -211,7 +177,7 @@ struct collected_vector
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator<(collected_vector const& other) const
|
||||
bool operator<(collected_vector_spherical const& other) const
|
||||
{
|
||||
if (math::equals(get<0>(origin), get<0>(other.origin)))
|
||||
{
|
||||
@ -235,13 +201,13 @@ struct collected_vector
|
||||
// For consistency with side and intersection strategies used by relops
|
||||
// IMPORTANT: this method should be called for previous vector
|
||||
// and next vector should be passed as parameter
|
||||
bool next_is_collinear(collected_vector const& other) const
|
||||
bool next_is_collinear(collected_vector_spherical const& other) const
|
||||
{
|
||||
return formula::sph_side_value(direction, other.next) == 0;
|
||||
return formula::sph_side_value(cross, other.next) == 0;
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
bool operator==(collected_vector const& other) const
|
||||
bool operator==(collected_vector_spherical const& other) const
|
||||
{
|
||||
return math::equals(get<0>(origin), get<0>(other.origin))
|
||||
&& math::equals(get<1>(origin), get<1>(other.origin))
|
||||
@ -250,76 +216,57 @@ struct collected_vector
|
||||
|
||||
private:
|
||||
// For consistency with side and intersection strategies used by relops
|
||||
bool is_collinear(collected_vector const& other) const
|
||||
// NOTE: alternative would be to equal-compare direction's coordinates
|
||||
// or to check if dot product of directions is equal to 1.
|
||||
bool is_collinear(collected_vector_spherical const& other) const
|
||||
{
|
||||
return formula::sph_side_value(direction, other.prev) == 0
|
||||
&& formula::sph_side_value(direction, other.next) == 0;
|
||||
return formula::sph_side_value(cross, other.prev) == 0
|
||||
&& formula::sph_side_value(cross, other.next) == 0;
|
||||
}
|
||||
|
||||
/*bool same_direction(collected_vector const& other) const
|
||||
{
|
||||
return math::equals_with_epsilon(get<0>(direction), get<0>(other.direction))
|
||||
&& math::equals_with_epsilon(get<1>(direction), get<1>(other.direction))
|
||||
&& math::equals_with_epsilon(get<2>(direction), get<2>(other.direction));
|
||||
}*/
|
||||
|
||||
point_type origin; // used for sorting and equality check
|
||||
Point origin; // used for sorting and equality check
|
||||
vector_type direction; // used for sorting, only in operator<
|
||||
vector_type cross; // used for sorting, used for collinearity check
|
||||
vector_type prev; // used for collinearity check, only in operator==
|
||||
vector_type next; // used for collinearity check
|
||||
};
|
||||
|
||||
// Specialization for spherical polar
|
||||
template <typename T, typename Geometry, typename CT>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_polar_tag
|
||||
>
|
||||
: public collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_equatorial_tag
|
||||
>
|
||||
// Version for spherical polar
|
||||
template <typename T, typename Point>
|
||||
struct collected_vector_polar
|
||||
: public collected_vector_spherical<T, Point>
|
||||
{
|
||||
typedef collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_equatorial_tag
|
||||
> base_type;
|
||||
using type = T;
|
||||
using base_point_type
|
||||
= model::point<T, 2, cs::spherical_equatorial<geometry::degree>>;
|
||||
using base_type = collected_vector_spherical<T, base_point_type>;
|
||||
|
||||
collected_vector() {}
|
||||
collected_vector_polar() {}
|
||||
|
||||
template <typename Point>
|
||||
collected_vector(Point const& p1, Point const& p2)
|
||||
collected_vector_polar(Point const& p1, Point const& p2)
|
||||
: base_type(to_equatorial(p1), to_equatorial(p2))
|
||||
{}
|
||||
|
||||
private:
|
||||
template <typename Point>
|
||||
Point to_equatorial(Point const& p)
|
||||
static base_point_type to_equatorial(Point const& p)
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coord_type;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
using coord_type = typename coordinate_type<Point>::type;
|
||||
using constants = math::detail::constants_on_spheroid
|
||||
<
|
||||
coord_type,
|
||||
typename coordinate_system<Point>::type::units
|
||||
> constants;
|
||||
> ;
|
||||
|
||||
coord_type const pi_2 = constants::half_period() / 2;
|
||||
constexpr coord_type pi_2 = constants::half_period() / 2;
|
||||
|
||||
Point res = p;
|
||||
base_point_type res;
|
||||
set<0>(res, get<0>(p));
|
||||
set<1>(res, pi_2 - get<1>(p));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO: specialize collected_vector for geographic_tag
|
||||
// TODO: implement collected_vector type for geographic
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
@ -348,15 +295,11 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
typedef typename boost::range_size<Collection>::type collection_size_t;
|
||||
collection_size_t c_old_size = boost::size(collection);
|
||||
|
||||
typedef typename boost::range_iterator<ClosedClockwiseRange const>::type iterator;
|
||||
|
||||
auto c_old_size = boost::size(collection);
|
||||
bool is_first = true;
|
||||
iterator it = boost::begin(range);
|
||||
auto it = boost::begin(range);
|
||||
|
||||
for (iterator prev = it++; it != boost::end(range); prev = it++)
|
||||
for (auto prev = it++; it != boost::end(range); prev = it++)
|
||||
{
|
||||
typename boost::range_value<Collection>::type v(*prev, *it);
|
||||
|
||||
@ -375,13 +318,10 @@ private:
|
||||
}
|
||||
|
||||
// If first one has same direction as last one, remove first one
|
||||
collection_size_t collected_count = boost::size(collection) - c_old_size;
|
||||
if ( collected_count > 1 )
|
||||
if (boost::size(collection) > c_old_size + 1)
|
||||
{
|
||||
typedef typename boost::range_iterator<Collection>::type c_iterator;
|
||||
c_iterator first = range::pos(collection, c_old_size);
|
||||
|
||||
if (collection.back().next_is_collinear(*first) )
|
||||
auto first = range::pos(collection, c_old_size);
|
||||
if (collection.back().next_is_collinear(*first))
|
||||
{
|
||||
//collection.erase(first);
|
||||
// O(1) instead of O(N)
|
||||
|
@ -160,26 +160,32 @@ struct length_check
|
||||
*/
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
struct collected_vector
|
||||
// Small helper structure do decide to use collect_vectors, or not
|
||||
template <typename Strategy, typename CsTag>
|
||||
struct use_collect_vectors
|
||||
{
|
||||
typedef typename geometry::select_most_precise
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type calculation_type;
|
||||
|
||||
typedef geometry::collected_vector
|
||||
<
|
||||
calculation_type,
|
||||
Geometry1,
|
||||
decltype(std::declval<Strategy>().side())
|
||||
> type;
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct use_collect_vectors<Strategy, cartesian_tag>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
|
||||
template <typename T, typename Point>
|
||||
using type = collected_vector_cartesian<T>;
|
||||
};
|
||||
|
||||
template <typename CV>
|
||||
struct use_collect_vectors<strategy::side::spherical_side_formula<CV>, spherical_tag>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
|
||||
template <typename T, typename Point>
|
||||
using type = collected_vector_spherical<T, Point>;
|
||||
};
|
||||
|
||||
|
||||
template <typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
@ -193,10 +199,24 @@ struct equals_by_collection
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename collected_vector
|
||||
using calculation_type = typename geometry::select_most_precise
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type collected_vector_type;
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type;
|
||||
|
||||
using collected_vector_type = typename use_collect_vectors
|
||||
<
|
||||
decltype(std::declval<Strategy>().side()),
|
||||
typename Strategy::cs_tag
|
||||
>::template type
|
||||
<
|
||||
calculation_type,
|
||||
typename geometry::point_type<Geometry1>::type
|
||||
>;
|
||||
|
||||
std::vector<collected_vector_type> c1, c2;
|
||||
|
||||
@ -211,7 +231,7 @@ struct equals_by_collection
|
||||
std::sort(c1.begin(), c1.end());
|
||||
std::sort(c2.begin(), c2.end());
|
||||
|
||||
// Just check if these vectors are equal.
|
||||
// Check if these vectors are equal.
|
||||
return std::equal(c1.begin(), c1.end(), c2.begin());
|
||||
}
|
||||
};
|
||||
@ -226,47 +246,40 @@ struct equals_by_relate
|
||||
>
|
||||
{};
|
||||
|
||||
// If collect_vectors which is a SideStrategy-dispatched optimization
|
||||
// is implemented in a way consistent with the Intersection/Side Strategy
|
||||
// then collect_vectors is used, otherwise relate is used.
|
||||
// Use either collect_vectors or relate
|
||||
// NOTE: the result could be conceptually different for invalid
|
||||
// geometries in different coordinate systems because collect_vectors
|
||||
// and relate treat invalid geometries differently.
|
||||
template<typename TrivialCheck>
|
||||
struct equals_by_collection_or_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Strategy>
|
||||
using use_vectors = use_collect_vectors
|
||||
<
|
||||
decltype(std::declval<Strategy>().side()),
|
||||
typename Strategy::cs_tag
|
||||
>;
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2, typename Strategy,
|
||||
std::enable_if_t<use_vectors<Strategy>::value, int> = 0
|
||||
>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef std::is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type
|
||||
> enable_relate_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy, enable_relate_type());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
std::false_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_collection<TrivialCheck>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2, typename Strategy,
|
||||
std::enable_if_t<! use_vectors<Strategy>::value, int> = 0
|
||||
>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
std::true_type /*enable_relate*/)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
@ -22,22 +22,23 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/expand.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/expand/services.hpp>
|
||||
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@ -97,10 +98,10 @@ struct expand<default_strategy, false>
|
||||
} //namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
namespace resolve_dynamic
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct expand
|
||||
{
|
||||
template <typename Box, typename Strategy>
|
||||
@ -116,68 +117,24 @@ struct expand
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct expand<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Box, typename Strategy>
|
||||
struct visitor: boost::static_visitor<void>
|
||||
{
|
||||
Box& m_box;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Box& box, Strategy const& strategy)
|
||||
: m_box(box)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
void operator()(Geometry const& geometry) const
|
||||
{
|
||||
return expand<Geometry>::apply(m_box, geometry, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Box, typename Strategy>
|
||||
static inline void
|
||||
apply(Box& box,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
Strategy const& strategy)
|
||||
static inline void apply(Box& box,
|
||||
Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Box, Strategy>(box, strategy),
|
||||
geometry);
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
expand<util::remove_cref_t<decltype(g)>>::apply(box, g, strategy);
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/***
|
||||
*!
|
||||
\brief Expands a box using the extend (envelope) of another geometry (box, point)
|
||||
\ingroup expand
|
||||
\tparam Box type of the box
|
||||
\tparam Geometry of second geometry, to be expanded with the box
|
||||
\param box box to expand another geometry with, might be changed
|
||||
\param geometry other geometry
|
||||
\param strategy_less
|
||||
\param strategy_greater
|
||||
\note Strategy is currently ignored
|
||||
*
|
||||
template
|
||||
<
|
||||
typename Box, typename Geometry,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
inline void expand(Box& box, Geometry const& geometry,
|
||||
StrategyLess const& strategy_less,
|
||||
StrategyGreater const& strategy_greater)
|
||||
{
|
||||
concepts::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
||||
|
||||
dispatch::expand<Box, Geometry>::apply(box, geometry);
|
||||
}
|
||||
***/
|
||||
|
||||
/*!
|
||||
\brief Expands (with strategy)
|
||||
\ingroup expand
|
||||
@ -195,7 +152,7 @@ will be added to the box
|
||||
template <typename Box, typename Geometry, typename Strategy>
|
||||
inline void expand(Box& box, Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
resolve_variant::expand<Geometry>::apply(box, geometry, strategy);
|
||||
resolve_dynamic::expand<Geometry>::apply(box, geometry, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -213,7 +170,7 @@ added to the box
|
||||
template <typename Box, typename Geometry>
|
||||
inline void expand(Box& box, Geometry const& geometry)
|
||||
{
|
||||
resolve_variant::expand<Geometry>::apply(box, geometry, default_strategy());
|
||||
resolve_dynamic::expand<Geometry>::apply(box, geometry, default_strategy());
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@ -54,11 +54,6 @@ private:
|
||||
CSTag
|
||||
>::type rescale_policy_type;
|
||||
|
||||
typedef detail::overlay::get_turn_info
|
||||
<
|
||||
detail::overlay::assign_null_policy
|
||||
> turn_policy;
|
||||
|
||||
public:
|
||||
typedef detail::overlay::turn_info
|
||||
<
|
||||
@ -88,12 +83,11 @@ public:
|
||||
> interrupt_policy;
|
||||
|
||||
// Calculate self-turns, skipping adjacent segments
|
||||
detail::self_get_turn_points::self_turns<false, turn_policy>(geometry,
|
||||
strategy,
|
||||
robust_policy,
|
||||
turns,
|
||||
interrupt_policy,
|
||||
0, true);
|
||||
detail::self_get_turn_points::self_turns
|
||||
<
|
||||
false, detail::overlay::assign_null_policy
|
||||
>(geometry, strategy, robust_policy, turns, interrupt_policy,
|
||||
0, true);
|
||||
|
||||
if (interrupt_policy.has_intersections)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@ -14,12 +14,11 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/policies/is_valid/default_policy.hpp>
|
||||
#include <boost/geometry/policies/is_valid/failing_reason_policy.hpp>
|
||||
@ -90,10 +89,10 @@ struct is_valid<default_strategy, false>
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
namespace resolve_variant
|
||||
namespace resolve_dynamic
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct is_valid
|
||||
{
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
@ -110,39 +109,42 @@ struct is_valid
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct is_valid<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct is_valid<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
struct visitor : boost::static_visitor<bool>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
VisitPolicy& policy_visitor,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
visitor(VisitPolicy& policy, Strategy const& strategy)
|
||||
: m_policy(policy)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
bool operator()(Geometry const& geometry) const
|
||||
bool result = true;
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
return is_valid<Geometry>::apply(geometry, m_policy, m_strategy);
|
||||
}
|
||||
|
||||
VisitPolicy& m_policy;
|
||||
Strategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
static inline bool
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
VisitPolicy& policy_visitor,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<VisitPolicy, Strategy>(policy_visitor, strategy),
|
||||
geometry);
|
||||
result = is_valid<util::remove_cref_t<decltype(g)>>::apply(g, policy_visitor, strategy);
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
template <typename Geometry>
|
||||
struct is_valid<Geometry, geometry_collection_tag>
|
||||
{
|
||||
template <typename VisitPolicy, typename Strategy>
|
||||
static inline bool apply(Geometry const& geometry,
|
||||
VisitPolicy& policy_visitor,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
bool result = true;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
result = is_valid<util::remove_cref_t<decltype(g)>>::apply(g, policy_visitor, strategy);
|
||||
return result;
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
// Undocumented for now
|
||||
@ -151,7 +153,7 @@ inline bool is_valid(Geometry const& geometry,
|
||||
VisitPolicy& visitor,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
return resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
}
|
||||
|
||||
|
||||
@ -175,7 +177,7 @@ template <typename Geometry, typename Strategy>
|
||||
inline bool is_valid(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
is_valid_default_policy<> visitor;
|
||||
return resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
return resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -220,7 +222,7 @@ template <typename Geometry, typename Strategy>
|
||||
inline bool is_valid(Geometry const& geometry, validity_failure_type& failure, Strategy const& strategy)
|
||||
{
|
||||
failure_type_policy<> visitor;
|
||||
bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
bool result = resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
failure = visitor.failure();
|
||||
return result;
|
||||
}
|
||||
@ -271,7 +273,7 @@ inline bool is_valid(Geometry const& geometry, std::string& message, Strategy co
|
||||
{
|
||||
std::ostringstream stream;
|
||||
failing_reason_policy<> visitor(stream);
|
||||
bool result = resolve_variant::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
bool result = resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
|
||||
message = stream.str();
|
||||
return result;
|
||||
}
|
||||
|
@ -3,9 +3,8 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2017-2020.
|
||||
// This file was modified by Oracle on 2017-2021.
|
||||
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -353,21 +352,20 @@ inline typename geometry::coordinate_type<Point1>::type
|
||||
template <typename Turns>
|
||||
inline void calculate_remaining_distance(Turns& turns)
|
||||
{
|
||||
typedef typename boost::range_value<Turns>::type turn_type;
|
||||
typedef typename turn_type::turn_operation_type op_type;
|
||||
using turn_type = typename boost::range_value<Turns>::type;
|
||||
using op_type = typename turn_type::turn_operation_type;
|
||||
|
||||
for (typename boost::range_iterator<Turns>::type
|
||||
it = boost::begin(turns);
|
||||
it != boost::end(turns);
|
||||
++it)
|
||||
typename op_type::comparable_distance_type const zero_distance = 0;
|
||||
|
||||
for (auto it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
turn_type& turn = *it;
|
||||
|
||||
op_type& op0 = turn.operations[0];
|
||||
op_type& op1 = turn.operations[1];
|
||||
|
||||
if (op0.remaining_distance != 0
|
||||
|| op1.remaining_distance != 0)
|
||||
if (op0.remaining_distance != zero_distance
|
||||
|| op1.remaining_distance != zero_distance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -242,33 +242,45 @@ struct base_turn_handler
|
||||
BOOST_GEOMETRY_ASSERT(index_q > 0 && index_q <= 2);
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_USE_RESCALING)
|
||||
ti.operations[IndexP].remaining_distance = distance_measure(ti.point, range_p.at(index_p));
|
||||
ti.operations[IndexQ].remaining_distance = distance_measure(ti.point, range_q.at(index_q));
|
||||
bool const p_in_range = index_p < range_p.size();
|
||||
bool const q_in_range = index_q < range_q.size();
|
||||
ti.operations[IndexP].remaining_distance
|
||||
= p_in_range
|
||||
? distance_measure(ti.point, range_p.at(index_p))
|
||||
: 0;
|
||||
ti.operations[IndexQ].remaining_distance
|
||||
= q_in_range
|
||||
? distance_measure(ti.point, range_q.at(index_q))
|
||||
: 0;
|
||||
|
||||
// pk/q2 is considered as collinear, but there might be
|
||||
// a tiny measurable difference. If so, use that.
|
||||
// Calculate pk // qj-qk
|
||||
bool const p_closer =
|
||||
ti.operations[IndexP].remaining_distance
|
||||
< ti.operations[IndexQ].remaining_distance;
|
||||
auto const dm
|
||||
if (p_in_range && q_in_range)
|
||||
{
|
||||
// pk/q2 is considered as collinear, but there might be
|
||||
// a tiny measurable difference. If so, use that.
|
||||
// Calculate pk // qj-qk
|
||||
bool const p_closer
|
||||
= ti.operations[IndexP].remaining_distance
|
||||
< ti.operations[IndexQ].remaining_distance;
|
||||
auto const dm
|
||||
= p_closer
|
||||
? get_distance_measure(range_q.at(index_q - 1),
|
||||
range_q.at(index_q), range_p.at(index_p))
|
||||
: get_distance_measure(range_p.at(index_p - 1),
|
||||
range_p.at(index_p), range_q.at(index_q));
|
||||
|
||||
if (! dm.is_zero())
|
||||
{
|
||||
// Not truely collinear, distinguish for union/intersection
|
||||
// If p goes left (positive), take that for a union
|
||||
bool const p_left = p_closer ? dm.is_positive() : dm.is_negative();
|
||||
if (! dm.is_zero())
|
||||
{
|
||||
// Not truely collinear, distinguish for union/intersection
|
||||
// If p goes left (positive), take that for a union
|
||||
bool const p_left
|
||||
= p_closer ? dm.is_positive() : dm.is_negative();
|
||||
|
||||
ti.operations[IndexP].operation = p_left
|
||||
? operation_union : operation_intersection;
|
||||
ti.operations[IndexQ].operation = p_left
|
||||
? operation_intersection : operation_union;
|
||||
return;
|
||||
ti.operations[IndexP].operation = p_left
|
||||
? operation_union : operation_intersection;
|
||||
ti.operations[IndexQ].operation = p_left
|
||||
? operation_intersection : operation_union;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3,9 +3,8 @@
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2017-2020.
|
||||
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2017-2021.
|
||||
// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -33,6 +32,9 @@
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
#include <boost/geometry/util/condition.hpp>
|
||||
|
||||
|
||||
@ -271,6 +273,85 @@ struct self_get_turn_points
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
bool Reverse,
|
||||
typename AssignPolicy,
|
||||
typename Strategies,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
|
||||
>
|
||||
struct self_get_turn_points
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Strategies const& strategies,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy,
|
||||
int source_index,
|
||||
bool skip_adjacent)
|
||||
{
|
||||
using turn_policy = detail::overlay::get_turn_info<AssignPolicy>;
|
||||
|
||||
dispatch::self_get_turn_points
|
||||
<
|
||||
Reverse,
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
turn_policy
|
||||
>::apply(geometry, strategies, robust_policy, turns, interrupt_policy,
|
||||
source_index, skip_adjacent);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool Reverse, typename AssignPolicy, typename Strategy>
|
||||
struct self_get_turn_points<Reverse, AssignPolicy, Strategy, false>
|
||||
{
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy,
|
||||
int source_index,
|
||||
bool skip_adjacent)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
self_get_turn_points
|
||||
<
|
||||
Reverse,
|
||||
AssignPolicy,
|
||||
decltype(strategy_converter<Strategy>::get(strategy))
|
||||
>::apply(geometry,
|
||||
strategy_converter<Strategy>::get(strategy),
|
||||
robust_policy,
|
||||
turns,
|
||||
interrupt_policy,
|
||||
source_index,
|
||||
skip_adjacent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace self_get_turn_points
|
||||
{
|
||||
@ -282,13 +363,13 @@ template
|
||||
bool Reverse,
|
||||
typename AssignPolicy,
|
||||
typename Geometry,
|
||||
typename IntersectionStrategy,
|
||||
typename Strategy,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename InterruptPolicy
|
||||
>
|
||||
inline void self_turns(Geometry const& geometry,
|
||||
IntersectionStrategy const& strategy,
|
||||
Strategy const& strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns,
|
||||
InterruptPolicy& interrupt_policy,
|
||||
@ -297,14 +378,9 @@ inline void self_turns(Geometry const& geometry,
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
typedef detail::overlay::get_turn_info<detail::overlay::assign_null_policy> turn_policy;
|
||||
|
||||
dispatch::self_get_turn_points
|
||||
resolve_strategy::self_get_turn_points
|
||||
<
|
||||
Reverse,
|
||||
typename tag<Geometry>::type,
|
||||
Geometry,
|
||||
turn_policy
|
||||
Reverse, AssignPolicy, Strategy
|
||||
>::apply(geometry, strategy, robust_policy, turns, interrupt_policy,
|
||||
source_index, skip_adjacent);
|
||||
}
|
||||
@ -351,12 +427,11 @@ inline void self_turns(Geometry const& geometry,
|
||||
geometry::point_order<Geometry>::value
|
||||
>::value;
|
||||
|
||||
detail::self_get_turn_points::self_turns
|
||||
resolve_strategy::self_get_turn_points
|
||||
<
|
||||
reverse,
|
||||
AssignPolicy
|
||||
>(geometry, strategy, robust_policy, turns, interrupt_policy,
|
||||
source_index, skip_adjacent);
|
||||
reverse, AssignPolicy, Strategy
|
||||
>::apply(geometry, strategy, robust_policy, turns, interrupt_policy,
|
||||
source_index, skip_adjacent);
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,20 +181,16 @@ struct visit_breadth_first<Geometry, dynamic_geometry_tag>
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE: This specialization works partially like std::visit and partially like
|
||||
// std::ranges::for_each. If the argument is rvalue reference then the elements
|
||||
// are passed into the function as rvalue references as well. This is consistent
|
||||
// with std::visit but different than std::ranges::for_each. It's done this way
|
||||
// because visit_breadth_first is also specialized for static and dynamic geometries
|
||||
// which and references for them has to be propagated like that. If this is not
|
||||
// desireable then the support for other kinds of geometries should be dropped and
|
||||
// this algorithm should work only for geometry collection.
|
||||
// This is not a problem right now because only non-rvalue references are passed
|
||||
// but in the future there might be some issues. Consider e.g. passing a temporary
|
||||
// mutable proxy range as geometry collection. In such case the elements would be
|
||||
// passed as rvalue references which would be incorrect.
|
||||
template <typename Geometry>
|
||||
struct visit_breadth_first<Geometry, geometry_collection_tag>
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <bool PassIterator = false>
|
||||
struct visit_breadth_first_impl
|
||||
{
|
||||
template <typename F, typename Geom>
|
||||
static bool apply(F function, Geom && geom)
|
||||
@ -217,7 +213,7 @@ struct visit_breadth_first<Geometry, geometry_collection_tag>
|
||||
bool result = true;
|
||||
traits::iter_visit<util::remove_cref_t<Geom>>::apply([&](auto && g)
|
||||
{
|
||||
result = visit_breadth_first::visit_or_enqueue(
|
||||
result = visit_breadth_first_impl::visit_or_enqueue<PassIterator>(
|
||||
function, std::forward<decltype(g)>(g), queue, it);
|
||||
}, it);
|
||||
|
||||
@ -236,7 +232,7 @@ struct visit_breadth_first<Geometry, geometry_collection_tag>
|
||||
// so this call can be avoided.
|
||||
traits::iter_visit<util::remove_cref_t<Geom>>::apply([&](auto && g)
|
||||
{
|
||||
visit_breadth_first::set_iterators(std::forward<decltype(g)>(g), it, end);
|
||||
visit_breadth_first_impl::set_iterators(std::forward<decltype(g)>(g), it, end);
|
||||
}, queue.front());
|
||||
queue.pop_front();
|
||||
}
|
||||
@ -247,7 +243,7 @@ struct visit_breadth_first<Geometry, geometry_collection_tag>
|
||||
private:
|
||||
template
|
||||
<
|
||||
typename F, typename Geom, typename Iterator,
|
||||
bool PassIter, typename F, typename Geom, typename Iterator,
|
||||
std::enable_if_t<util::is_geometry_collection<Geom>::value, int> = 0
|
||||
>
|
||||
static bool visit_or_enqueue(F &, Geom &&, std::deque<Iterator> & queue, Iterator iter)
|
||||
@ -257,13 +253,22 @@ private:
|
||||
}
|
||||
template
|
||||
<
|
||||
typename F, typename Geom, typename Iterator,
|
||||
std::enable_if_t<! util::is_geometry_collection<Geom>::value, int> = 0
|
||||
bool PassIter, typename F, typename Geom, typename Iterator,
|
||||
std::enable_if_t<! util::is_geometry_collection<Geom>::value && ! PassIter, int> = 0
|
||||
>
|
||||
static bool visit_or_enqueue(F & f, Geom && g, std::deque<Iterator> & , Iterator)
|
||||
{
|
||||
return f(std::forward<Geom>(g));
|
||||
}
|
||||
template
|
||||
<
|
||||
bool PassIter, typename F, typename Geom, typename Iterator,
|
||||
std::enable_if_t<! util::is_geometry_collection<Geom>::value && PassIter, int> = 0
|
||||
>
|
||||
static bool visit_or_enqueue(F & f, Geom && g, std::deque<Iterator> & , Iterator iter)
|
||||
{
|
||||
return f(std::forward<Geom>(g), iter);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
@ -284,6 +289,32 @@ private:
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// NOTE: This specialization works partially like std::visit and partially like
|
||||
// std::ranges::for_each. If the argument is rvalue reference then the elements
|
||||
// are passed into the function as rvalue references as well. This is consistent
|
||||
// with std::visit but different than std::ranges::for_each. It's done this way
|
||||
// because visit_breadth_first is also specialized for static and dynamic geometries
|
||||
// and references for them has to be propagated like that. If this is not
|
||||
// desireable then the support for other kinds of geometries should be dropped and
|
||||
// this algorithm should work only for geometry collection. Or forwarding of rvalue
|
||||
// references should simply be dropped entirely.
|
||||
// This is not a problem right now because only non-rvalue references are passed
|
||||
// but in the future there might be some issues. Consider e.g. passing a temporary
|
||||
// mutable proxy range as geometry collection. In such case the elements would be
|
||||
// passed as rvalue references which would be incorrect.
|
||||
template <typename Geometry>
|
||||
struct visit_breadth_first<Geometry, geometry_collection_tag>
|
||||
: detail::visit_breadth_first_impl<>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
@ -68,6 +68,29 @@ struct distance_strategy_type<Geometry1, Geometry2, Strategies, true, true>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2, typename Strategies,
|
||||
bool IsDynamicOrGC = util::is_dynamic_geometry<Geometry1>::value
|
||||
|| util::is_dynamic_geometry<Geometry2>::value
|
||||
|| util::is_geometry_collection<Geometry1>::value
|
||||
|| util::is_geometry_collection<Geometry2>::value
|
||||
>
|
||||
struct distance_strategy_tag
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategies>
|
||||
struct distance_strategy_tag<Geometry1, Geometry2, Strategies, false>
|
||||
{
|
||||
using type = typename strategy::distance::services::tag
|
||||
<
|
||||
typename distance_strategy_type<Geometry1, Geometry2, Strategies>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
@ -91,11 +114,11 @@ template
|
||||
linear_tag,
|
||||
areal_tag
|
||||
>::type,
|
||||
typename StrategyTag = typename strategy::distance::services::tag
|
||||
typename StrategyTag = typename distance_strategy_tag
|
||||
<
|
||||
typename distance_strategy_type<Geometry1, Geometry2, Strategy>::type
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::value
|
||||
>
|
||||
struct distance : not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2014-2020.
|
||||
// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014-2021.
|
||||
// Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@ -26,21 +26,20 @@
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/geometry/algorithms/detail/counting.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/counting.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@ -140,48 +139,54 @@ struct num_points<Geometry, AddForOpen, multi_tag>
|
||||
#endif
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
namespace resolve_dynamic
|
||||
{
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct num_points
|
||||
{
|
||||
static inline std::size_t apply(Geometry const& geometry,
|
||||
bool add_for_open)
|
||||
static inline std::size_t apply(Geometry const& geometry, bool add_for_open)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
return add_for_open
|
||||
? dispatch::num_points<Geometry, true>::apply(geometry)
|
||||
: dispatch::num_points<Geometry, false>::apply(geometry);
|
||||
? dispatch::num_points<Geometry, true>::apply(geometry)
|
||||
: dispatch::num_points<Geometry, false>::apply(geometry);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct num_points<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct num_points<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
struct visitor: boost::static_visitor<std::size_t>
|
||||
static inline std::size_t apply(Geometry const& geometry, bool add_for_open)
|
||||
{
|
||||
bool m_add_for_open;
|
||||
|
||||
visitor(bool add_for_open): m_add_for_open(add_for_open) {}
|
||||
|
||||
template <typename Geometry>
|
||||
inline std::size_t operator()(Geometry const& geometry) const
|
||||
std::size_t result = 0;
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
return num_points<Geometry>::apply(geometry, m_add_for_open);
|
||||
}
|
||||
};
|
||||
|
||||
static inline std::size_t
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
bool add_for_open)
|
||||
{
|
||||
return boost::apply_visitor(visitor(add_for_open), geometry);
|
||||
result = num_points<util::remove_cref_t<decltype(g)>>::apply(g, add_for_open);
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
template <typename Geometry>
|
||||
struct num_points<Geometry, geometry_collection_tag>
|
||||
{
|
||||
static inline std::size_t apply(Geometry const& geometry, bool add_for_open)
|
||||
{
|
||||
std::size_t result = 0;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
result += num_points<util::remove_cref_t<decltype(g)>>::apply(g, add_for_open);
|
||||
return true;
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -198,7 +203,7 @@ struct num_points<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_points(Geometry const& geometry, bool add_for_open = false)
|
||||
{
|
||||
return resolve_variant::num_points<Geometry>::apply(geometry, add_for_open);
|
||||
return resolve_dynamic::num_points<Geometry>::apply(geometry, add_for_open);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2020, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@ -16,22 +16,19 @@
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/geometry/algorithms/detail/counting.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/counting.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@ -140,11 +137,11 @@ struct num_segments<Geometry, multi_polygon_tag>
|
||||
|
||||
|
||||
|
||||
namespace resolve_variant
|
||||
namespace resolve_dynamic
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct num_segments
|
||||
{
|
||||
static inline std::size_t apply(Geometry const& geometry)
|
||||
@ -156,27 +153,38 @@ struct num_segments
|
||||
};
|
||||
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
struct visitor: boost::static_visitor<std::size_t>
|
||||
static inline std::size_t apply(Geometry const& geometry)
|
||||
{
|
||||
template <typename Geometry>
|
||||
inline std::size_t operator()(Geometry const& geometry) const
|
||||
std::size_t result = 0;
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
return num_segments<Geometry>::apply(geometry);
|
||||
}
|
||||
};
|
||||
|
||||
static inline std::size_t
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
|
||||
{
|
||||
return boost::apply_visitor(visitor(), geometry);
|
||||
result = num_segments<util::remove_cref_t<decltype(g)>>::apply(g);
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace resolve_variant
|
||||
template <typename Geometry>
|
||||
struct num_segments<Geometry, geometry_collection_tag>
|
||||
{
|
||||
static inline std::size_t apply(Geometry const& geometry)
|
||||
{
|
||||
std::size_t result = 0;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
result += num_segments<util::remove_cref_t<decltype(g)>>::apply(g);
|
||||
return true;
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
|
||||
@ -193,7 +201,7 @@ struct num_segments<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
inline std::size_t num_segments(Geometry const& geometry)
|
||||
{
|
||||
return resolve_variant::num_segments<Geometry>::apply(geometry);
|
||||
return resolve_dynamic::num_segments<Geometry>::apply(geometry);
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,20 +21,19 @@
|
||||
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_null.hpp>
|
||||
#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
|
||||
#include <boost/geometry/algorithms/detail/multi_sum.hpp>
|
||||
// #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/closure.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_length_result.hpp>
|
||||
@ -162,9 +161,9 @@ struct perimeter<default_strategy, false>
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
namespace resolve_dynamic {
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename geometry::tag<Geometry>::type>
|
||||
struct perimeter
|
||||
{
|
||||
template <typename Strategy>
|
||||
@ -176,39 +175,40 @@ struct perimeter
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct perimeter<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct perimeter<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
typedef typename default_length_result
|
||||
<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>
|
||||
>::type result_type;
|
||||
|
||||
template <typename Strategy>
|
||||
struct visitor: boost::static_visitor<result_type>
|
||||
static inline typename default_length_result<Geometry>::type
|
||||
apply(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy): m_strategy(strategy) {}
|
||||
|
||||
template <typename Geometry>
|
||||
typename default_length_result<Geometry>::type
|
||||
operator()(Geometry const& geometry) const
|
||||
typename default_length_result<Geometry>::type result = 0;
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
return perimeter<Geometry>::apply(geometry, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline result_type
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
|
||||
result = perimeter<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
template <typename Geometry>
|
||||
struct perimeter<Geometry, geometry_collection_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline typename default_length_result<Geometry>::type
|
||||
apply(Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
typename default_length_result<Geometry>::type result = 0;
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
result += perimeter<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
|
||||
return true;
|
||||
}, geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -232,7 +232,7 @@ inline typename default_length_result<Geometry>::type perimeter(
|
||||
Geometry const& geometry)
|
||||
{
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
return resolve_variant::perimeter<Geometry>::apply(geometry, default_strategy());
|
||||
return resolve_dynamic::perimeter<Geometry>::apply(geometry, default_strategy());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -254,7 +254,7 @@ inline typename default_length_result<Geometry>::type perimeter(
|
||||
Geometry const& geometry, Strategy const& strategy)
|
||||
{
|
||||
// detail::throw_on_empty_input(geometry);
|
||||
return resolve_variant::perimeter<Geometry>::apply(geometry, strategy);
|
||||
return resolve_dynamic::perimeter<Geometry>::apply(geometry, strategy);
|
||||
}
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
@ -31,15 +31,13 @@
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/clear.hpp>
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/detail/dummy_geometries.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/visit.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
#include <boost/geometry/algorithms/perimeter.hpp>
|
||||
@ -50,7 +48,9 @@
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/mutable_range.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/visit.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/concepts/simplify_concept.hpp>
|
||||
@ -60,6 +60,8 @@
|
||||
#include <boost/geometry/strategies/simplify/geographic.hpp>
|
||||
#include <boost/geometry/strategies/simplify/spherical.hpp>
|
||||
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
|
||||
#include <boost/geometry/io/dsv/write.hpp>
|
||||
#endif
|
||||
@ -301,6 +303,23 @@ struct simplify_range_insert
|
||||
};
|
||||
|
||||
|
||||
struct simplify_copy_assign
|
||||
{
|
||||
template
|
||||
<
|
||||
typename In, typename Out, typename Distance,
|
||||
typename Impl, typename Strategies
|
||||
>
|
||||
static inline void apply(In const& in, Out& out,
|
||||
Distance const& ,
|
||||
Impl const& ,
|
||||
Strategies const& )
|
||||
{
|
||||
out = in;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct simplify_copy
|
||||
{
|
||||
template
|
||||
@ -615,6 +634,17 @@ struct simplify<Point, point_tag>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment>
|
||||
struct simplify<Segment, segment_tag>
|
||||
: detail::simplify::simplify_copy_assign
|
||||
{};
|
||||
|
||||
template <typename Box>
|
||||
struct simplify<Box, box_tag>
|
||||
: detail::simplify::simplify_copy_assign
|
||||
{};
|
||||
|
||||
|
||||
// Linestring, keep 2 points (unless those points are the same)
|
||||
template <typename Linestring>
|
||||
struct simplify<Linestring, linestring_tag>
|
||||
@ -803,9 +833,9 @@ struct simplify_insert<default_strategy, false>
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
namespace resolve_dynamic {
|
||||
|
||||
template <typename Geometry>
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct simplify
|
||||
{
|
||||
template <typename Distance, typename Strategy>
|
||||
@ -818,43 +848,46 @@ struct simplify
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct simplify<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry>
|
||||
struct simplify<Geometry, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Distance, typename Strategy>
|
||||
struct visitor: boost::static_visitor<void>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Geometry& out,
|
||||
Distance const& max_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Distance const& m_max_distance;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Distance const& max_distance, Strategy const& strategy)
|
||||
: m_max_distance(max_distance)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry>
|
||||
void operator()(Geometry const& geometry, Geometry& out) const
|
||||
traits::visit<Geometry>::apply([&](auto const& g)
|
||||
{
|
||||
simplify<Geometry>::apply(geometry, out, m_max_distance, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Distance, typename Strategy>
|
||||
static inline void
|
||||
apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& out,
|
||||
Distance const& max_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
boost::apply_visitor(
|
||||
visitor<Distance, Strategy>(max_distance, strategy),
|
||||
geometry,
|
||||
out
|
||||
);
|
||||
using geom_t = util::remove_cref_t<decltype(g)>;
|
||||
geom_t o;
|
||||
simplify<geom_t>::apply(g, o, max_distance, strategy);
|
||||
out = std::move(o);
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
template <typename Geometry>
|
||||
struct simplify<Geometry, geometry_collection_tag>
|
||||
{
|
||||
template <typename Distance, typename Strategy>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
Geometry& out,
|
||||
Distance const& max_distance,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
using geom_t = util::remove_cref_t<decltype(g)>;
|
||||
geom_t o;
|
||||
simplify<geom_t>::apply(g, o, max_distance, strategy);
|
||||
traits::emplace_back<Geometry>::apply(out, std::move(o));
|
||||
return true;
|
||||
}, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@ -882,7 +915,7 @@ inline void simplify(Geometry const& geometry, Geometry& out,
|
||||
|
||||
geometry::clear(out);
|
||||
|
||||
resolve_variant::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
|
||||
resolve_dynamic::simplify<Geometry>::apply(geometry, out, max_distance, strategy);
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,39 +45,43 @@ struct geometry_id
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<point_tag> : std::integral_constant<int, 1> {};
|
||||
struct geometry_id<point_tag> : std::integral_constant<int, 1> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<linestring_tag> : std::integral_constant<int, 2> {};
|
||||
struct geometry_id<linestring_tag> : std::integral_constant<int, 2> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<polygon_tag> : std::integral_constant<int, 3> {};
|
||||
struct geometry_id<polygon_tag> : std::integral_constant<int, 3> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<multi_point_tag> : std::integral_constant<int, 4> {};
|
||||
struct geometry_id<multi_point_tag> : std::integral_constant<int, 4> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<multi_linestring_tag> : std::integral_constant<int, 5> {};
|
||||
struct geometry_id<multi_linestring_tag> : std::integral_constant<int, 5> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<multi_polygon_tag> : std::integral_constant<int, 6> {};
|
||||
struct geometry_id<multi_polygon_tag> : std::integral_constant<int, 6> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<segment_tag> : std::integral_constant<int, 92> {};
|
||||
struct geometry_id<geometry_collection_tag> : std::integral_constant<int, 7> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<ring_tag> : std::integral_constant<int, 93> {};
|
||||
struct geometry_id<segment_tag> : std::integral_constant<int, 92> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<box_tag> : std::integral_constant<int, 94> {};
|
||||
struct geometry_id<ring_tag> : std::integral_constant<int, 93> {};
|
||||
|
||||
|
||||
template <>
|
||||
struct geometry_id<box_tag> : std::integral_constant<int, 94> {};
|
||||
|
||||
|
||||
} // namespace core_dispatch
|
||||
|
@ -4,8 +4,8 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2020.
|
||||
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2020-2021.
|
||||
// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
@ -21,10 +21,12 @@
|
||||
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/geometry/core/geometry_types.hpp>
|
||||
#include <boost/geometry/core/ring_type.hpp>
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/util/sequence.hpp>
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
|
||||
@ -137,6 +139,36 @@ struct point_type<multi_polygon_tag, MultiPolygon>
|
||||
};
|
||||
|
||||
|
||||
template <typename DynamicGeometry>
|
||||
struct point_type<dynamic_geometry_tag, DynamicGeometry>
|
||||
{
|
||||
using geometry_t = typename util::sequence_front
|
||||
<
|
||||
typename traits::geometry_types<DynamicGeometry>::type
|
||||
>::type;
|
||||
using type = typename point_type
|
||||
<
|
||||
typename tag<geometry_t>::type,
|
||||
typename util::remove_cptrref<geometry_t>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
|
||||
template <typename GeometryCollection>
|
||||
struct point_type<geometry_collection_tag, GeometryCollection>
|
||||
{
|
||||
using geometry_t = typename util::sequence_front
|
||||
<
|
||||
typename traits::geometry_types<GeometryCollection>::type
|
||||
>::type;
|
||||
using type = typename point_type
|
||||
<
|
||||
typename tag<geometry_t>::type,
|
||||
typename util::remove_cptrref<geometry_t>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace core_dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright (c) 2013 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2016-2020.
|
||||
// Modifications copyright (c) 2016-2020 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2016-2021.
|
||||
// Modifications copyright (c) 2016-2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
@ -53,8 +53,8 @@ struct less<Type, false>
|
||||
template <typename Ratio>
|
||||
static inline bool apply(Ratio const& lhs, Ratio const& rhs)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(lhs.denominator() != 0);
|
||||
BOOST_GEOMETRY_ASSERT(rhs.denominator() != 0);
|
||||
BOOST_GEOMETRY_ASSERT(lhs.denominator() != Type(0));
|
||||
BOOST_GEOMETRY_ASSERT(rhs.denominator() != Type(0));
|
||||
Type const a = lhs.numerator() / lhs.denominator();
|
||||
Type const b = rhs.numerator() / rhs.denominator();
|
||||
return ! geometry::math::equals(a, b)
|
||||
@ -86,8 +86,8 @@ struct equal<Type, false>
|
||||
template <typename Ratio>
|
||||
static inline bool apply(Ratio const& lhs, Ratio const& rhs)
|
||||
{
|
||||
BOOST_GEOMETRY_ASSERT(lhs.denominator() != 0);
|
||||
BOOST_GEOMETRY_ASSERT(rhs.denominator() != 0);
|
||||
BOOST_GEOMETRY_ASSERT(lhs.denominator() != Type(0));
|
||||
BOOST_GEOMETRY_ASSERT(rhs.denominator() != Type(0));
|
||||
Type const a = lhs.numerator() / lhs.denominator();
|
||||
Type const b = rhs.numerator() / rhs.denominator();
|
||||
return geometry::math::equals(a, b);
|
||||
@ -144,7 +144,8 @@ class segment_ratio
|
||||
// Type-alias for the type itself
|
||||
using thistype = segment_ratio<Type>;
|
||||
|
||||
public :
|
||||
public:
|
||||
using int_type = Type;
|
||||
|
||||
inline segment_ratio()
|
||||
: m_numerator(0)
|
||||
@ -231,7 +232,7 @@ public :
|
||||
);
|
||||
}
|
||||
|
||||
inline bool is_zero() const { return math::equals(m_numerator, 0); }
|
||||
inline bool is_zero() const { return math::equals(m_numerator, Type(0)); }
|
||||
inline bool is_one() const { return math::equals(m_numerator, m_denominator); }
|
||||
inline bool on_segment() const
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/covered_by.hpp>
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
@ -118,11 +118,14 @@ struct cartesian_point_box_by_side
|
||||
template <typename Point, typename Box>
|
||||
static inline bool apply(Point const& point, Box const& box)
|
||||
{
|
||||
using side_strategy_type
|
||||
= typename strategy::side::services::default_strategy
|
||||
<cartesian_tag, CalculationType>::type;
|
||||
|
||||
return within::detail::point_in_box_by_side
|
||||
<
|
||||
within::detail::decide_within
|
||||
>(point, box,
|
||||
strategy::side::side_robust<CalculationType>());
|
||||
>(point, box, side_strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
@ -189,11 +192,13 @@ struct cartesian_point_box_by_side
|
||||
template <typename Point, typename Box>
|
||||
static bool apply(Point const& point, Box const& box)
|
||||
{
|
||||
using side_strategy_type
|
||||
= typename strategy::side::services::default_strategy
|
||||
<cartesian_tag, CalculationType>::type;
|
||||
return within::detail::point_in_box_by_side
|
||||
<
|
||||
within::detail::decide_covered_by
|
||||
>(point, box,
|
||||
strategy::side::side_robust<CalculationType>());
|
||||
>(point, box, side_strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -86,8 +86,11 @@ struct strategy_converter<strategy::area::geographic<FP, SO, S, CT> >
|
||||
: strategies::area::geographic<FP, S, CT>(spheroid)
|
||||
{}
|
||||
|
||||
using strategies::area::geographic<FP, S, CT>::area;
|
||||
|
||||
template <typename Geometry>
|
||||
auto area(Geometry const&) const
|
||||
auto area(Geometry const&,
|
||||
std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
|
||||
{
|
||||
return strategy::area::geographic<FP, SO, S, CT>(this->m_spheroid);
|
||||
}
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include <boost/geometry/strategy/cartesian/envelope.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/expand_box.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/expand_segment.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
|
||||
@ -174,7 +173,7 @@ struct cartesian_segments
|
||||
// Up to now, division was postponed. Here we divide using numerator/
|
||||
// denominator. In case of integer this results in an integer
|
||||
// division.
|
||||
BOOST_GEOMETRY_ASSERT(ratio.denominator() != 0);
|
||||
BOOST_GEOMETRY_ASSERT(ratio.denominator() != typename SegmentRatio::int_type(0));
|
||||
|
||||
typedef typename promote_integral<CoordinateType>::type calc_type;
|
||||
|
||||
@ -439,7 +438,9 @@ struct cartesian_segments
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
typedef side::side_robust<CalculationType> side_strategy_type;
|
||||
using side_strategy_type
|
||||
= typename side::services::default_strategy
|
||||
<cartesian_tag, CalculationType>::type;
|
||||
side_info sides;
|
||||
sides.set<0>(side_strategy_type::apply(q1, q2, p1),
|
||||
side_strategy_type::apply(q1, q2, p2));
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategy/cartesian/expand_point.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
|
||||
@ -116,7 +116,9 @@ public:
|
||||
else // count == 2 || count == -2
|
||||
{
|
||||
// 1 left, -1 right
|
||||
typedef side::side_robust<CalculationType> side_strategy_type;
|
||||
using side_strategy_type
|
||||
= typename side::services::default_strategy
|
||||
<cartesian_tag, CalculationType>::type;
|
||||
side = side_strategy_type::apply(s1, s2, point);
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,11 @@
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
|
||||
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
|
||||
#include <boost/geometry/strategies/convex_hull/services.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
#include <boost/geometry/util/type_traits.hpp>
|
||||
|
||||
|
||||
@ -42,7 +42,10 @@ public:
|
||||
|
||||
static auto side()
|
||||
{
|
||||
return strategy::side::side_robust<CalculationType>();
|
||||
using side_strategy_type
|
||||
= typename strategy::side::services::default_strategy
|
||||
<cartesian_tag, CalculationType>::type;
|
||||
return side_strategy_type();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -68,6 +68,13 @@ struct cartesian
|
||||
{
|
||||
return strategy::envelope::cartesian<CalculationType>();
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Box>
|
||||
static auto envelope(Geometry const&, Box const&,
|
||||
typename util::enable_if_geometry_collection_t<Geometry> * = nullptr)
|
||||
{
|
||||
return strategy::envelope::cartesian<CalculationType>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -86,6 +86,16 @@ public:
|
||||
FormulaPolicy, Spheroid, CalculationType
|
||||
>(base_t::m_spheroid);
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Box>
|
||||
auto envelope(Geometry const&, Box const&,
|
||||
typename util::enable_if_geometry_collection_t<Geometry> * = nullptr) const
|
||||
{
|
||||
return strategy::envelope::geographic
|
||||
<
|
||||
FormulaPolicy, Spheroid, CalculationType
|
||||
>(base_t::m_spheroid);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -79,6 +79,13 @@ struct spherical
|
||||
{
|
||||
return strategy::envelope::spherical<CalculationType>();
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Box>
|
||||
static auto envelope(Geometry const&, Box const&,
|
||||
typename util::enable_if_geometry_collection_t<Geometry> * = nullptr)
|
||||
{
|
||||
return strategy::envelope::spherical<CalculationType>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include <boost/geometry/policies/relate/intersection_policy.hpp>
|
||||
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
#include <boost/geometry/strategies/intersection_result.hpp>
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/is_convex/services.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
|
@ -158,7 +158,10 @@ public:
|
||||
|
||||
static auto side()
|
||||
{
|
||||
return strategy::side::side_robust<CalculationType>();
|
||||
using side_strategy_type
|
||||
= typename strategy::side::services::default_strategy
|
||||
<cartesian_tag, CalculationType>::type;
|
||||
return side_strategy_type();
|
||||
}
|
||||
|
||||
// within
|
||||
|
@ -24,17 +24,15 @@
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/geometry/core/config.hpp>
|
||||
#include <boost/geometry/arithmetic/determinant.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
|
||||
#include <boost/geometry/strategies/compare.hpp>
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
|
||||
#include <boost/geometry/strategy/cartesian/envelope.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
|
||||
@ -254,6 +252,23 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_USE_RESCALING)
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
namespace services
|
||||
{
|
||||
|
||||
template <typename CalculationType>
|
||||
struct default_strategy<cartesian_tag, CalculationType>
|
||||
{
|
||||
typedef side_by_triangle<CalculationType> type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}} // namespace strategy::side
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
@ -18,6 +18,7 @@
|
||||
#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP
|
||||
|
||||
#include <boost/geometry/core/config.hpp>
|
||||
#include <boost/geometry/strategy/cartesian/side_non_robust.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
@ -177,6 +178,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#ifdef BOOST_GEOMETRY_USE_RESCALING
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
namespace services
|
||||
@ -190,6 +192,7 @@ struct default_strategy<cartesian_tag, CalculationType>
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}} // namespace strategy::side
|
||||
|
@ -26,7 +26,16 @@ test-suite boost-geometry-algorithms-buffer
|
||||
[ run buffer_multi_linestring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_multi_linestring ]
|
||||
[ run buffer_multi_polygon.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_multi_polygon ]
|
||||
[ run buffer_linestring_aimes.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_linestring_aimes ]
|
||||
# Uncomment next line if you want to test this manually; requires access to data/ folder
|
||||
# TODO
|
||||
# [ run buffer_linestring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_linestring_norescale ]
|
||||
# [ run buffer_multi_linestring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_multi_linestring_norescale ]
|
||||
[ run buffer_ring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_ring_norescale ]
|
||||
[ run buffer_polygon.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_polygon_norescale ]
|
||||
[ run buffer_multi_point.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_multi_point_norescale ]
|
||||
[ run buffer_multi_polygon.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_multi_polygon_norescale ]
|
||||
[ run buffer_linestring_aimes.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_linestring_aimes_norescale ]
|
||||
# Uncomment next lines if you want to test this manually; requires access to data/ folder
|
||||
# [ run buffer_countries.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_countries ]
|
||||
# [ run buffer_countries.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_buffer_countries_norescale ]
|
||||
;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Boost.Geometry
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2017-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
@ -159,6 +161,17 @@ inline void test_geometry(std::string const& wkt, Check const& check)
|
||||
bg::densify(g, o, max_distance);
|
||||
|
||||
check_result(g, o, max_distance, def_s, check);
|
||||
|
||||
using variant_t = boost::variant<G, typename bg::point_type<G>::type>;
|
||||
variant_t v = g, vo;
|
||||
bg::densify(v, vo, max_distance);
|
||||
|
||||
check(v, vo, def_s);
|
||||
|
||||
bg::model::geometry_collection<variant_t> gc{v}, gco;
|
||||
bg::densify(gc, gco, max_distance);
|
||||
|
||||
check(gc, gco, def_s);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -491,6 +491,24 @@ void test_variant()
|
||||
//BOOST_CHECK_CLOSE(bg::distance(point, v2, s), bg::distance(point, point, s), 0.0001);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_geometry_collection()
|
||||
{
|
||||
using point_type = bg::model::point<T, 2, bg::cs::cartesian>;
|
||||
using segment_type = bg::model::segment<point_type>;
|
||||
using box_type = bg::model::box<point_type>;
|
||||
using variant_type = boost::variant<point_type, segment_type, box_type>;
|
||||
using gc_type = bg::model::geometry_collection<variant_type>;
|
||||
|
||||
point_type p1 {1, 3}, p2 {2, 3};
|
||||
segment_type s1 {{2, 2}, {4, 4}}, s2 {{3, 2}, {5, 4}};
|
||||
gc_type gc1 {p1, s1}, gc2 {p2, s2};
|
||||
|
||||
BOOST_CHECK_CLOSE(bg::distance(p1, gc2), bg::distance(p1, p2), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(gc1, s2), bg::distance(s1, s2), 0.0001);
|
||||
BOOST_CHECK_CLOSE(bg::distance(gc1, gc2), bg::distance(s1, s2), 0.0001);
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
#ifdef TEST_ARRAY
|
||||
@ -525,5 +543,7 @@ int test_main(int, char* [])
|
||||
test_variant<double>();
|
||||
test_variant<int>();
|
||||
|
||||
test_geometry_collection<double>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/geometries/geometry_collection.hpp>
|
||||
#include <boost/geometry/strategies/strategies.hpp>
|
||||
|
||||
#include <boost/geometry/io/wkt/read.hpp>
|
||||
@ -97,6 +98,10 @@ void test_envelope(std::string const& wkt,
|
||||
check_result<box_type, bg::dimension<Geometry>::type::value>
|
||||
::apply(b, x1, y1, z1, x2, y2, z2);
|
||||
|
||||
bg::model::geometry_collection<boost::variant<Geometry>> gc{v};
|
||||
bg::envelope(gc, b);
|
||||
check_result<box_type, bg::dimension<Geometry>::type::value>
|
||||
::apply(b, x1, y1, z1, x2, y2, z2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,4 +19,5 @@ test-suite boost-geometry-algorithms-equals
|
||||
[ run equals.cpp : : : : algorithms_equals ]
|
||||
[ run equals_multi.cpp : : : : algorithms_equals_multi ]
|
||||
[ run equals_on_spheroid.cpp : : : : algorithms_equals_on_spheroid ]
|
||||
[ run equals_sph.cpp : : : : algorithms_equals_sph ]
|
||||
;
|
||||
|
@ -233,3 +233,32 @@ BOOST_AUTO_TEST_CASE( equals_segment_segment_geo )
|
||||
test_segment_segment<bgm::point<double, 2, cs_type> >("geo");
|
||||
test_segment_segment<bgm::point<long double, 2, cs_type> >("geo");
|
||||
}
|
||||
|
||||
// This version uses collect_vectors (because its side
|
||||
// strategy is spherical_side_formula) and fails
|
||||
BOOST_AUTO_TEST_CASE( equals_ring_ring_se)
|
||||
{
|
||||
using cs_type = bg::cs::spherical_equatorial<bg::degree> ;
|
||||
using ring_type = bgm::ring<bgm::point<double, 2, cs_type> >;
|
||||
|
||||
test_geometry<ring_type, ring_type>("ring_simplex",
|
||||
"POLYGON((10 50,10 51,11 50,10 50))",
|
||||
"POLYGON((10 50,10 51,11 50,10 50))",
|
||||
true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( equals_ring_ring_geo )
|
||||
{
|
||||
using cs_type = bg::cs::geographic<bg::degree> ;
|
||||
using ring_type = bgm::ring<bgm::point<double, 2, cs_type> >;
|
||||
|
||||
test_geometry<ring_type, ring_type>("ring_simplex",
|
||||
"POLYGON((10 50,10 51,11 50,10 50))",
|
||||
"POLYGON((10 50,10 51,11 50,10 50))",
|
||||
true);
|
||||
|
||||
test_geometry<ring_type, ring_type>("ring_simplex_false",
|
||||
"POLYGON((10 50,10 51,11 50,10 50))",
|
||||
"POLYGON((10 50,10 51.01,11 50,10 50))",
|
||||
false);
|
||||
}
|
||||
|
@ -147,5 +147,13 @@ int test_main( int , char* [] )
|
||||
{
|
||||
test_all<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> > >();
|
||||
|
||||
// TODO: the polar version needs several traits more, for example in cs_tag,
|
||||
// to compile properly.
|
||||
//test_all<bg::model::point<double, 2, bg::cs::polar<bg::degree> > >();
|
||||
|
||||
#if defined(BOOST_GEOMETRY_TEST_FAILURES)
|
||||
test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,7 +26,10 @@
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
||||
|
||||
struct no_strategy {};
|
||||
struct no_strategy
|
||||
{
|
||||
using cs_tag = void;
|
||||
};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
bool call_equals(Geometry1 const& geometry1,
|
||||
@ -60,7 +63,9 @@ void check_geometry(Geometry1 const& geometry1,
|
||||
<< " equals: " << wkt1
|
||||
<< " to " << wkt2
|
||||
<< " -> Expected: " << expected
|
||||
<< " detected: " << detected);
|
||||
<< " detected: " << detected
|
||||
<< " strategy: " << typeid(Strategy).name()
|
||||
<< " cs: " << typeid(typename Strategy::cs_tag).name());
|
||||
|
||||
detected = call_equals(geometry2, geometry1, strategy);
|
||||
|
||||
@ -69,7 +74,8 @@ void check_geometry(Geometry1 const& geometry1,
|
||||
<< " equals: " << wkt2
|
||||
<< " to " << wkt1
|
||||
<< " -> Expected: " << expected
|
||||
<< " detected: " << detected);
|
||||
<< " strategy: " << typeid(Strategy).name()
|
||||
<< " cs: " << typeid(typename Strategy::cs_tag).name());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
@ -27,6 +27,8 @@
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometry_collection.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_valid_point )
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
@ -1414,3 +1416,40 @@ BOOST_AUTO_TEST_CASE( test_is_valid_variant )
|
||||
vg = invalid_polygon;
|
||||
test::apply("v04", vg, false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_valid_geometry_collection )
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
std::cout << "************************************" << std::endl;
|
||||
std::cout << " is_valid: geometry collection" << std::endl;
|
||||
std::cout << "************************************" << std::endl;
|
||||
#endif
|
||||
|
||||
using polygon_type = bg::model::polygon<point_type>; // cw, closed
|
||||
using variant_type = boost::variant
|
||||
<
|
||||
linestring_type, multi_linestring_type, polygon_type
|
||||
>;
|
||||
using gc_type = bg::model::geometry_collection<variant_type>;
|
||||
|
||||
typedef test_valid_variant<gc_type> test;
|
||||
|
||||
gc_type gc;
|
||||
|
||||
linestring_type valid_linestring =
|
||||
from_wkt<linestring_type>("LINESTRING(0 0,1 0)");
|
||||
multi_linestring_type invalid_multi_linestring =
|
||||
from_wkt<multi_linestring_type>("MULTILINESTRING((0 0,1 0),(0 0))");
|
||||
polygon_type valid_polygon =
|
||||
from_wkt<polygon_type>("POLYGON((0 0,1 1,1 0,0 0))");
|
||||
polygon_type invalid_polygon =
|
||||
from_wkt<polygon_type>("POLYGON((0 0,2 2,2 0,1 0))");
|
||||
|
||||
gc = {valid_linestring, valid_polygon};
|
||||
test::apply("gc01", gc, true);
|
||||
gc = {invalid_multi_linestring, valid_polygon};
|
||||
test::apply("gc02", gc, false);
|
||||
gc = {valid_linestring, invalid_polygon};
|
||||
test::apply("gc03", gc, false);
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2021.
|
||||
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -67,6 +71,12 @@ int test_main(int, char* [])
|
||||
typedef bg::model::polygon<point, true, false> open_polygon;
|
||||
typedef bg::model::multi_polygon<open_polygon> open_multi_polygon;
|
||||
|
||||
using variant = boost::variant<linestring, polygon>;
|
||||
using open_variant = boost::variant<linestring, open_polygon>;
|
||||
|
||||
using geometry_collection = bg::model::geometry_collection<variant>;
|
||||
using open_geometry_collection = bg::model::geometry_collection<open_variant>;
|
||||
|
||||
test_num_points<point>("POINT(0 0)", 1u);
|
||||
test_num_points<linestring>("LINESTRING(0 0,1 1)", 2u);
|
||||
test_num_points<segment>("LINESTRING(0 0,1 1)", 2u);
|
||||
@ -89,6 +99,12 @@ int test_main(int, char* [])
|
||||
test_num_points<open_multi_polygon>("MULTIPOLYGON(((0 0,0 10,10 10,10 0)),((0 10,1 10,1 9)))", 7u, 9u);
|
||||
test_num_points<open_multi_polygon>("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((0 10,1 10,1 9,0 10)))", 7u, 9u);
|
||||
|
||||
test_num_points<variant>("POLYGON((0 0,1 1,0 1,0 0))", 4u);
|
||||
test_num_points<open_variant>("POLYGON((0 0,1 1,0 1))", 3u, 4u);
|
||||
|
||||
test_num_points<geometry_collection>("GEOMETRYCOLLECTION(POLYGON((0 0,1 1,0 1,0 0)),LINESTRING(0 0,1 1))", 6u);
|
||||
test_num_points<open_geometry_collection>("GEOMETRYCOLLECTION(POLYGON((0 0,1 1,0 1)),LINESTRING(0 0,1 1))", 5u, 6u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2014, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2014-2021, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
@ -289,3 +290,16 @@ BOOST_AUTO_TEST_CASE( test_variant )
|
||||
variant_geometry = p_closed;
|
||||
tester::apply(variant_geometry, 4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_geometry_collection )
|
||||
{
|
||||
using variant = boost::variant<linestring, polygon_cw_closed>;
|
||||
using geometry_collection = bg::model::geometry_collection<variant>;
|
||||
|
||||
using tester = test_num_segments<geometry_collection>;
|
||||
|
||||
geometry_collection gc;
|
||||
bg::read_wkt("GEOMETRYCOLLECTION(LINESTRING(0 0,1 1,2 2),POLYGON((0 0,0 1,1 1,1 0,0 0)))", gc);
|
||||
|
||||
tester::apply(gc, 6);
|
||||
}
|
||||
|
@ -16,16 +16,15 @@
|
||||
|
||||
test-suite boost-geometry-algorithms-difference
|
||||
:
|
||||
[ run difference.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_difference ]
|
||||
[ run difference.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference ]
|
||||
[ run difference_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference_multi ]
|
||||
[ run difference.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_difference_norescale ]
|
||||
[ run difference_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_difference_multi_norescale ]
|
||||
[ run difference_multi_spike.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference_multi_spike ]
|
||||
[ run difference_areal_linear.cpp : : : : algorithms_difference_areal_linear ]
|
||||
[ run difference_l_a_sph.cpp : : : : algorithms_difference_l_a_sph ]
|
||||
[ run difference_linear_linear.cpp : : : : algorithms_difference_linear_linear ]
|
||||
[ run difference_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_difference_multi ]
|
||||
[ run difference_multi_areal_linear.cpp : : : : algorithms_difference_multi_areal_linear ]
|
||||
[ run difference_multi_spike.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_difference_multi_spike ]
|
||||
[ run difference_pl_a.cpp : : : : algorithms_difference_pl_a ]
|
||||
[ run difference_pl_l.cpp : : : : algorithms_difference_pl_l ]
|
||||
[ run difference_pl_pl.cpp : : : : algorithms_difference_pl_pl ]
|
||||
|
@ -51,7 +51,7 @@ void test_spikes_in_ticket_8364()
|
||||
"MULTIPOLYGON(((1032 2556,1778 2556,1032 2130,1032 2556)),((3234 2580,3234 2556,1778 2556,2136 2760,3234 2580)))",
|
||||
count_set(1, 2), -1, expectation_limits(2615783, 2616030), // SQL Server: 2616029.55616044
|
||||
1, -1, expectation_limits(161054, 161134), // SQL Server: 161054.560110092
|
||||
count_set(1, 3));
|
||||
count_set(1, 3), ignore_validity);
|
||||
}
|
||||
|
||||
template <typename P, bool ClockWise, bool Closed>
|
||||
|
@ -16,12 +16,12 @@
|
||||
|
||||
test-suite boost-geometry-algorithms-intersection
|
||||
:
|
||||
[ run intersection.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_intersection ]
|
||||
[ run intersection.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_intersection ]
|
||||
[ run intersection_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_intersection_multi ]
|
||||
[ run intersection.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_intersection_norescale ]
|
||||
[ run intersection_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_intersection_multi_norescale ]
|
||||
[ run intersection_areal_areal_linear.cpp : : : : algorithms_intersection_areal_areal_linear ]
|
||||
[ run intersection_linear_linear.cpp : : : : algorithms_intersection_linear_linear ]
|
||||
[ run intersection_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_intersection_multi ]
|
||||
[ run intersection_pl_a.cpp : : : : algorithms_intersection_pl_a ]
|
||||
[ run intersection_pl_l.cpp : : : : algorithms_intersection_pl_l ]
|
||||
[ run intersection_pl_pl.cpp : : : : algorithms_intersection_pl_pl ]
|
||||
|
@ -16,14 +16,14 @@
|
||||
|
||||
test-suite boost-geometry-algorithms-union
|
||||
:
|
||||
[ run union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_union ]
|
||||
[ run union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union ]
|
||||
[ run union_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union_multi ]
|
||||
[ run union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_union_norescale ]
|
||||
[ run union_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_NO_ROBUSTNESS : algorithms_union_multi_norescale ]
|
||||
[ run union_aa_geo.cpp : : : : algorithms_union_aa_geo ]
|
||||
[ run union_aa_sph.cpp : : : : algorithms_union_aa_sph ]
|
||||
[ run union_linear_linear.cpp : : : : algorithms_union_linear_linear ]
|
||||
[ run union_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
|
||||
: algorithms_union_multi ]
|
||||
[ run union_pl_pl.cpp : : : : algorithms_union_pl_pl ]
|
||||
[ run union_tupled.cpp : : : : algorithms_union_tupled ]
|
||||
[ run union_other_types.cpp : : : : algorithms_union_other_types ]
|
||||
[ run union_other_types.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union_other_types ]
|
||||
;
|
||||
|
@ -113,6 +113,7 @@ int test_main(int, char* [])
|
||||
|
||||
using bg::model::d2::point_xy;
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
|
||||
// Standard floating point types
|
||||
test_areal<point_xy<float>>({exclude::hard});
|
||||
test_areal<point_xy<double>>({});
|
||||
@ -121,23 +122,30 @@ int test_main(int, char* [])
|
||||
// Standard integer types
|
||||
test_areal<point_xy<std::int16_t>>({exclude::fp});
|
||||
test_areal<point_xy<std::int32_t>>({exclude::fp});
|
||||
#endif
|
||||
test_areal<point_xy<std::int64_t>>({exclude::fp});
|
||||
|
||||
// Boost multi precision (integer)
|
||||
test_areal<point_xy<bm::int128_t>>({exclude::fp});
|
||||
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
|
||||
test_areal<point_xy<bm::checked_int128_t>>({exclude::fp});
|
||||
#endif
|
||||
|
||||
// Boost multi precision (floating point)
|
||||
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
|
||||
test_areal<point_xy<bm::number<bm::cpp_bin_float<5>>>>();
|
||||
test_areal<point_xy<bm::number<bm::cpp_bin_float<10>>>>();
|
||||
test_areal<point_xy<bm::number<bm::cpp_bin_float<50>>>>();
|
||||
#endif
|
||||
test_areal<point_xy<bm::number<bm::cpp_bin_float<100>>>>();
|
||||
|
||||
test_areal<point_xy<bm::number<bm::cpp_dec_float<50>>>>({});
|
||||
|
||||
// Boost multi precision (rational)
|
||||
test_areal<point_xy<bm::cpp_rational>>({exclude::fp});
|
||||
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
|
||||
test_areal<point_xy<bm::checked_cpp_rational>>({exclude::fp});
|
||||
#endif
|
||||
|
||||
// Boost multi precision float128 wrapper, is currently NOT supported
|
||||
// and it is limited to certain compilers anyway
|
||||
@ -146,8 +154,10 @@ int test_main(int, char* [])
|
||||
// Boost rational (tests compilation)
|
||||
// (the rectangular case is correct; other input might give wrong results)
|
||||
// The int16 version throws a <zero denominator> exception
|
||||
#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
|
||||
test_areal<point_xy<boost::rational<std::int16_t>>>({exclude::all});
|
||||
test_areal<point_xy<boost::rational<std::int32_t>>>({exclude::fp});
|
||||
#endif
|
||||
test_areal<point_xy<boost::rational<std::int64_t>>>({exclude::fp});
|
||||
|
||||
return 0;
|
||||
|
@ -5,6 +5,10 @@
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2021.
|
||||
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
@ -222,6 +226,18 @@ void test_all()
|
||||
"POINT(0 0)",
|
||||
"POINT(0 0)", 1.0);
|
||||
|
||||
test_geometry<bg::model::segment<P> >(
|
||||
"SEGMENT(0 0, 1 1)",
|
||||
"SEGMENT(0 0, 1 1)", 1.0);
|
||||
|
||||
test_geometry<bg::model::box<P> >(
|
||||
"BOX(0 0, 1 1)",
|
||||
"BOX(0 0, 1 1)", 1.0);
|
||||
|
||||
test_geometry<bg::model::multi_point<P> >(
|
||||
"MULTIPOINT(0 0, 1 1, 2 2)",
|
||||
"MULTIPOINT(0 0, 1 1, 2 2)", 1.0);
|
||||
|
||||
|
||||
// RING: check compilation and behaviour
|
||||
test_geometry<bg::model::ring<P> >(
|
||||
|
@ -2,6 +2,11 @@
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2021.
|
||||
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -15,6 +20,7 @@
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/perimeter.hpp>
|
||||
#include <boost/geometry/geometries/geometry_collection.hpp>
|
||||
#include <boost/geometry/strategies/strategies.hpp>
|
||||
#include <boost/geometry/io/wkt/read.hpp>
|
||||
|
||||
@ -37,6 +43,16 @@ void test_perimeter(Geometry const& geometry, long double expected_perimeter)
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_CLOSE(perimeter, expected_perimeter, 0.0001);
|
||||
|
||||
boost::variant<Geometry> v(geometry);
|
||||
perimeter = bg::perimeter(v);
|
||||
|
||||
BOOST_CHECK_CLOSE(perimeter, expected_perimeter, 0.0001);
|
||||
|
||||
bg::model::geometry_collection<boost::variant<Geometry>> gc{v};
|
||||
perimeter = bg::perimeter(gc);
|
||||
|
||||
BOOST_CHECK_CLOSE(perimeter, expected_perimeter, 0.0001);
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +74,16 @@ void test_perimeter(Geometry const& geometry, long double expected_perimeter, St
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_CLOSE(perimeter, expected_perimeter, 0.0001);
|
||||
|
||||
boost::variant<Geometry> v(geometry);
|
||||
perimeter = bg::perimeter(v, strategy);
|
||||
|
||||
BOOST_CHECK_CLOSE(perimeter, expected_perimeter, 0.0001);
|
||||
|
||||
bg::model::geometry_collection<boost::variant<Geometry>> gc{v};
|
||||
perimeter = bg::perimeter(gc, strategy);
|
||||
|
||||
BOOST_CHECK_CLOSE(perimeter, expected_perimeter, 0.0001);
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
@ -65,12 +91,7 @@ void test_geometry(std::string const& wkt, double expected_perimeter)
|
||||
{
|
||||
Geometry geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
boost::variant<Geometry> v(geometry);
|
||||
|
||||
test_perimeter(geometry, expected_perimeter);
|
||||
#if !defined(BOOST_GEOMETRY_TEST_DEBUG)
|
||||
test_perimeter(v, expected_perimeter);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Geometry, typename Strategy>
|
||||
|
@ -2,6 +2,11 @@
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// This file was modified by Oracle on 2021.
|
||||
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -18,11 +23,24 @@
|
||||
#include <boost/geometry/algorithms/equals.hpp>
|
||||
#include <boost/geometry/algorithms/simplify.hpp>
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
#include <boost/geometry/geometries/geometry_collection.hpp>
|
||||
#include <boost/geometry/strategies/strategies.hpp>
|
||||
#include <boost/geometry/io/wkt/wkt.hpp>
|
||||
#include <boost/variant/variant.hpp>
|
||||
|
||||
|
||||
template <typename Geometry, typename Tag = typename bg::tag<Geometry>::type>
|
||||
struct boost_variant_type
|
||||
{
|
||||
using type = boost::variant<Geometry, typename bg::point_type<Geometry>::type>;
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct boost_variant_type<Geometry, bg::point_tag>
|
||||
{
|
||||
using type = boost::variant<Geometry>;
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryForTag,
|
||||
@ -158,8 +176,9 @@ void test_geometry(std::string const& wkt,
|
||||
bg::read_wkt(wkt, geometry);
|
||||
bg::read_wkt(expected_wkt, expected);
|
||||
|
||||
boost::variant<Geometry> v(geometry);
|
||||
|
||||
using variant_t = typename boost_variant_type<Geometry>::type;
|
||||
variant_t v(geometry);
|
||||
|
||||
// Define default strategy for testing
|
||||
typedef bg::strategy::simplify::douglas_peucker
|
||||
<
|
||||
@ -167,15 +186,27 @@ void test_geometry(std::string const& wkt,
|
||||
bg::strategy::distance::projected_point<double>
|
||||
> dp;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((bg::concepts::SimplifyStrategy<dp, point_type>));
|
||||
|
||||
check_geometry(geometry, expected, distance);
|
||||
check_geometry(v, expected, distance);
|
||||
|
||||
|
||||
BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy<dp, point_type>) );
|
||||
|
||||
|
||||
check_geometry(geometry, expected, distance, dp());
|
||||
check_geometry(v, expected, distance, dp());
|
||||
|
||||
// For now check GC here because it's not supported by equals()
|
||||
{
|
||||
using gc_t = bg::model::geometry_collection<variant_t>;
|
||||
gc_t gc{v};
|
||||
gc_t gc_simplified;
|
||||
bg::simplify(gc, gc_simplified, distance);
|
||||
bg::detail::visit_breadth_first([&](auto const& g)
|
||||
{
|
||||
test_equality<Geometry>::apply(g, expected);
|
||||
return false;
|
||||
}, gc_simplified);
|
||||
}
|
||||
|
||||
// Check inserter (if applicable)
|
||||
test_inserter
|
||||
<
|
||||
@ -217,7 +248,7 @@ void test_geometry(std::string const& wkt,
|
||||
bg::correct_closure(geometry);
|
||||
bg::correct_closure(expected);
|
||||
|
||||
boost::variant<Geometry> v(geometry);
|
||||
typename boost_variant_type<Geometry>::type v(geometry);
|
||||
|
||||
BOOST_CONCEPT_ASSERT( (bg::concepts::SimplifyStrategy<Strategy,
|
||||
typename bg::point_type<Geometry>::type>) );
|
||||
|
Loading…
x
Reference in New Issue
Block a user