Merge pull request #3566 from mapycz/better-largest-bbox

Better largest bbox
This commit is contained in:
lightmare 2017-01-02 03:25:14 +01:00 committed by GitHub
commit e41f41b0a6
3 changed files with 29 additions and 14 deletions

View file

@ -116,6 +116,7 @@ public:
bool valid() const; bool valid() const;
void move(T x, T y); void move(T x, T y);
std::string to_string() const; std::string to_string() const;
T area() const;
// define some operators // define some operators
box2d_type& operator+=(box2d_type const& other); box2d_type& operator+=(box2d_type const& other);

View file

@ -407,6 +407,11 @@ std::string box2d<T>::to_string() const
return s.str(); return s.str();
} }
template <typename T>
T box2d<T>::area() const
{
return width() * height();
}
template <typename T> template <typename T>
box2d<T>& box2d<T>::operator+=(box2d<T> const& other) box2d<T>& box2d<T>::operator+=(box2d<T> const& other)

View file

@ -187,23 +187,26 @@ base_symbolizer_helper::base_symbolizer_helper(
initialize_points(); initialize_points();
} }
struct largest_bbox_first template <typename It>
static It largest_bbox(It begin, It end)
{ {
bool operator() (geometry::geometry<double> const* g0, geometry::geometry<double> const* g1) const if (begin == end)
{ {
box2d<double> b0 = geometry::envelope(*g0); return end;
box2d<double> b1 = geometry::envelope(*g1);
return b0.width() * b0.height() > b1.width() * b1.height();
} }
bool operator() (base_symbolizer_helper::geometry_cref const& g0, It largest_geom = begin;
base_symbolizer_helper::geometry_cref const& g1) const double largest_bbox = geometry::envelope(*largest_geom).area();
for (++begin; begin != end; ++begin)
{ {
// TODO - this has got to be expensive! Can we cache bbox's if there are repeated calls to same geom? double bbox = geometry::envelope(*begin).area();
box2d<double> b0 = geometry::envelope(g0); if (bbox > largest_bbox)
box2d<double> b1 = geometry::envelope(g1); {
return b0.width() * b0.height() > b1.width() * b1.height(); largest_bbox = bbox;
largest_geom = begin;
}
} }
}; return largest_geom;
}
void base_symbolizer_helper::initialize_geometries() const void base_symbolizer_helper::initialize_geometries() const
{ {
@ -216,10 +219,16 @@ void base_symbolizer_helper::initialize_geometries() const
type == geometry::geometry_types::MultiPolygon) type == geometry::geometry_types::MultiPolygon)
{ {
bool largest_box_only = text_props_->largest_bbox_only; bool largest_box_only = text_props_->largest_bbox_only;
if (largest_box_only) if (largest_box_only && geometries_to_process_.size() > 1)
{ {
geometries_to_process_.sort(largest_bbox_first()); auto largest_geom = largest_bbox(
geometries_to_process_.begin(),
geometries_to_process_.end());
geo_itr_ = geometries_to_process_.begin(); geo_itr_ = geometries_to_process_.begin();
if (geo_itr_ != largest_geom)
{
std::swap(*geo_itr_, *largest_geom);
}
geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end()); geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end());
} }
} }