chip away at complexity of marker_helpers.hpp
This commit is contained in:
parent
d111dcbed6
commit
40a1189357
4 changed files with 186 additions and 143 deletions
|
@ -60,11 +60,14 @@
|
|||
// stl
|
||||
#include <memory>
|
||||
#include <type_traits> // remove_reference
|
||||
#include <cmath>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct clip_poly_tag;
|
||||
|
||||
using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;
|
||||
|
||||
template <typename SvgRenderer, typename Detector, typename RendererContext>
|
||||
struct vector_markers_rasterizer_dispatch : mapnik::noncopyable
|
||||
{
|
||||
|
@ -80,7 +83,7 @@ struct vector_markers_rasterizer_dispatch : mapnik::noncopyable
|
|||
attribute_source_type const& attrs,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
markers_symbolizer const& sym,
|
||||
symbolizer_base const& sym,
|
||||
Detector & detector,
|
||||
double scale_factor,
|
||||
feature_impl & feature,
|
||||
|
@ -145,7 +148,7 @@ private:
|
|||
RasterizerType & ras_;
|
||||
box2d<double> const& bbox_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
markers_symbolizer const& sym_;
|
||||
symbolizer_base const& sym_;
|
||||
Detector & detector_;
|
||||
feature_impl & feature_;
|
||||
attributes const& vars_;
|
||||
|
@ -168,7 +171,7 @@ struct raster_markers_rasterizer_dispatch : mapnik::noncopyable
|
|||
|
||||
raster_markers_rasterizer_dispatch(image_data_32 const& src,
|
||||
agg::trans_affine const& marker_trans,
|
||||
markers_symbolizer const& sym,
|
||||
symbolizer_base const& sym,
|
||||
Detector & detector,
|
||||
double scale_factor,
|
||||
feature_impl & feature,
|
||||
|
@ -299,7 +302,7 @@ private:
|
|||
RasterizerType & ras_;
|
||||
image_data_32 const& src_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
markers_symbolizer const& sym_;
|
||||
symbolizer_base const& sym_;
|
||||
Detector & detector_;
|
||||
feature_impl & feature_;
|
||||
attributes const& vars_;
|
||||
|
@ -308,132 +311,24 @@ private:
|
|||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
void build_ellipse(T const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path)
|
||||
{
|
||||
double width = 0.0;
|
||||
double height = 0.0;
|
||||
if (has_key<double>(sym,keys::width) && has_key<double>(sym,keys::height))
|
||||
{
|
||||
width = get<double>(sym, keys::width, feature, vars, 0.0);
|
||||
height = get<double>(sym, keys::height, feature, vars, 0.0);
|
||||
}
|
||||
else if (has_key<double>(sym,keys::width))
|
||||
{
|
||||
width = height = get<double>(sym, keys::width, feature, vars, 0.0);
|
||||
}
|
||||
else if (has_key<double>(sym,keys::height))
|
||||
{
|
||||
width = height = get<double>(sym, keys::height, feature, vars, 0.0);
|
||||
}
|
||||
svg::svg_converter_type styled_svg(svg_path, marker_ellipse.attributes());
|
||||
styled_svg.push_attr();
|
||||
styled_svg.begin_path();
|
||||
agg::ellipse c(0, 0, width/2.0, height/2.0);
|
||||
styled_svg.storage().concat_path(c);
|
||||
styled_svg.end_path();
|
||||
styled_svg.pop_attr();
|
||||
double lox,loy,hix,hiy;
|
||||
styled_svg.bounding_rect(&lox, &loy, &hix, &hiy);
|
||||
styled_svg.set_dimensions(width,height);
|
||||
marker_ellipse.set_dimensions(width,height);
|
||||
marker_ellipse.set_bounding_box(lox,loy,hix,hiy);
|
||||
}
|
||||
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path);
|
||||
|
||||
template <typename Attr>
|
||||
bool push_explicit_style(Attr const& src, Attr & dst,
|
||||
markers_symbolizer const& sym,
|
||||
bool push_explicit_style(svg_attribute_type const& src,
|
||||
svg_attribute_type & dst,
|
||||
symbolizer_base const& sym,
|
||||
feature_impl & feature,
|
||||
attributes const& vars)
|
||||
{
|
||||
auto fill_color = get_optional<color>(sym, keys::fill, feature, vars);
|
||||
auto fill_opacity = get_optional<double>(sym, keys::fill_opacity, feature, vars);
|
||||
auto stroke_color = get_optional<color>(sym, keys::stroke, feature, vars);
|
||||
auto stroke_width = get_optional<double>(sym, keys::stroke_width, feature, vars);
|
||||
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
|
||||
if (fill_color ||
|
||||
fill_opacity ||
|
||||
stroke_color ||
|
||||
stroke_width ||
|
||||
stroke_opacity)
|
||||
{
|
||||
bool success = false;
|
||||
for(unsigned i = 0; i < src.size(); ++i)
|
||||
{
|
||||
success = true;
|
||||
dst.push_back(src[i]);
|
||||
mapnik::svg::path_attributes & attr = dst.last();
|
||||
if (attr.stroke_flag)
|
||||
{
|
||||
if (stroke_width)
|
||||
{
|
||||
attr.stroke_width = *stroke_width;
|
||||
}
|
||||
if (stroke_color)
|
||||
{
|
||||
color const& s_color = *stroke_color;
|
||||
attr.stroke_color = agg::rgba(s_color.red()/255.0,
|
||||
s_color.green()/255.0,
|
||||
s_color.blue()/255.0,
|
||||
s_color.alpha()/255.0);
|
||||
}
|
||||
if (stroke_opacity)
|
||||
{
|
||||
attr.stroke_opacity = *stroke_opacity;
|
||||
}
|
||||
}
|
||||
if (attr.fill_flag)
|
||||
{
|
||||
if (fill_color)
|
||||
{
|
||||
color const& f_color = *fill_color;
|
||||
attr.fill_color = agg::rgba(f_color.red()/255.0,
|
||||
f_color.green()/255.0,
|
||||
f_color.blue()/255.0,
|
||||
f_color.alpha()/255.0);
|
||||
}
|
||||
if (fill_opacity)
|
||||
{
|
||||
attr.fill_opacity = *fill_opacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
attributes const& vars);
|
||||
|
||||
template <typename T>
|
||||
void setup_transform_scaling(agg::trans_affine & tr,
|
||||
double svg_width,
|
||||
double svg_height,
|
||||
mapnik::feature_impl & feature,
|
||||
attributes const& vars,
|
||||
T const& sym)
|
||||
{
|
||||
double width = get<double>(sym, keys::width, feature, vars, 0.0);
|
||||
double height = get<double>(sym, keys::height, feature, vars, 0.0);
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
double sx = width/svg_width;
|
||||
double sy = height/svg_height;
|
||||
tr *= agg::trans_affine_scaling(sx,sy);
|
||||
}
|
||||
else if (width > 0)
|
||||
{
|
||||
double sx = width/svg_width;
|
||||
tr *= agg::trans_affine_scaling(sx);
|
||||
}
|
||||
else if (height > 0)
|
||||
{
|
||||
double sy = height/svg_height;
|
||||
tr *= agg::trans_affine_scaling(sy);
|
||||
}
|
||||
}
|
||||
symbolizer_base const& sym);
|
||||
|
||||
// Apply markers to a feature with multiple geometries
|
||||
template <typename Converter>
|
||||
void apply_markers_multi(feature_impl const& feature, attributes const& vars, Converter & converter, markers_symbolizer const& sym)
|
||||
void apply_markers_multi(feature_impl const& feature, attributes const& vars, Converter & converter, symbolizer_base const& sym)
|
||||
{
|
||||
std::size_t geom_count = feature.paths().size();
|
||||
if (geom_count == 1)
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <mapnik/renderer_common.hpp>
|
||||
#include <mapnik/svg/svg_storage.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||
#include <mapnik/vertex_converters.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
#include <mapnik/marker_helpers.hpp>
|
||||
|
@ -46,8 +45,6 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
|||
using raster_dispatch_type = T1;
|
||||
using renderer_context_type = T2;
|
||||
|
||||
using svg_attribute_type = agg::pod_bvector<path_attributes>;
|
||||
|
||||
std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
|
||||
bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, false);
|
||||
double offset = get<value_double>(sym, keys::offset, feature, common.vars_, 0.0);
|
||||
|
@ -96,13 +93,13 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
|||
snap_to_pixels,
|
||||
renderer_context);
|
||||
|
||||
vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_);
|
||||
using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type 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();
|
||||
|
@ -140,13 +137,13 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
|||
snap_to_pixels,
|
||||
renderer_context);
|
||||
|
||||
vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_);
|
||||
using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type 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();
|
||||
|
@ -183,13 +180,13 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
|||
common.vars_,
|
||||
renderer_context);
|
||||
|
||||
vertex_converter<raster_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_);
|
||||
using vertex_converter_type = vertex_converter<raster_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type 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)
|
||||
{
|
||||
|
|
|
@ -142,6 +142,7 @@ else: # unix, non-macos
|
|||
|
||||
source = Split(
|
||||
"""
|
||||
marker_helpers.cpp
|
||||
dasharray_parser.cpp
|
||||
expression_grammar.cpp
|
||||
fs.cpp
|
||||
|
|
150
src/marker_helpers.cpp
Normal file
150
src/marker_helpers.cpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/marker_helpers.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path)
|
||||
{
|
||||
double width = 0.0;
|
||||
double height = 0.0;
|
||||
if (has_key<double>(sym,keys::width) && has_key<double>(sym,keys::height))
|
||||
{
|
||||
width = get<double>(sym, keys::width, feature, vars, 0.0);
|
||||
height = get<double>(sym, keys::height, feature, vars, 0.0);
|
||||
}
|
||||
else if (has_key<double>(sym,keys::width))
|
||||
{
|
||||
width = height = get<double>(sym, keys::width, feature, vars, 0.0);
|
||||
}
|
||||
else if (has_key<double>(sym,keys::height))
|
||||
{
|
||||
width = height = get<double>(sym, keys::height, feature, vars, 0.0);
|
||||
}
|
||||
svg::svg_converter_type styled_svg(svg_path, marker_ellipse.attributes());
|
||||
styled_svg.push_attr();
|
||||
styled_svg.begin_path();
|
||||
agg::ellipse c(0, 0, width/2.0, height/2.0);
|
||||
styled_svg.storage().concat_path(c);
|
||||
styled_svg.end_path();
|
||||
styled_svg.pop_attr();
|
||||
double lox,loy,hix,hiy;
|
||||
styled_svg.bounding_rect(&lox, &loy, &hix, &hiy);
|
||||
styled_svg.set_dimensions(width,height);
|
||||
marker_ellipse.set_dimensions(width,height);
|
||||
marker_ellipse.set_bounding_box(lox,loy,hix,hiy);
|
||||
}
|
||||
|
||||
bool push_explicit_style(svg_attribute_type const& src,
|
||||
svg_attribute_type & dst,
|
||||
symbolizer_base const& sym,
|
||||
feature_impl & feature,
|
||||
attributes const& vars)
|
||||
{
|
||||
auto fill_color = get_optional<color>(sym, keys::fill, feature, vars);
|
||||
auto fill_opacity = get_optional<double>(sym, keys::fill_opacity, feature, vars);
|
||||
auto stroke_color = get_optional<color>(sym, keys::stroke, feature, vars);
|
||||
auto stroke_width = get_optional<double>(sym, keys::stroke_width, feature, vars);
|
||||
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
|
||||
if (fill_color ||
|
||||
fill_opacity ||
|
||||
stroke_color ||
|
||||
stroke_width ||
|
||||
stroke_opacity)
|
||||
{
|
||||
bool success = false;
|
||||
for(unsigned i = 0; i < src.size(); ++i)
|
||||
{
|
||||
success = true;
|
||||
dst.push_back(src[i]);
|
||||
mapnik::svg::path_attributes & attr = dst.last();
|
||||
if (attr.stroke_flag)
|
||||
{
|
||||
if (stroke_width)
|
||||
{
|
||||
attr.stroke_width = *stroke_width;
|
||||
}
|
||||
if (stroke_color)
|
||||
{
|
||||
color const& s_color = *stroke_color;
|
||||
attr.stroke_color = agg::rgba(s_color.red()/255.0,
|
||||
s_color.green()/255.0,
|
||||
s_color.blue()/255.0,
|
||||
s_color.alpha()/255.0);
|
||||
}
|
||||
if (stroke_opacity)
|
||||
{
|
||||
attr.stroke_opacity = *stroke_opacity;
|
||||
}
|
||||
}
|
||||
if (attr.fill_flag)
|
||||
{
|
||||
if (fill_color)
|
||||
{
|
||||
color const& f_color = *fill_color;
|
||||
attr.fill_color = agg::rgba(f_color.red()/255.0,
|
||||
f_color.green()/255.0,
|
||||
f_color.blue()/255.0,
|
||||
f_color.alpha()/255.0);
|
||||
}
|
||||
if (fill_opacity)
|
||||
{
|
||||
attr.fill_opacity = *fill_opacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setup_transform_scaling(agg::trans_affine & tr,
|
||||
double svg_width,
|
||||
double svg_height,
|
||||
mapnik::feature_impl & feature,
|
||||
attributes const& vars,
|
||||
symbolizer_base const& sym)
|
||||
{
|
||||
double width = get<double>(sym, keys::width, feature, vars, 0.0);
|
||||
double height = get<double>(sym, keys::height, feature, vars, 0.0);
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
double sx = width/svg_width;
|
||||
double sy = height/svg_height;
|
||||
tr *= agg::trans_affine_scaling(sx,sy);
|
||||
}
|
||||
else if (width > 0)
|
||||
{
|
||||
double sx = width/svg_width;
|
||||
tr *= agg::trans_affine_scaling(sx);
|
||||
}
|
||||
else if (height > 0)
|
||||
{
|
||||
double sy = height/svg_height;
|
||||
tr *= agg::trans_affine_scaling(sy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace mapnik
|
Loading…
Add table
Reference in a new issue