#include "stdafx.h"
#include "SARSimulationImageL1.h"
#include "LogInfoCls.h"
#include <memory>
#include <QFile>
#include <QDomDocument>
#include <QXmlStreamReader>

SARSimulationImageL1Dataset::SARSimulationImageL1Dataset(RasterLevel level)
{
    this->Rasterlevel = level;
}

SARSimulationImageL1Dataset::~SARSimulationImageL1Dataset()
{
}

RasterLevel SARSimulationImageL1Dataset::getRasterLevel()
{
    return this->Rasterlevel;
}

QString SARSimulationImageL1Dataset::getoutFolderPath()
{
	return outFolderPath;
}

QString SARSimulationImageL1Dataset::getDatesetName()
{
	return L1DatasetName;
}

QString SARSimulationImageL1Dataset::getxmlfileName()
{
	return xmlfileName;
}

QString SARSimulationImageL1Dataset::getxmlFilePath()
{
	return xmlFilePath;
}

QString SARSimulationImageL1Dataset::getImageRasterName()
{
	return ImageRasterName;
}

QString SARSimulationImageL1Dataset::getImageRasterPath()
{
	return ImageRasterPath;
}

QString SARSimulationImageL1Dataset::getGPSPointFilename()
{
    if (this->Rasterlevel == RasterLevel::RasterL2) {
        return "";
    }
    return GPSPointFilename;
}

QString SARSimulationImageL1Dataset::getGPSPointFilePath()
{
    if (this->Rasterlevel == RasterLevel::RasterL2) {
        return "";
    }
    return GPSPointFilePath;
}

ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filename, long inrowCount, long incolCount)
{
    qDebug() << "--------------Image Raster L1 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->rowCount = inrowCount;
    this->colCount = incolCount;

    this->outFolderPath = folder;
    this->L1DatasetName = filename;

    this->xmlfileName = filename + ".xml";
    this->GPSPointFilename = filename + ".gpspos.data";
    this->ImageRasterName = filename + ".bin";

    this->xmlFilePath = dir.filePath(this->xmlfileName);
    this->GPSPointFilePath = dir.filePath(this->GPSPointFilename);
    this->ImageRasterPath = dir.filePath(this->ImageRasterName);
        
    if (QFile(this->xmlFilePath).exists())
    {
        this->loadFromXml();
    }
    else
    {
        this->saveToXml();
    }

    if (this->Rasterlevel!=RasterL2||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");
        std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->GPSPointFilePath.toUtf8().constData(), 19, rowCount, 1, GDT_Float64, NULL));
        GDALFlushCache((GDALDatasetH)poDstDS.get());
        poDstDS.reset();
        omp_unset_lock(&lock);	   
        omp_destroy_lock(&lock);    
    }

    if (this->Rasterlevel == RasterLevel::RasterSLC || QFile(this->ImageRasterPath).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");
        std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->ImageRasterPath.toUtf8().constData(), colCount, rowCount, 1, GDT_CFloat32, NULL));
        GDALFlushCache((GDALDatasetH)poDstDS.get());
        poDstDS.reset();
        omp_unset_lock(&lock);	 //  
        omp_destroy_lock(&lock); //  
    }


    if (this->Rasterlevel != RasterLevel::RasterSLC || QFile(this->ImageRasterPath).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");
        std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->ImageRasterPath.toUtf8().constData(), colCount, rowCount, 1, GDT_CFloat32, NULL));
        GDALFlushCache((GDALDatasetH)poDstDS.get());
        poDstDS.reset();
        omp_unset_lock(&lock);	 //  
        omp_destroy_lock(&lock); //  
    }


    return ErrorCode::SUCCESS;
}

ErrorCode SARSimulationImageL1Dataset::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->outFolderPath = folder;
    this->L1DatasetName = filename;

    this->xmlfileName = filename + ".xml";
    this->GPSPointFilename = filename + ".gpspos.data";
    this->ImageRasterName = filename + ".bin";

    this->xmlFilePath = dir.filePath(this->xmlfileName);
    this->GPSPointFilePath = dir.filePath(this->GPSPointFilename);
    this->ImageRasterPath = dir.filePath(this->ImageRasterName);

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

ErrorCode SARSimulationImageL1Dataset::Open(QString xmlPath)
{
    QFileInfo fileInfo(xmlPath);
    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::IMAGE_L1DATA_XMLNAMEERROR;
    }
    return ErrorCode::SUCCESS;

}

void SARSimulationImageL1Dataset::saveToXml()
{
    QFile file(this->xmlFilePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "Cannot open file for writing:" << file.errorString();
        return;
    }

    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);

    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("Parameters");

    switch (this->Rasterlevel)
    {
    case(RasterLevel::RasterSLC):
        xmlWriter.writeTextElement("rasterlevel", "SLC");
        break;
    case(RasterLevel::RasterL1B):
        xmlWriter.writeTextElement("rasterlevel", "L1B");
        break;
    case(RasterLevel::RasterL2):
        xmlWriter.writeTextElement("rasterlevel", "L2");
        break;
    default:
        break;
    }

    xmlWriter.writeTextElement("RowCount", QString::number(this->rowCount));
    xmlWriter.writeTextElement("ColCount", QString::number(this->colCount));
    xmlWriter.writeTextElement("Rnear", QString::number(this->Rnear));
    xmlWriter.writeTextElement("Rfar", QString::number(this->Rfar));
    xmlWriter.writeTextElement("Rref", QString::number(this->Rref));
    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);

    // 保存sateantpos 
    xmlWriter.writeStartElement("AntPos");
    
    for (long i = 0; i < this->sateposes.count(); i++) {
        xmlWriter.writeStartElement("AntPosParam");
        xmlWriter.writeTextElement("time", QString::number(this->sateposes[i].time));          // time
        xmlWriter.writeTextElement("Px",    QString::number(this->sateposes[i].Px));            // Px
        xmlWriter.writeTextElement("Py",    QString::number(this->sateposes[i].Py));            // Py
        xmlWriter.writeTextElement("Pz",    QString::number(this->sateposes[i].Pz));            // Pz
        xmlWriter.writeTextElement("Vx",    QString::number(this->sateposes[i].Vx));            // Vx
        xmlWriter.writeTextElement("Vy",    QString::number(this->sateposes[i].Vy));            // Vy
        xmlWriter.writeTextElement("Vz",    QString::number(this->sateposes[i].Vz));            // Vz
        xmlWriter.writeTextElement("AntDirectX", QString::number(this->sateposes[i].AntDirectX));    // AntDirectX
        xmlWriter.writeTextElement("AntDirectY", QString::number(this->sateposes[i].AntDirectY));    // AntDirectY
        xmlWriter.writeTextElement("AntDirectZ", QString::number(this->sateposes[i].AntDirectZ));    // AntDirectZ
        xmlWriter.writeTextElement("AVx", QString::number(this->sateposes[i].AVx));           // AVx
        xmlWriter.writeTextElement("AVy", QString::number(this->sateposes[i].AVy));           // AVy
        xmlWriter.writeTextElement("AVz", QString::number(this->sateposes[i].AVz));           // AVz
        xmlWriter.writeTextElement("lon", QString::number(this->sateposes[i].lon));           // lon
        xmlWriter.writeTextElement("lat", QString::number(this->sateposes[i].lat));           // lat
        xmlWriter.writeTextElement("ati", QString::number(this->sateposes[i].ati));           // ati
        xmlWriter.writeEndElement();  // 结束 <AntPosParam>
    }
 
    xmlWriter.writeTextElement("ImageStartTime", QString::number(this->startImageTime));
    xmlWriter.writeTextElement("ImageEndTime", QString::number(this->EndImageTime));

    xmlWriter.writeTextElement("incidenceAngleNearRange", QString::number(this->incidenceAngleNearRange));
    xmlWriter.writeTextElement("incidenceAngleFarRange", QString::number(this->incidenceAngleFarRange));
    xmlWriter.writeTextElement("TotalProcessedAzimuthBandWidth", QString::number(this->TotalProcessedAzimuthBandWidth));
    xmlWriter.writeTextElement("DopplerParametersReferenceTime", QString::number(this->DopplerParametersReferenceTime));

    xmlWriter.writeStartElement("DopplerCentroidCoefficients");
    xmlWriter.writeTextElement("d0", QString::number(this->d0));
    xmlWriter.writeTextElement("d1", QString::number(this->d1));
    xmlWriter.writeTextElement("d2", QString::number(this->d2));
    xmlWriter.writeTextElement("d3", QString::number(this->d3));
    xmlWriter.writeTextElement("d4", QString::number(this->d4));
    xmlWriter.writeEndElement(); // DopplerCentroidCoefficients

    xmlWriter.writeStartElement("DopplerRateValuesCoefficients");
    xmlWriter.writeTextElement("r0", QString::number(this->r0));
    xmlWriter.writeTextElement("r1", QString::number(this->r1));
    xmlWriter.writeTextElement("r2", QString::number(this->r2));
    xmlWriter.writeTextElement("r3", QString::number(this->r3));
    xmlWriter.writeTextElement("r4", QString::number(this->r4));
    xmlWriter.writeEndElement(); // DopplerRateValuesCoefficients


    xmlWriter.writeTextElement("latitude_center", QString::number(this->latitude_center));
    xmlWriter.writeTextElement("longitude_center", QString::number(this->longitude_center));
    xmlWriter.writeTextElement("latitude_topLeft", QString::number(this->latitude_topLeft));
    xmlWriter.writeTextElement("longitude_topLeft", QString::number(this->longitude_topLeft));
    xmlWriter.writeTextElement("latitude_topRight", QString::number(this->latitude_topRight));
    xmlWriter.writeTextElement("longitude_topRight", QString::number(this->longitude_topRight));
    xmlWriter.writeTextElement("latitude_bottomLeft", QString::number(this->latitude_bottomLeft));
    xmlWriter.writeTextElement("longitude_bottomLeft", QString::number(this->longitude_bottomLeft));
    xmlWriter.writeTextElement("latitude_bottomRight", QString::number(this->latitude_bottomRight));
    xmlWriter.writeTextElement("longitude_bottomRight", QString::number(this->longitude_bottomRight));

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

    file.close();
}

ErrorCode SARSimulationImageL1Dataset::loadFromXml()
{
    QFile file(this->xmlFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Cannot open file for reading:" << file.errorString();
        return ErrorCode::IMAGE_L1DATA_XMLNAMEOPENERROR;
    }

    QXmlStreamReader xmlReader(&file);
    while (!xmlReader.atEnd() && !xmlReader.hasError()) {
        QXmlStreamReader::TokenType token = xmlReader.readNext();
        if (token == QXmlStreamReader::StartDocument) {
            continue;
        }
        if (token == QXmlStreamReader::StartElement) {
            if (xmlReader.name() == "Parameters") {
                continue;
            }
            else if (xmlReader.name() == "rasterlevel") {
                QString rasterlevelstr = xmlReader.readElementText();
                if (rasterlevelstr == "SLC") {
                    this->Rasterlevel = RasterLevel::RasterSLC;
                }
                else if (rasterlevelstr == "L1B") {
                    this->Rasterlevel = RasterLevel::RasterL1B;
                }
                else if (rasterlevelstr == "L2") {
                    this->Rasterlevel = RasterLevel::RasterL2;
                }
            }
            else if (xmlReader.name() == "RowCount") {
                this->rowCount = xmlReader.readElementText().toLong();
            }
            else if (xmlReader.name() == "ColCount") {
                this->colCount = xmlReader.readElementText().toLong();
            }
            else if (xmlReader.name() == "Rnear") {
                this->Rnear = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "Rfar") {
                this->Rfar = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "Rref") {
                this->Rref = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "CenterFreq") {
                this->centerFreq = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "Fs") {
                this->Fs = xmlReader.readElementText().toDouble();
            }
            else if(xmlReader.name() == "ImageStartTime"){
                this->startImageTime = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "ImageEndTime") {
                this->EndImageTime = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "CenterAngle") {
                this->CenterAngle = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "LookSide") {
                this->LookSide = xmlReader.readElementText();
            }
            else if (xmlReader.name() == "AntPosParam") {
                SatelliteAntPos antPosParam;
                while (!(xmlReader.isEndElement() && xmlReader.name() == "AntPosParam")) {
                    if (xmlReader.isStartElement()) {
                        if (xmlReader.name() == "time") {
                            antPosParam.time = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "Px") {
                            antPosParam.Px = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "Py") {
                            antPosParam.Py = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "Pz") {
                            antPosParam.Pz = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "Vx") {
                            antPosParam.Vx = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "Vy") {
                            antPosParam.Vy = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "Vz") {
                            antPosParam.Vz = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "AntDirectX") {
                            antPosParam.AntDirectX = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "AntDirectY") {
                            antPosParam.AntDirectY = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "AntDirectZ") {
                            antPosParam.AntDirectZ = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "AVx") {
                            antPosParam.AVx = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "AVy") {
                            antPosParam.AVy = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "AVz") {
                            antPosParam.AVz = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "lon") {
                            antPosParam.lon = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "lat") {
                            antPosParam.lat = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "ati") {
                            antPosParam.ati = xmlReader.readElementText().toDouble();
                        }
                    }
                    xmlReader.readNext();
                }

                sateposes.append(antPosParam); // 将解析的数据添加到列表中
            }
            else if (xmlReader.name() == "incidenceAngleNearRange") {
                incidenceAngleNearRange = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "incidenceAngleFarRange") {
                incidenceAngleFarRange = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "TotalProcessedAzimuthBandWidth") {
                this->TotalProcessedAzimuthBandWidth = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "DopplerParametersReferenceTime") {
                this->DopplerParametersReferenceTime = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "DopplerCentroidCoefficients") {

                while (!(xmlReader.tokenType() == QXmlStreamReader::EndElement && xmlReader.name() == "DopplerCentroidCoefficients")) {
                    if (xmlReader.tokenType() == QXmlStreamReader::StartElement) {
                        if (xmlReader.name() == "d0") {
                            this->d0 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "d1") {
                            this->d1 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "d2") {
                            this->d2 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "d3") {
                            this->d3 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "d4") {
                            this->d4 = xmlReader.readElementText().toDouble();
                        }
                    }
                    xmlReader.readNext();
                }
            }
            else if (xmlReader.name() == "DopplerRateValuesCoefficients") {
                while (!(xmlReader.tokenType() == QXmlStreamReader::EndElement && xmlReader.name() == "DopplerRateValuesCoefficients")) {
                    if (xmlReader.tokenType() == QXmlStreamReader::StartElement) {
                        if (xmlReader.name() == "r0") {
                            this->r0 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "r1") {
                            this->r1 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "r2") {
                            this->r2 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "r3") {
                            this->r3 = xmlReader.readElementText().toDouble();
                        }
                        else if (xmlReader.name() == "r4") {
                            this->r4 = xmlReader.readElementText().toDouble();
                        }
                    }
                    xmlReader.readNext();
                }
            }
            else if (xmlReader.name() == "latitude_center") {
                this->latitude_center = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "longitude_center") {
                this->longitude_center = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "latitude_topLeft") {
                this->latitude_topLeft = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "longitude_topLeft") {
                this->longitude_topLeft = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "latitude_topRight") {
                this->latitude_topRight = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "longitude_topRight") {
                this->longitude_topRight = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "latitude_bottomLeft") {
                this->latitude_bottomLeft = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "longitude_bottomLeft") {
                this->longitude_bottomLeft = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "latitude_bottomRight") {
                this->latitude_bottomRight = xmlReader.readElementText().toDouble();
            }
            else if (xmlReader.name() == "longitude_bottomRight") {
                this->longitude_bottomRight = xmlReader.readElementText().toDouble();
            }
        }
    }
 
    if (xmlReader.hasError()) {
        qDebug() << "XML error:" << xmlReader.errorString();
        return ErrorCode::IMAGE_L1DATA_XMLNAMEPARASEERROR;
    }

    file.close();
    return ErrorCode::SUCCESS;
}

std::shared_ptr<double> SARSimulationImageL1Dataset::getAntPos()
{
    if (this->Rasterlevel == RasterLevel::RasterL2) {
        return nullptr;
    }


    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->rowCount * 19], delArrPtr);
        demBand->RasterIO(GF_Read, 0, 0, 19, this->rowCount, temp.get(), 19, this->rowCount, 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;
}

ErrorCode SARSimulationImageL1Dataset::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->rowCount, ptr.get(), 19, this->rowCount, 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;
}

std::shared_ptr<std::complex<double>> SARSimulationImageL1Dataset::getImageRaster()
{
    if (this->Rasterlevel != RasterLevel::RasterSLC) {
        return nullptr;
    }

    return  this->getImageRaster(0, this->rowCount);
}

ErrorCode SARSimulationImageL1Dataset::saveImageRaster(std::shared_ptr<std::complex<double>> echoPtr, long startPRF, long PRFLen)
{
    if (!(startPRF < this->rowCount)) {
        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);
    std::shared_ptr<GDALDataset> rasterDataset = OpenDataset(this->ImageRasterPath, 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->rowCount || width != this->colCount) {
        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_CFloat32) {
            poBand->RasterIO(GF_Write, 0, startPRF, width, PRFLen, echoPtr.get(), width, PRFLen, GDT_CFloat32, 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 ErrorCode::SUCCESS;
}

std::shared_ptr<std::complex<double>> SARSimulationImageL1Dataset::getImageRaster(long startPRF, long PRFLen)
{
    if (this->Rasterlevel != RasterLevel::RasterSLC) {
        return nullptr;
    }


    if (!(startPRF < this->rowCount)) {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE)) << startPRF << "  " << this->rowCount;
        return nullptr;
    }
    else {}

    omp_lock_t lock;
    omp_init_lock(&lock);
    omp_set_lock(&lock);
    std::shared_ptr<GDALDataset> rasterDataset = OpenDataset(this->ImageRasterPath, 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->rowCount || width != this->colCount) {
        qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
    }
    else {
        if (gdal_datatype == GDT_CFloat32) {
            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_CFloat32, 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;
}

Eigen::MatrixXcd SARSimulationImageL1Dataset::getImageRasterMatrix()
{
    if (this->Rasterlevel != RasterLevel::RasterSLC) {
        return Eigen::MatrixXcd::Zero(0,0);
    }


    std::shared_ptr<std::complex<double>> data = this->getImageRaster();
    Eigen::MatrixXcd dataimg = Eigen::MatrixXcd::Zero(this->rowCount, this->colCount);
    for (long i = 0; i < this->rowCount; i++) {
        for (long j = 0; j < this->colCount; j++) {
            dataimg(i, j) = data.get()[i*colCount+j];
        }
    }
    return Eigen::MatrixXcd();
}

ErrorCode SARSimulationImageL1Dataset::saveImageRaster(Eigen::MatrixXcd& dataimg, long startPRF)
{
    std::shared_ptr<std::complex<double>> data(new std::complex<double>[dataimg.rows()* dataimg.cols()]);
    long dataimgrows = dataimg.rows();
    long dataimgcols = dataimg.cols();
    for (long i = 0; i < dataimgrows; i++) {
        for (long j = 0; j < dataimgcols; j++) {
            data.get()[i * dataimgcols + j] = dataimg(i, j);
        }
    }
    this->saveImageRaster(data, startPRF,dataimgrows);
    return ErrorCode();
}

gdalImage SARSimulationImageL1Dataset::getImageRasterGdalImage()
{
    return gdalImage(this->ImageRasterPath);
}

void SARSimulationImageL1Dataset::setStartImageTime(double imageTime)
{
    this->startImageTime = imageTime;
}

double SARSimulationImageL1Dataset::getStartImageTime()
{
    return this->startImageTime;
}

void SARSimulationImageL1Dataset::setEndImageTime(double imageTime)
{
    this->EndImageTime = imageTime;
}

double SARSimulationImageL1Dataset::getEndImageTime()
{
    return this->EndImageTime;
}

QVector<SatelliteAntPos> SARSimulationImageL1Dataset::getXmlSateAntPos()
{
    if (this->Rasterlevel == RasterLevel::RasterL2) {
        return QVector<SatelliteAntPos>(0);
    }
    return this->sateposes;
}

void SARSimulationImageL1Dataset::setSateAntPos(QVector<SatelliteAntPos> pos)
{
    this->sateposes = pos;
}

// Getter 和 Setter 方法实现
long SARSimulationImageL1Dataset::getrowCount() { return this->rowCount; }
void SARSimulationImageL1Dataset::setrowCount(long rowCountin) { this->rowCount = rowCountin; }

long SARSimulationImageL1Dataset::getcolCount() { return this->colCount; }
void SARSimulationImageL1Dataset::setcolCount(long pulsePointsin) { this->colCount = pulsePointsin; }


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

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

double SARSimulationImageL1Dataset::getRefRange()
{
    return this->Rref;
}

void SARSimulationImageL1Dataset::setRefRange(double refRange)
{
    this->Rref = refRange;
}

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

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

double SARSimulationImageL1Dataset::getPRF()
{
    return this->prf;
}

void SARSimulationImageL1Dataset::setPRF(double PRF)
{
    this->prf = PRF;
}

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

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

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

void SARSimulationImageL1Dataset::setLookSide(QString looksides)
{
    this->LookSide = looksides;
}

double SARSimulationImageL1Dataset::getTotalProcessedAzimuthBandWidth()
{
    return TotalProcessedAzimuthBandWidth;
}

void SARSimulationImageL1Dataset::setTotalProcessedAzimuthBandWidth(double v)
{
    TotalProcessedAzimuthBandWidth = v;
}

double SARSimulationImageL1Dataset::getDopplerParametersReferenceTime()
{
    return DopplerParametersReferenceTime;
}

void SARSimulationImageL1Dataset::setDopplerParametersReferenceTime(double v)
{
    DopplerParametersReferenceTime = v;
}

QVector<double> SARSimulationImageL1Dataset::getDopplerParams()
{
    QVector<double> result(5);
    result[0] = d0;
    result[1] = d1;
    result[2] = d2;
    result[3] = d3;
    result[4] = d4;
    return result;
}

void SARSimulationImageL1Dataset::setDopplerParams(double id0, double id1, double id2, double id3, double id4)
{
    this->d0 = id0;
    this->d1 = id1;
    this->d2 = id2;
    this->d3 = id3;
    this->d4 = id4;
}

QVector<double> SARSimulationImageL1Dataset::getDopplerCenterCoff()
{
    QVector<double> result(5);
    result[0]=r0;
    result[1]=r1;
    result[2]=r2;
    result[3]=r3;
    result[4]=r4;
    return result;
}

void SARSimulationImageL1Dataset::setDopplerCenterCoff(double ir0, double ir1, double ir2, double ir3, double ir4)
{
	this->r0 = ir0;
	this->r1 = ir1;
	this->r2 = ir2;
	this->r3 = ir3;
	this->r4 = ir4;
}

double SARSimulationImageL1Dataset::getIncidenceAngleNearRange()
{
    return incidenceAngleNearRange;
}

void SARSimulationImageL1Dataset::setIncidenceAngleNearRangeet(double angle)
{
    this->incidenceAngleNearRange = angle;
}

double SARSimulationImageL1Dataset::getIncidenceAngleFarRange()
{
    return incidenceAngleFarRange;
}

void SARSimulationImageL1Dataset::setIncidenceAngleFarRange(double angle)
{
    this->incidenceAngleFarRange = angle;
}
 
double SARSimulationImageL1Dataset::getLatitudeCenter()   { return latitude_center; }
void SARSimulationImageL1Dataset::setLatitudeCenter(double value) { latitude_center = value; }

double SARSimulationImageL1Dataset::getLongitudeCenter()   { return longitude_center; }
void SARSimulationImageL1Dataset::setLongitudeCenter(double value) { longitude_center = value; }

double SARSimulationImageL1Dataset::getLatitudeTopLeft()   { return latitude_topLeft; }
void SARSimulationImageL1Dataset::setLatitudeTopLeft(double value) { latitude_topLeft = value; }

double SARSimulationImageL1Dataset::getLongitudeTopLeft()   { return longitude_topLeft; }
void SARSimulationImageL1Dataset::setLongitudeTopLeft(double value) { longitude_topLeft = value; }

double SARSimulationImageL1Dataset::getLatitudeTopRight()   { return latitude_topRight; }
void SARSimulationImageL1Dataset::setLatitudeTopRight(double value) { latitude_topRight = value; }

double SARSimulationImageL1Dataset::getLongitudeTopRight()   { return longitude_topRight; }
void SARSimulationImageL1Dataset::setLongitudeTopRight(double value) { longitude_topRight = value; }

double SARSimulationImageL1Dataset::getLatitudeBottomLeft()   { return latitude_bottomLeft; }
void SARSimulationImageL1Dataset::setLatitudeBottomLeft(double value) { latitude_bottomLeft = value; }

double SARSimulationImageL1Dataset::getLongitudeBottomLeft()   { return longitude_bottomLeft; }
void SARSimulationImageL1Dataset::setLongitudeBottomLeft(double value) { longitude_bottomLeft = value; }

double SARSimulationImageL1Dataset::getLatitudeBottomRight()   { return latitude_bottomRight; }
void SARSimulationImageL1Dataset::setLatitudeBottomRight(double value) { latitude_bottomRight = value; }

double SARSimulationImageL1Dataset::getLongitudeBottomRight()   { return longitude_bottomRight; }
void SARSimulationImageL1Dataset::setLongitudeBottomRight(double value) { longitude_bottomRight = value; }

double SARSimulationImageL1Dataset::getdrange() { return this->dr; }
void SARSimulationImageL1Dataset::setdrange(double idr) { this->dr = idr; }

double SARSimulationImageL1Dataset::getdAz() { return this->dAz; }
void SARSimulationImageL1Dataset::setdAz(double idAz) { this->dAz = idAz; }




DemBox SARSimulationImageL1Dataset::getExtend()
{
    double minlon = 0, maxlon = 0;
    double minlat = 0, maxlat = 0;
    minlon = this->longitude_bottomLeft < this->longitude_bottomRight ? this->longitude_bottomLeft : this->longitude_bottomRight;
    minlon = minlon < this->longitude_topLeft ? minlon : this->longitude_topLeft;
    minlon = minlon < this->longitude_topRight ? minlon : this->longitude_topRight;

    minlat = this->latitude_bottomLeft < this->latitude_bottomRight ? this->latitude_bottomLeft : this->latitude_bottomRight;
    minlat = minlat < this->latitude_topLeft ? minlat : this->latitude_topLeft;
    minlat = minlat < this->latitude_bottomRight ? minlat : this->latitude_bottomRight;

    maxlon = this->longitude_bottomLeft > this->longitude_bottomRight ? this->longitude_bottomLeft : this->longitude_bottomRight;
    maxlon = maxlon > this->longitude_topLeft ? maxlon : this->longitude_topLeft;
    maxlon = maxlon > this->longitude_topRight ? maxlon : this->longitude_topRight;

    maxlat = this->latitude_bottomLeft > this->latitude_bottomRight ? this->latitude_bottomLeft : this->latitude_bottomRight;
    maxlat = maxlat > this->latitude_topLeft ? maxlat : this->latitude_topLeft;
    maxlat = maxlat > this->latitude_bottomRight ? maxlat : this->latitude_bottomRight;

    DemBox box;
    box.min_lat = minlat;
    box.min_lon = minlon;
    box.max_lat = maxlat;
    box.max_lon = maxlon;

    return box;
}
