编译shapelib库并调用

  • 1. 下载
  • 2.cmd编译
  • 3.VS本机工具命令
  • 4. VS本机工具命令编译
  • 5. 躺坑说明
  • 6. 测试函数:
  • 7. 封装shapelib,创建shapeFileHelper类:
  • 8. 参考文章

1. 下载

shapelib

2.cmd编译

使用nmake编译的时候,直接通过cmd进行编译,输入命令

nmake -f makefile.vc


由于nmake没有增加到系统变量,所以提示错误。

3.VS本机工具命令

使用VS2017本机工具命令提示,该命令位于win10菜单下:

该命令其实还是cmd,不过是增加了VS2017的系统变量

4. VS本机工具命令编译

双击打开,然后切换到shapelib1.5目录,运行nmake -f makefile.vc,编译成功,如图所示:

此时会shapelib1.5文件夹下会生成静态库shapelib.lib,和动态库shapelib_i.libshapelib.dll

makefile.vc文件中描述的一样:

5. 躺坑说明

如果按照shapelib1.5文件夹中的ReadMe说明文件进行编译:

也可以运行,能够生成编译文件,但是会发现VS2017调用的时候,总是报错,要么链接出错,要么没有该函数,各种问题。

6. 测试函数:

#include <iostream>
#include <shapefil.h>int main()
{const char* filename = "D:\\PCL\\testpcl\\格网.shp";SHPHandle hShp = SHPOpen(filename,"r");int nShapeType, nVertices;int nEntities = 0;double* minB = new double[4];double* maxB = new double[4];SHPGetInfo(hShp, &nEntities, &nShapeType, minB, maxB);printf("ShapeType:%d\n", nShapeType);printf("Entities:%d\n", nEntities);SHPClose(hShp);system("Pause");
}

7. 封装shapelib,创建shapeFileHelper类:

  • 正确使用方法: 参考Shapefile C Library,网站上对库的使用写得非常良心,调用方法,函数参数含义,说的明明白白,配合库的头文件shapefil.h一起使用,就能清楚地明白。

  • 头文件 shapeFileHelper.h

#ifndef __SHAPEFILE_HELPER__
#define __SHAPEFILE_HELPER__#pragma once#include<vector>
#include "point_type_qcj.h"
#include "shapefil.h"using namespace std;class shapeFileHelper
{public:shapeFileHelper();~shapeFileHelper();//pszAccess: "rb" (read-only binary) and "rb+" (read/write binary)     should be used.bool openShapeFile(const char* filename, const char* pszAccess = "r");//nShapeType:     SHPT_NULL       0 //2D Shape Types://               SHPT_POINT      1 , SHPT_ARC        3 , SHPT_POLYGON    5 //                SHPT_MULTIPOINT 8 , //3D Shape Types://                 SHPT_POINTZ     11, SHPT_ARCZ       13, SHPT_POLYGONZ   15, SHPT_MULTIPOINTZ 18 //2D + Measure Types://                SHPT_POINTM     21 , SHPT_ARCM       23 , SHPT_POLYGONM   25 , SHPT_MULTIPOINTM 28 //Complex (TIN-like) with Z, and Measure://                  SHPT_MULTIPATCH 31bool createShapeFile(std::string folderPath,std::string shp_fn, int nShapeType = SHPT_POINTZ);bool write3DPts(int iVertices, const double * padfX, const double * padfY,const double * padfZ);bool write2DPts(int iVertices, const double * padfX, const double * padfY);bool write3DLines(int iVertices, const double * padfX, const double * padfY, const double * padfZ);bool write2DLines(int iVertices, const double * padfX, const double * padfY);vector<Point3D> getAllVertices();int getEntitiesCount() { return m_nEntities;};int getShapeTypeCount() { return m_nShapeType; };double calculateLineLength(int iVertices, const double * padfX, const double * padfY, const double * padfZ);double calculateLineLength(int iVertices, const double * padfX, const double * padfY);void close();protected:SHPHandle hReadShp;SHPHandle hWriteShp;DBFHandle hWriteDbf;private:int m_nEntities{ 0 };int m_nShapeType{ 0 };
};#endif
  • cpp文件
#include "shapeFileHelper.h"shapeFileHelper::shapeFileHelper()
{hReadShp = NULL;
}shapeFileHelper::~shapeFileHelper()
{close();
}void shapeFileHelper::close()
{if (hReadShp){SHPClose(hReadShp);hReadShp = NULL;}if (hWriteDbf){DBFClose(hWriteDbf);hWriteDbf = NULL;}if (hWriteShp){SHPClose(hWriteShp);hWriteShp = NULL;}
}bool shapeFileHelper::openShapeFile(const char* filename, const char* pszAccess)
{hReadShp = SHPOpen(filename, pszAccess);if (hReadShp){double* minB = new double[4];double* maxB = new double[4];SHPGetInfo(hReadShp, &m_nEntities, &m_nShapeType, minB, maxB);return true;}else return false;
}vector<Point3D> shapeFileHelper::getAllVertices()
{vector<Point3D> points;if (m_nEntities > 0){for (int i = 0; i < m_nEntities; ++i){int iShape = i;//The entity number of the shape to read.  Entity numbers are between 0 and nEntities - 1 (as returned by SHPGetInfo()).SHPObject *obj = SHPReadObject(hReadShp, iShape);int verts = obj->nVertices;for (size_t j = 0; j < verts; ++j){double x = obj->padfX[j];double y = obj->padfY[j];double z = obj->padfZ[j];Point3D pt = { x,y,z };points.push_back(pt);}}}return points;
}bool shapeFileHelper::createShapeFile(std::string folderPath, std::string shp_fn,  int nShapeType /* = SHPT_POINTZ */)
{hWriteShp = SHPCreate(std::string(folderPath + "/" + shp_fn + ".shp").c_str(), nShapeType);hWriteDbf = DBFCreate(std::string(folderPath + "/" + shp_fn + ".dbf").c_str());// 创建dbf文件表DBFAddField(hWriteDbf, "ID", FTInteger, 10, 0);DBFAddField(hWriteDbf, "Name", FTString, 10, 0);if (nShapeType == SHPT_POINT)                        //2D point{DBFAddField(hWriteDbf, "X", FTDouble, 32, 3);DBFAddField(hWriteDbf, "Y", FTDouble, 32, 3);}else if (nShapeType == SHPT_POINTZ)                 //3D point{DBFAddField(hWriteDbf, "X", FTDouble, 32, 3);DBFAddField(hWriteDbf, "Y", FTDouble, 32, 3);DBFAddField(hWriteDbf, "Z", FTDouble, 32, 3);}else if (nShapeType == SHPT_ARCZ  || nShapeType == SHPT_ARC)   //line{DBFAddField(hWriteDbf, "Length", FTDouble, 32, 3);}DBFAddField(hWriteDbf, "Marks", FTString, 10, 0);return  true;
}bool shapeFileHelper::write3DPts( int iVertices, const double* padfX, const double* padfY, const double* padfZ)
{if (hWriteDbf == NULL || hWriteShp == NULL){return false;}for (int i =0; i < iVertices; ++i){//-1 is unknown/unassigned. The entity number of the shape to write.A value of -1 should be used for new shapes.SHPObject* shpObject = SHPCreateObject(SHPT_POINTZ, -1, 0, NULL, NULL, 1, &padfX[i], &padfY[i], &padfZ[i], NULL);//shpObject = SHPCreateSimpleObject(SHPT_POINTZ, 1, &padfX[i], &padfY[i], &padfZ[i]);SHPWriteObject(hWriteShp, -1, shpObject);SHPDestroyObject(shpObject);// dbf的记录数int record_idx = DBFGetRecordCount(hWriteDbf);// 字段索引int field_idx = 0;DBFWriteIntegerAttribute(hWriteDbf, record_idx, field_idx++, record_idx + 1);DBFWriteStringAttribute(hWriteDbf, record_idx, field_idx++, "point3D");DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, padfX[i]);DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, padfY[i]);DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, padfZ[i]);if (-9999.0 == padfZ[i]){DBFWriteStringAttribute(hWriteDbf, record_idx, field_idx++, "未找到满足条件的高程点");}}
}bool shapeFileHelper::write2DPts(int iVertices, const double * padfX, const double * padfY)
{if (hWriteDbf == NULL || hWriteShp == NULL){return false;}//2d point SHPT_POINTfor (int i = 0; i < iVertices; ++i){//The entity number of the shape to write.A value of -1 should be used for new shapes.SHPObject* shpObject = SHPCreateObject(SHPT_POINT, -1, 0, NULL, NULL, 1, &padfX[i], &padfY[i], NULL, NULL);//shpObject = SHPCreateSimpleObject(SHPT_POINT, 1, &padfX[i], &padfY[i], NULL);SHPWriteObject(hWriteShp, -1, shpObject);SHPDestroyObject(shpObject);// dbf的记录数int record_idx = DBFGetRecordCount(hWriteDbf);// 字段索引int field_idx = 0;DBFWriteIntegerAttribute(hWriteDbf, record_idx, field_idx++, record_idx + 1);DBFWriteStringAttribute(hWriteDbf, record_idx, field_idx++, "point2D");DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, padfX[i]);DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, padfY[i]);}
}bool shapeFileHelper::write3DLines(int iVertices, const double * padfX, const double * padfY, const double * padfZ)
{if (hWriteDbf == NULL || hWriteShp == NULL){return false;}SHPObject* shpObject = SHPCreateObject(SHPT_ARCZ, -1, 0, NULL, NULL, iVertices, padfX, padfY, padfZ, NULL);SHPWriteObject(hWriteShp, -1, shpObject);SHPDestroyObject(shpObject);// dbf的记录数int record_idx = DBFGetRecordCount(hWriteDbf);// 字段索引int field_idx = 0;double len = calculateLineLength(iVertices, padfX, padfY, padfZ);DBFWriteIntegerAttribute(hWriteDbf, record_idx, field_idx++, record_idx + 1);DBFWriteStringAttribute(hWriteDbf, record_idx, field_idx++, "polyline3D");DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, len);
}bool shapeFileHelper::write2DLines(int iVertices, const double * padfX, const double * padfY)
{if (hWriteDbf == NULL || hWriteShp == NULL){return false;}SHPObject* shpObject = SHPCreateObject(SHPT_ARC, -1, 0, NULL, NULL, iVertices, padfX, padfY, NULL, NULL);SHPWriteObject(hWriteShp, -1, shpObject);SHPDestroyObject(shpObject);// dbf的记录数int record_idx = DBFGetRecordCount(hWriteDbf);// 字段索引int field_idx = 0;double len = calculateLineLength(iVertices, padfX, padfY);DBFWriteIntegerAttribute(hWriteDbf, record_idx, field_idx++, record_idx + 1);DBFWriteStringAttribute(hWriteDbf, record_idx, field_idx++, "polyline2D");DBFWriteDoubleAttribute(hWriteDbf, record_idx, field_idx++, len);
}double shapeFileHelper::calculateLineLength(int iVertices, const double * padfX, const double * padfY, const double * padfZ)
{double len = 0.0;for (int i = 0; i < iVertices; ++i){len += sqrt(pow(padfX[i], 2) + pow(padfX[i], 2) + pow(padfX[i], 2));}return len;
}double shapeFileHelper::calculateLineLength(int iVertices, const double * padfX, const double * padfY)
{double len = 0.0;for (int i = 0; i < iVertices; ++i){len += sqrt(pow(padfX[i], 2) + pow(padfX[i], 2) );}return len;
}

8. 参考文章

  • 利用ShapeLib读写ShapeFile文件
  • nmake && shapelib 编译

shapelib库 VS2017X64编译并调用相关推荐

  1. MFC模块的动态链接库DLL以及静态链接库LIB编译后的调用

    静态链接库LIB和动态链接库DLL的区别,创建和示例   1.什么是静态连接库,什么是动态链接库   静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都 ...

  2. 详解PyTorch编译并调用自定义CUDA算子的三种方式

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 在上一篇教程中,我们实现了一个自定义的CUDA算子add2,用来实现两个Tensor的相加.然后用Py ...

  3. Tensorflow C++ 编译和调用图模型

    简介 最近在研究如何打通tensorflow线下 python 的脚本训练建模, 利用freeze_graph工具输出.pb图文件,之后再线上生产环境用C++代码直接调用预先训练好的模型完成预测的工作 ...

  4. C++中.lib静态库、.dll动态库的生成及调用1

    一.前言 1.动态链接库(dll)与静态链接库(lib): 动态链接库(dll)是一个可以被其他应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源.在链接步骤中,连接器将从库文件取得所需的代 ...

  5. vs2008中xlslib与libxls库的编译及使用

    C++用来操作Excel的方法很多,但是涉及到跨平台,同时又要对Excel的读写操作兼顾,而且免费的库,那应该是要用xlslib和libxls了.由于技术比较菜,折腾这个折腾了一个星期了.最开始是使用 ...

  6. 【Android NDK 开发】NDK 交叉编译 ( NDK 函数库目录 | Linux 交叉编译环境搭建 | 指定头文件目录 | 指定函数库目录 | 编译 Android 命令行可执行文件 )

    文章目录 I . NDK platforms 目录下的 函数库 II . Ubuntu 配置 NDK 交叉编译环境 III . 同时指定编译的头文件和库文件 IV . 指定编译的头文件 V . 指定编 ...

  7. 阐述Linux动态库的显式调用

    阐述Linux动态库的显式调用 分类: Linux 2011-02-12 10:27 168人阅读 评论(0) 收藏 举报 linux测试nulllibrarypathgcc 十年的发展,Linux系 ...

  8. Linux上静态库和动态库的编译和使用

    linux上静态库和动态库的编译和使用(附外部符号错误浅谈) 这就是静态库和动态库的显著区别,静态库是编译期间由链接器通过include目录找到并链接到到可执行文件中,而动态库则是运行期间动态调用,只 ...

  9. gcc/g++ 链接库的编译与链接

          程序编译一般需要经预处理.编译.汇编和链接几个步骤.在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为"库"文件.在链接步骤中,连接器将从库文件取得所需的代码 ...

最新文章

  1. 神经网络RNN图解!
  2. python压缩文件夹下的所有文件_python压缩文件夹内所有文件为zip文件的方法
  3. 【TypeScript】使用 const 关键字声明只读变量
  4. IntelliJ IDEA 超实用技巧分享,不能再全了!
  5. ubuntu apache php mysql phpmyadmin_Ubuntu下Apache+PHP+MySQL+phpMyAdmin的快速安装步骤
  6. SAP Kyma组件一览
  7. Linux命令工作中常用的总结
  8. 数据科学与python语言——Matplotlib数据可视化基础
  9. 哪些事是你当了大学老师之后才知道的?
  10. 数学里的π究竟牛在哪里
  11. 流内容html,为什么,和元素属于html中的流内容?
  12. java第四次上机作业
  13. inux中tail命令---用于查看文件内容
  14. Atitit ForkJoinTask的使用以及与futuretask的区别 1.1. Forkjoin原理图 1 1.2. Fork/Join使用两个类完成以上两件事情:ForkJoinTask
  15. “医检助手”诚聘互联网运营总监
  16. 学习Java心得体会
  17. Scrapy--下载器中间件(Downloader Middleware)
  18. 抗变态或亲变态是更好的解决方案
  19. 学习《图说设计模式》观察者模式
  20. 掺铥铝酸钇晶体(Tm:YAP)晶体的资料及其相关产品目录

热门文章

  1. linux下拆分压缩包
  2. php世界上最美丽,世界上最漂亮的十大桥梁(一)
  3. 关于毕业设计汇报PPT
  4. CSDN论坛目录树调整公告
  5. Cubase Artist 7 v7.0.2 WiN 艺术家版便携安装编曲录音软件主程序
  6. WinCap网络开发库入门(转)
  7. MongoDB(4):多种方式关闭服务命令
  8. Template、ItemsPanel、ItemContainerStyle、ItemTemplate
  9. 全国女子足球U13锦标赛
  10. 移动测试人员学习Python的顺序