// Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test // Copyright (c) 2014, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #ifndef BOOST_TEST_MODULE #define BOOST_TEST_MODULE test_is_simple #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef GEOMETRY_TEST_DEBUG #include #include #include #include #endif #include #include namespace bg = ::boost::geometry; typedef bg::model::point point_type; typedef bg::model::segment segment_type; typedef bg::model::linestring linestring_type; typedef bg::model::multi_linestring multi_linestring_type; // ccw open and closed polygons typedef bg::model::polygon open_ccw_polygon_type; typedef bg::model::polygon closed_ccw_polygon_type; // multi-geometries typedef bg::model::multi_point multi_point_type; typedef bg::model::multi_polygon multi_polygon_type; // box typedef bg::model::box box_type; template Geometry from_wkt(std::string const& wkt) { Geometry g; bg::read_wkt(wkt, g); return g; } //---------------------------------------------------------------------------- #ifdef GEOMETRY_TEST_DEBUG template ::type> struct pretty_print_geometry { static inline std::ostream& apply(std::ostream& os, Geometry const& geometry) { os << bg::wkt(geometry); return os; } }; template struct pretty_print_geometry { static inline std::ostream& apply(std::ostream& os, Box const& box) { return os << "BOX" << bg::dsv(box); } }; template struct pretty_print_geometry { static inline std::ostream& apply(std::ostream& os, Segment const& segment) { return os << "SEGMENT" << bg::dsv(segment); } }; template struct pretty_print_geometry { static inline std::ostream& apply(std::ostream& os, Ring const& ring) { return os << "RING" << bg::dsv(ring); } }; #endif //---------------------------------------------------------------------------- template void test_simple(Geometry const& g, bool simple_geometry) { #ifdef GEOMETRY_TEST_DEBUG std::cout << "=======" << std::endl; #endif bool simple = bg::is_simple(g); BOOST_CHECK(simple == simple_geometry); #ifdef GEOMETRY_TEST_DEBUG std::cout << "Geometry: "; pretty_print_geometry::apply(std::cout, g); std::cout << std::endl; std::cout << std::boolalpha; std::cout << "is valid : " << bg::is_valid(g) << std::endl; std::cout << "is simple: " << simple << std::endl; std::cout << "expected result: " << simple_geometry << std::endl; std::cout << "=======" << std::endl; std::cout << std::endl << std::endl; std::cout << std::noboolalpha; #endif } //---------------------------------------------------------------------------- BOOST_AUTO_TEST_CASE( test_is_simple_point ) { #ifdef GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; std::cout << " is_simple: POINT " << std::endl; std::cout << "************************************" << std::endl; #endif typedef point_type G; test_simple(from_wkt("POINT(0 0)"), true); } BOOST_AUTO_TEST_CASE( test_is_simple_multipoint ) { #ifdef GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; std::cout << " is_simple: MULTIPOINT " << std::endl; std::cout << "************************************" << std::endl; #endif typedef multi_point_type G; test_simple(from_wkt("MULTIPOINT()"), false); test_simple(from_wkt("MULTIPOINT(0 0)"), true); test_simple(from_wkt("MULTIPOINT(0 0,1 0,1 1,0 1)"), true); test_simple(from_wkt("MULTIPOINT(0 0,1 0,1 1,1 0,0 1)"), false); } BOOST_AUTO_TEST_CASE( test_is_simple_segment ) { #ifdef GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; std::cout << " is_simple: SEGMENT " << std::endl; std::cout << "************************************" << std::endl; #endif typedef segment_type G; test_simple(from_wkt("SEGMENT(0 0,0 0)"), false); test_simple(from_wkt("SEGMENT(0 0,1 0)"), true); } BOOST_AUTO_TEST_CASE( test_is_simple_linestring ) { #ifdef GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; std::cout << " is_simple: LINESTRING " << std::endl; std::cout << "************************************" << std::endl; #endif typedef linestring_type G; // invalid linestrings test_simple(from_wkt("LINESTRING()"), false); test_simple(from_wkt("LINESTRING(0 0)"), false); test_simple(from_wkt("LINESTRING(0 0,0 0)"), false); // valid linestrings with multiple points test_simple(from_wkt("LINESTRING(0 0,0 0,1 0)"), false); test_simple(from_wkt("LINESTRING(0 0,0 0,1 0,0 0)"), false); test_simple(from_wkt("LINESTRING(0 0,0 0,1 0,1 0,1 1,0 0)"), false); test_simple(from_wkt("LINESTRING(0 0,1 0,2 0,1 1,1 0,1 -1)"), false); // simple open linestrings test_simple(from_wkt("LINESTRING(0 0,1 2)"), true); test_simple(from_wkt("LINESTRING(0 0,1 2,2 3)"), true); // simple closed linestrings test_simple(from_wkt("LINESTRING(0 0,1 0,1 1,0 0)"), true); test_simple(from_wkt("LINESTRING(0 0,1 0,1 1,0 1,0 0)"), true); // non-simple linestrings test_simple(from_wkt("LINESTRING(0 0,1 0,0 0)"), false); test_simple(from_wkt("LINESTRING(0 0,1 0,2 10,0.5 -1)"), false); test_simple(from_wkt("LINESTRING(0 0,1 0,2 1,1 0)"), false); test_simple(from_wkt("LINESTRING(0 0,1 0,2 1,0.5 0)"), false); test_simple(from_wkt("LINESTRING(0 0,2 0,1 0)"), false); test_simple(from_wkt("LINESTRING(0 0,3 0,5 0,1 0)"), false); test_simple(from_wkt("LINESTRING(0 0,3 0,5 0,4 0)"), false); test_simple(from_wkt("LINESTRING(0 0,3 0,5 0,4 0,2 0)"), false); test_simple(from_wkt("LINESTRING(0 0,3 0,2 0,5 0)"), false); test_simple(from_wkt("LINESTRING(0 0,2 0,2 2,1 0,0 0)"), false); } BOOST_AUTO_TEST_CASE( test_is_simple_multilinestring ) { #ifdef GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; std::cout << " is_simple: MULTILINESTRING " << std::endl; std::cout << "************************************" << std::endl; #endif typedef multi_linestring_type G; // empty multilinestring test_simple(from_wkt("MULTILINESTRING()"), false); // multilinestrings with empty linestrings test_simple(from_wkt("MULTILINESTRING(())"), false); test_simple(from_wkt("MULTILINESTRING((),(),())"), false); test_simple(from_wkt("MULTILINESTRING((),(0 1,1 0))"), false); // multilinestrings with 1-point linestrings test_simple(from_wkt("MULTILINESTRING((0 0),(0 1,1 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,0 0),(0 1,1 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0),(1 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,0 0),(1 0,1 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0),(0 0))"), false); // multilinestrings with linestrings with spikes test_simple(from_wkt("MULTILINESTRING((0 0,1 0,0 0),(5 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 0,0 0),(5 0,1 0,4 1))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 0,0 0),(5 0,1 0,4 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 0,0 0),(1 0,2 0))"), false); // simple multilinestrings test_simple(from_wkt("MULTILINESTRING((0 0,1 1),(1 1,1 0))"), true); test_simple(from_wkt("MULTILINESTRING((0 0,1 1),(1 1,1 0),(0 1,1 1))"), true); test_simple(from_wkt("MULTILINESTRING((0 0,2 2),(0 0,1 0,2 0,2 2))"), true); test_simple(from_wkt("MULTILINESTRING((0 0,2 2),(2 2,2 0,1 0,0 0))"), true); test_simple(from_wkt("MULTILINESTRING((0 0,1 0),(0 0,-1 0),\ (1 0,2 0))"), true); test_simple(from_wkt("MULTILINESTRING((0 0,1 0),(-1 0,0 0),\ (2 0,1 0))"), true); test_simple(from_wkt("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(-1 0,0 0))"), true); // non-simple multilinestrings test_simple(from_wkt("MULTILINESTRING((0 0,2 2),(0 0,2 2))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,2 2),(2 2,0 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,2 2),\ (0 0,1 0,1 1,2 0,2 2))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 1,2 2),\ (0 0,1 0,1 1,2 0,2 2))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 1,2 2),(2 2,0 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 1),(0 1,1 0))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,2 0),(1 0,0 1))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 1),(1 1,1 0),\ (1 1,0 1,0.5,0.5))"), false); test_simple(from_wkt("MULTILINESTRING((0 0,1 0,1 1,0 1,0 0),(1 0,1 -1))"), false); } BOOST_AUTO_TEST_CASE( test_is_simple_areal ) { // for areal geometries validity and simplicity are identical // notions // here just check that the code compiles typedef box_type b; typedef open_ccw_polygon_type o_ccw_p; typedef multi_polygon_type mpl; test_simple(from_wkt("BOX(0 0,1 1)"), true); test_simple(from_wkt("POLYGON((0 0,1 0,1 1))"), true); test_simple(from_wkt("MULTIPOLYGON(((0 0,1 0,1 1)),\ ((10 0,20 0,20 10,10 10)))"), true); }