274 lines
12 KiB
C++
274 lines
12 KiB
C++
#include "VrBeltTearingConfig.h"
|
|
#include "IVrBeltTearingConfig.h"
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
#include "VrLog.h"
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
#include <QString>
|
|
#include <QTextCodec>
|
|
#include <QXmlStreamReader>
|
|
#include <QXmlStreamWriter>
|
|
|
|
VrBeltTearingConfig::VrBeltTearingConfig()
|
|
: m_notify(nullptr)
|
|
{
|
|
}
|
|
|
|
VrBeltTearingConfig::~VrBeltTearingConfig()
|
|
{
|
|
}
|
|
|
|
// Also add the static CreateInstance method to the interface class
|
|
bool IVrBeltTearingConfig::CreateInstance(IVrBeltTearingConfig** ppVrConfig)
|
|
{
|
|
if (!ppVrConfig) {
|
|
return false;
|
|
}
|
|
|
|
*ppVrConfig = new VrBeltTearingConfig();
|
|
return true;
|
|
}
|
|
|
|
BeltTearingConfigResult VrBeltTearingConfig::LoadConfig(const std::string& filePath)
|
|
{
|
|
BeltTearingConfigResult result;
|
|
|
|
// 使用QString处理可能包含中文的路径
|
|
QString qFilePath = QString::fromStdString(filePath);
|
|
QFile file(qFilePath);
|
|
|
|
// 检查文件是否存在并可读
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
LOG_DEBUG("Failed to open file: %s\n", filePath.c_str());
|
|
return result;
|
|
}
|
|
|
|
// 使用QXmlStreamReader解析XML内容
|
|
QXmlStreamReader xml(&file);
|
|
|
|
// 读取到根元素
|
|
if (xml.readNextStartElement()) {
|
|
if (xml.name() != "BeltTearingConfig") {
|
|
xml.raiseError(QObject::tr("Not a BeltTearingConfig file"));
|
|
}
|
|
} else {
|
|
xml.raiseError(QObject::tr("Failed to read root element"));
|
|
}
|
|
|
|
// 解析XML内容
|
|
while (!xml.atEnd() && !xml.hasError()) {
|
|
xml.readNext();
|
|
|
|
// 解析服务器配置
|
|
if (xml.isStartElement() && xml.name() == "ClientServers") {
|
|
while (xml.readNextStartElement()) {
|
|
if (xml.name() == "Server") {
|
|
ServerInfo server;
|
|
server.name = xml.attributes().value("name").toString().toStdString(); server.ip = xml.attributes().value("ip").toString().toStdString();
|
|
server.port = xml.attributes().value("port").toInt();
|
|
result.servers.push_back(server);
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 解析算法参数
|
|
else if (xml.isStartElement() && xml.name() == "AlgorithmParams") {
|
|
while (xml.readNextStartElement()) {
|
|
// 皮带撕裂参数
|
|
if (xml.name() == "BeltTearingParam") {
|
|
// 读取简化的SDK兼容参数
|
|
result.algorithmParams.beltTearingParam.scanXScale =
|
|
xml.attributes().value("ScanXScale").toDouble();
|
|
result.algorithmParams.beltTearingParam.scanYScale =
|
|
xml.attributes().value("ScanYScale").toDouble();
|
|
result.algorithmParams.beltTearingParam.differnceBinTh =
|
|
xml.attributes().value("DiffernceBinTh").toDouble();
|
|
result.algorithmParams.beltTearingParam.tearingMinLen =
|
|
xml.attributes().value("TearingMinLen").toDouble();
|
|
result.algorithmParams.beltTearingParam.tearingMinGap =
|
|
xml.attributes().value("TearingMinGap").toDouble();
|
|
result.algorithmParams.beltTearingParam.sameGapTh =
|
|
xml.attributes().value("SameGapTh").toDouble();
|
|
result.algorithmParams.beltTearingParam.gapChkWin =
|
|
xml.attributes().value("GapChkWin").toInt();
|
|
|
|
// 设置默认值(如果参数不存在)
|
|
if (result.algorithmParams.beltTearingParam.scanXScale == 0.0) {
|
|
result.algorithmParams.beltTearingParam.scanXScale = 1.0;
|
|
}
|
|
if (result.algorithmParams.beltTearingParam.scanYScale == 0.0) {
|
|
result.algorithmParams.beltTearingParam.scanYScale = 1.0;
|
|
}
|
|
if (result.algorithmParams.beltTearingParam.differnceBinTh == 0.0) {
|
|
result.algorithmParams.beltTearingParam.differnceBinTh = 1.0;
|
|
}
|
|
if (result.algorithmParams.beltTearingParam.tearingMinLen == 0.0) {
|
|
result.algorithmParams.beltTearingParam.tearingMinLen = 5.0;
|
|
}
|
|
if (result.algorithmParams.beltTearingParam.tearingMinGap == 0.0) {
|
|
result.algorithmParams.beltTearingParam.tearingMinGap = 2.0;
|
|
}
|
|
if (result.algorithmParams.beltTearingParam.sameGapTh == 0.0) {
|
|
result.algorithmParams.beltTearingParam.sameGapTh = 2.0;
|
|
}
|
|
if (result.algorithmParams.beltTearingParam.gapChkWin == 0) {
|
|
result.algorithmParams.beltTearingParam.gapChkWin = 5;
|
|
}
|
|
|
|
xml.skipCurrentElement();
|
|
}
|
|
// 监控参数
|
|
else if (xml.name() == "MonitoringParam") {
|
|
result.algorithmParams.monitoringParam.checkInterval =
|
|
xml.attributes().value("CheckInterval").toInt();
|
|
result.algorithmParams.monitoringParam.alertThreshold =
|
|
xml.attributes().value("AlertThreshold").toDouble();
|
|
|
|
// 向后兼容:忽略不再使用的参数
|
|
// maxHistorySize 已移除,不再读取
|
|
xml.skipCurrentElement();
|
|
}
|
|
// 跳过不再使用的图像处理参数
|
|
else if (xml.name() == "ImageProcessingParam") {
|
|
// 向后兼容:跳过图像处理参数,不再使用
|
|
xml.skipCurrentElement();
|
|
}
|
|
else {
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 解析调试参数
|
|
else if (xml.isStartElement() && xml.name() == "DebugParam") {
|
|
result.debugParam.enableDebug = xml.attributes().value("enableDebug").toInt();
|
|
result.debugParam.saveDebugImage = xml.attributes().value("saveDebugImage").toInt();
|
|
result.debugParam.printDetailLog = xml.attributes().value("printDetailLog").toInt();
|
|
result.debugParam.debugOutputPath = xml.attributes().value("debugOutputPath").toString().toStdString();
|
|
xml.skipCurrentElement();
|
|
}
|
|
|
|
// 解析项目类型
|
|
else if (xml.isStartElement() && xml.name() == "ProjectType") {
|
|
QString typeStr = xml.attributes().value("type").toString();
|
|
if (typeStr == "BeltMonitoring") {
|
|
result.projectType = BeltTearingProjectType::BeltMonitoring;
|
|
} else {
|
|
result.projectType = BeltTearingProjectType::BeltTearing;
|
|
}
|
|
xml.skipCurrentElement();
|
|
}
|
|
|
|
// 解析服务端配置
|
|
else if (xml.isStartElement() && xml.name() == "LocalServerConfig") {
|
|
while (xml.readNextStartElement()) {
|
|
if (xml.name() == "ServerPort") {
|
|
result.serverPort = xml.attributes().value("port").toInt();
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
|
|
// 检查解析错误
|
|
if (xml.hasError()) {
|
|
LOG_ERROR("XML parsing error: %s\n", xml.errorString().toStdString().c_str());
|
|
return BeltTearingConfigResult(); // 返回空结果
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool VrBeltTearingConfig::SaveConfig(const std::string& filePath, BeltTearingConfigResult& configResult)
|
|
{
|
|
// 使用QString处理可能包含中文的路径
|
|
QString qFilePath = QString::fromStdString(filePath);
|
|
QFile file(qFilePath);
|
|
|
|
// 打开文件进行写入
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
LOG_DEBUG("Failed to open file for writing: %s\n", filePath.c_str());
|
|
return false;
|
|
}
|
|
|
|
// 使用QXmlStreamWriter写入XML内容
|
|
QXmlStreamWriter xml(&file);
|
|
xml.setAutoFormatting(true);
|
|
xml.setCodec("UTF-8"); // Explicitly set UTF-8 encoding to handle Chinese characters correctly
|
|
xml.writeStartDocument();
|
|
// 设置编码为UTF-8以正确处理中文
|
|
xml.writeStartElement("BeltTearingConfig");
|
|
|
|
// 保存服务器配置
|
|
if (!configResult.servers.empty()) {
|
|
xml.writeStartElement("ClientServers");
|
|
for (const auto& server : configResult.servers) {
|
|
xml.writeStartElement("Server");
|
|
xml.writeAttribute("name", QString::fromStdString(server.name));
|
|
xml.writeAttribute("ip", QString::fromStdString(server.ip));
|
|
xml.writeAttribute("port", QString::number(server.port));
|
|
xml.writeEndElement(); // Server
|
|
}
|
|
xml.writeEndElement(); // ClientServers
|
|
}
|
|
|
|
// 保存算法参数
|
|
xml.writeStartElement("AlgorithmParams");
|
|
|
|
// 皮带撕裂参数 - 简化版本
|
|
xml.writeStartElement("BeltTearingParam");
|
|
xml.writeAttribute("ScanXScale", QString::number(configResult.algorithmParams.beltTearingParam.scanXScale));
|
|
xml.writeAttribute("ScanYScale", QString::number(configResult.algorithmParams.beltTearingParam.scanYScale));
|
|
xml.writeAttribute("DiffernceBinTh", QString::number(configResult.algorithmParams.beltTearingParam.differnceBinTh));
|
|
xml.writeAttribute("TearingMinLen", QString::number(configResult.algorithmParams.beltTearingParam.tearingMinLen));
|
|
xml.writeAttribute("TearingMinGap", QString::number(configResult.algorithmParams.beltTearingParam.tearingMinGap));
|
|
xml.writeAttribute("SameGapTh", QString::number(configResult.algorithmParams.beltTearingParam.sameGapTh));
|
|
xml.writeAttribute("GapChkWin", QString::number(configResult.algorithmParams.beltTearingParam.gapChkWin));
|
|
xml.writeEndElement(); // BeltTearingParam
|
|
|
|
// 监控参数
|
|
xml.writeStartElement("MonitoringParam");
|
|
xml.writeAttribute("CheckInterval", QString::number(configResult.algorithmParams.monitoringParam.checkInterval));
|
|
xml.writeAttribute("AlertThreshold", QString::number(configResult.algorithmParams.monitoringParam.alertThreshold));
|
|
xml.writeEndElement(); // MonitoringParam
|
|
|
|
xml.writeEndElement(); // AlgorithmParams
|
|
|
|
// 保存调试参数
|
|
xml.writeStartElement("DebugParam");
|
|
xml.writeAttribute("enableDebug", QString::number(configResult.debugParam.enableDebug));
|
|
xml.writeAttribute("saveDebugImage", QString::number(configResult.debugParam.saveDebugImage));
|
|
xml.writeAttribute("printDetailLog", QString::number(configResult.debugParam.printDetailLog));
|
|
xml.writeAttribute("debugOutputPath", QString::fromStdString(configResult.debugParam.debugOutputPath));
|
|
xml.writeEndElement(); // DebugParam
|
|
|
|
// 保存项目类型
|
|
xml.writeStartElement("ProjectType");
|
|
QString typeStr = (configResult.projectType == BeltTearingProjectType::BeltMonitoring) ? "BeltMonitoring" : "BeltTearing";
|
|
xml.writeAttribute("type", typeStr);
|
|
xml.writeEndElement(); // ProjectType
|
|
|
|
// 保存服务端配置
|
|
xml.writeStartElement("LocalServerConfig");
|
|
xml.writeStartElement("ServerPort");
|
|
xml.writeAttribute("port", QString::number(configResult.serverPort));
|
|
xml.writeEndElement(); // ServerPort
|
|
xml.writeEndElement(); // LocalServerConfig
|
|
|
|
xml.writeEndElement(); // BeltTearingConfig
|
|
xml.writeEndDocument();
|
|
|
|
file.close();
|
|
|
|
return true;
|
|
}
|
|
|
|
void VrBeltTearingConfig::SetConfigChangeNotify(IVrBeltTearingConfigChangeNotify* notify)
|
|
{
|
|
m_notify = notify;
|
|
}
|