Merge pull request #2955 from mapnik/offset_converter-fix
Offset converter fix
This commit is contained in:
commit
714b88d244
4 changed files with 73 additions and 27 deletions
|
@ -53,7 +53,7 @@ struct offset_converter
|
||||||
, pre_first_(vertex2d::no_init)
|
, pre_first_(vertex2d::no_init)
|
||||||
, pre_(vertex2d::no_init)
|
, pre_(vertex2d::no_init)
|
||||||
, cur_(vertex2d::no_init)
|
, cur_(vertex2d::no_init)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
enum status
|
enum status
|
||||||
{
|
{
|
||||||
|
@ -299,36 +299,51 @@ private:
|
||||||
vertex2d v1(vertex2d::no_init);
|
vertex2d v1(vertex2d::no_init);
|
||||||
vertex2d v2(vertex2d::no_init);
|
vertex2d v2(vertex2d::no_init);
|
||||||
vertex2d w(vertex2d::no_init);
|
vertex2d w(vertex2d::no_init);
|
||||||
|
vertex2d start(vertex2d::no_init);
|
||||||
vertex2d start_v2(vertex2d::no_init);
|
vertex2d start_v2(vertex2d::no_init);
|
||||||
std::vector<vertex2d> points;
|
std::vector<vertex2d> points;
|
||||||
std::vector<vertex2d> close_points;
|
std::vector<vertex2d> close_points;
|
||||||
bool is_polygon = false;
|
bool is_polygon = false;
|
||||||
std::size_t cpt = 0;
|
std::size_t cpt = 0;
|
||||||
v0.cmd = geom_.vertex(&v0.x, &v0.y);
|
v0.cmd = geom_.vertex(&v0.x, &v0.y);
|
||||||
v1.x = v0.x;
|
v1 = v0;
|
||||||
v1.y = v0.y;
|
|
||||||
v1.cmd = v0.cmd;
|
|
||||||
// PUSH INITIAL
|
// PUSH INITIAL
|
||||||
points.push_back(vertex2d(v0.x, v0.y, v0.cmd));
|
points.push_back(v0);
|
||||||
if (v0.cmd == SEG_END) // not enough vertices in source
|
if (v0.cmd == SEG_END) // not enough vertices in source
|
||||||
{
|
{
|
||||||
return status_ = process;
|
return status_ = process;
|
||||||
}
|
}
|
||||||
|
start = v0;
|
||||||
while ((v0.cmd = geom_.vertex(&v0.x, &v0.y)) != SEG_END)
|
while ((v0.cmd = geom_.vertex(&v0.x, &v0.y)) != SEG_END)
|
||||||
{
|
{
|
||||||
points.push_back(vertex2d(v0.x, v0.y, v0.cmd));
|
|
||||||
if (v0.cmd == SEG_CLOSE)
|
if (v0.cmd == SEG_CLOSE)
|
||||||
{
|
{
|
||||||
is_polygon = true;
|
is_polygon = true;
|
||||||
close_points.push_back(vertex2d(v1.x, v1.y, v1.cmd));
|
auto & prev = points.back();
|
||||||
|
if (prev.x == start.x && prev.y == start.y)
|
||||||
|
{
|
||||||
|
prev.x = v0.x; // hack
|
||||||
|
prev.y = v0.y;
|
||||||
|
prev.cmd = SEG_CLOSE; // account for dupes (line_to(move_to) + close_path) in agg poly clipper
|
||||||
|
std::size_t size = points.size();
|
||||||
|
if (size > 1) close_points.push_back(points[size - 2]);
|
||||||
|
else close_points.push_back(prev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close_points.push_back(v1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v1.x = v0.x;
|
else if (v0.cmd == SEG_MOVETO)
|
||||||
v1.y = v0.y;
|
{
|
||||||
v1.cmd = v0.cmd;
|
start = v0;
|
||||||
|
}
|
||||||
|
v1 = v0;
|
||||||
|
points.push_back(v0);
|
||||||
}
|
}
|
||||||
// Push SEG_END
|
// Push SEG_END
|
||||||
points.push_back(vertex2d(v0.x, v0.y, v0.cmd));
|
points.push_back(vertex2d(v0.x,v0.y,SEG_END));
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
v1 = points[i++];
|
v1 = points[i++];
|
||||||
v2 = points[i++];
|
v2 = points[i++];
|
||||||
|
@ -375,11 +390,11 @@ private:
|
||||||
{
|
{
|
||||||
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
|
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
|
||||||
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
|
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
|
||||||
|
|
||||||
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
||||||
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
|
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
|
||||||
joint_angle = std::fmod(joint_angle, 2 * M_PI);
|
joint_angle = std::fmod(joint_angle, 2 * M_PI);
|
||||||
|
|
||||||
if (offset_ > 0.0)
|
if (offset_ > 0.0)
|
||||||
{
|
{
|
||||||
joint_angle = 2 * M_PI - joint_angle;
|
joint_angle = 2 * M_PI - joint_angle;
|
||||||
|
@ -390,7 +405,7 @@ private:
|
||||||
if (std::abs(joint_angle) > M_PI)
|
if (std::abs(joint_angle) > M_PI)
|
||||||
{
|
{
|
||||||
curve_angle = explement_reflex_angle(angle_b - angle_a);
|
curve_angle = explement_reflex_angle(angle_b - angle_a);
|
||||||
// Bulge steps should be determined by the inverse of the joint angle.
|
// Bulge steps should be determined by the inverse of the joint angle.
|
||||||
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
|
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
|
||||||
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
|
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
|
||||||
}
|
}
|
||||||
|
@ -470,7 +485,7 @@ private:
|
||||||
v_y1y0 = -v_y1y2;
|
v_y1y0 = -v_y1y2;
|
||||||
// Calculate new angle_a
|
// Calculate new angle_a
|
||||||
angle_a = std::atan2(v_y1y2, v_x1x2);
|
angle_a = std::atan2(v_y1y2, v_x1x2);
|
||||||
|
|
||||||
// Calculate the new vector
|
// Calculate the new vector
|
||||||
v_x1x2 = v2.x - v1.x;
|
v_x1x2 = v2.x - v1.x;
|
||||||
v_y1y2 = v2.y - v1.y;
|
v_y1y2 = v2.y - v1.y;
|
||||||
|
@ -479,11 +494,11 @@ private:
|
||||||
|
|
||||||
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
|
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
|
||||||
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
|
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
|
||||||
|
|
||||||
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
||||||
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
|
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
|
||||||
joint_angle = std::fmod(joint_angle, 2 * M_PI);
|
joint_angle = std::fmod(joint_angle, 2 * M_PI);
|
||||||
|
|
||||||
if (offset_ > 0.0)
|
if (offset_ > 0.0)
|
||||||
{
|
{
|
||||||
joint_angle = 2 * M_PI - joint_angle;
|
joint_angle = 2 * M_PI - joint_angle;
|
||||||
|
@ -494,7 +509,7 @@ private:
|
||||||
if (std::abs(joint_angle) > M_PI)
|
if (std::abs(joint_angle) > M_PI)
|
||||||
{
|
{
|
||||||
curve_angle = explement_reflex_angle(angle_b - angle_a);
|
curve_angle = explement_reflex_angle(angle_b - angle_a);
|
||||||
// Bulge steps should be determined by the inverse of the joint angle.
|
// Bulge steps should be determined by the inverse of the joint angle.
|
||||||
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
|
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
|
||||||
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
|
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <mapnik/vertex_processor.hpp>
|
#include <mapnik/vertex_processor.hpp>
|
||||||
#include <mapnik/renderer_common/clipping_extent.hpp>
|
#include <mapnik/renderer_common/clipping_extent.hpp>
|
||||||
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
||||||
|
#include <mapnik/geometry_type.hpp>
|
||||||
// agg
|
// agg
|
||||||
#include "agg_basics.h"
|
#include "agg_basics.h"
|
||||||
#include "agg_rendering_buffer.h"
|
#include "agg_rendering_buffer.h"
|
||||||
|
@ -164,12 +165,19 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
|
||||||
rasterizer_type ras(ren);
|
rasterizer_type ras(ren);
|
||||||
set_join_caps_aa(sym, ras, feature, common_.vars_);
|
set_join_caps_aa(sym, ras, feature, common_.vars_);
|
||||||
|
|
||||||
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
|
using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag,
|
||||||
affine_transform_tag,
|
affine_transform_tag,
|
||||||
simplify_tag, smooth_tag,
|
simplify_tag, smooth_tag,
|
||||||
offset_transform_tag>;
|
offset_transform_tag>;
|
||||||
vertex_converter_type converter(clip_box,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
vertex_converter_type converter(clip_box,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
||||||
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
|
if (clip)
|
||||||
|
{
|
||||||
|
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
|
||||||
|
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
|
||||||
|
converter.template set<clip_poly_tag>();
|
||||||
|
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
|
||||||
|
converter.template set<clip_line_tag>();
|
||||||
|
}
|
||||||
converter.set<transform_tag>(); // always transform
|
converter.set<transform_tag>(); // always transform
|
||||||
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
||||||
converter.set<affine_transform_tag>(); // optional affine transform
|
converter.set<affine_transform_tag>(); // optional affine transform
|
||||||
|
@ -183,14 +191,20 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
|
using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag,
|
||||||
affine_transform_tag,
|
affine_transform_tag,
|
||||||
simplify_tag, smooth_tag,
|
simplify_tag, smooth_tag,
|
||||||
offset_transform_tag,
|
offset_transform_tag,
|
||||||
dash_tag, stroke_tag>;
|
dash_tag, stroke_tag>;
|
||||||
vertex_converter_type converter(clip_box, sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
vertex_converter_type converter(clip_box, sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
||||||
|
if (clip)
|
||||||
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
|
{
|
||||||
|
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
|
||||||
|
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
|
||||||
|
converter.template set<clip_poly_tag>();
|
||||||
|
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
|
||||||
|
converter.template set<clip_line_tag>();
|
||||||
|
}
|
||||||
converter.set<transform_tag>(); // always transform
|
converter.set<transform_tag>(); // always transform
|
||||||
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
||||||
converter.set<affine_transform_tag>(); // optional affine transform
|
converter.set<affine_transform_tag>(); // optional affine transform
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <mapnik/vertex_converters.hpp>
|
#include <mapnik/vertex_converters.hpp>
|
||||||
#include <mapnik/vertex_processor.hpp>
|
#include <mapnik/vertex_processor.hpp>
|
||||||
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
||||||
|
#include <mapnik/geometry_type.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
@ -82,6 +83,7 @@ void cairo_renderer<T>::process(line_symbolizer const& sym,
|
||||||
clipping_extent.pad(padding);
|
clipping_extent.pad(padding);
|
||||||
}
|
}
|
||||||
using vertex_converter_type = vertex_converter<clip_line_tag,
|
using vertex_converter_type = vertex_converter<clip_line_tag,
|
||||||
|
clip_poly_tag,
|
||||||
transform_tag,
|
transform_tag,
|
||||||
affine_transform_tag,
|
affine_transform_tag,
|
||||||
simplify_tag, smooth_tag,
|
simplify_tag, smooth_tag,
|
||||||
|
@ -89,7 +91,14 @@ void cairo_renderer<T>::process(line_symbolizer const& sym,
|
||||||
|
|
||||||
vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
||||||
|
|
||||||
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
|
if (clip)
|
||||||
|
{
|
||||||
|
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
|
||||||
|
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
|
||||||
|
converter.template set<clip_poly_tag>();
|
||||||
|
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
|
||||||
|
converter.template set<clip_line_tag>();
|
||||||
|
}
|
||||||
converter.set<transform_tag>(); // always transform
|
converter.set<transform_tag>(); // always transform
|
||||||
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
||||||
converter.set<affine_transform_tag>(); // optional affine transform
|
converter.set<affine_transform_tag>(); // optional affine transform
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <mapnik/vertex_converters.hpp>
|
#include <mapnik/vertex_converters.hpp>
|
||||||
#include <mapnik/vertex_processor.hpp>
|
#include <mapnik/vertex_processor.hpp>
|
||||||
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
||||||
|
#include <mapnik/geometry_type.hpp>
|
||||||
// agg
|
// agg
|
||||||
#include "agg_rasterizer_scanline_aa.h"
|
#include "agg_rasterizer_scanline_aa.h"
|
||||||
#include "agg_renderer_scanline.h"
|
#include "agg_renderer_scanline.h"
|
||||||
|
@ -89,14 +90,21 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
|
||||||
padding *= common_.scale_factor_;
|
padding *= common_.scale_factor_;
|
||||||
clipping_extent.pad(padding);
|
clipping_extent.pad(padding);
|
||||||
}
|
}
|
||||||
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
|
using vertex_converter_type = vertex_converter<clip_line_tag, clip_poly_tag, transform_tag,
|
||||||
affine_transform_tag,
|
affine_transform_tag,
|
||||||
simplify_tag, smooth_tag,
|
simplify_tag, smooth_tag,
|
||||||
offset_transform_tag,
|
offset_transform_tag,
|
||||||
dash_tag, stroke_tag>;
|
dash_tag, stroke_tag>;
|
||||||
|
|
||||||
vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
vertex_converter_type converter(clipping_extent,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
||||||
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
|
if (clip)
|
||||||
|
{
|
||||||
|
geometry::geometry_types type = geometry::geometry_type(feature.get_geometry());
|
||||||
|
if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
|
||||||
|
converter.template set<clip_poly_tag>();
|
||||||
|
else if (type == geometry::geometry_types::LineString || type == geometry::geometry_types::MultiLineString)
|
||||||
|
converter.template set<clip_line_tag>();
|
||||||
|
}
|
||||||
converter.set<transform_tag>(); // always transform
|
converter.set<transform_tag>(); // always transform
|
||||||
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
||||||
converter.set<affine_transform_tag>(); // optional affine transform
|
converter.set<affine_transform_tag>(); // optional affine transform
|
||||||
|
|
Loading…
Reference in a new issue