123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- // 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.
- // 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)
- //
- // Example: Custom coordinate system example, using transform
- #include <iostream>
- #include <boost/geometry/geometry.hpp>
- // See also c10_custom_cs_example
- // 1: declare, for example two cartesian coordinate systems
- struct cart {};
- struct cart_shifted5 {};
- // 2: register to which coordinate system family they belong
- namespace boost { namespace geometry { namespace traits
- {
- template<> struct cs_tag<cart> { typedef cartesian_tag type; };
- template<> struct cs_tag<cart_shifted5> { typedef cartesian_tag type; };
- }}} // namespaces
- // 3: sample implementation of a shift
- // to convert coordinate system "cart" to "cart_shirted5"
- struct shift
- {
- template <typename P1, typename P2>
- inline bool apply(P1 const& p1, P2& p2) const
- {
- namespace bg = boost::geometry;
- bg::set<0>(p2, bg::get<0>(p1) + 5);
- bg::set<1>(p2, bg::get<1>(p1));
- return true;
- }
- };
- // 4: register the default strategy to transform any cart point to any cart_shifted5 point
- namespace boost { namespace geometry { namespace strategy { namespace transform { namespace services
- {
- template <typename P1, typename P2>
- struct default_strategy<cartesian_tag, cartesian_tag, cart, cart_shifted5, 2, 2, P1, P2>
- {
- typedef shift type;
- };
- }}}}} // namespaces
- // 5: implement a distance strategy between the two different ones
- struct shift_and_calc_distance
- {
- template <typename P1, typename P2>
- inline double apply(P1 const& p1, P2 const& p2) const
- {
- P2 p1_shifted;
- boost::geometry::transform(p1, p1_shifted);
- return boost::geometry::distance(p1_shifted, p2);
- }
- };
- // 6: Define point types using this explicitly
- typedef boost::geometry::model::point<double, 2, cart> point1;
- typedef boost::geometry::model::point<double, 2, cart_shifted5> point2;
- // 7: register the distance strategy
- namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
- {
- template <>
- struct tag<shift_and_calc_distance>
- {
- typedef strategy_tag_distance_point_point type;
- };
- template <typename P1, typename P2>
- struct return_type<shift_and_calc_distance, P1, P2>
- {
- typedef double type;
- };
- template <>
- struct default_strategy<point_tag, point_tag, point1, point2, cartesian_tag, cartesian_tag>
- {
- typedef shift_and_calc_distance type;
- };
- }}}}}
- int main()
- {
- point1 p1_a(0, 0), p1_b(5, 5);
- point2 p2_a(2, 2), p2_b(6, 6);
- // Distances run for points on the same coordinate system.
- // This is possible by default because they are cartesian coordinate systems.
- double d1 = boost::geometry::distance(p1_a, p1_b);
- double d2 = boost::geometry::distance(p2_a, p2_b);
- std::cout << d1 << " " << d2 << std::endl;
- // Transform from a to b:
- boost::geometry::model::point<double, 2, cart_shifted5> p1_shifted;
- boost::geometry::transform(p1_a, p1_shifted);
- // Of course this can be calculated now, same CS
- double d3 = boost::geometry::distance(p1_shifted, p2_a);
- // Calculate distance between them. Note that inside distance the
- // transformation is called.
- double d4 = boost::geometry::distance(p1_a, p2_a);
- // The result should be the same.
- std::cout << d3 << " " << d4 << std::endl;
- return 0;
- }
|