Commit 7e8877e5 authored by xuebingbing's avatar xuebingbing

1 修复因为偏移值过大造成存储las缩放银子过大造成的无法保存的bug,因为las中将double放大到一个int32值保存的原因;

2 完善转换失败时输出的错误信息
parent be91ed3d
...@@ -9,5 +9,21 @@ IF(MSVC) ...@@ -9,5 +9,21 @@ IF(MSVC)
# ADD_DEFINITIONS(-DNOMINMAX) # ADD_DEFINITIONS(-DNOMINMAX)
ENDIF(MSVC) ENDIF(MSVC)
#############################################################################################################
# 本组设置控制所有可执行文件或库输出到一个目录进而在win下可以直接执行
set(DEFAULT_BIN_SUBDIR bin)
set(DEFAULT_LIB_SUBDIR lib)
set(DEFAULT_INCLUDE_SUBDIR include)
set(AUTOMATION_BIN_DIR ${DEFAULT_BIN_SUBDIR} CACHE STRING "可执行文件安装子目录")
set(AUTOMATION_LIB_DIR ${DEFAULT_LIB_SUBDIR} CACHE STRING "库文件安装子目录")
set(AUTOMATION_INCLUDE_DIR ${DEFAULT_INCLUDE_SUBDIR} CACHE STRING "头文件安装子目录")
set(AUTOMATION_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${AUTOMATION_OUTPUT_DIRECTORY}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${AUTOMATION_OUTPUT_DIRECTORY}/lib)
################################################################################
add_subdirectory(src) add_subdirectory(src)
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
#include <pdal/Options.hpp> #include <pdal/Options.hpp>
#include <pdal/io/BufferReader.hpp> #include <pdal/io/BufferReader.hpp>
#include <pdal/StageFactory.hpp> #include <pdal/StageFactory.hpp>
#include <pdal/Dimension.hpp> #include <pdal/Dimension.hpp>
#include <pdal/util/Utils.hpp>
// stl // stl
#include <unordered_map> #include <unordered_map>
pdal::Dimension::Type GetLasDimDataType(const pcl::PCLPointField& field) pdal::Dimension::Type GetLasDimDataType(const pcl::PCLPointField& field)
{ {
switch (field.datatype) { switch (field.datatype) {
...@@ -95,8 +95,9 @@ std::unordered_map<std::string, pdal::Dimension::Id> GetLasdimidFromPcdFields(co ...@@ -95,8 +95,9 @@ std::unordered_map<std::string, pdal::Dimension::Id> GetLasdimidFromPcdFields(co
void PcdPoint2LasPoint(const std::uint8_t* msg_data, const std::vector<::pcl::PCLPointField>& pcdfields, void PcdPoint2LasPoint(const std::uint8_t* msg_data, const std::vector<::pcl::PCLPointField>& pcdfields,
const std::unordered_map<std::string, pdal::Dimension::Id>& pcdfieldname2lasdimid, const std::unordered_map<std::string, pdal::Dimension::Id>& pcdfieldname2lasdimid,
const jfhd::convert::Pcd2LasInfo& info, std::uint64_t las_pointid, pdal::PointViewPtr view) const jfhd::convert::Pcd2LasInfo& info, std::uint64_t las_pointid, pdal::PointViewPtr view, std::int64_t point_count, double* ave_xyz, double* max_xyz)
{ {
double x(0.), y(0.), z(0.);
for (const auto& item : pcdfields) for (const auto& item : pcdfields)
{ {
auto it = pcdfieldname2lasdimid.find(item.name); auto it = pcdfieldname2lasdimid.find(item.name);
...@@ -140,19 +141,19 @@ void PcdPoint2LasPoint(const std::uint8_t* msg_data, const std::vector<::pcl::PC ...@@ -140,19 +141,19 @@ void PcdPoint2LasPoint(const std::uint8_t* msg_data, const std::vector<::pcl::PC
// TODO: 判断x,y,z 进行加减 // TODO: 判断x,y,z 进行加减
if (it->second == pdal::Dimension::Id::X) if (it->second == pdal::Dimension::Id::X)
{ {
double x = val; x = val;
x += info.offsetx; x += info.offsetx;
view->setField(it->second, las_pointid, x); view->setField(it->second, las_pointid, x);
} }
else if(it->second == pdal::Dimension::Id::Y) else if(it->second == pdal::Dimension::Id::Y)
{ {
double y = val; y = val;
y += info.offsety; y += info.offsety;
view->setField(it->second, las_pointid, y); view->setField(it->second, las_pointid, y);
} }
else if(it->second == pdal::Dimension::Id::Z) else if(it->second == pdal::Dimension::Id::Z)
{ {
double z = val; z = val;
z += info.offsetz; z += info.offsetz;
view->setField(it->second, las_pointid, z); view->setField(it->second, las_pointid, z);
} }
...@@ -170,6 +171,14 @@ void PcdPoint2LasPoint(const std::uint8_t* msg_data, const std::vector<::pcl::PC ...@@ -170,6 +171,14 @@ void PcdPoint2LasPoint(const std::uint8_t* msg_data, const std::vector<::pcl::PC
break; break;
} }
} }
ave_xyz[0] += x / (double)point_count;
ave_xyz[1] += y / (double)point_count;
ave_xyz[2] += z / (double)point_count;
max_xyz[0] = x > max_xyz[0] ? x : max_xyz[0];
max_xyz[1] = y > max_xyz[1] ? y : max_xyz[1];
max_xyz[2] = z > max_xyz[2] ? z : max_xyz[2];
} }
namespace jfhd { namespace jfhd {
...@@ -211,29 +220,107 @@ namespace jfhd { ...@@ -211,29 +220,107 @@ namespace jfhd {
std::uint64_t point_index = 0; std::uint64_t point_index = 0;
double ave_xyz[3] = { 0.,0.,0. };
double max_xyz[3] = { std::numeric_limits<double>::min(), std::numeric_limits<double>::min(), std::numeric_limits<double>::min() };
for (std::uint64_t row = 0; row < height; ++row) for (std::uint64_t row = 0; row < height; ++row)
{ {
const std::uint8_t* row_data = &pcloud.data[row * pcloud.row_step]; const std::uint8_t* row_data = &pcloud.data[row * pcloud.row_step];
for (std::uint32_t col = 0; col < pcloud.width; ++col) for (std::uint32_t col = 0; col < pcloud.width; ++col)
{ {
//std::cout << point_index << ":";
const std::uint8_t* msg_data = row_data + col * point_step; const std::uint8_t* msg_data = row_data + col * point_step;
PcdPoint2LasPoint(msg_data, pcloud.fields, dict_pclfieldname_lasid, info, point_index, view); PcdPoint2LasPoint(msg_data, pcloud.fields, dict_pclfieldname_lasid, info, point_index, view, point_count, ave_xyz, max_xyz);
++point_index; ++point_index;
//std::cout << std::endl;
} }
} }
//std::string lasfilepath{ "E:/data/jd/task1-2/1106/JF_PCD/12_ground_utm_add_myself.las" }; //std::string lasfilepath{ "E:/data/jd/task1-2/1106/JF_PCD/12_ground_utm_add_myself.las" };
pdal::Options las_options; pdal::Options las_options;
las_options.add("filename", lasfilepath); las_options.add("filename", lasfilepath);
las_options.add("extra_dims", "all"); las_options.add("extra_dims", "all");
las_options.add("scale_x", 1.0e-5);
las_options.add("scale_y", 1.0e-5); // 计算scale 和 offset
las_options.add("scale_z", 1.0e-5); std::int32_t x_offset(0), y_offset(0), z_offset(0);
if (!pdal::Utils::numericCast(ave_xyz[0], x_offset))
{
std::stringstream ss;
ss << "Unable to convert scaled value (average X)[" << pcdfilepath << "]failed";
*errormsg = ss.str();
return false;
}
if (!pdal::Utils::numericCast(ave_xyz[1], y_offset))
{
std::stringstream ss;
ss << "Unable to convert scaled value (average Y)[" << pcdfilepath << "]failed";
*errormsg = ss.str();
return false;
}
if (!pdal::Utils::numericCast(ave_xyz[2], z_offset))
{
std::stringstream ss;
ss << "Unable to convert scaled value (average Z)[" << pcdfilepath << "]failed";
*errormsg = ss.str();
return false;
}
auto get_intpartlen_func = [](double max, double offset) {
std::int32_t integer_part_len = 0;
double temp = 0., low = 0.;
while (true)
{
temp = std::abs(max - offset);
low = std::pow(10, integer_part_len);
if (temp < low)
return integer_part_len;
else
++integer_part_len;
}
};
// 该处理能最大的保留数据精度,小数点后数字保留精度
constexpr std::int32_t kMaxPresionLen = 8;
int x_presion_len = get_intpartlen_func(max_xyz[0], x_offset) - kMaxPresionLen;
int y_presion_len = get_intpartlen_func(max_xyz[1], y_offset) - kMaxPresionLen;
int z_presion_len = get_intpartlen_func(max_xyz[2], z_offset) - kMaxPresionLen;
double x_scale = std::pow(10., x_presion_len);
double y_scale = std::pow(10., y_presion_len);
double z_scale = std::pow(10., z_presion_len);
auto check_xyz_func = [=](pdal::XForm& form, double value, std::string* error_msg) {
double temp = form.toScaled(value);
std::int32_t i(0);
if (!pdal::Utils::numericCast(temp, i))
{
std::stringstream ss;
ss << "Unable to convert scaled value " << value << "[" << pcdfilepath << "]failed";
*errormsg = ss.str();
return false;
}
return true;
};
pdal::XForm x_xform(x_scale, x_offset);
pdal::XForm y_xform(y_scale, y_offset);
pdal::XForm z_xform(z_scale, z_offset);
if (!check_xyz_func(x_xform, max_xyz[0], errormsg)
|| !check_xyz_func(y_xform, max_xyz[1], errormsg)
|| !check_xyz_func(z_xform, max_xyz[2], errormsg))
return false;
las_options.add("scale_x", x_scale);
las_options.add("scale_y", y_scale);
las_options.add("scale_z", z_scale);
las_options.add("offset_x", x_offset);
las_options.add("offset_y", y_offset);
las_options.add("offset_z", z_offset);
pdal::Uuid uuid; pdal::Uuid uuid;
uuid.parse("C8DED732-F71F-44D7-A62E-24F7F8A43E69"); uuid.parse("C8DED732-F71F-44D7-A62E-24F7F8A43E69");
las_options.add("project_id", uuid); las_options.add("project_id", uuid);
......
...@@ -512,9 +512,10 @@ int pcd2lasByStationFiles(const cxxopts::ParseResult& argsresult) ...@@ -512,9 +512,10 @@ int pcd2lasByStationFiles(const cxxopts::ParseResult& argsresult)
std::string temp = argsresult["jf_station_file"].as<std::string>(); std::string temp = argsresult["jf_station_file"].as<std::string>();
// 查找station_jf.txt文件 // 查找station_jf.txt文件
path testdir(initial_path()); //path testdir(initial_path());
// path testdir("D:/workspace/JF/repos/cc/fmt_converter/build/src/jfhdconvertor");
//workdir = system_complete(path(workdirpath, portable_name)); //workdir = system_complete(path(workdirpath, portable_name));
testdir = system_complete(path(temp)); //testdir = system_complete(path(temp));
//workdir = system_complete(path(workdirpath)); //workdir = system_complete(path(workdirpath));
path jf_stationfilepath(temp.begin(), temp.end());// = initial_path(); path jf_stationfilepath(temp.begin(), temp.end());// = initial_path();
...@@ -592,7 +593,8 @@ int pcd2lasByStationFiles(const cxxopts::ParseResult& argsresult) ...@@ -592,7 +593,8 @@ int pcd2lasByStationFiles(const cxxopts::ParseResult& argsresult)
std::string errormsg; std::string errormsg;
if (!jfhd::convert::Convertor::Pcd2Las(pcd_filepath.string(), las_filepath.string(), convert_info, &errormsg)) if (!jfhd::convert::Convertor::Pcd2Las(pcd_filepath.string(), las_filepath.string(), convert_info, &errormsg))
{ {
std::cout << "ERROR: failed" << pcd_filepath.string() << ">>" << las_filepath.string() << std::endl; std::cout << "ERROR: failed" << pcd_filepath.string() << ">>" << las_filepath.string() << " DETAIL:" << errormsg
<< std::endl;
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment