我得到了一个boost多边形的WKT字符串,它是由boost多边形在一个称为vectorPolygons的向量中的并构造的。
std::vector<boost::geometry::Polygon> vectorPolygons;
在下面的vectorPolygons中添加数据后,代码计算它的联合,然后提取多个多边形的WKT
if (!vectorPolygons.empty())
{
multi_polygon boost_multipolygon; // Will store union of polygons
// Create the union of all the polygons
for (const boost::geometry::Polygon& p : vectorPolygons) {
// add another polygon each iteration
multi_polygon tmp_poly;
boost::geometry::union_(boost_multipolygon, p, tmp_poly);
boost_multipolygon= tmp_poly;
boost::geometry::clear(tmp_poly);
}
std::string validity_reason;
bool valid = boost::geometry::is_valid(boost_multipolygon, validity_reason);
if (!valid)
{
boost::geometry::correct(boost_multipolygon);
}
std::stringstream ss;
ss << boost::geometry::wkt(boost_multipolygon);
std::string wkt = ss.str();
}
WKT字符串如下所示
MULTIPOLYGON(((40000 30000,40000 -0,30000 -0,30000 10000,20000 10000,20000 20000,10000 20000,0 20000,0 30000,40000 30000)))
当我使用下面的代码示例显示这个多多边形时,我不知道为什么它的显示总是倒转。在现实中,它应该完全颠倒它所展示的东西。
在提取WKT之前,我尝试在boost多多边形上使用boost::geometry::correct
,但是显示始终是旋转的。我做错什么了?
下面是代码,它试图显示上面生成的WKT,输出是颠倒的。
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/adapted/boost_polygon.hpp>
#include <vector>
namespace boost {
namespace geometry {
typedef model::d2::point_xy<double> point;
typedef model::polygon<point> polygon;
}
}
using multi_polygon = boost::geometry::model::multi_polygon<boost::geometry::polygon>;
namespace bg = boost::geometry;
int main()
{
// Specify the basic type
typedef boost::geometry::model::d2::point_xy<double> point_type;
multi_polygon b;
boost::geometry::read_wkt("MULTIPOLYGON(((40000 30000,40000 -0,30000 -0,30000 10000,20000 10000,20000 20000,10000 20000,0 20000,0 30000,40000 30000)))", b);
boost::geometry::correct(b);
// Declare a stream and an SVG mapper
std::ofstream svg("my_map.svg");
boost::geometry::svg_mapper<point_type> mapper(svg, 500, 500);
// Add geometries such that all these geometries fit on the map
mapper.add(b);
// Draw the geometries on the SVG map, using a specific SVG style
mapper.map(b, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:2");
// Destructor of map will be called - adding </svg>
// Destructor of stream will be called, closing the file
return 0;
}
发布于 2022-01-11 15:32:23
没有“右边朝上”。笛卡尔坐标系就是:坐标系。如何在视觉投影上映射它们是你的选择。
这是我的系统的输出:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <fstream>
#include <iostream>
namespace bg = boost::geometry;
int main()
{
using Point = bg::model::d2::point_xy<double>;
using Poly = bg::model::polygon<Point>;
bg::model::multi_polygon<Poly> p;
bg::read_wkt("MULTIPOLYGON(((40 30,40 -0,30 -0,30 10,20 10,20 20,10 20,0 20,0 30,40 30)))",
p);
{
std::ofstream svg("my_map.svg");
bg::svg_mapper<Point> mapper(svg, 400, 400);
mapper.add(p);
mapper.map(p, "fill-opacity:0.3;fill:rgb(51,51,153);stroke:rgb(51,51,153);stroke-width:1");
}
}
显示为
所以你可以看到斧头向下/向右生长。这与我能找到的第一台随机在线WKT渲染器是一致的:
按此计算,我认为输出是“正确的”。
翻转它?
您可以手动翻转系统:
for (auto& pt : make_iterator_range(bg::points_begin(p), bg::points_end(p))) {
pt.x(pt.x() * -1);
pt.y(pt.y() * -1);
}
结果
一种更通用的方法是使用一种可以在任意距离/数量上缩放、旋转和平移的变换:strategy.html
更新
我已经用实际数据更新了这个示例,网址是coliru.堆栈-crooked.com/a/2ba8df83a1ecce91。您共享的代码将我的输入标记为无效,boost::几何学::更正操作它并旋转输出。不可能保留输入以使输出不旋转吗?- 16个小时前的测试
逐点考虑:“不可能保留输入”--是的,总是可以保留无效的输入,而且您应该期望保留无效的输出。
然而,你没有说什么是被纠正的。我用你的数据运行我的代码:
POLYGON((30 10,30 -0,40 -0,40 10,30 10)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((30 10,40 10,40 -0,30 -0,30 10))): 100
POLYGON((30 20,30 10,40 10,40 20,30 20)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((40 -0,30 -0,30 10,30 20,40 20,40 -0))): 200
POLYGON((30 30,30 20,40 20,40 30,30 30)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((40 -0,30 -0,30 20,30 30,40 30,40 -0))): 300
POLYGON((20 20,20 10,30 10,30 20,20 20)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((30 20,30 30,40 30,40 -0,30 -0,30 10,20 10,20 20,30 20))): 400
POLYGON((20 30,20 20,30 20,30 30,20 30)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((40 30,40 -0,30 -0,30 10,20 10,20 20,20 30,40 30))): 500
POLYGON((10 30,10 20,20 20,20 30,10 30)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((40 30,40 -0,30 -0,30 10,20 10,20 20,10 20,10 30,40 30))): 600
POLYGON((0 30,0 20,10 20,10 30,0 30)): -100
Correcting source poly: Geometry has wrong orientation
Union: MULTIPOLYGON(((40 30,40 -0,30 -0,30 10,20 10,20 20,10 20,0 20,0 30,40 30))): 700
The important bit: "Correcting source poly: Geometry has wrong orientation".
在某种程度上,您的数据不是无效的,它只是无效的选择几何类型!您可以简单地更改多边形类型的方向:
using Poly = bg::model::polygon<Point, false>;
不作任何进一步的更改:http://coliru.stacked-crooked.com/a/f02e56fc2402112d
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <fstream>
#include <iostream>
namespace bg = boost::geometry;
template <typename T> auto from_wkt(std::string const& wkt) {
T result;
bg::read_wkt(wkt, result);
return result;
}
template <typename T> void check(T& geo, std::string_view label) {
for (std::string reason; !bg::is_valid(geo, reason); bg::correct(geo)) {
std::cout << "Correcting " << label << ": " << reason << "\n";
}
}
int main()
{
using Point = bg::model::d2::point_xy<double>;
using Poly = bg::model::polygon<Point, false>;
using MPoly = bg::model::multi_polygon<Poly>;
std::vector vectorPolygons{
from_wkt<Poly>(R"(POLYGON(( 30 10, 30 -0, 40 -0, 40 10, 30 10 )))"),
from_wkt<Poly>(R"(POLYGON(( 30 20, 30 10, 40 10, 40 20, 30 20 )))"),
from_wkt<Poly>(R"(POLYGON(( 30 30, 30 20, 40 20, 40 30, 30 30 )))"),
from_wkt<Poly>(R"(POLYGON(( 20 20, 20 10, 30 10, 30 20, 20 20 )))"),
from_wkt<Poly>(R"(POLYGON(( 20 30, 20 20, 30 20, 30 30, 20 30 )))"),
from_wkt<Poly>(R"(POLYGON(( 10 30, 10 20, 20 20, 20 30, 10 30 )))"),
from_wkt<Poly>(R"(POLYGON(( 0 30, 0 20, 10 20, 10 30, 0 30 )))"),
};
MPoly union_poly; // will store union of polygons
for (auto& p : vectorPolygons) {
std::cout << bg::wkt(p) << ": " << bg::area(p) << "\n";
check(p, "source poly");
MPoly tmp;
boost::geometry::union_(union_poly, p, tmp);
union_poly.swap(tmp);
//check(union_poly, "union");
std::cout << "Union: " << bg::wkt(union_poly) << ": "
<< bg::area(union_poly) << "\n";
}
{
std::ofstream svg("my_map.svg");
bg::svg_mapper<Point> mapper(svg, 400, 400);
mapper.add(union_poly);
mapper.map(union_poly,
"fill-opacity:0.1;fill:rgb(51,51,153);stroke:rgb(51,51,153);"
"stroke-width:0");
for (auto const& p : vectorPolygons) {
mapper.add(p);
mapper.map(
p,
"fill-opacity:0.3;fill:rgb(77,77,77);stroke:rgb(77,77,77);"
"stroke-width:1;stroke-dasharray:1 2");
}
}
}
打印
POLYGON((30 10,30 -0,40 -0,40 10,30 10)): 100
Union: MULTIPOLYGON(((30 10,30 -0,40 -0,40 10,30 10))): 100
POLYGON((30 20,30 10,40 10,40 20,30 20)): 100
Union: MULTIPOLYGON(((40 -0,40 20,30 20,30 10,30 -0,40 -0))): 200
POLYGON((30 30,30 20,40 20,40 30,30 30)): 100
Union: MULTIPOLYGON(((40 -0,40 30,30 30,30 20,30 -0,40 -0))): 300
POLYGON((20 20,20 10,30 10,30 20,20 20)): 100
Union: MULTIPOLYGON(((30 20,20 20,20 10,30 10,30 -0,40 -0,40 30,30 30,30 20))): 400
POLYGON((20 30,20 20,30 20,30 30,20 30)): 100
Union: MULTIPOLYGON(((40 30,20 30,20 20,20 10,30 10,30 -0,40 -0,40 30))): 500
POLYGON((10 30,10 20,20 20,20 30,10 30)): 100
Union: MULTIPOLYGON(((40 30,10 30,10 20,20 20,20 10,30 10,30 -0,40 -0,40 30))): 600
POLYGON((0 30,0 20,10 20,10 30,0 30)): 100
Union: MULTIPOLYGON(((40 30,0 30,0 20,10 20,20 20,20 10,30 10,30 -0,40 -0,40 30))): 700
摘要
故事的寓意:始终检查输入的数据是否有效。
此外,请注意,这些从来没有“旋转”输出。输出是简单的未定义的,而不是你想要的(它更类似于你正在寻找的形状的“负补足”,但这实际上是偶然的,结果没有具体说明,因为输入违反了预设条件)。
https://stackoverflow.com/questions/70664253
复制相似问题