// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2020-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 #include #include #include #include #include #include #include #include #include typedef bg::model::point Pt; typedef bg::model::linestring Ls; typedef bg::model::polygon Po; typedef bg::model::ring R; typedef bg::model::multi_point MPt; typedef bg::model::multi_linestring MLs; typedef bg::model::multi_polygon MPo; template inline void check(std::string const& wkt1, std::string const& wkt2, G const& g, std::string const& expected) { G expect; bg::read_wkt(expected, expect); bg::correct(expect); if (! boost::empty(g) || ! boost::empty(expect)) { BOOST_CHECK_MESSAGE( // Commented out becasue the output in reversed case may be slightly different // e.g. different number of duplicated points in MultiPoint //boost::size(g) == boost::size(expect) && bg::equals(g, expect), wkt1 << " \\ " << wkt2 << " -> " << bg::wkt(g) << " different than expected: " << expected ); } } template inline void check(std::string const& wkt1, std::string const& wkt2, boost::tuple const& tup, std::string const& out_str) { check(wkt1, wkt2, boost::get(tup), out_str); } template inline void check(std::string const& wkt1, std::string const& wkt2, std::pair const& pair, std::string const& out_str) { if (BOOST_GEOMETRY_CONDITION(I == 0)) check(wkt1, wkt2, pair.first, out_str); else check(wkt1, wkt2, pair.second, out_str); } template inline void check(std::string const& wkt1, std::string const& wkt2, std::tuple const& tup, std::string const& out_str) { check(wkt1, wkt2, std::get(tup), out_str); } template using out_id = std::integral_constant < int, (bg::util::is_pointlike::value ? 0 : (bg::util::is_linear::value ? 1 : 2)) >; template inline void test_one(std::string const& in1_str, std::string const& in2_str, std::string const& out1_str, std::string const& out2_str) { In1 in1; bg::read_wkt(in1_str, in1); bg::correct(in1); In2 in2; bg::read_wkt(in2_str, in2); bg::correct(in2); { Tup result; bg::difference(in1, in2, result); check::value>(in1_str, in2_str, result, out1_str); } { Tup result; bg::difference(in2, in1, result); check::value>(in2_str, in1_str, result, out2_str); } } template inline void test_pp() { test_one( "POINT(0 0)", "POINT(0 0)", "MULTIPOINT()", "MULTIPOINT()"); test_one( "POINT(0 0)", "POINT(1 1)", "MULTIPOINT(0 0)", "MULTIPOINT(1 1)"); test_one( "POINT(0 0)", "MULTIPOINT(0 0, 1 1)", "MULTIPOINT()", "MULTIPOINT(1 1)"); test_one( "POINT(2 2)", "MULTIPOINT(0 0, 1 1)", "MULTIPOINT(2 2)", "MULTIPOINT(0 0, 1 1)"); test_one( "MULTIPOINT(0 0, 1 1, 2 2)", "MULTIPOINT(1 1, 3 3, 4 4)", "MULTIPOINT(0 0, 2 2)", "MULTIPOINT(3 3, 4 4)"); } template inline void test_pl() { test_one( "POINT(0 0)", "LINESTRING(0 0, 1 1)", "MULTIPOINT()", "MULTILINESTRING((0 0, 1 1))"); test_one( "POINT(0 1)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2),(4 4, 5 5))", "MULTIPOINT(0 1)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2),(4 4, 5 5))"); test_one( "MULTIPOINT(0 0, 1 1, 2 2, 3 3)", "LINESTRING(0 0, 1 1)", "MULTIPOINT(2 2, 3 3)", "MULTILINESTRING((0 0, 1 1))"); test_one( "MULTIPOINT(0 0, 1 1, 2 2, 3 3)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2),(4 4, 5 5))", "MULTIPOINT(3 3)", "MULTILINESTRING((0 0, 1 1),(1 1, 2 2),(4 4, 5 5))"); } template inline void test_pa() { test_one( "POINT(0 0)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))", "MULTIPOINT()", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)))"); test_one( "POINT(0 0)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTIPOINT()", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)))"); test_one( "POINT(3 3)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTIPOINT(3 3)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)))"); test_one( "POINT(2 2)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))", "MULTIPOINT()", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"); test_one( "POINT(3 3)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))", "MULTIPOINT(3 3)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"); test_one( "POINT(6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))", "MULTIPOINT(6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"); test_one( "MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))", "MULTIPOINT(6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)))"); test_one( "MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTIPOINT(1 1, 2 2, 3 3, 6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)))"); test_one( "MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))", "MULTIPOINT(3 3, 6 6)", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"); } template inline void test_ll() { test_one( "LINESTRING(0 0, 1 0, 2 1, 3 0)", "LINESTRING(0 0, 1 0, 3 0, 4 0)", "MULTILINESTRING((1 0, 2 1, 3 0))", "MULTILINESTRING((1 0, 3 0, 4 0))"); test_one( "LINESTRING(0 0, 1 0, 2 1, 3 0)", "MULTILINESTRING((0 0, 1 0, 3 0),(2 1, 2 2))", "MULTILINESTRING((1 0, 2 1, 3 0))", "MULTILINESTRING((1 0, 3 0),(2 1, 2 2))"); test_one( "MULTILINESTRING((0 0, 1 0, 2 1),(2 1, 3 0))", "MULTILINESTRING((0 0, 1 0, 3 0),(2 1, 2 2))", "MULTILINESTRING((1 0, 2 1),(2 1, 3 0))", "MULTILINESTRING((1 0, 3 0),(2 1, 2 2))"); test_one( "LINESTRING(0 0, 0 5, 5 5, 5 0, 0 0)", "LINESTRING(0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0)", "MULTILINESTRING((0 1, 0 5, 5 5),(5 2, 5 0))", "MULTILINESTRING((0 1, 6 1, 5 2),(5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 5 0))"); test_one( "MULTILINESTRING((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTILINESTRING((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))", "MULTILINESTRING((0 0, 0 5, 5 5, 5 4),(5 1, 5 0, 0 0),(4 4, 4 1))", "MULTILINESTRING((4 4, 5 4),(5 1, 4 1),(0 0, 2 1, 2 2, 1 2, 0 0))"); } template inline void test_la() { test_one( "LINESTRING(0 2, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9, 4 5, 3 3, 2 5, 2 9, 0 5)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))", "MULTILINESTRING((0 2, -4 1, 0 0),(5 0, 9 1, 5 2, 9 3, 5 5, 4 9, 4 5),(2 5, 2 9, 0 5))", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)))"); test_one( "LINESTRING(1 4, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9, 4 5, 3 3, 2 5, 2 9, 0 5)", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTILINESTRING((0 3.4, -4 1, 0 0),(5 0, 9 1, 5 2, 9 3, 5 5, 4 9, 4 5),(3.5 4, 3 3, 2.5 4),(2 5, 2 9, 0 5))", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)))"); test_one( "MULTILINESTRING((0 2, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9), (4 9, 4 5, 3 3, 2 5, 2 9, 0 5))", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))", "MULTILINESTRING((0 2, -4 1, 0 0),(5 0, 9 1, 5 2, 9 3, 5 5, 4 9),(4 9, 4 5),(2 5, 2 9, 0 5))", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0)))"); test_one( "MULTILINESTRING((1 4, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9), (4 9, 4 5, 3 3, 2 5, 2 9, 0 5))", "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTILINESTRING((0 3.4, -4 1, 0 0),(5 0, 9 1, 5 2, 9 3, 5 5, 4 9),(4 9, 4 5),(3.5 4, 3 3, 2.5 4),(2 5, 2 9, 0 5))", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)))"); test_one( "MULTILINESTRING((1 4, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9), (4 9, 4 5, 4 4, 2 2, 2 5, 1 9, 0 5))", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))", "MULTILINESTRING((0 3.4, -4 1, 0 0),(5 0, 9 1, 5 2, 9 3, 5 5, 4 9),(4 9, 4 5),(4 4, 2 2, 2 4),(2 5, 1 9, 0 5))", "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"); test_one( "LINESTRING(0 0, 0 5, 5 5, 5 0, 0 0)", "POLYGON((0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0))", "MULTILINESTRING((0 1, 0 5, 5 5),(5 2, 5 1))", "MULTIPOLYGON(((0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0)))"); test_one( "MULTILINESTRING((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "POLYGON((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))", "MULTILINESTRING((0 0, 0 5, 5 5, 5 4),(5 1, 5 0, 0 0))", "MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0)))"); } template inline void test_aa() { test_one( "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))", "POLYGON((0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0))", "MULTIPOLYGON(((0 1,0 5,5 5,5 1,0 1)))", "MULTIPOLYGON(((5 1,6 1,5 2,5 5,5 6,4 5,4 7,7 7,7 0,5 0,5 1)))"); test_one( "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))", "MULTIPOLYGON(((0 0, 0 1, 6 1, 6 0, 0 0))," "((6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 1, 6 1)))", "MULTIPOLYGON(((0 1,0 5,5 5,5 1,0 1)))", "MULTIPOLYGON(((5 1,6 1,6 0,5 0,5 1)),((5 2,5 5,5 6,4 5,4 7,7 7,7 1,6 1,5 2)))"); test_one( "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "POLYGON((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))", "MULTIPOLYGON(((5 1,5 0,0 0,4 1,5 1)),((5 4,1 4,0 0,0 5,5 5,5 4)))", "MULTIPOLYGON(((1 4,4 4,4 1,0 0,1 4),(0 0,2 1,2 2,1 2,0 0)))"); test_one( "POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))", "MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))," "((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))", "MULTIPOLYGON(((4 5,5 4,1 4,0 0,0 5,4 5)),((5 1,5 0,0 0,4 1,5 1)))", "MULTIPOLYGON(((5 0,5 1,6 1,6 4,5 4,5 5,4 5,3 6,2 5,2 7,7 7,7 0,5 0))," "((1 4,4 4,4 1,0 0,1 4),(0 0,2 1,2 2,1 2,0 0)))"); test_one( "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))," "((2 6, 2 8, 8 8, 8 5, 7 5, 7 6, 2 6)))", "MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))," "((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))", "MULTIPOLYGON(((4 5,5 4,1 4,0 0,0 5,4 5))," "((5 1,5 0,0 0,4 1,5 1))," "((2 7,2 8,8 8,8 5,7 5,7 6,7 7,2 7)))", "MULTIPOLYGON(((1 4,4 4,4 1,0 0,1 4),(0 0,2 1,2 2,1 2,0 0))," "((5 1,6 1,6 4,5 4,5 5,4 5,3 6,7 6,7 5,7 0,5 0,5 1))," "((3 6,2 5,2 6,3 6)))"); } template inline void test_pair() { test_pp(); test_pl(); test_ll(); } template inline void test_tuple() { test_pp(); test_pl(); test_pa(); test_ll(); test_la(); test_aa(); } int test_main(int, char* []) { test_pair >(); test_tuple >(); test_tuple >(); return 0; }