没有“正面朝上”。笛卡尔坐标系就是这样:坐标系。如何将它们映射到视觉投影上是您的选择。
这是我系统上的输出:
#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);
}
结果
一种更通用的方法是使用可以在任意距离/数量上缩放、旋转和平移的变换:https ://www.boost.org/doc/libs/1_78_0/libs/geometry/doc/html/geometry/reference/算法/变换/transform_3_with_strategy.html
更新
我已经用 cololiru.stacked-crooked.com/a/2ba8df83a1ecce91 上的实际数据更新了示例。您共享的代码将我的输入标记为无效,并且 boost::geometry::correct 对其进行操作并旋转输出。是否无法保留输入以使输出不旋转?–测试 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
概括
故事的寓意:始终检查您的输入数据是否有效。
另外,请注意,这些都没有“旋转”输出。输出只是未定义,而不是您想要的(它更类似于您正在寻找的形状的“负补码”,但这实际上是偶然的,结果是未指定的,因为输入违反了先决条件)。