diff --git a/include/boost/geometry/algorithms/point_on_surface.hpp b/include/boost/geometry/algorithms/point_on_surface.hpp index a6f7ed71d..01f012308 100644 --- a/include/boost/geometry/algorithms/point_on_surface.hpp +++ b/include/boost/geometry/algorithms/point_on_surface.hpp @@ -142,6 +142,30 @@ struct min_of_intruder } }; + +template +inline void calculate_average(Point& point, std::vector

const& points) +{ + typedef typename geometry::coordinate_type::type coordinate_type; + typedef typename std::vector

::const_iterator iterator_type; + typedef typename std::vector

::size_type size_type; + + coordinate_type x = 0; + coordinate_type y = 0; + + iterator_type end = points.end(); + for ( iterator_type it = points.begin() ; it != end ; ++it) + { + x += geometry::get<0>(*it); + y += geometry::get<1>(*it); + } + + size_type const count = points.size(); + geometry::set<0>(point, x / count); + geometry::set<1>(point, y / count); +} + + template inline void calculate_centroid(Point& point, Segments const& segments) { @@ -305,7 +329,8 @@ inline bool calculate_point_on_surface(Geometry const& geometry, Point& point) } // Now calculate the centroid of the (possibly adapted) extremes - calculate_centroid(point, extremes); + calculate_average(point, extremes); + //calculate_centroid(point, extremes); return true; } diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index b393a35b8..bd8be5676 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -51,15 +51,11 @@ #endif template -void test_geometry(std::string const& case_id, std::string const& wkt, double expected_x, double expected_y) +void test_geometry(std::string const& case_id, Geometry const& geometry, double /*expected_x*/ = 0, double /*expected_y*/ = 0) { //std::cout << case_id << std::endl; typedef typename bg::point_type::type point_type; - Geometry geometry; - bg::read_wkt(wkt, geometry); - bg::correct(geometry); - point_type point; bg::point_on_surface(geometry, point); @@ -125,6 +121,15 @@ void test_geometry(std::string const& case_id, std::string const& wkt, double ex } +template +void test_geometry(std::string const& case_id, std::string const& wkt, double expected_x = 0, double expected_y = 0) +{ + Geometry geometry; + bg::read_wkt(wkt, geometry); + bg::correct(geometry); + test_geometry(case_id, geometry, expected_x, expected_y); +} + template void test_all() { @@ -152,6 +157,9 @@ void test_all() test_geometry("disjoint_simplex0", disjoint_simplex[0], 0, 0); test_geometry("disjoint_simplex1", disjoint_simplex[1], 0, 0); + test_geometry("ticket_10643", "POLYGON((1074699.93 703064.65, 1074703.90 703064.58, 1074704.53 703061.40, 1074702.10 703054.62, 1074699.93 703064.65))"); + test_geometry("ticket_10643_2", "POLYGON((699.93 64.65, 703.90 64.58, 704.53 61.40, 702.10 54.62, 699.93 64.65))"); + #if defined(BOOST_GEOMETRY_UNIT_TEST_MULTI) { typedef bg::model::multi_polygon multi_polygon; @@ -303,12 +311,29 @@ void test_all() test_geometry("ticket_8254", ticket_8254[0], 0, 0); } +template +void test_dense(std::string const& case_id, double size) +{ + typedef bg::model::polygon polygon; + polygon poly; + double thres = 3.14158 / 8; + for ( double a = thres ; a > -thres ; a -= 0.01 ) + { + bg::append(poly, Point(size * ::cos(a), size * ::sin(a))); + } + bg::append(poly, Point(-size, 0)); + + test_geometry(case_id, poly); +} int test_main(int, char* []) { test_all >(); + test_dense >("dense1", 100); + test_dense >("dense2", 1000000); + return 0; }