编译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.lib和shapelib.dll。
如makefile.vc文件中描述的一样:
5. 躺坑说明
如果按照shapelib1.5文件夹中的ReadMe说明文件进行编译:
也可以运行,能够生成编译文件,但是会发现VS2017调用的时候,总是报错,要么链接出错,要么没有该函数,各种问题。
6. 测试函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #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 31 bool 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文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | #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_POINT for (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 编译