2014-12-25 3 views
1

Как создать прямоугольник с использованием API-библиотеки библиотеки GEOS?Как сделать прямоугольник в GEOS?

+0

_ "StackOverflow, вы не можете помочь?" _ Нет! И с вашим фактическим представителем вы должны это хорошо знать: _'Questions, предлагающие нам рекомендовать или находить книгу, инструмент, библиотеку программного обеспечения, учебник или другой ресурс вне сайта, не относятся к теме для переполнения стека, поскольку они, как правило, привлекают упрямые ответы и спам. Вместо этого опишите проблему и то, что было сделано до сих пор, чтобы ее решить. ' –

+0

Я, конечно, не эксперт в библиотеке [tag: geos] (в первый раз я читал об этом здесь). Хотя, 2-минутное исследование привело меня к ['geos :: geom :: Polygon'] (http://geos.osgeo.org/doxygen/classgeos_1_1geom_1_1Polygon.html), который выглядит хорошей отправной точкой. (Отсутствие исследований также является причиной закрытия SO). Если у вас возникли определенные проблемы с этим, уточните свой вопрос. –

+1

Благодарим за помощь, @ πάντα ῥεῖ. Я бы не спросил, был ли поиск, который вы выполнили достаточно, и сделал проводку только после того, что я чувствовал, что это адекватное исследование. Фактический ответ, который я собрал вместе, более запутанный, чем, вероятно, любой из нас ожидал, особенно для того, что кажется широко используемой библиотекой. – Richard

ответ

4

Следующая реализация выполняет свою работу в GEOS.

//Compile with: g++ code.cpp -lgeos 
#include <geos/geom/Polygon.h> 
#include <geos/geom/LinearRing.h> 
#include <geos/geom/CoordinateSequenceFactory.h> 
#include <geos/geom/GeometryFactory.h> 
#include <iostream> 

geos::geom::Polygon* MakeBox(double xmin, double ymin, double xmax, double ymax){ 
    geos::geom::GeometryFactory factory; 
    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; 
} 

Для справки, вы можете сделать это с помощью 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; 
}