PageRenderTime 15ms CodeModel.GetById 9ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/geometry/example/c10_custom_cs_example.cpp

http://hadesmem.googlecode.com/
C++ | 106 lines | 46 code | 23 blank | 37 comment | 0 complexity | 751308390637cb2cd258cce7cbd84d2f MD5 | raw file
  1// Boost.Geometry (aka GGL, Generic Geometry Library)
  2
  3// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
  4// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
  5// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
  6
  7// Use, modification and distribution is subject to the Boost Software License,
  8// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9// http://www.boost.org/LICENSE_1_0.txt)
 10//
 11// Example: Custom coordinate system example 
 12
 13#include <iostream>
 14
 15#include <boost/geometry/geometry.hpp>
 16
 17#ifdef OPTIONALLY_ELLIPSOIDAL  // see below
 18#include <boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp>
 19#endif
 20
 21// 1: declare a coordinate system. For example for Mars
 22//    Like for the Earth, we let the use choose between degrees or radians
 23//    (Unfortunately, in real life Mars has two coordinate systems:
 24//     http://planetarynames.wr.usgs.gov/Page/MARS/system)
 25template<typename DegreeOrRadian>
 26struct martian
 27{
 28    typedef DegreeOrRadian units;
 29};
 30
 31// 2: give it also a family
 32struct martian_tag;
 33
 34// 3: register to which coordinate system family it belongs to
 35//    this must be done in namespace boost::geometry::traits
 36namespace boost { namespace geometry { namespace traits
 37{
 38
 39template <typename DegreeOrRadian>
 40struct cs_tag<martian<DegreeOrRadian> >
 41{
 42    typedef martian_tag type;
 43};
 44
 45}}} // namespaces
 46
 47
 48// NOTE: if the next steps would not be here, 
 49// compiling a distance function call with martian coordinates 
 50// would result in a MPL assertion
 51
 52// 4: so register a distance strategy as its default strategy
 53namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
 54{
 55
 56template <typename Point1, typename Point2>
 57struct default_strategy<point_tag, Point1, Point2, martian_tag, martian_tag>
 58{
 59    typedef haversine<Point1, Point2> type;
 60};
 61
 62}}}}} // namespaces
 63
 64// 5: not worked out. To implement a specific distance strategy for Mars,
 65//    e.g. with the Mars radius given by default, 
 66//    you will have to implement (/register) several other metafunctions:
 67//      tag, return_type, similar_type, comparable_type, 
 68//    and structs:
 69//      get_similar, get_comparable, result_from_distance
 70//   See e.g. .../boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp 
 71
 72int main()
 73{
 74    typedef boost::geometry::model::point
 75        <
 76            double, 2, martian<boost::geometry::degree> 
 77        > mars_point;
 78
 79    // Declare two points 
 80    // (Source: http://nssdc.gsfc.nasa.gov/planetary/mars_mileage_guide.html)
 81    // (Other sources: Wiki and Google give slightly different coordinates, resulting
 82    //  in other distance, 20 km off)
 83    mars_point viking1(-48.23, 22.54); // Viking 1 landing site in Chryse Planitia
 84    mars_point pathfinder(-33.55, 19.33); // Pathfinder landing site in Ares Vallis
 85
 86    double d = boost::geometry::distance(viking1, pathfinder); // Distance in radians on unit-sphere
 87
 88    // Using the Mars mean radius
 89    // (Source: http://nssdc.gsfc.nasa.gov/planetary/factsheet/marsfact.html)
 90    std::cout << "Distance between Viking1 and Pathfinder landing sites: " 
 91        << d * 3389.5 << " km" << std::endl;
 92
 93    // We would get 832.616 here, same order as the 835 (rounded on 5 km) listed
 94    // on the mentioned site 
 95
 96#ifdef OPTIONALLY_ELLIPSOIDAL
 97    // Optionally the distance can be calculated more accurate by an Ellipsoidal approach,
 98    // giving 834.444 km
 99    d = boost::geometry::distance(viking1, pathfinder,
100        boost::geometry::strategy::distance::andoyer<mars_point>
101            (boost::geometry::detail::ellipsoid<double>(3396.2, 3376.2)));
102    std::cout << "Ellipsoidal distance: " << d << " km" << std::endl;
103#endif
104
105    return 0;
106}