new dot symbolizer for fast rendering of points - refs #1651 mapbox/mapnik-vector-tile#62 #2612

This commit is contained in:
Dane Springmeyer 2014-12-16 21:45:56 -08:00
parent 1dfdfb3b22
commit 569a539518
15 changed files with 237 additions and 1 deletions

View file

@ -8,6 +8,7 @@ For a complete change history, see the git log.
## 3.0.0 ## 3.0.0
- Added new and experimental `dot` symbolizer for fast rendering of points
- Improved support for International Text (now uses harfbuzz library for text shaping) - Improved support for International Text (now uses harfbuzz library for text shaping)
- Uses latest c++11 features for better performance (especially map loading) - Uses latest c++11 features for better performance (especially map loading)
- Expressions everywhere: all symbolizer properties can now be data driven expressions (with the exception of `face-name` and `fontset-name` on the `TextSymbolizer`). - Expressions everywhere: all symbolizer properties can now be data driven expressions (with the exception of `face-name` and `fontset-name` on the `TextSymbolizer`).

View file

@ -48,6 +48,7 @@ namespace agg
void approximation_scale(double scale); void approximation_scale(double scale);
void rewind(unsigned path_id); void rewind(unsigned path_id);
unsigned vertex(double* x, double* y); unsigned vertex(double* x, double* y);
unsigned num_steps() { return m_num; }
private: private:
void calc_num_steps(); void calc_num_steps();

View file

@ -122,6 +122,9 @@ public:
void process(debug_symbolizer const& sym, void process(debug_symbolizer const& sym,
feature_impl & feature, feature_impl & feature,
proj_transform const& prj_trans); proj_transform const& prj_trans);
void process(dot_symbolizer const& sym,
mapnik::feature_impl & feature,
proj_transform const& prj_trans);
inline bool process(rule::symbolizers const&, inline bool process(rule::symbolizers const&,
mapnik::feature_impl&, mapnik::feature_impl&,

View file

@ -149,6 +149,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base {};
struct MAPNIK_DECL building_symbolizer : public symbolizer_base {}; struct MAPNIK_DECL building_symbolizer : public symbolizer_base {};
struct MAPNIK_DECL group_symbolizer : public symbolizer_base {}; struct MAPNIK_DECL group_symbolizer : public symbolizer_base {};
struct MAPNIK_DECL debug_symbolizer : public symbolizer_base {}; struct MAPNIK_DECL debug_symbolizer : public symbolizer_base {};
struct MAPNIK_DECL dot_symbolizer : public symbolizer_base {};
// symbolizer // symbolizer
using symbolizer = util::variant<point_symbolizer, using symbolizer = util::variant<point_symbolizer,
@ -162,7 +163,8 @@ using symbolizer = util::variant<point_symbolizer,
building_symbolizer, building_symbolizer,
markers_symbolizer, markers_symbolizer,
group_symbolizer, group_symbolizer,
debug_symbolizer>; debug_symbolizer,
dot_symbolizer>;
} }

View file

@ -120,6 +120,12 @@ struct symbolizer_traits<debug_symbolizer>
static char const* name() { return "DebugSymbolizer";} static char const* name() { return "DebugSymbolizer";}
}; };
template<>
struct symbolizer_traits<dot_symbolizer>
{
static char const* name() { return "DotSymbolizer";}
};
// symbolizer name impl // symbolizer name impl
namespace detail { namespace detail {

View file

@ -0,0 +1,105 @@
/*****************************************************************************
*
* 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/feature.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/symbolizer_keys.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/vertex.hpp>
#include <mapnik/renderer_common.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/image_compositing.hpp>
// agg
#include "agg_ellipse.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_color_rgba.h"
#include "agg_renderer_base.h"
namespace mapnik {
template <typename T0, typename T1>
void agg_renderer<T0,T1>::process(dot_symbolizer const& sym,
mapnik::feature_impl & feature,
proj_transform const& prj_trans)
{
double width = 0.0;
double height = 0.0;
bool has_width = has_key(sym,keys::width);
bool has_height = has_key(sym,keys::height);
if (has_width && has_height)
{
width = get<double>(sym, keys::width, feature, common_.vars_, 0.0);
height = get<double>(sym, keys::height, feature, common_.vars_, 0.0);
}
else if (has_width)
{
width = height = get<double>(sym, keys::width, feature, common_.vars_, 0.0);
}
else if (has_height)
{
width = height = get<double>(sym, keys::height, feature, common_.vars_, 0.0);
}
double rx = width/2.0;
double ry = height/2.0;
double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0);
color const& fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128));
ras_ptr->reset();
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(),current_buffer_->width() * 4);
using blender_type = agg::comp_op_adaptor_rgba_pre<agg::rgba8, agg::order_rgba>;
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
pixfmt_comp_type pixf(buf);
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over)));
renderer_base renb(pixf);
renderer_type ren(renb);
agg::scanline_u8 sl;
ren.color(agg::rgba8_pre(fill.red(), fill.green(), fill.blue(), int(fill.alpha() * opacity)));
agg::ellipse el(0,0,rx,ry);
unsigned num_steps = el.num_steps();
for (geometry_type const& geom : feature.paths()) {
double x,y,z = 0;
unsigned cmd = 1;
geom.rewind(0);
while ((cmd = geom.vertex(&x, &y)) != mapnik::SEG_END) {
if (cmd == SEG_CLOSE) continue;
prj_trans.backward(x,y,z);
common_.t_.forward(&x,&y);
el.init(x,y,rx,ry,num_steps);
ras_ptr->add_path(el);
agg::render_scanlines(*ras_ptr, sl, ren);
}
}
}
template void agg_renderer<image_32>::process(dot_symbolizer const&,
mapnik::feature_impl &,
proj_transform const&);
}

View file

@ -301,6 +301,7 @@ for cpp in enabled_imaging_libraries:
source += Split( source += Split(
""" """
agg/agg_renderer.cpp agg/agg_renderer.cpp
agg/process_dot_symbolizer.cpp
agg/process_building_symbolizer.cpp agg/process_building_symbolizer.cpp
agg/process_line_symbolizer.cpp agg/process_line_symbolizer.cpp
agg/process_line_pattern_symbolizer.cpp agg/process_line_pattern_symbolizer.cpp

View file

@ -119,6 +119,7 @@ private:
void parse_markers_symbolizer(rule & rule, xml_node const& node); void parse_markers_symbolizer(rule & rule, xml_node const& node);
void parse_group_symbolizer(rule &rule, xml_node const& node); void parse_group_symbolizer(rule &rule, xml_node const& node);
void parse_debug_symbolizer(rule & rule, xml_node const& node); void parse_debug_symbolizer(rule & rule, xml_node const& node);
void parse_dot_symbolizer(rule & rule, xml_node const& node);
void parse_group_rule(group_symbolizer_properties &prop, xml_node const& node); void parse_group_rule(group_symbolizer_properties &prop, xml_node const& node);
void parse_simple_layout(group_symbolizer_properties &prop, xml_node const& node); void parse_simple_layout(group_symbolizer_properties &prop, xml_node const& node);
void parse_pair_layout(group_symbolizer_properties &prop, xml_node const& node); void parse_pair_layout(group_symbolizer_properties &prop, xml_node const& node);
@ -853,6 +854,11 @@ void map_parser::parse_symbolizers(rule & rule, xml_node const & node)
parse_debug_symbolizer(rule, sym_node); parse_debug_symbolizer(rule, sym_node);
sym_node.set_processed(true); sym_node.set_processed(true);
break; break;
case name2int("DotSymbolizer"):
parse_dot_symbolizer(rule, sym_node);
sym_node.set_processed(true);
break;
default: default:
break; break;
} }
@ -908,6 +914,25 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & node)
} }
} }
void map_parser::parse_dot_symbolizer(rule & rule, xml_node const & node)
{
try
{
dot_symbolizer sym;
set_symbolizer_property<symbolizer_base,color>(sym, keys::fill, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::opacity, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::width, node);
set_symbolizer_property<symbolizer_base,double>(sym, keys::height, node);
set_symbolizer_property<symbolizer_base,composite_mode_e>(sym, keys::comp_op, node);
rule.append(std::move(sym));
}
catch (config_error const& ex)
{
ex.append_context(node);
throw;
}
}
void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node) void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
{ {
try try

View file

@ -0,0 +1,33 @@
{
"keys": [
""
],
"data": {},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]
}

View file

@ -0,0 +1,33 @@
{
"keys": [
""
],
"data": {},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

View file

@ -0,0 +1,26 @@
<Map
srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
background-color="white">
<Style name="dots">
<Rule>
<DotSymbolizer height="[height]" width="[width]" fill="[fill]" opacity="[opacity]"/>
</Rule>
</Style>
<Layer name="layer" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>dots</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="extent">0,0,5,5</Parameter>
<Parameter name="inline">
fill, opacity,height, width, wkt
green,.5, 40, 40, "POINT(2.5 2.5)"
red, .5, 20, 20, "MULTIPOINT((2 2.5),(2.5 2.5),(3 2.5))"
blue, .5, 45, 45, "POLYGON((1 1,4 1,4 4,1 4,1 1))"
red, .5, 3, 3, "LINESTRING(3 2.5,3.0472522909029145 2.5549083791557554,3.088039946704745 2.6192015984770367,3.120968717931644 2.692088134329871,3.1447426958020195 2.7725928396160553,3.1581869214177796 2.859569153953152,3.1602684919277424 2.9517139787160285,3.150115859191815 3.0475850341520374,3.1270360384124487 3.1456204818095705,3.090529469857131 3.2441605641461093,3.0403023058681398 3.3414709848078967,2.9762759274968564 3.435767728064507,2.898593529924341 3.525242994563949,2.8076236529182754 3.6080919132297717,2.7039605714802892 3.6825396759861526,2.588421502084629 3.7468687332550683,2.4620406210083243 3.799445683953957,2.3260599327010416 3.838747494110833,2.181917067429678 3.863386683229473,2.0312301280479197 3.872135127146751,1.8757797451792864 3.8639461402385225,1.7174885378702207 3.8379745183057543,1.5583982123914466 3.7935942461113443,1.4006445648882897 3.7304136000915884,1.246430683579882 3.648287406936956,1.0979986727928661 3.547326252181924,0.9576002439358948 3.4279024692786355,0.8274665372684367 3.290652778432585,0.7097775527295491 3.136477485296219,0.606631577958298 2.966536191967265,0.5200150067991092 2.7822400161197343,0.45177294193977735 2.5852403579882455,0.4035809708310185 2.3774142988020817,0.3769184946959401 2.160846757592015,0.37304397632518604 1.9378095755409703,0.3929724535957084 1.7107377376983552,0.4374556424314622 1.4822029804218395,0.5069649254805411 1.2548850688650404,0.6016774914054002 1.0315410617374736,0.7214658547096571 0.8149729099992633,0.8658909478409702 0.6079937617301794,1.0341989363401651 0.4133933667857521,1.2253218645141815 0.23390299172467044,1.437882193988065 0.07216026761394456,1.6702012510582676 -0.06932559950169326,1.920311551565356 -0.18820782357901678,2.185972924581849 -0.2823348101737011,2.4646923091307618 -0.34978128405768727,2.753747051974397 -0.38887736562393815,3.0502114897965984 -0.3982352072417812,3.350986556389679 -0.37677282398941525,3.6528321152745926 -0.3237347810995832,3.9524016810311693 -0.2387094327324748,4.246279158964359 -0.12164244300528804,4.531017203016431 0.027153639820840958,4.803176766446595 0.2069939418962261,5.0593673990838255 0.416820095021341,5.2962878292111855 0.6552034322979141,5.510766357600486 0.9203525899932274,5.6998005860669245 1.2101255063356857,5.860596003276281 1.5220457563037595,5.990602956471176 1.8533231098340628,6.087551549283583 2.200878149857013,6.149484022799466 2.5613707367678797,6.1747841994053125 2.9312320579468265,6.162203596480088 3.306699955329308,6.110883849442411 3.683857181350839,6.02037512070598 4.058672194373903,5.890650212364317 4.427042069440575,5.722114145495159 4.78483706933339,5.515609017373219 5.127946394875156,5.272413999093365 5.4523246125098,4.994240389582243 5.754038241781528,4.683221697131584 6.029311975608545,4.34189877581244 6.2745740024088335,3.9732001007988598 6.486499901292641,3.5804173231036964 6.662054589735392,3.16717629986471 6.798531817364951,2.737403850475655 6.893590719648262,2.2952905409040607 6.945288971186986,1.8452498478612391 6.952112109805218,1.3918741005021504 6.912998639345142,0.9398876394743532 6.827360560726954,0.4940976708866134 6.695099026966764,0.05934332565157785 6.516614868014918,-0.3595565377529124 6.292813784961579,-0.7578562271360596 6.0251060697957435,-1.1309362311473898 5.715400765898583,-1.474355768902115 5.3660942451696325,-1.783904285743506 4.980053239466529,-2.055651309423385 4.560592426208784,-2.285994090762115 4.1114467298642285,-2.4717024691612375 3.636738561911254,-2.6099604260809084 3.1409402810613676,-2.698403818583074 2.6288322123574606,-2.7351538200309866 2.105456617575501,-2.718845635708872 1.5760680595181986,-2.648652107097507 1.0460806487014485,-2.524301869365668 0.5210127020395867,-2.3460917818082168 0.006429378924498685)"
</Parameter>
</Datasource>
</Layer>
</Map>