删除重复项:如何为 boost::geometry::box 编写排序谓词?
Posted
技术标签:
【中文标题】删除重复项:如何为 boost::geometry::box 编写排序谓词?【英文标题】:removing duplicates: How do I write a sort predicate for boost::geometry::box? 【发布时间】:2018-05-24 02:47:09 【问题描述】:我在这样的课程中使用boost::geometry::model::box
:
struct Feature
typedef boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> point;
typedef boost::geometry::model::box<point> box;
box bounds;
//... other members ...
;
std::list<Feature> v;
我想删除v
中的重复项。
通常我会编写一个排序谓词以便我可以这样做:
v.sort(sort_pred); //?
std::unique(v.begin(), v.end());
我可以使用boost::geometry::equals
(如How do I compare Boost Geometries? 中所述)来编写operator==
,所以std::unique
有效。是否有类似的函数可以用来将谓词写入sort
,还是需要从头开始编写?
或者,boost::geometry
中是否有更好的方法来删除重复项?
【问题讨论】:
【参考方案1】:我认为您不能重复使用来自 boost::geometry::index
的任何内容,因为(遗憾地)即使是 nearest()
查询的结果也没有排序。
所以,你来看看我的……最简单的看法:
Live On Coliru
#include <boost/geometry.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
// #include <boost/range/adaptors.hpp>
#include <tuple>
#include <iostream>
#include <iomanip>
namespace bg = boost::geometry;
namespace bgm = bg::model;
typedef bgm::point<double, 2, bg::cs::cartesian> point;
typedef bgm::box<point> box;
namespace std
// less
template <> struct less<point>
bool operator()(point const& a, point const& b) const return std::tie(a.get<0>(), a.get<1>()) < std::tie(b.get<0>(), b.get<1>());
;
template <> struct less<box>
bool operator()(box const& a, box const& b) const return
std::tie(a.min_corner().get<0>(), a.min_corner().get<1>(), a.max_corner().get<0>(), a.max_corner().get<1>())
< std::tie(b.min_corner().get<0>(), b.min_corner().get<1>(), b.max_corner().get<0>(), b.max_corner().get<1>());
;
// equal_to
template <> struct equal_to<point>
bool operator()(point const& a, point const& b) const return std::tie(a.get<0>(), a.get<1>()) == std::tie(b.get<0>(), b.get<1>());
;
template <> struct equal_to<box>
bool operator()(box const& a, box const& b) const return
std::tie(a.min_corner().get<0>(), a.min_corner().get<1>(), a.max_corner().get<0>(), a.max_corner().get<1>())
== std::tie(b.min_corner().get<0>(), b.min_corner().get<1>(), b.max_corner().get<0>(), b.max_corner().get<1>());
;
struct Feature
box bounds;
//... other members ...
std::string other;
friend std::ostream& operator<<(std::ostream& os, Feature const& f)
return os << "" << bg::wkt(f.bounds) << ", " << std::quoted(f.other) << "";
struct less_by_box : std::less<box>
bool operator()(Feature const& a, Feature const& b) const return std::less<box>::operator()(a.bounds, b.bounds);
;
struct by_box : std::equal_to<box>
bool operator()(Feature const& a, Feature const& b) const return std::equal_to<box>::operator()(a.bounds, b.bounds);
;
;
int main()
std::vector<Feature> v
box 2,3, 4,5 , "three" ,
box 1,2, 3,4 , "two" ,
box 2,3, 4,5 , "one" ,
;
auto dump = [&]
std::cout << "Size: " << v.size() << "\n";
for (Feature const& f : v) std::cout << f << "\n";
;
dump();
std::cout << " -- Sort, Unique, Erase:\n";
std::stable_sort(v.begin(), v.end(), Feature::less_by_box);
v.erase(std::unique(v.begin(), v.end(), Feature::by_box), v.end());
dump();
打印
Size: 3
POLYGON((2 3,2 5,4 5,4 3,2 3)), "three"
POLYGON((1 2,1 4,3 4,3 2,1 2)), "two"
POLYGON((2 3,2 5,4 5,4 3,2 3)), "one"
-- Sort, Unique, Erase:
Size: 2
POLYGON((1 2,1 4,3 4,3 2,1 2)), "two"
POLYGON((2 3,2 5,4 5,4 3,2 3)), "three"
【讨论】:
这类似于我最终所做的,除了我没有阅读 std::tie 所以我的更加冗长......以上是关于删除重复项:如何为 boost::geometry::box 编写排序谓词?的主要内容,如果未能解决你的问题,请参考以下文章