解析十六进制雷达数据格式:解析雷达FSPEC数据

以Cat62格式雷达数据为例,十六进制雷达数据部分代码:

3e0120bf7da4ffee0085

base_fspec_processor.h

//
// Created by qiaowei on 2024-02-03.
//

#ifndef RADARDATACONTROLLER_BASE_FSPEC_PROCESSOR_H
#define RADARDATACONTROLLER_BASE_FSPEC_PROCESSOR_H


#include 
#include 


namespace processor {

    class BaseFspecProcessor {

    public:
        virtual QVector* processor(const QString& content,
                                        int begin_position_index,
                                        int& end_position_index) = 0;
    };

} // processor

#endif //RADARDATACONTROLLER_BASE_FSPEC_PROCESSOR_H

cat62_fspec_processor.h

//
// Created by qiaowei on 2024-01-25.
//


#ifndef RADARDATACONTROLLER_CAT62_FSPEC_PROCESSOR_H
#define RADARDATACONTROLLER_CAT62_FSPEC_PROCESSOR_H


#include 
#include 
#include 

#include "../baseprocess/base_fspec_processor.h"


namespace processor {

    /**
     * @copyright 2003-2024
     * @date      2024-02-09 22:40
     * @author    qiao wei
     * @version   1.0
     * @brief     处理十六进制雷达数据的FSPEC数据。
     * @history
     */
    class Cat62FspecProcessor : public QObject, public BaseFspecProcessor {

        Q_OBJECT

    public:
        explicit Cat62FspecProcessor(QObject* parent = nullptr);

        virtual ~Cat62FspecProcessor() override;

        /**
         * @author  qiao wei
         * @brief   从雷达数据hex_track_data中读取FSPEC数据。将FSPEC数据按照二进制格式保存到QVector指针并返回。
         * @param   hex_track_data 十六进制雷达数据。
         * @param   begin_position FSPEC数据的起始索引。
         * @param   readed_data_end_position FSPEC数据的末位索引。
         * @return  QVector指针。二进制格式保存的FSPEC数据。
         * @history
         */
        virtual QVector* processor(const QString& hex_track_data,
                                        int begin_position,
                                        int& readed_data_end_position) override;

    private:
        /**
         * @author  qiao wei
         * @brief   将存储FSPEC内容由十六进制的字符串转换为二进制的QVector*。
         * @param   fspec_content FSPEC内容字符串。
         * @param   count FSPEC内容的字节数。因为参数content是2个字符组成1个字节,所以count数为字符串中字符数量的一半。
         * @return  FSPEC内容转换为二进制的QVector*。
         * @history
         */
        QVector* convertFspecToIntArray(QString fspec_content);

        /**
         * @author  qiao wei
         * @brief   将int数据value以二进制数的格式保存到容器vector的指定位置处。
         *          传入的value是1个字节,将其转换为8位二进制数从左向右保存,因为每次只能保存1个字节的数据,保存多个
         *          字节的数据需要依次保存到容器vector中。
         * @param   vector 存储二进制数的容器。
         * @param   value FSPES数据中的1个字节。
         * @param   begin_position 将字节value转换成二进制数保存到容器vector的第一位索引。
         * @return
         * @history
         */
        virtual void replaceBinaryValueToContainer(QVector* vector, int value, int begin_position);

        /**
         * @author  qiao wei
         * @brief   分步骤读取十六进制雷达数据track_data中的FSPEC数据,返回起始索引begin_position的1个字节FSPEC数据。
         * @param   track_data 十六进制雷达数据。
         * @param   begin_position 读取FSPEC数据的首位索引。
         * @param   readed_data_end_position 读取FSPEC数据的末位索引,该参数为引用类型。
         * @return  返回读取的1个字节FSPEC数据,如果数据读取异常则返回""。
         * @history
         */
        QString readAByteFspec(const QString& track_data,
                               int begin_position,
                               int& readed_data_end_position);

        /**
         * @author  qiao wei
         * @brief   将完整的FSPEC数据从雷达数据中读取出。
         * @param   track_data 十六进制雷达数据。
         * @param   begin_position_index FSPEC在track_data中的起始索引。
         * @return  FSPEC数据。
         * @history
         */
        QString readFspecContent(const QString& track_data,
                                 int begin_position_index);

        /**
         * @author  qiao wei
         * @brief   判断1个字节的数据是否是FSPEC数据的最后1个字节。
         * @param   a_byte_fspec_content 1个字节的FSPEC数据。
         * @return  true 已到FSPEC数据末位。
         * @history
         */
        bool isTheLastValueOfFspec(QString a_byte_fspec_content);

    private:
        /**
         * @author qiao wei
         * @brief  标识位,通过与运算判断字节最后一位是否为0。0b0000,0001。
         */
        const static int THE_0_POSITION_VALUE;

        /**
         * @author qiao wei
         * @brief  0b1000,0000。
         */
        const static int THE_7_POSITION_VALUE;
    };

} // processor

#endif //RADARDATACONTROLLER_CAT62_FSPEC_PROCESSOR_H

base_fspec_processor.cpp

//
// Created by qiaowei on 2024-01-25.
//


#include 

#include "cat62_fspec_processor.h"


namespace processor {

    const int Cat62FspecProcessor::THE_0_POSITION_VALUE{1};

    const int Cat62FspecProcessor::THE_7_POSITION_VALUE{128};

    Cat62FspecProcessor::Cat62FspecProcessor(QObject* parent) : QObject(parent) {}

    Cat62FspecProcessor::~Cat62FspecProcessor() {}

    QVector* Cat62FspecProcessor::processor(const QString& hex_track_data,
                                                 int begin_position,
                                                 int& readed_data_end_position) {
        /**
         * 1:从hex_track_data数据中读取完整的FSPEC数据。
         * 1.1:从begin_position索引开始,依次读取2个字符(1个字节)。
         * 1.2:判断读取的2个字符是否是FSPEC数据结尾。
         * 1.3:将读取的2个字符依次添加到同一个字符串中,如果到了FSPEC数据结尾,则不再读取数据。
         * 2:将FSPEC数据转换成int类型,保存到QVector*容器。
         * 3:返回QVect*容器。
         */

        readed_data_end_position = begin_position;

        // 保存hex_track_data数据中指定位置的FSPEC数据。
        QString fspec_content = readFspecContent(hex_track_data, begin_position);

        readed_data_end_position = readed_data_end_position + fspec_content.length() - 1;
        QVector* fspec_vector = convertFspecToIntArray(fspec_content);

        return fspec_vector;
    }

    QVector* Cat62FspecProcessor::convertFspecToIntArray(QString fspec_content) {
        /**
         * 雷达数据中,2个字符表示1个字节。
         * 根据字节数设置对应的QVector*容量。1个字节是8位二进制数。
         */
        // 获取FSPEC数据中字节个数。
        int byte_count{fspec_content.length() / 2};
        QVector* vector{new QVector(byte_count * 8)};

        const int step{2};
        int begin_position_index{0};
        int value{0};

        for (int index{0}; index != byte_count; ++index) {
            value = fspec_content.mid(begin_position_index, step).toInt(nullptr, 16);

            replaceBinaryValueToContainer(vector, value, index * 8);
            begin_position_index += step;
        }

        return vector;
    }

    void Cat62FspecProcessor::replaceBinaryValueToContainer(QVector* vector,
                                                            int value,
                                                            int begin_position) {
        // 遍历1个字节所有位的次数。
        const int count{8};

        /**
         * 1:依次遍历value值的每一位(8位二进制,从左侧高位开始依次遍历),并将二级制值保存到容器vector。
         * 2:右移1位。依次读取value中每一位二进制值。
         */
        for (int index{0}; index != 8; ++index) {
            vector->replace(begin_position + index,
                            ((THE_7_POSITION_VALUE == (value & THE_7_POSITION_VALUE)) ? 1 : 0));
            value = value<<1;
        }
    }

    QString Cat62FspecProcessor::readAByteFspec(const QString& track_data,
                                                int begin_position,
                                                int& readed_data_end_position) {
        readed_data_end_position = begin_position;
        QString content{track_data.mid(begin_position, 2)};

        // 当前数据的末位索引。“+2”是当前数据末位下一位的索引,所以要减1。保证数据与参数名一致。
        readed_data_end_position = begin_position + 2 - 1;

        /**
         * 判断读取的1个字节(2个字符)的FSPEC数据是否为空,是否读取到的是1个字节。如果以上条件满足,返回
         * 字符串content,反之返回""。
         */
        if (!content.isNull() && 2 == content.length()) {
            return content;
        } else {
            return "";
        }
    }

    QString Cat62FspecProcessor::readFspecContent(const QString& track_data,
                                                  int begin_position_index) {
        int end_position_index{begin_position_index};
        QString fspec_content;
        QString a_byte_fspec_content;

        /**
         * 从雷达数据track_data中依次读取1个字节FSPEC数据,将数据保存到字符串fspec_content。
         * 判断是否是FSPEC最后一个字节,如果不是继续读取FSPEC数据,反之退出循环。
         */
        while (true) {
            a_byte_fspec_content =
                readAByteFspec(track_data,
                               begin_position_index,
                               end_position_index);

            begin_position_index = end_position_index + 1;
            fspec_content.append(a_byte_fspec_content);

            if (isTheLastValueOfFspec(a_byte_fspec_content)) {
                break;
            }
        }

        return fspec_content;
    }

    bool Cat62FspecProcessor::isTheLastValueOfFspec(QString a_byte_fspec_content) {
        int value{a_byte_fspec_content.toInt(nullptr, 16)};

        return ((THE_0_POSITION_VALUE & value) == THE_0_POSITION_VALUE) ? false : true;
    }

} // processor

main.cpp

#include 

#include 
#include 
#include 
#include 

#include "./form/main_window.h"
#include "./cat62process/cat62_fspec_processor.h"
#include "./cat62process/cat_62_length_processor.h"
#include "./cat62process/cat_62_header_processor.h"


using std::string;

using form::MainWindow;
using processor::Cat62FspecProcessor;
using processor::Cat62HeaderProcessor;
using processor::Cat62LengthProcessor;


int main(int argc,
         char *argv[]) {
    QApplication a(argc, argv);

//    MainWindow* main_window{new MainWindow{nullptr}};
//    main_window->show();

    QString content = "3e0120bf7da4ffee00859880007205a0";

    int begin_position{0};
    int end_position = begin_position;
    Cat62HeaderProcessor* header_processor{new Cat62HeaderProcessor{}};
    qDebug()<< header_processor->processor(content, begin_position, end_position);
    qDebug()<< "Header end position: " << end_position;

    begin_position = end_position + 1;
    Cat62LengthProcessor* lenght_processor{new Cat62LengthProcessor{}};
    qDebug()<< lenght_processor->processor(content, begin_position, end_position);
    qDebug()<< "Length end position: " << end_position;

    begin_position = end_position + 1;
    Cat62FspecProcessor* fspec_processor{new Cat62FspecProcessor{}};
    QVector* vector = fspec_processor->processor(content, begin_position, end_position);

    for (int index = 0; index < vector->capacity(); ++index) {
        qDebug()<< index << ": " << vector->at(index) << ", ";
    }

    qDebug()<< "FSPEC end position: " << end_position;

    return QApplication::exec();
}

运行结果:

解析十六进制雷达数据格式:解析雷达FSPEC数据_第1张图片

你可能感兴趣的:(C&C++,Qt&Pyside,qt,开发语言,c++)