GEOS使用记录【几何运算】
1.geos::geom::LineSegment相关计算
1.1 angle
计算的值为弧度,通过乘以180°除以Π得到角度,角度分正负,上半轴为正,下半轴为负;
geos::geom::LineSegment l1 = geos::geom::LineSegment(0,0,1,0);
geos::geom::LineSegment l2 = geos::geom::LineSegment(0,0,1,-1);
geos::geom::LineSegment l3 = geos::geom::LineSegment(1,-1,0,0);
qDebug()<<l1.angle()<<" "<<l2.angle()*180/M_PI<<" "<<l3.angle()*180/M_PI;
1.2 segmentFraction
给定一个点可以计算分位数,当点不在直线上时,通过计算垂足得到分位数;
double s = l1.segmentFraction({0.4,0});
2.geos::geom::Geometry相关计算
2.1.getBoundary
当Geometry中有多个polygon的图形时,返回的是多个图形的MULTILINESTRING
类型数据,当只有一个图形时,返回LINESTRING
类型数据。
geos::io::WKTReader reader;
geos::io::WKTWriter writer;
std::unique_ptr<geos::geom::Geometry> poly1 = reader.read("POLYGON((0 0,1 0,1 1,0 1,0 0))");
std::unique_ptr<geos::geom::Geometry> poly4 = reader.read("POLYGON((0.5 0.5,1.5 0.5,1.5 1.5,0.5 1.5,0.5 0.5))");
std::unique_ptr<geos::geom::Geometry> poly5 = reader.read("POLYGON((1 1,2 1,2 2,1 2,1 1))");
std::unique_ptr<geos::geom::Geometry> x1 = poly1->Union(poly4.get());
std::unique_ptr<geos::geom::Geometry> x2 = poly1->Union(poly5.get());
std::unique_ptr<Geometry> f = x1->getBoundary();
qDebug()<<QString::fromStdString(writer.write(f.get()));
f = x2->getBoundary();
qDebug()<<QString::fromStdString(writer.write(f.get()));
2.2.union
geos::io::WKTReader reader;
geos::io::WKTWriter writer;
std::unique_ptr<geos::geom::Geometry> poly1 = reader.read("POLYGON((0 0,1 0,1 1,0 1,0 0))");
std::unique_ptr<geos::geom::Geometry> poly2 = reader.read("POLYGON((0 2,2 0,3 1,1 2,0 2))");
std::unique_ptr<geos::geom::Geometry> poly4 = reader.read("POLYGON((0.5 0.5,1.5 0.5,1.5 1.5,0.5 1.5,0.5 0.5))");
std::unique_ptr<geos::geom::Geometry> x1 = poly1->Union(poly4.get());
qDebug()<<x1->getNumGeometries();
std::unique_ptr<geos::geom::Geometry> x2 = poly1->Union(poly2.get());
qDebug()<<x2->getNumGeometries();
打印结果是1,2,结果说明如果两个图形相交了会合并成一个,如果两个图形不相交会有两个图形;如果连续合并,原来两个分开的图形会因为poly4
的关系再次合并成一个。
std::unique_ptr<geos::geom::Geometry> x3 = poly1->Union(poly2.get())->Union(poly4.get());
qDebug()<<x3->getNumGeometries();
2.3.getEnvelope
该方法返回的是一个外接矩形,不管是多图形的情况还是单个图形仅返回一个矩形框,矩形框的范围囊括了所有图形。
geos::io::WKTReader reader;
geos::io::WKTWriter writer;
std::unique_ptr<geos::geom::Geometry> poly1 = reader.read("POLYGON((0 0,1 0,1 1,0 1,0 0))");
std::unique_ptr<geos::geom::Geometry> poly4 = reader.read("POLYGON((0.5 0.5,1.5 0.5,1.5 1.5,0.5 1.5,0.5 0.5))");
std::unique_ptr<geos::geom::Geometry> poly5 = reader.read("POLYGON((1 1,2 1,2 2,1 2,1 1))");
std::unique_ptr<geos::geom::Geometry> x1 = poly1->Union(poly4.get());
std::unique_ptr<geos::geom::Geometry> x2 = poly1->Union(poly5.get());
std::unique_ptr<Geometry> f = x1->getEnvelope();
qDebug()<<QString::fromStdString(writer.write(f.get()));
f = x2->getEnvelope();
qDebug()<<QString::fromStdString(writer.write(f.get()));
打印结果:
"POLYGON ((0 0, 1.5 0, 1.5 1.5, 0 1.5, 0 0))"
"POLYGON ((0 0, 2 0, 2 2, 0 2, 0 0))"
2.4.convexHull
该方法返回的是一个外接图形,但不一定是矩形,有时跟getEnvelope的结果类似,比如上面的情况。
std::unique_ptr<geos::geom::Geometry> f = x1->convexHull();
qDebug()<<QString::fromStdString(writer.write(f.get()));
f = x2->convexHull();
qDebug()<<QString::fromStdString(writer.write(f.get()));
更多示例:
std::unique_ptr<geos::geom::Geometry> poly1 = reader.read("POLYGON((1 0,2 0,2 0.2,1 0.2,1 0))");
std::unique_ptr<geos::geom::Geometry> poly2 = reader.read("POLYGON((1 0,1 0.2,0.2 1,0 1,1 0))");
std::unique_ptr<geos::geom::Geometry> poly3 = reader.read("POLYGON((0 1,0.2 1,0.2 2,0 2,0 1))");
std::unique_ptr<geos::geom::Geometry> x1 = poly1->Union(poly2.get());
std::unique_ptr<geos::geom::Geometry> x2 = x1->Union(poly3.get());
std::unique_ptr<geos::geom::Geometry> f = x2->convexHull();
qDebug()<<QString::fromStdString(writer.write(f.get()));
f = x2->getBoundary();
qDebug()<<QString::fromStdString(writer.write(f.get()));
f = x2->getEnvelope();
qDebug()<<QString::fromStdString(writer.write(f.get()));
打印结果:
"POLYGON ((1 0, 0 1, 0 2, 0.2 2, 2 0.2, 2 0, 1 0))"
"LINESTRING (2 0, 1 0, 0 1, 0 2, 0.2 2, 0.2 1, 1 0.2, 2 0.2, 2 0)"
"POLYGON ((0 0, 2 0, 2 2, 0 2, 0 0))"
2.5.project
该方法在原线上找到与参考线最近的两个点,按照参考线的顺序返回segment类型。
geos::geom::LineSegment l1 = geos::geom::LineSegment(0,0,10,0);
geos::geom::LineSegment l2 = geos::geom::LineSegment(-1,1,9,1);
geos::geom::LineSegment ret;
l1.project(l2, ret);//在原线上找到与参考线最近的两个点,按照参考线的顺序
qDebug()<<"ret result"<<ret.p0.x<<ret.p0.y<<ret.p1.x<<ret.p1.y;
打印结果:
ret result 0 0 9 0
3.geos::geom::MultiPoint
创建一个多点的方法
std::unique_ptr<geos::geom::Geometry> poly1 = reader.read("POLYGON((1 0,2 0,2 0.2,1 0.2,1 0))");
// std::unique_ptr<geos::geom::Geometry> poly2 = reader.read("POLYGON((1 0,1 0.2,0.2 1,0 1,1 0))");
std::unique_ptr<geos::geom::Geometry> poly3 = reader.read("POLYGON((0 1,0.2 1,0.2 2,0 2,0 1))");
// std::unique_ptr<geos::geom::Geometry> x1 = poly1->Union(poly2.get());
std::unique_ptr<geos::geom::Geometry> x2 = poly1->Union(poly3.get());
std::vector<geos::geom::Coordinate> seq;
for (int var = 0; var < x2->getNumGeometries(); ++var) {
for (int j = 0; j < x2->getGeometryN(var)->getNumPoints(); ++j) {
geos::geom::Coordinate c = x2->getGeometryN(var)->getCoordinates()->getAt(j);
seq.push_back(c);
}
}
std::unique_ptr<geos::geom::MultiPoint> points = factory->createMultiPoint(seq);