#include "TransTrainEngine.h" #include "myutils.h" #include #include using namespace ai_matrix; namespace { //按照x坐标排列 bool CompareX(const SingleData &v1, const SingleData &v2) { return (v1.fLTX < v2.fLTX); } //自定义比较规则 bool CmpVec(const pair &P1, const pair &P2) { return P1.second < P2.second; } } TransTrainEngine::TransTrainEngine() {} TransTrainEngine::~TransTrainEngine() {} APP_ERROR TransTrainEngine::Init() { bUseEngine_ = MyUtils::getins()->ChkIsHaveTarget("NUM"); if (!bUseEngine_) { LogWarn << "engineId_:" << engineId_ << " not use engine"; return APP_ERR_OK; } strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; modelConfig_ = MyYaml::GetIns()->GetModelConfig("TrainStepTwoEngine"); strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path"); //读取模型参数信息文件 Json::Value jvModelInfo; if (!MyUtils::getins()->ReadJsonInfo(jvModelInfo, modelConfig_.strModelInfoPath)) { LogError << "ModelInfoPath:" << modelConfig_.strModelInfoPath << " doesn't exist or read failed!"; return APP_ERR_COMM_NO_EXIST; } for (int i = 0; i < jvModelInfo["class"].size(); i++) { vecClassNames_.push_back(jvModelInfo["class"][i].asString()); } // 获取几个摄像头识别车号 std::map mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig(); for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++) { iSkipInterval_ = iter->second.iSkipInterval; if (iter->second.strTarget.find("NUM") != std::string::npos) { LogDebug << "sourceid:" << iter->first << " deal Num"; mapDataSourceIsEnd_[iter->first] = false; } } InitParam(); LogInfo << "TransTrainEngine Init ok"; return APP_ERR_OK; } APP_ERROR TransTrainEngine::DeInit() { if (!bUseEngine_) { LogWarn << "engineId_:" << engineId_ << " not use engine"; return APP_ERR_OK; } LogInfo << "TransTrainEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void TransTrainEngine::InitParam() { for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++) { iter->second = false; } mapNumInfo_.clear(); mapPreFrameId_.clear(); } /** * 校验车型是否符合验证 * inParam : int classId 大框类别id * : const std::string &trainNum 车型字符信息 * outParam: N/A * return : true:符合; false:不符合 */ bool TransTrainEngine::AuthTransNum(int classId, const std::string &trainNum) { // LogInfo << "classId:" << classId << " trainNum:" << trainNum; switch (classId) { case TRAIN_HEAD: // 车头上的编号 break; case K_TRAIN_NUM: // 编号 矿车、煤炭漏斗车(兖矿自备、枣矿自备) { if (trainNum == "K13" || trainNum == "KM100AH") { return true; } std::regex reg; switch (trainNum.size()) { case 4: reg = "^K[1FMZ]{1}[36789]{1}[018ABKNT]{1}"; break; case 5: reg = "^K[1M]{1}[368]{1}[1ABDN]{1}[AGKNT]{1}"; break; case 6: reg = "^K[MF]{1}[69]{1}[80]{1}A[KH]{1}"; break; default: LogWarn << "Unknow train,classId:" << classId << " trainNum:" << trainNum; return false; } return std::regex_match(trainNum, reg); } case C_TRAIN_NUM: // 敞车 特殊车型 C5D CF CFK { if (trainNum == "CF" || trainNum == "C62A(N)") { return true; } std::regex reg; switch (trainNum.size()) { case 3: reg = "^C[15678F]{1}[0123456DK]{1}"; break; case 4: reg = "^C[1678]{1}[012346]{1}[0ABCEFHKMTY]{1}"; break; case 5: reg = "^C[1678]{1}[01246]{1}[0ABCEY]{1}[KAFHNT]{1}"; break; case 6: reg = "^C[17]{1}0[0E]{1}[A-]{1}[AH]{1}"; break; default: LogWarn << "Unknow train,classId:" << classId << " trainNum:" << trainNum; return false; } return std::regex_match(trainNum, reg); } case P_TRAIN_NUM: // 编号 棚车 { if (trainNum == "P70(H)" || trainNum == "P62(N)") { return true; } std::regex reg; switch (trainNum.size()) { case 3: reg = "^P[1678]{1}[012345]{1}"; break; case 4: reg = "^P[678]{1}[023456]{1}[ABHKNST]{1}"; break; case 5: reg = "^P6[24]{1}[ANG]{1}[KT]{1}"; break; default: LogWarn << "Unknow train,classId:" << classId << " trainNum:" << trainNum; return false; } return std::regex_match(trainNum, reg); } case G_TRAIN_NUM: // 编号 罐车 { if (trainNum == "GY100SK") { return true; } std::regex reg; switch (trainNum.size()) { case 2: reg = "^G[HLS]{1}"; break; case 3: reg = "^[GL]{1}[1567HL]{1}[01246789K]{1}"; break; case 4: reg = "^[GU]{1}[167FJLNQSWY]{1}[170689]{1}[KSABDGTM075W]{1}"; break; case 5: reg = "^[GU]{1}[17FHNQY6]{1}[1706A89]{1}[SBDAM057W]{1}[KEHTB0ZAS]{1}"; break; case 6: reg = "^[UG]{1}[6YH]{1}[1489A]{1}[057W]{1}[Z0LSA]{1}[KSAT]{1}"; break; default: LogWarn << "Unknow train,classId:" << classId << " trainNum:" << trainNum; return false; } return std::regex_match(trainNum, reg); } case NX_TRAIN_NUM: // 编号 平车 { if (trainNum == "N6") { return true; } std::regex reg; switch (trainNum.size()) { case 3: reg = "^[NQX]{1}[1234678T]{1}[0124567HK]{1}"; break; case 4: reg = "^[BNX]{1}[16X]{1}[17BC]{1}[07AGKT]{1}"; break; case 5: reg = "^[NX]{1}[16NX]{1}[17C]{1}[07AGT]{1}[KTABH]{1}"; break; case 6: reg = "^NX17[AB]{1}[KTH]{1}"; break; default: LogWarn << "Unknow train,classId:" << classId << " trainNum:" << trainNum; return false; } return std::regex_match(trainNum, reg); } case J_TRAIN_NUM: // 编号 牲畜车 特种车 { if (trainNum == "TP64GK") { return true; } std::regex reg; switch (trainNum.size()) { case 2: reg = "^[DT]{1}[2678]{1}"; break; case 3: reg = "^[DST]{1}[12346789LQ]{1}[012578ADFGP]{1}"; break; case 4: reg = "^[DJNT]{1}[12356AFKQS]{1}[012345678DFQS]{1}[A12345679GHKQ]{1}"; break; case 5: reg = "^[DJQT]{1}[2KNSH1P]{1}[613XQ2]{1}[A761234B]{1}[KA70G]{1}"; break; default: LogWarn << "Unknow train, classId: " << classId << " trainNum:" << trainNum; return false; } return std::regex_match(trainNum, reg); } default: LogWarn << "Unknow train,classId:" << classId << " trainNum:" << trainNum; return false; } return true; } /** * 过滤第二步字段代号的误识别 * inParam : std::vector &vecObjs * : TargetMaxLen iMaxLen * outParam: N/A * return : N/A */ void TransTrainEngine::FilterSingleData(std::vector &vecObjs, TargetMaxLen iMaxLen) { /*误识别场景 例: 车厢容积属性只有2位时,但因误识别导致自重的某个字符字段代号错误,划归到容积中,这样实际只有2位的容积变为3位。导致选优时错误。 只处理1个字段代号的误识别,若有多个字段代号同时错误,无法区分哪些字符字段代号是正确的。(字段代号误识别较多时,则增强模型训练) 排除一个最大和最小值后计算平局坐标值,每个框左上角和平局值左上角高度差大于平局值的高度则剔除. */ if (vecObjs.size() != iMaxLen || vecObjs.size() <= 2) { return; } std::deque dqObjs(vecObjs.begin(), vecObjs.end()); std::sort(dqObjs.begin(), dqObjs.end(), [](SingleData &a, SingleData &b) { return a.fLTY < b.fLTY; }); dqObjs.pop_front(); dqObjs.pop_back(); SingleData singleDataAvg; for (auto iter = dqObjs.begin(); iter != dqObjs.end(); iter++) { singleDataAvg.fLTX += iter->fLTX; singleDataAvg.fLTY += iter->fLTY; singleDataAvg.fRBX += iter->fRBX; singleDataAvg.fRBY += iter->fRBY; } singleDataAvg.fLTX = singleDataAvg.fLTX / dqObjs.size(); singleDataAvg.fLTY = singleDataAvg.fLTY / dqObjs.size(); singleDataAvg.fRBX = singleDataAvg.fRBX / dqObjs.size(); singleDataAvg.fRBY = singleDataAvg.fRBY / dqObjs.size(); float fAvgHeight = singleDataAvg.fRBY - singleDataAvg.fLTY; //剔除位置错误的字符信息 for (auto iter = vecObjs.begin(); iter != vecObjs.end(); iter++) { float fTemp = fabs(iter->fLTY - singleDataAvg.fLTY); if (fTemp > (fAvgHeight - 5)) { std::string strOne = vecClassNames_.at(iter->iClassId); LogWarn << "engineId:" << engineId_ << " " << strOne << " Line wrong "; vecObjs.erase(iter); break; } } } /** * 属性框内容转换 * inParam : std::map> &mapLine * outParam: TransSubData &transSubData * return : N/A */ void TransTrainEngine::TransPro(TransSubData &transSubData, std::map> &mapLine) { //载重 if (mapLine.find(0) != mapLine.end()) { TransInfo loadInfo; loadInfo.iLine = 0; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(0).size(); j++) { //过滤非数字 std::string strOne = vecClassNames_.at(mapLine.at(0).at(j).iClassId); if (strOne[0] < '0' || strOne[0] > '9') { LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in load"; continue; } strTemp += strOne; loadInfo.vecValue.emplace_back(strOne); loadInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore); transSubData.fScoreSum += mapLine.at(0).at(j).fScore; } //匹配正则表达式 //std::regex reg("^[0-9]{2}"); std::regex reg("^[1,4,5,6,7,8,9]{1}[0-9]{1,2}$"); //(第1位:棚车:4 5; K自备车:1 5 7 8 9; 平车:7; 罐车:6 7; 敞车:6 7 8) if (std::regex_match(strTemp, reg)) { loadInfo.IsChkFlag = true; } transSubData.vecTransInfo.emplace_back(loadInfo); } //自重 if (mapLine.find(1) != mapLine.end()) { FilterSingleData(mapLine.at(1), SELF_MAXLEN); TransInfo selfInfo; selfInfo.iLine = 1; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(1).size(); j++) { //过滤非数字 std::string strOne = vecClassNames_.at(mapLine.at(1).at(j).iClassId); if (strOne[0] < '0' || strOne[0] > '9') { LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in self"; continue; } strTemp += strOne; selfInfo.vecValue.emplace_back(strOne); selfInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore); transSubData.fScoreSum += mapLine.at(1).at(j).fScore; } //匹配正则表达式 std::regex reg("^[1,2,3]{1}[0-9]{1,2}$"); if (std::regex_match(strTemp, reg)) { selfInfo.IsChkFlag = true; } transSubData.vecTransInfo.emplace_back(selfInfo); } //容积 if (mapLine.find(2) != mapLine.end()) { FilterSingleData(mapLine.at(2), VOLUME_MAXLEN); TransInfo volumeInfo; volumeInfo.iLine = 2; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(2).size(); j++) { //过滤非数字 std::string strOne = vecClassNames_.at(mapLine.at(2).at(j).iClassId); if (strOne[0] < '0' || strOne[0] > '9') { LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in volume"; continue; } strTemp += strOne; volumeInfo.vecValue.emplace_back(strOne); volumeInfo.vecScore.emplace_back(mapLine.at(2).at(j).fScore); transSubData.fScoreSum += mapLine.at(2).at(j).fScore; } //匹配正则表达式 //std::regex reg("^[0-9]{2,3}$"); std::regex reg("^[1,6,7,8,9]{1}[0-9]{1,2}$"); //(第1位:棚车:1; K自备车:1或9; 罐车:6或7; 敞车:7或8) if (std::regex_match(strTemp, reg)) { volumeInfo.IsChkFlag = true; } transSubData.vecTransInfo.emplace_back(volumeInfo); } //换长 if (mapLine.find(3) != mapLine.end()) { TransInfo changeInfo; changeInfo.iLine = 3; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(3).size(); j++) { //过滤非数字 std::string strOne = vecClassNames_.at(mapLine.at(3).at(j).iClassId); if (strOne[0] < '0' || strOne[0] > '9') { LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in change"; continue; } strTemp += strOne; changeInfo.vecValue.emplace_back(strOne); changeInfo.vecScore.emplace_back(mapLine.at(3).at(j).fScore); transSubData.fScoreSum += mapLine.at(3).at(j).fScore; } //匹配正则表达式 //std::regex reg("^[0-9]{2}$"); std::regex reg("^[1]{1}[0-9]{1}$"); if (std::regex_match(strTemp, reg)) { changeInfo.IsChkFlag = true; } transSubData.vecTransInfo.emplace_back(changeInfo); } //罐车容量计表 if (mapLine.find(4) != mapLine.end()) { TransInfo volumeSurfaceInfo; volumeSurfaceInfo.iLine = 4; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(4).size(); j++) { strTemp += vecClassNames_.at(mapLine.at(4).at(j).iClassId); volumeSurfaceInfo.vecValue.emplace_back(vecClassNames_.at(mapLine.at(4).at(j).iClassId)); volumeSurfaceInfo.vecScore.emplace_back(mapLine.at(4).at(j).fScore); transSubData.fScoreSum += mapLine.at(4).at(j).fScore; } volumeSurfaceInfo.IsChkFlag = true; //暂不校验 transSubData.vecTransInfo.emplace_back(volumeSurfaceInfo); } } /** * 车号框内容转换 * inParam : std::map> &mapLine * outParam: TransSubData &transSubData * return : N/A */ void TransTrainEngine::TransNum(TransSubData &transSubData, std::map> &mapLine) { //车型 if (mapLine.find(0) != mapLine.end()) { TransInfo typeInfo; typeInfo.iLine = 0; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(0).size(); j++) { std::string strOne = vecClassNames_.at(mapLine.at(0).at(j).iClassId); /*20230117 该逻辑删除,有厂区发现有C70C DF4DD等车型。 针对重复印刷的场景需想其他方法处理。 //注:车型多次印刷会导致之前印刷的个别字符会识别,导致最终的识别内容变多。针对车型没有重复字符的特点,因此剔除重复的字符 auto iter = find(typeInfo.vecValue.begin(), typeInfo.vecValue.end(), strOne); if (iter != typeInfo.vecValue.end()) { LogWarn << "Possible duplicate recognition strOne:" << strOne; continue; } */ strTemp += strOne; typeInfo.vecValue.emplace_back(strOne); typeInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore); transSubData.fScoreSum += mapLine.at(0).at(j).fScore; } //校验车型是否符合验证 typeInfo.IsChkFlag = AuthTransNum(transSubData.iBigClassId, strTemp); transSubData.vecTransInfo.emplace_back(typeInfo); } //编号 if (mapLine.find(1) != mapLine.end()) { TransInfo numInfo; numInfo.iLine = 1; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(1).size(); j++) { std::string strOne = vecClassNames_.at(mapLine.at(1).at(j).iClassId); //过滤非数字 if (strOne[0] < '0' || strOne[0] > '9') { LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in num"; continue; } strTemp += strOne; numInfo.vecValue.emplace_back(strOne); numInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore); transSubData.fScoreSum += mapLine.at(1).at(j).fScore; } //匹配正则表达式 std::regex reg("^[0-9]{7}$"); //车厢编号,固定7位 if (std::regex_match(strTemp, reg)) { numInfo.IsChkFlag = true; } transSubData.vecTransInfo.emplace_back(numInfo); } } /** * 车头框内容转换 * inParam : std::map> &mapLine * outParam: TransSubData &transSubData * return : N/A */ void TransTrainEngine::TransHead(TransSubData &transSubData, std::map> &mapLine) { //车头型号 if (mapLine.find(0) != mapLine.end()) { TransInfo typeInfo; typeInfo.iLine = 0; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(0).size(); j++) { strTemp += vecClassNames_.at(mapLine.at(0).at(j).iClassId); typeInfo.vecValue.emplace_back(vecClassNames_.at(mapLine.at(0).at(j).iClassId)); typeInfo.vecScore.emplace_back(mapLine.at(0).at(j).fScore); transSubData.fScoreSum += mapLine.at(0).at(j).fScore; } //不做结果校验,IsChkFlag默认为true typeInfo.IsChkFlag = true; transSubData.vecTransInfo.emplace_back(typeInfo); } //车头编号 if (mapLine.find(1) != mapLine.end()) { TransInfo numInfo; numInfo.iLine = 1; std::string strTemp = ""; for (auto j = 0; j < mapLine.at(1).size(); j++) { std::string strOne = vecClassNames_.at(mapLine.at(1).at(j).iClassId); //过滤非数字 if (strOne[0] < '0' || strOne[0] > '9') { LogWarn << "engineId:" << engineId_ << " " << strOne << " not digit in headnum"; continue; } strTemp += strOne; numInfo.vecValue.emplace_back(strOne); numInfo.vecScore.emplace_back(mapLine.at(1).at(j).fScore); transSubData.fScoreSum += mapLine.at(1).at(j).fScore; } //不做结果校验,IsChkFlag默认为true numInfo.IsChkFlag = true; transSubData.vecTransInfo.emplace_back(numInfo); } } /** * 记录在画面中间位置识别的车号 * inParam : const TransSubData &transSubData 车号信息 : const std::shared_ptr &pProcessData 帧数据 * outParam: N/A * return : N/A */ void TransTrainEngine::RecordNum(const TransSubData &transSubData, const std::shared_ptr &pProcessData) { int iCenterX = transSubData.step1Location.fLTX + (transSubData.step1Location.fRBX - transSubData.step1Location.fLTX) / 2; int iImgL = pProcessData->iWidth / 3; int iImgR = pProcessData->iWidth / 3 * 2; if (iCenterX <= iImgL || iCenterX >= iImgR) { return; } std::string strValue; for (size_t i = 0; i < transSubData.vecTransInfo.size(); i++) { TransInfo transInfo = transSubData.vecTransInfo[i]; if (transInfo.iLine != 1) { continue; } for (size_t j = 0; j < transInfo.vecValue.size(); j++) { strValue += transInfo.vecValue[j]; } } bool bIntervalFlag = ((int)(pProcessData->iFrameId - mapPreFrameId_[pProcessData->iDataSource]) > iSkipInterval_ * 2); if (mapNumInfo_[pProcessData->iDataSource].find(strValue) == mapNumInfo_[pProcessData->iDataSource].end()) { LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " NUM:" << strValue << " bIntervalFlag:" << bIntervalFlag; if (bIntervalFlag) { mapNumInfo_[pProcessData->iDataSource][strValue] = pProcessData->iFrameId; } } LogDebug << "sourceid:" << pProcessData->iDataSource << " preframeid:" << mapPreFrameId_[pProcessData->iDataSource] << " frameid:" << pProcessData->iFrameId << " mapsize:" << mapNumInfo_[pProcessData->iDataSource].size(); mapPreFrameId_[pProcessData->iDataSource] = pProcessData->iFrameId; } /** * 保存中间位置识别车号信息到csv中 * inParam : std::shared_ptr pTrain :列车信息 * outParam: * return : true/false */ bool TransTrainEngine::SaveMiddleNumCsv(const std::vector> &vecNums, const std::shared_ptr &pProcessData, int iSourceId) { //1. 创建保存路径 (固定路径/YYYY-MM-DD/hh-mm-ss/) std::string strTrainPath = strResultPath_ + pProcessData->strTrainDate + "/" + pProcessData->strTrainName + "/"; if (!MyUtils::getins()->CreateDirPath(strTrainPath)) { LogError << "fail CreateDirPath:" << strTrainPath; return false; } //2. 保存csv std::string strCsvName = pProcessData->strTrainDate + pProcessData->strTrainName + "_" + std::to_string(iSourceId) + ".csv"; strCsvName = MyUtils::getins()->replace_all_distinct(strCsvName, std::string("-"), std::string("")); strTrainPath += strCsvName; try { // 写文件 std::ofstream outFile; outFile.open(strTrainPath, std::ios::app); outFile << "num" << ',' << "frameid" << std::endl; for (auto iterVec = vecNums.begin(); iterVec != vecNums.end(); iterVec++) { outFile << iterVec->first << "," << iterVec->second << std::endl; } outFile.close(); } catch (const std::exception &) { LogError << "fail open dirPath:" << strTrainPath; return false; } return true; } /** * push数据到队列,队列满时则休眠一段时间再push * inParam : const std::string strPort push的端口 : const std::shared_ptr &pProcessData push的数据 * outParam: N/A * return : N/A */ void TransTrainEngine::PushData(const std::string &strPort, const std::shared_ptr &pProcessData) { while (true) { int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast(pProcessData)); if (iRet != 0) { LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " push fail iRet:" << iRet; if (iRet == 2) { usleep(10000); // 10ms continue; } } break; } } APP_ERROR TransTrainEngine::Process() { if (!bUseEngine_) { LogWarn << "engineId_:" << engineId_ << " not use engine"; return APP_ERR_OK; } int iRet = APP_ERR_OK; while (!isStop_) { std::shared_ptr pVoidData0 = nullptr; inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); //1ms continue; } std::shared_ptr pProcessData = std::static_pointer_cast(pVoidData0); //第2步后处理结果 std::shared_ptr pPostData = std::static_pointer_cast(pProcessData->pVoidData); //最后一节的最后一帧为整列车的结束 if (pProcessData->bIsTrainEnd && pProcessData->bIsEnd) { mapDataSourceIsEnd_[pProcessData->iDataSource] = true; } //组织输出数据 std::shared_ptr pTransData = std::make_shared(); for (size_t i = 0; i < pPostData->vecPostSubData.size(); i++) { PostSubData postSubData = pPostData->vecPostSubData[i]; //按字段代号分类 std::map> mapLine; for (size_t j = 0; j < postSubData.vecSingleData.size(); j++) { mapLine[postSubData.vecSingleData.at(j).iLine].push_back(postSubData.vecSingleData.at(j)); } //每一行按x坐标排序 for (auto it = mapLine.begin(); it != mapLine.end(); it++) { std::sort(it->second.begin(), it->second.end(), CompareX); std::string strTemp = ""; for (auto j = 0; j < it->second.size(); j++) { strTemp += vecClassNames_.at(it->second.at(j).iClassId); } // LogDebug << "step2 char sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId // << " bigclassId:" << postSubData.iBigClassId << " line:" << it->first << "," << strTemp; } TransSubData transSubData; transSubData.iBigClassId = postSubData.iBigClassId; transSubData.iCarXH = postSubData.iCarXH; transSubData.step1Location = postSubData.step1Location; //按大类处理 if(postSubData.iBigClassId == 1) { TransPro(transSubData, mapLine); } else if (postSubData.iBigClassId >= 2 && postSubData.iBigClassId <= 6) { TransNum(transSubData, mapLine); RecordNum(transSubData, pProcessData); } else if(postSubData.iBigClassId == 0) { TransHead(transSubData, mapLine); RecordNum(transSubData, pProcessData); } else { continue; } pTransData->vecTransSubData.emplace_back(transSubData); } //是否全部结束 bool bAllEnd = true; for (auto iter = mapDataSourceIsEnd_.begin(); iter != mapDataSourceIsEnd_.end(); iter++) { bAllEnd = bAllEnd && iter->second; } pProcessData->pVoidData = std::static_pointer_cast(pTransData); // push端口0,车号属性选优处理 PushData(strPort0_, pProcessData); if (bAllEnd) { for(auto iter = mapNumInfo_.begin(); iter != mapNumInfo_.end(); iter++) { std::vector> vecTemp(iter->second.begin(), iter->second.end()); sort(vecTemp.begin(), vecTemp.end(), CmpVec); //按帧号排序 SaveMiddleNumCsv(vecTemp, pProcessData, iter->first); // for(auto iterVec = vecTemp.begin(); iterVec != vecTemp.end(); iterVec++) // { // LogDebug << "sourceid:" << iter->first << " num:" << iterVec->first << " frameid:" << iterVec->second; // } } //转个json数组发送后面用于比较。(车厢个数和该json数据是否相等,相等则不处理。不相等则挨个比较下。) //初始化参数变量 InitParam(); } } return APP_ERR_OK; }