掌握GDAL奥秘:从DXF到SHP的矢量转换之旅

时间:2025-02-02 00:10 分类:其他教程

在GIS的世界里,矢量数据以其独特的空间关系和丰富的属性信息,成为了地理分析不可或缺的工具。然而,随着版本的迭代,矢量数据的读写也变得越来越复杂。今天,就让我们通过一个生动的示例,探索如何使用GDAL/OGR库,轻松实现从DXF文件到SHP文件的矢量转换。

一、读取DXF文件中的线(环)特征

首先,我们来看一个具体的例子。假设我们有一个DXF文件,里面包含了线(环)特征。我们的目标是将这些线特征转换为面特征,并保存在一个新的SHP文件中。

# include <iostream>
# include <gdal/ogrsf_frmts.h>

using namespace std;

bool ReadDXF(string filePath, vector<vector<OGRPoint>>& vertexPoint)
{
    GDALDataset *poDS = (GDALDataset*)GDALOpenEx(filePath.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL);
    if (!poDS)
    {
        printf("无法读取该文件,试检查格式是否正确!");
        return false;
    }
    if (poDS->GetLayerCount() < 1)
    {
        printf("该文件的层数小于1,试检查格式是否正确!");
        return false;
    }

    OGRLayer *poLayer = poDS->GetLayer(0);
    poLayer->ResetReading();
    OGRFeature *poFeature;
    while ((poFeature = poLayer->GetNextFeature()) != NULL)
    {
        OGRGeometry *pGeo = poFeature->GetGeometryRef();
        OGRwkbGeometryType pGeoType = pGeo->getGeometryType();
        if (pGeoType == wkbLineString || pGeoType == wkbLineString25D)
        {
            OGRLinearRing *pCurve = (OGRLinearRing*)pGeo;
            if (pCurve->getNumPoints() < 1)
            {
                continue;
            }

            vector<OGRPoint> pl;
            for (int i = 0; i < pCurve->getNumPoints(); i++)
            {
                OGRPoint point;
                pCurve->getPoint(i, &point);
                pl.push_back(point);
            }
            vertexPoint.push_back(pl);
        }
    }

    GDALClose(poDS);
    poDS = nullptr;
    return true;
}

二、将线特征转换为面特征

接下来,我们需要将这些线特征转换为面特征。这一步骤通常涉及到对几何对象的合并和简化。

bool WriteShp(string filePath, vector<vector<OGRPoint>> vertexPoint)
{
    GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile");
    if (!driver)
    {
        printf("Get Driver ESRI Shapefile Error!");
        return false;
    }

    GDALDataset* dataset = driver->Create(filePath.c_str(), 0, 0, 0, GDT_Unknown, NULL);
    OGRLayer* poLayer = dataset->CreateLayer("houseType", NULL, wkbPolygon, NULL);

    {
        OGRFieldDefn oField1("名称", OFTString);
        oField1.SetWidth(8);
        if (poLayer->CreateField(&oField1) != OGRERR_NONE)
        {
            printf("Creating Name field failed.");
            return FALSE;
        }

        OGRFieldDefn oField2("面积", OFTReal);
        oField2.SetPrecision(3);
        if (poLayer->CreateField(&oField2) != OGRERR_NONE)
        {
            printf("Creating Area field failed.");
            return FALSE;
        }

        OGRFieldDefn oField3("结点数", OFTInteger);
        if (poLayer->CreateField(&oField3) != OGRERR_NONE)
        {
            printf("Creating Node count field failed.");
            return FALSE;
        }
    }

    for (auto& iter : vertexPoint)
    {
        OGRFeature *poFeature = new OGRFeature(poLayer->GetLayerDefn());
        OGRLinearRing ogrring;
        int pNum = (int)iter.size();
        ogrring.setNumPoints(pNum);
        for (int i = 0; i < iter.size(); i++)
        {
            ogrring.setPoint(i, iter[i].getX(), iter[i].getY(), iter[i].getZ());
        }
        OGRPolygon polygon;
        polygon.addRing(&ogrring);
        poFeature->SetGeometry(&polygon);
        poFeature->SetField("名称", "多边形");
        poFeature->SetField("面积", polygon.get_Area());
        poFeature->SetField("结点数", pNum);
        if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
        {
            printf("Failed to create feature in shapefile.");
            return false;
        }
    }

    GDALClose(dataset);
    dataset = nullptr;
    return true;
}

三、主函数

最后,我们将这些功能整合到一个主函数中,以便在实际应用中使用。

int main()
{
    GDALAllRegister();
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
    CPLSetConfigOption("SHAPE_ENCODING", "");

    string filePath = "D:/2.dxf";
    vector<vector<OGRPoint>> vertexPoint;
    if (!ReadDXF(filePath, vertexPoint))
    {
        return 1;
    }

    string newPath = "C:/Users/charlee/Desktop/SHP/dst.shp";
    WriteShp(newPath, vertexPoint);
    return 0;
}

通过这个示例,我们不仅学会了如何使用GDAL/OGR库读取和写入矢量数据,还掌握了如何将线特征转换为面特征,并保存在SHP文件中。希望这个示例能帮助你在实际工作中更加得心应手地处理矢量数据。

声明:

1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。

2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。

3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。

4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。

本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 0人参与,0条评论
查看更多

Copyright 2005-2024 yuanmayuan.com 源码园 版权所有 备案信息

声明: 本站非腾讯QQ官方网站 所有软件和文章来自互联网 如有异议 请与本站联系 本站为非赢利性网站 不接受任何赞助和广告