summaryrefslogtreecommitdiff
path: root/libs/geometry/test/algorithms/set_operations/union
diff options
context:
space:
mode:
Diffstat (limited to 'libs/geometry/test/algorithms/set_operations/union')
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/Jamfile.v223
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/multi_union.cpp168
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/test_union.hpp198
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/test_union_linear_linear.hpp185
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/union.cpp446
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/union_linear_linear.cpp1075
-rw-r--r--libs/geometry/test/algorithms/set_operations/union/union_pl_pl.cpp187
7 files changed, 2282 insertions, 0 deletions
diff --git a/libs/geometry/test/algorithms/set_operations/union/Jamfile.v2 b/libs/geometry/test/algorithms/set_operations/union/Jamfile.v2
new file mode 100644
index 000000000..1f6b4f17e
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/Jamfile.v2
@@ -0,0 +1,23 @@
+# Boost.Geometry (aka GGL, Generic Geometry Library)
+#
+# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+# Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+# Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+#
+# This file was modified by Oracle on 2014.
+# Modifications copyright (c) 2014, 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
+#
+# 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)
+
+test-suite boost-geometry-algorithms-union
+ :
+ [ run multi_union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE ]
+ [ run union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE ]
+ [ run union_linear_linear.cpp ]
+ [ run union_pl_pl.cpp ]
+ ;
diff --git a/libs/geometry/test/algorithms/set_operations/union/multi_union.cpp b/libs/geometry/test/algorithms/set_operations/union/multi_union.cpp
new file mode 100644
index 000000000..74c9d060d
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/multi_union.cpp
@@ -0,0 +1,168 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 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)
+
+#include <iostream>
+#include <string>
+
+// If defined, tests are run without rescaling-to-integer or robustness policy
+// This multi_union currently contains no tests for double which then fail
+// #define BOOST_GEOMETRY_NO_ROBUSTNESS
+
+#include "test_union.hpp"
+#include <algorithms/test_overlay.hpp>
+#include <algorithms/overlay/multi_overlay_cases.hpp>
+
+#include <boost/geometry/multi/algorithms/correct.hpp>
+#include <boost/geometry/multi/algorithms/intersection.hpp>
+#include <boost/geometry/multi/algorithms/within.hpp>
+
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/multi/geometries/multi_linestring.hpp>
+#include <boost/geometry/multi/geometries/multi_polygon.hpp>
+
+#include <boost/geometry/multi/io/wkt/read.hpp>
+
+
+template <typename Ring, typename Polygon, typename MultiPolygon>
+void test_areal()
+{
+ test_one<Polygon, MultiPolygon, MultiPolygon>("simplex_multi",
+ case_multi_simplex[0], case_multi_simplex[1],
+ 1, 0, 20, 14.58);
+
+ test_one<Polygon, Polygon, MultiPolygon>("simplex_multi_p_mp",
+ case_single_simplex, case_multi_simplex[0],
+ 1, 0, 20, 14.58);
+ test_one<Polygon, MultiPolygon, Polygon>("simplex_multi_mp_p",
+ case_multi_simplex[0], case_single_simplex,
+ 1, 0, 20, 14.58);
+
+ test_one<Polygon, Ring, MultiPolygon>("simplex_multi_r_mp",
+ case_single_simplex, case_multi_simplex[0],
+ 1, 0, 20, 14.58);
+ test_one<Ring, MultiPolygon, Polygon>("simplex_multi_mp_r",
+ case_multi_simplex[0], case_single_simplex,
+ 1, 0, 20, 14.58);
+
+
+ // Normal test cases
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_multi_no_ip",
+ case_multi_no_ip[0], case_multi_no_ip[1],
+ 4, 0, 16, 66.5);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_multi_2",
+ case_multi_2[0], case_multi_2[1],
+ 3, 0, 16, 59.1);
+
+ // Constructed cases for multi/touch/equal/etc
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_61_multi",
+ case_61_multi[0], case_61_multi[1],
+ 1, 0, 11, 4.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_62_multi",
+ case_62_multi[0], case_62_multi[1],
+ 2, 0, 10, 2.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_63_multi",
+ case_63_multi[0], case_63_multi[1],
+ 2, 0, 10, 2.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_64_multi",
+ case_64_multi[0], case_64_multi[1],
+ 1, 0, 9, 3.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_65_multi",
+ case_65_multi[0], case_65_multi[1],
+ 3, 0, 15, 4.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_66_multi",
+ case_66_multi[0], case_66_multi[1],
+ 3, 0, 23, 7.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_72_multi",
+ case_72_multi[0], case_72_multi[1],
+ 1, 0, 13, 10.65);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_75_multi",
+ case_75_multi[0], case_75_multi[1],
+ 5, 0, 25, 5.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_76_multi",
+ case_76_multi[0], case_76_multi[1],
+ 5, 0, 31, 8.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_89_multi",
+ case_89_multi[0], case_89_multi[1],
+ 1, 0, 13, 6);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_101_multi",
+ case_101_multi[0], case_101_multi[1],
+ 1, 0, 32, 22.25);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_103_multi",
+ case_103_multi[0], case_103_multi[1],
+ 1, 0, 7, 25);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_104_multi",
+ case_104_multi[0], case_104_multi[1],
+ 1, 0, 8, 25);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_105_multi",
+ case_105_multi[0], case_105_multi[1],
+ 1, 0, 5, 25);
+
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_1",
+ case_recursive_boxes_1[0], case_recursive_boxes_1[1],
+ 1, 1, 36, 97.0);
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_2",
+ case_recursive_boxes_2[0], case_recursive_boxes_2[1],
+ 1, 0, 14, 100.0); // Area from SQL Server
+ test_one<Polygon, MultiPolygon, MultiPolygon>("case_recursive_boxes_3",
+ case_recursive_boxes_3[0], case_recursive_boxes_3[1],
+ 17, 0, 159, 56.5); // Area from SQL Server
+
+ test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_a",
+ ggl_list_20120915_h2[0], ggl_list_20120915_h2[1],
+ 1, 0, 12, 23.0); // Area from SQL Server
+ test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20120915_h2_b",
+ ggl_list_20120915_h2[0], ggl_list_20120915_h2[2],
+ 1, 0, 12, 23.0); // Area from SQL Server
+
+ test_one<Polygon, MultiPolygon, MultiPolygon>("ggl_list_20140212_sybren",
+ ggl_list_20140212_sybren[0], ggl_list_20140212_sybren[1],
+ 2, 0, 16, 0.002471626);
+
+ test_one<Polygon, MultiPolygon, MultiPolygon>("ticket_9081",
+ ticket_9081[0], ticket_9081[1],
+ 3, 0, 31, 0.2187385);
+}
+
+template <typename P>
+void test_all()
+{
+
+ {
+ typedef bg::model::ring<P> ring;
+ typedef bg::model::polygon<P> polygon;
+ typedef bg::model::multi_polygon<polygon> multi_polygon;
+ test_areal<ring, polygon, multi_polygon>();
+ }
+
+ {
+ typedef bg::model::ring<P, false> ring_ccw;
+ typedef bg::model::polygon<P, false> polygon_ccw;
+ typedef bg::model::multi_polygon<polygon_ccw> multi_polygon_ccw;
+ test_areal<ring_ccw, polygon_ccw, multi_polygon_ccw>();
+ }
+
+}
+
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::d2::point_xy<double> >();
+
+#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
+ test_all<bg::model::d2::point_xy<float> >();
+
+#if defined(HAVE_TTMATH)
+ std::cout << "Testing TTMATH" << std::endl;
+ test_all<bg::model::d2::point_xy<ttmath_big> >();
+#endif
+
+#endif
+
+ return 0;
+}
diff --git a/libs/geometry/test/algorithms/set_operations/union/test_union.hpp b/libs/geometry/test/algorithms/set_operations/union/test_union.hpp
new file mode 100644
index 000000000..2c1868ef2
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/test_union.hpp
@@ -0,0 +1,198 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 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)
+
+#ifndef BOOST_GEOMETRY_TEST_UNION_HPP
+#define BOOST_GEOMETRY_TEST_UNION_HPP
+
+#include <fstream>
+
+#include <geometry_test_common.hpp>
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/range/algorithm/copy.hpp>
+
+#include <boost/geometry/algorithms/union.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/correct.hpp>
+#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+#include <boost/geometry/geometries/geometries.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <boost/geometry/io/wkt/wkt.hpp>
+
+
+#if defined(TEST_WITH_SVG)
+# include <boost/geometry/io/svg/svg_mapper.hpp>
+#endif
+
+
+
+template <typename OutputType, typename G1, typename G2>
+void test_union(std::string const& caseid, G1 const& g1, G2 const& g2,
+ int expected_count, int expected_hole_count,
+ int expected_point_count, double expected_area,
+ double percentage)
+{
+ typedef typename bg::coordinate_type<G1>::type coordinate_type;
+ boost::ignore_unused<coordinate_type>();
+
+ std::vector<OutputType> clip;
+
+#if defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS)
+ std::cout << "*** UNION " << caseid << std::endl;
+#endif
+
+ bg::union_(g1, g2, clip);
+
+ typename bg::default_area_result<OutputType>::type area = 0;
+ std::size_t n = 0;
+ std::size_t holes = 0;
+ for (typename std::vector<OutputType>::iterator it = clip.begin();
+ it != clip.end(); ++it)
+ {
+ area += bg::area(*it);
+ holes += bg::num_interior_rings(*it);
+ n += bg::num_points(*it, true);
+ }
+
+#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
+ {
+ // Test inserter functionality
+ // Test if inserter returns output-iterator (using Boost.Range copy)
+ std::vector<OutputType> inserted, array_with_one_empty_geometry;
+ array_with_one_empty_geometry.push_back(OutputType());
+ boost::copy(array_with_one_empty_geometry, bg::detail::union_::union_insert<OutputType>(g1, g2, std::back_inserter(inserted)));
+
+ typename bg::default_area_result<OutputType>::type area_inserted = 0;
+ int index = 0;
+ for (typename std::vector<OutputType>::iterator it = inserted.begin();
+ it != inserted.end();
+ ++it, ++index)
+ {
+ // Skip the empty polygon created above to avoid the empty_input_exception
+ if (bg::num_points(*it) > 0)
+ {
+ area_inserted += bg::area(*it);
+ }
+ }
+ BOOST_CHECK_EQUAL(boost::size(clip), boost::size(inserted) - 1);
+ BOOST_CHECK_CLOSE(area_inserted, expected_area, percentage);
+ }
+#endif
+
+
+
+#if defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS)
+ std::cout << "*** case: " << caseid
+ << " area: " << area
+ << " points: " << n
+ << " polygons: " << boost::size(clip)
+ << " holes: " << holes
+ << std::endl;
+#endif
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ BOOST_CHECK_MESSAGE(expected_point_count < 0 || std::abs(int(n) - expected_point_count) < 3,
+ "union: " << caseid
+ << " #points expected: " << expected_point_count
+ << " detected: " << n
+ << " type: " << (type_for_assert_message<G1, G2>())
+ );
+#endif
+
+ BOOST_CHECK_MESSAGE(expected_count < 0 || int(clip.size()) == expected_count,
+ "union: " << caseid
+ << " #clips expected: " << expected_count
+ << " detected: " << clip.size()
+ << " type: " << (type_for_assert_message<G1, G2>())
+ );
+
+ BOOST_CHECK_MESSAGE(expected_hole_count < 0 || int(holes) == expected_hole_count,
+ "union: " << caseid
+ << " #holes expected: " << expected_hole_count
+ << " detected: " << holes
+ << " type: " << (type_for_assert_message<G1, G2>())
+ );
+
+ BOOST_CHECK_CLOSE(area, expected_area, percentage);
+
+#if defined(TEST_WITH_SVG)
+ {
+ bool const ccw =
+ bg::point_order<G1>::value == bg::counterclockwise
+ || bg::point_order<G2>::value == bg::counterclockwise;
+ bool const open =
+ bg::closure<G1>::value == bg::open
+ || bg::closure<G2>::value == bg::open;
+
+ std::ostringstream filename;
+ filename << "union_"
+ << caseid << "_"
+ << string_from_type<coordinate_type>::name()
+ << (ccw ? "_ccw" : "")
+ << (open ? "_open" : "")
+#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ << "_no_rob"
+#endif
+ << ".svg";
+
+ std::ofstream svg(filename.str().c_str());
+
+ bg::svg_mapper
+ <
+ typename bg::point_type<G2>::type
+ > mapper(svg, 500, 500);
+ mapper.add(g1);
+ mapper.add(g2);
+
+ mapper.map(g1, "fill-opacity:0.5;fill:rgb(153,204,0);"
+ "stroke:rgb(153,204,0);stroke-width:3");
+ mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);"
+ "stroke:rgb(51,51,153);stroke-width:3");
+ //mapper.map(g1, "opacity:0.6;fill:rgb(0,0,255);stroke:rgb(0,0,0);stroke-width:1");
+ //mapper.map(g2, "opacity:0.6;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1");
+
+ for (typename std::vector<OutputType>::const_iterator it = clip.begin();
+ it != clip.end(); ++it)
+ {
+ mapper.map(*it, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);"
+ "stroke:rgb(255,0,255);stroke-width:8");
+ //mapper.map(*it, "opacity:0.6;fill:none;stroke:rgb(255,0,0);stroke-width:5");
+ }
+ }
+#endif
+}
+
+template <typename OutputType, typename G1, typename G2>
+void test_one(std::string const& caseid, std::string const& wkt1, std::string const& wkt2,
+ int expected_count, int expected_hole_count,
+ int expected_point_count, double expected_area,
+ double percentage = 0.001)
+{
+ G1 g1;
+ bg::read_wkt(wkt1, g1);
+
+ G2 g2;
+ bg::read_wkt(wkt2, g2);
+
+ // Reverse if necessary
+ bg::correct(g1);
+ bg::correct(g2);
+
+ test_union<OutputType>(caseid, g1, g2,
+ expected_count, expected_hole_count, expected_point_count,
+ expected_area, percentage);
+}
+
+
+
+#endif
diff --git a/libs/geometry/test/algorithms/set_operations/union/test_union_linear_linear.hpp b/libs/geometry/test/algorithms/set_operations/union/test_union_linear_linear.hpp
new file mode 100644
index 000000000..1b6dda37c
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/test_union_linear_linear.hpp
@@ -0,0 +1,185 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+#ifndef BOOST_GEOMETRY_TEST_UNION_LINEAR_LINEAR_HPP
+#define BOOST_GEOMETRY_TEST_UNION_LINEAR_LINEAR_HPP
+
+#include <limits>
+
+#include <boost/geometry/geometry.hpp>
+#include "../test_set_ops_linear_linear.hpp"
+#include <from_wkt.hpp>
+#include <to_svg.hpp>
+
+
+//==================================================================
+//==================================================================
+// union of (linear) geometries
+//==================================================================
+//==================================================================
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename MultiLineString
+>
+class test_union_of_geometries
+{
+private:
+ static inline void base_test(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ MultiLineString const& mls_union1,
+ MultiLineString const& mls_union2,
+ std::string const& case_id,
+ double tolerance,
+ bool test_vector_and_deque = false)
+ {
+ static bool vector_deque_already_tested = false;
+
+ typedef typename boost::range_value<MultiLineString>::type LineString;
+ typedef std::vector<LineString> linestring_vector;
+ typedef std::deque<LineString> linestring_deque;
+
+ MultiLineString mls_output;
+
+ linestring_vector ls_vector_output;
+ linestring_deque ls_deque_output;
+
+ bg::union_(geometry1, geometry2, mls_output);
+
+ BOOST_CHECK_MESSAGE( equals::apply(mls_union1, mls_output, tolerance),
+ "case id: " << case_id
+ << ", union L/L: " << bg::wkt(geometry1)
+ << " " << bg::wkt(geometry2)
+ << " -> Expected: " << bg::wkt(mls_union1)
+ << " computed: " << bg::wkt(mls_output) );
+
+ set_operation_output("union", case_id,
+ geometry1, geometry2, mls_output);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
+ std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
+ std::cout << "union : " << bg::wkt(mls_output) << std::endl;
+ std::cout << "expected union : " << bg::wkt(mls_union1)
+ << std::endl;
+ std::cout << std::endl;
+ std::cout << "************************************" << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+#endif
+
+ if ( !vector_deque_already_tested && test_vector_and_deque )
+ {
+ vector_deque_already_tested = true;
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "Testing with vector and deque as output container..."
+ << std::endl;
+#endif
+ bg::union_(geometry1, geometry2, ls_vector_output);
+ bg::union_(geometry1, geometry2, ls_deque_output);
+
+ BOOST_CHECK(multilinestring_equals
+ <
+ false
+ >::apply(mls_union1, ls_vector_output, tolerance));
+
+ BOOST_CHECK(multilinestring_equals
+ <
+ false
+ >::apply(mls_union1, ls_deque_output, tolerance));
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "Done!" << std::endl << std::endl;
+#endif
+ }
+
+ // check the symmetric difference where the order of the two
+ // geometries is reversed
+ bg::clear(mls_output);
+ bg::union_(geometry2, geometry1, mls_output);
+
+ BOOST_CHECK_MESSAGE( equals::apply(mls_union2, mls_output, tolerance),
+ "case id: " << case_id
+ << ", union L/L: " << bg::wkt(geometry2)
+ << " " << bg::wkt(geometry1)
+ << " -> Expected: " << bg::wkt(mls_union2)
+ << " computed: " << bg::wkt(mls_output) );
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "Geometry #1: " << bg::wkt(geometry2) << std::endl;
+ std::cout << "Geometry #2: " << bg::wkt(geometry1) << std::endl;
+ std::cout << "union : " << bg::wkt(mls_output) << std::endl;
+ std::cout << "expected union : " << bg::wkt(mls_union2)
+ << std::endl;
+ std::cout << std::endl;
+ std::cout << "************************************" << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+#endif
+ }
+
+
+public:
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ MultiLineString const& mls_union1,
+ MultiLineString const& mls_union2,
+ std::string const& case_id,
+ double tolerance
+ = std::numeric_limits<double>::epsilon())
+ {
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "test case: " << case_id << std::endl;
+ std::stringstream sstr;
+ sstr << "svgs/" << case_id << ".svg";
+ to_svg(geometry1, geometry2, sstr.str());
+#endif
+
+ Geometry1 rg1(geometry1);
+ bg::reverse<Geometry1>(rg1);
+
+ Geometry2 rg2(geometry2);
+ bg::reverse<Geometry2>(rg2);
+
+ test_get_turns_ll_invariance<>::apply(geometry1, geometry2);
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl
+ << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
+ << std::endl << std::endl;
+#endif
+ test_get_turns_ll_invariance<>::apply(rg1, geometry2);
+
+ base_test(geometry1, geometry2, mls_union1, mls_union2,
+ case_id, tolerance, true);
+ // base_test(geometry1, rg2, mls_sym_diff);
+ // base_test(rg1, geometry2, mls_sym_diff);
+ base_test(rg1, rg2, mls_union1, mls_union2, case_id, tolerance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << std::endl;
+#endif
+ }
+
+
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ MultiLineString const& mls_union,
+ std::string const& case_id,
+ double tolerance
+ = std::numeric_limits<double>::epsilon())
+ {
+ apply(geometry1, geometry2, mls_union, mls_union, case_id, tolerance);
+ }
+};
+
+
+#endif // BOOST_GEOMETRY_TEST_UNION1_HPP
diff --git a/libs/geometry/test/algorithms/set_operations/union/union.cpp b/libs/geometry/test/algorithms/set_operations/union/union.cpp
new file mode 100644
index 000000000..20820a2d2
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/union.cpp
@@ -0,0 +1,446 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-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)
+
+#include <iostream>
+#include <string>
+
+// If defined, tests are run without rescaling-to-integer or robustness policy
+// Test which would fail then are disabled automatically
+// #define BOOST_GEOMETRY_NO_ROBUSTNESS
+
+#include "test_union.hpp"
+#include <algorithms/test_overlay.hpp>
+
+#include <algorithms/overlay/overlay_cases.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+
+
+
+template <typename Ring, typename Polygon>
+void test_areal()
+{
+ typedef typename bg::coordinate_type<Polygon>::type ct;
+
+ test_one<Polygon, Polygon, Polygon>("simplex_normal",
+ simplex_normal[0], simplex_normal[1],
+ 1, 0, 13, 11.526367);
+
+ test_one<Polygon, Polygon, Polygon>("simplex_with_empty_1",
+ simplex_normal[0], polygon_empty,
+ 1, 0, 4, 8.0);
+ test_one<Polygon, Polygon, Polygon>("simplex_with_empty_2",
+ polygon_empty, simplex_normal[0],
+ 1, 0, 4, 8.0);
+
+ test_one<Polygon, Polygon, Polygon>("star_ring", example_star, example_ring,
+ 1, 0, 23, 5.67017141);
+
+ // This sample was selected because of the border case, and ttmath generates one point more.
+ test_one<Polygon, Polygon, Polygon>("star_poly", example_star, example_polygon,
+ 1, 1,
+ if_typed_tt<ct>(28, 27), 5.647949);
+
+ // Pseudo-box as Polygon
+ // (note, internally, the intersection points is different, so yes,
+ // it has to be tested)
+ test_one<Polygon, Polygon, Polygon>("box_poly3", "POLYGON((1.5 1.5 , 1.5 2.5 , 4.5 2.5 , 4.5 1.5 , 1.5 1.5))",
+ "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,5.3 2.5,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))",
+ 1, 1, 15, 5.93625);
+
+ test_one<Polygon, Polygon, Polygon>("first_within_second",
+ first_within_second[0], first_within_second[1],
+ 1, 0, 5, 25.0);
+
+ test_one<Polygon, Polygon, Polygon>("second_within_first",
+ first_within_second[1], first_within_second[0],
+ 1, 0, 5, 25.0);
+
+ test_one<Polygon, Polygon, Polygon>("first_within_hole_of_second",
+ first_within_hole_of_second[0], first_within_hole_of_second[1],
+ 2, 1, 15, 17.0);
+
+ test_one<Polygon, Polygon, Polygon>("new_hole",
+ new_hole[0], new_hole[1],
+ 1, 1, 14, 23.0);
+
+ test_one<Polygon, Polygon, Polygon>("side_side",
+ side_side[0], side_side[1], 1, 0, 7, 2.0);
+
+ test_one<Polygon, Polygon, Polygon>("identical",
+ identical[0], identical[1], 1, 0, 5, 1.0);
+
+ test_one<Polygon, Polygon, Polygon>("disjoint",
+ disjoint[0], disjoint[1], 2, 0, 10, 2.0);
+
+ test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect",
+ intersect_holes_intersect[0], intersect_holes_intersect[1],
+ 1, 1, 14, 39.75);
+
+ test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_disjoint",
+ intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
+ 1, 1, 14, 39.75);
+
+ test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_touch",
+ intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1],
+ 1, 1, 14, 39.75);
+
+ test_one<Polygon, Polygon, Polygon>("intersect_holes_new_ring",
+ intersect_holes_new_ring[0], intersect_holes_new_ring[1],
+ 1, 2, 15, 253.8961);
+
+ test_one<Polygon, Polygon, Polygon>("intersect_holes_disjoint",
+ intersect_holes_disjoint[0],
+ intersect_holes_disjoint[1],
+ 1, 0, 9, 40.0);
+
+ test_one<Polygon, Polygon, Polygon>("within_holes_disjoint",
+ within_holes_disjoint[0], within_holes_disjoint[1],
+ 1, 0, 5, 49.0);
+
+ test_one<Polygon, Polygon, Polygon>("winded",
+ winded[0], winded[1],
+ 1, 5, 30, 114.0);
+
+ test_one<Polygon, Polygon, Polygon>("two_bends",
+ two_bends[0], two_bends[1],
+ 1, 0, 7, 40.0);
+
+ test_one<Polygon, Polygon, Polygon>("star_comb_15",
+ star_comb_15[0], star_comb_15[1],
+ 1, 27, 204, 898.09693338);
+
+ test_one<Polygon, Polygon, Polygon>("equal_holes_disjoint",
+ equal_holes_disjoint[0], equal_holes_disjoint[1],
+ 1, 1, 10, 81 - 3 * 7);
+
+ test_one<Polygon, Polygon, Polygon>("only_hole_intersections1",
+ only_hole_intersections[0], only_hole_intersections[1],
+ 1, 2, 13, 190.9090909);
+ test_one<Polygon, Polygon, Polygon>("only_hole_intersections2",
+ only_hole_intersections[0], only_hole_intersections[2],
+ 1, 2, 13, 190.9090909);
+
+ test_one<Polygon, Polygon, Polygon>("intersect_exterior_and_interiors_winded",
+ intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1],
+ 1, 1, 26, 66.5333333);
+
+ test_one<Polygon, Polygon, Polygon>("crossed",
+ crossed[0], crossed[1],
+ 1, 3, 17, 23.5); // Area from SQL Server - was somehow wrong before
+
+ test_one<Polygon, Polygon, Polygon>("fitting",
+ fitting[0], fitting[1],
+ 1, 0, 5, 25);
+
+ test_one<Polygon, Polygon, Polygon>("distance_zero",
+ distance_zero[0], distance_zero[1],
+ 1, 0, if_typed<ct, float>(9, 11), 9.0098387);
+
+ test_one<Polygon, Polygon, Polygon>("wrapped_a",
+ wrapped[0], wrapped[1],
+ 1, 1, 16, 16);
+ test_one<Polygon, Polygon, Polygon>("wrapped_b",
+ wrapped[0], wrapped[2],
+ 1, 1, 16, 16);
+
+ test_one<Polygon, Polygon, Polygon>("9",
+ case_9[0], case_9[1], 2, 0, 8, 11);
+ test_one<Polygon, Polygon, Polygon>("22",
+ case_22[0], case_22[1], 2, 0, 8, 9.5);
+ test_one<Polygon, Polygon, Polygon>("25",
+ case_25[0], case_25[1], 2, 0, 8, 7);
+ test_one<Polygon, Polygon, Polygon>("26",
+ case_26[0], case_26[1], 2, 0, 9, 7.5);
+ test_one<Polygon, Polygon, Polygon>("31",
+ case_31[0], case_31[1], 2, 0, 8, 4.5);
+ test_one<Polygon, Polygon, Polygon>("32",
+ case_32[0], case_32[1], 2, 0, 8, 4.5);
+ test_one<Polygon, Polygon, Polygon>("33",
+ case_33[0], case_33[1], 2, 0, 8, 4.5);
+ test_one<Polygon, Polygon, Polygon>("36",
+ case_36[0], case_36[1], 1, 0, 10, 14.375);
+ test_one<Polygon, Polygon, Polygon>("40",
+ case_40[0], case_40[1], 2, 0, 18, 11);
+
+ // Test rings which should be generated by assemble
+ test_one<Polygon, Polygon, Polygon>("53_iet",
+ case_53[0], case_53[2], 1, 1, 16, 16);
+ test_one<Polygon, Polygon, Polygon>("58_iet",
+ case_58[0], case_58[2], 1, 3, 20, 12.16666);
+ test_one<Polygon, Polygon, Polygon>("59_iet",
+ case_59[0], case_59[2], 1, 1, 14, 17.20833);
+
+
+ /*
+ test_one<Polygon, Polygon, Polygon>(102,
+ simplex_normal[0], simplex_reversed[1],
+ 1, 0, 7, X);
+
+ test_one<Polygon, Polygon, Polygon>(103,
+ simplex_reversed[0], simplex_normal[1],
+ 1, 0, 7, 24.0);
+
+ test_one<Polygon, Polygon, Polygon>(104,
+ simplex_reversed[0], simplex_reversed[1],
+ 1, 0, 7, 24.0);
+
+ test_one<Polygon, Polygon, Polygon>(100,
+ star_15, comb_15,
+ 1, 10, 7, 24.0);
+ */
+
+ // test some other input/output types
+
+ // 1 input Ring
+ test_one<Polygon, Polygon, Ring>("identical_pr", identical[0], identical[1], 1, 0, 5, 1.0);
+ test_one<Polygon, Ring, Polygon>("identical_rp", identical[0], identical[1], 1, 0, 5, 1.0);
+
+ // 2 input rings
+ test_one<Polygon, Ring, Ring>("identical_rr", identical[0], identical[1], 1, 0, 5, 1.0);
+
+ // output is also Ring
+ test_one<Ring, Ring, Ring>("identical_rrr", identical[0], identical[1], 1, 0, 5, 1.0);
+
+ // "new hole", tested with Ring -> the newly formed hole will be omitted
+ test_one<Ring, Ring, Ring>("new_hole_discarded", new_hole[0], new_hole[1], 1, 0, 9, 24.0);
+
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110306_javier",
+ ggl_list_20110306_javier[0], ggl_list_20110306_javier[1],
+ 1, 1, 16, 80456.4904910401);
+
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110307_javier",
+ ggl_list_20110307_javier[0], ggl_list_20110307_javier[1],
+ 1, 1, 13, 20016.4);
+
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110627_phillip",
+ ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
+ 1, 0, 8, 14729.07145);
+
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
+ ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
+ 1, 1, 15, 129904.197692871);
+
+ test_one<Polygon, Polygon, Polygon>("ggl_list_20110820_christophe",
+ ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1],
+ -1, // Either 1 or 2, depending if the intersection/turn point (eps.region) is missed
+ 0,
+ if_typed_tt<ct>(9, 8),
+ 67.3550722317627);
+
+
+ test_one<Polygon, Polygon, Polygon>("isovist",
+ isovist1[0], isovist1[1],
+ 1,
+ 0,
+ -1,
+ 313.36036462, 0.01);
+
+ // SQL Server gives: 313.360374193241
+ // PostGIS gives: 313.360364623393
+
+ // Ticket 5103 https://svn.boost.org/trac/boost/ticket/5103
+ // This ticket was actually reported for Boost.Polygon
+ // We check it for Boost.Geometry as well.
+ // SQL Server gives: 2515271331437.69
+ // PostGIS gives: 2515271327070.52
+ // Boost.Geometry gives: 2515271327070.5237746891 (ttmath)
+ // 2515271327070.5156 (double)
+ // 2515271320603.0000 (int)
+ // Note the int-test was tested outside of this unit test. It is in two points 0.37 off (logical for an int).
+ // Because of the width of the polygon (400000 meter) this causes a substantial difference.
+
+ test_one<Polygon, Polygon, Polygon>("ticket_5103", ticket_5103[0], ticket_5103[1],
+ 1, 0, 25, 2515271327070.5);
+
+ test_one<Polygon, Polygon, Polygon>("ticket_8310a", ticket_8310a[0], ticket_8310a[1],
+ 1, 0, 5, 10.5000019595);
+ test_one<Polygon, Polygon, Polygon>("ticket_8310b", ticket_8310b[0], ticket_8310b[1],
+ 1, 0, 5, 10.5000019595);
+ test_one<Polygon, Polygon, Polygon>("ticket_8310c", ticket_8310c[0], ticket_8310c[1],
+ 1, 0, 5, 10.5000019595);
+
+ test_one<Polygon, Polygon, Polygon>("ticket_9081_15",
+ ticket_9081_15[0], ticket_9081_15[1],
+ 1, 0, 7, 0.0403425433);
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_one<Polygon, Polygon, Polygon>("ticket_9563", ticket_9563[0], ticket_9563[1],
+ 1, 0, 13, 150.0);
+#endif
+
+ test_one<Polygon, Polygon, Polygon>("ticket_9756", ticket_9756[0], ticket_9756[1],
+ 1, 0, 10, 1289.08374);
+
+ test_one<Polygon, Polygon, Polygon>("ticket_10108_a", ticket_10108_a[0], ticket_10108_a[1],
+ 2, 0, 8, 0.0435229);
+ test_one<Polygon, Polygon, Polygon>("ticket_10108_b", ticket_10108_b[0], ticket_10108_b[1],
+ 2, 0, 10, 2424.3449);
+
+ test_one<Polygon, Polygon, Polygon>("geos_1", geos_1[0], geos_1[1],
+ 1, 0, -1, 3461.3203125);
+ test_one<Polygon, Polygon, Polygon>("geos_2", geos_2[0], geos_2[1],
+ 1, 0, -1, 350.55102539);
+ test_one<Polygon, Polygon, Polygon>("geos_3", geos_3[0], geos_3[1],
+ 1, 0, -1, 29391548.4998779);
+ test_one<Polygon, Polygon, Polygon>("geos_4", geos_4[0], geos_4[1],
+ 1, 0, -1, 2304.4163115);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_a", buffer_rt_a[0], buffer_rt_a[1],
+ 1, 0, 265, 19.280667);
+
+ // Robustness issues, followed out buffer-robustness-tests, test them also reverse
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
+ 1, 0, if_typed<ct, double>(21, 23), 4.60853);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_f_rev", buffer_rt_f[1], buffer_rt_f[0],
+ 1, 0, if_typed<ct, double>(21, 23), 4.60853);
+#endif
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
+ 1, 0, if_typed<ct, float>(18, 17), 16.571);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_g_rev", buffer_rt_g[1], buffer_rt_g[0],
+ 1, 0, if_typed<ct, float>(18, 17), 16.571);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_i", buffer_rt_i[0], buffer_rt_i[1],
+ 1, 0, if_typed<ct, float>(14, 13), 13.6569);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_i_rev", buffer_rt_i[1], buffer_rt_i[0],
+ 1, 0, 13, 13.6569);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_j", buffer_rt_j[0], buffer_rt_j[1],
+ 1, 0, -1, 16.5711);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_j_rev", buffer_rt_j[1], buffer_rt_j[0],
+ 1, 0, -1, 16.5711);
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_l", buffer_rt_l[0], buffer_rt_l[1],
+ 1, 0, -1, 19.3995);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_l_rev", buffer_rt_l[1], buffer_rt_l[0],
+ 1, 0, -1, 19.3995);
+#endif
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m1", buffer_rt_m1[0], buffer_rt_m1[1],
+ 1, 0, if_typed_tt<ct>(14, 13), 19.4852);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m1_rev", buffer_rt_m1[1], buffer_rt_m1[0],
+ 1, 0, if_typed_tt<ct>(14, 13), 19.4852);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m2", buffer_rt_m2[0], buffer_rt_m2[1],
+ 1, 0, if_typed_tt<ct>(20, 19), 21.4853);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_m2_rev", buffer_rt_m2[1], buffer_rt_m2[0],
+ 1, 0, if_typed_tt<ct>(20, 19), 21.4853);
+
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_q", buffer_rt_q[0], buffer_rt_q[1],
+ 1, 0, 18, 18.5710);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_q_rev", buffer_rt_q[1], buffer_rt_q[0],
+ 1, 0, 18, 18.5710);
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_r", buffer_rt_r[0], buffer_rt_r[1],
+ 1, 0, 19, 21.07612);
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_r_rev", buffer_rt_r[1], buffer_rt_r[0],
+ 1, 0, if_typed_tt<ct>(20, 19), 21.07612);
+#endif
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_t", buffer_rt_t[0], buffer_rt_t[1],
+ 1, 0, if_typed_tt<ct>(16, 14), 15.6569);
+#endif
+ test_one<Polygon, Polygon, Polygon>("buffer_rt_t_ref", buffer_rt_t[1], buffer_rt_t[0],
+ 1, 0, if_typed_tt<ct>(16, if_typed<ct, float>(15, 14)), 15.6569);
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_one<Polygon, Polygon, Polygon>("buffer_mp1", buffer_mp1[0], buffer_mp1[1],
+ 1, 0, if_typed_tt<ct>(93, 91), 22.815);
+#endif
+
+ test_one<Polygon, Polygon, Polygon>("buffer_mp2", buffer_mp2[0], buffer_mp2[1],
+ 1, 0, 217, 36.752837);
+}
+
+template <typename P>
+void test_all()
+{
+ typedef bg::model::polygon<P> polygon;
+ typedef bg::model::ring<P> ring;
+ typedef bg::model::box<P> box;
+
+ test_areal<ring, polygon>();
+
+ // Open
+ test_areal<bg::model::ring<P, true, false>, bg::model::polygon<P, true, false> >();
+
+ // Counter clockwise
+ test_areal<bg::model::ring<P, false>, bg::model::polygon<P, false> >();
+
+#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
+ // Counter clockwise and open
+ test_areal<bg::model::ring<P, false, false>, bg::model::polygon<P, false, false> >();
+#endif
+
+ test_one<polygon, box, polygon>("box_ring", example_box, example_ring,
+ 1, 1, 15, 6.38875);
+
+ test_one<polygon, box, polygon>("box_poly", example_box, example_polygon,
+ 1, 3, 23, 6.30983);
+
+
+ test_one<polygon, box, polygon>("box_poly1", example_box,
+ "POLYGON((3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2))",
+ 1, 1, 15, 6.38875);
+ test_one<polygon, box, polygon>("box_poly2", example_box,
+ "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,5.3 2.5,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))",
+ 1, 1, 15, 5.93625);
+
+ // 3: see areal
+
+ test_one<polygon, box, polygon>("box_poly4", example_box,
+ "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,4.5 2.5,4.5 1.2,4.9 0.8,2.9 0.7,2 1.3))",
+ 1, 1, 15, 4.651245);
+
+ test_one<polygon, box, polygon>("box_poly5", example_box,
+ "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,4.5 2.5,4.5 2.3,5.0 2.3,5.0 2.1,4.5 2.1,4.5 1.9,4.0 1.9,4.5 1.2,4.9 0.8,2.9 0.7,2 1.3))",
+ 1, 1, 21, 4.7191);
+
+ test_one<polygon, box, polygon>("box_poly6", example_box,
+ "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 2.5,4.5 1.2,2.9 0.7,2 1.3))",
+ 1, 1, 15, 4.2174);
+
+ test_one<polygon, box, polygon>("box_poly7", example_box,
+ "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.0 3.0,5.0 2.0,2.9 0.7,2 1.3))",
+ 1, 1, 17, 4.270554);
+
+ test_one<polygon, box, polygon>("box_poly8", "box(0 0, 3 3)",
+ "POLYGON((2 2, 1 4, 2 4, 3 3, 2 2))",
+ 1, 0, 8, 10.25);
+}
+
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::d2::point_xy<double> >();
+
+#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
+
+#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
+ test_all<bg::model::d2::point_xy<float> >();
+ test_all<bg::model::d2::point_xy<long double> >();
+#endif
+
+#if defined(HAVE_TTMATH)
+ std::cout << "Testing TTMATH" << std::endl;
+ test_all<bg::model::d2::point_xy<ttmath_big> >();
+#endif
+#endif
+
+ return 0;
+}
diff --git a/libs/geometry/test/algorithms/set_operations/union/union_linear_linear.cpp b/libs/geometry/test/algorithms/set_operations/union/union_linear_linear.cpp
new file mode 100644
index 000000000..925c8363b
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/union_linear_linear.cpp
@@ -0,0 +1,1075 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_union_linear_linear
+#endif
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+#define BOOST_GEOMETRY_DEBUG_TURNS
+#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_union_linear_linear.hpp"
+
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/multi/geometries/multi_linestring.hpp>
+#include <boost/geometry/algorithms/union.hpp>
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::linestring<point_type> linestring_type;
+typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+
+BOOST_AUTO_TEST_CASE( test_union_linestring_linestring )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** LINESTRING / LINESTRING UNION ***" << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef linestring_type L;
+ typedef multi_linestring_type ML;
+
+ typedef test_union_of_geometries<L, L, ML> tester;
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 1,2 1,3 2)"),
+ from_wkt<L>("LINESTRING(0 2,1 1,2 1,3 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 1,2 1,3 2),\
+ (0 2,1 1),(2 1,3 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 2,1 1,2 1,3 0),\
+ (0 0,1 1),(2 1,3 2))"),
+ "llu00");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,5 0)"),
+ from_wkt<L>("LINESTRING(3 0,4 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((3 0,4 0),(0 0,3 0),(4 0,5 0))"),
+ "llu01");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(3 0,4 0)"),
+ from_wkt<L>("LINESTRING(0 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((3 0,4 0),(0 0,3 0),(4 0,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,5 0))"),
+ "llu01-1");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,4 0)"),
+ from_wkt<L>("LINESTRING(3 0,6 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,4 0),(4 0,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((3 0,6 0),(0 0,3 0))"),
+ "llu01-2");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(3 0,6 0)"),
+ from_wkt<L>("LINESTRING(0 0,4 0)"),
+ from_wkt<ML>("MULTILINESTRING((3 0,6 0),(0 0,3 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,4 0),(4 0,6 0))"),
+ "llu01-3");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,6 0)"),
+ from_wkt<L>("LINESTRING(0 0,4 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,4 0),(4 0,6 0))"),
+ "llu01-4");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<L>("LINESTRING(0 0,1 1,2 0,3 1,4 0,5 0,6 1,7 -1,8 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),\
+ (0 0,1 1,2 0,3 1,4 0),\
+ (5 0,6 1,7 -1,8 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 1,2 0,3 1,4 0,5 0,6 1,7 -1,8 0),\
+ (0 0,4 0),(5 0,20 0))"),
+ "llu01-6");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-20 0,20 0)"),
+ from_wkt<L>("LINESTRING(0 0,1 1,2 0,3 1,4 0,5 0,6 1,7 -1,8 0)"),
+ from_wkt<ML>("MULTILINESTRING((-20 0,20 0),\
+ (0 0,1 1,2 0,3 1,4 0),\
+ (5 0,6 1,7 -1,8 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 1,2 0,3 1,4 0,5 0,6 1,7 -1,8 0),\
+ (-20 0,4 0),(5 0,20 0))"),
+ "llu01-7");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,4 0)"),
+ from_wkt<L>("LINESTRING(2 0,4 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((2 0,4 0),(0 0,2 0))"),
+ "llu01-8");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,2 0)"),
+ from_wkt<L>("LINESTRING(4 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,2 0),(4 0,5 0))"),
+ "llu01-10");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,2 0)"),
+ from_wkt<L>("LINESTRING(2 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,2 0),(2 0,5 0))"),
+ "llu01-11");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,4 0)"),
+ from_wkt<L>("LINESTRING(3 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,4 0),(4 0,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((3 0,5 0),(0 0,1 0,3 0))"),
+ "llu01-11a");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,4 0)"),
+ from_wkt<L>("LINESTRING(3 0,4 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,4 0),(4 0,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((3 0,4 0,5 0),(0 0,1 0,3 0))"),
+ "llu01-11b");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,6 0)"),
+ from_wkt<L>("LINESTRING(2 0,4 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((2 0,4 0,5 0),(0 0,2 0),(5 0,6 0))"),
+ "llu01-12");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,5 5,10 5,15 0)"),
+ from_wkt<L>("LINESTRING(-1 6,0 5,15 5)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,5 5,10 5,15 0),\
+ (-1 6,0 5,5 5),(10 5,15 5))"),
+ from_wkt<ML>("MULTILINESTRING((-1 6,0 5,15 5),\
+ (0 0,1 0,5 5),(10 5,15 0))"),
+ "llu02");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0)"),
+ from_wkt<L>("LINESTRING(-1 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0),\
+ (-1 0,0 0),(1 0,15 0),(20 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0))"),
+ "llu03");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,5 5,10 5,15 0,20 0)"),
+ from_wkt<L>("LINESTRING(-1 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,5 5,10 5,15 0,20 0),\
+ (-1 0,0 0),(1 0,15 0),(20 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,30 0),(1 0,5 5,10 5,15 0))"),
+ "llu04");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,25 1)"),
+ from_wkt<L>("LINESTRING(-1 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,25 1),\
+ (-1 0,0 0),(1 0,15 0),(20 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0),(20 0,25 1))"),
+ "llu05");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,30 0)"),
+ from_wkt<L>("LINESTRING(-1 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,30 0),\
+ (-1 0,0 0),(1 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0))"),
+ "llu05-1");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,31 0)"),
+ from_wkt<L>("LINESTRING(-1 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,31 0),\
+ (-1 0,0 0),(1 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0),(30 0,31 0))"),
+ "llu06");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,31 0)"),
+ from_wkt<L>("LINESTRING(-1 0,25 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,31 0),\
+ (-1 0,0 0),(1 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,25 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0),(30 0,31 0))"),
+ "llu07");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,31 0)"),
+ from_wkt<L>("LINESTRING(-1 0,19 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,31 0),\
+ (-1 0,0 0),(1 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,19 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0),(30 0,31 0))"),
+ "llu08");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,30 0,31 1)"),
+ from_wkt<L>("LINESTRING(-1 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,\
+ 30 0,31 1),(-1 0,0 0),(1 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 0,30 0),(-1 1,0 0),\
+ (1 0,5 5,10 5,15 0),(30 0,31 1))"),
+ "llu09");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,5 5,10 5,15 0,20 0,30 0,31 1)"),
+ from_wkt<L>("LINESTRING(-1 -1,0 0,1 0,2 1,3 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,5 5,10 5,15 0,20 0,\
+ 30 0,31 1),(-1 -1,0 0),(1 0,2 1,3 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,1 0,2 1,3 0,30 0),\
+ (-1 1,0 0),(1 0,5 5,10 5,15 0),(30 0,31 1))"),
+ "llu10");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,20 0,\
+ 30 0,31 1)"),
+ from_wkt<L>("LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,4 0,5 5,10 5,15 0,20 0,\
+ 30 0,31 1),(-1 -1,0 0),(2 0,2.5 1,3 0),(4 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0),\
+ (-1 1,0 0),(2 0,3 0),(4 0,5 5,10 5,15 0),(30 0,31 1))"),
+ "llu11");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0)"),
+ from_wkt<L>("LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,1 0,4 0,5 5,10 5,15 0,31 0),\
+ (-1 -1,0 0),(2 0,2.5 1,3 0),(4 0,15 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0),\
+ (-1 1,0 0),(2 0,3 0),(4 0,5 5,10 5,15 0),(30 0,31 0))"),
+ "llu11-1");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,2 0,3 1)"),
+ from_wkt<L>("LINESTRING(0 0,2 0,3 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,2 0,3 1))"),
+ "llu12");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,2 0,3 1)"),
+ from_wkt<L>("LINESTRING(3 1,2 0,0 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,2 0,3 1))"),
+ from_wkt<ML>("MULTILINESTRING((3 1,2 0,0 0))"),
+ "llu12-1");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,2 1,3 5,4 0)"),
+ from_wkt<L>("LINESTRING(1 0,2 1,3 5,4 0,5 10)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 1,3 5,4 0),(4 0,5 10))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,2 1,3 5,4 0,5 10),(0 0,1 0))"),
+ "llu13");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,2 0,2.5 0,3 1)"),
+ from_wkt<L>("LINESTRING(0 0,2 0,2.5 0,3 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 0,2.5 0,3 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,2 0,2.5 0,3 1))"),
+ "llu14");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,2 1,3 5,4 0)"),
+ from_wkt<L>("LINESTRING(1 0,2 1,3 5)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 1,3 5,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,2 1,3 5),(0 0,1 0),(3 5,4 0))"),
+ "llu15");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,2 1,3 2)"),
+ from_wkt<L>("LINESTRING(0.5 0,1 0,3 2,4 5)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 1,3 2),(3 2,4 5))"),
+ from_wkt<ML>("MULTILINESTRING((0.5 0,1 0,3 2,4 5),(0 0,0.5 0))"),
+ "llu16");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,2 1,3 2)"),
+ from_wkt<L>("LINESTRING(4 5,3 2,1 0,0.5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 1,3 2),(4 5,3 2))"),
+ from_wkt<ML>("MULTILINESTRING((4 5,3 2,1 0,0.5 0),(0 0,0.5 0))"),
+ "llu16-r");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,10 0,20 1,30 1)"),
+ from_wkt<L>("LINESTRING(1 1,2 0,3 1,20 1,25 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1,30 1),(1 1,2 0,3 1,20 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,3 1,20 1,25 1),\
+ (0 0,10 0,20 1),(25 1,30 1))"),
+ "llu17");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,10 0,20 1,21 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 1,2 0,3 1,20 1,25 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1,21 0,30 0),\
+ (1 1,2 0,3 1,20 1,25 0))"),
+ "llu18");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0,5 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0,5 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0,5 1),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(5 1,4 0,4 1,20 1,5 0,1 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 1,4 0,4 1,20 1,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((5 1,4 0,4 1,20 1,5 0,1 0),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19-r");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0),(0 0,1 0),\
+ (5 0,30 0))"),
+ "llu19a");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(4 0,4 1,20 1,5 0,1 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(4 0,4 1,20 1,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((4 0,4 1,20 1,5 0,1 0),(0 0,1 0),\
+ (5 0,30 0))"),
+ "llu19a-r");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0,5 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0,5 0),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19b");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0,5 0,6 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0),(5 0,6 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0,5 0,6 1),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19c");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0,3 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0,3 0),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19d");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0,3 0,3 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0),(3 0,3 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0,3 0,3 1),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19e");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,4 0,5 0,5 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,4 0),(5 0,5 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,4 0,5 0,5 1),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19f");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(5 1,5 0,4 0,4 1,20 1,5 0,1 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 1,5 0),\
+ (4 0,4 1,20 1,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((5 1,5 0,4 0,4 1,20 1,5 0,1 0),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19f-r");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(1 0,5 0,20 1,4 1,5 0,5 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 0,20 1,4 1,5 0,5 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,5 0,20 1,4 1,5 0,5 1),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19g");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<L>("LINESTRING(5 1,5 0,4 1,20 1,5 0,1 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(5 1,5 0,4 1,20 1,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((5 1,5 0,4 1,20 1,5 0,1 0),\
+ (0 0,1 0),(5 0,30 0))"),
+ "llu19g-r");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0,30 30,10 30,10 -10,15 0,40 0)"),
+ from_wkt<L>("LINESTRING(5 5,10 0,10 30,20 0,25 0,25 25,50 0,35 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0,30 30,10 30,10 -10,15 0,40 0),\
+ (5 5,10 0),(10 30,20 0),(25 0,25 25,50 0,40 0))"),
+ from_wkt<ML>("MULTILINESTRING((5 5,10 0,10 30,20 0,25 0,25 25,50 0,35 0),\
+ (0 0,20 0),(25 0,30 0,30 30,10 30),\
+ (10 0,10 -10,15 0,20 0),(25 0,35 0))"),
+ "llu20");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0,30 30,10 30,10 -10,15 0,40 0)"),
+ from_wkt<L>("LINESTRING(5 5,10 0,10 30,20 0,25 0,25 25,50 0,15 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0,30 30,10 30,10 -10,15 0,40 0),\
+ (5 5,10 0),(10 30,20 0),(25 0,25 25,50 0,40 0))"),
+ from_wkt<ML>("MULTILINESTRING((5 5,10 0,10 30,20 0,25 0,25 25,50 0,15 0),\
+ (0 0,15 0),(30 0,30 30,10 30),(10 0,10 -10,15 0))"),
+ "llu20a");
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,18 0,19 0,30 0)"),
+ from_wkt<L>("LINESTRING(2 2,5 -1,15 2,18 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),\
+ (2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((2 2,5 -1,15 2,18 0,20 0),\
+ (0 0,18 0),(20 0,30 0))"),
+ "llu21"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(2 2,5 -1,15 2,18 0,20 0)"),
+ from_wkt<L>("LINESTRING(0 0,18 0,19 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((2 2,5 -1,15 2,18 0,20 0),\
+ (0 0,18 0),(20 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),\
+ (2 2,5 -1,15 2,18 0))"),
+ "llu21a"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,3 0,\
+ 4 -1,-7 10,-4 10)"),
+ from_wkt<L>("LINESTRING(-5 -4,3 0,4 -1,7 -4,2 -1,-4 -1,-2 6)"),
+ from_wkt<ML>("MULTILINESTRING((-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,3 0,\
+ 4 -1,-7 10,-4 10),(-5 -4,3 0),\
+ (4 -1,7 -4,2 -1,-4 -1,-2 6))"),
+ from_wkt<ML>("MULTILINESTRING((-5 -4,3 0,4 -1,7 -4,2 -1,-4 -1,-2 6),\
+ (-2 -2,-4 0,1 -8,-2 6,8 5,-7 -8,3 0),\
+ (3 0,-7 10,-4 10))"),
+ "llu22"
+ );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( test_union_linestring_multilinestring )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** LINESTRING / MULTILINESTRING UNION ***"
+ << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef linestring_type L;
+ typedef multi_linestring_type ML;
+
+ typedef test_union_of_geometries<L, ML, ML> tester;
+
+ // disjoint linestrings
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,10 0,20 1)"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 2,4 3),(1 1,2 2,5 3))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 1,2 2,4 3),\
+ (1 1,2 2,5 3))"),
+ "lmlu01"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,10 0,20 1)"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(1 1,3 0,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 1,2 0),(1 1,3 0))"),
+ "lmlu02"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,10 0,20 1)"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(1 1,3 0,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 1,2 0),(1 1,3 0))"),
+ "lmlu03"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,10 0,20 1)"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 1,2 0))"),
+ "lmlu04"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,101 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,101 0),(-1 -1,1 0),(101 0,200 -1))"),
+ "lmlu07"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(-1 1,0 0,101 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,50 0),\
+ (19 -1,20 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,101 0),(-1 -1,0 0),\
+ (19 -1,20 0),(101 0,200 -1))"),
+ "lmlu07a"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,101 0)"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,50 0),\
+ (19 -1,20 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,101 0),(-1 -1,0 0),\
+ (19 -1,20 0),(101 0,200 -1))"),
+ "lmlu07b"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,101 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,2 0),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,101 0),(0 1,1 1,2 0),\
+ (-1 -1,1 0),(101 0,200 -1))"),
+ "lmlu08"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,2 0.5,3 0,101 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,2 0.5),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 0.5,3 0,101 0),\
+ (0 1,1 1,2 0.5),(-1 -1,1 0,3 0),(101 0,200 -1))"),
+ "lmlu09"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,1 0,1.5 0,2 0.5,3 0,101 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,1 0,2 0.5),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,1.5 0,2 0.5,3 0,101 0),\
+ (0 1,1 1,1 0,2 0.5),(-1 -1,1 0),(1.5 0,3 0),\
+ (101 0,200 -1))"),
+ "lmlu10"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (1 1,2 0,18 0,19 1),(2 1,3 0,17 0,18 1),\
+ (3 1,4 0,16 0,17 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (1 1,2 0),(18 0,19 1),(2 1,3 0),(17 0,18 1),\
+ (3 1,4 0),(16 0,17 1))"),
+ "lmlu12"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((1 0,19 0,20 1),\
+ (2 0,18 0,19 1),(3 0,17 0,18 1),\
+ (4 0,16 0,17 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(19 0,20 1),(18 0,19 1),\
+ (17 0,18 1),(16 0,17 1))"),
+ "lmlu13"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1,19 1,18 0,2 0,\
+ 1 1,2 1,3 0,17 0,18 1,17 1,16 0,4 0,3 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),\
+ (19 0,20 1,19 1,18 0),(2 0,1 1,2 1,3 0),\
+ (17 0,18 1,17 1,16 0),(4 0,3 1))"),
+ "lmlu14"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 2,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 2,6 0))"),
+ "lmlu15"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (6 0,4 2,2 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (6 0,4 2,2 2))"),
+ "lmlu15a"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 2,5 0,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 2,5 0))"),
+ "lmlu16"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,20 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (6 0,5 0,4 2,2 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (5 0,4 2,2 2))"),
+ "lmlu16a"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0))"),
+ "lmlu17"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0,26 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0,26 2))"),
+ "lmlu17a"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,5 -1,15 2,18 0))"),
+ "lmlu18"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,18 0,19 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),(0 1,1 0),\
+ (19 0,20 1),(2 2,5 -1,15 2,18 0))"),
+ "lmlu18a"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,18 0,19 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),(0 1,1 0),\
+ (19 0,20 1),(2 2,5 -1,15 2,18 0))"),
+ "lmlu18b"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,18 0,19 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,25 0,26 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),(0 1,1 0),\
+ (19 0,20 1),(2 2,5 -1,15 2,25 0))"),
+ "lmlu18c"
+ );
+
+ tester::apply
+ (from_wkt<L>("LINESTRING(0 0,18 0,19 0,30 0)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,25 0,21 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),(0 1,1 0),\
+ (19 0,20 1),(2 2,5 -1,15 2,25 0))"),
+ "lmlu18d"
+ );
+}
+
+
+
+BOOST_AUTO_TEST_CASE( test_union_multilinestring_linestring )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** MULTILINESTRING / LINESTRING UNION ***"
+ << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef linestring_type L;
+ typedef multi_linestring_type ML;
+
+ typedef test_union_of_geometries<ML, L, ML> tester;
+
+ // disjoint linestrings
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0))"),
+ from_wkt<L>("LINESTRING(1 1,2 2,4 3)"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 2,4 3),(0 0,10 0,20 1),(1 0,7 0))"),
+ "mllu01"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0))"),
+ from_wkt<L>("LINESTRING(1 1,2 0,4 0)"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(0 0,2 0),(4 0,10 0,20 1),\
+ (1 0,2 0),(4 0,7 0))"),
+ "mllu02"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,101 0))"),
+ from_wkt<L>("LINESTRING(-1 -1,1 0,101 0,200 -1)"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,1 0,101 0,200 -1),(0 0,1 0))"),
+ "mllu03"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<L>("LINESTRING(0 1,1 0,19 0,20 1,19 1,18 0,2 0,\
+ 1 1,2 1,3 0,17 0,18 1,17 1,16 0,4 0,3 1)"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1,19 1,18 0,2 0,\
+ 1 1,2 1,3 0,17 0,18 1,17 1,16 0,4 0,3 1),\
+ (0 0,1 0),(19 0,20 0))"),
+ "mllu04"
+ );
+}
+
+
+
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_union_multilinestring_multilinestring )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** MULTILINESTRING / MULTILINESTRING UNION ***"
+ << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef multi_linestring_type ML;
+
+ typedef test_union_of_geometries<ML, ML, ML> tester;
+
+ // disjoint linestrings
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 2,4 3),(1 1,2 2,5 3))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0),\
+ (1 1,2 2,4 3),(1 1,2 2,5 3))"),
+ "mlmlu01"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(1 1,3 0,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0),\
+ (1 1,2 0),(1 1,3 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(1 1,3 0,4 0),\
+ (0 0,2 0),(4 0,10 0,20 1),(1 0,2 0),(4 0,7 0))"),
+ "mlmlu02"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(1 1,3 0,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0),\
+ (1 1,2 0),(1 1,3 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(1 1,3 0,5 0),\
+ (0 0,2 0),(5 0,10 0,20 1),(1 0,2 0),(5 0,7 0))"),
+ "mlmlu03"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0),\
+ (1 1,2 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),(0 0,2 0),\
+ (4 0,10 0,20 1),(1 0,2 0),(4 0,7 0))"),
+ "mlmlu04"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0),\
+ (10 10,20 10,30 20))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),\
+ (10 20,15 10,25 10,30 15))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 1),(1 0,7 0),\
+ (10 10,20 10,30 20),(1 1,2 0),(10 20,15 10),\
+ (20 10,25 10,30 15))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),\
+ (10 20,15 10,25 10,30 15),(0 0,2 0),(4 0,10 0,20 1),\
+ (1 0,2 0),(4 0,7 0),(10 10,15 10),(20 10,30 20))"),
+ "mlmlu05"
+ );
+
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 10),(1 0,7 0),\
+ (10 10,20 10,30 20))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),\
+ (-1 -1,0 0,9 0,11 10,12 10,13 3,14 4,15 5),\
+ (10 20,15 10,25 10,30 15))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 10),(1 0,7 0),\
+ (10 10,20 10,30 20),(1 1,2 0),\
+ (-1 -1,0 0),(9 0,11 10),(12 10,13 3),(10 20,15 10),\
+ (20 10,25 10,30 15))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),\
+ (-1 -1,0 0,9 0,11 10,12 10,13 3,14 4,15 5),\
+ (10 20,15 10,25 10,30 15),(9 0,10 0,13 3),\
+ (15 5,20 10),(10 10,11 10),(12 10,15 10),(20 10,30 20))"),
+ "mlmlu06"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),\
+ (-1 -1,0 0,9 0,11 10,12 10,13 3,14 4,15 5),\
+ (10 20,15 10,25 10,30 15))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 10),(1 0,7 0),\
+ (10 10,20 10,30 20))"),
+ from_wkt<ML>("MULTILINESTRING((1 1,2 0,4 0),\
+ (-1 -1,0 0,9 0,11 10,12 10,13 3,14 4,15 5),\
+ (10 20,15 10,25 10,30 15),(9 0,10 0,13 3),\
+ (15 5,20 10),(10 10,11 10),(12 10,15 10),\
+ (20 10,30 20))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,10 0,20 10),(1 0,7 0),\
+ (10 10,20 10,30 20),(1 1,2 0),(-1 -1,0 0), \
+ (9 0,11 10),(12 10,13 3),(10 20,15 10),\
+ (20 10,25 10,30 15))"),
+ "mlmlu06a"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,101 0),(-1 -1,1 0),(101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,1 0,101 0,200 -1),(0 0,1 0))"),
+ "mlmlu07"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((-1 1,0 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,50 0),\
+ (19 -1,20 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((-1 1,0 0,101 0),(-1 -1,0 0),\
+ (19 -1,20 0),(101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,50 0),\
+ (19 -1,20 0,101 0,200 -1),(-1 1,0 0))"),
+ "mlmlu07a"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,50 0),\
+ (19 -1,20 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,101 0),(-1 -1,0 0),\
+ (19 -1,20 0),(101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((-1 -1,0 0,50 0),\
+ (19 -1,20 0,101 0,200 -1))"),
+ "mlmlu07b"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,2 0),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,101 0),(0 1,1 1,2 0),\
+ (-1 -1,1 0),(101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,2 0),\
+ (-1 -1,1 0,101 0,200 -1),(0 0,1 0))"),
+ "mlmlu08"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 0.5,3 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,2 0.5),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,2 0.5,3 0,101 0),\
+ (0 1,1 1,2 0.5),(-1 -1,1 0,3 0),(101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,2 0.5),\
+ (-1 -1,1 0,101 0,200 -1),(0 0,1 0,2 0.5,3 0))"),
+ "mlmlu09"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,1 0,1.5 0,2 0.5,3 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,1 0,2 0.5),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 0,1.5 0,2 0.5,3 0,101 0),\
+ (0 1,1 1,1 0,2 0.5),(-1 -1,1 0),(1.5 0,3 0),\
+ (101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 1,1 0,2 0.5),\
+ (-1 -1,1 0,101 0,200 -1),(0 0,1 0),(1.5 0,2 0.5,3 0))"),
+ "mlmlu10"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,1 1,100 1,101 0),\
+ (0 0,101 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,1 1,2 1,3 0,4 0,5 1,6 1,\
+ 7 0,8 0,9 1,10 1,11 0,12 0,13 1,14 1,15 0),\
+ (-1 -1,1 0,101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,1 1,100 1,101 0),\
+ (0 0,101 0),(1 0,1 1),(2 1,3 0),(4 0,5 1),(6 1,7 0),\
+ (8 0,9 1),(10 1,11 0),(12 0,13 1),(14 1,15 0),\
+ (-1 -1,1 0),(101 0,200 -1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,1 1,2 1,3 0,4 0,5 1,6 1,\
+ 7 0,8 0,9 1,10 1,11 0,12 0,13 1,14 1,15 0),\
+ (-1 -1,1 0,101 0,200 -1),(0 0,1 1),(2 1,5 1),\
+ (6 1,9 1),(10 1,13 1),(14 1,100 1,101 0),(0 0,1 0))"),
+ "mlmlu11"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (1 1,2 0,18 0,19 1),(2 1,3 0,17 0,18 1),\
+ (3 1,4 0,16 0,17 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (1 1,2 0),(18 0,19 1),(2 1,3 0),(17 0,18 1),\
+ (3 1,4 0),(16 0,17 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (1 1,2 0,18 0,19 1),(2 1,3 0,17 0,18 1),\
+ (3 1,4 0,16 0,17 1),(0 0,1 0),(19 0,20 0))"),
+ "mlmlu12"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,19 0,20 1),\
+ (2 0,18 0,19 1),(3 0,17 0,18 1),\
+ (4 0,16 0,17 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(19 0,20 1),(18 0,19 1),\
+ (17 0,18 1),(16 0,17 1))"),
+ from_wkt<ML>("MULTILINESTRING((1 0,19 0,20 1),\
+ (2 0,18 0,19 1),(3 0,17 0,18 1),\
+ (4 0,16 0,17 1),(0 0,1 0),(19 0,20 0))"),
+ "mlmlu13"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1,19 1,18 0,2 0,\
+ 1 1,2 1,3 0,17 0,18 1,17 1,16 0,4 0,3 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),\
+ (19 0,20 1,19 1,18 0),(2 0,1 1,2 1,3 0),\
+ (17 0,18 1,17 1,16 0),(4 0,3 1))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1,19 1,18 0,2 0,\
+ 1 1,2 1,3 0,17 0,18 1,17 1,16 0,4 0,3 1),\
+ (0 0,1 0),(19 0,20 0))"),
+ "mlmlu14"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 2,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 2,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 2,6 0),(0 0,1 0),(19 0,20 0))"),
+ "mlmlu15"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (6 0,4 2,2 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (6 0,4 2,2 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (6 0,4 2,2 2),(0 0,1 0),(19 0,20 0))"),
+ "mlmlu15a"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 2,5 0,6 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 2,5 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 2,5 0,6 0),(0 0,1 0),(19 0,20 0))"),
+ "mlmlu16"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,20 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (6 0,5 0,4 2,2 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,20 0),(0 1,1 0),(19 0,20 1),\
+ (5 0,4 2,2 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (6 0,5 0,4 2,2 2),(0 0,1 0),(19 0,20 0))"),
+ "mlmlu16a"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0),(0 0,1 0),(19 0,30 0))"),
+ "mlmlu17"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0,26 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0,26 2))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,4 0,5 2,20 2,25 0,26 2),(0 0,1 0),(19 0,30 0))"),
+ "mlmlu17a"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,30 0),(0 1,1 0),(19 0,20 1),\
+ (2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0),(0 0,1 0),(19 0,30 0))"),
+ "mlmlu18"
+ );
+
+ tester::apply
+ (from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 0,18 0,19 0,30 0),(0 1,1 0),\
+ (19 0,20 1),(2 2,5 -1,15 2,18 0))"),
+ from_wkt<ML>("MULTILINESTRING((0 1,1 0,19 0,20 1),\
+ (2 2,5 -1,15 2,18 0),(0 0,1 0),(19 0,30 0))"),
+ "mlmlu18a"
+ );
+}
diff --git a/libs/geometry/test/algorithms/set_operations/union/union_pl_pl.cpp b/libs/geometry/test/algorithms/set_operations/union/union_pl_pl.cpp
new file mode 100644
index 000000000..59798be23
--- /dev/null
+++ b/libs/geometry/test/algorithms/set_operations/union/union_pl_pl.cpp
@@ -0,0 +1,187 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_union_pointlike_pointlike
+#endif
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+#define BOOST_GEOMETRY_DEBUG_TURNS
+#define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "../test_set_ops_pl_pl.hpp"
+
+#include <boost/geometry/geometries/multi_point.hpp>
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+
+
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+
+BOOST_AUTO_TEST_CASE( test_union_point_point )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** POINT / POINT UNION ***" << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef point_type P;
+ typedef multi_point_type MP;
+
+ typedef test_set_op_of_pointlike_geometries
+ <
+ P, P, MP, bg::overlay_union
+ > tester;
+
+ tester::apply
+ (from_wkt<P>("POINT(0 0)"),
+ from_wkt<P>("POINT(1 1)"),
+ from_wkt<MP>("MULTIPOINT(0 0,1 1)"),
+ "ppu01");
+
+ tester::apply
+ (from_wkt<P>("POINT(0 0)"),
+ from_wkt<P>("POINT(0 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0)"),
+ "ppu02");
+}
+
+
+BOOST_AUTO_TEST_CASE( test_union_multipoint_point )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** MULTIPOINT / POINT UNION ***" << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef point_type P;
+ typedef multi_point_type MP;
+
+ typedef test_set_op_of_pointlike_geometries
+ <
+ MP, P, MP, bg::overlay_union
+ > tester;
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0)"),
+ from_wkt<P>("POINT(1 1)"),
+ from_wkt<MP>("MULTIPOINT(0 0,1 1)"),
+ "mppu01");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0)"),
+ from_wkt<P>("POINT(0 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0)"),
+ "mppu02");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,0 0)"),
+ from_wkt<P>("POINT(1 1)"),
+ from_wkt<MP>("MULTIPOINT(0 0,0 0,1 1)"),
+ "mppu03");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,0 0)"),
+ from_wkt<P>("POINT(0 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0)"),
+ "mppu04");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,0 0,1 0)"),
+ from_wkt<P>("POINT(1 1)"),
+ from_wkt<MP>("MULTIPOINT(0 0,0 0,1 0,1 1)"),
+ "mppu05");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,0 0,1 0)"),
+ from_wkt<P>("POINT(1 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0,0 0,1 0)"),
+ "mppu06");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,0 0,1 0)"),
+ from_wkt<P>("POINT(0 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0,1 0)"),
+ "mppu07");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT()"),
+ from_wkt<P>("POINT(0 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0)"),
+ "mppu08");
+}
+
+
+BOOST_AUTO_TEST_CASE( test_union_multipoint_multipoint )
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl << std::endl << std::endl;
+ std::cout << "*** MULTIPOINT / MULTIPOINT UNION ***" << std::endl;
+ std::cout << std::endl;
+#endif
+
+ typedef multi_point_type MP;
+
+ typedef test_set_op_of_pointlike_geometries
+ <
+ MP, MP, MP, bg::overlay_union
+ > tester;
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(2 2,3 3,0 0,0 0,2 2,1 1,1 1,1 0,1 0)"),
+ from_wkt<MP>("MULTIPOINT(1 0,1 1,1 1,1 1)"),
+ from_wkt<MP>("MULTIPOINT(2 2,3 3,0 0,0 0,2 2,1 1,1 1,1 0,1 0)"),
+ from_wkt<MP>("MULTIPOINT(1 0,1 1,1 1,1 1,2 2,3 3,0 0,0 0,2 2)"),
+ "mpmpu01");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,1 1,1 0,1 1)"),
+ from_wkt<MP>("MULTIPOINT(1 0,0 0,1 1,0 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0,1 1,1 0,1 1)"),
+ from_wkt<MP>("MULTIPOINT(1 0,0 0,1 1,0 0)"),
+ "mpmpu02");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT()"),
+ from_wkt<MP>("MULTIPOINT(1 0,0 0,1 1,0 0)"),
+ from_wkt<MP>("MULTIPOINT(1 0,0 0,1 1,0 0)"),
+ "mpmpu03");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,1 1,1 0,1 1)"),
+ from_wkt<MP>("MULTIPOINT()"),
+ from_wkt<MP>("MULTIPOINT(0 0,1 1,1 0,1 1)"),
+ "mpmpu04");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT()"),
+ from_wkt<MP>("MULTIPOINT()"),
+ from_wkt<MP>("MULTIPOINT()"),
+ "mpmpu05");
+
+ tester::apply
+ (from_wkt<MP>("MULTIPOINT(0 0,1 0,2 0,3 0,0 0,1 0,2 0)"),
+ from_wkt<MP>("MULTIPOINT(0 1,0 2,1 0,0 0,2 0)"),
+ from_wkt<MP>("MULTIPOINT(0 0,1 0,2 0,3 0,0 0,1 0,2 0,0 1,0 2)"),
+ from_wkt<MP>("MULTIPOINT(0 1,0 2,1 0,0 0,2 0,3 0)"),
+ "mpmpu06");
+}
+