我可以将矩形范围转换为增强多边形吗?

问题描述

我有 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)。请注意,这是技术转换,而不是坐标系投影或类似的东西。

现场演示

结合上述信息的列表:

Live On Coliru

#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