From e1aededb096cbbf6cd2d0aa62f262ff042eae7c3 Mon Sep 17 00:00:00 2001 From: Jiri Drbalek Date: Sun, 24 Aug 2014 10:16:32 +0000 Subject: [PATCH] refactor marker placements --- include/mapnik/grid/grid_marker_helpers.hpp | 20 ++----- include/mapnik/marker_helpers.hpp | 20 ++----- include/mapnik/markers_placement.hpp | 22 ++----- .../mapnik/markers_placements/interior.hpp | 15 +---- include/mapnik/markers_placements/line.hpp | 58 ++++++++----------- include/mapnik/markers_placements/point.hpp | 50 ++++++---------- .../markers_placements/vertext_first.hpp | 15 +---- .../markers_placements/vertext_last.hpp | 15 +---- src/cairo/process_markers_symbolizer.cpp | 20 ++----- 9 files changed, 68 insertions(+), 167 deletions(-) diff --git a/include/mapnik/grid/grid_marker_helpers.hpp b/include/mapnik/grid/grid_marker_helpers.hpp index 1279d0565..1bf04fc2e 100644 --- a/include/mapnik/grid/grid_marker_helpers.hpp +++ b/include/mapnik/grid/grid_marker_helpers.hpp @@ -83,15 +83,9 @@ struct raster_markers_rasterizer_dispatch_grid : mapnik::noncopyable box2d bbox(0,0, src_.width(), src_.height()); double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0); double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2); + markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap }; markers_placement_finder placement_finder( - placement_method, - path, - bbox, - marker_trans_, - detector_, - spacing * scale_factor_, - max_error, - allow_overlap); + placement_method, path, detector_, params); double x, y, angle = .0; while (placement_finder.get_point(x, y, angle, ignore_placement)) { @@ -200,15 +194,9 @@ struct vector_markers_rasterizer_dispatch_grid : mapnik::noncopyable agg::trans_affine_translation recenter(-center.x, -center.y); double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0); double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2); + markers_placement_params params { bbox_, marker_trans_, spacing * scale_factor_, max_error, allow_overlap }; markers_placement_finder placement_finder( - placement_method, - path, - bbox_, - marker_trans_, - detector_, - spacing * scale_factor_, - max_error, - allow_overlap); + placement_method, path, detector_, params); double x, y, angle = .0; while (placement_finder.get_point(x, y, angle, ignore_placement)) { diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index ef38ad0e1..3a5921bbc 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.hpp @@ -117,15 +117,9 @@ struct vector_markers_rasterizer_dispatch : mapnik::noncopyable coord2d center = bbox_.center(); agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine tr = recenter * marker_trans_; + markers_placement_params params { bbox_, tr, spacing * scale_factor_, max_error, allow_overlap }; markers_placement_finder placement_finder( - placement_method, - path, - bbox_, - tr, - detector_, - spacing * scale_factor_, - max_error, - allow_overlap); + placement_method, path, detector_, params); double x, y, angle = .0; while (placement_finder.get_point(x, y, angle, ignore_placement)) { @@ -206,15 +200,9 @@ struct raster_markers_rasterizer_dispatch : mapnik::noncopyable bool ignore_placement = get(sym_, keys::ignore_placement, feature_, vars_, false); double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0); double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2); + markers_placement_params params { bbox_, marker_trans_, spacing * scale_factor_, max_error, allow_overlap }; markers_placement_finder placement_finder( - placement_method, - path, - bbox_, - marker_trans_, - detector_, - spacing * scale_factor_, - max_error, - allow_overlap); + placement_method, path, detector_, params); double x, y, angle = .0; while (placement_finder.get_point(x, y, angle, ignore_placement)) { diff --git a/include/mapnik/markers_placement.hpp b/include/mapnik/markers_placement.hpp index f58e1b0b2..6db046a33 100644 --- a/include/mapnik/markers_placement.hpp +++ b/include/mapnik/markers_placement.hpp @@ -67,13 +67,9 @@ public: markers_placement_finder(marker_placement_e placement_type, Locator &locator, - box2d const& size, - agg::trans_affine const& tr, Detector &detector, - double spacing, - double max_error, - bool allow_overlap) - : placement_(create(placement_type, locator, size, tr, detector, spacing, max_error, allow_overlap)) + markers_placement_params const& params) + : placement_(create(placement_type, locator, detector, params)) { } @@ -87,21 +83,13 @@ private: // Factory function for particular placement implementations. static markers_placement create(marker_placement_e placement_type, Locator &locator, - box2d const& size, - agg::trans_affine const& tr, Detector &detector, - double spacing, - double max_error, - bool allow_overlap) + markers_placement_params const& params) { static const std::map const& size, - agg::trans_affine const& tr, Detector &detector, - double spacing, - double max_error, - bool allow_overlap)>> factories = + markers_placement_params const& params)>> factories = { { MARKER_POINT_PLACEMENT, boost::value_factory>() }, { MARKER_INTERIOR_PLACEMENT, boost::value_factory>() }, @@ -109,7 +97,7 @@ private: { MARKER_VERTEX_FIRST_PLACEMENT, boost::value_factory>() }, { MARKER_VERTEX_LAST_PLACEMENT, boost::value_factory>() } }; - return factories.at(placement_type)(locator, size, tr, detector, spacing, max_error, allow_overlap); + return factories.at(placement_type)(locator, detector, params); } markers_placement placement_; diff --git a/include/mapnik/markers_placements/interior.hpp b/include/mapnik/markers_placements/interior.hpp index 02d998655..efd52d392 100644 --- a/include/mapnik/markers_placements/interior.hpp +++ b/include/mapnik/markers_placements/interior.hpp @@ -32,17 +32,8 @@ template class markers_interior_placement : public markers_point_placement { public: - markers_interior_placement( - Locator &locator, - box2d const& size, - agg::trans_affine const& tr, - Detector &detector, - double spacing, - double max_error, - bool allow_overlap) - : markers_point_placement( - locator, size, tr, detector, - spacing, max_error, allow_overlap) + markers_interior_placement(Locator &locator, Detector &detector, markers_placement_params const& params) + : markers_point_placement(locator, detector, params) { } @@ -79,7 +70,7 @@ public: box2d box = this->perform_transform(angle, x, y); - if (!this->allow_overlap_ && !this->detector_.has_placement(box)) + if (!this->params_.allow_overlap && !this->detector_.has_placement(box)) { return false; } diff --git a/include/mapnik/markers_placements/line.hpp b/include/mapnik/markers_placements/line.hpp index 782a4a04e..38d68f380 100644 --- a/include/mapnik/markers_placements/line.hpp +++ b/include/mapnik/markers_placements/line.hpp @@ -36,32 +36,18 @@ template class markers_line_placement : public markers_point_placement { public: - markers_line_placement(Locator &locator, - box2d const& size, - agg::trans_affine const& tr, - Detector &detector, - double spacing, - double max_error, - bool allow_overlap) - : markers_point_placement( - locator, size, tr, detector, - spacing, max_error, allow_overlap), - last_x(0.0), - last_y(0.0), - next_x(0.0), - next_y(0.0), - error_(0.0), - spacing_left_(0.0), - marker_nr_(0) + markers_line_placement(Locator &locator, Detector &detector, markers_placement_params const& params) + : markers_point_placement(locator, detector, params), + marker_width_((params.size * params.tr).width()), + last_x(0.0), + last_y(0.0), + next_x(0.0), + next_y(0.0), + error_(0.0), + spacing_left_(0.0), + marker_nr_(0) { - if (spacing >= 1) - { - this->spacing_ = spacing; - } - else - { - this->spacing_ = 100; - } + spacing_ = params.spacing < 1 ? 100 : params.spacing; rewind(); } @@ -103,31 +89,31 @@ public: { //First marker marker_nr_++; - this->spacing_left_ = this->spacing_ / 2; + spacing_left_ = spacing_ / 2; } else { - this->spacing_left_ = this->spacing_; + spacing_left_ = spacing_; } spacing_left_ -= error_; error_ = 0.0; - double max_err_allowed = this->max_error_ * this->spacing_; + double max_err_allowed = this->params_.max_error * spacing_; //Loop exits when a position is found or when no more segments are available while (true) { //Do not place markers too close to the beginning of a segment - if (spacing_left_ < this->marker_width_/2) + if (spacing_left_ < this->marker_width_ / 2) { - set_spacing_left(this->marker_width_/2); //Only moves forward + set_spacing_left(this->marker_width_ / 2); //Only moves forward } //Error for this marker is too large. Skip to the next position. if (std::fabs(error_) > max_err_allowed) { - while (this->error_ > this->spacing_) + while (this->error_ > spacing_) { - error_ -= this->spacing_; //Avoid moving backwards + error_ -= spacing_; //Avoid moving backwards } - spacing_left_ += this->spacing_ - this->error_; + spacing_left_ += spacing_ - this->error_; error_ = 0.0; } double dx = next_x - last_x; @@ -185,10 +171,10 @@ public: x = last_x + dx * (spacing_left_ / segment_length); y = last_y + dy * (spacing_left_ / segment_length); box2d box = this->perform_transform(angle, x, y); - if (!this->allow_overlap_ && !this->detector_.has_placement(box)) + if (!this->params_.allow_overlap && !this->detector_.has_placement(box)) { //10.0 is the approxmiate number of positions tried and choosen arbitrarily - set_spacing_left(spacing_left_ + this->spacing_ * this->max_error_ / 10.0); //Only moves forward + set_spacing_left(spacing_left_ + spacing_ * this->params_.max_error / 10.0); //Only moves forward continue; } if (!ignore_placement) @@ -206,6 +192,8 @@ private: double last_y; double next_x; double next_y; + double spacing_; + double marker_width_; // If a marker could not be placed at the exact point where it should // go the next marker's distance will be a bit lower. double error_; diff --git a/include/mapnik/markers_placements/point.hpp b/include/mapnik/markers_placements/point.hpp index 60ec39320..8af6f8ca5 100644 --- a/include/mapnik/markers_placements/point.hpp +++ b/include/mapnik/markers_placements/point.hpp @@ -23,7 +23,6 @@ #ifndef MAPNIK_MARKERS_PLACEMENTS_POINT_HPP #define MAPNIK_MARKERS_PLACEMENTS_POINT_HPP -#include #include #include "agg_basics.h" @@ -31,26 +30,23 @@ namespace mapnik { +struct markers_placement_params +{ + box2d const& size; + agg::trans_affine const& tr; + double spacing; + double max_error; + bool allow_overlap; +}; + template class markers_point_placement { public: - markers_point_placement( - Locator &locator, - box2d const& size, - agg::trans_affine const& tr, - Detector &detector, - double spacing, - double max_error, - bool allow_overlap) + markers_point_placement(Locator &locator, Detector &detector, markers_placement_params const& params) : locator_(locator), - size_(size), - tr_(tr), detector_(detector), - spacing_(spacing), - max_error_(max_error), - allow_overlap_(allow_overlap), - marker_width_((size_ * tr_).width()), + params_(params), done_(false) { rewind(); @@ -89,11 +85,9 @@ public: } angle = 0; - agg::trans_affine matrix = tr_; - matrix.translate(x,y); - box2d box = size_ * matrix; + box2d box = perform_transform(angle, x, y); - if (!allow_overlap_ && !detector_.has_placement(box)) + if (!params_.allow_overlap && !detector_.has_placement(box)) { return false; } @@ -109,24 +103,18 @@ public: protected: Locator &locator_; - box2d size_; - agg::trans_affine tr_; Detector &detector_; - double spacing_; - double max_error_; - bool allow_overlap_; - double marker_width_; + markers_placement_params const& params_; bool done_; // Rotates the size_ box and translates the position. box2d perform_transform(double angle, double dx, double dy) { - double x1 = size_.minx(); - double x2 = size_.maxx(); - double y1 = size_.miny(); - double y2 = size_.maxy(); - agg::trans_affine tr = tr_ * agg::trans_affine_rotation(angle) - .translate(dx, dy); + double x1 = params_.size.minx(); + double x2 = params_.size.maxx(); + double y1 = params_.size.miny(); + double y2 = params_.size.maxy(); + agg::trans_affine tr = params_.tr * agg::trans_affine_rotation(angle).translate(dx, dy); double xA = x1, yA = y1, xB = x2, yB = y1, xC = x2, yC = y2, diff --git a/include/mapnik/markers_placements/vertext_first.hpp b/include/mapnik/markers_placements/vertext_first.hpp index 57608fbdd..2c562a8f3 100644 --- a/include/mapnik/markers_placements/vertext_first.hpp +++ b/include/mapnik/markers_placements/vertext_first.hpp @@ -31,17 +31,8 @@ template class markers_vertex_first_placement : public markers_point_placement { public: - markers_vertex_first_placement( - Locator &locator, - box2d const& size, - agg::trans_affine const& tr, - Detector &detector, - double spacing, - double max_error, - bool allow_overlap) - : markers_point_placement( - locator, size, tr, detector, - spacing, max_error, allow_overlap) + markers_vertex_first_placement(Locator &locator, Detector &detector, markers_placement_params const& params) + : markers_point_placement(locator, detector, params) { } @@ -78,7 +69,7 @@ public: box2d box = this->perform_transform(angle, x, y); - if (!this->allow_overlap_ && !this->detector_.has_placement(box)) + if (!this->params_.allow_overlap && !this->detector_.has_placement(box)) { return false; } diff --git a/include/mapnik/markers_placements/vertext_last.hpp b/include/mapnik/markers_placements/vertext_last.hpp index 2ff1f740a..faad98a5e 100644 --- a/include/mapnik/markers_placements/vertext_last.hpp +++ b/include/mapnik/markers_placements/vertext_last.hpp @@ -31,17 +31,8 @@ template class markers_vertex_last_placement : public markers_point_placement { public: - markers_vertex_last_placement( - Locator &locator, - box2d const& size, - agg::trans_affine const& tr, - Detector &detector, - double spacing, - double max_error, - bool allow_overlap) - : markers_point_placement( - locator, size, tr, detector, - spacing, max_error, allow_overlap) + markers_vertex_last_placement(Locator &locator, Detector &detector, markers_placement_params const& params) + : markers_point_placement(locator, detector, params) { } @@ -83,7 +74,7 @@ public: box2d box = this->perform_transform(angle, x, y); - if (!this->allow_overlap_ && !this->detector_.has_placement(box)) + if (!this->params_.allow_overlap && !this->detector_.has_placement(box)) { return false; } diff --git a/src/cairo/process_markers_symbolizer.cpp b/src/cairo/process_markers_symbolizer.cpp index 07bd142ee..d782e499f 100644 --- a/src/cairo/process_markers_symbolizer.cpp +++ b/src/cairo/process_markers_symbolizer.cpp @@ -87,15 +87,9 @@ struct markers_dispatch : mapnik::noncopyable coord2d center = bbox_.center(); agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine tr = recenter * marker_trans_; + markers_placement_params params { bbox_, tr, spacing * scale_factor_, max_error, allow_overlap }; markers_placement_finder placement_finder( - placement_method, - path, - bbox_, - tr, - detector_, - spacing * scale_factor_, - max_error, - allow_overlap); + placement_method, path, detector_, params); double x, y, angle = .0; while (placement_finder.get_point(x, y, angle, ignore_placement)) { @@ -156,15 +150,9 @@ struct raster_markers_dispatch : mapnik::noncopyable bool allow_overlap = get(sym_, keys::allow_overlap, feature_, vars_, false); bool ignore_placement = get(sym_, keys::ignore_placement, feature_, vars_, false); box2d bbox_(0,0, src_.width(),src_.height()); + markers_placement_params params { bbox_, marker_trans_, spacing * scale_factor_, max_error, allow_overlap }; markers_placement_finder placement_finder( - placement_method, - path, - bbox_, - marker_trans_, - detector_, - spacing * scale_factor_, - max_error, - allow_overlap); + placement_method, path, detector_, params); double x, y, angle = .0; while (placement_finder.get_point(x, y, angle, ignore_placement)) {