环境:visual studio2022,libLAS1.8。

visual studio2022编译依赖静态库gdal

版本:gdal2.4.1

  1. 地址上下载源码,这里我选择的是2.4.1版本。将其解压放置libLAS根目录下
  2. 在cmd窗口下进入vcvars64.bat所在的目录执行该脚本
  3. 更改gdal-2.4.1根目录下的nmake.opt配置文件
# 更改GDAL_HOME的值
GDAL_HOME = "C:\Users\wzh\Desktop\libLAS\gdal-2.4.1\installlation"
  1. 进入gdal-2.4.1项目的根目录,分别执行以下命令:
    1. 执行过程中报错gdal-2.4.1\ogr\ogrlinestring.cpp(2554): error C2039: "fabs": 不是 "std" 的成员:将ogrlinestring.cpp中的fas前的std::删除
    # 变量MSVC_VER的值可以在集成开发环境vs中查看_MSC_VER的值
    nmake -f makefile.vc MSVC_VER=1939 WIN64=1
    
    1. 执行
    nmake -f makefile.vc MSVC_VER=1939 WIN64=1 install
    
    1. 执行
    nmake -f makefile.vc MSVC_VER=1939 WIN64=1 devinstall
    
  2. 成功后,将会在GDAL_HOME目录下生成如下文件

visual studio2022编译依赖静态库geotiff

1.编译libtiff
  1. 地址上下载libtiff,这里我下载的是4.0.6.将其解压放置libLAS根目录下
  2. 进入tiff-4.0.6根目录下,执行nmake -f makefile.vc MSVC_VER=1939 WIN64=1中报错libtiff\tiffiop.h(62): note: 参见“snprintf”的前一个定义,打开tiffiop.h文件,将如下内容注释:
//#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF)
//#undef snprintf
//#define snprintf _TIFF_snprintf_f
//extern int snprintf(char* str, size_t size, const char* format, ...);
//#endif
  1. 上述步骤执行成功,会在tiff-4.0.6\libtiff目录下生成库文件等
2.编译geotiff
  1. 地址上下载geotiff,这里下载的是1.2.5。将其解压放置libLAS根目录下
  2. 将编译libtiff时,项目根目录下的libtiff目录复制到libLAS\libgeotiff-1.2.5目录下
  3. 进入libgeotiff-1.2.5目录下,分别执行
    1. nmake -f makefile.vc MSVC_VER=1939 WIN64=1
    2. nmake -f makefile.vc MSVC_VER=1939 WIN64=1 install
    3. nmake -f makefile.vc MSVC_VER=1939 WIN64=1 devinstall

visual studio2022编译依赖静态库zlib

我使用的版本为1.2.11。这个教程较多,省略。

visual studio2022编译依赖静态库liblas

由于本次PCL读取las格式的点云数据文件使用第三方libLAS库,地址为:https://github.com/libLAS/libLAS。为了方便使用,将其编译成静态lib。以Debug版本的静态库为例,编译Release版本的静态库雷同,步骤如下:

  1. 打开vs创建新项目,模板类型选择库=》静态库
  2. 位置选择克隆项目的根目录
  3. 然后移除liblas项目下的源文件
  4. 将liblas目录下的四个文件复制到libLAS根目录下,并将liblas目录删除。目录调整结构如下:
  5. 打开liblas.sln文件,右击头文件、源文件将需要编译的文件加进来:主要是src目录以及include目录
  6. libLAS项目根目录下新建libs目录,将boost,gdal,geotiff,tiff,zip这些静态库放置该目录下。其中boost相关的静态库不用再编译了,可以在PCL 1.13.0\3rdParty\Boost\lib目录下找到。
  7. 将boost,gdal,geotiff,tiff,zip这些库的头文件放置libLAS\include目录下。其中boost库的头文件在PCL 1.13.0\3rdParty\Boost\include目录下可以找到,可以直接拿来用。
  8. 在项目属性页中进行基本的配置
    1. 预编译头选择不使用
    2. 配置属性=》VC++目录=》包含目录进行头文件目录的包含,新增如下内容:
    .\include
    .\include\gdal_2.4.1
    .\include\libgeotiff-debug
    .\include\libtiff
    .\include\boost
    .\include\zip
    
    1. 将安装好的PCL1.13.0PCL 1.13.0\3rdParty\Boost\include\boost-1_80目录下的boost文件夹复制到libLAS\include目录下
    2. 配置属性=》VC++目录=》库目录进行依赖库的包含,新增如下内容
    .\libs
    
    1. 配置属性=》C/C++=》预处理器中新增预处理器定义如下:
    _CRT_SECURE_NO_WARNINGS
    BOOST_BIND_GLOBAL_PLACEHOLDERS
    
  9. 编译过程中遇到一个问题:xxx.obj : warning LNK4042: 对象被多次指定;已忽略多余的指定,解决方法是更改编译输出的文件名,如下所示:
  10. 最终进行编译,会在输出目录下生成静态库

在plc项目中读取las格式的点云数据文件

  1. 示例代码如下:
#include "liblas/liblas.hpp"

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

#include <vector>

int main(int argc, char** argv)
{
	// 读取las文件
	std::ifstream ifs("./dataset/祖庙牌坊.las", std::ios::in | std::ios::binary);

	liblas::ReaderFactory f;
	liblas::Reader reader = f.CreateWithStream(ifs);

	//获取las数据点的个数
	unsigned long int nPoints = reader.GetHeader().GetPointRecordsCount();

	// 初始化点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	cloud->width = nPoints;
	cloud->height = 1;
	cloud->resize(nPoints);

	std::vector<uint8_t> pclassification(nPoints);  //记录类别信息
	std::vector<liblas::Color> pcolor(nPoints);		//记录颜色信息
	std::vector<uint16_t> pintencity(nPoints);		//记录强度信息
	for (int i = 0; i < nPoints; i++)    
	{
		reader.ReadNextPoint();
		const liblas::Point& p = reader.GetPoint();

		float px = (float)p.GetX();
		float py = (float)p.GetY();
		float pz = (float)p.GetZ();

		(*cloud)[i].x = px;
		(*cloud)[i].y = py;
		(*cloud)[i].z = pz;

		pclassification[i] = p.GetClassification().GetClass();
		pcolor[i] = p.GetColor();
		pintencity[i] = p.GetIntensity();
	}

	ifs.close();

	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	viewer->setWindowName("可视化las格式的点云");

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 0, 0, 255);

	viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return 0;
}