Boost logo

Geometry :

Subject: Re: [geometry] Compatibility with Boost.Units
From: Jeremy Murphy (jeremy.william.murphy_at_[hidden])
Date: 2015-10-09 02:23:02


On 9 October 2015 at 06:24, Adam Wulkiewicz <adam.wulkiewicz_at_[hidden]>
wrote:

> Hi Jeremy,
>
> Jeremy Murphy wrote:
>
>> Hi,
>>
>> I recently tried using Boost.Units' SI length as the coordinate type for
>> geometry and, well, it didn't work: specifically, the BG algorithms didn't
>> compile. I'm not that familiar with Boost.Units so maybe I'm using the
>> wrong unit.
>> Should it be possible to do this (use an SI unit as the coordinate type)?
>>
>
> Boost.Geometry wasn't tested with Boost.Units' coordinates so it's
> probable that they aren't supported. Using length units as cartesian
> coordinates seems to be ok. Though I can imagine that something may easily
> go wrong in places where e.g. coordinate type is used to store the result
> of multiplication of coordinates, so basically in the whole library. AFAIU
> the unit of a product should be squared unit of coordinate. I'm not
> familiar with Boost.Unit neither but I guess that Boost.Unit requires to
> use a different type of it. Is that correct? If that's true, supporting
> Boost.Unit may be out of our reach, at while Boost.Geometry supports C++03.

 Yeah, multiplication and division of a unit results in a different unit
and thus a different type.

> What errors are reported exactly?
>

I have contracted the boost::units::quantity template parameters for ease
of reading as I assume their omission doesn't actually detract from
understanding.

(1) construction:

.../boost/geometry/util/normalize_spheroidal_coordinates.hpp:76:16: error:
no matching conversion for functional-style cast from 'double' to
'boost::units::quantity<...>'

which is for code like:

    template <typename CoordinateType>
    struct constants_on_spheroid<CoordinateType, degree>
    {
        static inline CoordinateType period()
        {
            return CoordinateType(360.0); // Construction.
        }

Construction requires specifying units, e.g.: (360.0 * degree::plane_angle)
or (2.5 * si::metres).

(2) conversion:

.../boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp:63:12: error:
no viable conversion from 'typename fp_coordinate_type<point<degree,
quantity<...>, cs::geographic, 2> >::type' (aka
'boost::units::quantity<...>') to 'double'

on:

    template <typename Prj, typename LL, typename XY, typename P>
    inline void pj_fwd(Prj const& prj, P const& par, LL const& ll, XY& xy)
    {
        using namespace detail;

        double lp_lon = geometry::get_as_radian<0>(ll); // Conversion.

There is no implicit conversion (except from dimensionless units) so
usually this would require calling .value() to extract the raw value.

(3) mixing double with quantity in expressions:

.../boost/geometry/extensions/gis/projections/impl/pj_inv.hpp:63:56: error:
invalid operands to binary expression ('typename
multiply_typeof_helper<quantity<...>, double>::type' (aka
'quantity<unit_type, value_type>') and 'double')

(4) no matching function call, presumably because of no implicit conversion:

.../boost/geometry/extensions/gis/projections/impl/pj_inv.hpp:73:5: error:
no matching function for call to 'set_from_radian'

(5) other

.../boost/lexical_cast/detail/converter_lexical.hpp:243:13: error:
static_assert failed "Target type is neither std::istream`able nor
std::wistream`able"

on:

            BOOST_STATIC_ASSERT_MSG((result_t::value ||
boost::has_right_shift<std::basic_istream<wchar_t>, T >::value),
                "Target type is neither std::istream`able nor
std::wistream`able");

even though I included <boost/units/io.hpp>

So apart from (5) I think the errors are all quite predictable failures to
implicitly construct or convert. Would it be reasonable to try to include
support for Boost.Units explicitly in Boost.Geometry? I'm guessing some
template metaprogramming could generalize construction and conversion but
would it be worth the effort?

I'm thinking, off the top of my head, a construct function or class
template that constructs everything except quantities as per usual but is
specialized for Boost.Unit quantities and constructs them appropriately.

Cheers.

Jeremy



Geometry list run by mateusz at loskot.net