【问题标题】:How Do I Make A Rectangle in GEOS? [closed]如何在 GEOS 中制作矩形? [关闭]
【发布时间】:2014-12-25 00:01:32
【问题描述】:

如何使用 GEOS 库的 C++ API 制作矩形?

【问题讨论】:

  • 我当然不是geos 库的专家(我第一次在这里读到这个)。不过,2 分钟的研究让我找到了geos::geom::Polygon,这看起来是一个很好的起点。 (缺乏研究也是 SO 的关闭原因)。如果您遇到了一些特殊问题,请详细说明您的问题。
  • 感谢您的帮助,@πάντα ῥεῖ。如果您进行了充分的搜索,并且仅在我认为进行了充分的研究后才发布,我就不会问这个问题。我拼凑起来的实际答案可能比我们任何一个人预期的都要复杂,尤其是对于似乎被广泛使用的库。
  • 关于您的第一条评论,@πάντα ῥεῖ,我认为这个问题的格式正确,并且没有寻找会吸引自以为是的答案/垃圾邮件的资源。通过我的代表,我已经看到了足够多的这些问题,知道它们对未来的编码员有多大用处。
  • @Richard “我认为这个问题的格式很好......”嗯,我不是唯一一个。已经有 3 个其他用户也发现了这个问题。如果您有一个广泛的问题,并希望将其设为规范问答,请先进行研究,然后一次性发布问题和答案。这将使它在短期内更好地实现,而不是看到一个没有答案的糟糕问题。 (here's a good sample 我指的是)。
  • 这个问题及其答案非常有用。真的没有什么可以给出简明的例子。这是我在网上找到的。如果 Stack Overflow 上的每个“我该怎么做”问题都被关闭,那么就不会有任何帖子了!

标签: c++ geos


【解决方案1】:

以下实现在GEOS 中完成工作。

//Compile with: g++ code.cpp -lgeos
//Updated: 2019-03-31
#include <geos/geom/PrecisionModel.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/GeometryFactory.h>
#include <iostream>
#include <memory>

geos::geom::Polygon* MakeBox(double xmin, double ymin, double xmax, double ymax){
  std::unique_ptr<geos::geom::PrecisionModel> pm(new geos::geom::PrecisionModel());

  geos::geom::GeometryFactory::unique_ptr factory = geos::geom::GeometryFactory::create(pm.get(), -1);
  geos::geom::CoordinateSequence *temp = factory->getCoordinateSequenceFactory()->create((std::size_t) 0, 0);

  temp->add(geos::geom::Coordinate(xmin, ymin));
  temp->add(geos::geom::Coordinate(xmin, ymax));
  temp->add(geos::geom::Coordinate(xmax, ymax));
  temp->add(geos::geom::Coordinate(xmax, ymin));
  //Must close the linear ring or we will get an error:
  //"Points of LinearRing do not form a closed linestring"
  temp->add(geos::geom::Coordinate(xmin, ymin));

  geos::geom::LinearRing *shell=factory->createLinearRing(temp);

  //NULL in this case could instead be a collection of one or more holes
  //in the interior of the polygon
  return factory->createPolygon(shell,NULL);
}

int main(){
  geos::geom::Polygon* box = MakeBox(0,0,10,10);
  std::cout<<box->getArea()<<std::endl;
  delete box; //Important to avoid memory leaks
}

作为参考,您也可以使用boost::polygon 库来完成此操作,如下所示。

//Compile with: g++ code.cpp
#include <boost/polygon/polygon.hpp>
#include <iostream>
namespace gtl = boost::polygon;

typedef gtl::polygon_data<float> Polygon;

Polygon MakeBox(float xmin, float ymin, float xmax, float ymax){
  typedef gtl::polygon_traits<Polygon>::point_type Point;
  Point pts[] = {
    gtl::construct<Point>(xmin, ymin),
    gtl::construct<Point>(xmin, ymax),
    gtl::construct<Point>(xmax, ymax),
    gtl::construct<Point>(xmax, ymin)
  };
  Polygon poly;
  gtl::set_points(poly, pts, pts+4);

  return poly;
}

int main(){
  Polygon box = MakeBox(0,0,10,10);
  std::cout<<gtl::area(box)<<std::endl;
}

还有Clipper。请注意,Clipper 不能使用浮点坐标。

#include "clipper_cpp/clipper.hpp"
#include <iostream>

ClipperLib::Paths MakeBox(int xmin, int ymin, int xmax, int ymax){
  ClipperLib::Paths box(1);
  //Note that we run the path in the reverse direction to previous examples in
  //order to maintain positive area
  box[0] << ClipperLib::IntPoint(xmin,ymin) << ClipperLib::IntPoint(xmax,ymin)
         << ClipperLib::IntPoint(xmax,ymax) << ClipperLib::IntPoint(xmin,ymax);
  return box;
}

int main(){
  ClipperLib::Paths box = MakeBox(0,0,10,10);
  std::cout<<ClipperLib::Area(box[0])<<std::endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2017-11-20
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多