编译shapelib库并调用
1. 下载
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. 测试函数:
#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 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文件
#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;
}