read.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  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. #ifndef BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP
  11. #define BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP
  12. #include <string>
  13. #include <boost/geometry/core/mutable_range.hpp>
  14. #include <boost/geometry/multi/core/tags.hpp>
  15. #include <boost/geometry/multi/core/point_type.hpp>
  16. #include <boost/geometry/multi/geometries/concepts/check.hpp>
  17. #include <boost/geometry/multi/io/wkt/detail/prefix.hpp>
  18. #include <boost/geometry/io/wkt/read.hpp>
  19. namespace boost { namespace geometry
  20. {
  21. namespace detail { namespace wkt
  22. {
  23. template <typename MultiGeometry, template<typename> class Parser, typename PrefixPolicy>
  24. struct multi_parser
  25. {
  26. static inline void apply(std::string const& wkt, MultiGeometry& geometry)
  27. {
  28. traits::clear<MultiGeometry>::apply(geometry);
  29. tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
  30. tokenizer::iterator it;
  31. if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
  32. {
  33. handle_open_parenthesis(it, tokens.end(), wkt);
  34. // Parse sub-geometries
  35. while(it != tokens.end() && *it != ")")
  36. {
  37. traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
  38. Parser
  39. <
  40. typename boost::range_value<MultiGeometry>::type
  41. >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
  42. if (it != tokens.end() && *it == ",")
  43. {
  44. // Skip "," after multi-element is parsed
  45. ++it;
  46. }
  47. }
  48. handle_close_parenthesis(it, tokens.end(), wkt);
  49. }
  50. check_end(it, tokens.end(), wkt);
  51. }
  52. };
  53. template <typename P>
  54. struct noparenthesis_point_parser
  55. {
  56. static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
  57. std::string const& wkt, P& point)
  58. {
  59. parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
  60. }
  61. };
  62. template <typename MultiGeometry, typename PrefixPolicy>
  63. struct multi_point_parser
  64. {
  65. static inline void apply(std::string const& wkt, MultiGeometry& geometry)
  66. {
  67. traits::clear<MultiGeometry>::apply(geometry);
  68. tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
  69. tokenizer::iterator it;
  70. if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
  71. {
  72. handle_open_parenthesis(it, tokens.end(), wkt);
  73. // If first point definition starts with "(" then parse points as (x y)
  74. // otherwise as "x y"
  75. bool using_brackets = (it != tokens.end() && *it == "(");
  76. while(it != tokens.end() && *it != ")")
  77. {
  78. traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
  79. if (using_brackets)
  80. {
  81. point_parser
  82. <
  83. typename boost::range_value<MultiGeometry>::type
  84. >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
  85. }
  86. else
  87. {
  88. noparenthesis_point_parser
  89. <
  90. typename boost::range_value<MultiGeometry>::type
  91. >::apply(it, tokens.end(), wkt, *(boost::end(geometry) - 1));
  92. }
  93. if (it != tokens.end() && *it == ",")
  94. {
  95. // Skip "," after point is parsed
  96. ++it;
  97. }
  98. }
  99. handle_close_parenthesis(it, tokens.end(), wkt);
  100. }
  101. check_end(it, tokens.end(), wkt);
  102. }
  103. };
  104. }} // namespace detail::wkt
  105. #ifndef DOXYGEN_NO_DISPATCH
  106. namespace dispatch
  107. {
  108. template <typename MultiGeometry>
  109. struct read_wkt<multi_point_tag, MultiGeometry>
  110. : detail::wkt::multi_point_parser
  111. <
  112. MultiGeometry,
  113. detail::wkt::prefix_multipoint
  114. >
  115. {};
  116. template <typename MultiGeometry>
  117. struct read_wkt<multi_linestring_tag, MultiGeometry>
  118. : detail::wkt::multi_parser
  119. <
  120. MultiGeometry,
  121. detail::wkt::linestring_parser,
  122. detail::wkt::prefix_multilinestring
  123. >
  124. {};
  125. template <typename MultiGeometry>
  126. struct read_wkt<multi_polygon_tag, MultiGeometry>
  127. : detail::wkt::multi_parser
  128. <
  129. MultiGeometry,
  130. detail::wkt::polygon_parser,
  131. detail::wkt::prefix_multipolygon
  132. >
  133. {};
  134. } // namespace dispatch
  135. #endif // DOXYGEN_NO_DISPATCH
  136. }} // namespace boost::geometry
  137. #endif // BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP