2017-09-13 11:14:13 +02:00
|
|
|
#include "catch.hpp"
|
|
|
|
|
|
|
|
#include <mapnik/memory_datasource.hpp>
|
|
|
|
#include <mapnik/feature.hpp>
|
|
|
|
#include <mapnik/feature_factory.hpp>
|
|
|
|
#include <mapnik/map.hpp>
|
|
|
|
#include <mapnik/params.hpp>
|
|
|
|
#include <mapnik/expression.hpp>
|
|
|
|
#include <mapnik/layer.hpp>
|
|
|
|
#include <mapnik/rule.hpp>
|
|
|
|
#include <mapnik/feature_style_processor.hpp>
|
|
|
|
#include <mapnik/feature_style_processor_impl.hpp>
|
|
|
|
#include <mapnik/value/types.hpp>
|
|
|
|
#include <mapnik/symbolizer.hpp>
|
|
|
|
#include <mapnik/geometry/geometry_type.hpp>
|
|
|
|
|
|
|
|
struct rendering_result
|
|
|
|
{
|
|
|
|
unsigned start_map_processing = 0;
|
|
|
|
unsigned end_map_processing = 0;
|
|
|
|
|
|
|
|
unsigned end_layer_processing = 0;
|
|
|
|
|
|
|
|
unsigned start_style_processing = 0;
|
|
|
|
unsigned end_style_processing = 0;
|
|
|
|
|
|
|
|
std::vector<mapnik::box2d<double>> layer_query_extents;
|
|
|
|
std::vector<mapnik::geometry::geometry<double>> geometries;
|
|
|
|
};
|
|
|
|
|
|
|
|
class test_renderer : public mapnik::feature_style_processor<test_renderer>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using processor_impl_type = test_renderer;
|
|
|
|
|
|
|
|
test_renderer(mapnik::Map const& map, rendering_result & result)
|
|
|
|
: mapnik::feature_style_processor<test_renderer>(map),
|
|
|
|
result_(result),
|
|
|
|
painted_(false),
|
|
|
|
vars_()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void start_map_processing(mapnik::Map const& map)
|
|
|
|
{
|
|
|
|
result_.start_map_processing++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void end_map_processing(mapnik::Map const& map)
|
|
|
|
{
|
|
|
|
result_.end_map_processing++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void start_layer_processing(mapnik::layer const& lay, mapnik::box2d<double> const& query_extent)
|
|
|
|
{
|
|
|
|
result_.layer_query_extents.push_back(query_extent);
|
|
|
|
}
|
|
|
|
|
|
|
|
void end_layer_processing(mapnik::layer const& lay)
|
|
|
|
{
|
|
|
|
result_.end_layer_processing++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void start_style_processing(mapnik::feature_type_style const& st)
|
|
|
|
{
|
|
|
|
result_.start_style_processing++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void end_style_processing(mapnik::feature_type_style const& st)
|
|
|
|
{
|
|
|
|
result_.end_style_processing++;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Symbolizer>
|
|
|
|
void process(Symbolizer const& sym, mapnik::feature_impl & feature, mapnik::proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
result_.geometries.push_back(feature.get_geometry());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool process(mapnik::rule::symbolizers const&, mapnik::feature_impl&, mapnik::proj_transform const& )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
double scale_factor() const
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
mapnik::attributes const& variables() const
|
|
|
|
{
|
|
|
|
return vars_;
|
|
|
|
}
|
|
|
|
|
|
|
|
mapnik::eAttributeCollectionPolicy attribute_collection_policy() const
|
|
|
|
{
|
|
|
|
return mapnik::eAttributeCollectionPolicy::DEFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool painted() const
|
|
|
|
{
|
|
|
|
return painted_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void painted(bool painted)
|
|
|
|
{
|
|
|
|
painted_ = painted;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
rendering_result & result_;
|
|
|
|
bool painted_;
|
|
|
|
mapnik::attributes vars_;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::shared_ptr<mapnik::memory_datasource> prepare_datasource()
|
|
|
|
{
|
|
|
|
mapnik::parameters params;
|
|
|
|
params["type"] = "memory";
|
|
|
|
|
|
|
|
using datasource_ptr = std::shared_ptr<mapnik::memory_datasource>;
|
|
|
|
datasource_ptr datasource = std::make_shared<mapnik::memory_datasource>(params);
|
|
|
|
mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
|
|
|
|
|
|
|
|
{
|
|
|
|
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, 1));
|
|
|
|
mapnik::geometry::point<double> point(1, 2);
|
|
|
|
feature->set_geometry(std::move(point));
|
|
|
|
datasource->push(feature);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, 2));
|
|
|
|
mapnik::geometry::line_string<double> path;
|
|
|
|
path.emplace_back(-10, 0);
|
|
|
|
path.emplace_back(0, 20);
|
|
|
|
path.emplace_back(10, 0);
|
|
|
|
path.emplace_back(15, 5);
|
|
|
|
feature->set_geometry(std::move(path));
|
|
|
|
datasource->push(feature);
|
|
|
|
}
|
|
|
|
|
|
|
|
return datasource;
|
|
|
|
}
|
|
|
|
|
|
|
|
mapnik::Map prepare_map()
|
|
|
|
{
|
|
|
|
mapnik::Map map(256, 256);
|
|
|
|
|
|
|
|
mapnik::feature_type_style lines_style;
|
|
|
|
mapnik::rule rule;
|
|
|
|
mapnik::line_symbolizer line_sym;
|
|
|
|
rule.append(std::move(line_sym));
|
|
|
|
lines_style.add_rule(std::move(rule));
|
|
|
|
map.insert_style("lines", std::move(lines_style));
|
|
|
|
|
|
|
|
mapnik::layer lyr("layer");
|
|
|
|
lyr.set_datasource(prepare_datasource());
|
|
|
|
lyr.add_style("lines");
|
|
|
|
map.add_layer(lyr);
|
|
|
|
|
|
|
|
map.zoom_all();
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("feature_style_processor") {
|
|
|
|
|
|
|
|
SECTION("test_renderer") {
|
|
|
|
|
|
|
|
mapnik::Map map(prepare_map());
|
|
|
|
rendering_result result;
|
|
|
|
test_renderer renderer(map, result);
|
|
|
|
renderer.apply();
|
|
|
|
|
|
|
|
REQUIRE(renderer.painted());
|
|
|
|
|
|
|
|
REQUIRE(result.start_map_processing == 1);
|
|
|
|
REQUIRE(result.end_map_processing == 1);
|
|
|
|
REQUIRE(result.end_layer_processing == 1);
|
|
|
|
REQUIRE(result.start_style_processing == 1);
|
|
|
|
REQUIRE(result.end_style_processing == 1);
|
|
|
|
|
|
|
|
REQUIRE(result.layer_query_extents.size() == 1);
|
|
|
|
const mapnik::box2d<double> reference_query_extent(-10, 0, 15, 20);
|
|
|
|
REQUIRE(result.layer_query_extents.front() == reference_query_extent);
|
|
|
|
|
|
|
|
REQUIRE(result.geometries.size() == 2);
|
|
|
|
REQUIRE(mapnik::geometry::geometry_type(result.geometries[0]) == mapnik::geometry::geometry_types::Point);
|
|
|
|
REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString);
|
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("test_renderer - apply() with single layer") {
|
|
|
|
|
|
|
|
mapnik::Map map(prepare_map());
|
|
|
|
rendering_result result;
|
|
|
|
test_renderer renderer(map, result);
|
|
|
|
std::set<std::string> attributes;
|
2021-02-25 12:05:11 +01:00
|
|
|
mapnik::layer const& layer = map.get_layer(0);
|
2017-09-13 11:14:13 +02:00
|
|
|
renderer.apply(layer, attributes);
|
|
|
|
|
|
|
|
REQUIRE(renderer.painted());
|
|
|
|
|
|
|
|
REQUIRE(result.start_map_processing == 1);
|
|
|
|
REQUIRE(result.end_map_processing == 1);
|
|
|
|
REQUIRE(result.end_layer_processing == 1);
|
|
|
|
REQUIRE(result.start_style_processing == 1);
|
|
|
|
REQUIRE(result.end_style_processing == 1);
|
|
|
|
|
|
|
|
REQUIRE(result.layer_query_extents.size() == 1);
|
|
|
|
const mapnik::box2d<double> reference_query_extent(-10, 0, 15, 20);
|
|
|
|
REQUIRE(result.layer_query_extents.front() == reference_query_extent);
|
|
|
|
|
|
|
|
REQUIRE(result.geometries.size() == 2);
|
|
|
|
REQUIRE(mapnik::geometry::geometry_type(result.geometries[0]) == mapnik::geometry::geometry_types::Point);
|
|
|
|
REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString);
|
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("test_renderer - apply_to_layer") {
|
|
|
|
|
|
|
|
mapnik::Map map(prepare_map());
|
|
|
|
rendering_result result;
|
|
|
|
test_renderer renderer(map, result);
|
|
|
|
std::set<std::string> attributes;
|
|
|
|
mapnik::projection map_proj(map.srs(), true);
|
2021-02-25 12:05:11 +01:00
|
|
|
mapnik::layer const& layer = map.get_layer(0);
|
2017-09-13 11:14:13 +02:00
|
|
|
renderer.apply_to_layer(layer,
|
|
|
|
renderer,
|
|
|
|
map_proj,
|
|
|
|
map.scale(),
|
|
|
|
map.scale_denominator(),
|
|
|
|
map.width(),
|
|
|
|
map.height(),
|
|
|
|
map.get_current_extent(),
|
|
|
|
0,
|
|
|
|
attributes);
|
|
|
|
|
|
|
|
REQUIRE(renderer.painted());
|
|
|
|
|
|
|
|
REQUIRE(result.start_map_processing == 0);
|
|
|
|
REQUIRE(result.end_map_processing == 0);
|
|
|
|
REQUIRE(result.end_layer_processing == 1);
|
|
|
|
REQUIRE(result.start_style_processing == 1);
|
|
|
|
REQUIRE(result.end_style_processing == 1);
|
|
|
|
|
|
|
|
REQUIRE(result.layer_query_extents.size() == 1);
|
|
|
|
const mapnik::box2d<double> reference_query_extent(-10, 0, 15, 20);
|
|
|
|
REQUIRE(result.layer_query_extents.front() == reference_query_extent);
|
|
|
|
|
|
|
|
REQUIRE(result.geometries.size() == 2);
|
|
|
|
REQUIRE(mapnik::geometry::geometry_type(result.geometries[0]) == mapnik::geometry::geometry_types::Point);
|
|
|
|
REQUIRE(mapnik::geometry::geometry_type(result.geometries[1]) == mapnik::geometry::geometry_types::LineString);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|