#include "stdafx.h"
#include "EchoDataFormat.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QString>
#include <QFile>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QDebug>
#include "ImageOperatorBase.h"


std::shared_ptr<PluseAntPos> CreatePluseAntPosArr(long pluseCount)
{
    return std::shared_ptr<PluseAntPos>(new PluseAntPos[pluseCount],delArrPtr);
}

long getPluseDataSize(PluseData& pluseData)
{
    long datasize = sizeof(long) + sizeof(double) + sizeof(double) * 6 + sizeof(long);// PRFId,time,px-vz,pluseCount
    datasize = datasize + pluseData.plusePoints * sizeof(double) * 2; // 数据块
    return datasize;
}

ErrorCode getPluseDataFromBuffer(char* buffer, PluseData & data)
{
    long seekid = 0;
	std::memcpy(&data.id, buffer + seekid, sizeof(data.id));    seekid += sizeof(data.id);
	std::memcpy(&data.time, buffer + seekid, sizeof(data.time)); seekid += sizeof(data.time);
	std::memcpy(&data.Px, buffer + seekid, sizeof(data.Px));    seekid += sizeof(data.Px);
	std::memcpy(&data.Py, buffer + seekid, sizeof(data.Py));    seekid += sizeof(data.Py);
	std::memcpy(&data.Pz, buffer + seekid, sizeof(data.Pz));    seekid += sizeof(data.Pz);
	std::memcpy(&data.Vx, buffer + seekid, sizeof(data.Vx));    seekid += sizeof(data.Vx);
	std::memcpy(&data.Vy, buffer + seekid, sizeof(data.Vy));    seekid += sizeof(data.Vy);
	std::memcpy(&data.Vz, buffer + seekid, sizeof(data.Vz));    seekid += sizeof(data.Vz);
	std::memcpy(&data.plusePoints, buffer + seekid, sizeof(data.plusePoints)); seekid += sizeof(data.plusePoints);

    Eigen::MatrixXd echoData_real = Eigen::MatrixXd::Zero(1, data.plusePoints);
    Eigen::MatrixXd echoData_imag = Eigen::MatrixXd::Zero(1, data.plusePoints);
    std::memcpy(echoData_real.data(), buffer + seekid, sizeof(data.plusePoints)); seekid += data.plusePoints * sizeof(double);
    std::memcpy(echoData_imag.data(), buffer + seekid, sizeof(data.plusePoints));

	std::shared_ptr<Eigen::MatrixXcd> echoData = std::make_shared<Eigen::MatrixXcd>(1, data.plusePoints);
    echoData->real() = echoData_real.array();
    echoData->imag() = echoData_imag.array();
    return ErrorCode::SUCCESS;
}

std::shared_ptr<PluseData> CreatePluseDataArr(long pluseCount)
{
    return std::shared_ptr<PluseData>(new PluseData[pluseCount],delArrPtr);
}

std::shared_ptr<std::complex<double>> CreateEchoData(long plusePoints)
{
    return std::shared_ptr<std::complex<double>>(new std::complex<double>[plusePoints],delArrPtr);
}

EchoL0Dataset::EchoL0Dataset()
{
    this->folder="";
    this->filename="";
    this->xmlname="";
    this->GPSPointFilename="";
    this->echoDataFilename="";
    this->xmlFilePath="";
    this->GPSPointFilePath="";
    this->echoDataFilePath="";
    this->simulationTaskName = "";

	this->PluseCount = 0;
	this->PlusePoints = 0;
	this->NearRange = 0;
	this->FarRange = 0;
	this->centerFreq = 0;
	this->Fs = 0;

    this->folder.clear();
    this->filename.clear();
    this->xmlname.clear();
    this->GPSPointFilename.clear();
    this->echoDataFilename.clear();
    this->xmlFilePath.clear();
    this->GPSPointFilePath.clear();
    this->echoDataFilePath.clear();
    this->simulationTaskName.clear();

}

EchoL0Dataset::~EchoL0Dataset()
{
}

ErrorCode EchoL0Dataset::OpenOrNew(QString folder, QString filename, long PluseCount, long PlusePoints)
{
    qDebug() << "--------------Echo Data OpenOrNew ---------------------------------------";
	qDebug() << "Folder: " << folder;
	qDebug() << "Filename: " << filename;
	QDir dir(folder);
    if (dir.exists() == false)
    {
        dir.mkpath(folder);
    }
    else {}

    if (dir.exists() == false) {
        return ErrorCode::FOLDER_NOT_EXIST;
    }
    else {}
    QString filePath = dir.filePath(filename); // 生成完整的文件路径
 
    this->folder = folder;
    this->filename = filename;
    this->simulationTaskName = filename;

    this->xmlname=filename+".xml";
    this->GPSPointFilename=filename+".gpspos.data";
    this->echoDataFilename = filename + ".L0echo.data";

	this->xmlFilePath = dir.filePath(this->xmlname);
	this->GPSPointFilePath = dir.filePath(this->GPSPointFilename);
	this->echoDataFilePath = dir.filePath(this->echoDataFilename);

    this->PluseCount = PluseCount;
    this->PlusePoints = PlusePoints;


    // 
	if (QFile(this->xmlFilePath).exists())
    {
		this->loadFromXml();
	}
    else
    {
		this->saveToXml();
	}

    if (QFile(this->GPSPointFilePath).exists() == false) {
        // 创建新文件
        omp_lock_t lock;
        omp_init_lock(&lock);
        omp_set_lock(&lock);
        GDALAllRegister();
        CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
 
        GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI");
        GDALDataset* poDstDS=(poDriver->Create(this->GPSPointFilePath.toUtf8().constData(), 19, PluseCount, 1, GDT_Float64, NULL));
        GDALFlushCache((GDALDatasetH)poDstDS);
        GDALClose(poDstDS);
        //poDstDS.reset();
        omp_unset_lock(&lock);	 //  
        omp_destroy_lock(&lock); //  
 
    }

    if (QFile(this->echoDataFilePath).exists() == false) {

        // 创建新文件
        omp_lock_t lock;
        omp_init_lock(&lock);
        omp_set_lock(&lock);
        GDALAllRegister();
        CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
 
        GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI");
        GDALDataset* poDstDS = (poDriver->Create(this->echoDataFilePath.toUtf8().constData(), PlusePoints, PluseCount, 1, GDT_CFloat64, NULL));
        GDALFlushCache((GDALDatasetH)poDstDS);
        GDALClose(poDstDS);
        //poDstDS.reset();
        omp_unset_lock(&lock);	 //  
        omp_destroy_lock(&lock); //  

    }

 

    return ErrorCode::SUCCESS;
}

ErrorCode EchoL0Dataset::Open(QString xmlfilepath)
{
    QFileInfo fileInfo(xmlfilepath);
    QString fileName = fileInfo.fileName(); // 获取文件名
    QString fileSuffix = fileInfo.suffix(); // 获取后缀名
    QString fileNameWithoutSuffix = fileInfo.baseName(); // 获取不带后缀的文件名
    QString directoryPath = fileInfo.path(); // 获取文件夹路径
    if (fileSuffix.toLower() == "xml" || fileSuffix.toLower() == ".xml") {
        return this->Open(directoryPath,fileNameWithoutSuffix);
    }
    else {
        return ErrorCode::ECHO_L0DATA_XMLNAMEERROR;
    }

    return ErrorCode::SUCCESS;
}

ErrorCode EchoL0Dataset::Open(QString folder, QString filename)
{
    QDir dir(folder);
    if (dir.exists() == false)
    {
        return ErrorCode::FOLDER_NOT_EXIST;
    }
    else {}

    if (dir.exists() == false) {
        return ErrorCode::FOLDER_NOT_EXIST;
    }
    else {}
    QString filePath = dir.filePath(filename); // 生成完整的文件路径

    this->folder = folder;
    this->filename = filename;
    this->simulationTaskName = filename;

    this->xmlname = filename + ".xml";
    this->GPSPointFilename = filename + ".gpspos.data";
    this->echoDataFilename = filename + ".L0echo.data";

    this->xmlFilePath = dir.filePath(this->xmlname);
    this->GPSPointFilePath = dir.filePath(this->GPSPointFilename);
    this->echoDataFilePath = dir.filePath(this->echoDataFilename);

    this->PluseCount = PluseCount;
    this->PlusePoints = PlusePoints;

    // 
    if (QFile(this->xmlFilePath).exists())
    {
        this->loadFromXml();
    }
    else
    {
		return ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR;
    }
}

QString EchoL0Dataset::getxmlName()
{
    return xmlname;
}

QString EchoL0Dataset::getGPSPointFilename()
{
    return GPSPointFilename;
}

QString EchoL0Dataset::getEchoDataFilename()
{
    return GPSPointFilePath;
}

void EchoL0Dataset::initEchoArr(std::complex<double> init0)
{
    long blockline = Memory1MB  / 8 / 2 / this->PlusePoints * 8000;
    
    long start = 0;
    for (start = 0; start < this->PluseCount; start = start + blockline) {
        long templine = start + blockline < this->PluseCount ? blockline : this->PluseCount - start;
        std::shared_ptr<std::complex<double>> echotemp = this->getEchoArr(start, templine);
        for (long i = 0; i < templine; i++) {
            for (long j = 0; j < this->PlusePoints; j++) {
                echotemp.get()[i * this->PlusePoints + j] = init0;
            }
        }
        this->saveEchoArr(echotemp, start, templine);
        qDebug() << "echo init col : " << start << "\t-\t" << start + templine << "\t/\t" << this->PluseCount;
    }
}

// Getter 和 Setter 方法实现
long EchoL0Dataset::getPluseCount()  { return this->PluseCount; }
void EchoL0Dataset::setPluseCount(long pulseCount) { this->PluseCount = pulseCount; }

long EchoL0Dataset::getPlusePoints()  { return this->PlusePoints; }
void EchoL0Dataset::setPlusePoints(long pulsePoints) {  this->PlusePoints = pulsePoints; }


double EchoL0Dataset::getNearRange()  { return this->NearRange; }
void EchoL0Dataset::setNearRange(double nearRange) { this->NearRange = nearRange; }

double EchoL0Dataset::getFarRange()  { return this->FarRange; }
void EchoL0Dataset::setFarRange(double farRange) { this->FarRange = farRange; }

double EchoL0Dataset::getCenterFreq()  { return this->centerFreq; }
void EchoL0Dataset::setCenterFreq(double freq) { this->centerFreq = freq; }

double EchoL0Dataset::getFs()  { return this->Fs; }
void EchoL0Dataset::setFs(double samplingFreq) { this->Fs = samplingFreq; }

QString EchoL0Dataset::getSimulationTaskName()  { return this->simulationTaskName; }
void EchoL0Dataset::setSimulationTaskName(const QString& taskName) { this->simulationTaskName = taskName; }

double EchoL0Dataset::getCenterAngle()
{
    return this->CenterAngle;
}

void EchoL0Dataset::setCenterAngle(double angle)
{
    this->CenterAngle = angle;
}

QString EchoL0Dataset::getLookSide()
{
    return this->LookSide;
}

void EchoL0Dataset::setLookSide(QString lookside)
{
    this->LookSide = lookside;
}

double EchoL0Dataset::getBandwidth()
{
    return this->bandwidth;
}

void EchoL0Dataset::setBandwidth(double Inbandwidth)
{
    this->bandwidth = Inbandwidth;
}

SatelliteAntPos EchoL0Dataset::getSatelliteAntPos(long prf_id)
{
    std::shared_ptr<double> antpos = this->getAntPos();
    SatelliteAntPos prfpos{};
    prfpos.time = antpos.get()[prf_id *19 + 0];
    prfpos.Px = antpos.get()[prf_id *19 + 1];
    prfpos.Py = antpos.get()[prf_id *19 + 2];
    prfpos.Pz = antpos.get()[prf_id *19 + 3];
    prfpos.Vx = antpos.get()[prf_id *19 + 4];
    prfpos.Vy = antpos.get()[prf_id *19 + 5];
    prfpos.Vz = antpos.get()[prf_id *19 + 6];
    prfpos.AntDirectX = antpos.get()[prf_id *19 + 7];
    prfpos.AntDirectY = antpos.get()[prf_id *19 + 8];
    prfpos.AntDirectZ = antpos.get()[prf_id *19 + 9];
    prfpos.AVx = antpos.get()[prf_id *19 + 10];
    prfpos.AVy = antpos.get()[prf_id *19 + 11];
    prfpos.AVz =antpos.get()[prf_id *19 + 12];
    prfpos.ZeroAntDiectX = antpos.get()[prf_id *19 + 13];
    prfpos.ZeroAntDiectY = antpos.get()[prf_id *19 + 14];
    prfpos.ZeroAntDiectZ = antpos.get()[prf_id *19 + 15];
    prfpos.lon =antpos.get()[prf_id *19 + 16];
    prfpos.lat =antpos.get()[prf_id *19 + 17];
    prfpos.ati =antpos.get()[prf_id *19 + 18];
    return prfpos;
}

void EchoL0Dataset::setRefPhaseRange(double refRange)
{
    this->refPhaseRange = refRange;
}

double EchoL0Dataset::getRefPhaseRange()
{
    return  this->refPhaseRange;
}

// 打印信息的实现
void EchoL0Dataset::printInfo()  {
    qDebug() << "Simulation Task Name: " << this->simulationTaskName ;
    qDebug() << "Pulse Count: " << this->PluseCount ;
    qDebug() << "Pulse Points: " << this->PlusePoints;
    qDebug() << "Near Range: " << this->NearRange ;
    qDebug() << "Far Range: " << this->FarRange;
    qDebug() << "Center Frequency: " << this->centerFreq ;
    qDebug() << "Sampling Frequency: " << this->Fs ;
    qDebug() << "Band width: " << this->bandwidth ;
}

// xml文件读写
void EchoL0Dataset::saveToXml() {

	QString filePath = this->xmlFilePath;

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning() << "Cannot open file for writing:" << filePath;
        return;
    }

    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("SimulationConfig");

    xmlWriter.writeTextElement("PluseCount", QString::number(this->PluseCount));
    xmlWriter.writeTextElement("BandWidth", QString::number(this->bandwidth));
    xmlWriter.writeTextElement("PlusePoints", QString::number(this->PlusePoints));
    xmlWriter.writeTextElement("NearRange", QString::number(this->NearRange));
    xmlWriter.writeTextElement("FarRange", QString::number(this->FarRange));
    xmlWriter.writeTextElement("CenterFreq", QString::number(this->centerFreq));
    xmlWriter.writeTextElement("Fs", QString::number(this->Fs));
    xmlWriter.writeTextElement("CenterAngle", QString::number(this->CenterAngle));
    xmlWriter.writeTextElement("LookSide", this->LookSide);
    xmlWriter.writeTextElement("SimulationTaskName", this->simulationTaskName);
    xmlWriter.writeTextElement("Filename", this->filename);
    xmlWriter.writeTextElement("Xmlname", this->xmlname);
    xmlWriter.writeTextElement("GPSPointFilename", this->GPSPointFilename);
    xmlWriter.writeTextElement("EchoDataFilename", this->echoDataFilename);
    xmlWriter.writeTextElement("refPhaseRange", QString::number(this->refPhaseRange));

    xmlWriter.writeEndElement(); // SimulationConfig
    xmlWriter.writeEndDocument();

    file.close();
}

ErrorCode EchoL0Dataset::loadFromXml() {
    QString filePath = this->xmlFilePath;
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "Cannot open file for reading:" << filePath;
        return ErrorCode::FILEOPENFAIL;
    }


	bool PluseCountflag = false;
	bool PlusePointsflag = false;
	bool NearRangeflag = false;
	bool FarRangeflag = false;
	bool CenterFreqflag = false;
	bool Fsflag = false;


    QXmlStreamReader xmlReader(&file);
    while (!xmlReader.atEnd() && !xmlReader.hasError()) {
        xmlReader.readNext();

        if (xmlReader.isStartElement()) {
            QString elementName = xmlReader.name().toString();
            if (elementName == "BandWidth") {
                this->bandwidth = xmlReader.readElementText().toDouble();
            }
            else if (elementName == "PluseCount") {
                this->PluseCount = xmlReader.readElementText().toLong();
            }
            else if (elementName == "PlusePoints") {
                this->PlusePoints = xmlReader.readElementText().toLong();
				PlusePointsflag = true;
            }
            else if (elementName == "NearRange") {
                this->NearRange = xmlReader.readElementText().toDouble();
                NearRangeflag = true;
            }
            else if (elementName == "FarRange") {
                this->FarRange = xmlReader.readElementText().toDouble();
                FarRangeflag = true;
            }
            else if (elementName == "CenterFreq") {
                this->centerFreq = xmlReader.readElementText().toDouble();
                CenterFreqflag = true;
            }
            else if (elementName == "Fs") {
                this->Fs = xmlReader.readElementText().toDouble();
                Fsflag = true;
            }
            else if (elementName == "refPhaseRange") {
                this->refPhaseRange = xmlReader.readElementText().toDouble();
                Fsflag = true;
            }
            else if (elementName == "SimulationTaskName") {
                this->simulationTaskName = xmlReader.readElementText();
            }
            else if (elementName == "Filename") {
                this->filename = xmlReader.readElementText();
            }
            else if (elementName == "Xmlname") {
                this->xmlname = xmlReader.readElementText();
            }
            else if (elementName == "GPSPointFilename") {
                this->GPSPointFilename = xmlReader.readElementText();
            }
            else if (elementName == "EchoDataFilename") {
                this->echoDataFilename = xmlReader.readElementText();
            }
            else if (elementName == "CenterAngle") {
                this->CenterAngle = xmlReader.readElementText().toDouble();
            }
            else if (elementName == "LookSide") {
                this->LookSide = xmlReader.readElementText();
            }
        }
    }

    if (xmlReader.hasError()) {
        qWarning() << "XML error:" << xmlReader.errorString();
        file.close();
        return ErrorCode::ECHO_L0DATA_XMLFILENOTOPEN;
    }

    if (!(PlusePointsflag && PlusePointsflag && FarRangeflag && NearRangeflag && CenterFreqflag && Fsflag)) {
        file.close();
        return ErrorCode::ECHO_L0DATA_XMLFILENOTOPEN;
    }

    file.close();

    return ErrorCode::SUCCESS;
}

std::shared_ptr<double> EchoL0Dataset::getAntPos()
{
    omp_lock_t lock; 
    omp_init_lock(&lock);
    omp_set_lock(&lock);
    // 读取文件
    std::shared_ptr<GDALDataset> rasterDataset = OpenDataset(this->GPSPointFilePath, GDALAccess::GA_ReadOnly);

    GDALDataType	gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType();
    GDALRasterBand* demBand = rasterDataset->GetRasterBand(1);

    long width = rasterDataset->GetRasterXSize();
    long height = rasterDataset->GetRasterYSize();
    long band_num = rasterDataset->GetRasterCount();
 
    std::shared_ptr<double>  temp = nullptr;

    if (gdal_datatype == GDT_Float64) {
        temp=std::shared_ptr<double>(new double[this->PluseCount * 19],delArrPtr);
        demBand->RasterIO(GF_Read, 0, 0, 19, this->PluseCount, temp.get(), 19, this->PluseCount, gdal_datatype, 0, 0);
    }
    else {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_GPSFILEFORMATERROR)) ;
    }
    rasterDataset.reset();
    omp_unset_lock(&lock);	 //  
    omp_destroy_lock(&lock); //  
    return temp;
}

std::shared_ptr<std::complex<double>> EchoL0Dataset::getEchoArr(long startPRF, long PRFLen)
{
    if (!(startPRF < this->PluseCount)) {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE))<<startPRF<<"  "<<this->PluseCount;
        return nullptr;
    }
    else {}

    omp_lock_t lock;
    omp_init_lock(&lock);
    omp_set_lock(&lock);
    std::shared_ptr<GDALDataset> rasterDataset = OpenDataset(this->echoDataFilePath, GDALAccess::GA_ReadOnly);


    GDALDataType	gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType();
    GDALRasterBand* poBand = rasterDataset->GetRasterBand(1);
    if (NULL==poBand||nullptr == poBand) {
        omp_lock_t lock;
        omp_init_lock(&lock);
        omp_set_lock(&lock);
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
        return nullptr;
    }
    else {}
    long width = rasterDataset->GetRasterXSize();
    long height = rasterDataset->GetRasterYSize();
    long band_num = rasterDataset->GetRasterCount();
    std::shared_ptr<std::complex<double>>  temp = nullptr;
	if (height != this->PluseCount || width != this->PlusePoints) {
		qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
	}
	else {
		if (gdal_datatype == GDT_CFloat64) {
            temp= std::shared_ptr<std::complex<double>>(new std::complex<double>[PRFLen * width ], delArrPtr);
            poBand->RasterIO(GF_Read, 0, startPRF, width, PRFLen, temp.get(), width, PRFLen, GDT_CFloat64, 0, 0);
            GDALFlushCache((GDALDatasetH)rasterDataset.get());
		}
		else {
			qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
		}
	}
     
    rasterDataset.reset();
    omp_unset_lock(&lock);	 //  
    omp_destroy_lock(&lock); //  
    return temp;
}

std::shared_ptr<std::complex<double>> EchoL0Dataset::getEchoArr()
{
    return  this->getEchoArr(0,this->PluseCount);
}

ErrorCode EchoL0Dataset::saveAntPos(std::shared_ptr<double> ptr)
{
    omp_lock_t lock;
    omp_init_lock(&lock);
    omp_set_lock(&lock);
    // 读取文件
    std::shared_ptr<GDALDataset> rasterDataset = OpenDataset(this->GPSPointFilePath, GDALAccess::GA_Update);

    GDALDataType	gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType();
    GDALRasterBand* demBand = rasterDataset->GetRasterBand(1);

    long width = rasterDataset->GetRasterXSize();
    long height = rasterDataset->GetRasterYSize();
    long band_num = rasterDataset->GetRasterCount();

    if (gdal_datatype == GDT_Float64) {  
        demBand->RasterIO(GF_Write, 0, 0, 19, this->PluseCount, ptr.get(), 19, this->PluseCount, gdal_datatype, 0, 0);
    }
    else {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_GPSFILEFORMATERROR));
        omp_unset_lock(&lock);	 //  
        omp_destroy_lock(&lock); //  
		return ErrorCode::ECHO_L0DATA_GPSFILEFORMATERROR;
    }
    rasterDataset.reset();
    omp_unset_lock(&lock);	 //  
    omp_destroy_lock(&lock); //
    return ErrorCode::SUCCESS;
}

ErrorCode EchoL0Dataset::saveEchoArr(std::shared_ptr<std::complex<double>> echoPtr, long startPRF, long PRFLen)
{
    if (!(startPRF < this->PluseCount)) {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE));
        return ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE;
    }
    else {}

    omp_lock_t lock;
    omp_init_lock(&lock);
    omp_set_lock(&lock);

    GDALAllRegister();
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
    GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->echoDataFilePath.toUtf8().constData(), GDALAccess::GA_Update));
 


    GDALDataType	gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType();
    GDALRasterBand* poBand = rasterDataset->GetRasterBand(1);
    if (NULL == poBand || nullptr == poBand) {
        omp_lock_t lock;
        omp_init_lock(&lock);
        omp_set_lock(&lock);
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
        return ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR;
    }
    else {}
    long width = rasterDataset->GetRasterXSize();
    long height = rasterDataset->GetRasterYSize();
    long band_num = rasterDataset->GetRasterCount();
 
    if (height != this->PluseCount || width != this->PlusePoints) {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
        omp_unset_lock(&lock);	 //  
        omp_destroy_lock(&lock); //  
        return ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR;
    }
    else {
        if (gdal_datatype == GDT_CFloat64) {
            poBand->RasterIO(GF_Write, 0, startPRF, width, PRFLen,  echoPtr.get(), width, PRFLen, GDT_CFloat64, 0, 0);
            GDALFlushCache((GDALDatasetH)rasterDataset);
        }
        else {
            qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
        }
    }
    GDALClose(rasterDataset);
    rasterDataset = nullptr;
    omp_unset_lock(&lock);	 //  
    omp_destroy_lock(&lock); //  
    return ErrorCode::SUCCESS;
}
 