我正在尝试使用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;
}
任何帮助都非常感谢。
是的,虽然你可能是对的,可以制定一个战略,但没有实施。
一个小的并排测试清楚地表明,该策略没有在地理坐标系中实现:
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
查看文档策略表明,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;
也许我们可以"结束"了。与"just"为你的坐标系统专门设计侧边策略?更有趣的是:strategy::side::geographic
存在。我对参数的理解不够深入(例如,大地测量解策略是什么意思?),但也许你可以从那里入手?
我相信,如果你知道需要做什么,邮件列表中乐于助人的开发人员将非常愿意指导如何将其纳入库的技术问题。