diff --git a/deps/agg/include/agg_conv_adaptor_vcgen.h b/deps/agg/include/agg_conv_adaptor_vcgen.h index a79f2208c..ddbcef738 100644 --- a/deps/agg/include/agg_conv_adaptor_vcgen.h +++ b/deps/agg/include/agg_conv_adaptor_vcgen.h @@ -29,6 +29,7 @@ namespace agg void rewind(unsigned) {} unsigned vertex(double*, double*) { return path_cmd_stop; } + unsigned type() const { return 0; } }; @@ -64,6 +65,7 @@ namespace agg } unsigned vertex(double* x, double* y); + unsigned type() const { return m_source->type(); } private: // Prohibit copying diff --git a/deps/agg/include/agg_conv_adaptor_vpgen.h b/deps/agg/include/agg_conv_adaptor_vpgen.h index d6b545ef1..ae8d59320 100644 --- a/deps/agg/include/agg_conv_adaptor_vpgen.h +++ b/deps/agg/include/agg_conv_adaptor_vpgen.h @@ -33,6 +33,7 @@ namespace agg void rewind(unsigned path_id); unsigned vertex(double* x, double* y); + unsigned type() const { return m_source->type(); } private: conv_adaptor_vpgen(const conv_adaptor_vpgen&); diff --git a/deps/agg/include/agg_conv_clip_polygon.h b/deps/agg/include/agg_conv_clip_polygon.h index 87537638d..79aceedf3 100644 --- a/deps/agg/include/agg_conv_clip_polygon.h +++ b/deps/agg/include/agg_conv_clip_polygon.h @@ -51,6 +51,7 @@ namespace agg double y1() const { return base_type::vpgen().y1(); } double x2() const { return base_type::vpgen().x2(); } double y2() const { return base_type::vpgen().y2(); } + unsigned type() const { return base_type::type(); } private: conv_clip_polygon(const conv_clip_polygon&); diff --git a/deps/agg/include/agg_conv_clip_polyline.h b/deps/agg/include/agg_conv_clip_polyline.h index f3fc2888c..8bad5964f 100644 --- a/deps/agg/include/agg_conv_clip_polyline.h +++ b/deps/agg/include/agg_conv_clip_polyline.h @@ -51,6 +51,7 @@ namespace agg double y1() const { return base_type::vpgen().y1(); } double x2() const { return base_type::vpgen().x2(); } double y2() const { return base_type::vpgen().y2(); } + unsigned type() const { return base_type::type(); } private: conv_clip_polyline(const conv_clip_polyline&); diff --git a/deps/agg/include/agg_conv_smooth_poly1.h b/deps/agg/include/agg_conv_smooth_poly1.h index 4ac4e3d6e..00ab6b6af 100644 --- a/deps/agg/include/agg_conv_smooth_poly1.h +++ b/deps/agg/include/agg_conv_smooth_poly1.h @@ -42,6 +42,7 @@ namespace agg void smooth_value(double v) { base_type::generator().smooth_value(v); } double smooth_value() const { return base_type::generator().smooth_value(); } + unsigned type() const { return base_type::type(); } private: conv_smooth_poly1(const conv_smooth_poly1&); @@ -64,6 +65,7 @@ namespace agg void smooth_value(double v) { m_smooth.generator().smooth_value(v); } double smooth_value() const { return m_smooth.generator().smooth_value(); } + unsigned type() const { return m_smooth.type(); } private: conv_smooth_poly1_curve(const conv_smooth_poly1_curve&); diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index a56bc4bc4..07fbc9c3b 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -81,6 +81,11 @@ struct MAPNIK_DECL coord_transform geom_.rewind(pos); } + unsigned type() const + { + return static_cast(geom_.type()); + } + Geometry const& geom() const { return geom_; diff --git a/include/mapnik/grid/grid_marker_helpers.hpp b/include/mapnik/grid/grid_marker_helpers.hpp index a77bd7510..f5e3629a7 100644 --- a/include/mapnik/grid/grid_marker_helpers.hpp +++ b/include/mapnik/grid/grid_marker_helpers.hpp @@ -78,11 +78,17 @@ struct raster_markers_rasterizer_dispatch_grid { marker_placement_e placement_method = sym_.get_marker_placement(); box2d bbox_(0,0, src_.width(),src_.height()); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; @@ -209,11 +215,17 @@ struct vector_markers_rasterizer_dispatch_grid void add_path(T & path) { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index fd1a923d8..7d9861528 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.hpp @@ -87,11 +87,17 @@ struct vector_markers_rasterizer_dispatch { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; @@ -183,11 +189,17 @@ struct raster_markers_rasterizer_dispatch marker_placement_e placement_method = sym_.get_marker_placement(); box2d bbox_(0,0, src_.width(),src_.height()); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index ced6f7cb3..6972c5028 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -1494,11 +1494,17 @@ struct markers_dispatch { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; @@ -1577,11 +1583,17 @@ struct markers_dispatch_2 { marker_placement_e placement_method = sym_.get_marker_placement(); - if (placement_method != MARKER_LINE_PLACEMENT) + if (placement_method != MARKER_LINE_PLACEMENT || + path.type() == Point) { double x = 0; double y = 0; - if (placement_method == MARKER_INTERIOR_PLACEMENT) + if (path.type() == LineString) + { + if (!label::middle_point(path, x, y)) + return; + } + else if (placement_method == MARKER_INTERIOR_PLACEMENT) { if (!label::interior_position(path, x, y)) return; diff --git a/tests/visual_tests/data/marker-on-line.csv b/tests/visual_tests/data/marker-on-line.csv new file mode 100644 index 000000000..4835d65c5 --- /dev/null +++ b/tests/visual_tests/data/marker-on-line.csv @@ -0,0 +1,2 @@ +i|wkt +1|LINESTRING(-10 0, 0 20, 10 0, 15 5) diff --git a/tests/visual_tests/images/marker-on-line-600-reference.png b/tests/visual_tests/images/marker-on-line-600-reference.png new file mode 100644 index 000000000..b9893f537 Binary files /dev/null and b/tests/visual_tests/images/marker-on-line-600-reference.png differ diff --git a/tests/visual_tests/images/marker_line_placement_on_points-500-reference.png b/tests/visual_tests/images/marker_line_placement_on_points-500-reference.png new file mode 100644 index 000000000..71b1fb1f1 Binary files /dev/null and b/tests/visual_tests/images/marker_line_placement_on_points-500-reference.png differ diff --git a/tests/visual_tests/styles/marker-on-line.xml b/tests/visual_tests/styles/marker-on-line.xml new file mode 100644 index 000000000..1ca8ada6b --- /dev/null +++ b/tests/visual_tests/styles/marker-on-line.xml @@ -0,0 +1,21 @@ + + + + + line + point-placement + + csv + ../data/marker-on-line.csv + | + + + diff --git a/tests/visual_tests/styles/marker_line_placement_on_points.xml b/tests/visual_tests/styles/marker_line_placement_on_points.xml new file mode 100644 index 000000000..db11328c6 --- /dev/null +++ b/tests/visual_tests/styles/marker_line_placement_on_points.xml @@ -0,0 +1,36 @@ + + + + + + 1 + + csv + + x,y,id + 0,0,1 + 5,0,1 + 5,5,1 + 0,5,1 + 2.5,2.5,2 + 2.5,3,3 + 2.5,2,3 + 3,2.5,3 + 2,2.5,3 + + + + \ No newline at end of file diff --git a/tests/visual_tests/test.py b/tests/visual_tests/test.py index 2a8eab61a..ec05fde78 100755 --- a/tests/visual_tests/test.py +++ b/tests/visual_tests/test.py @@ -29,6 +29,10 @@ files = [ {'name': "lines-shield", 'sizes': sizes_few_square}, {'name': "marker-multi-policy", 'sizes':[(600,400)], 'bbox': mapnik.Box2d(0, 0, 190, 180)}, + {'name': "marker-on-line", 'sizes':[(600,400)], + 'bbox': mapnik.Box2d(-10, 0, 15, 20)}, + {'name': "marker_line_placement_on_points", 'sizes':[(500,100)], + 'bbox': mapnik.Box2d(0, 0, 5, 5)}, {'name': "whole-centroid", 'sizes':[(600,400)], 'bbox': mapnik.Box2d(736908, 4390316, 2060771, 5942346)}, {'name': "simple-E"},