diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index a3dd8879e..66fef803e 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -35,6 +35,7 @@ [*Solved tickets] * [@https://svn.boost.org/trac/boost/ticket/11113 11113] Support easy enumeration of all elements with BOOST_FOREACH +* [@https://svn.boost.org/trac/boost/ticket/11236 11236] Invalid result of centroid() for integer coordinate type [/=================] [heading Boost 1.58] diff --git a/extensions/test/gis/Jamfile.v2 b/extensions/test/gis/Jamfile.v2 index 13dafde28..ac76bde76 100644 --- a/extensions/test/gis/Jamfile.v2 +++ b/extensions/test/gis/Jamfile.v2 @@ -3,11 +3,13 @@ # 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. +# Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland. # # 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) +build-project io ; build-project latlong ; build-project projections ; diff --git a/include/boost/geometry/arithmetic/arithmetic.hpp b/include/boost/geometry/arithmetic/arithmetic.hpp index 6eb31f488..fbc3ca443 100644 --- a/include/boost/geometry/arithmetic/arithmetic.hpp +++ b/include/boost/geometry/arithmetic/arithmetic.hpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace boost { namespace geometry @@ -32,80 +33,94 @@ namespace detail { -template +template struct param { typedef typename boost::call_traits < - typename coordinate_type

::type + typename coordinate_type::type >::param_type type; }; -template class Function> +template class Function> struct value_operation { - C m_value; + Value m_value; - inline value_operation(C const &value) + inline value_operation(Value const &value) : m_value(value) {} - template - inline void apply(P& point) const + template + inline void apply(PointDst& point_dst) const { - set(point, Function()(get(point), m_value)); + set(point_dst, + Function + < + typename geometry::select_most_precise + < + Value, + typename geometry::coordinate_type::type + >::type + >()(get(point_dst), m_value)); } }; template class Function> struct point_operation { - typedef typename coordinate_type::type coordinate_type; - PointSrc const& m_source_point; + PointSrc const& m_point_src; inline point_operation(PointSrc const& point) - : m_source_point(point) + : m_point_src(point) {} - template - inline void apply(PointDst& dest_point) const + template + inline void apply(PointDst& point_dst) const { - set(dest_point, - Function()(get(dest_point), get(m_source_point))); + set(point_dst, + Function + < + typename geometry::select_most_precise + < + typename geometry::coordinate_type::type, + typename geometry::coordinate_type::type + >::type + >()(get(point_dst), get(m_point_src))); } }; -template +template struct value_assignment { - C m_value; + Value m_value; - inline value_assignment(C const &value) + inline value_assignment(Value const &value) : m_value(value) {} - template - inline void apply(P& point) const + template + inline void apply(PointDst& point_dst) const { - set(point, m_value); + set(point_dst, m_value); } }; template struct point_assignment { - PointSrc const& m_source_point; + PointSrc const& m_point_src; inline point_assignment(PointSrc const& point) - : m_source_point(point) + : m_point_src(point) {} - template - inline void apply(PointDst& dest_point) const + template + inline void apply(PointDst& point_dst) const { - set(dest_point, get(m_source_point)); + set(point_dst, get(m_point_src)); } }; @@ -126,7 +141,12 @@ inline void add_value(Point& p, typename detail::param::type value) { BOOST_CONCEPT_ASSERT( (concept::Point) ); - for_each_coordinate(p, detail::value_operation::type, std::plus>(value)); + for_each_coordinate(p, + detail::value_operation + < + typename coordinate_type::type, + std::plus + >(value)); } /*! @@ -161,7 +181,12 @@ inline void subtract_value(Point& p, typename detail::param::type value) { BOOST_CONCEPT_ASSERT( (concept::Point) ); - for_each_coordinate(p, detail::value_operation::type, std::minus>(value)); + for_each_coordinate(p, + detail::value_operation + < + typename coordinate_type::type, + std::minus + >(value)); } /*! @@ -196,7 +221,12 @@ inline void multiply_value(Point& p, typename detail::param::type value) { BOOST_CONCEPT_ASSERT( (concept::Point) ); - for_each_coordinate(p, detail::value_operation::type, std::multiplies>(value)); + for_each_coordinate(p, + detail::value_operation + < + typename coordinate_type::type, + std::multiplies + >(value)); } /*! @@ -232,7 +262,12 @@ inline void divide_value(Point& p, typename detail::param::type value) { BOOST_CONCEPT_ASSERT( (concept::Point) ); - for_each_coordinate(p, detail::value_operation::type, std::divides>(value)); + for_each_coordinate(p, + detail::value_operation + < + typename coordinate_type::type, + std::divides + >(value)); } /*! @@ -267,7 +302,11 @@ inline void assign_value(Point& p, typename detail::param::type value) { BOOST_CONCEPT_ASSERT( (concept::Point) ); - for_each_coordinate(p, detail::value_assignment::type>(value)); + for_each_coordinate(p, + detail::value_assignment + < + typename coordinate_type::type + >(value)); } /*! diff --git a/include/boost/geometry/extensions/contrib/ttmath_stub.hpp b/include/boost/geometry/extensions/contrib/ttmath_stub.hpp index 014378e06..cb53fc114 100644 --- a/include/boost/geometry/extensions/contrib/ttmath_stub.hpp +++ b/include/boost/geometry/extensions/contrib/ttmath_stub.hpp @@ -184,6 +184,18 @@ namespace detail // 1) lexical cast -> stack overflow and // 2) because it is implemented as a function, generic implementation not possible + // Partial specialization for ttmath + template + struct define_half_pi > + { + static inline ttmath::Big apply() + { + static ttmath::Big const half_pi( + "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404325664115332354692230477529111586267970406424055872514205135096926055277982231147447746519098"); + return half_pi; + } + }; + // Partial specialization for ttmath template struct define_pi > @@ -196,11 +208,33 @@ namespace detail } }; + // Partial specialization for ttmath + template + struct define_two_pi > + { + static inline ttmath::Big apply() + { + static ttmath::Big const two_pi( + "6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617302656461329418768921910116446345071881625696223490056820540387704221111928924589790986076392"); + return two_pi; + } + }; + + template <> + struct define_half_pi + : public define_half_pi > + {}; + template <> struct define_pi : public define_pi > {}; + template <> + struct define_two_pi + : public define_two_pi > + {}; + template struct equals_with_epsilon, false> { diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp index 8751f70c9..b85447347 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp @@ -107,9 +107,12 @@ struct ewkt_policy { }; -template ::value> +template +< + typename Geometry, + geometry_type_ogc::enum_t OgcType, + std::size_t Dim = dimension::value +> struct geometry_type_impl { static bool check(boost::uint32_t value) @@ -123,8 +126,11 @@ struct geometry_type_impl } }; -template +template +< + typename Geometry, + geometry_type_ogc::enum_t OgcType +> struct geometry_type_impl { static bool check(boost::uint32_t value) diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp index cf569276d..154d70038 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -152,11 +151,10 @@ template struct parsing_assigner { template - static void run(Iterator& it, Iterator end, P& point, - byte_order_type::enum_t order) + static void run(Iterator& /*it*/, Iterator /*end*/, P& /*point*/, + byte_order_type::enum_t /*order*/) { // terminate - boost::ignore_unused(it, end, point, order); } }; diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp index 8dd0eda9d..7db961404 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/writer.hpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -67,13 +66,16 @@ namespace detail { namespace wkb } }; - template ::value> + template + < + typename Point, + std::size_t I = 0, + std::size_t N = dimension::value + > struct writer_assigner { template - static void run(P const& point, + static void run(Point const& point, OutputIterator& iter, byte_order_type::enum_t byte_order) { @@ -83,28 +85,27 @@ namespace detail { namespace wkb iter, byte_order); - writer_assigner::run(point, iter, byte_order); + writer_assigner::run(point, iter, byte_order); } }; - template - struct writer_assigner + template + struct writer_assigner { template - static void run(P const& point, - OutputIterator& iter, - byte_order_type::enum_t byte_order) + static void run(Point const& /*point*/, + OutputIterator& /*iter*/, + byte_order_type::enum_t /*byte_order*/) { // terminate - boost::ignore_unused(point, iter, byte_order); } }; - template + template struct point_writer { template - static bool write(P const& point, + static bool write(Point const& point, OutputIterator& iter, byte_order_type::enum_t byte_order) { @@ -112,21 +113,21 @@ namespace detail { namespace wkb value_writer::write(byte_order, iter, byte_order); // write geometry type - uint32_t type = geometry_type

::get(); + uint32_t type = geometry_type::get(); value_writer::write(type, iter, byte_order); // write point's x, y, z - writer_assigner

::run(point, iter, byte_order); + writer_assigner::run(point, iter, byte_order); return true; } }; - template + template struct linestring_writer { template - static bool write(L const& linestring, + static bool write(Linestring const& linestring, OutputIterator& iter, byte_order_type::enum_t byte_order) { @@ -134,20 +135,20 @@ namespace detail { namespace wkb value_writer::write(byte_order, iter, byte_order); // write geometry type - uint32_t type = geometry_type::get(); + uint32_t type = geometry_type::get(); value_writer::write(type, iter, byte_order); // write num points uint32_t num_points = boost::size(linestring); value_writer::write(num_points, iter, byte_order); - for(typename boost::range_iterator::type + for(typename boost::range_iterator::type point_iter = boost::begin(linestring); point_iter != boost::end(linestring); ++point_iter) { // write point's x, y, z - writer_assigner::type> + writer_assigner::type> ::run(*point_iter, iter, byte_order); } @@ -155,11 +156,11 @@ namespace detail { namespace wkb } }; - template + template struct polygon_writer { template - static bool write(P const& polygon, + static bool write(Polygon const& polygon, OutputIterator& iter, byte_order_type::enum_t byte_order) { @@ -167,7 +168,7 @@ namespace detail { namespace wkb value_writer::write(byte_order, iter, byte_order); // write geometry type - uint32_t type = geometry_type

::get(); + uint32_t type = geometry_type::get(); value_writer::write(type, iter, byte_order); // write num rings @@ -175,10 +176,10 @@ namespace detail { namespace wkb value_writer::write(num_rings, iter, byte_order); // write exterior ring - typedef typename geometry::ring_type

::type + typedef typename geometry::ring_type::type ring_type; - typename geometry::ring_return_type

::type + typename geometry::ring_return_type::type exterior_ring = geometry::exterior_ring(polygon); value_writer::write(geometry::num_points(exterior_ring), @@ -191,15 +192,15 @@ namespace detail { namespace wkb ++point_iter) { // write point's x, y, z - writer_assigner::type> + writer_assigner::type> ::run(*point_iter, iter, byte_order); } // write interor rings - typedef typename geometry::interior_type

::type + typedef typename geometry::interior_type::type interior_rings_type; - typename geometry::interior_return_type

::type + typename geometry::interior_return_type::type interior_rings = geometry::interior_rings(polygon); for(typename boost::range_iterator::type @@ -217,7 +218,7 @@ namespace detail { namespace wkb ++point_iter) { // write point's x, y, z - writer_assigner::type> + writer_assigner::type> ::run(*point_iter, iter, byte_order); } } diff --git a/include/boost/geometry/io/wkt/write.hpp b/include/boost/geometry/io/wkt/write.hpp index add40e255..f16c0cab7 100644 --- a/include/boost/geometry/io/wkt/write.hpp +++ b/include/boost/geometry/io/wkt/write.hpp @@ -1,9 +1,14 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// 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. -// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2015. +// Modifications copyright (c) 2015, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -28,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -150,7 +155,7 @@ struct wkt_range // optionally, close range to ring by repeating the first point if (force_closed && boost::size(range) > 1 - && geometry::disjoint(*begin, *(end - 1))) + && detail::disjoint::disjoint_point_point(*begin, *(end - 1))) { os << ","; stream_type::apply(os, *begin); diff --git a/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp b/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp index a233f1c4b..3d7d5bb46 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp @@ -1,6 +1,11 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2015. +// Modifications copyright (c) 2015, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, 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 @@ -62,8 +67,7 @@ private : DistanceType const& buffer_distance, RangeOut& range_out) const { - PromotedType const two = 2.0; - PromotedType const two_pi = two * geometry::math::pi(); + PromotedType const two_pi = geometry::math::two_pi(); std::size_t point_buffer_count = m_points_per_circle; diff --git a/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp b/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp index 9ec51cd1e..aa0b6de8b 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2015. +// Modifications copyright (c) 2015, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, 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) @@ -76,8 +81,7 @@ private : PromotedType const dx2 = get<0>(perp2) - get<0>(vertex); PromotedType const dy2 = get<1>(perp2) - get<1>(vertex); - PromotedType const two = 2.0; - PromotedType const two_pi = two * geometry::math::pi(); + PromotedType const two_pi = geometry::math::two_pi(); PromotedType const angle1 = atan2(dy1, dx1); PromotedType angle2 = atan2(dy2, dx2); diff --git a/include/boost/geometry/strategies/cartesian/buffer_point_circle.hpp b/include/boost/geometry/strategies/cartesian/buffer_point_circle.hpp index 86ebc43c9..f28985717 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_point_circle.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_point_circle.hpp @@ -85,8 +85,7 @@ public : promoted_type const buffer_distance = distance_strategy.apply(point, point, strategy::buffer::buffer_side_left); - promoted_type const two = 2.0; - promoted_type const two_pi = two * geometry::math::pi(); + promoted_type const two_pi = geometry::math::two_pi(); promoted_type const diff = two_pi / promoted_type(m_count); promoted_type a = 0; diff --git a/include/boost/geometry/strategies/spherical/area_huiller.hpp b/include/boost/geometry/strategies/spherical/area_huiller.hpp index e55fdb2b0..f4dafbea0 100644 --- a/include/boost/geometry/strategies/spherical/area_huiller.hpp +++ b/include/boost/geometry/strategies/spherical/area_huiller.hpp @@ -1,6 +1,11 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2015. +// Modifications copyright (c) 2015, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, 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 @@ -39,10 +44,9 @@ crossing polygons and for polygons with holes. However, some cases (especially 180 meridian cases) must still be checked. \note The version which sums angles, which is often seen, doesn't handle non-convex polygons correctly. -\note The version which sums longitudes, see -http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf, is simple -and works well in most cases but not in 180 meridian crossing cases. This probably -could be solved. +\note The version which sums longitudes, see http://hdl.handle.net/2014/40409, +is simple and works well in most cases but not in 180 meridian crossing cases. +This probably could be solved. \note This version is made for spherical equatorial coordinate systems @@ -113,8 +117,10 @@ public : calculation_type const half = 0.5; calculation_type const two = 2.0; calculation_type const four = 4.0; - calculation_type const two_pi = two * geometry::math::pi(); - calculation_type const half_pi = half * geometry::math::pi(); + calculation_type const two_pi + = geometry::math::two_pi(); + calculation_type const half_pi + = geometry::math::half_pi(); // Distance p1 p2 calculation_type a = state.distance_over_unit_sphere.apply(p1, p2); diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index 721f1682a..8361ee76f 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -354,7 +354,8 @@ struct modulo /*! -\brief Short construct to enable partial specialization for PI, currently not possible in Math. +\brief Short constructs to enable partial specialization for PI, 2*PI + and PI/2, currently not possible in Math. */ template struct define_pi @@ -366,6 +367,26 @@ struct define_pi } }; +template +struct define_two_pi +{ + static inline T apply() + { + // Default calls Boost.Math + return boost::math::constants::two_pi(); + } +}; + +template +struct define_half_pi +{ + static inline T apply() + { + // Default calls Boost.Math + return boost::math::constants::half_pi(); + } +}; + template struct relaxed_epsilon { @@ -407,6 +428,12 @@ struct round template inline T pi() { return detail::define_pi::apply(); } +template +inline T two_pi() { return detail::define_two_pi::apply(); } + +template +inline T half_pi() { return detail::define_half_pi::apply(); } + template inline T relaxed_epsilon(T const& factor) { diff --git a/test/algorithms/centroid.cpp b/test/algorithms/centroid.cpp index b5fb87a81..59b483f90 100644 --- a/test/algorithms/centroid.cpp +++ b/test/algorithms/centroid.cpp @@ -56,6 +56,15 @@ void test_polygon() // should (1.5 1) be returned? // if yes, then all other Polygons degenerated to Linestrings should be handled test_centroid("POLYGON((1 1,2 1,1 1,1 1))", 1.0, 1.0); + + // reported 2015.04.24 + // input INT, result FP + test_centroid + < + bg::model::polygon >, + typename bg::point_type::type, + typename bg::coordinate_type::type + >("POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))", 1.5, 1.5); } @@ -97,6 +106,23 @@ void test_2d() test_centroid >("POLYGON((1 2,3 4))", 2, 3); test_centroid

("POINT(3 3)", 3, 3); + + // INT -> FP + test_centroid + < + bg::model::ring >, + P, typename bg::coordinate_type

::type + >("POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))", 1.5, 1.5); + test_centroid + < + bg::model::linestring >, + P, typename bg::coordinate_type

::type + >("LINESTRING(1 1, 2 2)", 1.5, 1.5); + test_centroid + < + bg::model::box >, + P, typename bg::coordinate_type

::type + >("BOX(1 1, 2 2)", 1.5, 1.5); } diff --git a/test/algorithms/test_centroid.hpp b/test/algorithms/test_centroid.hpp index 14e0ceff1..1784f66f4 100644 --- a/test/algorithms/test_centroid.hpp +++ b/test/algorithms/test_centroid.hpp @@ -30,6 +30,7 @@ struct check_result static void apply(Point1 const& actual, Point2 const& expected) { check_result::apply(actual, expected); + BOOST_CHECK_CLOSE(bg::get(actual), bg::get(expected), 0.001); } }; @@ -48,9 +49,9 @@ void test_with_other_calculation_type(Geometry const& geometry, Point& c1) { typedef typename bg::point_type::type point_type; // Calculate it with user defined strategy - point_type c2; + Point c2; bg::centroid(geometry, c2, - bg::strategy::centroid::bashein_detmer()); + bg::strategy::centroid::bashein_detmer()); std::cout << typeid(CalculationType).name() << ": " << std::setprecision(20) << bg::get<0>(c2) << " " << bg::get<1>(c2) @@ -58,13 +59,13 @@ void test_with_other_calculation_type(Geometry const& geometry, Point& c1) << std::endl; } -template +template void test_centroid(std::string const& wkt, T const& d1, T const& d2, T const& d3 = T(), T const& d4 = T(), T const& d5 = T()) { Geometry geometry; bg::read_wkt(wkt, geometry); - typedef typename bg::point_type::type point_type; - point_type c1; + + Point c1; bg::centroid(geometry, c1); check_result::type::value>::apply(c1, boost::make_tuple(d1, d2, d3, d4, d5)); @@ -85,6 +86,12 @@ void test_centroid(std::string const& wkt, T const& d1, T const& d2, T const& d3 #endif } +template +void test_centroid(std::string const& wkt, T const& d1, T const& d2, T const& d3 = T(), T const& d4 = T(), T const& d5 = T()) +{ + test_centroid::type>(wkt, d1, d2, d3, d4, d5); +} + template void test_centroid_exception() {