c10_custom_cs_example.cpp 3.5 KB

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