本文使用
LASlib
库完成点云及投影信息的读写。具体安装方式可自行网上搜索,推荐使用
vcpkg
安装,非常方便。
对于库的使用下面直接上代码:
头文件:
#include <LASlib/lasreader.hpp>
#include <LASlib/laswriter.hpp>
1、las文件的读
先是LASreadOpener对象构造,设置文件名,然后进行点云的打开。
LASreadOpener lasreadopener;
lasreadopener.set_file_name(input_file.c_str());
LASreader* lasreader = lasreadopener.open();
读取las头文件信息:
//打印头文件信息
F64 x_offset = lasreader->header.x_offset;
F64 y_offset = lasreader->header.y_offset;
F64 z_offset = lasreader->header.z_offset;
F64 x_scale_factor = lasreader->header.x_scale_factor;
F64 y_scale_factor = lasreader->header.y_scale_factor;
F64 z_scale_factor = lasreader->header.z_scale_factor;
U8 point_data_format = lasreader->header.point_data_format;
U16 point_data_record_length = lasreader->header.point_data_record_length;
U16 file_source_ID = lasreader->header.file_source_ID;
U16 global_encoding = lasreader->header.global_encoding;
//读取.las文件的版本号
U8 version_major = lasreader->header.version_major;
U8 version_minor = lasreader->header.version_minor;
查看las文件的
投影信息
,可以参考该
博客
。
string input_file = argv[1];
LASreadOpener lasreadopener;
lasreadopener.set_file_name(input_file.c_str());
LASreader* lasreader = lasreadopener.open();
printf("system_identifier : %s\n", lasreader->header.system_identifier);
printf("generating_software : %s\n", lasreader->header.generating_software);
char* ds = (char*)lasreader->header.vlrs->description;
printf("vlrs description: %s\n", ds);
char* ui = (char*)lasreader->header.vlrs->user_id;
printf("user_id: %s\n", ui);
printf("point_data_format:%d\n", lasreader->header.point_data_format);
printf("minX:%f maxX:%f\n", lasreader->header.min_x, lasreader->header.max_x);
printf("minY:%f maxY:%f\n", lasreader->header.min_y, lasreader->header.max_y);
printf("minZ:%f maxZ:%f\n", lasreader->header.min_z, lasreader->header.max_z);
printf("number_of_point_records:%d\n", lasreader->header.number_of_point_records);
//顺序读取Geokeys
int numof_keys2 = lasreader->header.vlr_geo_keys->number_of_keys;
cout << "numof_keys2:" << numof_keys2 << endl;
for (int i = 0; i < numof_keys2; i++)
{
//顺序读取GeoKey内容
U16 id = (lasreader->header.vlr_geo_key_entries + i)->key_id;
U16 Location = (lasreader->header.vlr_geo_key_entries + i)->tiff_tag_location;
U16 count = (lasreader->header.vlr_geo_key_entries + i)->count;
U16 value_offset = (lasreader->header.vlr_geo_key_entries + i)->value_offset;
//vlr_geo_double_params
F64 value;
if (Location == 34736)
{
value = lasreader->header.vlr_geo_double_params[value_offset];
printf("keysID:%d ,Location:%d,Count: %d ,Value_offset:%d ,Value:%f \n", id, Location, count, value_offset, value);
}
//vlr_geo_ascii_params
else if (Location == 34737)
{
CHAR value_char[32];
for (int j = 0; j < count; j++)
{
value_char[j] = lasreader->header.vlr_geo_ascii_params[value_offset + j];
}
printf("keysID:%d ,Location:%d,Count: %d ,Value_offset:%d ,ValueChar:%s \n", id, Location, count, value_offset, value_char);
}
else
printf("keysID:%d ,Location:%d,Count: %d ,Value_offset:%d\n", id, Location, count, value_offset);
}
打印结果如下:
system_identifier : libLAS
generating_software : libLAS 1.8.1
vlrs description: GeoTIFF GeoKeyDirectoryTag
user_id: LASF_Projection
point_data_format:3
minX:772891.614624 maxX:774110.863464
minY:2572529.591858 maxY:2573509.307495
minZ:-468.167542 maxZ:190.500195
number_of_point_records:36862258
numof_keys2:7
keysID:1024 ,Location:0,Count: 1 ,Value_offset:1
keysID:1025 ,Location:0,Count: 1 ,Value_offset:1
keysID:1026 ,Location:34737,Count: 22 ,Value_offset:0 ,ValueChar:WGS 84 / UTM zone 49N|
keysID:2049 ,Location:34737,Count: 7 ,Value_offset:22 ,ValueChar:WGS 84|/ UTM zone 49N|
keysID:2054 ,Location:0,Count: 1 ,Value_offset:9102
keysID:3072 ,Location:0,Count: 1 ,Value_offset:32649
keysID:3076 ,Location:0,Count: 1 ,Value_offset:9001
2、las文件的写
las文件的写使用的是LASwriteOpener,和LASreadOpener 类似,先构造LASwriteOpener对象,然后再设置输出路径。
LASwriteOpener laswriteopener;
laswriteopener.set_file_name(out_laz.c_str());
下面是设置las的头文件信息,代码中的具体参数值要根据实际情况数据来设定。
LASheader las_header_writer;
las_header_writer.global_encoding = global_encoding;
las_header_writer.x_scale_factor = resolution;
las_header_writer.y_scale_factor = resolution;
las_header_writer.z_scale_factor = resolution;
las_header_writer.x_offset = x_offset;
las_header_writer.y_offset = y_offset;
las_header_writer.z_offset = z_offset;
las_header_writer.point_data_format = point_data_format;
las_header_writer.point_data_record_length = point_data_record_length;
las_header_writer.version_minor = version_minor;
las_header_writer.version_major = version_major;
las_header_writer.file_source_ID = file_source_ID;
char system_identifier[32] = "PDAL";
char generating_software[32] = "PDAL 2.1.0";
char user_id[16] = "LASF_Projection";
char description[32] = " GeoTiff GeoKeyDirectoryTag";
las_header_writer.vlrs = new LASvlr();
strcpy(las_header_writer.system_identifier, system_identifier);
strcpy(las_header_writer.generating_software, generating_software);
strcpy(las_header_writer.vlrs->description, description);
strcpy(las_header_writer.vlrs->user_id, user_id);
上面是设置las文件基本的头文件信息,如果需要增加其他的信息,比如添加las文件的投影信息,则需要在可变长记录区(VLRs)中添加。下面是添加las文件的投影信息的例子。代码中的key_id以及value_offset代表的意义可以在
这里
查看。
LASvlr_key_entry geo_keys[5];
geo_keys[0].key_id = 1024; // GTModelTypeGeoKey
geo_keys[0].tiff_tag_location = 0;
geo_keys[0].count = 1;
geo_keys[0].value_offset = 1; // ModelTypeProjected
geo_keys[1].key_id = 3072; // ProjectedCSTypeGeoKey
geo_keys[1].tiff_tag_location = 0;
geo_keys[1].count = 1;
geo_keys[1].value_offset = epsg_code; // PCS_WGS84_UTM
// horizontal units
geo_keys[2].key_id = 3076; // ProjLinearUnitsGeoKey
geo_keys[2].tiff_tag_location = 0;
geo_keys[2].count = 1;
geo_keys[2].value_offset = 9001; // meters
// vertical units
geo_keys[3].key_id = 4099; // VerticalUnitsGeoKey
geo_keys[3].tiff_tag_location = 0;
geo_keys[3].count = 1;
geo_keys[3].value_offset = 9001; // meters
// vertical datum
geo_keys[4].key_id = 4096; // VerticalCSTypeGeoKey
geo_keys[4].tiff_tag_location = 0;
geo_keys[4].count = 1;
geo_keys[4].value_offset = 5030; // WGS84
las_header_writer.set_geo_keys(5, geo_keys);
接下来是构造LASwriter对象,写入点数据到该对象中。
// open laswriter
LASwriter* laswriter = laswriteopener.open(&las_header_writer);
if (laswriter == 0)
{
printf("ERROR: could not open laswriter\n");
return EXIT_FAILURE;
}
std::vector<LASpoint> vecLASpoint;
LASpoint laspoint;
// 初始化点的格式及一些属性
laspoint.init(&las_header_writer, las_header_writer.point_data_format, las_header_writer.point_data_record_length, 0);
通过遍历给LASwriter对象写入点数据:
double maxX = -DBL_MAX, maxY = -DBL_MAX, maxZ = -DBL_MAX;
int i_points= 0;
for (int i = 0; i < 100000; ++i)
{
laspoint.set_X(pointX[i]);
laspoint.set_Y(pointY[i]);
laspoint.set_Z(pointZ[i]);
laspoint.set_R(pointR[i]);
laspoint.set_G(pointG[i]);
laspoint.set_B(pointB[i]);
// write the point
laswriter->write_point(&laspoint);
// add it to the inventory
laswriter->update_inventory(&laspoint);
//range
double x = pointX[i];
double y = pointY[i];
double z = pointZ[i];
if (x < minX) minX = x;
if (x > maxX) maxX = x;
if (y < minY) minY = y;
if (y > maxY) maxY = y;
if (z < minZ) minZ = z;
if (z > maxZ) maxZ = z;
i_points++;
}
// update the boundary
las_header_writer.set_bounding_box(minX, minY, minZ, maxX, maxY, maxZ);
las_header_writer.number_of_point_records = i_points;
// update the header
laswriter->update_header(&las_header_writer, TRUE, TRUE);
// close the writer
laswriter->close();
delete laswriter;
以上记录了las文件的读写,以及las的投影信息的读写,如有错误望指正。
版权声明:本文为u010670734原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。