明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 826|回复: 3

利用gdal库读写shp简单代码示例

  [复制链接]
发表于 2025-8-16 10:10:14 | 显示全部楼层 |阅读模式
本帖最后由 gzxl 于 2025-8-16 10:12 编辑

利用 gdal 库读写 shp 简单代码示例

包含目录:添加 gdal 对应所在的 include
库目录:添加 gdal 对应所在的 lib
附加依赖项: gdal.lib

一 简介
  Shape files是ESRI提供的一种矢量数据格式,它没有拓扑信息,一个Shape files由一组文件组成,其中必要的基本文件包括坐标文件(.shp)、索引文件(.shx)和属性文件(.dbf)三个文件。

  1 坐标文件(.shp)的结构说明
    坐标文件(.shp)用于记录空间坐标信息。它由头文件和实体信息两部分构成

  2. 属性文件(.dbf)的结构说明
    属性文件(.dbf)用于记录属性信息。它是一个标准的DBF文件,也是由头文件和实体信息两部分构成

  3. 索引文件(.shx)的结构说明
    索引文件(.shx)主要包含坐标文件的索引信息,文件中每个记录包含对应的坐标文件记录距离坐标文件的文件头的偏移量。

二 《建设工程规划条件核实测量成果数据标准》
  1、分层及文件格式
  
  2、属性表
    属性表分类包含:
      2.1 建筑类规划核实属性表(图形文件)
      2.2 建筑类规划核实属性表(表格文件)
      2.3 市政类规划核实工程属性表(图形文件)
    截图其中一个,其他详细参加《建设工程规划条件核实测量成果数据标准》
      2.3 市政类规划核实工程属性表(图形文件)
        2.3.1 规划核实(交通工程)信息 (HY_JTGCGHHS)
        

三 代码示例:依据前面的数据标准输出ARC/INFO SHP格式
  1. TCHAR szKword[10];
  2. acedInitGet(0, _T("A B"));
  3. int nReturn = acedGetKword(_T("\n输入分层及文件格式选项[交通工程(A)/管线工程(B)]:"), szKword);
  4. if (nReturn == RTNORM)
  5. {
  6.     struct resbuf *rbuf;  // 结果缓冲区链表
  7.     ads_name ssname;
  8.     int res;
  9.     if (_tcscmp(szKword, _T("A")) == 0) // 交通工程
  10.     {
  11.         rbuf = acutBuildList(RTDXF0, _T("LWPOLYLINE"), RTNONE);
  12.         res = acedSSGet(TEXT("X"), NULL, NULL, rbuf, ssname);
  13.         acutRelRb(rbuf);
  14.         if (res != RTNORM)
  15.         {
  16.             acutPrintf(_T("\n图面没有可用的交通道路线(多段线)!\n"));
  17.             return;
  18.         }
  19.     }
  20.     else if (_tcscmp(szKword, _T("B")) == 0) // 管线工程
  21.     {
  22.         rbuf = acutBuildList(RTDXF0, _T("LINE"), RTNONE);
  23.         res = acedSSGet(TEXT("X"), NULL, NULL, rbuf, ssname);
  24.         acutRelRb(rbuf);
  25.         if (res != RTNORM)
  26.         {
  27.             acutPrintf(_T("\n图面没有可用的管线(直线)!\n"));
  28.             return;
  29.         }
  30.     }
  31.     Adesk::Int32 length;
  32.     acedSSLength(ssname, &length);
  33.     ads_name ename;
  34.     AcDbObjectId endId;

  35.     vector<vector<OGRPoint>> vertexPoint;
  36.     int noCloseNum = 0;
  37.     double dMaxArea = 0.0, dMaxLength = 0.0;
  38.     for (int i = 0; i < length; i++)
  39.     {
  40.         acedSSName(ssname, i, ename);
  41.         acdbGetObjectId(endId, ename);
  42.         AcDbEntity* pEnt = NULL;
  43.         acdbOpenObject(pEnt, endId, AcDb::kForRead);
  44.         if (_tcscmp(szKword, _T("A")) == 0) // 交通工程
  45.         {
  46.             if (pEnt->isKindOf(AcDbPolyline::desc()))
  47.             {
  48.                 AcDbPolyline *pPolyline = AcDbPolyline::cast(pEnt);
  49.                 if (!pPolyline->isClosed())
  50.                 {
  51.                     pPolyline->close();
  52.                     noCloseNum++;
  53.                     continue;
  54.                 }
  55.                 double dArea = 0.0;
  56.                 pPolyline->getArea(dArea);
  57.                 if (dArea > dMaxArea)
  58.                     dMaxArea = dArea;
  59.                 vector<OGRPoint> ogrPts;
  60.                 for (int j = 0; j < pPolyline->numVerts(); j++)
  61.                 {
  62.                     AcGePoint3d verPoint;
  63.                     if (pPolyline->getPointAt(j, verPoint) == Acad::eOk)
  64.                     {
  65.                         OGRPoint point;
  66.                         point.setX(verPoint.x);
  67.                         point.setY(verPoint.y);
  68.                         ogrPts.push_back(point);
  69.                     }
  70.                 }
  71.                 pPolyline->close();
  72.                 vertexPoint.push_back(ogrPts);
  73.                 ogrPts.clear();
  74.             }
  75.         }
  76.         else if (_tcscmp(szKword, _T("B")) == 0) // 管线工程
  77.         {
  78.             if (pEnt->isKindOf(AcDbLine::desc()))
  79.             {
  80.                 AcDbLine *pLine = AcDbLine::cast(pEnt);
  81.                 AcGePoint3d startPt, endPt;
  82.                 pLine->getStartPoint(startPt);
  83.                 pLine->getEndPoint(endPt);
  84.                 vector<OGRPoint> ogrPts;
  85.                 OGRPoint ogrStartPt, ogrEndPt;
  86.                 ogrStartPt.setX(startPt.x);
  87.                 ogrStartPt.setY(startPt.y);
  88.                 ogrEndPt.setX(endPt.x);
  89.                 ogrEndPt.setY(endPt.y);
  90.                 ogrPts.push_back(ogrStartPt);
  91.                 ogrPts.push_back(ogrEndPt);
  92.                 vertexPoint.push_back(ogrPts);
  93.                 ogrPts.clear();
  94.                 double dist = (AcGePoint2d(startPt.x, startPt.y)).distanceTo(AcGePoint2d(endPt.x, endPt.y));
  95.                 dMaxLength += dist;
  96.                 pLine->close();
  97.             }
  98.         }
  99.         pEnt->close();
  100.     }
  101.     acedSSFree(ssname);

  102.     int nFormatWidth = 0;
  103.     if (dMaxArea != 0.0)
  104.     {
  105.         CString sArea = ToString(dMaxArea, 2);
  106.         for (int i = 0; i < sArea.GetLength(); i++)
  107.         {
  108.             if ((sArea >= '0' && sArea <= '9') || sArea == '.')
  109.                 nFormatWidth++;
  110.         }
  111.     }
  112.     if (dMaxLength != 0.0)
  113.     {
  114.         CString sMaxLength = ToString(dMaxLength, 2);
  115.         for (int i = 0; i < sMaxLength.GetLength(); i++)
  116.         {
  117.             if ((sMaxLength >= '0' && sMaxLength <= '9') || sMaxLength == '.')
  118.                 nFormatWidth++;
  119.         }
  120.     }
  121.     if (nFormatWidth == 0)
  122.         nFormatWidth = 8;

  123.     if (vertexPoint.size() > 0)
  124.     {
  125.         CString ReturnPach;
  126.         Getbrowse(ReturnPach); // 获得文件夹路径
  127.         if (_tcscmp(ReturnPach, _T("")) == 1)
  128.         {
  129.             CString sPrefixName;
  130.             if (_tcscmp(szKword, _T("A")) == 0) // 交通工程
  131.                 sPrefixName = _T("HY_JTGCGHHS");
  132.             else if (_tcscmp(szKword, _T("B")) == 0) // 管线工程
  133.                 sPrefixName = _T("HY_GXGCGHHS");

  134.             CString sFileName = ReturnPach + _T("\\") + sPrefixName + _T(".shp");

  135.             const char *pszDriverName = "ESRI Shapefile";
  136.             // 注册所有的文件格式驱动
  137.             GDALDriver *poDriver;
  138.             GDALAllRegister();
  139.             // 得到shp文件的处理器
  140.             poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName);
  141.             if (poDriver == NULL)
  142.             {
  143.                 acutPrintf(_T("\n%s 获取驱动程序 ESRI Shapefile 错误!\n"), pszDriverName);
  144.                 return;
  145.             }
  146.             // 创建shp文件
  147.             GDALDataset *poDS;
  148.             const char* fileName = CStringToCharArray(sFileName);
  149.             poDS = poDriver->Create(fileName, 0, 0, 0, GDT_Unknown, NULL); //创建shp文件
  150.             if (poDS == NULL)
  151.             {
  152.                 acutPrintf(_T("\n创建输出文件失败!\n"));
  153.                 return;
  154.             }
  155.             // 创建图层
  156.             OGRLayer *poLayer;
  157.             if (_tcscmp(szKword, _T("A")) == 0) // 交通工程
  158.             {
  159.                 poLayer = poDS->CreateLayer("HY_JTGCGHHS", NULL, wkbPolygon, NULL);
  160.                 OGRFieldDefn KJFWXXIDField("KJFWXXID", OFTString); // 空间范围信息ID
  161.                 OGRFieldDefn YSDMField("YSDM", OFTString);         // 要素代码
  162.                 OGRFieldDefn DZJGHField("DZJGH", OFTString);       // 电子监管号
  163.                 OGRFieldDefn YDMJField("YDMJ", OFTReal);           // 用地面积
  164.                 OGRFieldDefn JTGCXMLXField("JTGCXMLX", OFTString); // 交通工程项目类型
  165.                 OGRFieldDefn DLDJField("DLDJ", OFTString);         // 道路等级
  166.                 OGRFieldDefn DLCDField("DLCD", OFTReal);           // 道路长度
  167.                 OGRFieldDefn BZHDMKDField("BZHDMKD", OFTReal);     // 标准横断面宽度
  168.                 OGRFieldDefn GDJTLXField("GDJTLX", OFTString);     // 轨道交通类型
  169.                 OGRFieldDefn GDCDField("GDCD", OFTReal);           // 轨道长度
  170.                 OGRFieldDefn KZXKDField("KZXKD", OFTReal);         // 轨道控制线宽度
  171.                 KJFWXXIDField.SetWidth(36);
  172.                 YSDMField.SetWidth(10);
  173.                 DZJGHField.SetWidth(19);
  174.                 YDMJField.Set("YDMJ", OFTReal, nFormatWidth, 2, OJRight);
  175.                 JTGCXMLXField.SetWidth(2);
  176.                 DLDJField.SetWidth(10);
  177.                 DLCDField.Set("DLCD", OFTReal, nFormatWidth, 2, OJRight);
  178.                 BZHDMKDField.Set("BZHDMKD", OFTReal, nFormatWidth, 2, OJRight);
  179.                 GDJTLXField.SetWidth(10);
  180.                 GDCDField.Set("GDCD", OFTReal, nFormatWidth, 2, OJRight);
  181.                 KZXKDField.Set("KZXKD", OFTReal, nFormatWidth, 2, OJRight);
  182.                 poLayer->CreateField(&KJFWXXIDField);
  183.                 poLayer->CreateField(&YSDMField);
  184.                 poLayer->CreateField(&DZJGHField);
  185.                 poLayer->CreateField(&YDMJField);
  186.                 poLayer->CreateField(&JTGCXMLXField);
  187.                 poLayer->CreateField(&DLDJField);
  188.                 poLayer->CreateField(&DLCDField);
  189.                 poLayer->CreateField(&BZHDMKDField);
  190.                 poLayer->CreateField(&GDJTLXField);
  191.                 poLayer->CreateField(&GDCDField);
  192.                 poLayer->CreateField(&KZXKDField);
  193.             }
  194.             else if (_tcscmp(szKword, _T("B")) == 0) // 管线工程
  195.             {
  196.                 poLayer = poDS->CreateLayer("HY_GXGCGHHS", NULL, wkbPolygon, NULL);
  197.                 OGRFieldDefn KJFWXXIDField("KJFWXXID", OFTString); // 空间范围信息ID
  198.                 OGRFieldDefn YSDMField("YSDM", OFTString);         // 要素代码
  199.                 OGRFieldDefn DZJGHField("DZJGH", OFTString);       // 电子监管号
  200.                 OGRFieldDefn SPGXLXField("SPGXLX", OFTString);     // 审批管线类型
  201.                 OGRFieldDefn GXFJField("GXFJ", OFTString);         // 审批管线分级
  202.                 OGRFieldDefn SPGXCDField("SPGXCD", OFTReal);       // 审批管线长度
  203.                 OGRFieldDefn JGGXCDField("JGGXCD", OFTReal);       // 竣工管线长度
  204.                 OGRFieldDefn SPGXGJField("SPGXGJ", OFTString);     // 审批管线管径
  205.                 OGRFieldDefn JGGXGJField("JGGXGJ", OFTString);     // 竣工管线管径
  206.                 KJFWXXIDField.SetWidth(36);
  207.                 YSDMField.SetWidth(10);
  208.                 DZJGHField.SetWidth(19);
  209.                 SPGXLXField.SetWidth(10);
  210.                 GXFJField.SetWidth(10);
  211.                 SPGXCDField.Set("SPGXCD", OFTReal, nFormatWidth, 2, OJRight);
  212.                 JGGXCDField.Set("JGGXCD", OFTReal, nFormatWidth, 2, OJRight);
  213.                 SPGXGJField.SetWidth(200);
  214.                 JGGXGJField.SetWidth(200);
  215.                 poLayer->CreateField(&KJFWXXIDField);
  216.                 poLayer->CreateField(&YSDMField);
  217.                 poLayer->CreateField(&DZJGHField);
  218.                 poLayer->CreateField(&SPGXLXField);
  219.                 poLayer->CreateField(&GXFJField);
  220.                 poLayer->CreateField(&SPGXCDField);
  221.                 poLayer->CreateField(&JGGXCDField);
  222.                 poLayer->CreateField(&SPGXGJField);
  223.                 poLayer->CreateField(&JGGXGJField);
  224.             }
  225.             if (poLayer == NULL)
  226.             {
  227.                 acutPrintf(_T("\n图层创建失败!\n"));
  228.                 GDALClose(poDS);
  229.                 poDS = NULL;
  230.                 vertexPoint.clear();
  231.                 return;
  232.             }
  233.             for (int i = 0; i < vertexPoint.size(); i++)
  234.             {
  235.                 vector<OGRPoint> ogrPts = vertexPoint.at(i);

  236.                 OGRFeature *poFeature;
  237.                 poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());

  238.                 // 创建几何和 Feature
  239.                 if (_tcscmp(szKword, _T("A")) == 0) // 交通工程
  240.                 {
  241.                     OGRLinearRing ogrring;
  242.                     int pNum = (int)ogrPts.size();
  243.                     ogrring.setNumPoints(pNum);
  244.                     for (int j = 0; j < ogrPts.size(); j++)
  245.                     {
  246.                         ogrring.setPoint(j, ogrPts[j].getX(), ogrPts[j].getY(), ogrPts[j].getZ());
  247.                     }
  248.                     OGRPolygon polygon; // 多边形
  249.                     polygon.addRing(&ogrring);
  250.                     poFeature->SetGeometry(&polygon);
  251.                     // 创建字段
  252.                     poFeature->SetField("KJFWXXID", "7CF7F6D9-9210-4BC7-AFAD-F288F2357A99");
  253.                     poFeature->SetField("YSDM", "8008010240");
  254.                     poFeature->SetField("DZJGH", "/");
  255.                     poFeature->SetField("YDMJ", polygon.get_Area());
  256.                     poFeature->SetField("JTGCXMLX", "1");
  257.                     poFeature->SetField("DLDJ", "03");
  258.                     poFeature->SetField("DLCD", 0.0);
  259.                     poFeature->SetField("BZHDMKD", 0.0);
  260.                     poFeature->SetField("GDJTLX", "");
  261.                     poFeature->SetField("GDCD", 0.0);
  262.                     poFeature->SetField("KZXKD", 0.0);
  263.                 }
  264.                 else if (_tcscmp(szKword, _T("B")) == 0) // 管线工程
  265.                 {
  266.                     OGRLineString pLine; // 线
  267.                     int pNum = (int)ogrPts.size();
  268.                     pLine.setNumPoints(pNum);
  269.                     for (int j = 0; j < ogrPts.size(); j++)
  270.                     {
  271.                         pLine.setPoint(j, ogrPts[j].getX(), ogrPts[j].getY(), ogrPts[j].getZ());
  272.                     }
  273.                     poFeature->SetGeometry((OGRGeometry *)(&pLine));
  274.                     // 创建字段
  275.                     poFeature->SetField("KJFWXXID", "7CF7F6D9-9210-4BC7-AFAD-F288F2357A99");
  276.                     poFeature->SetField("YSDM", "8008010250");
  277.                     poFeature->SetField("DZJGH", "/");
  278.                     // GS 给水   PS 排水   TX 通信   DL 电力
  279.                     // RQ 燃气   GR 供热   XF 消防   QT 其他
  280.                     poFeature->SetField("SPGXLX", "GS");
  281.                     poFeature->SetField("GXFJ", "");
  282.                     poFeature->SetField("SPGXCD", 0.0);
  283.                     poFeature->SetField("JGGXCD", dMaxLength);
  284.                     poFeature->SetField("SPGXGJ", "");
  285.                     poFeature->SetField("JGGXGJ", "");
  286.                 }

  287.                 if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
  288.                 {
  289.                     acutPrintf(_T("\n在 shapefile 中创建特性失败!\n"));
  290.                     OGRFeature::DestroyFeature(poFeature);
  291.                     GDALClose(poDS);
  292.                     poDS = NULL;
  293.                     vertexPoint.clear();
  294.                     return;
  295.                 }
  296.                 // 资源清理
  297.                 OGRFeature::DestroyFeature(poFeature);
  298.             }
  299.             // 资源清理
  300.             GDALClose(poDS);
  301.             poDS = NULL;
  302.             vertexPoint.clear();
  303.             acutPrintf(_T("\n已输出shp文件格式!\n"));
  304.         }
  305.     }
  306. }


四 代码示例:读shp文件
  1. // 打开文件对话框
  2. CFileDialog dlg(TRUE, NULL, NULL, OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, TEXT("shp文件(*.shp)|*.shp||"), NULL);
  3. dlg.GetOFN().lpstrTitle = _T("读取shp数据文件");
  4. if (dlg.DoModal() == IDOK)
  5. {
  6.     CString strPath = dlg.GetPathName();
  7.     USES_CONVERSION;  //需要这一步才能使用W2A
  8.     const char* pszShapeFile = string(W2A(strPath)).c_str();

  9.     GDALAllRegister();
  10.     GDALDataset *poDS;
  11.     CPLSetConfigOption("SHAPE_ENCODING", "");  //解决中文乱码问题
  12.     // 读取shp文件
  13.     poDS = (GDALDataset*)GDALOpenEx(pszShapeFile, GDAL_OF_VECTOR, NULL, NULL, NULL);
  14.     if (poDS == NULL)
  15.     {
  16.         acutPrintf(_T("Open failed.\n%s"));
  17.         return;
  18.     }
  19.     OGRLayer *poLayer;
  20.     poLayer = poDS->GetLayer(0); // 读取层
  21.     OGRFeature *poFeature;
  22.     poLayer->ResetReading();
  23.     int i = 0;
  24.     while ((poFeature = poLayer->GetNextFeature()) != NULL)
  25.     {
  26.         if (poFeature->GetFieldAsDouble("AREA") < 1)
  27.             continue; //去掉面积过小的 polygon
  28.         i = i++;
  29.         OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
  30.         int iField;
  31.         // 获得字段的数目,不包括前两个字段(FID,Shape);
  32.         int n = poFDefn->GetFieldCount();
  33.         for (iField = 0; iField < n; iField++)
  34.         {
  35.             // 输出每个字段的值
  36.             acutPrintf(_T("%s\n"), poFeature->GetFieldAsString(iField));
  37.         }
  38.         OGRFeature::DestroyFeature(poFeature);
  39.     }
  40.     GDALClose(poDS);
  41. }






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复

使用道具 举报

发表于 2025-8-16 14:46:47 | 显示全部楼层
G佬NB              
回复 支持 反对

使用道具 举报

发表于 2025-8-18 20:33:38 | 显示全部楼层
G大,SHP字段、长度、类型可以写到配置中,一个接口直接完成
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-10-6 01:40 , Processed in 0.188497 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表