Generation of output is now done through a stream iterator instead of the stream directly, which improves performance. Also made more compact generator for xml header, root element and bgcolor.

This commit is contained in:
Carlos López 2010-07-21 03:34:46 +00:00
parent 9800e38764
commit 94e8ee3a9f
15 changed files with 110 additions and 83 deletions

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(building_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(building_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(glyph_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(glyph_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(line_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(line_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(line_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(line_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(markers_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(markers_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(point_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(point_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(polygon_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(polygon_pattern_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(polygon_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(polygon_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(raster_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(raster_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(shield_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(shield_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -34,7 +34,7 @@ namespace mapnik
// nothing yet.
}
template void svg_renderer<std::stringstream>::process(text_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
template void svg_renderer<std::ostringstream>::process(text_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
}

View file

@ -29,6 +29,10 @@
#include <iostream>
#endif
#include <sstream>
#include <fstream>
// boost
#include <boost/fusion/tuple.hpp>
// boost.spirit
#include <boost/spirit/include/karma.hpp>
@ -36,7 +40,7 @@
namespace karma = boost::spirit::karma;
namespace repository = boost::spirit::repository;
namespace ascii = karma::ascii;
namespace fusion = boost::fusion;
namespace mapnik
{
@ -79,55 +83,49 @@ namespace mapnik
std::clog << "start map processing" << std::endl;
#endif
using repository::confix;
using karma::format;
using karma::lit;
using karma::eol;
using karma::int_;
using karma::double_;
using ascii::string;
using ascii::space;
// should I move these lines to the constructor?
// agg_renderer processes the background color of the map in the constructor.
using namespace karma;
using karma::string;
using repository::confix;
using fusion::tuple;
std::ostream_iterator<char> output_stream_iterator(output_stream_);
// generate XML header.
output_stream_ << format(string << eol << string << eol, XML_DECLARATION, SVG_DTD);
generate(
output_stream_iterator,
string << eol << string << eol,
XML_DECLARATION, SVG_DTD);
// generate SVG root element opening tag.
output_stream_
<< format(
confix("<svg width=\"", "\"")[int_ << string],
width_, "px")
<< format(
confix(" height=\"", "\"")[int_ << string],
height_, "px")
<< format(
confix(" version=\"", "\"")[double_],
SVG_VERSION)
<< format(
confix(" xmlns=\"", "\">")[string],
SVG_NAMESPACE_URL);
// the root element defines the size of the image,
// which is taken from the map's dimensions.
generate(
output_stream_iterator,
confix("<", ">")[
"svg width=" << confix('"', '"')[int_ << string]
<< " height=" << confix('"', '"')[int_ << string]
<< " version=" << confix('"', '"')[float_]
<< " xmlns=" << confix('"', '"')[string]]
<< eol,
tuple<int, std::string>(width_, "px"), tuple<int, std::string>(height_, "px"), SVG_VERSION, SVG_NAMESPACE_URL);
boost::optional<color> const& bgcolor = map.background();
if(bgcolor)
{
// generate background color as a rectangle that spans the whole image.
output_stream_
<< format(
confix("\n<rect x=\"", "\"")[int_],
0)
<< format(
confix(" y=\"", "\"")[int_],
0)
<< format(
confix(" width=\"", "\"")[int_ << string],
width_, "px")
<< format(
confix(" height=\"", "\"")[int_ << string],
height_, "px")
<< format(
confix(" style=\"fill: ", "\"/>")[string],
bgcolor->to_hex_string());
generate(
output_stream_iterator,
confix("<", "/>")[
"rect x=" << confix('"', '"')[int_]
<< " y=" << confix('"', '"')[int_]
<< " width=" << confix('"', '"')[int_ << string]
<< " height=" << confix('"', '"')[int_ << string]
<< " style=" << confix('"', '"')["fill: " << string]],
0, 0, tuple<int, std::string>(width_, "px"), tuple<int, std::string>(height_, "px"), bgcolor->to_hex_string());
}
}
@ -138,7 +136,6 @@ namespace mapnik
using karma::lit;
// generate SVG root element closing tag.
// this doesn't work.
output_stream_ << format(lit("\n</svg>"));
#ifdef MAPNIK_DEBUG
@ -166,5 +163,6 @@ namespace mapnik
#endif
}
template class svg_renderer<std::stringstream>;
template class svg_renderer<std::ostringstream>;
template class svg_renderer<std::ofstream>;
}

View file

@ -133,3 +133,33 @@ BOOST_FIXTURE_TEST_CASE(bgcolor_stream_confix_complete_test_case, F)
BOOST_CHECK_EQUAL(actual_output.str(), expected_output);
}
/*
* This test case uses an iterator to receive the generated
* output. The iterator comes from the std::ostringstream that's
* been used in the previous test cases, so the output is
* actually generated into the stream.
*
* Using iterators instead of streams has the advantage that
* more advanced concepts are implemented in karma for them,
* like rules and grammars.
*/
BOOST_FIXTURE_TEST_CASE(bgcolor_stream_iterator_test_case, F)
{
using repository::confix;
using fusion::tuple;
std::ostream_iterator<char> actual_output_iterator(actual_output);
generate(
actual_output_iterator,
confix("<", "/>")[
"rect x=" << confix('"', '"')[int_]
<< " y=" << confix('"', '"')[int_]
<< " width=" << confix('"', '"')[int_ << string]
<< " height=" << confix('"', '"')[int_ << string]
<< " style=" << confix('"', '"')["fill: " << string]],
x, y, tuple<int, std::string>(width, "px"), tuple<int, std::string>(height, "px"), bgcolor);
BOOST_CHECK_EQUAL(actual_output.str(), expected_output);
}

View file

@ -26,12 +26,12 @@
BOOST_AUTO_TEST_CASE(combined_test_case)
{
using namespace mapnik;
typedef svg_renderer<std::stringstream> svg_ren;
typedef svg_renderer<std::ostringstream> svg_ren;
Map map(800, 600);
map.set_background(color_factory::from_string("white"));
std::stringstream output_stream;
std::ostringstream output_stream;
svg_ren renderer(map, output_stream);
renderer.apply();

View file

@ -1,4 +1,4 @@
#define BOOST_TEST_MODULE compile_tests
#define BOOST_TEST_MODULE compile_test
// boost.test
#include <boost/test/included/unit_test.hpp>
@ -23,13 +23,12 @@ BOOST_AUTO_TEST_CASE(compile_test_case)
try
{
std::stringstream output_stream;
svg_renderer<std::stringstream> renderer(map, output_stream);
renderer.apply();
std::clog << output_stream.str() << "\n";
std::ostringstream output_stream;
svg_renderer<std::ostringstream> renderer(map, output_stream);
renderer.apply();
}
catch(...)
{
BOOST_FAIL("Empty implementation throws exception.");
BOOST_FAIL("Empty implementation throws exception.");
}
}