【问题标题】:Boost convex hull with longitude and latitude用经度和纬度提升凸包
【发布时间】:2021-06-08 21:55:19
【问题描述】:

我正在尝试将 boost 的 convex_hull 算法与经度/纬度坐标一起使用。

从这里:https://archive.fosdem.org/2017/schedule/event/geo_boost_geography/attachments/slides/1748/export/events/attachments/geo_boost_geography/slides/1748/FOSDEM17_vissarion.pdf

我可以看到我们可以计算两点之间的距离,甚至可以使用经度/纬度坐标找到区域(参见 PDF 文档的第 19 和 22 页)。

结合https://www.boost.org/doc/libs/1_75_0/libs/geometry/doc/html/geometry/reference/algorithms/convex_hull.html

我想出了这个:https://wandbox.org/permlink/2AGPUtHPWrlGFMTf,但它不会编译,为了方便,这里代码:

#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>

namespace bg = boost::geometry;

int main()
{
    typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree>> point;
    typedef boost::geometry::model::polygon<point> polygon;
    polygon poly;
    bg::read_wkt(" POLYGON ((4.346693 50.858306, 4.367945 50.852455, 4.366227 50.840809, 4.344961 50.833264, 4.338074 50.848677,4.346693 50.858306))",
    poly );
    
    polygon hull;
    boost::geometry::convex_hull(poly, hull);

    using boost::geometry::dsv;
    std::cout << "polygon: " << dsv(poly) << std::endl << "hull: " << dsv(hull) << std::endl;
}

非常感谢任何帮助。

【问题讨论】:

    标签: c++ boost convex-hull boost-geometry


    【解决方案1】:

    是的,虽然你可能是正确的,一个策略/可以/被制定,但没有实施。

    并排的小测试器清楚地表明该策略未针对地理坐标系实施:

    template <typename cs> void test() {
        using point   = bg::model::point<double, 2, cs>;
        using polygon = bg::model::polygon<point>;
        polygon poly;
        bg::read_wkt("POLYGON((4.346693 50.858306, 4.367945 50.852455, 4.366227 "
                     "50.840809, 4.344961 50.833264, 4.338074 50.848677,4.346693 "
                     "50.858306))",
                     poly);
    
        std::cout << std::fixed;
        std::cout << "Polygon:   " << bg::dsv(poly)       << std::endl;
        std::cout << "Perimeter: " << bg::perimeter(poly) << std::endl;
        std::cout << "Area:      " << bg::area(poly)      << std::endl;
    
        using Strategy = typename bg::strategy_convex_hull<polygon, point>::type;
        std::cout << "Strategy " << boost::core::demangle(typeid(Strategy).name()) << "\n";
    
        if constexpr (not std::is_same_v<Strategy, bg::strategy::not_implemented>) {
            polygon hull;
            bg::convex_hull(poly, hull);
            std::cout << "Hull: " << bg::dsv(hull) << std::endl;
        }
    }
    

    这也说明了一些其他策略已经实现(例如距离)。

    Live On Coliru

    int main() {
        std::cout << "Cartesian:\n";
        std::cout << "----------\n";
        test<bg::cs::cartesian>();
    
        std::cout << "\nGeographic:\n";
        std::cout <<   "-----------\n";
        test<bg::cs::geographic<bg::degree>>();
    }
    

    简化输出中的类型名:

        Cartesian:
        ----------
        Polygon:   (((4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)))
        Perimeter: 0.086184
        Area:      0.000488
        Strategy bg::strategy::convex_hull::graham_andrew<polygon, point>
        Hull: (((4.338074, 50.848677), (4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677)))
    
        Geographic:
        -----------
        Polygon:   (((4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)))
        Perimeter: 7663.398262
        Area:      3848183.734567
        Strategy bg::strategy::not_implemented
    

    查看documented strategies 表明graham_andrew 实际上是唯一可用的。

    您可能应该了解需要进行哪些调整才能使事情正常进行。从技术上讲,强制convex_hull 使用 Graham/Andrew 策略是可行的,但这似乎是不明智的,因为该特征意味着该策略特别根据坐标系取消选择:

    /*!
        \brief Traits class binding a convex hull calculation strategy to a coordinate system
        \ingroup convex_hull
        \tparam Tag tag of coordinate system
        \tparam Geometry the geometry type (hull operates internally per hull over geometry)
        \tparam Point point-type of output points
    */
    template
    <
        typename Geometry1,
        typename Point,
        typename CsTag = typename cs_tag<Point>::type
    >
    struct strategy_convex_hull
    {
        typedef strategy::not_implemented type;
    };
    

    这里有一个充满希望的提示:

        // TODO: User-defiend CS-specific side strategy
        typename strategy::side::services::default_strategy<cs_tag>::type side;
    

    也许我们可以“完成”“只是”为您的坐标系专门设置辅助策略?更有趣的是:a strategy::side::geographic 存在。我对参数的理解不够深入(例如,大地测量解决方案政策的含义是什么?),但也许你可以从那里得到它?

    我相信,如果您知道需要做什么,邮件列表中乐于助人的开发人员将非常愿意指导有关如何将其放入库中的技术问题。

    【讨论】:

    • 感谢您的宝贵时间。我将研究 strategy::side::geographic 并尝试了解它的工作原理。
    猜你喜欢
    • 2012-03-29
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多