点云:PDAL读写点云——VS2017,Qt5.9.8

1 配置环境

1.1 属性——C/C++——常规——附加包含目录,添加头文件路径C:\OSGeo4W64\include

1.2 属性——链接器——输入——附加依赖项,添加lib文件C:\OSGeo4W64\lib\pdalcpp.libC:\OSGeo4W64\lib\pdal_util.lib

2 分享给有需要的人,代码质量勿喷

2.1 头文件PDALtest.h

#pragma once
#pragma execution_character_set("utf-8")//中文路径问题

#include <QtWidgets/QMainWindow>
#include "ui_PDALtest.h"

#include <QFile>
#include <QFileDialog>
#include <QMultiHash>
#include <QMessageBox>

//PDAL
#include <vector>
#include <memory>
#include <pdal/Options.hpp>
#include <pdal/PointTable.hpp>
#include <pdal/PointView.hpp>
#include <pdal/StageFactory.hpp>
#include <pdal/SpatialReference.hpp>
#include <pdal/io/LasHeader.hpp>
#include <pdal/io/LasReader.hpp>
#include <pdal/io/BufferReader.hpp>
#include <pdal/io/LasWriter.hpp>

//自定义 点 结构体
struct xjPoint
{
	double x;
	double y;
	double z;
	int intensity;
	double GPStime;
	int PointSourceID;
	int r;
	int g;
	int b;
};

class PDALtest : public QMainWindow
{
	Q_OBJECT

public:
	PDALtest(QWidget *parent = Q_NULLPTR);

private:
	Ui::PDALtestClass ui;

	QString m_Path;
	QMultiHash<int, xjPoint> MhPC;

private slots:
	void SelectPCfile();
	void ReadPC();
	void WritePC();
};

2.2 源文件PDALtest.cpp

#include "PDALtest.h"

PDALtest::PDALtest(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	m_Path = "D:";
	MhPC.clear();

	connect(ui.btnSelectPC, SIGNAL(clicked()), this, SLOT(SelectPCfile()));
	connect(ui.btnReadPC, SIGNAL(clicked()), this, SLOT(ReadPC()));
	connect(ui.btnWritePC, SIGNAL(clicked()), this, SLOT(WritePC()));
}

//选择LAS文件
void PDALtest::SelectPCfile()
{
	//选择文件
	QString xjFilePath = QFileDialog::getOpenFileName(this, tr("选择LAS文件"), m_Path, tr("*.las"));
	if (xjFilePath.isEmpty())
		return;
	if (!QFile::exists(xjFilePath))
		return;
	ui.lineFilePath->setText(xjFilePath);
	m_Path = QFileInfo(xjFilePath).absolutePath();

	//ReadPC();

	//WritePC();
}

//读取点云
void PDALtest::ReadPC()
{
	//清空,点保存到哈希表
	MhPC.clear();

	using namespace pdal;
	using namespace pdal::Dimension;

	QString xjFilePath = ui.lineFilePath->text();
	pdal::Option las_opt("filename", xjFilePath.toStdString());//参数1:"filename"(键)
	pdal::Options las_opts;
	las_opts.add(las_opt);

	pdal::PointTable table;
	pdal::LasReader las_reader;
	las_reader.setOptions(las_opts);
	las_reader.prepare(table);

	pdal::PointViewSet point_view_set = las_reader.execute(table);
	pdal::PointViewPtr point_view = *point_view_set.begin();
	pdal::Dimension::IdList dims = point_view->dims();
	pdal::LasHeader las_header = las_reader.header();

	//头文件信息
	unsigned int PointCount = las_header.pointCount();
	//char* projstr = table.spatialRef().getWKT(pdal::SpatialReference::eCompoundOK).c_str();
	double scale_x = las_header.scaleX();
	double scale_y = las_header.scaleY();
	double scale_z = las_header.scaleZ();
	double offset_x = las_header.offsetX();
	double offset_y = las_header.offsetY();
	double offset_z = las_header.offsetZ();
	double xmin = las_header.minX();
	double xmax = las_header.maxX();
	double ymin = las_header.minY();
	double ymax = las_header.maxY();
	double zmin = las_header.minZ();
	double zmax = las_header.maxZ();

	QString HeaderInfo = "头文件信息:\n";
	HeaderInfo += "PointCount=" + QString::number(PointCount) + "\n";
	HeaderInfo += "scale_y=" + QString::number(scale_y, 'f', 4);
	HeaderInfo += ", scale_y=" + QString::number(scale_y, 'f', 4);
	HeaderInfo += ", scale_z=" + QString::number(scale_z, 'f', 4) + "\n";
	HeaderInfo += "offset_x=" + QString::number(offset_x, 'f', 4);
	HeaderInfo += ", offset_y=" + QString::number(offset_y, 'f', 4);
	HeaderInfo += ", offset_z=" + QString::number(offset_z, 'f', 4) + "\n";
	HeaderInfo += "xmin=" + QString::number(xmin, 'f', 4);
	HeaderInfo += ", xmax=" + QString::number(xmax, 'f', 4);
	HeaderInfo += ", ymin=" + QString::number(ymin, 'f', 4);
	HeaderInfo += ", ymax=" + QString::number(ymax, 'f', 4);
	HeaderInfo += ", zmin=" + QString::number(zmin, 'f', 4);
	HeaderInfo += ", zmax=" + QString::number(zmax, 'f', 4) + "\n";
	ui.listView->addItem(HeaderInfo);

	//读点
	unsigned int n_features = las_header.pointCount();
	int count = 0;
	for (pdal::PointId idx = 0; idx < point_view->size(); ++idx)
	{
		double x = point_view->getFieldAs<double>(Id::X, idx);
		double y = point_view->getFieldAs<double>(Id::Y, idx);
		double z = point_view->getFieldAs<double>(Id::Z, idx);
		int Pintensity = point_view->getFieldAs<int>(Id::Intensity, idx);
		int PointSourceID = point_view->getFieldAs<int>(Id::PointSourceId, idx);
		double GPStime = point_view->getFieldAs<double>(Id::GpsTime, idx);
		int red = point_view->getFieldAs<int>(Id::Red, idx);
		int green = point_view->getFieldAs<int>(Id::Green, idx);
		int blue = point_view->getFieldAs<int>(Id::Blue, idx);
		int point_class = point_view->getFieldAs<int>(Id::Classification, idx);

		//显示信息
		if (count < 5)
		{
			QString pinfo = "ID=" + QString::number(count);
			pinfo += ", X=" + QString::number(x, 'f', 4);
			pinfo += ", Y=" + QString::number(y, 'f', 4);
			pinfo += ", Z=" + QString::number(z, 'f', 4);
			pinfo += ", Intensity=" + QString::number(Pintensity);
			pinfo += ", PointSourceID=" + QString::number(PointSourceID);
			pinfo += ", GPStime=" + QString::number(GPStime, 'f', 4);
			pinfo += ", Red=" + QString::number(red);
			pinfo += ", Green=" + QString::number(green);
			pinfo += ", Blue=" + QString::number(blue);
			pinfo += ", class=" + QString::number(point_class) + "。";
			ui.listView->addItem(pinfo);
		}


		//存储
		xjPoint point;
		point.x = x + 11;
		point.y = y + 11;
		point.z = z + 11;
		point.intensity = Pintensity;
		point.PointSourceID = PointSourceID;
		point.GPStime = GPStime;
		point.r = red;
		point.g = green;
		point.b = blue;
		MhPC.insert(count, point);

		count++;
	}
}

//保存点云
void PDALtest::WritePC()
{
	QString SaveFilePath = m_Path + "/saved.las";

	using namespace pdal;
	using namespace pdal::Dimension;

	Options xjOptions;
	xjOptions.add("filename", SaveFilePath.toLocal8Bit().toStdString());
	xjPoint p3d = MhPC.value(0);
	double xoffset, yoffset, zoffset;
	xoffset = floor(p3d.x);
	yoffset = floor(p3d.y);
	zoffset = floor(p3d.z);
	xjOptions.add("offset_x", xoffset);
	xjOptions.add("offset_y", yoffset);
	xjOptions.add("offset_z", zoffset);
	xjOptions.add("scale_x", 0.0001);
	xjOptions.add("scale_y", 0.0001);
	xjOptions.add("scale_z", 0.0001);

	PointTable table;
	table.layout()->registerDim(Dimension::Id::X);
	table.layout()->registerDim(Dimension::Id::Y);
	table.layout()->registerDim(Dimension::Id::Z);
	table.layout()->registerDim(Dimension::Id::Intensity);
	table.layout()->registerDim(Dimension::Id::GpsTime);
	table.layout()->registerDim(Dimension::Id::PointSourceId);
	table.layout()->registerDim(Dimension::Id::Red);
	table.layout()->registerDim(Dimension::Id::Green);
	table.layout()->registerDim(Dimension::Id::Blue);

	PointViewPtr view(new PointView(table));

	for (int i = 0; i < MhPC.size(); i++)
	{
		double x = MhPC.value(i).x;
		double y = MhPC.value(i).y;
		double z = MhPC.value(i).z;
		int intensity = MhPC.value(i).intensity;
		double GPStime = MhPC.value(i).GPStime;
		int PointSourceId = MhPC.value(i).PointSourceID;
		int red = MhPC.value(i).r;
		int green = MhPC.value(i).g;
		int blue = MhPC.value(i).b;

		view->setField(pdal::Dimension::Id::X, i, x);
		view->setField(pdal::Dimension::Id::Y, i, y);
		view->setField(pdal::Dimension::Id::Z, i, z);
		view->setField(pdal::Dimension::Id::Intensity, i, intensity);
		view->setField(pdal::Dimension::Id::GpsTime, i, GPStime);
		view->setField(pdal::Dimension::Id::PointSourceId, i, PointSourceId);
		view->setField(pdal::Dimension::Id::Red, i, static_cast<uint16_t>(red));
		view->setField(pdal::Dimension::Id::Green, i, static_cast<uint16_t>(green));
		view->setField(pdal::Dimension::Id::Blue, i, static_cast<uint16_t>(blue));
	}

	BufferReader xjBufferReader;
	xjBufferReader.addView(view);

	StageFactory factory;
	Stage *writer = factory.createStage("writers.las");
	writer->setInput(xjBufferReader);
	writer->setOptions(xjOptions);
	writer->prepare(table);
	writer->execute(table);

	QMessageBox::information(0, "提示", "保存成功");
}

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

累了就要打游戏

把我养胖,搞代码

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值