libLAS 读写点云数据(las2txt)

前言

LAS格式是美国摄影测量与遥感协会(ASPRS)下属的LiDAR委员会制定的标准LiDAR数据格式,该格式是目前最常用的LiDAR数据存储格式。LAS文件里包含3个部分(头数据块、变长数据记录区和点数据记录区),具体意义在格式说明里都有详细讲解就不在这里赘述了。
不管是车载LiDAR、还是机载LiDAR,采集的点云数据都具有海量性,这也导致las数据文件常常有几个GB大小(甚至更大),其中包含的离散点数据能达到(千万以上)。若不对原始数据做金字塔处理,一般的硬件设备或常用的软件都不具备显示或编辑这样的数据能力,而金字塔处理方法目前还未发现开源代码可供学习(若有,还请提醒一下共同学习),但是可以采用将大数据量的las文件,分割成若干个小数据量的las或者文本文件(txt),这样就可以在普通硬件、软件和自己的程序里进行显示和处理了。下面笔者将对如何从大数据las文件分割成若干小数据量文本文件进行讲解,最后制作一个小的应用供大家使用。

实验数据介绍

数据为las格式,大小1.79GB,包含5600万离散点。

libLAS库的编译和配置

在前面博客中已有详细讲解,请参考。

代码及含义

利用C++语言读写las文件,在liblas库的官网上有详细的介绍,感兴趣的可以学习。官网链接:http://www.liblas.org/tutorial/cpp.html#reading-las-data-using-liblas-reader
lasfilesegment.h

#include <iostream>
#include <string>

    //************************************
    // ClassName: LasFileSegment
    // Date:      2016/04/29
    // Author:    Mr.Shi
    // Contact:   ***
    //************************************
class LasFileSegment
{
    std::string inFileName_;                    //文件名
public:
    LasFileSegment(){};
    void setFileName(std::string _inFileName){  //设置读入文件名
        inFileName_=_inFileName;
    }

    //************************************
    // Method:    fileSegment
    // FullName:  LasFileSegment::fileSegment
    // Access:    public 
    // Returns:   void
    // Qualifier:
    // function:  将las文件分割成1000万点一份的txt数据
    //************************************
    void fileSegment();                         //文件分割
};

lasfilesegment.cpp

#include <liblas\liblas.hpp>
#include <iomanip>
#include <sstream>
#include "lasfilesegment.h"

void LasFileSegment::fileSegment()
{
    std::ifstream ifs;
    ifs.open(inFileName_, std::ios::in | std::ios::binary);
    if (ifs == NULL)
    {
        std::cout<<"File Error!"<<std::endl;
        return;
    }
    liblas::ReaderFactory f ;

    liblas::Reader reader = f.CreateWithStream(ifs);                                                //
    liblas::Header const& header = reader.GetHeader();                                              //las文件头数据块信息

    std::cout<<"Number of point records     : "<<header.GetPointRecordsCount()<<std::endl;          //记录的点数信息,下面的信息比较重要,都列出来了,具体意思也比较好理解
    std::cout<<"File Signature (“LASF”)   : "<<header.GetFileSignature()<<std::endl;

    std::cout<<std::setiosflags(std::ios::fixed);                                                   //设置显示小数点后9位小数。
    std::cout<<std::setprecision(9)<<"X scale factor              : "<<header.GetScaleX()<<std::endl;
    std::cout<<"Y scale factor              : "<<header.GetScaleY()<<std::endl;
    std::cout<<"Z scale factor              : "<<header.GetScaleZ()<<std::endl;
    std::cout<<"X offset                    : "<<header.GetOffsetX()<<std::endl;
    std::cout<<"Y offset                    : "<<header.GetOffsetY()<<std::endl;
    std::cout<<"Z offset                    : "<<header.GetOffsetZ()<<std::endl;
    std::cout<<"Max X                       : "<<header.GetMaxX()<<std::endl;
    std::cout<<"Max Y                       : "<<header.GetMaxY()<<std::endl;
    std::cout<<"Max Z                       : "<<header.GetMaxZ()<<std::endl;
    std::cout<<"Min X                       : "<<header.GetMinX()<<std::endl;
    std::cout<<"Min Y                       : "<<header.GetMinY()<<std::endl;
    std::cout<<"Min Z                       : "<<header.GetMinZ()<<std::endl;

    reader.ReadPointAt(0);                                                                          //点集记录区中的信息
    liblas::Point const& p = reader.GetPoint();
    std::cout<<"X                           :"<<p.GetX()<<std::endl;
    std::cout<<"Y                           :"<<p.GetY()<<std::endl;
    std::cout<<"Z                           :"<<p.GetZ()<<std::endl;
    std::cout<<"Intensity                   :"<<p.GetIntensity()<<std::endl;
    std::cout<<"Return Number               :"<<p.GetReturnNumber()<<std::endl;
    std::cout<<"Number of Returns           :"<<p.GetNumberOfReturns()<<std::endl;
    std::cout<<"Classification              :"<<p.GetClassification()<<std::endl;
    std::cout<<"Scan Direction Flag         :"<<p.GetScanDirection()<<std::endl;
    std::cout<<"Edge of Flight Line         :"<<p.GetFlightLineEdge()<<std::endl;
    std::cout<<"Scan Angle Rank             :"<<p.GetScanAngleRank()<<std::endl;
    std::cout<<"Point Source ID             :"<<p.GetPointSourceID()<<std::endl;
    std::cout<<"GPS Time                    :"<<p.GetTime()<<std::endl;


    char path_buffer[_MAX_PATH];                                                                    //获取文件路径
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];
    _splitpath( inFileName_.c_str(), drive, dir, fname, ext );
    std::string driveStr(drive),dirStr(dir);
    std::string outFilePath(driveStr+dirStr);
    std::cout<<outFilePath;

    std::string currentFileName("0.txt");
    std::ofstream ofile;
    ofile.open(outFilePath+currentFileName);
    ofile<<"//X Y Z Intensity ReturnNumber NumberofReturns Classification ScanDirectionFlag EdgeofFlightLine ScanAngleRank PointSourceID GPSTime\n";

    int num(0),count(0);
    reader.Seek(0);
    while (reader.ReadNextPoint())                                                                  //每个1000万对数据进行一次保存
    {       
        liblas::Point const& p = reader.GetPoint();

        ofile<<std::setiosflags(std::ios::fixed);
        ofile<<std::setprecision(8)<<p.GetX()<<" "<<p.GetY()<<" "<<p.GetZ()<<" "<<p.GetIntensity()<<" "
            <<p.GetReturnNumber()<<" "<<p.GetNumberOfReturns()<<" "<<p.GetClassification()<<" "
            <<p.GetScanDirection()<<" "<<p.GetFlightLineEdge()<<" "<<p.GetScanAngleRank()<<" "
            <<p.GetPointSourceID()<<" "<<p.GetTime()<<std::endl;

        if (++num%10000000==0)
        {
            ++count;
            ofile.close();
            std::stringstream ss;
            std::string currentFileName;
            ss<<count;
            ss>>currentFileName;
            ofile.open(outFilePath+currentFileName+".txt");
            ofile<<"//X Y Z Intensity ReturnNumber NumberofReturns Classification ScanDirectionFlag EdgeofFlightLine ScanAngleRank PointSourceID GPSTime\n";
        }
    }
    ofile.close();
}

main.cpp


#include "lasfilesegment.h"

int main()
{
    std::string inFileName;
    std::cout<<"Input inFileName:\n";
    std::cin>>inFileName;

    LasFileSegment lfs;
    lfs.setFileName(inFileName);
    lfs.fileSegment();

    return 1;
}

控制台显示
这里写图片描述

使用Qt库为刚才写的代码加个简单界面

这里写图片描述
应用下载连接(使用环境64位系统):http://pan.baidu.com/s/1c1AMtaC

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值