Merge branch 'develop' into feature/cluster

This commit is contained in:
Barend Gehrels 2016-02-03 11:12:33 +01:00
commit 34db67d51d
24 changed files with 522 additions and 193 deletions

View File

@ -3,7 +3,7 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Copyright Antony Polukhin 2014.
# Copyright Adam Wulkiewicz 2015.
# Copyright Adam Wulkiewicz 2015-2016.
general:
branches:
@ -38,16 +38,16 @@ dependencies:
- sudo apt-get update
# gcc, g++, gcov
- sudo apt-get install gcc-4.8 g++-4.8 build-essential
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 10
- sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-4.8 10
- sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 20
- sudo update-alternatives --set cc /usr/bin/gcc
- sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 20
- sudo update-alternatives --set c++ /usr/bin/g++
- sudo update-alternatives --config gcc
- sudo update-alternatives --config g++
- sudo apt-get install gcc-4.9 g++-4.9 build-essential
#- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 10
#- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 10
- sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-4.9 10
#- sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 20
#- sudo update-alternatives --set cc /usr/bin/gcc
#- sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 20
#- sudo update-alternatives --set c++ /usr/bin/g++
#- sudo update-alternatives --config gcc
#- sudo update-alternatives --config g++
- sudo update-alternatives --config gcov
# coveralls-lcov for lcov *.info to JSON conversion
@ -86,9 +86,9 @@ dependencies:
# download and install the latest lcov
# do not use the old one from sources
- wget http://downloads.sourceforge.net/ltp/lcov-1.11.tar.gz
- tar xvzf lcov-1.11.tar.gz
- cd lcov-1.11 && sudo make install
- wget http://downloads.sourceforge.net/ltp/lcov-1.12.tar.gz
- tar xvzf lcov-1.12.tar.gz
- cd lcov-1.12 && sudo make install
# create a direcotry for temporary coverage data
- if [ ! -d $COVERAGE_ROOT ]; then mkdir $COVERAGE_ROOT; fi

View File

@ -185,4 +185,5 @@ execfile("make_qbk.py")
os.chdir("..")
# Use either bjam or b2 or ../../../b2 (the last should be done on Release branch)
run_command("b2")
if "--release-build" not in sys.argv:
run_command("b2")

View File

@ -1,15 +1,16 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2015 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
Copyright (c) 2009-2015 Bruno Lalande, Paris, France.
Copyright (c) 2009-2015 Mateusz Loskot <mateusz@loskot.net>, London, UK
Copyright (c) 2011-2015 Adam Wulkiewicz
Copyright (c) 2009-2016 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
Copyright (c) 2009-2016 Bruno Lalande, Paris, France.
Copyright (c) 2009-2016 Mateusz Loskot <mateusz@loskot.net>, London, UK.
Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland.
This file was modified by Oracle on 2015.
Modifications copyright (c) 2015, Oracle and/or its affiliates.
This file was modified by Oracle on 2015, 2016.
Modifications copyright (c) 2015-2016, 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
@ -18,6 +19,20 @@
[section:release_notes Release Notes]
[/=================]
[heading Boost 1.61]
[/=================]
[*Solved tickets]
* [@https://svn.boost.org/trac/boost/ticket/11637 11637] Unused parameter warning.
* [@https://svn.boost.org/trac/boost/ticket/11917 11917] Andoyer distance strategy returns 0 for antipodal points (default geographic distance).
* [@https://svn.boost.org/trac/boost/ticket/11928 11928] Improvement of the accuracy of surveyor area strategy.
[*Bugfixes]
* Fix wrong result of intersects/disjoints for Segment and Box when Segment is parallel to Box's face.
[/=================]
[heading Boost 1.60]
[/=================]

View File

@ -277,7 +277,7 @@ inline void buffer(GeometryIn const& geometry_in,
rescale_policy_type rescale_policy
= boost::geometry::get_rescale_policy<rescale_policy_type>(box);
detail::buffer::buffer_inserter<polygon_type>(geometry_in, std::back_inserter(geometry_out),
detail::buffer::buffer_inserter<polygon_type>(geometry_in, range::back_inserter(geometry_out),
distance_strategy,
side_strategy,
join_strategy,

View File

@ -83,7 +83,7 @@ struct hull_to_geometry
geometry::point_order<OutputGeometry>::value,
geometry::closure<OutputGeometry>::value
>::apply(geometry,
std::back_inserter(
range::back_inserter(
// Handle linestring, ring and polygon the same:
detail::as_range
<

View File

@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2015 Oracle and/or its affiliates.
// Copyright (c) 2015-2016 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -49,23 +49,17 @@ struct andoyer_inverse
T2 const& lat2,
Spheroid const& spheroid)
{
CT const c0 = CT(0);
CT const c1 = CT(1);
CT const pi = math::pi<CT>();
result_type result;
// coordinates in radians
if ( math::equals(lon1, lon2)
&& math::equals(lat1, lat2) )
if ( math::equals(lon1, lon2) && math::equals(lat1, lat2) )
{
result.set(CT(0), CT(0));
return result;
}
CT const pi_half = math::pi<CT>() / CT(2);
if ( math::equals(math::abs(lat1), pi_half)
&& math::equals(math::abs(lat2), pi_half) )
{
result.set(CT(0), CT(0));
result.set(c0, c0);
return result;
}
@ -80,22 +74,16 @@ struct andoyer_inverse
// H,G,T = infinity if cos_d = 1 or cos_d = -1
// lat1 == +-90 && lat2 == +-90
// lat1 == lat2 && lon1 == lon2
CT const cos_d = sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos_dlon;
CT const d = acos(cos_d);
CT const sin_d = sin(d);
// just in case since above lat1 and lat2 is checked
// the check below is equal to cos_d == 1 || cos_d == -1 || d == 0
if ( math::equals(sin_d, CT(0)) )
{
result.set(CT(0), CT(0));
return result;
}
// if the function returned before this place
// and endpoints were on the poles +-90 deg
// in this case the azimuth could either be 0 or +-pi
CT cos_d = sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos_dlon;
// on some platforms cos_d may be outside valid range
if (cos_d < -c1)
cos_d = -c1;
else if (cos_d > c1)
cos_d = c1;
CT const d = acos(cos_d); // [0, pi]
CT const sin_d = sin(d); // [-1, 1]
CT const f = detail::flattening<CT>(spheroid);
if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
@ -103,11 +91,18 @@ struct andoyer_inverse
CT const K = math::sqr(sin_lat1-sin_lat2);
CT const L = math::sqr(sin_lat1+sin_lat2);
CT const three_sin_d = CT(3) * sin_d;
// H or G = infinity if cos_d = 1 or cos_d = -1
CT const H = (d+three_sin_d)/(CT(1)-cos_d);
CT const G = (d-three_sin_d)/(CT(1)+cos_d);
// for e.g. lat1=-90 && lat2=90 here we have G*L=INF*0
CT const one_minus_cos_d = c1 - cos_d;
CT const one_plus_cos_d = c1 + cos_d;
// cos_d = 1 or cos_d = -1 means that the points are antipodal
CT const H = math::equals(one_minus_cos_d, c0) ?
c0 :
(d + three_sin_d) / one_minus_cos_d;
CT const G = math::equals(one_plus_cos_d, c0) ?
c0 :
(d - three_sin_d) / one_plus_cos_d;
CT const dd = -(f/CT(4))*(H*K+G*L);
CT const a = get_radius<0>(spheroid);
@ -116,41 +111,88 @@ struct andoyer_inverse
}
else
{
result.distance = CT(0);
result.distance = c0;
}
if ( BOOST_GEOMETRY_CONDITION(EnableAzimuth) )
{
CT A = CT(0);
CT U = CT(0);
if ( ! math::equals(cos_lat2, CT(0)) )
// sin_d = 0 <=> antipodal points
if (math::equals(sin_d, c0))
{
CT const tan_lat2 = sin_lat2/cos_lat2;
CT const M = cos_lat1*tan_lat2-sin_lat1*cos_dlon;
A = atan2(sin_dlon, M);
CT const sin_2A = sin(CT(2)*A);
U = (f/CT(2))*math::sqr(cos_lat1)*sin_2A;
// T = inf
// dA = inf
// azimuth = -inf
if (lat1 <= lat2)
result.azimuth = c0;
else
result.azimuth = pi;
}
CT V = CT(0);
if ( ! math::equals(cos_lat1, CT(0)) )
else
{
CT const tan_lat1 = sin_lat1/cos_lat1;
CT const N = cos_lat2*tan_lat1-sin_lat2*cos_dlon;
CT const B = atan2(sin_dlon, N);
CT const sin_2B = sin(CT(2)*B);
V = (f/CT(2))*math::sqr(cos_lat2)*sin_2B;
CT const c2 = CT(2);
CT A = c0;
CT U = c0;
if ( ! math::equals(cos_lat2, c0) )
{
CT const tan_lat2 = sin_lat2/cos_lat2;
CT const M = cos_lat1*tan_lat2-sin_lat1*cos_dlon;
A = atan2(sin_dlon, M);
CT const sin_2A = sin(c2*A);
U = (f/ c2)*math::sqr(cos_lat1)*sin_2A;
}
CT V = c0;
if ( ! math::equals(cos_lat1, c0) )
{
CT const tan_lat1 = sin_lat1/cos_lat1;
CT const N = cos_lat2*tan_lat1-sin_lat2*cos_dlon;
CT const B = atan2(sin_dlon, N);
CT const sin_2B = sin(c2*B);
V = (f/ c2)*math::sqr(cos_lat2)*sin_2B;
}
CT const T = d / sin_d;
CT const dA = V*T-U;
result.azimuth = A - dA;
// even with sin_d == 0 checked above if the second point
// is somewhere in the antipodal area T may still be great
// therefore dA may be great and the resulting azimuth
// may be some more or less arbitrary angle
if (A >= c0) // A indicates Eastern hemisphere
{
if (dA >= c0) // A altered towards 0
{
if ((result.azimuth) < c0)
result.azimuth = c0;
}
else // dA < 0, A altered towards pi
{
if (result.azimuth > pi)
result.azimuth = pi;
}
}
else // A indicates Western hemisphere
{
if (dA <= c0) // A altered towards 0
{
if (result.azimuth > c0)
result.azimuth = c0;
}
else // dA > 0, A altered towards -pi
{
CT const minus_pi = -pi;
if ((result.azimuth) < minus_pi)
result.azimuth = minus_pi;
}
}
}
// infinity if sin_d = 0, so cos_d = 1 or cos_d = -1
CT const T = d / sin_d;
CT const dA = V*T-U;
result.azimuth = A - dA;
}
else
{
result.azimuth = CT(0);
result.azimuth = c0;
}
return result;

View File

@ -128,7 +128,9 @@ struct disjoint_segment_box_impl
&& t_min.first > ti_max)
||
(geometry::math::equals(t_max.second, 0)
&& t_max.first < ti_min) )
&& t_max.first < ti_min)
||
(math::sign(ti_min) * math::sign(ti_max) > 0) )
{
return true;
}
@ -197,6 +199,11 @@ struct disjoint_segment_box_impl
{
if ( geometry::math::equals(t_min.first, 0) ) { t_min.first = -1; }
if ( geometry::math::equals(t_max.first, 0) ) { t_max.first = 1; }
if (math::sign(t_min.first) * math::sign(t_max.first) > 0)
{
return true;
}
}
if ( t_min.first > diff || t_max.first < 0 )

View File

@ -54,7 +54,7 @@ struct intersection
<
Geometry1, Geometry2, OneOut,
overlay_intersection
>::apply(geometry1, geometry2, robust_policy, std::back_inserter(geometry_out), strategy);
>::apply(geometry1, geometry2, robust_policy, range::back_inserter(geometry_out), strategy);
return true;
}

View File

@ -159,7 +159,7 @@ inline void difference(Geometry1 const& geometry1,
detail::difference::difference_insert<geometry_out>(
geometry1, geometry2, robust_policy,
std::back_inserter(output_collection));
range::back_inserter(output_collection));
}

View File

@ -139,7 +139,7 @@ struct range_remove_spikes
// Copy output
geometry::clear(range);
std::copy(cleaned.begin(), cleaned.end(), std::back_inserter(range));
std::copy(cleaned.begin(), cleaned.end(), range::back_inserter(range));
}
};

View File

@ -77,7 +77,7 @@ struct simplify_copy
{
std::copy
(
boost::begin(range), boost::end(range), std::back_inserter(out)
boost::begin(range), boost::end(range), geometry::range::back_inserter(out)
);
}
};
@ -113,7 +113,7 @@ struct simplify_range
{
simplify_range_insert::apply
(
range, std::back_inserter(out), max_distance, strategy
range, geometry::range::back_inserter(out), max_distance, strategy
);
}
}

View File

@ -332,7 +332,7 @@ inline void sym_difference(Geometry1 const& geometry1,
detail::sym_difference::sym_difference_insert<geometry_out>(
geometry1, geometry2, robust_policy,
std::back_inserter(output_collection));
range::back_inserter(output_collection));
}

View File

@ -162,7 +162,7 @@ struct transform_polygon
geometry::clear(poly2);
if (!transform_range_out<point2_type>(geometry::exterior_ring(poly1),
std::back_inserter(geometry::exterior_ring(poly2)), strategy))
range::back_inserter(geometry::exterior_ring(poly2)), strategy))
{
return false;
}
@ -189,7 +189,7 @@ struct transform_polygon
for ( ; it1 != boost::end(rings1); ++it1, ++it2)
{
if ( ! transform_range_out<point2_type>(*it1,
std::back_inserter(*it2),
range::back_inserter(*it2),
strategy) )
{
return false;
@ -228,7 +228,7 @@ struct transform_range
// Should NOT be done here!
// geometry::clear(range2);
return transform_range_out<point_type>(range1,
std::back_inserter(range2), strategy);
range::back_inserter(range2), strategy);
}
};

View File

@ -271,7 +271,7 @@ inline void union_(Geometry1 const& geometry1,
concept::check<geometry_out>();
detail::union_::union_insert<geometry_out>(geometry1, geometry2,
std::back_inserter(output_collection));
range::back_inserter(output_collection));
}

View File

@ -55,7 +55,7 @@ template <>
struct modify<false>
{
template <typename Ring, typename Point>
static inline void push_back(Ring& ring, Point const& point)
static inline void push_back(Ring& /*ring*/, Point const& /*point*/)
{
}

View File

@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2016.
// Modifications copyright (c) 2016, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, 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.
@ -17,7 +22,7 @@
#include <boost/mpl/if.hpp>
#include <boost/geometry/arithmetic/determinant.hpp>
//#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
@ -98,8 +103,20 @@ public :
PointOfSegment const& p2,
summation& state)
{
// Below formulas are equivalent, however the two lower ones
// suffer less from accuracy loss for great values of coordinates.
// See: https://svn.boost.org/trac/boost/ticket/11928
// SUM += x2 * y1 - x1 * y2;
state.sum += detail::determinant<return_type>(p2, p1);
// state.sum += detail::determinant<return_type>(p2, p1);
// SUM += (x2 - x1) * (y2 + y1)
//state.sum += (return_type(get<0>(p2)) - return_type(get<0>(p1)))
// * (return_type(get<1>(p2)) + return_type(get<1>(p1)));
// SUM += (x1 + x2) * (y1 - y2)
state.sum += (return_type(get<0>(p1)) + return_type(get<0>(p2)))
* (return_type(get<1>(p1)) - return_type(get<1>(p2)));
}
static inline return_type result(summation const& state)

View File

@ -1,9 +1,9 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2016.
// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -20,6 +20,7 @@
#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/core/srs.hpp>
#include <boost/geometry/algorithms/detail/andoyer_inverse.hpp>
#include <boost/geometry/algorithms/detail/flattening.hpp>
#include <boost/geometry/strategies/distance.hpp>
@ -50,6 +51,8 @@ are about the same as Vincenty. In my (Barend's) testcases the results didn't di
\see http://www.codeguru.com/Cpp/Cpp/algorithms/article.php/c5115 (implementation)
\see http://futureboy.homeip.net/frinksamp/navigation.frink (implementation)
\see http://www.voidware.com/earthdist.htm (implementation)
\see http://www.dtic.mil/docs/citations/AD0627893
\see http://www.dtic.mil/docs/citations/AD703541
*/
template
<
@ -82,16 +85,17 @@ public :
: m_spheroid(spheroid)
{}
template <typename Point1, typename Point2>
inline typename calculation_type<Point1, Point2>::type
apply(Point1 const& point1, Point2 const& point2) const
{
return calc<typename calculation_type<Point1, Point2>::type>
(
get_as_radian<0>(point1), get_as_radian<1>(point1),
get_as_radian<0>(point2), get_as_radian<1>(point2)
);
return geometry::detail::andoyer_inverse
<
typename calculation_type<Point1, Point2>::type,
true, false
>::apply(get_as_radian<0>(point1), get_as_radian<1>(point1),
get_as_radian<0>(point2), get_as_radian<1>(point2),
m_spheroid).distance;
}
inline Spheroid const& model() const
@ -100,55 +104,6 @@ public :
}
private :
template <typename CT, typename T>
inline CT calc(T const& lon1,
T const& lat1,
T const& lon2,
T const& lat2) const
{
CT const G = (lat1 - lat2) / 2.0;
CT const lambda = (lon1 - lon2) / 2.0;
if (geometry::math::equals(lambda, 0.0)
&& geometry::math::equals(G, 0.0))
{
return 0.0;
}
CT const F = (lat1 + lat2) / 2.0;
CT const sinG2 = math::sqr(sin(G));
CT const cosG2 = math::sqr(cos(G));
CT const sinF2 = math::sqr(sin(F));
CT const cosF2 = math::sqr(cos(F));
CT const sinL2 = math::sqr(sin(lambda));
CT const cosL2 = math::sqr(cos(lambda));
CT const S = sinG2 * cosL2 + cosF2 * sinL2;
CT const C = cosG2 * cosL2 + sinF2 * sinL2;
CT const c0 = 0;
CT const c1 = 1;
CT const c2 = 2;
CT const c3 = 3;
if (geometry::math::equals(S, c0) || geometry::math::equals(C, c0))
{
return c0;
}
CT const radius_a = CT(get_radius<0>(m_spheroid));
CT const flattening = geometry::detail::flattening<CT>(m_spheroid);
CT const omega = atan(math::sqrt(S / C));
CT const r3 = c3 * math::sqrt(S * C) / omega; // not sure if this is r or greek nu
CT const D = c2 * omega * radius_a;
CT const H1 = (r3 - c1) / (c2 * C);
CT const H2 = (r3 + c1) / (c2 * S);
return D * (c1 + flattening * (H1 * sinF2 * cosG2 - H2 * cosF2 * sinG2) );
}
Spheroid m_spheroid;
};

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015.
// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2015, 2016.
// Modifications copyright (c) 2013-2016 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -15,6 +15,7 @@
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
#include <algorithm>
#include <iterator>
#include <boost/concept_check.hpp>
#include <boost/config.hpp>
@ -362,6 +363,50 @@ erase(Range & rng,
return erase(rng, first, last);
}
// back_inserter
template <class Container>
class back_insert_iterator
: public std::iterator<std::output_iterator_tag, void, void, void, void>
{
public:
typedef Container container_type;
explicit back_insert_iterator(Container & c)
: container(boost::addressof(c))
{}
back_insert_iterator & operator=(typename Container::value_type const& value)
{
range::push_back(*container, value);
return *this;
}
back_insert_iterator & operator* ()
{
return *this;
}
back_insert_iterator & operator++ ()
{
return *this;
}
back_insert_iterator operator++(int)
{
return *this;
}
private:
Container * container;
};
template <typename Range>
inline back_insert_iterator<Range> back_inserter(Range & rng)
{
return back_insert_iterator<Range>(rng);
}
}}} // namespace boost::geometry::range
#endif // BOOST_GEOMETRY_UTIL_RANGE_HPP

View File

@ -5,8 +5,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -61,7 +61,24 @@ void test_all()
// ccw
test_geometry<bg::model::polygon<P, false> >
("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", -15.0);
("POLYGON((0 0,0 7,4 2,2 0,0 0), (1 1,2 1,2 2,1 2,1 1))", -15.0);
test_geometry<bg::model::polygon<P, false> >
("POLYGON((1 0,0 1,-1 0,0 -1,1 0))", 2);
typedef typename bg::coordinate_type<P>::type coord_type;
if (BOOST_GEOMETRY_CONDITION((boost::is_same<coord_type, double>::value)))
{
test_geometry<bg::model::polygon<P, false, false> >
("POLYGON((100000001 100000000, 100000000 100000001, \
99999999 100000000, 100000000 99999999))", 2);
}
else if (BOOST_GEOMETRY_CONDITION((boost::is_same<coord_type, float>::value)))
{
test_geometry<bg::model::polygon<P, false, false> >
("POLYGON((100001 100000, 100000 100001, \
99999 100000, 100000 99999))", 2);
}
}
template <typename Point>

View File

@ -83,9 +83,16 @@ void test_additional()
// http://stackoverflow.com/questions/32457920/boost-rtree-of-box-gives-wrong-intersection-with-segment
// http://lists.boost.org/geometry/2015/09/3476.php
// For now disabled by default even though it works properly on MSVC14
// it's probable that the result depends on the compiler
#ifdef BOOST_GEOMETRY_ENABLE_FAILING_TESTS
typedef bg::model::point<typename bg::coordinate_type<P>::type, 3, bg::cs::cartesian> point3d_t;
test_geometry<bg::model::segment<point3d_t>, bg::model::box<point3d_t> >(
"SEGMENT(2 1 0,2 1 10)",
"BOX(0 0 0,10 0 10)",
false);
test_geometry<bg::model::segment<point3d_t>, bg::model::box<point3d_t> >(
"SEGMENT(2 1 0,2 1 10)",
"BOX(0 -5 0,10 0 10)",
false);
// and derived from the cases above
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(12 0,20 10)",
"BOX(0 0,10 10)",
@ -98,12 +105,46 @@ void test_additional()
"SEGMENT(2 0,18 8)",
"BOX(0 0,10 10)",
true);
typedef bg::model::point<typename bg::coordinate_type<P>::type, 3, bg::cs::cartesian> point3d_t;
test_geometry<bg::model::segment<point3d_t>, bg::model::box<point3d_t> >(
"SEGMENT(2 1 0,2 1 10)",
"BOX(0 0 0,10 0 10)",
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(1 0,1 10)",
"BOX(0 0,0 10)",
false);
#endif
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(-1 0,-1 10)",
"BOX(0 0,0 10)",
false);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(2 1,2 1)",
"BOX(0 0,10 0)",
false);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(2 3,2 3)",
"BOX(0 0,10 0)",
false);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(0 0,10 0)",
"BOX(0 0,10 0)",
true);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(10 0,10 0)",
"BOX(0 0,10 0)",
true);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(1 0,1 0)",
"BOX(0 0,10 0)",
true);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(0 0,0 10)",
"BOX(0 0,0 10)",
true);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(0 10,0 10)",
"BOX(0 0,0 10)",
true);
test_geometry<bg::model::segment<P>, bg::model::box<P> >(
"SEGMENT(0 1,0 1)",
"BOX(0 0,0 10)",
true);
}

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) Point concept unit tests
//
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2016 Bruno Lalande, Paris, France.
// Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2016 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)
@ -9,8 +10,6 @@
#ifndef GEOMETRY_TEST_POINT_CONCEPT_FUNCTION_REQUIRING_A_POINT_HPP
#define GEOMETRY_TEST_POINT_CONCEPT_FUNCTION_REQUIRING_A_POINT_HPP
#include <boost/concept/requires.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
namespace bg = boost::geometry;
@ -18,13 +17,11 @@ namespace bg = boost::geometry;
namespace test
{
template <typename P, typename C>
inline BOOST_CONCEPT_REQUIRES(
((bg::concept::Point<P>))
((bg::concept::ConstPoint<C>)),
(void))
function_requiring_a_point(P& p1, const C& p2)
inline void function_requiring_a_point(P& p1, const C& p2)
{
BOOST_CONCEPT_ASSERT((bg::concept::Point<P>));
BOOST_CONCEPT_ASSERT((bg::concept::ConstPoint<C>));
bg::set<0>(p1, bg::get<0>(p2));
}
}

View File

@ -1,9 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2016, 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@ -27,6 +28,7 @@
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/optional.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/geometry/core/point_type.hpp>
@ -96,6 +98,28 @@ inline Geometry from_wkt(std::string const& wkt)
}
// this function is implemented because std::max_element() requires ForwardIterator
// but bg::point_iterator<> is InputIterator since it returns non-true reference
template <typename InputIt, typename Pred>
inline boost::optional<typename std::iterator_traits<InputIt>::value_type>
max_value(InputIt first, InputIt last, Pred pred)
{
typedef typename std::iterator_traits<InputIt>::value_type value_type;
if (first != last)
{
value_type found = *first++;
for (; first != last; )
{
value_type current = *first++;
if (pred(current, found))
found = current;
}
return found;
}
return boost::none;
}
template <typename Iterator>
inline std::ostream& print_point_range(std::ostream& os,
Iterator first,
@ -460,13 +484,12 @@ struct test_point_iterator_of_geometry
>::value_type point;
if (const_begin != const_end)
{
const_point_iterator pit_max = std::max_element(const_begin,
const_end,
bg::less<point>());
BOOST_CHECK(pit_max != const_end); // to avoid warnings
boost::optional<point>
pt_max = max_value(const_begin, const_end, bg::less<point>());
BOOST_CHECK(bool(pt_max)); // to avoid warnings
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << "max point: " << bg::dsv(*pit_max) << std::endl;
std::cout << "max point: " << bg::dsv(*pt_max) << std::endl;
#endif
}
#ifdef BOOST_GEOMETRY_TEST_DEBUG

View File

@ -1,12 +1,12 @@
// 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.
// Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2016 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2016 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2016.
// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -37,6 +37,33 @@
double make_deg(double deg, double min, double sec)
{
return deg + min / 60.0 + sec / 3600.0;
}
double to_rad(double deg)
{
return bg::math::pi<double>() * deg / 180.0;
}
double to_deg(double rad)
{
return 180.0 * rad / bg::math::pi<double>();
}
double normlized_deg(double deg)
{
double const pi = bg::math::pi<double>();
if (deg > 180)
return deg - 360;
else if (deg < -180)
return deg + 360;
else
return deg;
}
template <typename P1, typename P2>
void test_distance(double lon1, double lat1, double lon2, double lat2, double expected_km)
{
@ -49,6 +76,7 @@ void test_distance(double lon1, double lat1, double lon2, double lat2, double ex
typedef bg::srs::spheroid<rtype> stype;
typedef bg::strategy::distance::andoyer<stype> andoyer_type;
typedef bg::detail::andoyer_inverse<rtype, true, false> andoyer_inverse_type;
BOOST_CONCEPT_ASSERT
(
@ -65,10 +93,73 @@ void test_distance(double lon1, double lat1, double lon2, double lat2, double ex
bg::assign_values(p1, lon1, lat1);
bg::assign_values(p2, lon2, lat2);
BOOST_CHECK_CLOSE(andoyer.apply(p1, p2), return_type(1000.0 * expected_km), 0.001);
BOOST_CHECK_CLOSE(bg::distance(p1, p2, andoyer), return_type(1000.0 * expected_km), 0.001);
return_type d_strategy = andoyer.apply(p1, p2);
return_type d_function = bg::distance(p1, p2, andoyer);
return_type d_formula = andoyer_inverse_type::apply(to_rad(lon1), to_rad(lat1), to_rad(lon2), to_rad(lat2), stype()).distance;
BOOST_CHECK_CLOSE(d_strategy / 1000.0, expected_km, 0.001);
BOOST_CHECK_CLOSE(d_function / 1000.0, expected_km, 0.001);
BOOST_CHECK_CLOSE(d_formula / 1000.0, expected_km, 0.001);
}
template <typename PS, typename P>
void test_azimuth(double lon1, double lat1,
double lon2, double lat2,
double expected_azimuth_deg)
{
// Set radius type, but for integer coordinates we want to have floating point radius type
typedef typename bg::promote_floating_point
<
typename bg::coordinate_type<PS>::type
>::type rtype;
typedef bg::srs::spheroid<rtype> stype;
typedef bg::detail::andoyer_inverse<rtype, false, true> andoyer_inverse_type;
rtype a_formula = andoyer_inverse_type::apply(to_rad(lon1), to_rad(lat1), to_rad(lon2), to_rad(lat2), stype()).azimuth;
rtype azimuth_deg = to_deg(a_formula);
if (bg::math::equals(azimuth_deg, -180.0))
azimuth_deg = 180.0;
if (bg::math::equals(expected_azimuth_deg, -180.0))
expected_azimuth_deg = 180.0;
if (bg::math::equals(expected_azimuth_deg, 0.0))
{
BOOST_CHECK(bg::math::equals(azimuth_deg, expected_azimuth_deg));
}
else
{
BOOST_CHECK_CLOSE(azimuth_deg, expected_azimuth_deg, 0.001);
}
}
template <typename P1, typename P2>
void test_distazi(double lon1, double lat1, double lon2, double lat2, double expected_km, double expected_azimuth_deg)
{
test_distance<P1, P2>(lon1, lat1, lon2, lat2, expected_km);
test_azimuth<P1, P2>(lon1, lat1, lon2, lat2, expected_azimuth_deg);
}
// requires SW->NE
template <typename P1, typename P2>
void test_distazi_symm(double lon1, double lat1, double lon2, double lat2, double expected_km, double expected_azimuth_deg)
{
test_distazi<P1, P2>(lon1, lat1, lon2, lat2, expected_km, expected_azimuth_deg);
test_distazi<P1, P2>(-lon1, lat1, -lon2, lat2, expected_km, -expected_azimuth_deg);
test_distazi<P1, P2>(lon1, -lat1, lon2, -lat2, expected_km, 180 - expected_azimuth_deg);
test_distazi<P1, P2>(-lon1, -lat1, -lon2, -lat2, expected_km, -180 + expected_azimuth_deg);
}
template <typename P1, typename P2>
void test_distazi_symmNS(double lon1, double lat1, double lon2, double lat2, double expected_km, double expected_azimuth_deg)
{
test_distazi<P1, P2>(lon1, lat1, lon2, lat2, expected_km, expected_azimuth_deg);
test_distazi<P1, P2>(lon1, -lat1, lon2, -lat2, expected_km, 180 - expected_azimuth_deg);
}
template <typename PS, typename P>
void test_side(double lon1, double lat1,
double lon2, double lat2,
@ -102,9 +193,80 @@ void test_side(double lon1, double lat1,
template <typename P1, typename P2>
void test_all()
{
test_distance<P1, P2>(0, 90, 1, 80, 1116.814237); // polar
test_distance<P1, P2>(4, 52, 4, 52, 0.0); // no point difference
test_distance<P1, P2>(4, 52, 3, 40, 1336.039890); // normal case
// polar
test_distazi<P1, P2>(0, 90, 1, 80,
1116.814237, 179);
// no point difference
test_distazi<P1, P2>(4, 52, 4, 52,
0.0, 0.0);
// normal cases
test_distazi<P1, P2>(4, 52, 3, 40,
1336.039890, -176.3086);
test_distazi<P1, P2>(3, 52, 4, 40,
1336.039890, 176.3086);
test_distazi<P1, P2>(make_deg(17, 19, 43.28),
make_deg(40, 30, 31.151),
18, 40,
80.323245,
make_deg(134, 27, 50.05));
// antipodal
// ok? in those cases shorter path would pass through a pole
// but 90 or -90 would be consistent with distance?
test_distazi<P1, P2>(0, 0, 180, 0, 20037.5, 0.0);
test_distazi<P1, P2>(0, 0, -180, 0, 20037.5, 0.0);
test_distazi<P1, P2>(-90, 0, 90, 0, 20037.5, 0.0);
test_distazi<P1, P2>(90, 0, -90, 0, 20037.5, 0.0);
// 0, 45, 90 ...
for (int i = 0 ; i < 360 ; i += 45)
{
// 0 45 90 ...
double l = normlized_deg(i);
// -1 44 89 ...
double l1 = normlized_deg(i - 1);
// 1 46 91 ...
double l2 = normlized_deg(i + 1);
// near equator
test_distazi_symm<P1, P2>(l1, -1, l2, 1, 313.7956, 45.1964);
// near poles
test_distazi_symmNS<P1, P2>(l, -89.5, l, 89.5, 19892.2, 0.0);
test_distazi_symmNS<P1, P2>(l, -89.6, l, 89.6, 19914.6, 0.0);
test_distazi_symmNS<P1, P2>(l, -89.7, l, 89.7, 19936.9, 0.0);
test_distazi_symmNS<P1, P2>(l, -89.8, l, 89.8, 19959.2, 0.0);
test_distazi_symmNS<P1, P2>(l, -89.9, l, 89.9, 19981.6, 0.0);
test_distazi_symmNS<P1, P2>(l, -89.99, l, 89.99, 20001.7, 0.0);
test_distazi_symmNS<P1, P2>(l, -89.999, l, 89.999, 20003.7, 0.0);
// antipodal
test_distazi_symmNS<P1, P2>(l, -90, l, 90, 20003.9, 0.0);
test_distazi_symm<P1, P2>(normlized_deg(l-10.0), -10.0, normlized_deg(l+135), 45, 14892.1, 34.1802);
test_distazi_symm<P1, P2>(normlized_deg(l-30.0), -30.0, normlized_deg(l+135), 45, 17890.7, 33.7002);
test_distazi_symm<P1, P2>(normlized_deg(l-40.0), -40.0, normlized_deg(l+135), 45, 19319.7, 33.4801);
test_distazi_symm<P1, P2>(normlized_deg(l-41.0), -41.0, normlized_deg(l+135), 45, 19459.1, 33.2408);
test_distazi_symm<P1, P2>(normlized_deg(l-42.0), -42.0, normlized_deg(l+135), 45, 19597.8, 32.7844);
test_distazi_symm<P1, P2>(normlized_deg(l-43.0), -43.0, normlized_deg(l+135), 45, 19735.8, 31.7784);
test_distazi_symm<P1, P2>(normlized_deg(l-44.0), -44.0, normlized_deg(l+135), 45, 19873.0, 28.5588);
test_distazi_symm<P1, P2>(normlized_deg(l-44.1), -44.1, normlized_deg(l+135), 45, 19886.7, 27.8304);
test_distazi_symm<P1, P2>(normlized_deg(l-44.2), -44.2, normlized_deg(l+135), 45, 19900.4, 26.9173);
test_distazi_symm<P1, P2>(normlized_deg(l-44.3), -44.3, normlized_deg(l+135), 45, 19914.1, 25.7401);
test_distazi_symm<P1, P2>(normlized_deg(l-44.4), -44.4, normlized_deg(l+135), 45, 19927.7, 24.1668);
test_distazi_symm<P1, P2>(normlized_deg(l-44.5), -44.5, normlized_deg(l+135), 45, 19941.4, 21.9599);
test_distazi_symm<P1, P2>(normlized_deg(l-44.6), -44.6, normlized_deg(l+135), 45, 19955.0, 18.6438);
test_distazi_symm<P1, P2>(normlized_deg(l-44.7), -44.7, normlized_deg(l+135), 45, 19968.6, 13.1096);
test_distazi_symm<P1, P2>(normlized_deg(l-44.8), -44.8, normlized_deg(l+135), 45, 19982.3, 2.0300);
// nearly antipodal
test_distazi_symm<P1, P2>(normlized_deg(l-44.9), -44.9, normlized_deg(l+135), 45, 19995.9, 0.0);
test_distazi_symm<P1, P2>(normlized_deg(l-44.95), -44.95, normlized_deg(l+135), 45, 20002.7, 0.0);
test_distazi_symm<P1, P2>(normlized_deg(l-44.99), -44.99, normlized_deg(l+135), 45, 20008.1, 0.0);
test_distazi_symm<P1, P2>(normlized_deg(l-44.999), -44.999, normlized_deg(l+135), 45, 20009.4, 0.0);
// antipodal
test_distazi_symm<P1, P2>(normlized_deg(l-45), -45, normlized_deg(l+135), 45, 20020.7, 0.0);
}
/* SQL Server gives:
1116.82586908528, 0, 1336.02721932545
@ -115,6 +277,7 @@ union SELECT 0.001 * geography::STGeomFromText('POINT(4 52)', 4326).STDistance(g
union SELECT 0.001 * geography::STGeomFromText('POINT(4 52)', 4326).STDistance(geography::STGeomFromText('POINT(3 40)', 4326))
*/
test_side<P1, P2>(0, 0, 0, 1, 0, 2, 0);
test_side<P1, P2>(0, 0, 0, 1, 0, -2, 0);
test_side<P1, P2>(10, 0, 10, 1, 10, 2, 0);
@ -139,8 +302,8 @@ int test_main(int, char* [])
{
//test_all<float[2]>();
//test_all<double[2]>();
test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
//test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
//test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
#if defined(HAVE_TTMATH)

View File

@ -108,6 +108,12 @@ void test_all()
BOOST_CHECK(bgr::at(v, i) == i);
}
{
std::vector<T> w;
std::copy(v.begin(), v.end(), bgr::back_inserter(w));
BOOST_CHECK(v.size() == w.size() && std::equal(v.begin(), v.end(), w.begin()));
}
BOOST_CHECK(bgr::front(v) == 0);
BOOST_CHECK(bgr::back(v) == 19);