Compare commits
1 commit
master
...
rtree-plac
Author | SHA1 | Date | |
---|---|---|---|
|
8d9cecd6ad |
5 changed files with 73 additions and 44 deletions
|
@ -27,13 +27,39 @@
|
||||||
#include <mapnik/quad_tree.hpp>
|
#include <mapnik/quad_tree.hpp>
|
||||||
#include <mapnik/util/noncopyable.hpp>
|
#include <mapnik/util/noncopyable.hpp>
|
||||||
#include <mapnik/value_types.hpp>
|
#include <mapnik/value_types.hpp>
|
||||||
|
#include <mapnik/geometry_adapters.hpp>
|
||||||
|
// boost
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#include <boost/geometry/index/rtree.hpp>
|
||||||
// icu
|
// icu
|
||||||
#include <unicode/unistr.h>
|
#include <unicode/unistr.h>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
template <std::size_t Max, std::size_t Min>
|
||||||
|
struct detector_linear : boost::geometry::index::linear<Max,Min> {};
|
||||||
|
|
||||||
|
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
|
||||||
|
|
||||||
|
template <std::size_t Max, std::size_t Min>
|
||||||
|
struct options_type<detector_linear<Max,Min> >
|
||||||
|
{
|
||||||
|
using type = options<detector_linear<Max, Min>,
|
||||||
|
insert_default_tag,
|
||||||
|
choose_by_content_diff_tag,
|
||||||
|
split_default_tag,
|
||||||
|
linear_tag,
|
||||||
|
#if BOOST_VERSION >= 105700
|
||||||
|
node_variant_static_tag>;
|
||||||
|
#else
|
||||||
|
node_s_mem_static_tag>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}}}
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
//this needs to be tree structure
|
//this needs to be tree structure
|
||||||
|
@ -139,26 +165,23 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using tree_t = quad_tree< label >;
|
|
||||||
tree_t tree_;
|
|
||||||
|
|
||||||
|
using box_type = mapnik::box2d<double>;
|
||||||
|
using item_type = std::pair<box_type, label>;
|
||||||
|
using tree_t = boost::geometry::index::rtree<item_type,detector_linear<16,4> >;
|
||||||
|
tree_t tree_;
|
||||||
|
box2d<double> extent_;
|
||||||
public:
|
public:
|
||||||
using query_iterator = tree_t::query_iterator;
|
using query_iterator = tree_t::const_query_iterator;
|
||||||
|
|
||||||
explicit label_collision_detector4(box2d<double> const& extent)
|
explicit label_collision_detector4(box2d<double> const& extent)
|
||||||
: tree_(extent) {}
|
: tree_(), extent_(extent) {}
|
||||||
|
|
||||||
bool has_placement(box2d<double> const& box)
|
bool has_placement(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(box);
|
auto itr = tree_.qbegin(boost::geometry::index::intersects(box));
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
auto end = tree_.qend();
|
||||||
|
return (itr != end);
|
||||||
for ( ;itr != end; ++itr)
|
|
||||||
{
|
|
||||||
if (itr->get().box.intersects(box)) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_placement(box2d<double> const& box, double margin)
|
bool has_placement(box2d<double> const& box, double margin)
|
||||||
|
@ -168,23 +191,16 @@ public:
|
||||||
box.maxx() + margin, box.maxy() + margin)
|
box.maxx() + margin, box.maxy() + margin)
|
||||||
: box);
|
: box);
|
||||||
|
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(margin_box);
|
auto itr = tree_.qbegin(boost::geometry::index::intersects(margin_box));
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
auto end = tree_.qend();
|
||||||
|
return (itr != end);
|
||||||
for (;itr != end; ++itr)
|
|
||||||
{
|
|
||||||
if (itr->get().box.intersects(margin_box))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_placement(box2d<double> const& box, double margin, mapnik::value_unicode_string const& text, double repeat_distance)
|
bool has_placement(box2d<double> const& box, double margin, mapnik::value_unicode_string const& text, double repeat_distance)
|
||||||
{
|
{
|
||||||
// Don't bother with any of the repeat checking unless the repeat distance is greater than the margin
|
// Don't bother with any of the repeat checking unless the repeat distance is greater than the margin
|
||||||
if (repeat_distance <= margin) {
|
if (repeat_distance <= margin)
|
||||||
|
{
|
||||||
return has_placement(box, margin);
|
return has_placement(box, margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,12 +212,16 @@ public:
|
||||||
box.maxx() + margin, box.maxy() + margin)
|
box.maxx() + margin, box.maxy() + margin)
|
||||||
: box);
|
: box);
|
||||||
|
|
||||||
tree_t::query_iterator itr = tree_.query_in_box(repeat_box);
|
auto itr = tree_.qbegin(boost::geometry::index::intersects(margin_box));
|
||||||
tree_t::query_iterator end = tree_.query_end();
|
auto end = tree_.qend();
|
||||||
|
|
||||||
for ( ;itr != end; ++itr)
|
for ( ;itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if (itr->get().box.intersects(margin_box) || (text == itr->get().text && itr->get().box.intersects(repeat_box)))
|
auto const& node = *itr;
|
||||||
|
auto const& b = std::get<0>(node);
|
||||||
|
auto const& lab = std::get<1>(node);
|
||||||
|
|
||||||
|
if (b.intersects(margin_box) || (text == lab.text && b.intersects(repeat_box)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -212,12 +232,18 @@ public:
|
||||||
|
|
||||||
void insert(box2d<double> const& box)
|
void insert(box2d<double> const& box)
|
||||||
{
|
{
|
||||||
tree_.insert(label(box), box);
|
//if (tree_.extent().intersects(box))
|
||||||
|
//{
|
||||||
|
tree_.insert(std::make_pair(box, label(box)));
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(box2d<double> const& box, mapnik::value_unicode_string const& text)
|
void insert(box2d<double> const& box, mapnik::value_unicode_string const& text)
|
||||||
{
|
{
|
||||||
tree_.insert(label(box, text), box);
|
//if (tree_.extent().intersects(box))
|
||||||
|
// {
|
||||||
|
tree_.insert(std::make_pair(box, label(box, text)));
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
|
@ -227,11 +253,12 @@ public:
|
||||||
|
|
||||||
box2d<double> const& extent() const
|
box2d<double> const& extent() const
|
||||||
{
|
{
|
||||||
return tree_.extent();
|
//auto const& b = tree_.bounds();
|
||||||
|
return extent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
query_iterator begin() { return tree_.query_in_box(extent()); }
|
query_iterator begin() const { return tree_.qbegin(boost::geometry::index::intersects(extent_)); }
|
||||||
query_iterator end() { return tree_.query_end(); }
|
query_iterator end() const { return tree_.qend(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ void agg_renderer<T0,T1>::process(debug_symbolizer const& sym,
|
||||||
{
|
{
|
||||||
for (auto const& n : *common_.detector_)
|
for (auto const& n : *common_.detector_)
|
||||||
{
|
{
|
||||||
draw_rect(pixmap_, n.get().box);
|
draw_rect(pixmap_, std::get<1>(n).box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mode == DEBUG_SYM_MODE_VERTEX)
|
else if (mode == DEBUG_SYM_MODE_VERTEX)
|
||||||
|
|
|
@ -106,9 +106,9 @@ void cairo_renderer<T>::process(debug_symbolizer const& sym,
|
||||||
|
|
||||||
if (mode == DEBUG_SYM_MODE_COLLISION)
|
if (mode == DEBUG_SYM_MODE_COLLISION)
|
||||||
{
|
{
|
||||||
for (auto & n : *common_.detector_)
|
for (auto const& n : *common_.detector_)
|
||||||
{
|
{
|
||||||
render_debug_box(context_, n.get().box);
|
render_debug_box(context_, std::get<1>(n).box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mode == DEBUG_SYM_MODE_VERTEX)
|
else if (mode == DEBUG_SYM_MODE_VERTEX)
|
||||||
|
|
|
@ -215,15 +215,15 @@ void render_thunk_extractor::update_box() const
|
||||||
{
|
{
|
||||||
label_collision_detector4 & detector = *common_.detector_;
|
label_collision_detector4 & detector = *common_.detector_;
|
||||||
|
|
||||||
for (auto const& label : detector)
|
for (auto const& node : detector)
|
||||||
{
|
{
|
||||||
if (box_.width() > 0 && box_.height() > 0)
|
if (box_.width() > 0 && box_.height() > 0)
|
||||||
{
|
{
|
||||||
box_.expand_to_include(label.get().box);
|
box_.expand_to_include(std::get<1>(node).box);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
box_ = label.get().box;
|
box_ = std::get<1>(node).box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -399,7 +399,9 @@ bool placement_finder::collision(const box2d<double> &box, const value_unicode_s
|
||||||
margin = (text_props_->margin != 0 ? text_props_->margin : text_props_->minimum_distance) * scale_factor_;
|
margin = (text_props_->margin != 0 ? text_props_->margin : text_props_->minimum_distance) * scale_factor_;
|
||||||
repeat_distance = text_props_->repeat_distance * scale_factor_;
|
repeat_distance = text_props_->repeat_distance * scale_factor_;
|
||||||
}
|
}
|
||||||
return (text_props_->avoid_edges && !extent_.contains(box))
|
return !detector_.extent().intersects(box)
|
||||||
|
||
|
||||||
|
(text_props_->avoid_edges && !extent_.contains(box))
|
||||||
||
|
||
|
||||||
(text_props_->minimum_padding > 0 &&
|
(text_props_->minimum_padding > 0 &&
|
||||||
!extent_.contains(box + (scale_factor_ * text_props_->minimum_padding)))
|
!extent_.contains(box + (scale_factor_ * text_props_->minimum_padding)))
|
||||||
|
|
Loading…
Reference in a new issue