#ifndef LASER_DATA_LOADER_H #define LASER_DATA_LOADER_H #include #include #include #include "VZNL_Types.h" #include "VrError.h" #include "PointCloudXYZRange.h" // 保存进度回调接口 class ISaveProgressCallback { public: virtual ~ISaveProgressCallback() = default; // 进度回调,progress 范围 0.0~1.0 virtual void onSaveProgress(float progress) = 0; // 返回 true 取消保存 virtual bool isSaveCancelled() const { return false; } }; // 范围过滤后的源扫描线布局,仅在对应回调期间使用。 struct LaserLineLoadInfo { int sourcePointCount = 0; std::vector sourcePointIndices; }; // 激光数据加载器类 class LaserDataLoader { public: // lineData is valid only while the callback is running. Copy it to retain it. using LaserLineLoadCallback = std::function; // 过滤后仍提供源扫描线点数及每个保留点的原始线内索引。 using LaserLineLoadIndexedCallback = std::function; // Called exactly once when loading succeeds or fails. // Arguments: result, lineNum, scanSpeed, maxTimeStamp, clockPerSecond. using LaserLoadFinishedCallback = std::function; LaserDataLoader(); ~LaserDataLoader(); // 从文件加载激光扫描数据 - 统一接口,根据文件格式自动判断数据类型 int LoadLaserScanData(const std::string& fileName, std::vector>& laserLines, int& lineNum, float& scanSpeed, int& maxTimeStamp, int& clockPerSecond); // Same loader with an optional inclusive XYZ range. int LoadLaserScanData(const std::string& fileName, std::vector>& laserLines, int& lineNum, float& scanSpeed, int& maxTimeStamp, int& clockPerSecond, const PointCloudXYZRange& range); // Loads one source scan line at a time and immediately invokes lineCallback; // a range filter can make the callback line empty. // finishedCallback is invoked after all lines are read or an error occurs. int LoadLaserScanDataByCallback(const std::string& fileName, const LaserLineLoadCallback& lineCallback, const LaserLoadFinishedCallback& finishedCallback); // Same streaming loader with an optional inclusive XYZ range. int LoadLaserScanDataByCallback(const std::string& fileName, const LaserLineLoadCallback& lineCallback, const LaserLoadFinishedCallback& finishedCallback, const PointCloudXYZRange& range); // 需要保留过滤前拓扑时使用此回调入口。 int LoadLaserScanDataByIndexedCallback( const std::string& fileName, const LaserLineLoadIndexedCallback& lineCallback, const LaserLoadFinishedCallback& finishedCallback, const PointCloudXYZRange& range); // 保存激光扫描数据到文件 - 统一接口,支持两种类型的数据 int SaveLaserScanData(const std::string& fileName, const std::vector>& laserLines, int lineNum, float scanSpeed, int maxTimeStamp, int clockPerSecond); int DebugSaveLaser(std::string fileName, std::vector> xyzData); int DebugSaveLaser(std::string fileName, std::vector> xyzData, ISaveProgressCallback* callback); // 释放统一格式数据内存 void FreeLaserScanData(std::vector>& laserLines); // 释放转换后的SVzNL3DLaserLine数据内存 void FreeConvertedData(std::vector& xyzData); // 释放转换后的SVzNLXYZRGBDLaserLine数据内存 void FreeConvertedData(std::vector& rgbdData); // 转换统一格式数据为SVzNL3DLaserLine格式 int ConvertToSVzNL3DLaserLine(const std::vector>& unifiedData, std::vector& xyzData); // 转换统一格式数据为SVzNLXYZRGBDLaserLine格式 int ConvertToSVzNLXYZRGBDLaserLine(const std::vector>& unifiedData, std::vector& rgbdData); // 转换统一格式数据为std::vector>格式 // validPointCount: 可选输出参数,返回有效点个数(xyz全非0的点) int ConvertToSVzNL3DPosition(const std::vector>& unifiedData, std::vector>& scanLines, size_t* validPointCount = nullptr); // 转换统一格式数据为std::vector>格式 int ConvertToSVzNLPositionD(const std::vector>& unifiedData, std::vector>& scanLines); // 从文件加载图形块数据(Segment_/Poly_/Rect_/Surface_ 等标识)。 // 每个点可只包含 XYZ,也可使用与激光点兼容的 RGBD+RGBA 格式; // shapeBlocks[i] 保存一个图形块的点列表。 int LoadShapeBlocks(const std::string& fileName, std::vector>& shapeBlocks); // 保留旧名称,兼容已有调用方。 int LoadPolySegments(const std::string& fileName, std::vector>& polyLines); // 获取最后的错误信息 std::string GetLastError() const { return m_lastError; } private: // 读取XYZ格式的激光数据 int _ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPosition& s2DData); int _ParseLaserScanPoint(const std::string& data, SVzNL3DPosition& sData, SVzNL2DPositionF& s2DData); // 读取RGBD格式的激光数据 - 新增RGBD支持 int _ParseLaserScanPoint(const std::string& data, SVzNLPointXYZRGBA& sData, SVzNL2DLRPoint& s2DData); // 获取激光数据类型 int _GetLaserType(const std::string& fileName, EVzResultDataType& eDataType); // Read binary .dat laser scan data. int _LoadLaserScanDataFromDatFile(const std::string& fileName, std::vector>& laserLines, int& lineNum, float& scanSpeed, int& maxTimeStamp, int& clockPerSecond, const PointCloudXYZRange& range); int _LoadLaserScanDataFromDatFileByIndexedCallback( const std::string& fileName, const LaserLineLoadIndexedCallback& lineCallback, const LaserLoadFinishedCallback& finishedCallback, const PointCloudXYZRange& range); std::string m_lastError; static const int VZ_LASER_LINE_PT_MAX_NUM = 4096; }; #endif // LASER_DATA_LOADER_H