// 提取不带后缀的文件名
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;
}
LASTools点云分块(矩形分块以及按照点数分块)
于 2024-07-14 14:04:45 首次发布