diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp old mode 100644 new mode 100755 index 7fe9ea8e3..1a63d33fb --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -35,6 +35,12 @@ #include #include +// boost +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + namespace mapnik { template @@ -298,7 +304,7 @@ bool hit_test_first(PathType & path, double x, double y) namespace label { template -bool middle_point(PathType & path, double & x, double & y) +bool middle_point(PathType & path, double & x, double & y, boost::optional angle = boost::none) { double x0 = 0; double y0 = 0; @@ -319,6 +325,10 @@ bool middle_point(PathType & path, double & x, double & y) double r = (mid_length - dist)/seg_length; x = x0 + (x1 - x0) * r; y = y0 + (y1 - y0) * r; + if (angle) + { + *angle = atan2(y1 - y0, x1 - x0); + } break; } dist += seg_length; diff --git a/include/mapnik/markers_placement.hpp b/include/mapnik/markers_placement.hpp index bdb716f7c..4f4de7a02 100644 --- a/include/mapnik/markers_placement.hpp +++ b/include/mapnik/markers_placement.hpp @@ -49,6 +49,10 @@ public: case MARKER_POINT_PLACEMENT: construct(&point_, locator, detector, params); break; + case MARKER_ANGLED_POINT_PLACEMENT: + construct(&point_, locator, detector, params); + point_.use_angle(true); + break; case MARKER_INTERIOR_PLACEMENT: construct(&interior_, locator, detector, params); break; @@ -70,6 +74,7 @@ public: { default: case MARKER_POINT_PLACEMENT: + case MARKER_ANGLED_POINT_PLACEMENT: destroy(&point_); break; case MARKER_INTERIOR_PLACEMENT: @@ -94,6 +99,7 @@ public: { default: case MARKER_POINT_PLACEMENT: + case MARKER_ANGLED_POINT_PLACEMENT: return point_.get_point(x, y, angle, ignore_placement); case MARKER_INTERIOR_PLACEMENT: return interior_.get_point(x, y, angle, ignore_placement); diff --git a/include/mapnik/markers_placements/point.hpp b/include/mapnik/markers_placements/point.hpp old mode 100644 new mode 100755 index 2a12af87b..7fcf80c86 --- a/include/mapnik/markers_placements/point.hpp +++ b/include/mapnik/markers_placements/point.hpp @@ -38,11 +38,18 @@ public: : markers_basic_placement(params), locator_(locator), detector_(detector), - done_(false) + done_(false), + use_angle_(false) { locator_.rewind(0); } + // Use angle of line + void use_angle(bool enable) + { + use_angle_ = enable; + } + // Start again at first marker. Returns the same list of markers only works when they were NOT added to the detector. void rewind() { @@ -58,9 +65,11 @@ public: return false; } + angle = 0; + if (this->locator_.type() == geometry::geometry_types::LineString) { - if (!label::middle_point(this->locator_, x, y)) + if (!label::middle_point(this->locator_, x, y, use_angle_ ? boost::optional(angle) : boost::none)) { this->done_ = true; return false; @@ -75,8 +84,6 @@ public: } } - angle = 0; - if (!this->push_to_detector(x, y, angle, ignore_placement)) { return false; @@ -90,6 +97,7 @@ protected: Locator & locator_; Detector & detector_; bool done_; + bool use_angle_; // Checks transformed box placement with collision detector. // returns false if the box: diff --git a/include/mapnik/symbolizer_enumerations.hpp b/include/mapnik/symbolizer_enumerations.hpp index 297b45512..d1c07c1f2 100644 --- a/include/mapnik/symbolizer_enumerations.hpp +++ b/include/mapnik/symbolizer_enumerations.hpp @@ -105,6 +105,7 @@ enum marker_placement_enum : std::uint8_t MARKER_LINE_PLACEMENT, MARKER_VERTEX_FIRST_PLACEMENT, MARKER_VERTEX_LAST_PLACEMENT, + MARKER_ANGLED_POINT_PLACEMENT, marker_placement_enum_MAX }; diff --git a/src/symbolizer_enumerations.cpp b/src/symbolizer_enumerations.cpp index 63ec78056..6c3b0d96f 100644 --- a/src/symbolizer_enumerations.cpp +++ b/src/symbolizer_enumerations.cpp @@ -67,6 +67,7 @@ static const char * marker_placement_strings[] = { "line", "vertex-first", "vertex-last", + "angled-point", "" };