diff --git a/deps/agg/include/agg_conv_transform.h b/deps/agg/include/agg_conv_transform.h index b57fb07fa..886acb35b 100644 --- a/deps/agg/include/agg_conv_transform.h +++ b/deps/agg/include/agg_conv_transform.h @@ -54,6 +54,8 @@ namespace agg m_trans = &tr; } + unsigned type() const { return m_source->type(); } + private: conv_transform(const conv_transform&); const conv_transform& diff --git a/include/mapnik/offset_converter.hpp b/include/mapnik/offset_converter.hpp index e7316d0f9..28f690276 100644 --- a/include/mapnik/offset_converter.hpp +++ b/include/mapnik/offset_converter.hpp @@ -64,6 +64,11 @@ struct MAPNIK_DECL offset_converter process }; + unsigned type() const + { + return static_cast(geom_.type()); + } + double get_offset() const { return offset_; diff --git a/include/mapnik/renderer_common/process_markers_symbolizer.hpp b/include/mapnik/renderer_common/process_markers_symbolizer.hpp index 70f639f39..fcfa404b0 100644 --- a/include/mapnik/renderer_common/process_markers_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_markers_symbolizer.hpp @@ -49,11 +49,18 @@ void render_markers_symbolizer(markers_symbolizer const& sym, using raster_dispatch_type = T1; using renderer_context_type = T2; - using conv_types = boost::mpl::vector; using svg_attribute_type = agg::pod_bvector; + using conv_types = boost::mpl::vector; std::string filename = get(sym, keys::file, feature, common.vars_, "shape://ellipse"); bool clip = get(sym, keys::clip, feature, common.vars_, false); + double offset = get(sym, keys::offset, feature, common.vars_, 0.0); + double simplify_tolerance = get(sym, keys::simplify_tolerance, feature, common.vars_, 0.0); double smooth = get(sym, keys::smooth, feature, common.vars_, false); // https://github.com/mapnik/mapnik/issues/1316 @@ -63,7 +70,10 @@ void render_markers_symbolizer(markers_symbolizer const& sym, boost::optional mark = mapnik::marker_cache::instance().find(filename, true); if (mark && *mark) { - agg::trans_affine tr = agg::trans_affine_scaling(common.scale_factor_); + agg::trans_affine geom_tr; + auto transform = get_optional(sym, keys::geometry_transform); + if (transform) evaluate_transform(geom_tr, feature, common.vars_, *transform, common.scale_factor_); + agg::trans_affine image_tr = agg::trans_affine_scaling(common.scale_factor_); if ((*mark)->is_vector()) { @@ -84,12 +94,12 @@ void render_markers_symbolizer(markers_symbolizer const& sym, svg_attribute_type attributes; bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_); auto image_transform = get_optional(sym, keys::image_transform); - if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform); + if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform); box2d bbox = marker_ellipse.bounding_box(); vector_dispatch_type rasterizer_dispatch(svg_path, result ? attributes : (*stock_vector_marker)->attributes(), bbox, - tr, + image_tr, sym, *common.detector_, common.scale_factor_, @@ -100,27 +110,28 @@ void render_markers_symbolizer(markers_symbolizer const& sym, vertex_converter, vector_dispatch_type, markers_symbolizer, view_transform, proj_transform, agg::trans_affine, conv_types, feature_impl> - converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_); + converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_); if (clip && feature.paths().size() > 0) // optional clip (default: true) { geometry_type::types type = feature.paths()[0].type(); if (type == geometry_type::types::Polygon) converter.template set(); - // line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426 - //else if (type == LineString) - // converter.template set(); - // don't clip if type==Point + else if (type == geometry_type::types::LineString) + converter.template set(); } converter.template set(); //always transform + if (std::fabs(offset) > 0.0) converter.template set(); // parallel offset + converter.template set(); // optional affine transform + if (simplify_tolerance > 0.0) converter.template set(); // optional simplify converter if (smooth > 0.0) converter.template set(); // optional smooth converter apply_markers_multi(feature, common.vars_, converter, sym); } else { box2d const& bbox = (*mark)->bounding_box(); - setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, common.vars_, sym); + setup_transform_scaling(image_tr, bbox.width(), bbox.height(), feature, common.vars_, sym); auto image_transform = get_optional(sym, keys::image_transform); - if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform); + if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform); vertex_stl_adapter stl_storage((*stock_vector_marker)->source()); svg_path_adapter svg_path(stl_storage); svg_attribute_type attributes; @@ -128,7 +139,7 @@ void render_markers_symbolizer(markers_symbolizer const& sym, vector_dispatch_type rasterizer_dispatch(svg_path, result ? attributes : (*stock_vector_marker)->attributes(), bbox, - tr, + image_tr, sym, *common.detector_, common.scale_factor_, @@ -139,33 +150,34 @@ void render_markers_symbolizer(markers_symbolizer const& sym, vertex_converter, vector_dispatch_type, markers_symbolizer, view_transform, proj_transform, agg::trans_affine, conv_types, feature_impl> - converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_); + converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_); if (clip && feature.paths().size() > 0) // optional clip (default: true) { geometry_type::types type = feature.paths()[0].type(); if (type == geometry_type::types::Polygon) converter.template set(); - // line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426 - //else if (type == LineString) - // converter.template set(); - // don't clip if type==Point + else if (type == geometry_type::types::LineString) + converter.template set(); } converter.template set(); //always transform + if (std::fabs(offset) > 0.0) converter.template set(); // parallel offset + converter.template set(); // optional affine transform + if (simplify_tolerance > 0.0) converter.template set(); // optional simplify converter if (smooth > 0.0) converter.template set(); // optional smooth converter apply_markers_multi(feature, common.vars_, converter, sym); } } else // raster markers { - setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, common.vars_, sym); + setup_transform_scaling(image_tr, (*mark)->width(), (*mark)->height(), feature, common.vars_, sym); auto image_transform = get_optional(sym, keys::image_transform); - if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform); + if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform); box2d const& bbox = (*mark)->bounding_box(); boost::optional marker = (*mark)->get_bitmap_data(); // - clamp sizes to > 4 pixels of interactivity coord2d center = bbox.center(); agg::trans_affine_translation recenter(-center.x, -center.y); - agg::trans_affine marker_trans = recenter * tr; + agg::trans_affine marker_trans = recenter * image_tr; raster_dispatch_type rasterizer_dispatch(**marker, marker_trans, sym, @@ -177,19 +189,20 @@ void render_markers_symbolizer(markers_symbolizer const& sym, vertex_converter, raster_dispatch_type, markers_symbolizer, view_transform, proj_transform, agg::trans_affine, conv_types, feature_impl> - converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_); + converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_); if (clip && feature.paths().size() > 0) // optional clip (default: true) { geometry_type::types type = feature.paths()[0].type(); if (type == geometry_type::types::Polygon) converter.template set(); - // line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426 - //else if (type == geometry_type::types::LineString) - // converter.template set(); - // don't clip if type==geometry_type::types::Point + else if (type == geometry_type::types::LineString) + converter.template set(); } converter.template set(); //always transform + if (std::fabs(offset) > 0.0) converter.template set(); // parallel offset + converter.template set(); // optional affine transform + if (simplify_tolerance > 0.0) converter.template set(); // optional simplify converter if (smooth > 0.0) converter.template set(); // optional smooth converter apply_markers_multi(feature, common.vars_, converter, sym); } diff --git a/include/mapnik/simplify_converter.hpp b/include/mapnik/simplify_converter.hpp index b2fbca00c..5fa53b815 100644 --- a/include/mapnik/simplify_converter.hpp +++ b/include/mapnik/simplify_converter.hpp @@ -109,6 +109,11 @@ public: cache }; + unsigned type() const + { + return static_cast(geom_.type()); + } + simplify_algorithm_e get_simplify_algorithm() { return algorithm_; diff --git a/src/load_map.cpp b/src/load_map.cpp index ce3eaead2..70bcfd540 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -969,6 +969,8 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) set_symbolizer_property(sym, keys::avoid_edges, node); // ignore-placement set_symbolizer_property(sym, keys::ignore_placement, node); + // offset + set_symbolizer_property(sym, keys::offset, node); // width //set_symbolizer_property(sym, keys::width, node); // height @@ -1025,8 +1027,7 @@ void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & nod set_symbolizer_property(sym, keys::opacity, node); // offset value - optional offset = node.get_opt_attr("offset"); - if (offset) put(sym, keys::offset, *offset); + set_symbolizer_property(sym, keys::offset, node); // image transform set_symbolizer_property(sym, keys::image_transform, node); rule.append(std::move(sym)); diff --git a/tests/visual_tests/grids/marker-on-line-and-line-placement-600-400-1.0-grid-reference.json b/tests/visual_tests/grids/marker-on-line-and-line-placement-600-400-1.0-grid-reference.json index 13b79ad2e..6d60c0905 100644 --- a/tests/visual_tests/grids/marker-on-line-and-line-placement-600-400-1.0-grid-reference.json +++ b/tests/visual_tests/grids/marker-on-line-and-line-placement-600-400-1.0-grid-reference.json @@ -5,105 +5,105 @@ ], "data": {}, "grid": [ - " !!! ", - " !!! ", - " !!!! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " !! ! ", - " !! !!! ", - " ! !!! ", - " ! !! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " !! ! ", - " !!! ! ", - " !! !!! ", - " ! !!! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " !! ! ", - " !!! ", - " !!! !!! ", - " ! !!! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ", - " ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " !!! ! ", - " !!! !! !! ", - " !! !! !!! ", - " ! !! !!! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! ! ! ", - " ! ! ", - " ! !! " + " !!!!!! ", + " ! !! !!!! !! ", + " ! ! !!! ! ! ", + " ! ! !! ! !!! ", + " ! ! !!! ! !! ", + " ! ! ! ! ! ", + " ! ! ! ! !! ", + " ! ! ! ! ! ! ", + " ! ! ! ! ", + " ! ! ! !!! ! !! ", + " !! ! !!! !! ", + " ! !! ! ! ! ", + " ! ! ! !! ", + " ! ! ! ! ! !!! ", + " ! ! ! ! !!! ", + " ! ! ! ! ! ! !! ! ", + " ! ! ! ! !!! ", + " !! ! ! ! ! ! !!! ", + " !! ! ! ! !! ! ", + " ! !! ! ! !!! ! ", + " ! !!!!! ! !! ! ", + " !! !! ! ! ! ", + " ! ! ! !! !! ! ", + " ! ! !!! ! ! ", + " ! ! ! ! ", + " ! ! ! ! ! ", + " ! ! ! ! ! ! ", + " ! ! ! ", + " ! ! ! ! ! ", + " ! ! ! ! ! ", + " ! ! ! ! ! ", + " ! ! !! ! ! ", + " ! ! ! ! !!! ! ! ! ", + " ! ! ! !! ! ! ", + " ! ! ! ! ", + " ! ! ! ! ! ! ", + " ! ! !!! ", + " ! ! ! ! !!!! ", + " ! ! !!! ! ", + " !! ! ! ! !!!! ", + " !!! ! ! !!!!! ", + " !! !!! ! ! !! ", + " ! !!!!!! ! !!! ", + " !!!!! !! !!!! ! ", + " ! ! ! !!! ! ! ", + " ! ! ! !! !!!! ", + " ! ! ! !!!!! ! ", + " ! ! ! ! ! ", + " ! ! ! ! ! ! ", + " ! ! ! ! ", + " ! ! ! ! ! ", + " ! ! ! !! ! ", + " ! ! ! ", + " ! ! ! !! ", + " ! ! !! ! ", + " ! ! ! !!!! ", + " ! ! ! ! ", + " !! ! ! ! ", + " ! ! ! !! ", + " ! ! ! ! ", + " !! ! !! ", + " ! ! !!!! ", + " ! !! ! !!! ", + " !! !! ! !!!! ", + " !! !!! ! !!!! ", + " !! !!! !! !!! ", + " ! !!! !!! !! ", + " !!! !!! !!!! ", + " ! ! ! !!! ", + " ! ! ! ! ! ", + " ! ! ! ! ", + " ! ! !! ", + " ! ! ! ! ", + " ! ! !! ", + " ! !! ", + " ! ! ! ! !! !! ", + " ! ! ! !!! !!! ", + " ! ! ! !!! !!! ", + " ! ! ! ! !!! ", + " ! ! ! !! ! ! ! ", + " !!! ! ! ! !! ", + " ! !! ! ! !! ! ", + " ! !!! ! ! ! !!! ", + " ! !!! !! ! ! !!! ! ", + " ! !!!! ! ! !! ", + " ! ! ! !!! ! !! ! ! !!! ", + " ! ! !!!! !!! ! ! !!! ", + " !!! ! !!!! !!! ! ! ", + " !!!!! !! ! ! ", + " !!!!! !! !! !! ! ! ! ", + " !!!!! !!! !!! ! ! ! ", + " !!!! !!!! !!! ! ! ! ", + " ! !! ! ! ! ! ", + " !!! ! ! ! ! ", + " !! ! ! ! !!! ! ", + " !! ! !!! ! !! ! ! ", + " ! ! ! !! ! ", + " !! ! !! ! ! ! ! ", + " ! ! !! ! ! ! ! ", + " ! ! !!! ! ! ! " ] } \ No newline at end of file diff --git a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-agg-reference.png b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-agg-reference.png index d91c2f035..63fa8a641 100644 Binary files a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-agg-reference.png and b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-cairo-reference.png b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-cairo-reference.png index 9f027d556..baf6176a2 100644 Binary files a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-cairo-reference.png and b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-agg-reference.png b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-agg-reference.png index 4f4fc7526..754d22092 100644 Binary files a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-agg-reference.png and b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-cairo-reference.png b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-cairo-reference.png index a2846c175..81322150c 100644 Binary files a/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-cairo-reference.png and b/tests/visual_tests/images/marker-on-line-and-line-placement-600-400-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/styles/marker-on-line-and-line-placement.xml b/tests/visual_tests/styles/marker-on-line-and-line-placement.xml index 3469cc24b..6cbdcebd4 100644 --- a/tests/visual_tests/styles/marker-on-line-and-line-placement.xml +++ b/tests/visual_tests/styles/marker-on-line-and-line-placement.xml @@ -1,13 +1,19 @@