make geometry methods templated to allow using modified geometry types ( e.g variant<reference_wrapper<T>..>
symbolizer_helper - store geometries in custom varaint using reference_wrapper<T const>
This commit is contained in:
parent
22de30bb37
commit
389d00d442
7 changed files with 133 additions and 38 deletions
|
@ -38,21 +38,53 @@ struct geometry_centroid
|
|||
geometry_centroid(point & pt)
|
||||
: pt_(pt) {}
|
||||
|
||||
result_type operator() (geometry const& geom) const
|
||||
template <typename T>
|
||||
result_type operator() (T const& geom) const
|
||||
{
|
||||
return mapnik::util::apply_visitor(*this, geom);
|
||||
return util::apply_visitor(*this, geom);
|
||||
}
|
||||
|
||||
result_type operator() (geometry_empty const&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result_type operator() (geometry_collection const& collection) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
result_type operator() (T const& geom) const
|
||||
result_type operator() (point const& geom) const
|
||||
{
|
||||
boost::geometry::centroid(geom, pt_);
|
||||
return true;
|
||||
}
|
||||
|
||||
result_type operator() (line_string const& geom) const
|
||||
{
|
||||
boost::geometry::centroid(geom, pt_);
|
||||
return true;
|
||||
}
|
||||
|
||||
result_type operator() (polygon const& geom) const
|
||||
{
|
||||
boost::geometry::centroid(geom, pt_);
|
||||
return true;
|
||||
}
|
||||
|
||||
result_type operator() (multi_point const& geom) const
|
||||
{
|
||||
boost::geometry::centroid(geom, pt_);
|
||||
return true;
|
||||
}
|
||||
|
||||
result_type operator() (multi_line_string const& geom) const
|
||||
{
|
||||
boost::geometry::centroid(geom, pt_);
|
||||
return true;
|
||||
}
|
||||
|
||||
result_type operator() (multi_polygon const& geom) const
|
||||
{
|
||||
boost::geometry::centroid(geom, pt_);
|
||||
return true;
|
||||
|
@ -62,9 +94,10 @@ struct geometry_centroid
|
|||
|
||||
}
|
||||
|
||||
inline bool centroid(mapnik::geometry::geometry const& geom, point & pt)
|
||||
template <typename T>
|
||||
inline bool centroid(T const& geom, point & pt)
|
||||
{
|
||||
return detail::geometry_centroid(pt) (geom);
|
||||
return detail::geometry_centroid(pt)(geom);
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
|
@ -34,7 +34,8 @@ struct geometry_envelope
|
|||
{
|
||||
using bbox_type = box2d<double>;
|
||||
|
||||
bbox_type operator() (mapnik::geometry::geometry const& geom) const
|
||||
template <typename T>
|
||||
bbox_type operator() (T const& geom) const
|
||||
{
|
||||
return mapnik::util::apply_visitor(*this, geom);
|
||||
}
|
||||
|
@ -106,7 +107,8 @@ struct geometry_envelope
|
|||
|
||||
}
|
||||
|
||||
inline mapnik::box2d<double> envelope(mapnik::geometry::geometry const& geom)
|
||||
template <typename T>
|
||||
inline mapnik::box2d<double> envelope(T const& geom)
|
||||
{
|
||||
return detail::geometry_envelope() (geom);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,8 @@ namespace mapnik { namespace geometry { namespace detail {
|
|||
|
||||
struct geometry_type
|
||||
{
|
||||
mapnik::geometry::geometry_types operator () (mapnik::geometry::geometry const& geom) const
|
||||
template <typename T>
|
||||
mapnik::geometry::geometry_types operator () (T const& geom) const
|
||||
{
|
||||
return mapnik::util::apply_visitor(*this, geom);
|
||||
}
|
||||
|
@ -78,7 +79,8 @@ struct geometry_type
|
|||
};
|
||||
} // detail
|
||||
|
||||
static inline mapnik::geometry::geometry_types geometry_type(mapnik::geometry::geometry const& geom)
|
||||
template <typename T>
|
||||
static inline mapnik::geometry::geometry_types geometry_type(T const& geom)
|
||||
{
|
||||
return detail::geometry_type()(geom);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,13 @@ using vertex_converter_type = vertex_converter<placement_finder_adapter<placemen
|
|||
class base_symbolizer_helper
|
||||
{
|
||||
public:
|
||||
|
||||
using point_cref = std::reference_wrapper<geometry::point const>;
|
||||
using line_string_cref = std::reference_wrapper<geometry::line_string const>;
|
||||
using polygon_cref = std::reference_wrapper<geometry::polygon const>;
|
||||
using geometry_cref = util::variant<point_cref, line_string_cref, polygon_cref>;
|
||||
// Using list instead of vector, because we delete random elements and need iterators to stay valid.
|
||||
using geometry_container_type = std::list<geometry_cref>;
|
||||
base_symbolizer_helper(symbolizer_base const& sym,
|
||||
feature_impl const& feature,
|
||||
attributes const& vars,
|
||||
|
@ -86,13 +93,12 @@ protected:
|
|||
float scale_factor_;
|
||||
|
||||
//Processing
|
||||
// Using list instead of vector, because we delete random elements and need iterators to stay valid.
|
||||
// Remaining geometries to be processed.
|
||||
mutable std::list<geometry::geometry*> geometries_to_process_;
|
||||
mutable geometry_container_type geometries_to_process_;
|
||||
// Geometry currently being processed.
|
||||
mutable geometry_container_type::iterator geo_itr_;
|
||||
// Remaining points to be processed.
|
||||
mutable std::list<pixel_position> points_;
|
||||
// Geometry currently being processed.
|
||||
mutable std::list<geometry::geometry*>::iterator geo_itr_;
|
||||
// Point currently being processed.
|
||||
mutable std::list<pixel_position>::iterator point_itr_;
|
||||
// Use point placement. Otherwise line placement is used.
|
||||
|
|
|
@ -34,7 +34,8 @@ struct vertex_processor
|
|||
vertex_processor(processor_type& proc)
|
||||
: proc_(proc) {}
|
||||
|
||||
void operator() (geometry const& geom)
|
||||
template <typename Geometry>
|
||||
void operator() (Geometry const& geom)
|
||||
{
|
||||
util::apply_visitor(*this, geom);
|
||||
}
|
||||
|
|
|
@ -87,12 +87,12 @@ pixel_position_list const& group_symbolizer_helper::get()
|
|||
else
|
||||
{
|
||||
using apply_find_line_placements = detail::apply_find_line_placements<group_symbolizer_helper>;
|
||||
for (auto const* geom : geometries_to_process_)
|
||||
for (auto const& geom : geometries_to_process_)
|
||||
{
|
||||
// TODO to support clipped geometries this needs to use
|
||||
// vertex_converters
|
||||
apply_find_line_placements apply(t_, prj_trans_, *this);
|
||||
mapnik::util::apply_visitor(geometry::vertex_processor<apply_find_line_placements>(apply), *geom);
|
||||
mapnik::util::apply_visitor(geometry::vertex_processor<apply_find_line_placements>(apply), geom);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,54 @@ struct apply_vertex_placement
|
|||
proj_transform const& prj_trans_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct split_multi_geometries
|
||||
{
|
||||
using container_type = T;
|
||||
split_multi_geometries(container_type & cont)
|
||||
: cont_(cont) {}
|
||||
|
||||
void operator() (geometry::geometry_empty const&) const {}
|
||||
void operator() (geometry::multi_point const& multi_pt) const
|
||||
{
|
||||
for ( auto const& pt : multi_pt )
|
||||
{
|
||||
cont_.push_back(std::move(base_symbolizer_helper::geometry_cref(std::cref(pt))));
|
||||
}
|
||||
}
|
||||
void operator() (geometry::multi_line_string const& multi_line) const
|
||||
{
|
||||
for ( auto const& line : multi_line )
|
||||
{
|
||||
cont_.push_back(std::move(base_symbolizer_helper::geometry_cref(std::cref(line))));
|
||||
}
|
||||
}
|
||||
|
||||
void operator() (geometry::multi_polygon const& multi_poly) const
|
||||
{
|
||||
for ( auto const& poly : multi_poly )
|
||||
{
|
||||
cont_.push_back(std::move(base_symbolizer_helper::geometry_cref(std::cref(poly))));
|
||||
}
|
||||
}
|
||||
void operator() (geometry::geometry_collection const& collection) const
|
||||
{
|
||||
#if 0
|
||||
for ( auto const& geom : collection)
|
||||
{
|
||||
(*this)(geom);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
void operator() (Geometry const& geom) const
|
||||
{
|
||||
cont_.push_back(std::move(base_symbolizer_helper::geometry_cref(std::cref(geom))));
|
||||
}
|
||||
container_type & cont_;
|
||||
};
|
||||
|
||||
} // ns detail
|
||||
|
||||
base_symbolizer_helper::base_symbolizer_helper(
|
||||
|
@ -108,6 +156,13 @@ struct largest_bbox_first
|
|||
box2d<double> b1 = geometry::envelope(*g1);
|
||||
return b0.width() * b0.height() > b1.width() * b1.height();
|
||||
}
|
||||
bool operator() (base_symbolizer_helper::geometry_cref const& g0,
|
||||
base_symbolizer_helper::geometry_cref const& g1) const
|
||||
{
|
||||
box2d<double> b0 = geometry::envelope(g0);
|
||||
box2d<double> b1 = geometry::envelope(g1);
|
||||
return b0.width() * b0.height() > b1.width() * b1.height();
|
||||
}
|
||||
};
|
||||
|
||||
void base_symbolizer_helper::initialize_geometries() const
|
||||
|
@ -117,7 +172,9 @@ void base_symbolizer_helper::initialize_geometries() const
|
|||
|
||||
geometry::geometry const& geom = feature_.get_geometry();
|
||||
geometry::geometry_types type = geometry::geometry_type(geom);
|
||||
|
||||
// FIXME: how to handle MultiLinePolygon
|
||||
|
||||
if (type == geometry::geometry_types::Polygon)
|
||||
{
|
||||
if (minimum_path_length > 0)
|
||||
|
@ -125,24 +182,28 @@ void base_symbolizer_helper::initialize_geometries() const
|
|||
box2d<double> gbox = t_.forward(geometry::envelope(geom), prj_trans_);
|
||||
if (gbox.width() >= minimum_path_length)
|
||||
{
|
||||
geometries_to_process_.push_back(const_cast<geometry::geometry*>(&geom));
|
||||
//geometries_to_process_.push_back(const_cast<geometry::geometry*>(&geom));
|
||||
geometries_to_process_.push_back(std::move(geometry_cref(std::cref(geom.get<geometry::polygon>()))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
geometries_to_process_.push_back(const_cast<geometry::geometry*>(&geom));
|
||||
//geometries_to_process_.push_back(const_cast<geometry::geometry*>(&geom));
|
||||
geometries_to_process_.push_back(std::move(geometry_cref(std::cref(geom.get<geometry::polygon>()))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
geometries_to_process_.push_back(const_cast<geometry::geometry*>(&geom));
|
||||
//geometries_to_process_.push_back(const_cast<geometry::geometry*>(&geom));
|
||||
util::apply_visitor(detail::split_multi_geometries<geometry_container_type>(geometries_to_process_), geom);
|
||||
}
|
||||
|
||||
// FIXME: return early if geometries_to_process_.empty() ?
|
||||
if (largest_box_only)
|
||||
{
|
||||
geometries_to_process_.sort(largest_bbox_first());
|
||||
geo_itr_ = geometries_to_process_.begin();
|
||||
geometries_to_process_.erase(++geo_itr_,geometries_to_process_.end());
|
||||
geometries_to_process_.erase(++geo_itr_, geometries_to_process_.end());
|
||||
}
|
||||
geo_itr_ = geometries_to_process_.begin();
|
||||
}
|
||||
|
@ -164,24 +225,14 @@ void base_symbolizer_helper::initialize_points() const
|
|||
double label_y=0.0;
|
||||
double z=0.0;
|
||||
|
||||
for (auto * geom_ptr : geometries_to_process_)
|
||||
for (auto const& geom : geometries_to_process_)
|
||||
{
|
||||
geometry::geometry const& geom = *geom_ptr;
|
||||
//geometry::geometry const& geom = *geom_ptr;
|
||||
if (how_placed == VERTEX_PLACEMENT)
|
||||
{
|
||||
using apply_vertex_placement = detail::apply_vertex_placement<std::list<pixel_position> >;
|
||||
apply_vertex_placement apply(points_, t_, prj_trans_);
|
||||
util::apply_visitor(geometry::vertex_processor<apply_vertex_placement>(apply), geom);
|
||||
#if 0
|
||||
va.rewind(0);
|
||||
for(unsigned i = 0; i < va.size(); ++i)
|
||||
{
|
||||
va.vertex(&label_x, &label_y);
|
||||
prj_trans_.backward(label_x, label_y, z);
|
||||
t_.forward(&label_x, &label_y);
|
||||
points_.emplace_back(label_x, label_y);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -204,8 +255,6 @@ void base_symbolizer_helper::initialize_points() const
|
|||
label_x = pt.x;
|
||||
label_y = pt.y;
|
||||
success = true;
|
||||
|
||||
//success = label::centroid(va, label_x, label_y);
|
||||
}
|
||||
else if (how_placed == INTERIOR_PLACEMENT)
|
||||
{
|
||||
|
@ -282,10 +331,12 @@ bool text_symbolizer_helper::next_line_placement() const
|
|||
continue; //Reexecute size check
|
||||
}
|
||||
|
||||
auto type = geometry::geometry_type(**geo_itr_);
|
||||
if (type == geometry::LineString) // ??
|
||||
|
||||
//auto type = geometry::geometry_type(*geo_itr_.get());
|
||||
|
||||
if (geo_itr_->is<base_symbolizer_helper::line_string_cref>()) // line_string
|
||||
{
|
||||
auto const& line = util::get<geometry::line_string>(**geo_itr_);
|
||||
auto const& line = util::get<geometry::line_string const>(*geo_itr_);
|
||||
geometry::line_string_vertex_adapter va(line);
|
||||
converter_.apply(va);
|
||||
if (adapter_.status())
|
||||
|
|
Loading…
Reference in a new issue