This code:
#include <fstream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry;
int main()
{
std::ofstream svg ( "test.svg" );
boost::geometry::svg_mapper<bg::model::d2::point_xy<double>, true, double> mapper ( svg, 6000, 3000 );
bg::model::polygon<bg::model::d2::point_xy<double>> square{
{{0, 0}, {0, 1000}, {1000, 1000}, {1000, 0}, {0, 0}}};
const std::string style{"fill-opacity:1.0;fill:rgb(128,128,128);stroke:rgb(0,0,0);stroke-width:5"};
mapper.add ( square );
mapper.map ( square, style, 1.0 );
}
Produces this svg:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g fill-rule="evenodd"><path d="M 1500,3000 L 1500,0 L 4500,0 L 4500,3000 L 1500,3000 z " style="fill-opacity:1.0;fill:rgb(128,128,128);stroke:rgb(0,0,0);stroke-width:5"/></g>
</svg>
The following conversions happen from the input polygon to the mapped svg geometries:
(0, 0) -> (1500,3000)
(0, 1000) -> (1500,0)
(1000, 1000) -> (4500,0)
(1000, 0) -> (4500,3000)
(0, 0) -> (1500,3000)
Staring at it a bit you see there is some transformation applied, something like this:
- 1500 in x
- 3000 in y
- 3x scale in x
- -3x scale in y
My question is - What drives that transformation and can I prevent it? And if I can't prevent it, can I retrieve it or calculate it myself?
Reason being is I'm producing many complex SVG's and would like them to all be in the same frame. So if there is a circle at pixels (10,10) in one, I would like all the images to be of the same size with the circle in the exact same location. I tried to accomplish this with viewBox
but the scaling and translation was too hard to predict to keep the images consistent.
CodePudding user response:
svg_mapper
calculates a bounding box from all add
-ed geometries.
Then, a map_transformer
is used to scale down to the desired width/height.
Contrary to what you might expect, add
doesn't do anything besides expanding the bounding box. Likewise, after the first map
call, no other add
has any effect on the bounding-box used for the transformations.
In other words, you can use some kind of fixed bounding box, add only that, and then map your geometries into that "canvas":