Support ShieldSymbolizer.
This commit is contained in:
parent
d8fad34aa3
commit
a1f0af112e
9 changed files with 126 additions and 129 deletions
|
@ -70,8 +70,6 @@ public:
|
|||
|
||||
/** Return all placements.*/
|
||||
placements_list const& get();
|
||||
marker_ptr get_marker() const;
|
||||
agg::trans_affine const& get_image_transform() const;
|
||||
protected:
|
||||
bool next_point_placement();
|
||||
bool next_line_placement();
|
||||
|
@ -104,8 +102,6 @@ protected:
|
|||
placement_finder_ng finder_;
|
||||
|
||||
//ShieldSymbolizer only
|
||||
marker_ptr marker_;
|
||||
agg::trans_affine marker_transform_;
|
||||
void init_marker();
|
||||
};
|
||||
|
||||
|
|
|
@ -68,16 +68,24 @@ public:
|
|||
bool next_position();
|
||||
|
||||
placements_list const& placements() const;
|
||||
|
||||
void set_marker(marker_info_ptr m, box2d<double> box, bool marker_unlocked, pixel_position const& marker_displacement);
|
||||
private:
|
||||
void init_alignment();
|
||||
pixel_position alignment_offset() const;
|
||||
double jalign_offset(double line_width) const;
|
||||
|
||||
bool single_line_placement(vertex_cache &pp, text_upright_e orientation);
|
||||
/** Moves dx pixels but makes sure not to fall of the end. */
|
||||
void path_move_dx(vertex_cache &pp);
|
||||
/** Normalize angle in range [-pi, +pi]. */
|
||||
static double normalize_angle(double angle);
|
||||
/** Adjusts user defined spacing to place an integer number of labels. */
|
||||
double get_spacing(double path_length, double layout_width) const;
|
||||
/** Checks for collision. */
|
||||
bool collision(box2d<double> const& box) const;
|
||||
/** Adds marker to glyph_positions and to collision detector. Returns false if there is a collision. */
|
||||
bool add_marker(glyph_positions_ptr glyphs, pixel_position const& pos) const;
|
||||
box2d<double> get_bbox(glyph_info const& glyph, pixel_position const& pos, rotation const& rot);
|
||||
Feature const& feature_;
|
||||
DetectorType &detector_;
|
||||
|
@ -94,6 +102,13 @@ private:
|
|||
double scale_factor_;
|
||||
|
||||
placements_list placements_;
|
||||
|
||||
//ShieldSymbolizer
|
||||
bool has_marker_;
|
||||
marker_info_ptr marker_;
|
||||
box2d<double> marker_box_;
|
||||
bool marker_unlocked_;
|
||||
pixel_position marker_displacement_;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<placement_finder_ng> placement_finder_ng_ptr;
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#include <mapnik/pixel_position.hpp>
|
||||
#include <mapnik/text/glyph_info.hpp>
|
||||
#include <mapnik/text/rotation.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
//stl
|
||||
#include <vector>
|
||||
|
@ -45,9 +49,19 @@ struct glyph_position
|
|||
rotation rot;
|
||||
};
|
||||
|
||||
struct marker_info
|
||||
{
|
||||
marker_info() : marker(), transform() {}
|
||||
marker_info(marker_ptr marker, agg::trans_affine const& transform) :
|
||||
marker(marker), transform(transform) {}
|
||||
marker_ptr marker;
|
||||
agg::trans_affine transform;
|
||||
};
|
||||
typedef boost::shared_ptr<marker_info> marker_info_ptr;
|
||||
|
||||
/** Stores positions of glphys.
|
||||
*
|
||||
* The actual glyphs and their format is stored in text_layout.
|
||||
* The actual glyphs and their format are stored in text_layout.
|
||||
*/
|
||||
class glyph_positions
|
||||
{
|
||||
|
@ -62,9 +76,14 @@ public:
|
|||
|
||||
pixel_position const& get_base_point() const;
|
||||
void set_base_point(pixel_position base_point);
|
||||
void set_marker(marker_info_ptr marker, pixel_position const& marker_pos);
|
||||
marker_info_ptr marker() const;
|
||||
pixel_position const& marker_pos() const;
|
||||
private:
|
||||
std::vector<glyph_position> data_;
|
||||
pixel_position base_point_;
|
||||
marker_info_ptr marker_;
|
||||
pixel_position marker_pos_;
|
||||
};
|
||||
typedef boost::shared_ptr<glyph_positions> glyph_positions_ptr;
|
||||
|
||||
|
|
|
@ -22,15 +22,8 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/svg/svg_converter.hpp>
|
||||
#include <mapnik/svg/svg_renderer.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/symbolizer_helpers.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <mapnik/text/renderer.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
|
@ -39,47 +32,25 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
#if 0
|
||||
shield_symbolizer_helper<face_manager<freetype_engine>,
|
||||
label_collision_detector4> helper(
|
||||
text_symbolizer_helper helper(
|
||||
sym, feature, prj_trans,
|
||||
width_, height_,
|
||||
scale_factor_,
|
||||
t_, font_manager_, *detector_,
|
||||
query_extent_);
|
||||
|
||||
text_renderer<T> ren(*current_buffer_,
|
||||
font_manager_,
|
||||
*(font_manager_.get_stroker()),
|
||||
sym.comp_op(),
|
||||
scale_factor_);
|
||||
agg_text_renderer<T> ren(*current_buffer_, *(font_manager_.get_stroker()), sym.comp_op(), scale_factor_);
|
||||
|
||||
while (helper.next())
|
||||
placements_list const& placements = helper.get();
|
||||
BOOST_FOREACH(glyph_positions_ptr glyphs, placements)
|
||||
{
|
||||
placements_type const& placements = helper.placements();
|
||||
for (unsigned int ii = 0; ii < placements.size(); ++ii)
|
||||
{
|
||||
// get_marker_position returns (minx,miny) corner position,
|
||||
// while (currently only) agg_renderer::render_marker newly
|
||||
// expects center position;
|
||||
// until all renderers and shield_symbolizer_helper are
|
||||
// modified accordingly, we must adjust the position here
|
||||
pixel_position pos = helper.get_marker_position(placements[ii]);
|
||||
pos.x += 0.5 * helper.get_marker_width();
|
||||
pos.y += 0.5 * helper.get_marker_height();
|
||||
render_marker(pos,
|
||||
helper.get_marker(),
|
||||
helper.get_image_transform(),
|
||||
sym.get_opacity(),
|
||||
sym.comp_op());
|
||||
|
||||
ren.prepare_glyphs(placements[ii]);
|
||||
ren.render(placements[ii].center);
|
||||
}
|
||||
if (glyphs->marker())
|
||||
render_marker(glyphs->marker_pos(),
|
||||
*(glyphs->marker()->marker),
|
||||
glyphs->marker()->transform,
|
||||
sym.get_opacity(), sym.comp_op());
|
||||
ren.render(glyphs);
|
||||
}
|
||||
#else
|
||||
#warning AGG: ShieldSymbolizer disabled!
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,15 +21,9 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/grid/grid_rasterizer.hpp>
|
||||
#include <mapnik/grid/grid_renderer.hpp>
|
||||
#include <mapnik/grid/grid_pixfmt.hpp>
|
||||
#include <mapnik/grid/grid_pixel.hpp>
|
||||
#include <mapnik/grid/grid.hpp>
|
||||
#include <mapnik/symbolizer_helpers.hpp>
|
||||
#include <mapnik/svg/svg_converter.hpp>
|
||||
#include <mapnik/svg/svg_renderer.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/text/renderer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_trans_affine.h"
|
||||
|
@ -41,54 +35,28 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
|
|||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
#if 0
|
||||
shield_symbolizer_helper<face_manager<freetype_engine>,
|
||||
label_collision_detector4> helper(
|
||||
text_symbolizer_helper helper(
|
||||
sym, feature, prj_trans,
|
||||
width_, height_,
|
||||
scale_factor_,
|
||||
scale_factor_ * (1.0/pixmap_.get_resolution()),
|
||||
t_, font_manager_, *detector_,
|
||||
query_extent_);
|
||||
bool placement_found = false;
|
||||
|
||||
text_renderer<T> ren(pixmap_,
|
||||
font_manager_,
|
||||
*(font_manager_.get_stroker()),
|
||||
sym.comp_op(),
|
||||
scale_factor_);
|
||||
grid_text_renderer<T> ren(pixmap_, *(font_manager_.get_stroker()), sym.comp_op(), scale_factor_);
|
||||
|
||||
text_placement_info_ptr placement;
|
||||
while (helper.next())
|
||||
placements_list const& placements = helper.get();
|
||||
if (!placements.size()) return;
|
||||
BOOST_FOREACH(glyph_positions_ptr glyphs, placements)
|
||||
{
|
||||
placement_found = true;
|
||||
placements_type const& placements = helper.placements();
|
||||
for (unsigned int ii = 0; ii < placements.size(); ++ii)
|
||||
{
|
||||
// get_marker_position returns (minx,miny) corner position,
|
||||
// while (currently only) agg_renderer::render_marker newly
|
||||
// expects center position;
|
||||
// until all renderers and shield_symbolizer_helper are
|
||||
// modified accordingly, we must adjust the position here
|
||||
pixel_position pos = helper.get_marker_position(placements[ii]);
|
||||
pos.x += 0.5 * helper.get_marker_width();
|
||||
pos.y += 0.5 * helper.get_marker_height();
|
||||
render_marker(feature,
|
||||
pixmap_.get_resolution(),
|
||||
pos,
|
||||
helper.get_marker(),
|
||||
helper.get_image_transform(),
|
||||
sym.get_opacity(),
|
||||
sym.comp_op());
|
||||
|
||||
ren.prepare_glyphs(placements[ii]);
|
||||
ren.render_id(feature.id(), placements[ii].center, 2);
|
||||
}
|
||||
if (glyphs->marker()->marker)
|
||||
render_marker(feature, pixmap_.get_resolution(),
|
||||
glyphs->marker_pos(),
|
||||
*(glyphs->marker()->marker),
|
||||
glyphs->marker()->transform,
|
||||
sym.get_opacity(), sym.comp_op());
|
||||
ren.render(glyphs, feature.id(), 2);
|
||||
}
|
||||
if (placement_found)
|
||||
pixmap_.add_feature(feature);
|
||||
#else
|
||||
#warning GRID: TextSymbolizer disabled!
|
||||
#endif
|
||||
pixmap_.add_feature(feature);
|
||||
}
|
||||
|
||||
template void grid_renderer<grid>::process(shield_symbolizer const&,
|
||||
|
|
|
@ -267,45 +267,34 @@ void text_symbolizer_helper::init_marker()
|
|||
{
|
||||
shield_symbolizer const& sym = static_cast<shield_symbolizer const&>(sym_);
|
||||
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature_);
|
||||
evaluate_transform(marker_transform_, feature_, sym.get_image_transform());
|
||||
#if 0
|
||||
marker_.reset();
|
||||
agg::trans_affine trans;
|
||||
evaluate_transform(trans, feature_, sym.get_image_transform());
|
||||
boost::optional<marker_ptr> opt_marker; //TODO: Why boost::optional?
|
||||
if (!filename.empty())
|
||||
{
|
||||
marker_ = marker_cache::instance()->find(filename, true);
|
||||
opt_marker = marker_cache::instance()->find(filename, true);
|
||||
}
|
||||
if (!marker_) {
|
||||
marker_size_.clear();
|
||||
marker_ext_.init(0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
marker_size_.set((*marker_)->width(), (*marker_)->height());
|
||||
double px0 = - 0.5 * marker_size_.x;
|
||||
double py0 = - 0.5 * marker_size_.y;
|
||||
double px1 = 0.5 * marker_size_.x;
|
||||
double py1 = 0.5 * marker_size_.y;
|
||||
marker_ptr m;
|
||||
if (opt_marker) m = *opt_marker;
|
||||
if (!m) return;
|
||||
double width = m->width();
|
||||
double height = m->height();
|
||||
double px0 = - 0.5 * width;
|
||||
double py0 = - 0.5 * height;
|
||||
double px1 = 0.5 * width;
|
||||
double py1 = 0.5 * height;
|
||||
double px2 = px1;
|
||||
double py2 = py0;
|
||||
double px3 = px0;
|
||||
double py3 = py1;
|
||||
marker_transform_.transform(&px0,&py0);
|
||||
marker_transform_.transform(&px1,&py1);
|
||||
marker_transform_.transform(&px2,&py2);
|
||||
marker_transform_.transform(&px3,&py3);
|
||||
marker_ext_.init(px0, py0, px1, py1);
|
||||
marker_ext_.expand_to_include(px2, py2);
|
||||
marker_ext_.expand_to_include(px3, py3);
|
||||
#endif
|
||||
}
|
||||
|
||||
marker_ptr text_symbolizer_helper::get_marker() const
|
||||
{
|
||||
return marker_;
|
||||
}
|
||||
|
||||
agg::trans_affine const& text_symbolizer_helper::get_image_transform() const
|
||||
{
|
||||
return marker_transform_;
|
||||
trans.transform(&px0, &py0);
|
||||
trans.transform(&px1, &py1);
|
||||
trans.transform(&px2, &py2);
|
||||
trans.transform(&px3, &py3);
|
||||
box2d<double> bbox(px0, py0, px1, py1);
|
||||
bbox.expand_to_include(px2, py2);
|
||||
bbox.expand_to_include(px3, py3);
|
||||
finder_.set_marker(boost::make_shared<marker_info>(m, trans), bbox, sym.get_unlock_image(), sym.get_shield_displacement());
|
||||
}
|
||||
|
||||
template text_symbolizer_helper::text_symbolizer_helper(const text_symbolizer &sym, const Feature &feature,
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace mapnik
|
|||
{
|
||||
|
||||
placement_finder_ng::placement_finder_ng(Feature const& feature, DetectorType &detector, box2d<double> const& extent, text_placement_info_ptr placement_info, face_manager_freetype &font_manager, double scale_factor)
|
||||
: feature_(feature), detector_(detector), extent_(extent), layout_(font_manager), info_(placement_info), valid_(true), scale_factor_(scale_factor), placements_()
|
||||
: feature_(feature), detector_(detector), extent_(extent), layout_(font_manager), info_(placement_info), valid_(true), scale_factor_(scale_factor), placements_(), has_marker_(false), marker_(), marker_box_()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,6 @@ const placements_list &placement_finder_ng::placements() const
|
|||
return placements_;
|
||||
}
|
||||
|
||||
|
||||
void placement_finder_ng::init_alignment()
|
||||
{
|
||||
text_symbolizer_properties const& p = info_->properties;
|
||||
|
@ -191,7 +190,7 @@ bool placement_finder_ng::find_point_placement(pixel_position pos)
|
|||
rotated_box2d(bbox, orientation_, layout_.width(), layout_.height());
|
||||
bbox.re_center(glyphs->get_base_point().x, glyphs->get_base_point().y);
|
||||
if (collision(bbox)) return false;
|
||||
|
||||
if (has_marker_ && !add_marker(glyphs, pos)) return false;
|
||||
detector_.insert(bbox, layout_.get_text());
|
||||
|
||||
/* IMPORTANT NOTE:
|
||||
|
@ -438,6 +437,27 @@ bool placement_finder_ng::collision(const box2d<double> &box) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void placement_finder_ng::set_marker(marker_info_ptr m, box2d<double> box, bool marker_unlocked, const pixel_position &marker_displacement)
|
||||
{
|
||||
marker_ = m;
|
||||
marker_box_ = box;
|
||||
marker_unlocked_ = marker_unlocked;
|
||||
marker_displacement_ = marker_displacement;
|
||||
has_marker_ = true;
|
||||
}
|
||||
|
||||
|
||||
bool placement_finder_ng::add_marker(glyph_positions_ptr glyphs, const pixel_position &pos) const
|
||||
{
|
||||
pixel_position real_pos = (marker_unlocked_ ? pos : glyphs->get_base_point()) + marker_displacement_;
|
||||
box2d<double> bbox = marker_box_;
|
||||
bbox.move(real_pos.x, real_pos.y);
|
||||
glyphs->set_marker(marker_, real_pos);
|
||||
if (collision(bbox)) return false;
|
||||
detector_.insert(bbox);
|
||||
return true;
|
||||
}
|
||||
|
||||
box2d<double> placement_finder_ng::get_bbox(glyph_info const& glyph, pixel_position const& pos, rotation const& rot)
|
||||
{
|
||||
/*
|
||||
|
@ -507,6 +527,22 @@ void glyph_positions::set_base_point(pixel_position base_point)
|
|||
base_point_ = base_point;
|
||||
}
|
||||
|
||||
void glyph_positions::set_marker(marker_info_ptr marker, const pixel_position &marker_pos)
|
||||
{
|
||||
marker_ = marker;
|
||||
marker_pos_ = marker_pos;
|
||||
}
|
||||
|
||||
marker_info_ptr glyph_positions::marker() const
|
||||
{
|
||||
return marker_;
|
||||
}
|
||||
|
||||
const pixel_position &glyph_positions::marker_pos() const
|
||||
{
|
||||
return marker_pos_;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************/
|
||||
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
</Rule>
|
||||
<Rule>
|
||||
<Filter>[nr] = '10'</Filter>
|
||||
<ShieldSymbolizer face-name="DejaVu Sans Book" size="16" placement="point" file="../../data/images/crosshair16x16.png" unlock-image="false" shield-dx="15">'X'</ShieldSymbolizer>
|
||||
<ShieldSymbolizer face-name="DejaVu Sans Book" size="16" placement="point" file="../../data/images/crosshair16x16.png" unlock-image="false" shield-dx="15" dy="20">'X'</ShieldSymbolizer>
|
||||
</Rule>
|
||||
<Rule>
|
||||
<PointSymbolizer allow-overlap="true" file="../../data/raster/white-alpha.png"/>
|
||||
|
|
|
@ -50,11 +50,14 @@
|
|||
</Rule>
|
||||
<Rule>
|
||||
<Filter>[nr] = '10'</Filter>
|
||||
<ShieldSymbolizer face-name="DejaVu Sans Book" size="16" placement="point" file="../../data/images/crosshair16x16.png" unlock-image="true" shield-dx="15">'X'</ShieldSymbolizer>
|
||||
<ShieldSymbolizer face-name="DejaVu Sans Book" size="16" placement="point" file="../../data/images/crosshair16x16.png" unlock-image="true" shield-dx="15" dy="20">'X'</ShieldSymbolizer>
|
||||
</Rule>
|
||||
<Rule>
|
||||
<PointSymbolizer allow-overlap="true" file="../../data/raster/white-alpha.png"/>
|
||||
</Rule>
|
||||
<Rule>
|
||||
<DebugSymbolizer />
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
||||
|
|
Loading…
Reference in a new issue