[svg] Add scale function and examples of it

This commit is contained in:
Barend Gehrels 2020-11-12 14:16:59 +01:00
parent ee3509f2f3
commit 1c06875105
9 changed files with 114 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -151,6 +151,7 @@
[import src/examples/geometries/register/multi_polygon.cpp]
[import src/examples/io/svg.cpp]
[import src/examples/io/svg_mapper_scale.cpp]
[import src/examples/io/wkt.cpp]
[import src/examples/io/read_wkt.cpp]

View File

@ -12,5 +12,9 @@
[svg_mapper]
[svg_mapper_output]
[heading Example with arrows and groups]
[svg_mapper_scale]
[svg_mapper_scale_output]
[heading See also]
* [link geometry.reference.io.svg.svg The SVG manipulator]

View File

@ -15,5 +15,6 @@ project boost-geometry-doc-example-io
;
exe svg : svg.cpp ;
exe svg_mapper_scale : svg_mapper_scale.cpp ;
exe wkt : wkt.cpp ;
exe read_wkt : read_wkt.cpp ;

View File

@ -37,7 +37,7 @@ int main()
std::ofstream svg("my_map.svg");
boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400);
// Add geometries such that all these geometries fit on the map
// Add geometries such that all these geometries fit exactly on the map
mapper.add(a);
mapper.add(b);
mapper.add(c);

View File

@ -0,0 +1,75 @@
// Boost.Geometry
// QuickBook Example
// Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands.
// 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)
//[svg_mapper_scale
//` Shows the usage of svg_mapper with the scale function
#include <iostream>
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
int main()
{
// Specify the basic type
using point_type = boost::geometry::model::d2::point_xy<double>;
// Declare linestrings and set their values
boost::geometry::model::linestring<point_type> a, b, c;
a.push_back({1, 0});
a.push_back({3, 3});
b.push_back({5, 0});
b.push_back({3, 2});
c.push_back({4, 5});
c.push_back({3, 4});
// Declare a stream and an SVG mapper
std::ofstream svg("my_map.svg");
boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400);
// Add geometries such that all these geometries fit exactly on the map
mapper.add(a);
mapper.add(b);
mapper.add(c);
// Zoom out 5% to have a bit margin around the geometries
// This also forces writing the SVG header.
mapper.scale(0.95);
// Write a marker definition.
svg << "<defs>";
svg << "<marker id=\"arrowhead\" markerWidth=\"5\" markerHeight=\"3.5\""
" refX=\"0\" refY=\"1.75\" orient=\"auto\">"
" <polygon points=\"0 0, 5 1.75, 0 3.5\"/></marker>";
svg << "</defs>";
// Group the first two geometries
svg << "<g>";
mapper.map(a, "opacity:0.5;stroke-width:1;stroke:gray;marker-end:url(#arrowhead)");
mapper.map(b, "opacity:0.5;stroke-width:3;stroke:gray;marker-end:url(#arrowhead)");
svg << "</g>";
mapper.map(c, "opacity:0.5;stroke-width:5;stroke:red;marker-end:url(#arrowhead)");
return 0;
}
//]
//[svg_mapper_scale_output
/*`
Output:
[$img/io/svg_mapper_scale.png]
*/
//]

View File

@ -368,6 +368,35 @@ public :
}
}
/*!
\brief Optional step, zoom in or zoom out, and forces writing the header. After writing the
transformation, geometries should not be added, and mapping can begin. After writing the
header, other SVG elements can be streamed (for example defs) which can later be used
in styles.
Call this function after add and before map or text.
\param scale A value larger than 1.0 zooms in, a value smaller than 1.0 zooms out.
A scale of 1.0 doesn't change any scaling, but still writes the SVG header.
*/
void scale(double scale = 1.0)
{
if (scale != 1.0 && scale > 0)
{
// Zoom out (scale < 1) or zoom in (scale > 1).
// Typically, users might specify 0.95, to have a small margin around their geometries.
auto& b = m_bounding_box;
auto const w = geometry::get<1, 0>(b) - geometry::get<0, 0>(b);
auto const h = geometry::get<1, 1>(b) - geometry::get<0, 1>(b);
auto const& m = std::max(w, h) * (1.0 - scale);
geometry::set<0, 0>(b, geometry::get<0, 0>(b) - m);
geometry::set<0, 1>(b, geometry::get<0, 1>(b) - m);
geometry::set<1, 0>(b, geometry::get<1, 0>(b) + m);
geometry::set<1, 1>(b, geometry::get<1, 1>(b) + m);
}
init_matrix();
}
/*!
\brief Maps a geometry into the SVG map using the specified style
\tparam Geometry \tparam_geometry

View File

@ -131,6 +131,8 @@ void test_all()
mapper.add(m_po);
mapper.add(var);
mapper.scale(0.95);
mapper.map(pt, style);
mapper.map(b, style);
mapper.map(s, style);

View File

@ -259,11 +259,11 @@ inline void geom_to_svg(std::string const& wkt1, std::string const& wkt2, std::s
}
struct to_svg_assign_policy
: boost::geometry::detail::overlay::assign_null_policy
{
static bool const include_no_turn = false;
static bool const include_degenerate = false;
static bool const include_opposite = false;
static bool const include_start_turn = false;
};
template <typename G>