背景:项目需要判断多边形ROI区域和识别目标Bounding Box是否重叠。作者是在Jetson nano开发板上编译Geos,因为deepstream使用的是c语言,因此我使用Geos_c库。
geos官网
cd geos-3.6.2
./configue //或选择安装的目录./configure --prefix=/usr/geos
make
make install
我这里建议(Jetson环境下)自定义安装目录,方便在gcc编译的时候,添加:
头文件
“-I/home/lieryang/geos/include”,
库文件地址
-L/home/lieryang/geos/lib","-lgeos_c"
#include
#include
#include
#include "geos_c.h"
void
notice(const char *fmt, ...) {
va_list ap;
fprintf( stdout, "NOTICE: ");
va_start (ap, fmt);
vfprintf( stdout, fmt, ap);
va_end(ap);
fprintf( stdout, "\n" );
}
void
log_and_exit(const char *fmt, ...) {
va_list ap;
fprintf( stdout, "ERROR: ");
va_start (ap, fmt);
vfprintf( stdout, fmt, ap);
va_end(ap);
fprintf( stdout, "\n" );
exit(1);
}
int
main(int argc, char **argv)
{
int i, n=1;
initGEOS(notice, log_and_exit);
printf("GEOS version %s\n", GEOSversion());
GEOSGeometry* g1;
GEOSGeometry* g2;
GEOSGeometry* shell;
const GEOSGeometry* gtmp;
GEOSCoordSequence* cs;
unsigned int npoints, ndims;
g1 = GEOSGeomFromWKT("POLYGON((0 0, 0 10,10 10,0 0 ))");
g2 = GEOSGeomFromWKT("POLYGON((0 11,20 20,20 11,0 11))");
gtmp = GEOSGetExteriorRing(g1);
cs = GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(gtmp));
g1 = GEOSGeom_createLinearRing(cs);
gtmp = GEOSGetExteriorRing(g2);
cs = GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(gtmp));
//if(GEOSCoordSeq_setXY(cs, 2, 20, 9)){printf("ok\n");};
g2 = GEOSGeom_createLinearRing(cs);
npoints = GEOSGetNumCoordinates(g1);/*坐标个数*/
ndims = GEOSGeom_getDimensions(g1);/*坐标维度*/
printf("Geometry coordinates: %dx%d\n", npoints, ndims);
if ( GEOSIntersects(g1, g2) ) printf("Intersect\n");
if ( GEOSDisjoint(g1, g2) ) printf("Disjoint\n");
if ( GEOSTouches(g1, g2) ) printf("Touches\n");
if ( GEOSCrosses(g1, g2) ) printf("Crosses\n");
if ( GEOSWithin(g1, g2) ) printf("Within\n");
if ( GEOSContains(g1, g2) ) printf("Contains\n");
if ( GEOSOverlaps(g1, g2) ) printf("Overlaps\n");
finishGEOS();
return EXIT_SUCCESS;
}
#include
#include
#include
#include "geos.h"
using namespace std;
using namespace geos;
using namespace geos::geom;
static const GeometryFactory* g_factory = geos::geom::GeometryFactory::getDefaultInstance(); //全局对象,所有的图形都由此对象创建
#if 0
//单点的创建
Point* createGeosPoint(double x, double y)
{
Coordinate pt(x, y); //坐标
Point* p = g_factory->createPoint(pt);
return p;
}
//多点的创建
MultiPoint* createGeosMultiPoint(double x, double y, double offset)
{
CoordinateArraySequence *cas = new CoordinateArraySequence(); //构建点序列
std::vector<Coordinate> points;
points.push_back(Coordinate(x, y));
points.push_back(Coordinate(x + offset, y));
points.push_back(Coordinate(x + 2 * offset, y + offset));
points.push_back(Coordinate(x + 3 * offset, y + 2 * offset));
MultiPoint* Mp = g_factory->createMultiPoint(points);
return Mp;
}
//非闭合线
LineString* createGeosLine(double x, double y, double offset)
{
CoordinateArraySequence *cas = new CoordinateArraySequence(); //构建点序列
cas->add(Coordinate(x, y));
cas->add(Coordinate(x, y + offset));
cas->add(Coordinate(x + offset, y + offset));
cas->add(Coordinate(x + offset, y + 2 * offset));
cas->add(Coordinate(x + 2 * offset, y + 2 * offset));
LineString *ls = g_factory->createLineString(cas);
return ls;
}
#endif
//创建一条环线,与线的区别就是环线是闭合的。即第一个点和最后一点重合
LinearRing* createGeosRing(double x, double y, double offset)
{
CoordinateArraySequence *cas = new CoordinateArraySequence(); //构建点序列
cas->add(Coordinate(x, y));
/*cas->add(Coordinate(x, y + offset));
cas->add(Coordinate(x + offset, y + offset));
cas->add(Coordinate(x + offset, y + 2 * offset));
cas->add(Coordinate(x + 2 * offset, y + 2 * offset));
cas->add(Coordinate(x + 2 * offset, y));*/
cas->add(Coordinate(x, y + offset));
cas->add(Coordinate(x + 2, y + offset));
cas->add(Coordinate(x + offset + 5, y + offset + 5));
cas->add(Coordinate(x + offset, y));
cas->add(Coordinate(x, y)); //与第一个点相等
LinearRing *lr = g_factory->createLinearRing(cas);
return lr;
}
//创建一个多边形,如果多边形内部没有孔洞实际上与环线是一样的
Polygon* createGeosPolygon(double x, double y, double offset)
{
LinearRing *lr = createGeosRing(x, y, offset);
Polygon *poly = g_factory->createPolygon(lr, NULL); //如果多边形中间没有孔洞,第二个参数设为NULL
return poly;
}
int main()
{
long StartTime, EndTime;
// GeoTest.cpp : 定义控制台应用程序的入口点。
//
#include
#include
#include "geos.h"
using namespace std;
cout << "GEOS库版本为:" << GEOS_VERSION << endl;
LineString *ls = createGeosRing(10, 10, 5);
cout << "线条点数:" << ls->getNumPoints() << " 线条长度:" << ls->getLength() << endl;
Polygon *p1 = createGeosPolygon(0, 0, 5);
Polygon *p2 = createGeosPolygon(10, 10, 5);
cout << "多边形面积:" << p1->getArea() << endl;
bool flag = p2->touches(p1);
StartTime = clock();/*计时开始*/
for(int i = 0; i < 1000; i++)
{
flag = p2->touches(p1);
}EndTime = clock();/*计时结束*/
cout << (EndTime - StartTime) << endl;
if(p2->disjoint(p1))
cout<<"不相交"<<endl;
else
{
if(p2->touches(p1))
cout<<"接触"<<endl;
else if(p2->overlaps(p1))
cout<<"部分重叠"<<endl;
else if(p2->covers(p1))
cout<<"覆盖"<<endl;
}
return 0;
}
参考
Geos库学习