new dot symbolizer for fast rendering of points - refs #1651 mapbox/mapnik-vector-tile#62 #2612
This commit is contained in:
parent
17d3bd8a9d
commit
387b8f85d5
15 changed files with 237 additions and 1 deletions
|
@ -8,6 +8,7 @@ For a complete change history, see the git log.
|
|||
|
||||
## 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)
|
||||
- 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`).
|
||||
|
|
1
deps/agg/include/agg_ellipse.h
vendored
1
deps/agg/include/agg_ellipse.h
vendored
|
@ -48,6 +48,7 @@ namespace agg
|
|||
void approximation_scale(double scale);
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
unsigned num_steps() { return m_num; }
|
||||
|
||||
private:
|
||||
void calc_num_steps();
|
||||
|
|
|
@ -122,6 +122,9 @@ public:
|
|||
void process(debug_symbolizer const& sym,
|
||||
feature_impl & feature,
|
||||
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&,
|
||||
mapnik::feature_impl&,
|
||||
|
|
|
@ -149,6 +149,7 @@ struct MAPNIK_DECL raster_symbolizer : public symbolizer_base {};
|
|||
struct MAPNIK_DECL building_symbolizer : public symbolizer_base {};
|
||||
struct MAPNIK_DECL group_symbolizer : public symbolizer_base {};
|
||||
struct MAPNIK_DECL debug_symbolizer : public symbolizer_base {};
|
||||
struct MAPNIK_DECL dot_symbolizer : public symbolizer_base {};
|
||||
|
||||
// symbolizer
|
||||
using symbolizer = util::variant<point_symbolizer,
|
||||
|
@ -162,7 +163,8 @@ using symbolizer = util::variant<point_symbolizer,
|
|||
building_symbolizer,
|
||||
markers_symbolizer,
|
||||
group_symbolizer,
|
||||
debug_symbolizer>;
|
||||
debug_symbolizer,
|
||||
dot_symbolizer>;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,12 @@ struct symbolizer_traits<debug_symbolizer>
|
|||
static char const* name() { return "DebugSymbolizer";}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct symbolizer_traits<dot_symbolizer>
|
||||
{
|
||||
static char const* name() { return "DotSymbolizer";}
|
||||
};
|
||||
|
||||
// symbolizer name impl
|
||||
namespace detail {
|
||||
|
||||
|
|
105
src/agg/process_dot_symbolizer.cpp
Normal file
105
src/agg/process_dot_symbolizer.cpp
Normal 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&);
|
||||
|
||||
}
|
|
@ -301,6 +301,7 @@ for cpp in enabled_imaging_libraries:
|
|||
source += Split(
|
||||
"""
|
||||
agg/agg_renderer.cpp
|
||||
agg/process_dot_symbolizer.cpp
|
||||
agg/process_building_symbolizer.cpp
|
||||
agg/process_line_symbolizer.cpp
|
||||
agg/process_line_pattern_symbolizer.cpp
|
||||
|
|
|
@ -119,6 +119,7 @@ private:
|
|||
void parse_markers_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_dot_symbolizer(rule & rule, 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_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);
|
||||
sym_node.set_processed(true);
|
||||
break;
|
||||
case name2int("DotSymbolizer"):
|
||||
parse_dot_symbolizer(rule, sym_node);
|
||||
sym_node.set_processed(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
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)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"keys": [
|
||||
""
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"keys": [
|
||||
""
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
BIN
tests/visual_tests/images/dots-500-100-1.0-agg-reference.png
Normal file
BIN
tests/visual_tests/images/dots-500-100-1.0-agg-reference.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
tests/visual_tests/images/dots-500-100-1.0-cairo-reference.png
Normal file
BIN
tests/visual_tests/images/dots-500-100-1.0-cairo-reference.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 101 B |
BIN
tests/visual_tests/images/dots-500-100-2.0-agg-reference.png
Normal file
BIN
tests/visual_tests/images/dots-500-100-2.0-agg-reference.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
tests/visual_tests/images/dots-500-100-2.0-cairo-reference.png
Normal file
BIN
tests/visual_tests/images/dots-500-100-2.0-cairo-reference.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 101 B |
26
tests/visual_tests/styles/dots.xml
Normal file
26
tests/visual_tests/styles/dots.xml
Normal 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>
|
Loading…
Reference in a new issue