LASTools点云分块(矩形分块以及按照点数分块)

// 提取不带后缀的文件名
std::string getFileNameWithoutExtension(const std::string& filePath) {
    size_t pos = filePath.find_last_of("/\\");
    std::string fileName = (pos == std::string::npos) ? filePath : filePath.substr(pos + 1);

    size_t dotPos = fileName.find_last_of(".");
    if (dotPos == std::string::npos) {
        return fileName;
    }
    return fileName.substr(0, dotPos);
}
// 提取上一级目录
std::string getParentDirectory(const std::string& filePath) {
    size_t pos = filePath.find_last_of("/\\");
    if (pos == std::string::npos) {
        return "";
    }
    return filePath.substr(0, pos);
}
void lasFileDivisionBlock(std::string pc_path)
{
    struct MyPoint
    {
        double X;
        double Y;
        double Z;
        MyPoint(double x, double y, double z)
        {
            X = x;
            Y = y;
            Z = z;
        }
    };
    LASwriteOpener laswriteopener;
    LASwriter* laswriter = nullptr;

    LASreadOpener lasReadOpener;
    lasReadOpener.set_file_name(pc_path.c_str());
    LASreader* lasReader = lasReadOpener.open(false);

    typedef std::pair<double, double> minmax_t;
    minmax_t mx(DBL_MAX, -DBL_MAX);
    minmax_t my(DBL_MAX, -DBL_MAX);
    minmax_t mz(DBL_MAX, -DBL_MAX);
    std::vector<MyPoint> PointCloud;
    while (lasReader->read_point())
    {
        LASpoint& pointReader = lasReader->point;
        double X = pointReader.get_x();
        double Y = pointReader.get_y();
        double Z = pointReader.get_z();
        MyPoint one_point(X,Y,Z);
        PointCloud.push_back(one_point);
        mx.first = std::min<double>(mx.first, X);
        mx.second = std::max<double>(mx.second, X);
        my.first = std::min<double>(my.first, Y);
        my.second = std::max<double>(my.second, Y);
        mz.first = std::min<double>(mz.first, Z);
        mz.second = std::max<double>(mz.second, Z);
    }
    lasReader->close();
    delete lasReader;
    lasReader = nullptr;

    float chunk_size = 50.0;
    int num_chunks_x = static_cast<int>((mx.second - mx.first) / chunk_size)+1;
    int num_chunks_y = static_cast<int>((my.second - my.first) / chunk_size)+1;
    float remainder_x = fmod((mx.second - mx.first), chunk_size);
    float remainder_y = fmod((my.second - my.first), chunk_size);
    std::vector<minmax_t> box_xs;
    std::vector<minmax_t> box_ys;
    for (int x = 1; x < num_chunks_x+1; x++)
    {
        //x范围
        minmax_t box_x;
        if (x== num_chunks_x)
        {
            minmax_t box_x_temp(mx.first + chunk_size * (x-1), mx.second);
            box_x = box_x_temp;
        }
        else
        {
            minmax_t box_x_temp(mx.first + chunk_size * (x-1), mx.first + chunk_size * x);
            box_x = box_x_temp;
        }
        for (int y = 1; y < num_chunks_y+1; y++)
        {  
            //y范围
            minmax_t box_y;
            if (y== num_chunks_y)
            {
                minmax_t box_y_temp(my.first + chunk_size * (y-1), my.second);
                box_y = box_y_temp;
            }
            else
            {
                minmax_t box_y_temp(my.first + chunk_size * (y-1), my.first + chunk_size * y);
                box_y = box_y_temp;
            }
            box_xs.push_back(box_x);
            box_ys.push_back(box_y);
        }
    }
    //取出每一块的点云
    for (size_t i = 0; i < box_xs.size(); i++)
    {
        minmax_t box_x = box_xs[i];
        minmax_t box_y = box_ys[i];
        std::vector<MyPoint> PointCloud_Block;
        for (size_t j = 0; j < PointCloud.size(); j++)
        {
            if (box_x.first <= PointCloud[j].X && PointCloud[j].X <= box_x.second &&
                box_y.first <= PointCloud[j].Y && PointCloud[j].Y <= box_y.second)
            {
                PointCloud_Block.push_back(PointCloud[j]);
            }
        }
        if (PointCloud_Block.size() == 0) continue;
        //保存这一块的点云
        LASheader lasHeader;
        if (laswriter != NULL)
        {
            laswriter->close();
        }
        else
        {
            std::string file_name = getParentDirectory(pc_path) + "/" + getFileNameWithoutExtension(pc_path) + "_block" + std::to_string(i) + ".las";
            laswriteopener.set_file_name(file_name.c_str());
            LASheader writeHeader;
            laswriter = laswriteopener.open(&writeHeader);
        }
        for (size_t k = 0; k < PointCloud_Block.size(); k++)
        {
            LASpoint lasPoint;
            lasPoint.init(&lasHeader, lasHeader.point_data_format, lasHeader.point_data_record_length, 0);
            lasPoint.set_x(PointCloud_Block[k].X);
            lasPoint.set_y(PointCloud_Block[k].Y);
            lasPoint.set_z(PointCloud_Block[k].Z);
            laswriter->write_point(&lasPoint);
            laswriter->update_inventory(&lasPoint);
        }
        laswriter->close();
        laswriter = nullptr;
    }
}
void lasFileDivision(std::string pc_path)
{
    LASreadOpener lasreadopener;
    LASwriteOpener laswriteopener;
    int num = 1;
    lasreadopener.set_file_name(pc_path.c_str());
    LASreader* lasreader = lasreadopener.open();
    int loop_time = 0;
    LASwriter* laswriter = nullptr;
    while (lasreader->read_point())  //只让输出前 10 行坐标
    {
        //按照每889000个点一个las文件进行分割
        if (loop_time % 889000 == 0)
        {
            //每打开一次文件都需要close();否则文件会一直占用。
            if (laswriter != NULL)
            {
                laswriter->close();
            }
            std::string file_name = getParentDirectory(pc_path)+"/" + getFileNameWithoutExtension(pc_path) + "_block" + std::to_string(num) + ".las";
            laswriteopener.set_file_name(file_name.c_str());

            LASheader writeHeader;
            laswriter = laswriteopener.open(&writeHeader);
            if (laswriter == 0)
            {
                fprintf(stderr, "ERROR: could not open laswriter\n");
            }
            num++;
        }
        laswriter->write_point(&lasreader->point);
        laswriter->update_inventory(&lasreader->point);
        loop_time++;
    }
    laswriter->update_header(&lasreader->header, TRUE);

    I64 total_bytes = laswriter->close();
    delete laswriter;
    laswriter = nullptr;

    lasreader->close();
    delete lasreader;
    lasreader = nullptr;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值