Merge pull request #909 from MapQuest/expose-label-collision-detector
Exposed the label collision detector
This commit is contained in:
commit
c7e1174d6b
10 changed files with 216 additions and 19 deletions
123
bindings/python/mapnik_label_collision_detector.cpp
Normal file
123
bindings/python/mapnik_label_collision_detector.cpp
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 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
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/python/module.hpp>
|
||||||
|
#include <boost/python/def.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/label_collision_detector.hpp>
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
using mapnik::label_collision_detector4;
|
||||||
|
using mapnik::box2d;
|
||||||
|
using mapnik::Map;
|
||||||
|
using boost::make_shared;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
boost::shared_ptr<label_collision_detector4>
|
||||||
|
create_label_collision_detector_from_extent(box2d<double> const &extent)
|
||||||
|
{
|
||||||
|
return make_shared<label_collision_detector4>(extent);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<label_collision_detector4>
|
||||||
|
create_label_collision_detector_from_map(Map const &m)
|
||||||
|
{
|
||||||
|
double buffer = m.buffer_size();
|
||||||
|
box2d<double> extent(-buffer, -buffer, m.width() + buffer, m.height() + buffer);
|
||||||
|
return make_shared<label_collision_detector4>(extent);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::list
|
||||||
|
make_label_boxes(boost::shared_ptr<label_collision_detector4> det)
|
||||||
|
{
|
||||||
|
boost::python::list boxes;
|
||||||
|
|
||||||
|
for (label_collision_detector4::query_iterator jtr = det->begin();
|
||||||
|
jtr != det->end(); ++jtr)
|
||||||
|
{
|
||||||
|
boxes.append<box2d<double> >(jtr->box);
|
||||||
|
}
|
||||||
|
|
||||||
|
return boxes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_label_collision_detector()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
// for overload resolution
|
||||||
|
void (label_collision_detector4::*insert_box)(box2d<double> const &) = &label_collision_detector4::insert;
|
||||||
|
|
||||||
|
class_<label_collision_detector4, boost::shared_ptr<label_collision_detector4>, boost::noncopyable>
|
||||||
|
("LabelCollisionDetector",
|
||||||
|
"Object to detect collisions between labels, used in the rendering process.",
|
||||||
|
no_init)
|
||||||
|
|
||||||
|
.def("__init__", make_constructor(create_label_collision_detector_from_extent),
|
||||||
|
"Creates an empty collision detection object with a given extent. Note "
|
||||||
|
"that the constructor from Map objects is a sensible default and usually "
|
||||||
|
"what you want to do.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> m = Map(size_x, size_y)\n"
|
||||||
|
">>> buf_sz = m.buffer_size\n"
|
||||||
|
">>> extent = mapnik.Box2d(-buf_sz, -buf_sz, m.width + buf_sz, m.height + buf_sz)\n"
|
||||||
|
">>> detector = mapnik.LabelCollisionDetector(extent)")
|
||||||
|
|
||||||
|
.def("__init__", make_constructor(create_label_collision_detector_from_map),
|
||||||
|
"Creates an empty collision detection object matching the given Map object. "
|
||||||
|
"The created detector will have the same size, including the buffer, as the "
|
||||||
|
"map object. This is usually what you want to do.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> m = Map(size_x, size_y)\n"
|
||||||
|
">>> detector = mapnik.LabelCollisionDetector(m)")
|
||||||
|
|
||||||
|
.def("extent", &label_collision_detector4::extent, return_value_policy<copy_const_reference>(),
|
||||||
|
"Returns the total extent (bounding box) of all labels inside the detector.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> detector.extent()\n"
|
||||||
|
"Box2d(573.252589209,494.789179821,584.261023823,496.83610261)")
|
||||||
|
|
||||||
|
.def("boxes", &make_label_boxes,
|
||||||
|
"Returns a list of all the label boxes inside the detector.")
|
||||||
|
|
||||||
|
.def("insert", insert_box,
|
||||||
|
"Insert a 2d box into the collision detector. This can be used to ensure that "
|
||||||
|
"some space is left clear on the map for later overdrawing, for example by "
|
||||||
|
"non-Mapnik processes.\n"
|
||||||
|
"\n"
|
||||||
|
"Example:\n"
|
||||||
|
">>> m = Map(size_x, size_y)\n"
|
||||||
|
">>> detector = mapnik.LabelCollisionDetector(m)"
|
||||||
|
">>> detector.insert(mapnik.Box2d(196, 254, 291, 389))")
|
||||||
|
;
|
||||||
|
}
|
|
@ -66,6 +66,7 @@ void export_view_transform();
|
||||||
void export_raster_colorizer();
|
void export_raster_colorizer();
|
||||||
void export_glyph_symbolizer();
|
void export_glyph_symbolizer();
|
||||||
void export_inmem_metawriter();
|
void export_inmem_metawriter();
|
||||||
|
void export_label_collision_detector();
|
||||||
|
|
||||||
#include <mapnik/version.hpp>
|
#include <mapnik/version.hpp>
|
||||||
#include <mapnik/value_error.hpp>
|
#include <mapnik/value_error.hpp>
|
||||||
|
@ -120,6 +121,28 @@ void render(const mapnik::Map& map,
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void render_with_detector(
|
||||||
|
const mapnik::Map &map,
|
||||||
|
mapnik::image_32 &image,
|
||||||
|
boost::shared_ptr<mapnik::label_collision_detector4> detector,
|
||||||
|
double scale_factor = 1.0,
|
||||||
|
unsigned offset_x = 0u,
|
||||||
|
unsigned offset_y = 0u)
|
||||||
|
{
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> ren(map,image,detector);
|
||||||
|
ren.apply();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
Py_BLOCK_THREADS
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
|
||||||
void render_layer2(const mapnik::Map& map,
|
void render_layer2(const mapnik::Map& map,
|
||||||
mapnik::image_32& image,
|
mapnik::image_32& image,
|
||||||
unsigned layer_idx)
|
unsigned layer_idx)
|
||||||
|
@ -374,6 +397,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 4
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3)
|
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3)
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2)
|
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2)
|
||||||
BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5)
|
BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5)
|
||||||
|
BOOST_PYTHON_FUNCTION_OVERLOADS(render_with_detector_overloads, render_with_detector, 3, 6)
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(_mapnik2)
|
BOOST_PYTHON_MODULE(_mapnik2)
|
||||||
{
|
{
|
||||||
|
@ -427,6 +451,7 @@ BOOST_PYTHON_MODULE(_mapnik2)
|
||||||
export_raster_colorizer();
|
export_raster_colorizer();
|
||||||
export_glyph_symbolizer();
|
export_glyph_symbolizer();
|
||||||
export_inmem_metawriter();
|
export_inmem_metawriter();
|
||||||
|
export_label_collision_detector();
|
||||||
|
|
||||||
def("render_grid",&render_grid,
|
def("render_grid",&render_grid,
|
||||||
( arg("map"),
|
( arg("map"),
|
||||||
|
@ -503,6 +528,19 @@ BOOST_PYTHON_MODULE(_mapnik2)
|
||||||
"\n"
|
"\n"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
def("render_with_detector", &render_with_detector, render_with_detector_overloads(
|
||||||
|
"\n"
|
||||||
|
"Render Map to an AGG image_32 using a pre-constructed detector.\n"
|
||||||
|
"\n"
|
||||||
|
"Usage:\n"
|
||||||
|
">>> from mapnik import Map, Image, LabelCollisionDetector, render_with_detector, load_map\n"
|
||||||
|
">>> m = Map(256,256)\n"
|
||||||
|
">>> load_map(m,'mapfile.xml')\n"
|
||||||
|
">>> im = Image(m.width,m.height)\n"
|
||||||
|
">>> detector = LabelCollisionDetector(m)\n"
|
||||||
|
">>> render_with_detector(m, im, detector)\n"
|
||||||
|
));
|
||||||
|
|
||||||
def("render_layer", &render_layer2,
|
def("render_layer", &render_layer2,
|
||||||
(arg("map"),arg("image"),args("layer"))
|
(arg("map"),arg("image"),args("layer"))
|
||||||
);
|
);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
// boost
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
// forward declare so that
|
// forward declare so that
|
||||||
|
@ -61,7 +62,11 @@ class MAPNIK_DECL agg_renderer : public feature_style_processor<agg_renderer<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// create with default, empty placement detector
|
||||||
agg_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
agg_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
|
// create with external placement detector, possibly non-empty
|
||||||
|
agg_renderer(Map const &m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
||||||
|
double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
~agg_renderer();
|
~agg_renderer();
|
||||||
void start_map_processing(Map const& map);
|
void start_map_processing(Map const& map);
|
||||||
void end_map_processing(Map const& map);
|
void end_map_processing(Map const& map);
|
||||||
|
@ -122,8 +127,10 @@ private:
|
||||||
CoordTransform t_;
|
CoordTransform t_;
|
||||||
freetype_engine font_engine_;
|
freetype_engine font_engine_;
|
||||||
face_manager<freetype_engine> font_manager_;
|
face_manager<freetype_engine> font_manager_;
|
||||||
label_collision_detector4 detector_;
|
boost::shared_ptr<label_collision_detector4> detector_;
|
||||||
boost::scoped_ptr<rasterizer> ras_ptr;
|
boost::scoped_ptr<rasterizer> ras_ptr;
|
||||||
|
|
||||||
|
void setup(Map const &m);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class label_collision_detector2 : boost::noncopyable
|
||||||
typedef quad_tree<box2d<double> > tree_t;
|
typedef quad_tree<box2d<double> > tree_t;
|
||||||
tree_t tree_;
|
tree_t tree_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit label_collision_detector2(box2d<double> const& extent)
|
explicit label_collision_detector2(box2d<double> const& extent)
|
||||||
: tree_(extent) {}
|
: tree_(extent) {}
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ public:
|
||||||
//quad tree based label collission detector so labels dont appear within a given distance
|
//quad tree based label collission detector so labels dont appear within a given distance
|
||||||
class label_collision_detector4 : boost::noncopyable
|
class label_collision_detector4 : boost::noncopyable
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
struct label
|
struct label
|
||||||
{
|
{
|
||||||
label(box2d<double> const& b) : box(b) {}
|
label(box2d<double> const& b) : box(b) {}
|
||||||
|
@ -146,11 +147,13 @@ class label_collision_detector4 : boost::noncopyable
|
||||||
box2d<double> box;
|
box2d<double> box;
|
||||||
UnicodeString text;
|
UnicodeString text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
typedef quad_tree< label > tree_t;
|
typedef quad_tree< label > tree_t;
|
||||||
tree_t tree_;
|
tree_t tree_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef tree_t::query_iterator query_iterator;
|
||||||
|
|
||||||
explicit label_collision_detector4(box2d<double> const& extent)
|
explicit label_collision_detector4(box2d<double> const& extent)
|
||||||
: tree_(extent) {}
|
: tree_(extent) {}
|
||||||
|
@ -224,6 +227,9 @@ public:
|
||||||
{
|
{
|
||||||
return tree_.extent();
|
return tree_.extent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query_iterator begin() { return tree_.query_in_box(extent()); }
|
||||||
|
query_iterator end() { return tree_.query_end(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
|
@ -121,8 +121,31 @@ agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns
|
||||||
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
|
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
|
||||||
font_engine_(),
|
font_engine_(),
|
||||||
font_manager_(font_engine_),
|
font_manager_(font_engine_),
|
||||||
detector_(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size())),
|
detector_(boost::make_shared<label_collision_detector4>(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))),
|
||||||
ras_ptr(new rasterizer)
|
ras_ptr(new rasterizer)
|
||||||
|
{
|
||||||
|
setup(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
||||||
|
double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<agg_renderer>(m, scale_factor),
|
||||||
|
pixmap_(pixmap),
|
||||||
|
width_(pixmap_.width()),
|
||||||
|
height_(pixmap_.height()),
|
||||||
|
scale_factor_(scale_factor),
|
||||||
|
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
|
||||||
|
font_engine_(),
|
||||||
|
font_manager_(font_engine_),
|
||||||
|
detector_(detector),
|
||||||
|
ras_ptr(new rasterizer)
|
||||||
|
{
|
||||||
|
setup(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void agg_renderer<T>::setup(Map const &m)
|
||||||
{
|
{
|
||||||
boost::optional<color> const& bg = m.background();
|
boost::optional<color> const& bg = m.background();
|
||||||
if (bg) pixmap_.set_background(*bg);
|
if (bg) pixmap_.set_background(*bg);
|
||||||
|
@ -189,7 +212,7 @@ void agg_renderer<T>::start_layer_processing(layer const& lay)
|
||||||
#endif
|
#endif
|
||||||
if (lay.clear_label_cache())
|
if (lay.clear_label_cache())
|
||||||
{
|
{
|
||||||
detector_.clear();
|
detector_->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,12 +77,12 @@ void agg_renderer<T>::process(glyph_symbolizer const& sym,
|
||||||
// final box so we can check for a valid placement
|
// final box so we can check for a valid placement
|
||||||
box2d<double> dim = ren.prepare_glyphs(path.get());
|
box2d<double> dim = ren.prepare_glyphs(path.get());
|
||||||
box2d<double> ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2);
|
box2d<double> ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2);
|
||||||
if ((sym.get_allow_overlap() || detector_.has_placement(ext)) &&
|
if ((sym.get_allow_overlap() || detector_->has_placement(ext)) &&
|
||||||
(!sym.get_avoid_edges() || detector_.extent().contains(ext)))
|
(!sym.get_avoid_edges() || detector_->extent().contains(ext)))
|
||||||
{
|
{
|
||||||
// Placement is valid, render glyph and update detector.
|
// Placement is valid, render glyph and update detector.
|
||||||
ren.render(x, y);
|
ren.render(x, y);
|
||||||
detector_.insert(ext);
|
detector_->insert(ext);
|
||||||
metawriter_with_properties writer = sym.get_metawriter();
|
metawriter_with_properties writer = sym.get_metawriter();
|
||||||
if (writer.first) writer.first->add_box(ext, feature, t_, writer.second);
|
if (writer.first) writer.first->add_box(ext, feature, t_, writer.second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
}
|
}
|
||||||
|
|
||||||
path_type path(t_,geom,prj_trans);
|
path_type path(t_,geom,prj_trans);
|
||||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_,
|
markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
|
||||||
sym.get_spacing() * scale_factor_,
|
sym.get_spacing() * scale_factor_,
|
||||||
sym.get_max_error(),
|
sym.get_max_error(),
|
||||||
sym.get_allow_overlap());
|
sym.get_allow_overlap());
|
||||||
|
@ -194,7 +194,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
|
box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
|
||||||
|
|
||||||
if (sym.get_allow_overlap() ||
|
if (sym.get_allow_overlap() ||
|
||||||
detector_.has_placement(label_ext))
|
detector_->has_placement(label_ext))
|
||||||
{
|
{
|
||||||
agg::ellipse c(x, y, w, h);
|
agg::ellipse c(x, y, w, h);
|
||||||
marker.concat_path(c);
|
marker.concat_path(c);
|
||||||
|
@ -215,7 +215,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
|
ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
|
||||||
agg::render_scanlines(*ras_ptr, sl_line, ren);
|
agg::render_scanlines(*ras_ptr, sl_line, ren);
|
||||||
}
|
}
|
||||||
detector_.insert(label_ext);
|
detector_->insert(label_ext);
|
||||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
marker.concat_path(arrow_);
|
marker.concat_path(arrow_);
|
||||||
|
|
||||||
path_type path(t_,geom,prj_trans);
|
path_type path(t_,geom,prj_trans);
|
||||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_,
|
markers_placement<path_type, label_collision_detector4> placement(path, extent, *detector_,
|
||||||
sym.get_spacing() * scale_factor_,
|
sym.get_spacing() * scale_factor_,
|
||||||
sym.get_max_error(),
|
sym.get_max_error(),
|
||||||
sym.get_allow_overlap());
|
sym.get_allow_overlap());
|
||||||
|
|
|
@ -99,13 +99,13 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
|
||||||
label_ext.re_center(x,y);
|
label_ext.re_center(x,y);
|
||||||
|
|
||||||
if (sym.get_allow_overlap() ||
|
if (sym.get_allow_overlap() ||
|
||||||
detector_.has_placement(label_ext))
|
detector_->has_placement(label_ext))
|
||||||
{
|
{
|
||||||
|
|
||||||
render_marker(floor(x - 0.5 * w),floor(y - 0.5 * h) ,**marker,tr, sym.get_opacity());
|
render_marker(floor(x - 0.5 * w),floor(y - 0.5 * h) ,**marker,tr, sym.get_opacity());
|
||||||
|
|
||||||
if (!sym.get_ignore_placement())
|
if (!sym.get_ignore_placement())
|
||||||
detector_.insert(label_ext);
|
detector_->insert(label_ext);
|
||||||
metawriter_with_properties writer = sym.get_metawriter();
|
metawriter_with_properties writer = sym.get_metawriter();
|
||||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
||||||
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
||||||
ren.set_opacity(sym.get_text_opacity());
|
ren.set_opacity(sym.get_text_opacity());
|
||||||
|
|
||||||
placement_finder<label_collision_detector4> finder(detector_);
|
placement_finder<label_collision_detector4> finder(*detector_);
|
||||||
|
|
||||||
string_info info(text);
|
string_info info(text);
|
||||||
|
|
||||||
|
@ -210,13 +210,13 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
||||||
label_ext.re_center(label_x,label_y);
|
label_ext.re_center(label_x,label_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) )
|
if ( sym.get_allow_overlap() || detector_->has_placement(label_ext) )
|
||||||
{
|
{
|
||||||
render_marker(px,py,**marker,tr,sym.get_opacity());
|
render_marker(px,py,**marker,tr,sym.get_opacity());
|
||||||
|
|
||||||
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
|
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
|
||||||
ren.render(x,y);
|
ren.render(x,y);
|
||||||
detector_.insert(label_ext);
|
detector_->insert(label_ext);
|
||||||
finder.update_detector(text_placement);
|
finder.update_detector(text_placement);
|
||||||
if (writer.first) {
|
if (writer.first) {
|
||||||
writer.first->add_box(label_ext, feature, t_, writer.second);
|
writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||||
|
|
|
@ -110,7 +110,7 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
|
||||||
ren.set_opacity(sym.get_text_opacity());
|
ren.set_opacity(sym.get_text_opacity());
|
||||||
|
|
||||||
box2d<double> dims(0,0,width_,height_);
|
box2d<double> dims(0,0,width_,height_);
|
||||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
placement_finder<label_collision_detector4> finder(*detector_,dims);
|
||||||
|
|
||||||
string_info info(text);
|
string_info info(text);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue