annotate DEPENDENCIES/generic/include/boost/geometry/io/svg/write_svg.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@16 2
Chris@16 3 // Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
Chris@101 4 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
Chris@16 5
Chris@16 6 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
Chris@16 7 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
Chris@16 8
Chris@16 9 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 10 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 11 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 12
Chris@16 13 #ifndef BOOST_GEOMETRY_IO_SVG_WRITE_SVG_HPP
Chris@16 14 #define BOOST_GEOMETRY_IO_SVG_WRITE_SVG_HPP
Chris@16 15
Chris@16 16 #include <ostream>
Chris@16 17 #include <string>
Chris@16 18
Chris@16 19 #include <boost/config.hpp>
Chris@16 20 #include <boost/mpl/assert.hpp>
Chris@16 21 #include <boost/range.hpp>
Chris@16 22
Chris@101 23 #include <boost/geometry/algorithms/detail/interior_iterator.hpp>
Chris@16 24
Chris@16 25 #include <boost/geometry/core/exterior_ring.hpp>
Chris@16 26 #include <boost/geometry/core/interior_rings.hpp>
Chris@16 27 #include <boost/geometry/core/ring_type.hpp>
Chris@16 28
Chris@16 29 #include <boost/geometry/geometries/concepts/check.hpp>
Chris@16 30
Chris@16 31
Chris@16 32 namespace boost { namespace geometry
Chris@16 33 {
Chris@16 34
Chris@16 35
Chris@16 36 #ifndef DOXYGEN_NO_DETAIL
Chris@16 37 namespace detail { namespace svg
Chris@16 38 {
Chris@16 39
Chris@16 40
Chris@16 41 template <typename Point>
Chris@16 42 struct svg_point
Chris@16 43 {
Chris@16 44 template <typename Char, typename Traits>
Chris@16 45 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 46 Point const& p, std::string const& style, int size)
Chris@16 47 {
Chris@16 48 os << "<circle cx=\"" << geometry::get<0>(p)
Chris@16 49 << "\" cy=\"" << geometry::get<1>(p)
Chris@16 50 << "\" r=\"" << (size < 0 ? 5 : size)
Chris@16 51 << "\" style=\"" << style << "\"/>";
Chris@16 52 }
Chris@16 53 };
Chris@16 54
Chris@16 55
Chris@16 56 template <typename Box>
Chris@16 57 struct svg_box
Chris@16 58 {
Chris@16 59 template <typename Char, typename Traits>
Chris@16 60 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 61 Box const& box, std::string const& style, int )
Chris@16 62 {
Chris@16 63 // Prevent invisible boxes, making them >=1, using "max"
Chris@16 64 BOOST_USING_STD_MAX();
Chris@16 65
Chris@16 66 typedef typename coordinate_type<Box>::type ct;
Chris@16 67 ct x = geometry::get<geometry::min_corner, 0>(box);
Chris@16 68 ct y = geometry::get<geometry::min_corner, 1>(box);
Chris@16 69 ct width = max BOOST_PREVENT_MACRO_SUBSTITUTION(1,
Chris@16 70 geometry::get<geometry::max_corner, 0>(box) - x);
Chris@16 71 ct height = max BOOST_PREVENT_MACRO_SUBSTITUTION (1,
Chris@16 72 geometry::get<geometry::max_corner, 1>(box) - y);
Chris@16 73
Chris@16 74 os << "<rect x=\"" << x << "\" y=\"" << y
Chris@16 75 << "\" width=\"" << width << "\" height=\"" << height
Chris@16 76 << "\" style=\"" << style << "\"/>";
Chris@16 77 }
Chris@16 78 };
Chris@16 79
Chris@16 80
Chris@16 81 /*!
Chris@16 82 \brief Stream ranges as SVG
Chris@16 83 \note policy is used to select type (polyline/polygon)
Chris@16 84 */
Chris@16 85 template <typename Range, typename Policy>
Chris@16 86 struct svg_range
Chris@16 87 {
Chris@16 88 template <typename Char, typename Traits>
Chris@16 89 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 90 Range const& range, std::string const& style, int )
Chris@16 91 {
Chris@16 92 typedef typename boost::range_iterator<Range const>::type iterator;
Chris@16 93
Chris@16 94 bool first = true;
Chris@16 95
Chris@16 96 os << "<" << Policy::prefix() << " points=\"";
Chris@16 97
Chris@16 98 for (iterator it = boost::begin(range);
Chris@16 99 it != boost::end(range);
Chris@16 100 ++it, first = false)
Chris@16 101 {
Chris@16 102 os << (first ? "" : " " )
Chris@16 103 << geometry::get<0>(*it)
Chris@16 104 << ","
Chris@16 105 << geometry::get<1>(*it);
Chris@16 106 }
Chris@16 107 os << "\" style=\"" << style << Policy::style() << "\"/>";
Chris@16 108 }
Chris@16 109 };
Chris@16 110
Chris@16 111
Chris@16 112
Chris@16 113 template <typename Polygon>
Chris@16 114 struct svg_poly
Chris@16 115 {
Chris@16 116 template <typename Char, typename Traits>
Chris@16 117 static inline void apply(std::basic_ostream<Char, Traits>& os,
Chris@16 118 Polygon const& polygon, std::string const& style, int )
Chris@16 119 {
Chris@16 120 typedef typename geometry::ring_type<Polygon>::type ring_type;
Chris@16 121 typedef typename boost::range_iterator<ring_type const>::type iterator_type;
Chris@16 122
Chris@16 123 bool first = true;
Chris@16 124 os << "<g fill-rule=\"evenodd\"><path d=\"";
Chris@16 125
Chris@16 126 ring_type const& ring = geometry::exterior_ring(polygon);
Chris@16 127 for (iterator_type it = boost::begin(ring);
Chris@16 128 it != boost::end(ring);
Chris@16 129 ++it, first = false)
Chris@16 130 {
Chris@16 131 os << (first ? "M" : " L") << " "
Chris@16 132 << geometry::get<0>(*it)
Chris@16 133 << ","
Chris@16 134 << geometry::get<1>(*it);
Chris@16 135 }
Chris@16 136
Chris@16 137 // Inner rings:
Chris@16 138 {
Chris@101 139 typename interior_return_type<Polygon const>::type
Chris@101 140 rings = interior_rings(polygon);
Chris@101 141 for (typename detail::interior_iterator<Polygon const>::type
Chris@101 142 rit = boost::begin(rings); rit != boost::end(rings); ++rit)
Chris@16 143 {
Chris@16 144 first = true;
Chris@101 145 for (typename detail::interior_ring_iterator<Polygon const>::type
Chris@101 146 it = boost::begin(*rit); it != boost::end(*rit);
Chris@16 147 ++it, first = false)
Chris@16 148 {
Chris@16 149 os << (first ? "M" : " L") << " "
Chris@16 150 << geometry::get<0>(*it)
Chris@16 151 << ","
Chris@16 152 << geometry::get<1>(*it);
Chris@16 153 }
Chris@16 154 }
Chris@16 155 }
Chris@16 156 os << " z \" style=\"" << style << "\"/></g>";
Chris@16 157
Chris@16 158 }
Chris@16 159 };
Chris@16 160
Chris@16 161
Chris@16 162
Chris@16 163 struct prefix_linestring
Chris@16 164 {
Chris@16 165 static inline const char* prefix() { return "polyline"; }
Chris@16 166 static inline const char* style() { return ";fill:none"; }
Chris@16 167 };
Chris@16 168
Chris@16 169
Chris@16 170 struct prefix_ring
Chris@16 171 {
Chris@16 172 static inline const char* prefix() { return "polygon"; }
Chris@16 173 static inline const char* style() { return ""; }
Chris@16 174 };
Chris@16 175
Chris@16 176
Chris@16 177
Chris@16 178 }} // namespace detail::svg
Chris@16 179 #endif // DOXYGEN_NO_DETAIL
Chris@16 180
Chris@16 181
Chris@16 182 #ifndef DOXYGEN_NO_DISPATCH
Chris@16 183 namespace dispatch
Chris@16 184 {
Chris@16 185
Chris@16 186 /*!
Chris@16 187 \brief Dispatching base struct for SVG streaming, specialized below per geometry type
Chris@16 188 \details Specializations should implement a static method "stream" to stream a geometry
Chris@16 189 The static method should have the signature:
Chris@16 190
Chris@16 191 template <typename Char, typename Traits>
Chris@16 192 static inline void apply(std::basic_ostream<Char, Traits>& os, G const& geometry)
Chris@16 193 */
Chris@16 194 template <typename GeometryTag, typename Geometry>
Chris@16 195 struct svg
Chris@16 196 {
Chris@16 197 BOOST_MPL_ASSERT_MSG
Chris@16 198 (
Chris@16 199 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
Chris@16 200 , (Geometry)
Chris@16 201 );
Chris@16 202 };
Chris@16 203
Chris@16 204 template <typename Point>
Chris@16 205 struct svg<point_tag, Point> : detail::svg::svg_point<Point> {};
Chris@16 206
Chris@16 207 template <typename Box>
Chris@16 208 struct svg<box_tag, Box> : detail::svg::svg_box<Box> {};
Chris@16 209
Chris@16 210 template <typename Linestring>
Chris@16 211 struct svg<linestring_tag, Linestring>
Chris@16 212 : detail::svg::svg_range<Linestring, detail::svg::prefix_linestring> {};
Chris@16 213
Chris@16 214 template <typename Ring>
Chris@16 215 struct svg<ring_tag, Ring>
Chris@16 216 : detail::svg::svg_range<Ring, detail::svg::prefix_ring> {};
Chris@16 217
Chris@16 218 template <typename Polygon>
Chris@16 219 struct svg<polygon_tag, Polygon>
Chris@16 220 : detail::svg::svg_poly<Polygon> {};
Chris@16 221
Chris@16 222 } // namespace dispatch
Chris@16 223 #endif // DOXYGEN_NO_DISPATCH
Chris@16 224
Chris@16 225
Chris@16 226 /*!
Chris@16 227 \brief Generic geometry template manipulator class, takes corresponding output class from traits class
Chris@16 228 \ingroup svg
Chris@16 229 \details Stream manipulator, streams geometry classes as SVG (Scalable Vector Graphics)
Chris@16 230 */
Chris@16 231 template <typename G>
Chris@16 232 class svg_manipulator
Chris@16 233 {
Chris@16 234 public:
Chris@16 235
Chris@16 236 inline svg_manipulator(G const& g, std::string const& style, int size)
Chris@16 237 : m_geometry(g)
Chris@16 238 , m_style(style)
Chris@16 239 , m_size(size)
Chris@16 240 {}
Chris@16 241
Chris@16 242 template <typename Char, typename Traits>
Chris@16 243 inline friend std::basic_ostream<Char, Traits>& operator<<(
Chris@16 244 std::basic_ostream<Char, Traits>& os, svg_manipulator const& m)
Chris@16 245 {
Chris@16 246 dispatch::svg
Chris@16 247 <
Chris@16 248 typename tag<G>::type, G
Chris@16 249 >::apply(os, m.m_geometry, m.m_style, m.m_size);
Chris@16 250 os.flush();
Chris@16 251 return os;
Chris@16 252 }
Chris@16 253
Chris@16 254 private:
Chris@16 255 G const& m_geometry;
Chris@16 256 std::string const& m_style;
Chris@16 257 int m_size;
Chris@16 258 };
Chris@16 259
Chris@16 260 /*!
Chris@16 261 \brief Manipulator to stream geometries as SVG
Chris@16 262 \tparam Geometry \tparam_geometry
Chris@16 263 \param geometry \param_geometry
Chris@16 264 \param style String containing verbatim SVG style information
Chris@16 265 \param size Optional size (used for SVG points) in SVG pixels. For linestrings,
Chris@16 266 specify linewidth in the SVG style information
Chris@16 267 \ingroup svg
Chris@16 268 */
Chris@16 269 template <typename Geometry>
Chris@16 270 inline svg_manipulator<Geometry> svg(Geometry const& geometry, std::string const& style, int size = -1)
Chris@16 271 {
Chris@16 272 concept::check<Geometry const>();
Chris@16 273
Chris@16 274 return svg_manipulator<Geometry>(geometry, style, size);
Chris@16 275 }
Chris@16 276
Chris@16 277 }} // namespace boost::geometry
Chris@16 278
Chris@16 279 #endif // BOOST_GEOMETRY_IO_SVG_WRITE_SVG_HPP