删除重复项:如何为 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 编写排序谓词?的主要内容,如果未能解决你的问题,请参考以下文章

删除每个分区的重复项

如何为列表框(JList)动态添加删除项?在线等

如何为ListBox的每个项添加“删除”按钮并实现其功能?

如何为从 cPanel 中删除“Core.XXXX”文件创建 CRON [重复]

使用 boost::geometry::buffer 函数

boost::geometry 中无效几何的数据集