C++的GEOS库实现几何计算,多个面和一条线相交后得到多条线段的例子。

在vcpkg包管理工具的环境下使用VisualStudio,vcpkg确认已安装gdal:x64-windows库。

#include <drogon/drogon.h>
#include <stdio.h>
#include <stdarg.h>
#include <geos_c.h>
#include <iostream>
#include <math.h>

using namespace std;
static void geos_msg_handler(const char* fmt, ...){
    va_list ap;
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
}

double getPointX(double* dxdy) {
    return *dxdy;
}
double getPointY(double* dxdy) {
    return *(dxdy + 1);
}
double* getPointXY(GEOSGeometry* pt, GEOSWKTWriter* writer) {
    char* wkt = GEOSWKTWriter_write(writer, pt);
    //在这里,点对应的wkt字符串的小数部分固定是18位字符
    char* x = new char[18];
    char* y = new char[18];
    int state = 0;
    int count = 0;
    //第7位字符到第43位字符都是数字部分
    for (int i = 7; i < 44; i++) {
        if (state == 0) {
            *(x + count) = wkt[i];
            count++;
        }
        else {
            *(y + count) = wkt[i];
            count++;
        }
        if (wkt[i] == ' ') {
            count = 0;
            state = 1;
        }
    }
    double* dxdy = new double[2];
    *dxdy = atof(x);
    *(dxdy + 1) = atof(y);
    return dxdy;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    initGEOS(geos_msg_handler, geos_msg_handler);
    GEOSWKTReader* reader = GEOSWKTReader_create();
    GEOSGeometry* line_geo = GEOSWKTReader_read(reader, "LINESTRING(0.512114 0.5,1 1,1.5 1.5,2.5 0.5,4.5 1.5)");
    //GEOSGeometry* polygon_geo = GEOSWKTReader_read(reader, "MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)),((2 0,3 0,3 1,2 1,2 0)),((4 1,5 1,5 2,4 2,4 1)))");
    GEOSGeometry* polygon_geo = GEOSWKTReader_read(reader, "MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)),((2 0,3 0,3 1,2 1,2 0)),((4 1,5 1,5 2,4 2,4 1)))");
    GEOSGeometry* multi_line = GEOSIntersection(line_geo, polygon_geo);
    GEOSWKTWriter* writer = GEOSWKTWriter_create();
    int line_num = GEOSGetNumGeometries(multi_line);//线条的个数.

    for (int i = 0; i < line_num; i++) {
        const GEOSGeometry* line = GEOSGetGeometryN(multi_line, i);
        int point_num = GEOSGetNumCoordinates(line);
        cout << "第"<<i<<"条线:" << endl;
        for (int j = 0; j < point_num; j++) {
            GEOSGeometry* pt = GEOSGeomGetPointN(line, j);
            double* xy = getPointXY(pt, writer);
            cout << "x:" << xy[0] << "\t" << "y:" << xy[1] << endl;
        }
    }

    finishGEOS();

    return 0;
}


运行效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GEOS(Geometry Engine - Open Source,几何引擎开源)是一个用于处理地理空间数据的C++,提供了许多的几何分析函数,包括缓冲区分析。 要利用GEOS求一条线的缓冲区的外框线,可以按照以下步骤进行: 1. 定义线要素 首先需要定义一条线的要素,可以使用GEOS提供的GEOSGeom_createLineString函数创建一个线要素。 ```c GEOSCoordSequence* coords = GEOSCoordSeq_create(2, 2); GEOSCoordSeq_setX(coords, 0, 0.0); GEOSCoordSeq_setY(coords, 0, 0.0); GEOSCoordSeq_setX(coords, 1, 1.0); GEOSCoordSeq_setY(coords, 1, 1.0); GEOSGeometry* line = GEOSGeom_createLineString(coords); ``` 2. 计算缓冲区 使用GEOS提供的GEOSBuffer函数计算线的缓冲区,并指定缓冲区的半径和缓冲区的段数。 ```c double bufferDistance = 0.1; int bufferSegments = 16; GEOSGeometry* buffer = GEOSBuffer(line, bufferDistance, bufferSegments); ``` 3. 获取缓冲区的外框线 缓冲区的外框线是指缓冲区的边界线,可以使用GEOS提供的GEOSGeom_getExteriorRing函数获取缓冲区的外框线。 ```c GEOSGeometry* exterior = GEOSGeom_getExteriorRing(buffer); ``` 4. 输出外框线的坐标 最后可以使用GEOS提供的GEOSGeom_getCoordSeq函数获取外框线的坐标序列,并输出坐标。 ```c const GEOSCoordSequence* exteriorCoords = GEOSGeom_getCoordSeq(exterior); unsigned int exteriorSize = 0; GEOSCoordSeq_getSize(exteriorCoords, &exteriorSize); for (unsigned int i = 0; i < exteriorSize; i++) { double x, y; GEOSCoordSeq_getX(exteriorCoords, i, &x); GEOSCoordSeq_getY(exteriorCoords, i, &y); printf("(%f, %f)\n", x, y); } ``` 完整代码示例: ```c #include <geos_c.h> #include <stdio.h> int main() { // 创建线要素 GEOSCoordSequence* coords = GEOSCoordSeq_create(2, 2); GEOSCoordSeq_setX(coords, 0, 0.0); GEOSCoordSeq_setY(coords, 0, 0.0); GEOSCoordSeq_setX(coords, 1, 1.0); GEOSCoordSeq_setY(coords, 1, 1.0); GEOSGeometry* line = GEOSGeom_createLineString(coords); // 计算缓冲区 double bufferDistance = 0.1; int bufferSegments = 16; GEOSGeometry* buffer = GEOSBuffer(line, bufferDistance, bufferSegments); // 获取缓冲区的外框线 GEOSGeometry* exterior = GEOSGeom_getExteriorRing(buffer); // 输出外框线的坐标 const GEOSCoordSequence* exteriorCoords = GEOSGeom_getCoordSeq(exterior); unsigned int exteriorSize = 0; GEOSCoordSeq_getSize(exteriorCoords, &exteriorSize); for (unsigned int i = 0; i < exteriorSize; i++) { double x, y; GEOSCoordSeq_getX(exteriorCoords, i, &x); GEOSCoordSeq_getY(exteriorCoords, i, &y); printf("(%f, %f)\n", x, y); } // 释放内存 GEOSGeom_destroy(line); GEOSGeom_destroy(buffer); GEOSGeom_destroy(exterior); GEOSCoordSeq_destroy(coords); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值