一、Geos库的安装和计算多边形是否相交

1.Geos库的安装

背景:项目需要判断多边形ROI区域和识别目标Bounding Box是否重叠。作者是在Jetson nano开发板上编译Geos,因为deepstream使用的是c语言,因此我使用Geos_c库。

1.1 下载 geos-3.8.0.tar.bz2

geos官网

1.2 安装

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"

2.计算多边形是否相交

2.1 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;
}

2.2 C++实现

#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库学习

你可能感兴趣的:(Geos,c语言)