问题描述
我有 2 个框的范围(值在相同的投影/CRS 中)。如何使用 boost 将它们转换为多边形? Boost 多边形需要某种 WKT,我只有每个框的范围如下,指定其边界框坐标(每个框的范围如下所示)
minX = 394702.91392588202
minY = 6432746.6604581000
maxX = 403253.65448691702
maxY = 6439166.2975105597
我相信增强多边形需要某种 wkt
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
int main()
{
typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;
polygon a;
boost::geometry::read_wkt("polyGON((123.345 6205.885,5873.9832 6205.885,395873.998 674.0062,30.30683 614.300,910.3083 6435.40))",a);
return 0;
}
我的目的是使用 boost 将我的范围转换为多边形。任何指示如何实现这一点?
解决方法
我从您的问题中发现了 some fine points of confusion,但让我们用闪光灯照亮(通向)解决方案:
Boost Geometry 有一个 Box 概念,可以直接使用:
double minX = 394702.91392588202,minY = 6432746.6604581000,maxX = 403253.65448691702,maxY = 6439166.297510559;
box b{{minX,minY},{maxX,maxY}};
std::cout << bg::wkt(b) << "\n";
打印什么
POLYGON((394703 6.43275e+06,394703 6.43917e+06,403254 6.43917e+06,403254 6.43
275e+06,394703 6.43275e+06))
注意多边形以起点作为闭合点以满足概念要求。另请注意,外圈处于特定方向。如果您的盒子的角点混淆了,您可以使用 bg::correct
对环进行正确排序。
现在,如果您必须将其作为多边形,您可以通过多种方式实现。显然,从 WKT 读取是最灵活但效率不高的。
分配
我建议这样做,因为与手动处理坐标相比,它相对高效且不易出错。如果 b
仍然是上面的 box
:
polygon a;
bg::assign(a,b);
std::cout << bg::wkt(a) << "\n";
这与盒子的打印相同。
构建
polygon a{{
{minX,{minX,maxY},// closed
}};
std::cout << bg::wkt(a) << "\n";
再次打印相同的内容。另外,再次注意对点进行排序并关闭多边形!
分配点
使用库原语:
polygon a;
bg::assign_points(a,std::vector{
point{minX,// closed
});
使用直接模型实现:
polygon a;
a.outer() = {
{minX,// closed
};
请注意,在后一种情况下,您需要维护模型的不变量/一致性(例如处理任何现有的内环)。
转换
当点类型不匹配时,使用 bg::convert(from,to)
代替 bg::assign(to,from)
。请注意,这是技术转换,而不是坐标系投影或类似的东西。
现场演示
结合上述信息的列表:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <iostream>
namespace bg = boost::geometry;
namespace bgm = bg::model;
using point = bgm::d2::point_xy<double>;
using polygon = bgm::polygon<point>;
using box = bgm::box<point>;
int main()
{
double minX = 394702.91392588202,maxY = 6439166.297510559;
box b{{minX,maxY}};
std::cout << bg::wkt(b) << "\n";
polygon a;
bg::assign_points(a,std::vector{
point{minX,// closed
});
a.outer() = {
{minX,// closed
};
bg::assign(a,b);
bg::convert(b,a);
std::cout << bg::wkt(a) << "\n";
std::string validity_reason;
bool valid = bg::is_valid(a,validity_reason);
std::cout << "Assigned points: " << validity_reason << "\n";
if (!valid)
{
bg::correct(a);
std::cout << "Corrected: " << bg::wkt(a) << "\n";
}
}
印刷品
POLYGON((394703 6.43275e+06,403254 6.43275e+06,394703 6.43275e+06))
POLYGON((394703 6.43275e+06,394703 6.43275e+06))
Assigned points: Geometry is valid