點雲:libLAS 讀寫點雲

雖然libLAS已經被PDAL取代,但是不可否認,它是一個很nice的庫。

libLAS庫可以通過OSGeo4W下載。

一、配置環境

分享給有需要的人,代碼質量勿噴。

二、讀取點雲並存儲

//libLAS
#include "liblas\liblas.hpp"

/* read las */
void libLAStest::ReadLas(std::vector<xjPoint> &vPoints, const std::string &xjLasPath)
{
	std::ifstream ifs;
	ifs.open(xjLasPath, std::ios::in | std::ios::binary);
	liblas::ReaderFactory factory;
	liblas::Reader xjReader = factory.CreateWithStream(ifs);
	liblas::Header const& xjHeader = xjReader.GetHeader();

#pragma region
	QStringList xjInfo;
	//count
	int pCount = xjHeader.GetPointRecordsCount();
	xjInfo.append("points count: " + QString::number(pCount));
	//range
	double maxX = xjHeader.GetMaxX();
	double minX = xjHeader.GetMinX();
	double maxY = xjHeader.GetMaxY();
	double minY = xjHeader.GetMinY();
	double maxZ = xjHeader.GetMaxZ();
	double minZ = xjHeader.GetMinZ();
	double delatX = maxX - minX;
	double delatY = maxY - minY;
	double delatZ = maxZ - minZ;
	xjInfo.append("range X: " + QString::number(delatX));
	xjInfo.append("range Y: " + QString::number(delatY));
	xjInfo.append("range Z: " + QString::number(delatZ));
	xjInfo.append("-----------");
	//first point's information
	xjInfo.append("first point's information:");
	if (xjReader.ReadPointAt(0))
	{
		liblas::Point const & p = xjReader.GetPoint();
		xjInfo.append("X = " + QString::number(p.GetX(), 'f', 4));
		xjInfo.append("Y = " + QString::number(p.GetY(), 'f', 4));
		xjInfo.append("Z = " + QString::number(p.GetZ(), 'f', 4));
		xjInfo.append("Red = " + QString::number(p.GetColor().GetRed() >> 8));
		xjInfo.append("Green = " + QString::number(p.GetColor().GetGreen() >> 8));
		xjInfo.append("Blue = " + QString::number(p.GetColor().GetBlue() >> 8));
		xjInfo.append("Intensity = " + QString::number(p.GetIntensity()));
		xjInfo.append("PointSourceID = " + QString::number(p.GetPointSourceID()));
		xjInfo.append("GPStime = " + QString::number(p.GetTime()));
	}
	ui.listWidget->addItems(xjInfo);
#pragma endregion

	//while( xjReader.ReadNextPoint() )
	//{
	//	liblas::Point const & p =xjReader.GetPoint();
	//	//...
	//}
	for (unsigned long i = 0; i < pCount; i++)
	{
		if (xjReader.ReadPointAt(i))
		{
			liblas::Point const & p = xjReader.GetPoint();

			xjPoint xjP;
			xjP.x = p.GetX();
			xjP.y = p.GetY();
			xjP.z = p.GetZ();
			xjP.r = p.GetColor().GetRed();
			xjP.g = p.GetColor().GetGreen();
			xjP.b = p.GetColor().GetBlue();
			xjP.intensity = p.GetIntensity();
			xjP.pointSourceID = p.GetPointSourceID();
			xjP.GPStime = p.GetTime();

			vPoints.push_back(xjP);
		}
	}
}

三、寫las

//libLAS
#include <liblas/liblas.hpp>

/* write las */
void libLAStest::WriteLas(const std::string &xjLasResultPath, std::vector<xjPoint> &vPoints)
{
	std::ofstream ofs;
	if (!liblas::Create(ofs, xjLasResultPath))
		return;

	int xoffset = int(vPoints.at(0).x);
	int yoffset = int(vPoints.at(0).y);
	int zoffset = int(vPoints.at(0).z);
	liblas::Header header;
	header.SetVersionMajor(1);
	header.SetVersionMinor(2);
	header.SetOffset(xoffset, yoffset, zoffset);
	header.SetDataFormatId(liblas::ePointFormat3);
	header.SetPointRecordsCount(vPoints.size());
	header.SetScale(0.0001, 0.0001, 0.0001);
	liblas::Writer writer(ofs, header);

	double Max_x = vPoints.at(0).x, Min_x = vPoints.at(0).x;
	double Max_y = vPoints.at(0).y, Min_y = vPoints.at(0).y;
	double Max_z = vPoints.at(0).z, Min_z = vPoints.at(0).z;
	for (int i = 0; i < vPoints.size(); i++)
	{
		xjPoint p = vPoints.at(i);

		liblas::Point point;
		point.SetRawX((p.x - xoffset) * 10000);
		point.SetRawY((p.y - yoffset) * 10000);
		point.SetRawZ((p.z - zoffset) * 10000);

		liblas::Color color;
		color.SetRed(p.r);
		color.SetGreen(p.g);
		color.SetBlue(p.b);
		point.SetColor(color);

		point.SetIntensity(p.intensity);
		point.SetPointSourceID(p.pointSourceID);
		point.SetTime(p.GPStime);

		writer.WritePoint(point);

		if (p.x > Max_x)Max_x = p.x;
		if (p.y > Max_y)Max_y = p.y;
		if (p.z > Max_z)Max_z = p.z;
		if (p.x < Min_x)Min_x = p.x;
		if (p.y < Min_y)Min_y = p.y;
		if (p.z < Min_z)Min_z = p.z;
	}

	header.SetMax(Max_x, Max_y, Max_z);
	header.SetMin(Min_x, Min_y, Min_z);

	writer.SetHeader(header);
	writer.WriteHeader();
	ofs.close();

}

四、button功能

void libLAStest::on_btnLas_clicked()
{
	QString xjLasPath = QFileDialog::getOpenFileName(this, "select LAS", "D:/", "*.las");
	ui.lineEdit->setText(xjLasPath);

	std::vector<xjPoint> vPoints;
	ReadLas(vPoints, xjLasPath.toStdString());

	QString xjSaveLasPath = QCoreApplication::applicationDirPath() + "/save.las";
	WriteLas(xjSaveLasPath.toStdString(), vPoints);
	ui.listWidget->addItem("-------------");
	ui.listWidget->addItem("the new las file have save to");
	ui.listWidget->addItem(xjSaveLasPath);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章