shapelib库 VS2017X64编译并调用

编译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. 测试函数:

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 编译