You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
179 lines
4.4 KiB
179 lines
4.4 KiB
// Boost.Geometry (aka GGL, Generic Geometry Library) |
|
|
|
// Copyright (c) 2011-2011 Barend Gehrels, Amsterdam, the Netherlands. |
|
// Copyright (c) 2011-2011 Bruno Lalande, Paris, France. |
|
// Copyright (c) 2011-2011 Mateusz Loskot, London, UK. |
|
|
|
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library |
|
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. |
|
|
|
// 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) |
|
|
|
#ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP |
|
#define BOOST_GEOMETRY_UTIL_RATIONAL_HPP |
|
|
|
#include <boost/rational.hpp> |
|
#include <boost/numeric/conversion/bounds.hpp> |
|
|
|
#include <boost/geometry/util/coordinate_cast.hpp> |
|
#include <boost/geometry/util/select_most_precise.hpp> |
|
|
|
|
|
namespace boost{ namespace geometry |
|
{ |
|
|
|
|
|
// Specialize for Boost.Geometry's coordinate cast |
|
// (from string to coordinate type) |
|
namespace detail |
|
{ |
|
|
|
template <typename T> |
|
struct coordinate_cast<rational<T> > |
|
{ |
|
static inline void split_parts(std::string const& source, std::string::size_type p, |
|
T& before, T& after, bool& negate, std::string::size_type& len) |
|
{ |
|
std::string before_part = source.substr(0, p); |
|
std::string const after_part = source.substr(p + 1); |
|
|
|
negate = false; |
|
|
|
if (before_part.size() > 0 && before_part[0] == '-') |
|
{ |
|
negate = true; |
|
before_part.erase(0, 1); |
|
} |
|
before = atol(before_part.c_str()); |
|
after = atol(after_part.c_str()); |
|
len = after_part.length(); |
|
} |
|
|
|
|
|
static inline rational<T> apply(std::string const& source) |
|
{ |
|
T before, after; |
|
bool negate; |
|
std::string::size_type len; |
|
|
|
// Note: decimal comma is not (yet) supported, it does (and should) not |
|
// occur in a WKT, where points are comma separated. |
|
std::string::size_type p = source.find("."); |
|
if (p == std::string::npos) |
|
{ |
|
p = source.find("/"); |
|
if (p == std::string::npos) |
|
{ |
|
return rational<T>(atol(source.c_str())); |
|
} |
|
split_parts(source, p, before, after, negate, len); |
|
|
|
return negate |
|
? -rational<T>(before, after) |
|
: rational<T>(before, after) |
|
; |
|
|
|
} |
|
|
|
split_parts(source, p, before, after, negate, len); |
|
|
|
T den = 1; |
|
for (std::string::size_type i = 0; i < len; i++) |
|
{ |
|
den *= 10; |
|
} |
|
|
|
return negate |
|
? -rational<T>(before) - rational<T>(after, den) |
|
: rational<T>(before) + rational<T>(after, den) |
|
; |
|
} |
|
}; |
|
|
|
} // namespace detail |
|
|
|
// Specialize for Boost.Geometry's select_most_precise |
|
template <typename T1, typename T2> |
|
struct select_most_precise<boost::rational<T1>, boost::rational<T2> > |
|
{ |
|
typedef typename boost::rational |
|
< |
|
typename select_most_precise<T1, T2>::type |
|
> type; |
|
}; |
|
|
|
template <typename T> |
|
struct select_most_precise<boost::rational<T>, double> |
|
{ |
|
typedef typename boost::rational<T> type; |
|
}; |
|
|
|
|
|
}} // namespace boost::geometry |
|
|
|
|
|
// Specializes boost::rational to boost::numeric::bounds |
|
namespace boost { namespace numeric |
|
{ |
|
|
|
template<class T> |
|
struct bounds<rational<T> > |
|
{ |
|
static inline rational<T> lowest() |
|
{ |
|
return rational<T>(bounds<T>::lowest(), 1); |
|
} |
|
static inline rational<T> highest() |
|
{ |
|
return rational<T>(bounds<T>::highest(), 1); |
|
} |
|
}; |
|
|
|
}} // namespace boost::numeric |
|
|
|
|
|
// Support for boost::numeric_cast to int and to double (necessary for SVG-mapper) |
|
namespace boost { namespace numeric |
|
{ |
|
|
|
template |
|
< |
|
typename T, |
|
typename Traits, |
|
typename OverflowHandler, |
|
typename Float2IntRounder, |
|
typename RawConverter, |
|
typename UserRangeChecker |
|
> |
|
struct converter<int, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker> |
|
{ |
|
static inline int convert(rational<T> const& arg) |
|
{ |
|
return int(rational_cast<double>(arg)); |
|
} |
|
}; |
|
|
|
template |
|
< |
|
typename T, |
|
typename Traits, |
|
typename OverflowHandler, |
|
typename Float2IntRounder, |
|
typename RawConverter, |
|
typename UserRangeChecker |
|
> |
|
struct converter<double, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker> |
|
{ |
|
static inline double convert(rational<T> const& arg) |
|
{ |
|
return rational_cast<double>(arg); |
|
} |
|
}; |
|
|
|
|
|
}} |
|
|
|
|
|
#endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP
|
|
|