1 配置环境
1.1 属性——C/C++——常规——附加包含目录,添加头文件路径C:\OSGeo4W64\include
1.2 属性——链接器——输入——附加依赖项,添加lib文件C:\OSGeo4W64\lib\pdalcpp.lib和C:\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, "提示", "保存成功");
}