From 2d045747ebcfdcf4093e9f518068509297875d37 Mon Sep 17 00:00:00 2001 From: chenzenghui <3045316072@qq.com> Date: Wed, 28 May 2025 00:32:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0BaseTool=E3=80=81ToolAbstract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- BaseTool/BaseConstVariable.h | 388 ++++++ BaseTool/BaseTool.cpp | 775 +++++++++++ BaseTool/BaseTool.h | 226 ++++ BaseTool/EchoDataFormat.cpp | 822 ++++++++++++ BaseTool/EchoDataFormat.h | 225 ++++ BaseTool/FileOperator.cpp | 322 +++++ BaseTool/FileOperator.h | 64 + BaseTool/GeoOperator.cpp | 511 +++++++ BaseTool/GeoOperator.h | 150 +++ BaseTool/ImageOperatorBase.cpp | 1793 +++++++++++++++++++++++++ BaseTool/ImageOperatorBase.h | 631 +++++++++ BaseTool/LogInfoCls.cpp | 233 ++++ BaseTool/LogInfoCls.h | 103 ++ BaseTool/MergeRasterOperator.cpp | 488 +++++++ BaseTool/PrintMsgToQDebug.cpp | 36 + BaseTool/PrintMsgToQDebug.h | 16 + BaseTool/QToolProcessBarDialog.cpp | 24 + BaseTool/QToolProcessBarDialog.h | 23 + BaseTool/QToolProcessBarDialog.ui | 73 + BaseTool/RasterToolBase.cpp | 276 ++++ BaseTool/RasterToolBase.h | 96 ++ BaseTool/SARSimulationImageL1.cpp | 1001 ++++++++++++++ BaseTool/SARSimulationImageL1.h | 218 +++ BaseTool/ShowProessAbstract.cpp | 18 + BaseTool/TestImageOperator.cpp | 146 ++ BaseTool/gdalImageComplexOperator.cpp | 547 ++++++++ BaseTool/gdalImageOperator.cpp | 1530 +++++++++++++++++++++ BaseTool/stdafx.cpp | 1 + BaseTool/stdafx.h | 0 ToolAbstract/QToolAbstract.cpp | 41 + ToolAbstract/QToolAbstract.h | 40 + 32 files changed, 10818 insertions(+), 3 deletions(-) create mode 100644 BaseTool/BaseConstVariable.h create mode 100644 BaseTool/BaseTool.cpp create mode 100644 BaseTool/BaseTool.h create mode 100644 BaseTool/EchoDataFormat.cpp create mode 100644 BaseTool/EchoDataFormat.h create mode 100644 BaseTool/FileOperator.cpp create mode 100644 BaseTool/FileOperator.h create mode 100644 BaseTool/GeoOperator.cpp create mode 100644 BaseTool/GeoOperator.h create mode 100644 BaseTool/ImageOperatorBase.cpp create mode 100644 BaseTool/ImageOperatorBase.h create mode 100644 BaseTool/LogInfoCls.cpp create mode 100644 BaseTool/LogInfoCls.h create mode 100644 BaseTool/MergeRasterOperator.cpp create mode 100644 BaseTool/PrintMsgToQDebug.cpp create mode 100644 BaseTool/PrintMsgToQDebug.h create mode 100644 BaseTool/QToolProcessBarDialog.cpp create mode 100644 BaseTool/QToolProcessBarDialog.h create mode 100644 BaseTool/QToolProcessBarDialog.ui create mode 100644 BaseTool/RasterToolBase.cpp create mode 100644 BaseTool/RasterToolBase.h create mode 100644 BaseTool/SARSimulationImageL1.cpp create mode 100644 BaseTool/SARSimulationImageL1.h create mode 100644 BaseTool/ShowProessAbstract.cpp create mode 100644 BaseTool/TestImageOperator.cpp create mode 100644 BaseTool/gdalImageComplexOperator.cpp create mode 100644 BaseTool/gdalImageOperator.cpp create mode 100644 BaseTool/stdafx.cpp create mode 100644 BaseTool/stdafx.h create mode 100644 ToolAbstract/QToolAbstract.cpp create mode 100644 ToolAbstract/QToolAbstract.h diff --git a/.gitignore b/.gitignore index 32f607a..cd423fd 100644 --- a/.gitignore +++ b/.gitignore @@ -32,9 +32,7 @@ mono_crash.* **/**/[Oo]ut/ **/**/[Ll]og/ **/**/[Ll]ogs/ -**/BaseTool/ -BaseTool/ -ToolAbstract/ + **/Releases # Visual Studio 2015/2017 cache/options directory diff --git a/BaseTool/BaseConstVariable.h b/BaseTool/BaseConstVariable.h new file mode 100644 index 0000000..a67b9d5 --- /dev/null +++ b/BaseTool/BaseConstVariable.h @@ -0,0 +1,388 @@ +#pragma once + +#ifndef BASECONSTVARIABLE_H +#define BASECONSTVARIABLE_H +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_NO_DEBUG + + + +#ifdef BASECONSTVARIABLE_API +#define BASECONSTVARIABLEAPI __declspec(dllexport) +#else +#define BASECONSTVARIABLEAPI __declspec(dllimport) +#endif + + + +/** 定义常见文件格式*********/ +#define ENVI_FILE_FORMAT_FILTER u8"ALL File(*.*);;ENVI Bin(*.bin);;ENVI Data(*.dat);;ENVI Data(*.data);;tiff影像(*.tif);;tiff影像(*.tiff)" +#define XML_FILE_FORMAT_FILTER u8"ALL File(*.*);;XML File(*.xml);;tiff影像(*.tiff)" + + +// +//#define EIGEN_USE_BLAS +//#define EIGEN_USE_LAPACK +//#define EIGEN_VECTORIZE_SSE2 + +//#define DEBUGSHOWDIALOG + +#define __CUDANVCC___ // 定义CUDA函数 + +#define __PRFDEBUG__ +//#define __PRFDEBUG_PRFINF__ +//#define __ECHOTIMEDEBUG__ + +#define __TBPIMAGEDEBUG__ + +//#include +#include +#include +#include +#include + +/** 打印时间 ***************************************************************/ +inline char* get_cur_time() { + static char s[20]; + time_t t; + struct tm* ltime; + time(&t); + ltime = localtime(&t); + strftime(s, 20, "%Y-%m-%d %H:%M:%S", ltime); + return s; +} + +#define PRINT(fmt, ...) printf("%s " fmt, get_cur_time(), ##__VA_ARGS__); + + + + +#define MATPLOTDRAWIMAGE + + +#define r2d 180/3.141592653589793238462643383279 +#define d2r 3.141592653589793238462643383279/180 +#define LIGHTSPEED 299792458 +#define PRECISIONTOLERANCE 1e-6 +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI +#define EARTHWE 0.000072292115 +#define PI 3.141592653589793238462643383279 + +#define WGS84_A 6378137.0 // 长半轴 (m) +#define WGS84_F (1.0/298.257223563) +#define WGS84_B (WGS84_A*(1-WGS84_F)) // 短半轴 (m) + + +#define earthRoute 0.000072292115 +#define Memory1GB 1073741824 +#define Memory1MB 1048576 +#define Memory1KB 1024 + +const std::complex imagI(0, 1); + + +const double epsilon = 0.000000000000001; +const double pi = 3.14159265358979323846; + + +const double a = 6378137.0; //椭球长半轴 +const double ae = 6378137.0; //椭球长半轴 +const double ee = 0.0818191910428;// 第一偏心率 +const double f_inverse = 298.257223563; //扁率倒数 +const double b = a - a / f_inverse; +const double eSquare = (a * a - b * b) / (a * a); +const double e = sqrt(eSquare); +const double earth_Re = 6378136.49; +const double earth_Rp = (1 - 1 / f_inverse) * earth_Re; +const double earth_We = 0.000072292115; + +/*********************************************** openMap参数 ********************************************************************/ +static long Paral_num_thread = 14; + + +/*********************************************** 基础枚举 ********************************************************************/ + +enum POLARTYPEENUM { // 极化类型 + POLARHH, + POLARHV, + POLARVH, + POLARVV, + POLARUNKOWN +}; + + +enum SIGMATYPE { + DBVALUE, + AMPVALUE, + INTENSITYVALUE, + LINEARVALUE +}; + + +/*********************************************** 基础结构体区域 ********************************************************************/ + +/// +/// 地理坐标点 +/// +struct Landpoint // 点 SAR影像的像素坐标; +{ + double lon; // 经度x lon pixel_col + double lat; // 纬度y lat pixel_row + double ati; // 高程z ati pixel_time +}; + +struct Point2 { + double x = 0; + double y = 0; +}; + + +struct Point3 { + double x = 0; + double y = 0; + double z = 0; + void setX(double ix) { x = ix; } + void setY(double iy) { y = iy; } + void setZ(double iz) { z = iz; } +}; + +struct Point_3d { + double x; + double y; + double z; +}; + + + +struct DemBox { + double min_lon; + double max_lon; + double min_lat; + double max_lat; +}; + +struct Vector3 { + double x, y, z; +}; + + +struct Vector3_single { + float x, y, z; +}; + + +/*********************************************** FEKO仿真参数 ********************************************************************/ +extern "C" struct SatellitePos { + double time; + double Px ; + double Py ; + double Pz ; + double Vx ; + double Vy ; + double Vz ; +}; + + +extern "C" struct SatelliteAntPos { + double time; // 0 + double Px; + double Py; + double Pz; + double Vx; + double Vy; + double Vz; //7 + double AntDirectX; + double AntDirectY; + double AntDirectZ; + double AVx; + double AVy; + double AVz;//13 + double ZeroAntDiectX; + double ZeroAntDiectY; + double ZeroAntDiectZ; + double lon; + double lat; + double ati; // 19 +}; + + +extern "C" struct PatternImageDesc { + long phinum; + long thetanum; + double startTheta; + double startPhi; + double dtheta; + double dphi; +}; + + +struct CUDA_AntSate_PtrList { + long PRF_len = 0; + double* h_antpx = nullptr, * d_antpx = nullptr; + double* h_antpy = nullptr, * d_antpy = nullptr; + double* h_antpz = nullptr, * d_antpz = nullptr; + double* h_antvx = nullptr, * d_antvx = nullptr; + double* h_antvy = nullptr, * d_antvy = nullptr; + double* h_antvz = nullptr, * d_antvz = nullptr; + double* h_antdirectx = nullptr, * d_antdirectx = nullptr; + double* h_antdirecty = nullptr, * d_antdirecty = nullptr; + double* h_antdirectz = nullptr, * d_antdirectz = nullptr; + double* h_antXaxisX = nullptr, * d_antXaxisX = nullptr; + double* h_antXaxisY = nullptr, * d_antXaxisY = nullptr; + double* h_antXaxisZ = nullptr, * d_antXaxisZ = nullptr; + double* h_antYaxisX = nullptr, * d_antYaxisX = nullptr; + double* h_antYaxisY = nullptr, * d_antYaxisY = nullptr; + double* h_antYaxisZ = nullptr, * d_antYaxisZ = nullptr; + double* h_antZaxisX = nullptr, * d_antZaxisX = nullptr; + double* h_antZaxisY = nullptr, * d_antZaxisY = nullptr; + double* h_antZaxisZ = nullptr, * d_antZaxisZ = nullptr; +}; + +/*********************************************** 卫星轨道坐标 ********************************************************************/ + + +/// +/// 轨道节点,坐标系统为WGS84 +/// +struct SatelliteOribtNode { + double time; + + double Px;// 位置 + double Py; + double Pz; + + double Vx;// 速度 + double Vy; + double Vz; + + double AVx; // 加速度 + double AVy; + double AVz; + + double AntXaxisX; // X天线指向,对应翻滚角等参数 + double AntXaxisY; // + double AntXaxisZ; // + + double AntYaxisX; // Y天线指向,对应翻滚角等参数 + double AntYaxisY; // + double AntYaxisZ; // + + double AntZaxisX; // Z天线指向,对应翻滚角等参数 + double AntZaxisY; // + double AntZaxisZ; // + + + double AntDirecX; // 天线指向,对应翻滚角等参数 + double AntDirecY; + double AntDirecZ; + + double zeroDopplerDirectX; // 0 多普勒方向 + double zeroDopplerDirectY; + double zeroDopplerDirectZ; + + double beamAngle; // 波位角 + double AzAngle;// 摆动角 + + +}; + + +struct SatelliteAntDirect { + double Xst; // 地面-->卫星矢量 + double Yst; + double Zst; + double Vxs; // 卫星速度 + double Vys; + double Vzs; + + double Xant; // 天线坐标系下的 矢量坐标 + double Yant; + double Zant; + + double Norm; + + double ThetaAnt; // 天线坐标系下的 theta 坐标系 + double PhiAnt; +}; + + + +struct RadiationPatternGainPoint { + double theta; + double phi; + double GainValue; +}; + + + + +/*********************************************** 指针回收区域 ********************************************************************/ + +inline void delArrPtr(void* p) +{ + if (nullptr == p || NULL == p) { + return; + } + delete[] p; + p = nullptr; +}; + +inline void delPointer(void* p) +{ + if (nullptr == p || NULL == p) { + return; + } + delete p; + p = nullptr; +}; + +inline void PrintTime() { + time_t current_time; + time(¤t_time); + printf("Current timestamp in seconds: %ld\n", (long)current_time); +}; + +/** 计算分块 ******************************************************************/ + +inline long getBlockRows(long sizeMB, long cols, long sizeMeta, long maxRows) { + long rownum = (round(Memory1MB * 1.0 / sizeMeta / cols * sizeMB) + cols - 1); + rownum = rownum < 0 ? 1 : rownum; + rownum = rownum < maxRows ? rownum : maxRows; + return rownum; +}; + + +inline long nextpow2(long n) { + long en = ceil(log2(n)); + return pow(2, en); +}; + +inline void releaseVoidArray(void* a) +{ + free(a); + a = NULL; +}; + + + +inline double converSigma2amp(double inSig, SIGMATYPE sigtype) { + switch (sigtype) + { + case DBVALUE: + return pow(10, inSig / 20); + break; + case AMPVALUE: + return inSig; + break; + case INTENSITYVALUE: + return pow(10, inSig / 10); + break; + default: + return inSig; + break; + } +} + + +#endif \ No newline at end of file diff --git a/BaseTool/BaseTool.cpp b/BaseTool/BaseTool.cpp new file mode 100644 index 0000000..5ea4ed0 --- /dev/null +++ b/BaseTool/BaseTool.cpp @@ -0,0 +1,775 @@ +#include "stdafx.h" +//#define EIGEN_USE_BLAS +#define EIGEN_VECTORIZE_SSE4_2 +//#include + +#include +#include +#include +#include +////#include + +#include +#include +#include < io.h > +#include < stdio.h > +#include < stdlib.h > +#include +#include +#include +//#include +#include //#include "ogrsf_frmts.h" + +#include +#include +#include "GeoOperator.h" + +#include +#include +#include "baseTool.h" + +#include // 多项式拟合 +#include /* 提供了 gammaq 函数 */ +#include /* 提供了向量结构*/ +#include +#include +#include + +#include // 包含SSE指令集头文件 +#include // 包含SSE2指令集头文件 +#include // 包含OpenMP头文件 +#include +#include +#include +#include + +QString longDoubleToQStringScientific(long double value) { + std::ostringstream stream; + + // 设置流的精度为35位有效数字,并使用科学计数法 + stream << std::scientific << std::setprecision(35) << value; + + // 将标准字符串转换为 QString + return QString::fromStdString(stream.str()); +} + +QString getCurrentTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + QString strTime = mbstr; + return strTime; +} + +QString getCurrentShortTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + QString strTime = mbstr; + return strTime; +} + +std::vector splitString(const QString& str, char delimiter) +{ + QStringList tokens = str.split(delimiter); + return convertQStringListToStdVector(tokens); +} + + +std::complex Cubic_Convolution_interpolation(double u, double v, Eigen::MatrixX> img) +{ + if (img.rows() != 4 || img.cols() != 4) { + throw std::exception("the size of img's block is not right"); + } + // 斤拷锟斤拷模锟斤拷 + Eigen::MatrixX> wrc(1, 4);// 使锟斤拷 complex 斤拷锟斤拷要原斤拷为锟剿伙拷取值 + Eigen::MatrixX> wcr(4, 1);// + for (int i = 0; i < 4; i++) { + wrc(0, i) = Cubic_kernel_weight(u + 1 - i); // u+1,u,u-1,u-2 + wcr(i, 0) = Cubic_kernel_weight(v + 1 - i); + } + + Eigen::MatrixX> interValue = wrc * img * wcr; + return interValue(0, 0); +} + +std::complex Cubic_kernel_weight(double s) +{ + s = abs(s); + if (s <= 1) { + return std::complex(1.5 * s * s * s - 2.5 * s * s + 1, 0); + } + else if (s <= 2) { + return std::complex(-0.5 * s * s * s + 2.5 * s * s - 4 * s + 2, 0); + } + else { + return std::complex(0, 0); + } +} + +/// +/// p11 p12 -- x +/// p0(u,v) +/// p21 p22 +/// | +/// y +/// p11(0,0) +/// p21(0,1) +/// P12(1,0) +/// p22(1,1) +/// +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22) +{ + return p11.ati * (1 - p0.lon) * (1 - p0.lat) + + p12.ati * p0.lon * (1 - p0.lat) + + p21.ati * (1 - p0.lon) * p0.lat + + p22.ati * p0.lon * p0.lat; +} + + + +bool onSegment(Point3 Pi, Point3 Pj, Point3 Q) +{ + if ((Q.x - Pi.x) * (Pj.y - Pi.y) == (Pj.x - Pi.x) * (Q.y - Pi.y) //叉乘 + //保证Q点坐标在pi,pj之间 + && std::min(Pi.x, Pj.x) <= Q.x && Q.x <= std::max(Pi.x, Pj.x) + && std::min(Pi.y, Pj.y) <= Q.y && Q.y <= std::max(Pi.y, Pj.y)) + return true; + else + return false; +} + +Point3 invBilinear(Point3 p, Point3 a, Point3 b, Point3 c, Point3 d) +{ + Point3 res; + + Point3 e = b - a; + Point3 f = d - a; + Point3 g = a - b + c - d; + Point3 h = p - a; + + double k2 = cross2d(g, f); + double k1 = cross2d(e, f) + cross2d(h, g); + double k0 = cross2d(h, e); + double u, v; + // if edges are parallel, this is a linear equation + if (abs(k2) < 0.001) + { + v = -k0 / k1; + u = (h.x - f.x * v) / (e.x + g.x * v); + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + // otherwise, it's a quadratic + else + { + float w = k1 * k1 - 4.0 * k0 * k2; + if (w < 0.0) { + // 可能在边界上 + if (onSegment(a, b, p)) { + Point3 tt = b - a; + Point3 ttpa = p - a; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = a.z + scater * tt.z; + return p; + } + else if (onSegment(b, c, p)) { + Point3 tt = c - b; + Point3 ttpa = p - b; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = b.z + scater * tt.z; + return p; + } + else if (onSegment(c, d, p)) { + Point3 tt = d - c; + Point3 ttpa = p - c; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = c.z + scater * tt.z; + return p; + } + else if (onSegment(d, a, p)) { + Point3 tt = a - d; + Point3 ttpa = p - d; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = d.z + scater * tt.z; + return p; + } + + return { -9999,-9999,-9999 }; + } + else { + w = sqrt(w); + + float ik2 = 0.5 / k2; + float v = (-k1 - w) * ik2; + float u = (h.x - f.x * v) / (e.x + g.x * v); + + if (u < 0.0 || u>1.0 || v < 0.0 || v>1.0) + { + v = (-k1 + w) * ik2; + u = (h.x - f.x * v) / (e.x + g.x * v); + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; +} + +double sind(double degree) +{ + return sin(degree * d2r); +} + +double cosd(double d) +{ + return cos(d * d2r); +} + + +std::string Convert(float Num) +{ + std::ostringstream oss; + oss << Num; + std::string str(oss.str()); + return str; +} + +QString JoinPath(const QString& path, const QString& filename) +{ + QDir dir(path); + + // Ensure the path ends with the appropriate separator + if (!QDir::isAbsolutePath(path)) + dir.makeAbsolute(); + + return dir.filePath(filename); +} +std::vector convertQStringListToStdVector(const QStringList& qStringList) +{ + std::vector stdVector; + + for (const QString& str : qStringList) { + stdVector.push_back(str); + } + + return stdVector; +}; + + +ErrorCode polyfit(const double* x, const double* y, int xyLength, int poly_n, std::vector& out_factor, double& out_chisq) { + /* + * x:自变量,视差 + * y:因变量,距离 + * xyLength: x、y长度 + * poly_n:拟合的阶次 + * out_factor:拟合的系数结果,从0阶到poly_n阶的系数 + * out_chisq:拟合曲线与数据点的优值函数最小值 ,χ2 检验 + */ + + gsl_matrix* XX = gsl_matrix_alloc(xyLength, poly_n + 1); + gsl_vector* c = gsl_vector_alloc(poly_n + 1); + gsl_matrix* cov = gsl_matrix_alloc(poly_n + 1, poly_n + 1); + gsl_vector* vY = gsl_vector_alloc(xyLength); + + for (size_t i = 0; i < xyLength; i++) + { + gsl_matrix_set(XX, i, 0, 1.0); + gsl_vector_set(vY, i, y[i]); + for (int j = 1; j <= poly_n; j++) + { + gsl_matrix_set(XX, i, j, pow(x[i], j)); + } + } + gsl_multifit_linear_workspace* workspace = gsl_multifit_linear_alloc(xyLength, poly_n + 1); + int r = gsl_multifit_linear(XX, vY, c, cov, &out_chisq, workspace); + gsl_multifit_linear_free(workspace); + out_factor.resize(c->size, 0); + for (size_t i = 0; i < c->size; ++i) + { + out_factor[i] = gsl_vector_get(c, i); + } + + gsl_vector_free(vY); + gsl_matrix_free(XX); + gsl_matrix_free(cov); + gsl_vector_free(c); + + return GSLState2ErrorCode(r); +} + +Point3 crossProduct(const Point3& a, const Point3& b) +{ + return Point3{ + a.y * b.z - a.z * b.y, // C_x + a.z * b.x - a.x * b.z, // C_y + a.x * b.y - a.y * b.x // C_z + }; +} + + + + +// 计算绕任意轴旋转的旋转矩阵 +Eigen::Matrix3d rotationMatrix(const Eigen::Vector3d& axis, double angle) { + // 确保旋转轴是单位向量 + Eigen::Vector3d u = axis.normalized(); + + double cos_theta = cos(angle); + double sin_theta = sin(angle); + + // 计算旋转矩阵 + Eigen::Matrix3d R; + R << + cos_theta + u.x() * u.x() * (1 - cos_theta), u.x()* u.y()* (1 - cos_theta) - u.z() * sin_theta, u.x()* u.z()* (1 - cos_theta) + u.y() * sin_theta, + u.y()* u.x()* (1 - cos_theta) + u.z() * sin_theta, cos_theta + u.y() * u.y() * (1 - cos_theta), u.y()* u.z()* (1 - cos_theta) - u.x() * sin_theta, + u.z()* u.x()* (1 - cos_theta) - u.y() * sin_theta, u.z()* u.y()* (1 - cos_theta) + u.x() * sin_theta, cos_theta + u.z() * u.z() * (1 - cos_theta); + + return R; +} + + + + + +long double convertToMilliseconds(const std::string& dateTimeStr) { + // 定义日期时间字符串 + std::string dateTimeString = dateTimeStr; + // 使用 Boost.Date_Time 解析日期时间字符串 + boost::posix_time::ptime dateTime = boost::posix_time::time_from_string(dateTimeString); + + // 将 ptime 转换为自 epoch (1970年1月1日) 以来的毫秒数 + boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); + boost::posix_time::time_duration duration = dateTime - epoch; + long double milliseconds = duration.total_milliseconds() / 1000.0; + return milliseconds; + +} + +long FindValueInStdVector(std::vector& list, double& findv) +{ + if (list.size() == 0) { + return -1; + } + else if (list.size() == 1) { + if (abs(list[0] - findv) < 1e-9) { + return 0; + } + else { + return -1; + } + } + else {} + + if (abs(list[0] - findv) < 1e-9) { + return 0; + } + else if (abs(list[list.size() - 1] - findv) < 1e-9) { + return list.size() - 1; + } + else if (list[0] > findv) { + return -1; + } + else if (list[list.size() - 1] < findv) { + return -1; + } + else {} + + + + long low = 0; + long high = list.size() - 1; + while (low <= high) { + long mid = (low + high) / 2; + if (abs(list[mid] - findv) < 1e-9) { + return mid; + } + else if (list[mid] < findv) { + low = mid + 1; + } + else if (list[mid] > findv) { + high = mid - 1; + } + else {} + } + return -1; +} + +long InsertValueInStdVector(std::vector& list, double insertValue, bool repeatValueInsert) +{ + if (list.size() == 0) { + list.insert(list.begin(), insertValue); + return 0; + } + else if (list.size() == 1) { + if (std::abs(list[0] - insertValue) < PRECISIONTOLERANCE) { + if (repeatValueInsert) { + list.push_back(insertValue); + return 1; + } + else { + return -1; + } + } + else if (insertValue > list[0]) { + list.push_back(insertValue); + return 1; + } + else if (insertValue < list[0]) { + list.push_back(insertValue); + return 0; + } + } + else { + long low = 0; + long high = list.size() - 1; + long mid = -1; + // 处理边界 + if (list[high] <= insertValue) + { + if (std::abs(list[high] - insertValue) < PRECISIONTOLERANCE) { + if (repeatValueInsert) { + list.push_back(insertValue); + } + else {} + } + else { + list.push_back(insertValue); + } + return list.size() - 1; + } + + if (list[low] >= insertValue) { + + if (std::abs(list[low] - insertValue) < PRECISIONTOLERANCE) { + if (repeatValueInsert) { + list.insert(list.begin(), insertValue); + } + else {} + } + else { + list.insert(list.begin(), insertValue); + } + return 0; + } + // low 1) { + mid = (low + high) / 2; + if (std::abs(list[mid] - insertValue) < PRECISIONTOLERANCE) { + if (repeatValueInsert) { + list.insert(list.begin() + mid, insertValue); + } + return mid; + } + else if (insertValue < list[mid]) { + high = mid; + } + else if (list[mid] < insertValue) { + low = mid; + } + + } + if (list[low] <= insertValue && insertValue <= list[high]) + { + + if (std::abs(list[high] - insertValue) < PRECISIONTOLERANCE) { + if (repeatValueInsert) { + list.insert(list.begin() + high, insertValue); + } + else {} + } + else { + list.insert(list.begin() + high, insertValue); + } + return low; + } + else { + return -1; + } + } + return -1; +} + +long FindValueInStdVectorLast(std::vector& list, double& insertValue) +{ + if (list.size() == 0 || list.size() == 1) { + return -1; + } + else { + long low = 0; + long high = list.size() - 1; + long mid = -1; + // 处理边界 + if (list[high]+ PRECISIONTOLERANCE < insertValue) + { + return -1; + } + else if (std::abs(list[high] - insertValue) < PRECISIONTOLERANCE) + { + return high; + } + else if (list[low] > insertValue) { + return -1; + } + else if (std::abs(list[low] - insertValue) < PRECISIONTOLERANCE) { + return low; + } + else {} + // low 1) { + mid = (low + high) / 2; + if (insertValue < list[mid]) { + high = mid; + } + else if (list[mid] < insertValue) { + low = mid; + } + else {// insertValue==list[mid] , list[mid]===insertValue + return mid;// + } + } + if (list[low] <= insertValue && insertValue <= list[high]) + { + return low; + } + else { + return -1; + } + } + return -1; +} + + +ErrorCode polynomial_fit(const std::vector& x, const std::vector& y, int degree, std::vector& out_factor, double& out_chisq) { + int xyLength = x.size(); + double* xdata = new double[xyLength]; + double* ydata = new double[xyLength]; + for (long i = 0; i < xyLength; i++) { + xdata[i] = x[i]; + ydata[i] = y[i]; + } + ErrorCode state = polyfit(xdata, ydata, xyLength, degree, out_factor, out_chisq); + + delete[] xdata; + delete[] ydata; // 释放内存 + return state; +} + +QVector SatellitePos2SatelliteAntPos(QVector poses) +{ + QVector antposes(poses.count()); + for (long i = 0; i < poses.count(); i++) { + antposes[i].time = poses[i].time; + antposes[i].Px = poses[i].Px; + antposes[i].Py = poses[i].Py; + antposes[i].Pz = poses[i].Pz; + antposes[i].Vx = poses[i].Vx; + antposes[i].Vy = poses[i].Vy; + antposes[i].Vz = poses[i].Vz; + } + return antposes; +} + +QVector SatelliteAntPos2SatellitePos(QVector poses) +{ + QVector antposes(poses.count()); + for (long i = 0; i < poses.count(); i++) { + antposes[i].time = poses[i].time; + antposes[i].Px = poses[i].Px; + antposes[i].Py = poses[i].Py; + antposes[i].Pz = poses[i].Pz; + antposes[i].Vx = poses[i].Vx; + antposes[i].Vy = poses[i].Vy; + antposes[i].Vz = poses[i].Vz; + } + return antposes; +} + + +QString getDebugDataPath(QString filename) +{ + QString folderName = "debugdata"; + QString appDir = QCoreApplication::applicationDirPath(); + QString folderpath = JoinPath(appDir, folderName); + if (!QDir(folderpath).exists()) { + QDir(appDir).mkdir(folderName); + } + QString datapath = JoinPath(folderpath, filename); + QFile datafile(datapath); + if (datafile.exists()) { + datafile.remove(); + } + return datapath; +} + + +std::vector split(const std::string& str, char delimiter) { + std::vector tokens; + std::string token; + std::istringstream tokenStream(str); + + while (std::getline(tokenStream, token, delimiter)) { + tokens.push_back(token); + } + + return tokens; +} + + +Eigen::VectorXd linspace(double start, double stop, int num) { + Eigen::VectorXd result(num); + + double step = (stop - start) / (num - 1); // 计算步长 + for (int i = 0; i < num; ++i) { + result[i] = start + i * step; // 生成等间距数值 + } + + return result; +} + +void initializeMatrixWithSSE2(Eigen::MatrixXd& mat, const double* data, long rowcount, long colcount) { + __m128d zero = _mm_setzero_pd(); + +#pragma omp parallel for + for (long i = 0; i < rowcount; ++i) { + for (long j = 0; j < colcount; j += 2) { // 每次处理2个double + if (j + 2 <= colcount) { + __m128d src = _mm_loadu_pd(&data[i * colcount + j]); + _mm_storeu_pd(&mat(i, j), src); + } + else { + // 处理剩余部分 + for (long k = j; k < colcount; ++k) { + mat(i, k) = data[i * colcount + k]; + } + } + } + } +} + +void initializeMatrixWithSSE2(Eigen::MatrixXf& mat, const float* data, long rowcount, long colcount) { + __m128 zero = _mm_setzero_ps(); + +#pragma omp parallel for + for (long i = 0; i < rowcount; ++i) { + for (long j = 0; j < colcount; j += 4) { // 每次处理4个float + if (j + 4 <= colcount) { + __m128 src = _mm_loadu_ps(&data[i * colcount + j]); + _mm_storeu_ps(&mat(i, j), src); + } + else { + // 处理剩余部分 + for (long k = j; k < colcount; ++k) { + mat(i, k) = data[i * colcount + k]; + } + } + } + } +} + +Eigen::MatrixXd BASECONSTVARIABLEAPI MuhlemanSigmaArray(Eigen::MatrixXd& eta_deg) +{ + Eigen::MatrixXd sigma = Eigen::MatrixXd::Zero(eta_deg.rows(), eta_deg.cols()); + for (long i = 0; i < sigma.rows(); i++) { + for (long j = 0; j < sigma.cols(); j++) { + sigma(i,j) = calculate_MuhlemanSigma(eta_deg(i, j)); + } + } + return sigma; +} + +Eigen::MatrixXd BASECONSTVARIABLEAPI dB2Amp(Eigen::MatrixXd& sigma0) +{ + Eigen::MatrixXd sigma = Eigen::MatrixXd::Zero(sigma0.rows(), sigma0.cols()); + for (long i = 0; i < sigma.rows(); i++) { + for (long j = 0; j < sigma.cols(); j++) { + sigma(i, j) =std::pow(10.0, sigma0(i,j)/20.0); + } + } + return sigma; +} + + + +QDateTime parseCustomDateTime(const QString& dateTimeStr) { + // 手动解析日期时间字符串 + int year = dateTimeStr.left(4).toInt(); + int month = dateTimeStr.mid(5, 2).toInt(); + int day = dateTimeStr.mid(8, 2).toInt(); + int hour = dateTimeStr.mid(11, 2).toInt(); + int minute = dateTimeStr.mid(14, 2).toInt(); + int second = dateTimeStr.mid(17, 2).toInt(); + int msec = dateTimeStr.mid(20, 6).toInt(); // 只取毫秒的前三位,因为QDateTime支持到毫秒 + + // 创建 QDate 和 QTime 对象 + QDate date(year, month, day); + QTime time(hour, minute, second, msec ); // 转换为微秒,但QTime只支持毫秒精度 + + // 构造 QDateTime 对象 + QDateTime result(date, time); + + return result; +} + + +bool isLeapYear(int year) { + return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); +} + +int daysInMonth(int year, int month) { + if (month == 2) return isLeapYear(year) ? 29 : 28; + else if (month == 4 || month == 6 || month == 9 || month == 11) return 30; + else return 31; +} + + +TimestampMicroseconds parseAndConvert( std::string dateTimeStr) { + // 解析年、月、日、时、分、秒和微秒 + int year = std::stoi(dateTimeStr.substr(0, 4)); + int month = std::stoi(dateTimeStr.substr(5, 2)); + int day = std::stoi(dateTimeStr.substr(8, 2)); + int hour = std::stoi(dateTimeStr.substr(11, 2)); + int minute = std::stoi(dateTimeStr.substr(14, 2)); + int second = std::stoi(dateTimeStr.substr(17, 2)); + int microsec = std::stoi(dateTimeStr.substr(20, 6)); + + // 计算从1970年至目标年份前一年的总天数 + long long totalDays = 0; + for (int y = 1970; y < year; ++y) { + totalDays += isLeapYear(y) ? 366 : 365; + } + + // 加上目标年份从1月到上一个月的天数 + for (int m = 1; m < month; ++m) { + totalDays += daysInMonth(year, m); + } + + // 加上本月的天数 + totalDays += day - 1; + + // 转换为总秒数,再加上小时、分钟、秒 + long long totalSeconds = totalDays * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; + + // 转换为毫秒和微秒 + long long msecsSinceEpoch = totalSeconds * 1000 + microsec / 1000; + int microseconds = microsec % 1000; + + return { msecsSinceEpoch, microseconds }; +} + + diff --git a/BaseTool/BaseTool.h b/BaseTool/BaseTool.h new file mode 100644 index 0000000..6ad57ff --- /dev/null +++ b/BaseTool/BaseTool.h @@ -0,0 +1,226 @@ +#pragma once +#ifndef BASETOOL_H +#define BASETOOL_H +#include "BaseConstVariable.h" + +/// +/// 基本类、基本函数 +/// + + +// //#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GeoOperator.h" +#include +#include +#include +#include +#include "LogInfoCls.h" +#include +#include +#include +#include +#include +#include + +///////////////////////////////////// 基础数学函数 ///////////////////////////////////////////////////////////// + + +QString longDoubleToQStringScientific(long double value); + +///////////////////////////////////// 运行时间打印 ///////////////////////////////////////////////////////////// + + +QString BASECONSTVARIABLEAPI getCurrentTimeString(); +QString BASECONSTVARIABLEAPI getCurrentShortTimeString(); + +std::vector BASECONSTVARIABLEAPI splitString(const QString& str, char delimiter); +std::vector BASECONSTVARIABLEAPI convertQStringListToStdVector(const QStringList& qStringList); +/////////////////////////////// 基本图像类 结束 +///////////////////////////////////////////////////////////// + +std::string BASECONSTVARIABLEAPI Convert(float Num); +QString BASECONSTVARIABLEAPI JoinPath(const QString& path, const QString& filename); + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + +////////////////////////////// 插值 //////////////////////////////////////////// + +std::complex BASECONSTVARIABLEAPI Cubic_Convolution_interpolation(double u, double v, + Eigen::MatrixX> img); + +std::complex BASECONSTVARIABLEAPI Cubic_kernel_weight(double s); + +double BASECONSTVARIABLEAPI Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12,Landpoint p22); + +bool BASECONSTVARIABLEAPI onSegment(Point3 Pi, Point3 Pj, Point3 Q); + +Point3 BASECONSTVARIABLEAPI invBilinear(Point3 p, Point3 a, Point3 b, Point3 c, Point3 d); + +// +// WGS84 到J2000 坐标系的变换 +// 参考网址:https://blog.csdn.net/hit5067/article/details/116894616 +// 资料网址:http://celestrak.org/spacedata/ +// 参数文件: +// a. Earth Orientation Parameter 文件: http://celestrak.org/spacedata/EOP-Last5Years.csv +// b. Space Weather Data 文件: http://celestrak.org/spacedata/SW-Last5Years.csv +// 备注:上述文件是自2017年-五年内 +/** +在wgs84 坐标系转到J2000 坐标系 主要 涉及到坐标的相互转换。一般给定的WGS坐标为 给定时刻的 t ,BLH +转换步骤: +step 1: WGS 84 转换到协议地球坐标系 +step 2: 协议地球坐标系 转换为瞬时地球坐标系 +step 3: 瞬时地球坐标系 转换为 瞬时真天球坐标系 +step 4: 瞬时真天球坐标系 转到瞬时平天球 坐标系 +step 5: 瞬时平天球坐标系转换为协议天球坐标系(J2000) +**/ + +double BASECONSTVARIABLEAPI sind(double degree); + +double BASECONSTVARIABLEAPI cosd(double d); + +// 插值 +ErrorCode BASECONSTVARIABLEAPI polyfit(const double* x, const double* y, int xyLength, int poly_n, std::vector& out_factor, double& out_chisq); + +// 叉乘 +Point3 BASECONSTVARIABLEAPI crossProduct(const Point3& a, const Point3& b); + +Eigen::Matrix3d BASECONSTVARIABLEAPI rotationMatrix(const Eigen::Vector3d& axis, double angle); + +long double BASECONSTVARIABLEAPI convertToMilliseconds(const std::string& dateTimeStr); + +QDateTime BASECONSTVARIABLEAPI parseCustomDateTime(const QString& dateTimeStr); +/// +/// list 应该是按照从小到大的顺序排好 +/// +/// +/// +/// +long BASECONSTVARIABLEAPI FindValueInStdVector(std::vector& list,double& findv); + +long BASECONSTVARIABLEAPI InsertValueInStdVector(std::vector& list, double insertValue, bool repeatValueInsert = false); + +long BASECONSTVARIABLEAPI FindValueInStdVectorLast(std::vector& list, double& findv); + +ErrorCode BASECONSTVARIABLEAPI polynomial_fit(const std::vector& x, const std::vector& y, int degree, std::vector& out_factor, double& out_chisq); + +QVector BASECONSTVARIABLEAPI SatellitePos2SatelliteAntPos(QVector poses); + +QVector BASECONSTVARIABLEAPI SatelliteAntPos2SatellitePos(QVector poses); + +QString BASECONSTVARIABLEAPI getDebugDataPath(QString filename); +std::vector BASECONSTVARIABLEAPI split(const std::string& str, char delimiter); +Eigen::VectorXd BASECONSTVARIABLEAPI linspace(double start, double stop, int num); + + +/** 内存赋值 ***********************************************************************************************************/ +void initializeMatrixWithSSE2(Eigen::MatrixXd& mat, const double* data, long rowcount, long colcount); +void initializeMatrixWithSSE2(Eigen::MatrixXf& mat, const float* data, long rowcount, long colcount); + +Eigen::MatrixXd BASECONSTVARIABLEAPI MuhlemanSigmaArray(Eigen::MatrixXd& eta_deg); +Eigen::MatrixXd BASECONSTVARIABLEAPI dB2Amp(Eigen::MatrixXd& sigma0); + + +struct TimestampMicroseconds { + boost::int64_t msecsSinceEpoch; // 自1970-01-01T00:00:00 UTC以来的毫秒数 + int microseconds; // 额外的微秒(精确到微秒) +}; + + +bool BASECONSTVARIABLEAPI isLeapYear(int year); +int BASECONSTVARIABLEAPI daysInMonth(int year, int month); + +TimestampMicroseconds BASECONSTVARIABLEAPI parseAndConvert( std::string dateTimeStr); + + +/** 模板函数类 ***********************************************************************************************************/ + +inline double calculate_MuhlemanSigma(double eta_deg) { + const double eta_rad = eta_deg * M_PI / 180.0; // 角度转弧度 + + const double cos_eta = std::cos(eta_rad); + const double sin_eta = std::sin(eta_rad); + + const double denominator = sin_eta + 0.1 * cos_eta; + + return (0.0133 * cos_eta) / std::pow(denominator, 3); +}; + + + +template +inline void memsetInitArray(std::shared_ptr ptr, long arrcount, T ti) { + for (long i = 0; i < arrcount; i++) { + ptr.get()[i] = ti; + } +}; + +template +inline void memcpyArray(std::shared_ptr srct, std::shared_ptr dest, long arrcount) { + for (long i = 0; i < arrcount; i++) { + dest.get()[i] = srct.get()[i]; + } +}; + + +template +inline void minValueInArr(T* ptr, long arrcount, T& minvalue) { + + if (arrcount == 0)return; + + minvalue = ptr[0]; + for (long i = 0; i < arrcount; i++) { + if (minvalue > ptr[i]) { + minvalue = ptr[i]; + } + } +}; + +template +inline void maxValueInArr(T* ptr, long arrcount, T& maxvalue) { + + if (arrcount == 0)return; + + maxvalue = ptr[0]; + for (long i = 0; i < arrcount; i++) { + if (maxvalue < ptr[i]) { + maxvalue = ptr[i]; + } + } +}; + + + +/** 常用SAR工具 ***********************************************************************************************************/ + + +template +inline T complexAbs(std::complex ccdata) { + return T(sqrt(pow(ccdata.real(), 2) + pow(ccdata.imag(), 2))); +}; + +template +inline void complex2dB(std::complex* ccdata, T* outdata, long long count) { + + for (long long i = 0; i < count; i++) { + outdata[i] = 20 * log10(complexAbs(ccdata[i])); + } + +}; + + + +#endif \ No newline at end of file diff --git a/BaseTool/EchoDataFormat.cpp b/BaseTool/EchoDataFormat.cpp new file mode 100644 index 0000000..bc50ed5 --- /dev/null +++ b/BaseTool/EchoDataFormat.cpp @@ -0,0 +1,822 @@ +#include "stdafx.h" +#include "EchoDataFormat.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "ImageOperatorBase.h" + + +std::shared_ptr CreatePluseAntPosArr(long pluseCount) +{ + return std::shared_ptr(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 echoData = std::make_shared(1, data.plusePoints); + echoData->real() = echoData_real.array(); + echoData->imag() = echoData_imag.array(); + return ErrorCode::SUCCESS; +} + +std::shared_ptr CreatePluseDataArr(long pluseCount) +{ + return std::shared_ptr(new PluseData[pluseCount],delArrPtr); +} + +std::shared_ptr> CreateEchoData(long plusePoints) +{ + return std::shared_ptr>(new std::complex[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; + } + return ErrorCode::SUCCESS; +} + +QString EchoL0Dataset::getxmlName() +{ + return xmlname; +} + +QString EchoL0Dataset::getGPSPointFilename() +{ + return GPSPointFilename; +} + +QString EchoL0Dataset::getEchoDataFilename() +{ + return GPSPointFilePath; +} + +QString EchoL0Dataset::getGPSPointFilePath() +{ + return this->GPSPointFilePath; +} + +QString EchoL0Dataset::getEchoDataFilePath() +{ + return this->echoDataFilePath; +} + +void EchoL0Dataset::initEchoArr(std::complex 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> 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 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 EchoL0Dataset::getAntPosVelc() +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + long prfcount = this->PluseCount; + std::shared_ptr antposlist= SatelliteAntPosOperator::readAntPosFile(this->GPSPointFilePath, prfcount); + + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // + return antposlist; +} + +std::shared_ptr EchoL0Dataset::getAntPos() +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + // ȡļ + std::shared_ptr 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 temp = nullptr; + + if (gdal_datatype == GDT_Float64) { + temp=std::shared_ptr(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> EchoL0Dataset::getEchoArr(long startPRF, long& PRFLen) +{ + if (!(startPRF < this->PluseCount)) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE))<PluseCount; + return nullptr; + } + else {} + + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + std::shared_ptr 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(); + + PRFLen = (PRFLen + startPRF) < height ? PRFLen : height - startPRF; + + std::shared_ptr> 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>(new std::complex[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::vector> EchoL0Dataset::getEchoArrVector(long startPRF, long& PRFLen) { + if (!(startPRF < this->PluseCount)) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE)) << startPRF << " " << this->PluseCount; + return std::vector>(0); + } + else {} + + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + std::shared_ptr 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 std::vector>(0); + } + else {} + long width = rasterDataset->GetRasterXSize(); + long height = rasterDataset->GetRasterYSize(); + long band_num = rasterDataset->GetRasterCount(); + + PRFLen = (PRFLen + startPRF) < height ? PRFLen : height - startPRF; + + std::vector> tempArr(size_t(PRFLen) * width); + if (height != this->PluseCount || width != this->PlusePoints) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR)); + } + else { + if (gdal_datatype == GDT_CFloat64) { + std::shared_ptr> temp(new std::complex[PRFLen * width], delArrPtr); + poBand->RasterIO(GF_Read, 0, startPRF, width, PRFLen, temp.get(), width, PRFLen, GDT_CFloat64, 0, 0); + GDALFlushCache((GDALDatasetH)rasterDataset.get()); + + + for (long i = 0; i < PRFLen; i++){ + for (long j = 0; j < width; j++){ + tempArr[i * width + j] = temp.get()[i * width + j]; + } + } + + } + else { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR)); + } + } + + rasterDataset.reset(); + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // + return tempArr; +} + + +std::shared_ptr> EchoL0Dataset::getEchoArr() +{ + return this->getEchoArr(0,this->PluseCount); +} + +ErrorCode EchoL0Dataset::saveAntPos(std::shared_ptr ptr) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + // ȡļ + std::shared_ptr 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> 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; + GDALDestroy(); + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // + + return ErrorCode::SUCCESS; +} + +std::shared_ptr SatelliteAntPosOperator::readAntPosFile(QString filepath, long& count) +{ + gdalImage antimg(filepath); + long rowcount = count; + long colcount = 19; + std::shared_ptr antlist = readDataArr(antimg, 0, 0, rowcount, colcount, 1, GDALREADARRCOPYMETHOD::VARIABLEMETHOD); + std::shared_ptr antpos(new SatelliteAntPos[rowcount], delArrPtr); + for (long i = 0; i < rowcount; i++) { + antpos.get()[i].time = antlist.get()[i * 19 + 0]; + antpos.get()[i].Px = antlist.get()[i * 19 + 1]; + antpos.get()[i].Py = antlist.get()[i * 19 + 2]; + antpos.get()[i].Pz = antlist.get()[i * 19 + 3]; + antpos.get()[i].Vx = antlist.get()[i * 19 + 4]; + antpos.get()[i].Vy = antlist.get()[i * 19 + 5]; + antpos.get()[i].Vz = antlist.get()[i * 19 + 6]; //7 + antpos.get()[i].AntDirectX = antlist.get()[i * 19 + 7]; + antpos.get()[i].AntDirectY = antlist.get()[i * 19 + 8]; + antpos.get()[i].AntDirectZ = antlist.get()[i * 19 + 9]; + antpos.get()[i].AVx = antlist.get()[i * 19 + 10]; + antpos.get()[i].AVy = antlist.get()[i * 19 + 11]; + antpos.get()[i].AVz = antlist.get()[i * 19 + 12]; + antpos.get()[i].ZeroAntDiectX = antlist.get()[i * 19 + 13]; + antpos.get()[i].ZeroAntDiectY = antlist.get()[i * 19 + 14]; + antpos.get()[i].ZeroAntDiectZ = antlist.get()[i * 19 + 15]; + antpos.get()[i].lon = antlist.get()[i * 19 + 16]; + antpos.get()[i].lat = antlist.get()[i * 19 + 17]; + antpos.get()[i].ati = antlist.get()[i * 19 + 18]; // 19 + } + return antpos; +} + +void SatelliteAntPosOperator::writeAntPosFile(QString filepath, std::shared_ptr data, const long count) +{ + gdalImage antimg=CreategdalImageDouble(filepath,count,19,1,true,true); + long rowcount = count; + long colcount = 19; + std::shared_ptr antpos(new double[rowcount*19], delArrPtr); + for (long i = 0; i < colcount; i++) { + antpos.get()[i * 19 + 1] = data.get()[i].time; + antpos.get()[i * 19 + 2] = data.get()[i].Px; + antpos.get()[i * 19 + 3] = data.get()[i].Py; + antpos.get()[i * 19 + 4] = data.get()[i].Pz; + antpos.get()[i * 19 + 5] = data.get()[i].Vx; + antpos.get()[i * 19 + 6] = data.get()[i].Vy; + antpos.get()[i * 19 + 7] = data.get()[i].Vz; + antpos.get()[i * 19 + 8] = data.get()[i].AntDirectX; + antpos.get()[i * 19 + 9] = data.get()[i].AntDirectY; + antpos.get()[i * 19 + 10] = data.get()[i].AntDirectZ; + antpos.get()[i * 19 + 11] = data.get()[i].AVx; + antpos.get()[i * 19 + 12] = data.get()[i].AVy; + antpos.get()[i * 19 + 13] = data.get()[i].AVz; + antpos.get()[i * 19 + 14] = data.get()[i].ZeroAntDiectX; + antpos.get()[i * 19 + 15] = data.get()[i].ZeroAntDiectY; + antpos.get()[i * 19 + 16] = data.get()[i].ZeroAntDiectZ; + antpos.get()[i * 19 + 17] = data.get()[i].lon; + antpos.get()[i * 19 + 18] = data.get()[i].lat; + antpos.get()[i * 19 + 19] = data.get()[i].ati; + } + antimg.saveImage(antpos, 0,0,rowcount, colcount, 1); + + return ; + + + +} diff --git a/BaseTool/EchoDataFormat.h b/BaseTool/EchoDataFormat.h new file mode 100644 index 0000000..ec2f685 --- /dev/null +++ b/BaseTool/EchoDataFormat.h @@ -0,0 +1,225 @@ +#pragma once +/*****************************************************************//** + * \file EchoDataFormat.h + * \brief 洢еĸƷݸʽҪزݸʽݿ + * + * \author 30453 + * \date October 2024 + *********************************************************************/ + + +#include "BaseConstVariable.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "BaseTool.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for CPLMalloc() + +//======================================================================== +// زʽ +// file type: +// PRFCOUNT +// PRFPOINT +// nearRange +// farRange +// PRF1,time,Px,Py,Pz,Vx,Vy,Vz +// PRF2,time,Px,Py,Pz,Vx,Vy,Vz +// ------------------ ļ -------------------------------------- +// PRF1,time,Px,Py,Pz,Vx,Vy,Vz,PRFPOINT,RealData,imagData +// PRF2,time,Px,Py,Pz,Vx,Vy,Vz,PRFPOINT,RealData,imagData +// -------------------------------------------------------------- +// עBp˳ֻǹעλãĬϰĽ˳֯ +//======================================================================== + +// õĻزļʽ + +/// +/// ز-- +/// +struct PluseData { + long id; // PRF id + double time;// ʱ + double Px; // + double Py; + double Pz; + double Vx; // ٶ + double Vy; + double Vz; + long plusePoints; // + std::shared_ptr> echoData; // ز +}; + +long BASECONSTVARIABLEAPI getPluseDataSize(PluseData& pluseData); +ErrorCode BASECONSTVARIABLEAPI getPluseDataFromBuffer(char* buffer, PluseData& data); +std::shared_ptr BASECONSTVARIABLEAPI CreatePluseDataArr(long pluseCount); +std::shared_ptr> BASECONSTVARIABLEAPI CreateEchoData(long plusePoints); + + + +/// +/// ̬ +/// +struct PluseAntPos { + long id; // PRF id + double time;// ʱ + double Px; // + double Py; + double Pz; + double Vx; // ٶ + double Vy; + double Vz; +}; +std::shared_ptr BASECONSTVARIABLEAPI CreatePluseAntPosArr(long pluseCount); + + +class BASECONSTVARIABLEAPI SatelliteAntPosOperator { +public: + static std::shared_ptr readAntPosFile(QString filepath,long& count); + static void writeAntPosFile(QString filepath, std::shared_ptr< SatelliteAntPos> data,const long count); + + +}; + + + + + + + + + + + + + + + + + + +// L0 +class BASECONSTVARIABLEAPI EchoL0Dataset { + +public: + EchoL0Dataset(); + ~EchoL0Dataset(); + + +public: + ErrorCode OpenOrNew(QString folder, QString filename,long PluseCount,long PlusePoints); + ErrorCode Open(QString xmlfilepath); + ErrorCode Open(QString folder, QString filename); + QString getxmlName(); + QString getGPSPointFilename(); + QString getEchoDataFilename(); + QString getGPSPointFilePath(); + QString getEchoDataFilePath(); + void initEchoArr(std::complex init0); + + +private: // Ʒ + QString folder; + QString filename; + QString xmlname; + QString GPSPointFilename; + QString echoDataFilename; + // + QString xmlFilePath; + QString GPSPointFilePath; + QString echoDataFilePath; + + + +public: // ļ + // Getter Setter + long getPluseCount() ; + void setPluseCount(long pulseCount); + + long getPlusePoints() ; + void setPlusePoints(long pulsePoints); + + double getNearRange() ; + void setNearRange(double nearRange); + + double getFarRange() ; + void setFarRange(double farRange); + + double getCenterFreq() ; + void setCenterFreq(double freq); + + double getFs() ; + void setFs(double samplingFreq); + + QString getSimulationTaskName() ; + void setSimulationTaskName(const QString& taskName); + + double getCenterAngle(); + void setCenterAngle(double angle); + + QString getLookSide(); + void setLookSide(QString lookside); + + double getBandwidth(); + void setBandwidth(double Inbandwidth); + + SatelliteAntPos getSatelliteAntPos(long plusePRFID); + + void setRefPhaseRange(double refRange); + double getRefPhaseRange(); + // ӡϢijԱ + void printInfo() ; + +private: // ز + long PluseCount; + long PlusePoints; + double NearRange; + double FarRange; + double centerFreq; // Ƶ + double Fs; // ЧƵ + QString simulationTaskName; + + double CenterAngle; + QString LookSide; + double refPhaseRange; + double bandwidth; + +public: // д XML ĺ + void saveToXml(); + ErrorCode loadFromXml(); + +public: + // ȡļ + std::shared_ptr< SatelliteAntPos> getAntPosVelc(); + std::shared_ptr getAntPos(); + std::shared_ptr> getEchoArr(long startPRF, long& PRFLen); + std::shared_ptr> getEchoArr(); + std::vector> getEchoArrVector(long startPRF, long& PRFLen); + //ļ + ErrorCode saveAntPos(std::shared_ptr ptr); // עΣգдǰǷȷ + ErrorCode saveEchoArr(std::shared_ptr> echoPtr, long startPRF, long PRFLen); + +}; + + + + diff --git a/BaseTool/FileOperator.cpp b/BaseTool/FileOperator.cpp new file mode 100644 index 0000000..1d543cc --- /dev/null +++ b/BaseTool/FileOperator.cpp @@ -0,0 +1,322 @@ +#include "stdafx.h" +#include "FileOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + + +QString addMaskToFileName(const QString& filePath,QString _zzname) { + // 获取文件路径和文件名 + QFileInfo fileInfo(filePath); + + // 获取文件名和扩展名 + QString baseName = fileInfo.baseName(); // 不包含扩展名的文件名 + QString extension = fileInfo.suffix(); // 文件扩展名(例如 ".txt", ".jpg") + + // 拼接新的文件名 + QString newFileName = baseName + _zzname; // 在文件名中增加 "_mask" + if (!extension.isEmpty()) { + newFileName += "." + extension; // 如果有扩展名,添加扩展名 + } + + // 返回新的文件路径 + QString newFilePath = fileInfo.path() + "/" + newFileName; + return newFilePath; +} + + +std::vector getFilelist(const QString& folderpath, const QString& filenameExtension, int (*logfun)(QString logtext, int value)) +{ + QString filenameExtensionStr = filenameExtension; + filenameExtensionStr = filenameExtensionStr.remove(0, 1); + std::vector filenames(0); + if (isExists(folderpath) && isDirectory(folderpath)) { + QDir directory(folderpath); + if (directory.exists() && directory.isReadable()) { + QFileInfoList fileList = directory.entryInfoList(QDir::Files | QDir::NoDotAndDotDot); + for (const QFileInfo& fileInfo : fileList) { +// qDebug() << fileInfo.filePath() + "\nExtension: (" + filenameExtensionStr + ", " + fileInfo.suffix() + ")"; + if (filenameExtensionStr == u8"*" || filenameExtensionStr == fileInfo.suffix()) { + filenames.push_back(fileInfo.filePath()); + } + if (logfun) { + logfun(fileInfo.filePath() + "\nExtension: (" + filenameExtensionStr + ", " + fileInfo.suffix() + ")", 4); + } + } + } + else { + qWarning() << "Folder does not exist or is not readable: " << folderpath; + } + return filenames; + } + else { + return std::vector(0); + } + +} + +QString getParantFolderNameFromPath(const QString& path) +{ + QDir directory(path); + directory.cdUp(); + QString parentPath = directory.absolutePath(); + return directory.dirName(); +} + +QString getParantFromPath(const QString& path) +{ + //qDebug() << path; + QDir directory(path); + directory.cdUp(); + QString parentPath = directory.absolutePath(); + //qDebug() << parentPath; + return parentPath; +} + +QString getFileNameFromPath(const QString& path) +{ + QFileInfo fileInfo(path); + return fileInfo.fileName(); +} + +QString getFileNameWidthoutExtend(QString path) +{ + QFileInfo fileInfo(path); + QString fileNameWithoutExtension = fileInfo.completeBaseName(); // 获取无后缀文件名 + qDebug() << u8"File name without extension: " << fileNameWithoutExtension; + return fileNameWithoutExtension; +} + +QString BASECONSTVARIABLEAPI getFileExtension(QString path) +{ + QFileInfo fileInfo(path); + QString fileExtension = fileInfo.suffix(); // 获取无后缀文件名 + return fileExtension; +} + +bool isDirectory(const QString& path) +{ + QFileInfo fileinfo(path); + return fileinfo.isDir(); +} + +bool isExists(const QString& path) +{ + QFileInfo fileinfo(path); + return fileinfo.exists(); +} + +bool isFile(const QString& path) +{ + QFileInfo fileinfo(path); + return fileinfo.isFile(); +} + +int write_binfile(char* filepath, char* data, size_t data_len) +{ + FILE* pd = fopen(filepath, "w"); + if (NULL == pd) { + return 2; + } + //数据块首地址: "&a",元素大小: "sizeof(unsigned __int8)", 元素个数: "10", 文件指针:"pd" + fwrite(data, sizeof(char), data_len, pd); + fclose(pd); + return -1; +} + + char* read_textfile(char* text_path, int* length) +{ + char* data = NULL; + FILE* fp1 = fopen(text_path, "r"); + if (fp1 == NULL) { + return NULL; + } + else {} + // 读取文件 + fseek(fp1, 0, SEEK_END); + int data_length = ftell(fp1); + data = (char*)malloc((data_length + 1) * sizeof(char)); + rewind(fp1); + if (data_length == fread(data, sizeof(char), data_length, fp1)) { + data[data_length] = '\0'; // 文件尾 + } + else { + free(data); + fclose(fp1); + return NULL; + } + fclose(fp1); + *length = data_length + 1; + return data; +} + +bool exists_test(const QString& name) +{ + return isExists(name); +} + +size_t fsize(FILE* fp) +{ + size_t n; + fpos_t fpos; // 当前位置 + fgetpos(fp, &fpos); // 获取当前位置 + fseek(fp, 0, SEEK_END); + n = ftell(fp); + fsetpos(fp, &fpos); // 恢复之前的位置 + return n; +} + + +void removeFile(const QString& filePath) +{ + QFile file(filePath); + + if (file.exists()) { + if (file.remove()) { + qDebug() << "File removed successfully: " << filePath; + } + else { + qWarning() << "Failed to remove file: " << filePath; + } + } + else { + qDebug() << "File does not exist: " << filePath; + } +} + +unsigned long convertToULong(const QString& input) { + bool ok; // Used to check if the conversion was successful + unsigned long result = input.toULong(&ok); + + if (!ok) { + qWarning() << "Conversion to unsigned long failed for input: " << input; + } + + return result; +} + +void copyFile(const QString& sourcePath, const QString& destinationPath) { + QFile sourceFile(sourcePath); + QFile destinationFile(destinationPath); + qDebug() << QString("copy file ready !! from ") + sourcePath+" to "+destinationPath ; + if (sourceFile.exists()) { + if (sourceFile.copy(destinationPath)) { + qDebug() << QString("copy file sucessfully !! from ") + sourcePath+" to "+destinationPath ; + // 复制成功 + //QMessageBox::information(nullptr, u8"成功", u8"文件复制成功"); + } + else { + // 复制失败 + if(sourceFile.exists()){ + QMessageBox::critical(nullptr, QObject::tr("error"), QObject::tr("The file already exists !!")); + } + else{ + QMessageBox::critical(nullptr, QObject::tr("error"), QObject::tr("file copy error")); + } + } + } + else { + // 源文件不存在 + QMessageBox::warning(nullptr, QObject::tr("warning"), QObject::tr("Source file not found")); + } +} + + + + +bool copyAndReplaceFile(const QString& sourceFilePath, const QString& destinationFilePath) { + // 检查源文件是否存在 + if (!QFile::exists(sourceFilePath)) { + qDebug() << "Source file does not exist:" << sourceFilePath; + return false; + } + + // 如果目标文件存在,则删除它 + if (QFile::exists(destinationFilePath)) { + if (!QFile::remove(destinationFilePath)) { + qDebug() << "Failed to remove existing destination file:" << destinationFilePath; + return false; + } + } + + // 复制文件 + if (!QFile::copy(sourceFilePath, destinationFilePath)) { + qDebug() << "Failed to copy file from" << sourceFilePath << "to" << destinationFilePath; + return false; + } + + qDebug() << "File copied successfully from" << sourceFilePath << "to" << destinationFilePath; + return true; +} + + +bool BASECONSTVARIABLEAPI unTarfile(QString inTargzPath, QString outGzFolderPath) +{ + // tar -zxvf 压缩包路径 文件或目录路径 + QProcess process; + // 同步执行(阻塞当前线程) + QString cmdstr = QString("tar -zxvf %1 -C %2").arg(inTargzPath).arg(outGzFolderPath); + process.execute("cmd.exe", QStringList() << "/c" << cmdstr); // "/c" 表示执行后关闭 CMD + process.waitForFinished(); // 等待执行完成 + // 获取输出 + QString output = QString::fromLocal8Bit(process.readAllStandardOutput()); + QString error = QString::fromLocal8Bit(process.readAllStandardError()); + qDebug() << "Output:" << output; + qDebug() << "Error:" << error; + return true; +} + +bool BASECONSTVARIABLEAPI createNewFolerPath(QString inpath, bool isremoveExist) +{ + QDir outDir(inpath); + if (outDir.exists()) { + if (isremoveExist) { + outDir.removeRecursively(); + } + else { + return true; + } + } + QDir().mkpath(inpath); + return true; +} + +QFileInfoList findFilePath(const QString& strFilePath, const QString& strNameFilters) +{ + QFileInfoList fileList; + if (strFilePath.isEmpty() || strNameFilters.isEmpty()) + { + return fileList; + } + + QDir dir; + QStringList filters; + filters << strNameFilters; + dir.setPath(strFilePath); + dir.setNameFilters(filters); + QDirIterator iter(dir, QDirIterator::Subdirectories); + while (iter.hasNext()) + { + iter.next(); + QFileInfo info = iter.fileInfo(); + if (info.isFile()) + { + fileList.append(info); + } + } + return fileList; +}//blog.csdn.net/sinat_33419023/article/details/106105037 \ No newline at end of file diff --git a/BaseTool/FileOperator.h b/BaseTool/FileOperator.h new file mode 100644 index 0000000..8d197b6 --- /dev/null +++ b/BaseTool/FileOperator.h @@ -0,0 +1,64 @@ +#pragma once + +#ifndef FILEOPERATOR_H +#define FILEOPERATOR_H +#include "BaseConstVariable.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +bool BASECONSTVARIABLEAPI isDirectory(const QString& path); +bool BASECONSTVARIABLEAPI isExists(const QString& path); +bool BASECONSTVARIABLEAPI isFile(const QString& path); +void BASECONSTVARIABLEAPI removeFile(const QString& filePath); +unsigned long BASECONSTVARIABLEAPI convertToULong(const QString& input); +/// +/// 获取文件(绝对路径) +/// +/// +/// +/// +std::vector BASECONSTVARIABLEAPI getFilelist(const QString& folderpath, const QString& FilenameExtension = ".*", int (*logfun)(QString logtext, int value) = nullptr); + +QString BASECONSTVARIABLEAPI getParantFolderNameFromPath(const QString& path); + +QString BASECONSTVARIABLEAPI getFileNameFromPath(const QString& path); + +QString BASECONSTVARIABLEAPI getFileNameWidthoutExtend(QString path); + +QString BASECONSTVARIABLEAPI getFileExtension(QString path); + +int BASECONSTVARIABLEAPI write_binfile(char* filepath, char* data, size_t data_len); + +char* read_textfile(char* text_path, int* length); + +bool BASECONSTVARIABLEAPI exists_test(const QString& name); + +size_t BASECONSTVARIABLEAPI fsize(FILE* fp); + +QString BASECONSTVARIABLEAPI getParantFromPath(const QString& path); +void BASECONSTVARIABLEAPI copyFile(const QString& sourcePath, const QString& destinationPath); +QString BASECONSTVARIABLEAPI addMaskToFileName(const QString& filePath, QString _zzname); +// QT FileOperator + +bool BASECONSTVARIABLEAPI copyAndReplaceFile(const QString& sourceFilePath, const QString& destinationFilePath); + +// 压缩包文件解压 +bool BASECONSTVARIABLEAPI unTarfile(QString inTargzPath,QString outGzFolderPath); +bool BASECONSTVARIABLEAPI createNewFolerPath(QString inpath, bool isremoveExist = false); + +QFileInfoList BASECONSTVARIABLEAPI findFilePath(const QString& dirPath, const QString& pattern); + +#endif \ No newline at end of file diff --git a/BaseTool/GeoOperator.cpp b/BaseTool/GeoOperator.cpp new file mode 100644 index 0000000..33f585b --- /dev/null +++ b/BaseTool/GeoOperator.cpp @@ -0,0 +1,511 @@ +#include "stdafx.h" +#include "GeoOperator.h" +#include +#include +#include +#include +////#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include //#include "ogrsf_frmts.h" +#include +#include +#include "GeoOperator.h" +#include // OGRSpatialReference ڿռοת +#include // GDALWarp +#include + + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon + p2.lon,p1.lat + p2.lat,p1.ati + p2.ati }; +} + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon - p2.lon,p1.lat - p2.lat,p1.ati - p2.ati }; +} + +bool operator ==(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat == p2.lat && p1.lon == p2.lon && p1.ati == p2.ati; +} + + + +Landpoint operator *(const Landpoint& p, double scale) +{ + return Landpoint{ + p.lon * scale, + p.lat * scale, + p.ati * scale + }; +} + + +Landpoint LLA2XYZ(const Landpoint& LLA) { + double L = LLA.lon * d2r; + double B = LLA.lat * d2r; + double H = LLA.ati; + + double sinB = sin(B); + double cosB = cos(B); + + //double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + double N = a / sqrt(1 - eSquare * sinB * sinB); + Landpoint result = { 0,0,0 }; + result.lon = (N + H) * cosB * cos(L); + result.lat = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.ati = (N * (1 - 1 / f_inverse) * (1 - 1 / f_inverse) + H) * sinB; + return result; +} + +void LLA2XYZ(const Landpoint& LLA, Point3& XYZ) +{ + double L = LLA.lon * d2r; + double B = LLA.lat * d2r; + double H = LLA.ati; + + double sinB = sin(B); + double cosB = cos(B); + + //double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + double N = a / sqrt(1 - eSquare * sinB * sinB); + Landpoint result = { 0,0,0 }; + XYZ.x = (N + H) * cosB * cos(L); + XYZ.y = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + XYZ.z = (N * (1 - 1 / f_inverse) * (1 - 1 / f_inverse) + H) * sinB; + +} + + +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint) +{ + landpoint.col(0) = landpoint.col(0).array() * d2r; // lon + landpoint.col(1) = landpoint.col(1).array() * d2r; // lat + + Eigen::MatrixXd sinB = (landpoint.col(1).array().sin());//lat + Eigen::MatrixXd cosB = (landpoint.col(1).array().cos());//lat + + Eigen::MatrixXd N = a / ((1 - sinB.array().pow(2) * eSquare).array().sqrt()); + Eigen::MatrixXd result(landpoint.rows(), 3); + + result.col(0) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::cos(landpoint.col(0).array()).array(); //x + result.col(1) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::sin(landpoint.col(0).array()).array(); //y + + result.col(2) = (N.array() * (1 - 1 / f_inverse) * (1 - 1 / f_inverse) + landpoint.col(2).array()) * sinB.array(); //z + + return result; +} + + +Landpoint XYZ2LLA(const Landpoint& XYZ) { + double tmpX = XYZ.lon;// + double temY = XYZ.lat;// + double temZ = XYZ.ati; + + double curB = 0; + double N = 0; + double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + Landpoint result = { 0,0,0 }; + result.lon = atan2(temY, tmpX) * r2d; + result.lat = curB * r2d; + result.ati = temZ / sinCurB - N * (1 - eSquare); + return result; +} + + + +void XYZ2BLH_FixedHeight(double x, double y, double z,double ati, Landpoint& point) { + const double a = 6378137.0; // WGS84 + const double f = 1.0 / 298.257223563; + const double e2 = 2 * f - f * f; // һƫƽ + + // 㾭L () + const double L_rad = std::atan2(y, x); + point.lon = L_rad * 180.0 / M_PI; // תΪ + + const double p = std::sqrt(x * x + y * y); + const double H = ati; // ʹ֪߶ + + // ʼγȹ㣨֪߶H + double B_rad = std::atan2(z, p * (1 - e2 * (a / (a + H)))); + + // γB̶H + for (int i = 0; i < 10; ++i) { // ֪Hʱ + const double sin_B = std::sin(B_rad); + const double N = a / std::sqrt(1 - e2 * sin_B * sin_B); + const double delta = e2 * N / (N + H); // ߶ȹ̶ʱ + + const double B_new = std::atan2(z, p * (1 - delta)); + + if (std::abs(B_new - B_rad) < 1e-9) { + B_rad = B_new; + break; + } + B_rad = B_new; + } + + point.lat = B_rad * 180.0 / M_PI; // ת + + // ȷΧ [-180, 180] + point.lon = std::fmod(point.lon + 360.0, 360.0); + if (point.lon > 180.0) point.lon -= 360.0; + point.ati = ati; +} + + +double getAngle(const Landpoint& a, const Landpoint& b) +{ + double c = dot(a, b) / (getlength(a) * getlength(b)); + if (a.lon * b.lat - a.lat * b.lon >= 0) { + return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } + else { + return 360 - acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } +} + +double dot(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat * p2.lat + p1.lon * p2.lon + p1.ati * p2.ati; +} + +double getlength(const Landpoint& p1) { + + return sqrt(dot(p1, p1)); +} + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b) { + return Landpoint{ + a.lat * b.ati - a.ati * b.lat,//x + a.ati * b.lon - a.lon * b.ati,//y + a.lon * b.lat - a.lat * b.lon//z + }; +} + +float cross2d(Point3 a, Point3 b) +{ + return a.x * b.y - a.y * b.x; +} + +Point3 operator -(Point3 a, Point3 b) +{ + return Point3{ a.x - b.x, a.y - b.y, a.z - b.z }; +} + +Point3 operator +(Point3 a, Point3 b) +{ + return Point3{ a.x + b.x, a.y + b.y, a.z + b.z }; +} + +double operator /(Point3 a, Point3 b) +{ + return sqrt(pow(a.x, 2) + pow(a.y, 2)) / sqrt(pow(b.x, 2) + pow(b.y, 2)); +} + +double BASECONSTVARIABLEAPI getPixelSpacingInDegree(double pixelSpacingInMeter) +{ + return pixelSpacingInMeter / WGS84_A * r2d; + +} + +double BASECONSTVARIABLEAPI getPixelSpacingInMeter(double pixelSpacingInDegree) +{ + return pixelSpacingInDegree * WGS84_A * r2d; +} + + +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4,bool inLBH) { + Landpoint n0, n1, n2, n3, n4; + if (inLBH) { + n0 = LLA2XYZ(p0); + n1 = LLA2XYZ(p1); + n2 = LLA2XYZ(p2); + n3 = LLA2XYZ(p3); + n4 = LLA2XYZ(p4); + } + else { + n0 = p0; + n1 = p1; + n2 = p2; + n3 = p3; + n4 = p4; + } + + Landpoint n01 = n1 - n0, n02 = n2 - n0, n03 = n3 - n0, n04 = n4 - n0; + // ��n01Ϊ�������� + Landpoint np01 = p1 - p0, np02 = p2 - p0, np03 = p3 - p0, np04 = p4 - p0; + double a2 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np02.lon,np02.lat,0 });// 01->02 + double a3 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np03.lon,np03.lat,0 });// 01->03 + double a4 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np04.lon,np04.lat,0 });// 01->04 + //qDebug() << a2 << "\t" << a3 << "\t" << a4 << endl; + a2 = 360 - a2; + a3 = 360 - a3; + a4 = 360 - a4; + Landpoint N, W, S, E; + N = n01; + if (a2 >= a3 && a2 >= a4) { + W = n02; + if (a3 >= a4) { + S = n03; + E = n04; + } + else { + S = n04; + E = n03; + } + } + else if (a3 >= a2 && a3 >= a4) { + W = n03; + if (a2 >= a4) { + S = n02; + E = n04; + } + else { + S = n04; + E = n02; + } + } + else if (a4 >= a2 && a4 >= a3) + { + W = n04; + if (a2 >= a3) { + S = n02; + E = n03; + } + else { + S = n03; + E = n02; + } + } + return (crossProduct(N, W) + crossProduct(W, S) + crossProduct(S, E) + crossProduct(E, N)) * 0.25; +} + + + +double distance(const Vector3D& p1, const Vector3D& p2) +{ + double dx = p1.x - p2.x; + double dy = p1.y - p2.y; + double dz = p1.z - p2.z; + return std::sqrt(dx * dx + dy * dy + dz * dz); +} + +double pointToLineDistance(const Vector3D& point, const Vector3D& linePoint, const Vector3D& lineDirection) +{ + Vector3D pointToLine = { point.x - linePoint.x, point.y - linePoint.y, point.z - linePoint.z }; + + // 计算点到直线的投影点的位? + double t = (pointToLine.x * lineDirection.x + pointToLine.y * lineDirection.y + pointToLine.z * lineDirection.z) / + (lineDirection.x * lineDirection.x + lineDirection.y * lineDirection.y + lineDirection.z * lineDirection.z); + + // 计算投影? + Vector3D projection = { linePoint.x + t * lineDirection.x, linePoint.y + t * lineDirection.y, linePoint.z + t * lineDirection.z }; + + // 计算点到直线的距? + return distance(point, projection); +} + +Vector3D operator+(const Vector3D& p1, const Vector3D& p2) +{ + return Vector3D{ p1.x + p2.x,p1.y + p2.y,p1.z + p2.z }; +} + +Vector3D operator-(const Vector3D& p1, const Vector3D& p2) +{ + return Vector3D{ p1.x - p2.x,p1.y - p2.y,p1.z - p2.z }; +} + +bool operator==(const Vector3D& p1, const Vector3D& p2) +{ + return p1.x == p2.x && p1.y == p2.y && p1.z == p2.z; +} + +Vector3D operator*(const Vector3D& p, double scale) +{ + return Vector3D{ + p.x * scale, + p.y * scale, + p.z * scale + }; +} + +Vector3D operator*(double scale, const Vector3D& p) +{ + return Vector3D{ + p.x * scale, + p.y * scale, + p.z * scale + }; +} + +double getAngle(const Vector3D& a, const Vector3D& b) +{ + double c = dot(a, b) / (getlength(a) * getlength(b)); + if (a.x * b.y - a.y * b.x >= 0) { + return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } + else { + return 360 - acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } +} + +double getCosAngle(const Vector3D& a, const Vector3D& b) +{ + double c = dot(a, b) / (getlength(a) * getlength(b)); + return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; +} + +double dot(const Vector3D& p1, const Vector3D& p2) +{ + return p1.y * p2.y + p1.x * p2.x + p1.z * p2.z; +} + +double getlength(const Vector3D& p1) +{ + return std::sqrt(std::pow(p1.x, 2) + std::pow(p1.y, 2) + std::pow(p1.z, 2)); +} + +Vector3D crossProduct(const Vector3D& a, const Vector3D& b) +{ + return Vector3D{ + a.y * b.z - a.z * b.y,//x + a.z * b.x - a.x * b.z,//y + a.x * b.y - a.y * b.x//z + }; +} + + +/// +/// n1 +/// n4 n0 n2 +/// n3 +/// +Vector3D getSlopeVector(const Vector3D& n0, const Vector3D& n1, const Vector3D& n2, const Vector3D& n3, const Vector3D& n4) +{ + Vector3D n01 = n1 - n0, n02 = n2 - n0, n03 = n3 - n0, n04 = n4 - n0; + return (crossProduct(n01, n04) + crossProduct(n04, n03) + crossProduct(n03, n02) + crossProduct(n02, n01)) * 0.25; +} + + +SphericalCoordinates cartesianToSpherical(const CartesianCoordinates& cartesian) +{ + SphericalCoordinates spherical; + + spherical.r = std::sqrt(cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z); + spherical.theta = std::acos(cartesian.z / spherical.r); + spherical.phi = std::atan2(cartesian.y, cartesian.x); + + return spherical; +} + +CartesianCoordinates sphericalToCartesian(const SphericalCoordinates& spherical) +{ + CartesianCoordinates cartesian; + + cartesian.x = spherical.r * std::sin(spherical.theta) * std::cos(spherical.phi); + cartesian.y = spherical.r * std::sin(spherical.theta) * std::sin(spherical.phi); + cartesian.z = spherical.r * std::cos(spherical.theta); + + return cartesian; +} + + +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector) { + Landpoint Rsc = satepoint - landpoint; // AB=B-A + //double R = getlength(Rsc); + //qDebug() << R << endl; + double angle = getAngle(Rsc, slopeVector); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + + +double getlocalIncAngle(Vector3D& satepoint, Vector3D& landpoint, Vector3D& slopeVector){ + Vector3D Rsc = satepoint - landpoint; // AB=B-A + //double R = getlength(Rsc); + //qDebug() << R << endl; + double angle = getAngle(Rsc, slopeVector); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + +bool BASECONSTVARIABLEAPI ConvertResolutionToDegrees(int sourceEPSG, double resolutionMeters, double refLon, double refLat, double& degreePerPixelX, double& degreePerPixelY){ + // ʼԴϵƽͶӰĿϵWGS84 γȣ + OGRSpatialReference sourceSRS, targetSRS; + sourceSRS.importFromEPSG(sourceEPSG); // Դϵȷ EPSG + targetSRS.importFromEPSG(4326); // ĿΪ WGS84 γ + + // תγ -> ƽ + OGRCoordinateTransformation* toPlane = OGRCreateCoordinateTransformation(&targetSRS, &sourceSRS); + if (!toPlane) return false; + + // ο㾭γתΪƽ + double x = refLon, y = refLat; + if (!toPlane->Transform(1, &x, &y)) { + OGRCoordinateTransformation::DestroyCT(toPlane); + return false; + } + + // תƽ -> γ + OGRCoordinateTransformation* toGeo = OGRCreateCoordinateTransformation(&sourceSRS, &targetSRS); + if (!toGeo) { + OGRCoordinateTransformation::DestroyCT(toPlane); + return false; + } + + // 㶫ֱʣȱ仯 + double eastX = x + resolutionMeters, eastY = y; + double eastLon = eastX, eastLat = eastY; + if (!toGeo->Transform(1, &eastLon, &eastLat)) { + OGRCoordinateTransformation::DestroyCT(toPlane); + OGRCoordinateTransformation::DestroyCT(toGeo); + return false; + } + degreePerPixelX = (eastLon - refLon) / resolutionMeters; // ȷÿ׶Ӧ + + // 㱱ֱʣγȱ仯 + double northX = x, northY = y + resolutionMeters; + double northLon = northX, northLat = northY; + if (!toGeo->Transform(1, &northLon, &northLat)) { + OGRCoordinateTransformation::DestroyCT(toPlane); + OGRCoordinateTransformation::DestroyCT(toGeo); + return false; + } + degreePerPixelY = (northLat - refLat) / resolutionMeters; // γȷÿ׶Ӧ + + // ͷԴ + OGRCoordinateTransformation::DestroyCT(toPlane); + OGRCoordinateTransformation::DestroyCT(toGeo); + return true; +} diff --git a/BaseTool/GeoOperator.h b/BaseTool/GeoOperator.h new file mode 100644 index 0000000..bd0125d --- /dev/null +++ b/BaseTool/GeoOperator.h @@ -0,0 +1,150 @@ +#pragma once + + +#ifndef _GEOOPERATOR_H +#define _GEOOPERATOR_H + +#include "BaseConstVariable.h" +#include +#include +#include +#include +#include +#include +#include + + +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +Landpoint BASECONSTVARIABLEAPI LLA2XYZ(const Landpoint& LLA); +void BASECONSTVARIABLEAPI LLA2XYZ(const Landpoint& LLA,Point3& XYZ); +Eigen::MatrixXd BASECONSTVARIABLEAPI LLA2XYZ(Eigen::MatrixXd landpoint); + +double BASECONSTVARIABLEAPI getPixelSpacingInDegree(double pixelSpacingInMeter); + +double BASECONSTVARIABLEAPI getPixelSpacingInMeter(double pixelSpacingInDegree); +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +Landpoint BASECONSTVARIABLEAPI XYZ2LLA(const Landpoint& XYZ); + +void BASECONSTVARIABLEAPI XYZ2BLH_FixedHeight(double x, double y, double z, double ati, Landpoint& point); + +Landpoint BASECONSTVARIABLEAPI operator +(const Landpoint& p1, const Landpoint& p2); + +Landpoint BASECONSTVARIABLEAPI operator -(const Landpoint& p1, const Landpoint& p2); + +bool BASECONSTVARIABLEAPI operator ==(const Landpoint& p1, const Landpoint& p2); + +Landpoint BASECONSTVARIABLEAPI operator *(const Landpoint& p, double scale); + +double BASECONSTVARIABLEAPI getAngle(const Landpoint& a, const Landpoint& b); + +double BASECONSTVARIABLEAPI dot(const Landpoint& p1, const Landpoint& p2); + +double BASECONSTVARIABLEAPI getlength(const Landpoint& p1); + +Landpoint BASECONSTVARIABLEAPI crossProduct(const Landpoint& a, const Landpoint& b); + + +Landpoint BASECONSTVARIABLEAPI getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4, bool inLBH=true); + +double BASECONSTVARIABLEAPI getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector); + +float BASECONSTVARIABLEAPI cross2d(Point3 a, Point3 b); + +Point3 BASECONSTVARIABLEAPI operator -(Point3 a, Point3 b); + +Point3 BASECONSTVARIABLEAPI operator +(Point3 a, Point3 b); + +double BASECONSTVARIABLEAPI operator /(Point3 a, Point3 b); + + + +// 矢量计算 +struct Vector3D { + double x, y, z; +}; + +// 计算两点之间的距离 +double BASECONSTVARIABLEAPI distance(const Vector3D& p1, const Vector3D& p2); +// 计算点到直线的最短距离 +double BASECONSTVARIABLEAPI pointToLineDistance(const Vector3D& point, const Vector3D& linePoint, const Vector3D& lineDirection); + +Vector3D BASECONSTVARIABLEAPI operator +(const Vector3D& p1, const Vector3D& p2); + +Vector3D BASECONSTVARIABLEAPI operator -(const Vector3D& p1, const Vector3D& p2); + +bool BASECONSTVARIABLEAPI operator ==(const Vector3D& p1, const Vector3D& p2); + +Vector3D BASECONSTVARIABLEAPI operator *(const Vector3D& p, double scale); + +Vector3D BASECONSTVARIABLEAPI operator *(double scale,const Vector3D& p ); + +double BASECONSTVARIABLEAPI getAngle(const Vector3D& a, const Vector3D& b); + +double BASECONSTVARIABLEAPI getCosAngle(const Vector3D& a, const Vector3D& b); + +double BASECONSTVARIABLEAPI dot(const Vector3D& p1, const Vector3D& p2); + +double BASECONSTVARIABLEAPI getlength(const Vector3D& p1); + +Vector3D BASECONSTVARIABLEAPI crossProduct(const Vector3D& a, const Vector3D& b); + + + +/// +/// n1 +/// n4 n0 n2 +/// n3 +/// +/// +/// +/// +/// +/// +/// +Vector3D BASECONSTVARIABLEAPI getSlopeVector(const Vector3D& n0, const Vector3D& n1, const Vector3D& n2, const Vector3D& n3, const Vector3D& n4); + + +struct CartesianCoordinates { + double x, y, z; +}; + +struct SphericalCoordinates { + double r, theta, phi; +}; + +SphericalCoordinates BASECONSTVARIABLEAPI cartesianToSpherical(const CartesianCoordinates& cartesian); + +CartesianCoordinates BASECONSTVARIABLEAPI sphericalToCartesian(const SphericalCoordinates& spherical); + +double BASECONSTVARIABLEAPI getlocalIncAngle(Vector3D& satepoint, Vector3D& landpoint, Vector3D& slopeVector); + + + +/** + * @brief 将平面坐标分辨率(米)转换为经纬度分辨率(度) + * @param sourceEPSG 平面坐标系 EPSG 码(如 UTM Zone 50N 对应 32650) + * @param resolutionMeters 输入分辨率(单位:米) + * @param refLon 参考点经度(十进制度,用于计算局部转换系数) + * @param refLat 参考点纬度(十进制度,用于计算局部转换系数) + * @param[out] degreePerPixelX 经度方向分辨率(度/像素) + * @param[out] degreePerPixelY 纬度方向分辨率(度/像素) + * @return 是否转换成功 + */ +bool BASECONSTVARIABLEAPI ConvertResolutionToDegrees( + int sourceEPSG, + double resolutionMeters, + double refLon, + double refLat, + double& degreePerPixelX, + double& degreePerPixelY +); + +#endif \ No newline at end of file diff --git a/BaseTool/ImageOperatorBase.cpp b/BaseTool/ImageOperatorBase.cpp new file mode 100644 index 0000000..0edf2f0 --- /dev/null +++ b/BaseTool/ImageOperatorBase.cpp @@ -0,0 +1,1793 @@ +#include "stdafx.h" +#include "ImageOperatorBase.h" +#include "BaseTool.h" +#include "GeoOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FileOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include // OGRSpatialReference 用于空间参考转换 +#include // 用于 GDALWarp 操作 + + + +/** + * 输入数据是ENVI格式数据 + */ + +std::shared_ptr OpenDataset(const QString& in_path, GDALAccess rwmode) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* dataset_ptr = (GDALDataset*)(GDALOpen(in_path.toUtf8().constData(), rwmode)); + std::shared_ptr rasterDataset(dataset_ptr, CloseDataset); + return rasterDataset; +} + +void CloseDataset(GDALDataset* ptr) +{ + GDALClose(ptr); + ptr = NULL; +} + +int TIFF2ENVI(QString in_tiff_path, QString out_envi_path) +{ + std::shared_ptr ds = OpenDataset(in_tiff_path); + const char* args[] = { "-of", "ENVI", NULL }; + GDALTranslateOptions* psOptions = GDALTranslateOptionsNew((char**)args, NULL); + GDALClose(GDALTranslate(out_envi_path.toUtf8().constData(), ds.get(), psOptions, NULL)); + GDALTranslateOptionsFree(psOptions); + return 0; +} + +int ENVI2TIFF(QString in_envi_path, QString out_tiff_path) +{ + std::shared_ptr ds = OpenDataset(in_envi_path); + const char* args[] = { "-of", "Gtiff", NULL }; + GDALTranslateOptions* psOptions = GDALTranslateOptionsNew((char**)args, NULL); + GDALClose(GDALTranslate(out_tiff_path.toUtf8().constData(), ds.get(), psOptions, NULL)); + GDALTranslateOptionsFree(psOptions); + return 0; +} + +int CreateDataset(QString new_file_path, int height, int width, int band_num, double* gt, + QString projection, GDALDataType gdal_dtype, bool need_gt) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + std::shared_ptr poDstDS(poDriver->Create(new_file_path.toUtf8().constData(), width, + height, band_num, gdal_dtype, NULL)); + if(need_gt) { + poDstDS->SetProjection(projection.toUtf8().constData()); + poDstDS->SetGeoTransform(gt); + } else { + } + GDALFlushCache((GDALDatasetH)poDstDS.get()); + return 0; +} + +int saveDataset(QString new_file_path, int start_line, int start_cols, int band_ids, int datacols, + int datarows, void* databuffer) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + std::shared_ptr poDstDS = OpenDataset(new_file_path, GA_Update); + GDALDataType gdal_datatype = poDstDS->GetRasterBand(1)->GetRasterDataType(); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_cols, start_line, datacols, datarows, + databuffer, datacols, datarows, gdal_datatype, 0, 0); + GDALFlushCache(poDstDS.get()); + return 0; +} + +int block_num_pre_memory(int block_width, int height, GDALDataType gdal_datatype, double memey_size) +{ + // 计算大小 + int size_meta = 0; + + if(gdal_datatype == GDT_Byte) { + size_meta = 1; + } else if(gdal_datatype == GDT_UInt16) { + size_meta = 2; // 只有双通道才能构建 复数矩阵 + } else if(gdal_datatype == GDT_UInt16) { + size_meta = 2; + } else if(gdal_datatype == GDT_Int16) { + size_meta = 2; + } else if(gdal_datatype == GDT_UInt32) { + size_meta = 4; + } else if(gdal_datatype == GDT_Int32) { + size_meta = 4; + } + // else if (gdal_datatype == GDT_UInt64) { + // size_meta = 8; + // } + // else if (gdal_datatype == GDT_Int64) { + // size_meta = 8; + // } + else if(gdal_datatype == GDT_Float32) { + size_meta = 4; + } else if(gdal_datatype == GDT_Float64) { + size_meta = 4; + } else if(gdal_datatype == GDT_CInt16) { + size_meta = 2; + } else if(gdal_datatype == GDT_CInt32) { + size_meta = 2; + } else if(gdal_datatype == GDT_CFloat32) { + size_meta = 4; + } else if(gdal_datatype == GDT_CFloat64) { + size_meta = 8; + } else { + } + int block_num = int(memey_size / (size_meta * block_width)); + block_num = block_num > height ? height : block_num; // 行数 + block_num = block_num < 1 ? 1 : block_num; + return block_num; +} + +Eigen::Matrix +ReadComplexMatrixData(int start_line, int width, int line_num, + std::shared_ptr rasterDataset, GDALDataType gdal_datatype) +{ + int band_num = rasterDataset->GetRasterCount(); + if(gdal_datatype == 0) { + return Eigen::Matrix(0, 0); + } else if(gdal_datatype < 8) { + if(band_num != 2) { + return Eigen::Matrix(0, 0); + } + } else if(gdal_datatype < 12) { + if(band_num != 1) { + return Eigen::Matrix(0, 0); + } + + } else { + } + bool _flag = false; + Eigen::Matrix data_mat( + line_num * width, 2); // 必须强制行优先 + if(gdal_datatype == GDT_Byte) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_UInt16) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_Int16) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_UInt32) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_Int32) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } + // else if (gdal_datatype == GDT_UInt64) { + // Eigen::MatrixX real_mat(line_num * width, 1); + // Eigen::MatrixX imag_mat(line_num * width, 1); + // rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + //real_mat.data(), width, line_num, gdal_datatype, 0, 0); // real + // rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + //imag_mat.data(), width, line_num, gdal_datatype, 0, 0); // imag data_mat.col(0) = + //(real_mat.array().cast()).array(); data_mat.col(1) = + //(imag_mat.array().cast()).array(); _flag = true; + // } + // else if (gdal_datatype == GDT_Int64) { + // Eigen::MatrixX real_mat(line_num * width, 1); + // Eigen::MatrixX imag_mat(line_num * width, 1); + // rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + //real_mat.data(), width, line_num, gdal_datatype, 0, 0); // real + // rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + //imag_mat.data(), width, line_num, gdal_datatype, 0, 0); // imag data_mat.col(0) = + //(real_mat.array().cast()).array(); data_mat.col(1) = + //(imag_mat.array().cast()).array(); _flag = true; + // } + else if(gdal_datatype == GDT_Float32) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_Float64) { + Eigen::MatrixX real_mat(line_num * width, 1); + Eigen::MatrixX imag_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, gdal_datatype, + 0, 0); // real + rasterDataset->GetRasterBand(2)->RasterIO(GF_Read, 0, start_line, width, line_num, + imag_mat.data(), width, line_num, gdal_datatype, + 0, 0); // imag + data_mat.col(0) = (real_mat.array().cast()).array(); + data_mat.col(1) = (imag_mat.array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_CInt16) { + Eigen::MatrixX> complex_short_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + complex_short_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = (complex_short_mat.real().array().cast()).array(); + data_mat.col(1) = (complex_short_mat.imag().array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_CInt32) { + Eigen::MatrixX> complex_short_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + complex_short_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = (complex_short_mat.real().array().cast()).array(); + data_mat.col(1) = (complex_short_mat.imag().array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_CFloat32) { + Eigen::MatrixX> complex_short_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + complex_short_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = (complex_short_mat.real().array().cast()).array(); + data_mat.col(1) = (complex_short_mat.imag().array().cast()).array(); + _flag = true; + } else if(gdal_datatype == GDT_CFloat64) { + Eigen::MatrixX> complex_short_mat(line_num * width, 1); + rasterDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, start_line, width, line_num, + complex_short_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = (complex_short_mat.real().array().cast()).array(); + data_mat.col(1) = (complex_short_mat.imag().array().cast()).array(); + _flag = true; + } else { + } + // 保存数据 + + if(_flag) { + return data_mat; + } else { + return Eigen::Matrix( + 0, 0); // 必须强制行优先; + } +} + +Eigen::Matrix +ReadMatrixDoubleData(int start_line, int width, int line_num, + std::shared_ptr rasterDataset, GDALDataType gdal_datatype, + int band_idx) +{ + // 构建矩阵块,使用eigen 进行矩阵计算,加速计算 + bool _flag = false; + Eigen::Matrix data_mat( + line_num * width, 1); // 必须强制行优先 + if(gdal_datatype == GDT_Byte) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } else if(gdal_datatype == GDT_UInt16) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } else if(gdal_datatype == GDT_Int16) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } else if(gdal_datatype == GDT_UInt32) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } else if(gdal_datatype == GDT_Int32) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } + // else if (gdal_datatype == GDT_UInt64) { + // Eigen::MatrixX real_mat(line_num * width, 1); + // rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + //real_mat.data(), width, line_num, gdal_datatype, 0, 0); // real data_mat.col(0) = + //((real_mat.array().cast()).array().pow(2)).log10() * 10.0; _flag = true; + // } + // else if (gdal_datatype == GDT_Int64) { + // Eigen::MatrixX real_mat(line_num * width, 1); + // rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + //real_mat.data(), width, line_num, gdal_datatype, 0, 0); // real data_mat.col(0) = + //((real_mat.array().cast()).array().pow(2)).log10() * 10.0; _flag = true; + // } + else if(gdal_datatype == GDT_Float32) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } else if(gdal_datatype == GDT_Float64) { + Eigen::MatrixX real_mat(line_num * width, 1); + rasterDataset->GetRasterBand(band_idx)->RasterIO(GF_Read, 0, start_line, width, line_num, + real_mat.data(), width, line_num, + gdal_datatype, 0, 0); // real + data_mat.col(0) = ((real_mat.array().cast()).array().pow(2)).log10() * 10.0; + _flag = true; + } else { + } + + return data_mat; +} + +Eigen::MatrixXd getGeoTranslationArray(QString in_path) +{ + return Eigen::MatrixXd(); +} + +ImageGEOINFO getImageINFO(QString in_path) +{ + std::shared_ptr df = OpenDataset(in_path); + int width = df->GetRasterXSize(); + int heigh = df->GetRasterYSize(); + int band_num = df->GetRasterCount(); + ImageGEOINFO result; + result.width = width; + result.height = heigh; + result.bandnum = band_num; + + return result; +} + +GDALDataType getGDALDataType(QString fileptah) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen( + fileptah.toUtf8().constData(), GA_ReadOnly)); // 锟斤拷只斤拷式锟斤拷取斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // 锟酵放伙拷斤拷 + omp_destroy_lock(&lock); // 劫伙拷斤拷 + + return gdal_datatype; +} + + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, + int new_height, GDALResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if(pDSrc == NULL) { + return -1; + } + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if(pDriver == NULL) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + // 锟斤拷锟矫伙拷锟酵队帮拷锟斤拷锟轿?拷锟斤拷锟揭伙拷锟?1锟?7 + if(strlen(pszSrcWKT) <= 0) { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + // oSRS.SetUTM(50, true); //锟斤拷锟斤拷锟斤拷 锟斤拷锟斤拷120锟斤拷 + // oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + } + qDebug() << "GDALCreateGenImgProjTransformer " << Qt::endl; + void* hTransformArg; + hTransformArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, NULL, pszSrcWKT, + FALSE, 0.0, 1); + qDebug() << "no proj " << Qt::endl; + //(没锟斤拷投影锟斤拷影锟斤拷锟斤拷锟斤拷锟斤拷卟锟酵?拷锟?1锟?7) + if(hTransformArg == NULL) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + qDebug() << "has proj " << Qt::endl; + double dGeoTrans[6] = { 0 }; + int nNewWidth = 0, nNewHeight = 0; + if(GDALSuggestedWarpOutput((GDALDatasetH)pDSrc, GDALGenImgProjTransform, hTransformArg, + dGeoTrans, &nNewWidth, &nNewHeight) + != CE_None) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + + // GDALDestroyGenImgProjTransformer(hTransformArg); + qDebug() << "create init GDALDataset " ; + GDALDataset* pDDst = + pDriver->Create(pszOutFile, new_width, new_height, nBandCount, dataType, NULL); + if(pDDst == NULL) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(gt); + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + CPLSetConfigOption("GDAL_NUM_THREADS", "ALL_CPUS"); // 使用所有可用的CPU核心 + CPLSetConfigOption("GDAL_CACHEMAX", "16000"); // 设置缓存大小为500MB + // psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + qDebug() << "GDALCreateGenImgProjTransformer" << Qt::endl; + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = GDALCreateGenImgProjTransformer( + (GDALDatasetH)pDSrc, pszSrcWKT, (GDALDatasetH)pDDst, pszSrcWKT, FALSE, 0.0, 1); + ; + + qDebug() << "GDALCreateGenImgProjTransformer has created" << Qt::endl; + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for(int i = 0; i < nBandCount; i++) { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + GDALWarpOperation oWo; + if(oWo.Initialize(psWo) != CE_None) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + return -3; + } + qDebug() << "ChunkAndWarpImage:" << new_width << "," << new_height << Qt::endl; + oWo.ChunkAndWarpMulti(0, 0, new_width, new_height); + GDALFlushCache(pDDst); + qDebug() << "ChunkAndWarpImage over" << Qt::endl; + // GDALDestroyGenImgProjTransformer(psWo->pTransformerArg); + // GDALDestroyWarpOptions(psWo); + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return 0; +} + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_Update); + if(pDSrc == NULL) { + return -1; + } + + GDALDataType gdal_datatype = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* demBand = pDSrc->GetRasterBand(band_ids); + + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int start_col = 0, start_row = 0, rows_count = 0, cols_count; + + int row_delta = int(120000000 / width); + + GDALRasterIOExtraArg psExtraArg; + INIT_RASTERIO_EXTRA_ARG(psExtraArg); + psExtraArg.eResampleAlg = eResample; + + do { + rows_count = start_row + row_delta < height ? row_delta : height - start_row; + cols_count = width; + + if(gdal_datatype == GDALDataType::GDT_UInt16) { + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, + cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, + cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + + } else if(gdal_datatype == GDALDataType::GDT_Int16) { + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, + cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, + cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } else if(gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, + cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, + cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + start_row = start_row + rows_count; + } while(start_row < height); + GDALClose((GDALDatasetH)pDSrc); + + return 0; +} + +int alignRaster(QString inputPath, QString referencePath, QString outputPath, GDALResampleAlg eResample) +{ + + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(inputPath.toUtf8().constData(), GA_ReadOnly); + if (pDSrc == NULL) { + return -1; + } + + GDALDataset* tDSrc = (GDALDataset*)GDALOpen(referencePath.toUtf8().constData(), GA_ReadOnly); + if (tDSrc == NULL) { + return -1; + } + + long new_width = tDSrc->GetRasterXSize(); + long new_height = tDSrc->GetRasterYSize(); + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + if (strlen(pszSrcWKT) <= 0) { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + oSRS.exportToWkt(&pszSrcWKT); + } + qDebug() << "GDALCreateGenImgProjTransformer " << Qt::endl; + void* hTransformArg; + hTransformArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, NULL, pszSrcWKT,FALSE, 0.0, 1); + qDebug() << "no proj " << Qt::endl; + if (hTransformArg == NULL) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + qDebug() << "has proj " << Qt::endl; + std::shared_ptr dGeoTrans(new double[6], delArrPtr); + int nNewWidth = 0, + nNewHeight = 0; + + if (GDALSuggestedWarpOutput((GDALDatasetH)pDSrc, GDALGenImgProjTransform, hTransformArg,dGeoTrans.get(), &nNewWidth, &nNewHeight) != CE_None) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + + GDALDataset* pDDst = pDriver->Create(outputPath.toUtf8().constData(), new_width, new_height, pDSrc->GetRasterCount(), dataType, NULL); + if (pDDst == NULL) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + + std::shared_ptr gt(new double[6], delArrPtr); + tDSrc->GetGeoTransform(gt.get()); + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(gt.get()); + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, (GDALDatasetH)pDDst, pszSrcWKT, FALSE, 0.0, 1); + + + qDebug() << "GDALCreateGenImgProjTransformer has created" << Qt::endl; + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)tDSrc); + return -3; + } + qDebug() << "ChunkAndWarpImage:" << new_width << "," << new_height << Qt::endl; + oWo.ChunkAndWarpMulti(0, 0, new_width, new_height); + GDALFlushCache(pDDst); + qDebug() << "ChunkAndWarpImage over" << Qt::endl; + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)tDSrc); + return 0; + + +} + + +int saveMatrixXcd2TiFF(Eigen::MatrixXcd data, QString out_tiff_path) +{ + int rows = data.rows(); + int cols = data.cols(); + + Eigen::MatrixXd gt = Eigen::MatrixXd::Zero(2, 3); + + gdalImage image_tiff = + CreategdalImage(out_tiff_path, rows, cols, 2, gt, "", false, true); // 注意这里保留仿真结果 + // 保存二进制文件 + Eigen::MatrixXd real_img = data.array().real(); + Eigen::MatrixXd imag_img = data.array().imag(); + image_tiff.saveImage(real_img, 0, 0, 1); + image_tiff.saveImage(imag_img, 0, 0, 2); + return -1; +} + +void clipRaster(QString inRasterPath, QString outRasterPath, long minRow, long maxRow, long minCol, long maxCol) +{ + long rownum = maxRow - minRow + 1; + long colnum = maxCol - minCol + 1; + + gdalImage inimg(inRasterPath); + Eigen::MatrixXd gt = inimg.gt; + + Landpoint lp = inimg.getLandPoint(minRow, minCol, 0); + + gt(0, 0) = lp.lon; + gt(1, 0) = lp.lat; + + gdalImage outimg= CreategdalImageDouble(outRasterPath, rownum, colnum, inimg.band_num, gt, inimg.projection, true, true, true); + + for (long bi = 1; bi < inimg.band_num + 1; bi++) { + Eigen::MatrixXd brasterData = inimg.getData(minRow, minCol, rownum, colnum, bi); + outimg.saveImage(brasterData, 0, 0, bi); + qDebug() << "writer raster band : " << bi; + } + + qDebug() << "writer raster overring"; + +} + + + + +long getProjectEPSGCodeByLon_Lat(double long, double lat, ProjectStripDelta stripState) +{ + long EPSGCode = 0; + switch (stripState) { + case ProjectStripDelta::Strip_3: { + break; + }; + case ProjectStripDelta::Strip_6: { + break; + } + default: { + EPSGCode = -1; + break; + } + } + qDebug() << QString(" EPSG code : %1").arg(EPSGCode); + return EPSGCode; +} +long getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat) +{ + // EPSG 4534 ~ 4554 3 度带 + // 首先判断是否是在 中国带宽范围 + // 中心经度范围 :75E ~ 135E 实际范围 73.5E ~ 136.5E, + // 纬度范围 3N ~ 54N,放宽到 0N~ 60N + if (73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内 + long code = trunc((lon - 73.5) / 3) + 4534; + return code; + } + else { // 非中国境内 使用 高斯克吕格 + bool isSouth = lat < 0; // 简单判断南北半球,这里仅为示例,实际应用可能需要更细致的逻辑 + long prefix = isSouth ? 327000 : 326000; + // std::string prefix = isSouth ? "327" : "326"; + lon = fmod(lon + 360.0, 360.0); + long zone = std::floor((lon + 180.0) / 3.0); + prefix = prefix + zone; + return prefix; + } + return 0; +} +long getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat) +{ + // EPSG 4502 ~ 4512 6度带 + // 首先判断是否是在 中国带宽范围 + // 中心经度范围 :75E ~ 135E 实际范围 72.0E ~ 138E, + // 纬度范围 3N ~ 54N,放宽到 0N~ 60N + if (73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内 + long code = trunc((lon - 72.0) / 6) + 4502; + return code; + } + else { // 非中国境内 使用 UTM// 确定带号,6度带从1开始到60,每6度一个带 + int zone = static_cast((lon + 180.0) / 6.0) + 1; + bool isSouth = lon < 0; // 判断是否在南半球 + long epsgCodeBase = isSouth ? 32700 : 32600; // 计算EPSG代码 + long prefix = static_cast(epsgCodeBase + zone); + return prefix; + } + return 0; +} + +QString GetProjectionNameFromEPSG(long epsgCode) +{ + qDebug() << "============= GetProjectionNameFromEPSG ======================"; + OGRSpatialReference oSRS; + + // 设置EPSG代码 + if (oSRS.importFromEPSG(epsgCode) != OGRERR_NONE) { + qDebug() << "epsgcode not recognition"; + return ""; + } + + // 获取并输出坐标系的描述(名称) + const char* pszName = oSRS.GetAttrValue("GEOGCS"); + if (pszName) { + qDebug() << "Coordinate system name for EPSG " + QString::number(epsgCode) + << " is: " + QString::fromStdString(pszName); + return QString::fromStdString(pszName); + } + else { + qDebug() << "Unable to retrieve the name for EPSG " + QString::number(epsgCode); + return ""; + } + + // char* wkt = NULL; + // // 转换为WKT格式 + // oSRS.exportToWkt(&wkt); + // + // qDebug() << wkt; + // + // // 从WKT中解析投影名称,这里简化处理,实际可能需要更复杂的逻辑来准确提取名称 + // std::string wktStr(wkt); + // long start = wktStr.find("PROJCS[\"") + 8; // 找到"PROJCS["后的第一个双引号位置 + // // 从start位置开始找下一个双引号,这之间的内容即为投影名称 + // int end = wktStr.find('\"', start); + // QString projName = QString::fromStdString(wktStr.substr(start, end - start)); + // + // // 释放WKT字符串内存 + // CPLFree(wkt); + + // return projName; +} + + + +long GetEPSGFromRasterFile(QString filepath) +{ + qDebug() << "============= GetEPSGFromRasterFile ======================"; + // QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器 + // QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray + //,这个应该会自动释放 const char* charArray = byteArray.constData(); // + // 获取QByteArray的const char*指针 + + { + if (QFile(filepath).exists()) { + qDebug() << "info: the image found.\n"; + } + else { + return -1; + } + + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 注册GDAL驱动 + // qDebug()<GetProjectionRef(); + + qDebug() << QString::fromUtf8(pszProjection); + + // 创建SpatialReference对象 + OGRSpatialReference oSRS; + if (oSRS.importFromWkt((char**)&pszProjection) != OGRERR_NONE) { + qDebug() << ("Error: Unable to import projection information.\n"); + GDALClose(poDataset); + return -1; + } + + qDebug() << pszProjection ; + + const char* epscodestr = oSRS.GetAuthorityCode(nullptr); + if (NULL == epscodestr || nullptr == epscodestr) { + qDebug() << "EPSG code string could not be determined from the spatial reference."; + GDALClose(poDataset); + + return -1; + } + long epsgCode = atoi(epscodestr); // 获取EPSG代码 + + if (epsgCode != 0) { + GDALClose(poDataset); + qDebug() << QString("file %1 :epsg Code %2").arg(filepath).arg(epsgCode); + return epsgCode; + } + else { + qDebug() << "EPSG code could not be determined from the spatial reference."; + GDALClose(poDataset); + + return -1; + } + } +} + +std::shared_ptr GetCenterPointInRaster(QString filepath) +{ + qDebug() << "============= GetCenterPointInRaster ======================"; + // QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器 + // QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray + //,这个应该会自动释放 const char* charArray = byteArray.constData(); // + // 获取QByteArray的const char*指针 + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + // qDebug()<GetGeoTransform(adfGeoTransform) != CE_None) { + qDebug() << "Failed to get GeoTransform"; + return nullptr; + } + + double dfWidth = poDataset->GetRasterXSize(); + double dfHeight = poDataset->GetRasterYSize(); + + // 计算中心点坐标(像素坐标) + double dfCenterX = adfGeoTransform[0] + dfWidth * adfGeoTransform[1] / 2.0 + + dfHeight * adfGeoTransform[2] / 2.0; + double dfCenterY = adfGeoTransform[3] + dfWidth * adfGeoTransform[4] / 2.0 + + dfHeight * adfGeoTransform[5] / 2.0; + + OGRSpatialReference oSRS; + oSRS.importFromWkt(poDataset->GetProjectionRef()); + + if (oSRS.IsGeographic()) { + qDebug() << "Center coords (already in geographic): (" + QString::number(dfCenterX) + + ", " + QString::number(dfCenterY) + ")"; + flag = true; + x = dfCenterX; + y = dfCenterY; + } + else { + // 如果不是地理坐标系,转换到WGS84 + OGRSpatialReference oSRS_WGS84; + oSRS_WGS84.SetWellKnownGeogCS("WGS84"); + + OGRCoordinateTransformation* poCT = + OGRCreateCoordinateTransformation(&oSRS, &oSRS_WGS84); + if (poCT == nullptr) { + qDebug() << "Failed to create coordinate transformation"; + return nullptr; + } + + // double dfLon, dfLat; + if (poCT->Transform(1, &dfCenterX, &dfCenterY)) { + qDebug() << "Center coords (transformed to WGS84): (" + + QString::number(dfCenterX) + ", " + QString::number(dfCenterY) + << ")"; + flag = true; + x = dfCenterX; + y = dfCenterY; + } + else { + qDebug() << "Transformation failed."; + } + OGRCoordinateTransformation::DestroyCT(poCT); + } + } + if (nullptr == poDataset || NULL == poDataset) {} + else { + GDALClose(poDataset); + } + + if (flag) { + std::shared_ptr RasterCenterPoint = std::make_shared(); + RasterCenterPoint->x = x; + RasterCenterPoint->y = y; + RasterCenterPoint->z = 0; + return RasterCenterPoint; + } + else { + return nullptr; + } +} +CoordinateSystemType getCoordinateSystemTypeByEPSGCode(long epsg_code) +{ + OGRSpatialReference oSRS; + if (oSRS.importFromEPSG(epsg_code) == OGRERR_NONE) { + if (oSRS.IsGeographic()) { + return CoordinateSystemType::GeoCoordinateSystem; + } + else if (oSRS.IsProjected()) { + return CoordinateSystemType::ProjectCoordinateSystem; + } + else { + return CoordinateSystemType::UNKNOW; + } + } + else { + return CoordinateSystemType::UNKNOW; + } +} + + +void resampleRaster(const char* inputRaster, const char* outputRaster, double targetPixelSizeX, double targetPixelSizeY) { + // 初始化GDAL + GDALAllRegister(); + // 打开输入栅格文件 + GDALDataset* poDataset = (GDALDataset*)GDALOpen(inputRaster, GA_ReadOnly); + if (poDataset == nullptr) { + std::cerr << "Failed to open raster file." << std::endl; + return; + } + + // 获取原始栅格的空间参考 + double adfGeoTransform[6]; + if (poDataset->GetGeoTransform(adfGeoTransform) != CE_None) { + std::cerr << "Failed to get geotransform." << std::endl; + GDALClose(poDataset); + return; + } + + // 获取原始栅格的尺寸 + int nXSize = poDataset->GetRasterXSize(); + int nYSize = poDataset->GetRasterYSize(); + + // 计算目标栅格的尺寸 + double targetXSize = (adfGeoTransform[1] * nXSize) / targetPixelSizeX; + double targetYSize = (adfGeoTransform[5] * nYSize) / targetPixelSizeY; + + // 创建目标数据集(输出栅格) + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (poDriver == nullptr) { + std::cerr << "Failed to get GTiff driver." << std::endl; + GDALClose(poDataset); + return; + } + + // 创建输出数据集 + GDALDataset* poOutDataset = poDriver->Create(outputRaster, (int)targetXSize, (int)targetYSize, poDataset->GetRasterCount(), GDT_Float32, nullptr); + if (poOutDataset == nullptr) { + std::cerr << "Failed to create output raster." << std::endl; + GDALClose(poDataset); + return; + } + + // 设置输出数据集的地理变换(坐标系) + double targetGeoTransform[6] = { + adfGeoTransform[0], targetPixelSizeX, 0, adfGeoTransform[3], 0, -targetPixelSizeY + }; + poOutDataset->SetGeoTransform(targetGeoTransform); + + // 设置输出数据集的投影信息 + poOutDataset->SetProjection(poDataset->GetProjectionRef()); + + // 进行重采样 + for (int i = 0; i < poDataset->GetRasterCount(); i++) { + GDALRasterBand* poBand = poDataset->GetRasterBand(i + 1); + GDALRasterBand* poOutBand = poOutDataset->GetRasterBand(i + 1); + + // 使用GDAL的重采样方法,选择一个适当的重采样方式 + poOutBand->RasterIO(GF_Write, 0, 0, (int)targetXSize, (int)targetYSize, + nullptr, (int)targetXSize, (int)targetYSize, + poBand->GetRasterDataType(), 0, 0, nullptr); + } + + // 关闭数据集 + GDALClose(poDataset); + GDALClose(poOutDataset); + + qDebug() << "Resampling completed." ; +} + +void transformRaster(const char* inputFile, const char* outputFile, int sourceEPSG, int targetEPSG) { + // 初始化 GDAL 库 + GDALAllRegister(); + + // 打开源栅格文件 + GDALDataset* poSrcDS = (GDALDataset*)GDALOpen(inputFile, GA_ReadOnly); + if (poSrcDS == nullptr) { + qDebug() << "Failed to open input file:" << inputFile; + return; + } + + // 获取源栅格的基本信息 + int nXSize = poSrcDS->GetRasterXSize(); + int nYSize = poSrcDS->GetRasterYSize(); + int nBands = poSrcDS->GetRasterCount(); + GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); + + // 创建目标栅格文件 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (poDriver == nullptr) { + qDebug() << "GTiff driver not available."; + GDALClose(poSrcDS); + return; + } + + GDALDataset* poDstDS = poDriver->Create(outputFile, nXSize, nYSize, nBands, eDT, nullptr); + if (poDstDS == nullptr) { + qDebug() << "Failed to create output file:" << outputFile; + GDALClose(poSrcDS); + return; + } + + // 设置目标栅格的空间参考系统 + OGRSpatialReference oSRS; + oSRS.importFromEPSG(targetEPSG); + + char* pszWKT = nullptr; + oSRS.exportToWkt(&pszWKT); + poDstDS->SetProjection(pszWKT); + CPLFree(pszWKT); + + // 复制元数据 + poDstDS->SetMetadata(poSrcDS->GetMetadata()); + + // 复制每个波段的数据 + for (int i = 1; i <= nBands; ++i) { + GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(i); + GDALRasterBand* poDstBand = poDstDS->GetRasterBand(i); + + float* pafScanline = (float*)CPLMalloc(sizeof(float) * nXSize); + + for (int j = 0; j < nYSize; ++j) { + poSrcBand->RasterIO(GF_Read, 0, j, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0); + poDstBand->RasterIO(GF_Write, 0, j, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0); + } + + CPLFree(pafScanline); + } + + // 关闭数据集 + GDALClose(poSrcDS); + GDALClose(poDstDS); + + qDebug() << "Raster transformation completed successfully."; +} + + + +ErrorCode transformCoordinate(double x, double y, int sourceEPSG, int targetEPSG, Point2 &p) { + // 创建源坐标系(原始坐标系) + OGRSpatialReference sourceSRS; + sourceSRS.importFromEPSG(sourceEPSG); // 使用 EPSG 编码来指定坐标系 + + // 创建目标坐标系(目标坐标系) + OGRSpatialReference targetSRS; + targetSRS.importFromEPSG(targetEPSG); // WGS84 坐标系 EPSG:4326 + + // 创建坐标变换对象 + OGRCoordinateTransformation* transform = OGRCreateCoordinateTransformation(&sourceSRS, &targetSRS); + if (transform == nullptr) { + qDebug() << "Failed to create coordinate transformation." ; + return ErrorCode::FAIL; + } + + // 转换坐标 + double transformedX = x; + double transformedY = y; + if (transform->Transform(1, &transformedX, &transformedY)) { + qDebug() << "Original Coordinates: (" << x << ", " << y << ")" ; + qDebug() << "Transformed Coordinates (EPSG:" << targetEPSG << "): (" << transformedX << ", " << transformedY << ")" ; + } + else { + qDebug() << "Coordinate transformation failed." ; + } + + // 清理 + delete transform; + p.x = transformedX; + p.y = transformedY; + return ErrorCode::SUCCESS; + +} + +void cropRasterByLatLon(const char* inputFile, const char* outputFile,double minLon, double maxLon, double minLat, double maxLat) { + // 初始化 GDAL 库 + GDALAllRegister(); + + // 打开栅格数据集 + GDALDataset* poDataset = (GDALDataset*)GDALOpen(inputFile, GA_ReadOnly); + if (poDataset == nullptr) { + std::cerr << "Failed to open input raster." << std::endl; + return; + } + + // 获取栅格数据的地理参考信息 + double adfGeoTransform[6]; + if (poDataset->GetGeoTransform(adfGeoTransform) != CE_None) { + std::cerr << "Failed to get geotransform." << std::endl; + GDALClose(poDataset); + return; + } + + // 获取输入影像的投影信息 + const char* projection = poDataset->GetProjectionRef(); + + // 根据经纬度计算出裁剪区域对应的栅格像素坐标 + int xMin = (int)((minLon - adfGeoTransform[0]) / adfGeoTransform[1]); + int xMax = (int)((maxLon - adfGeoTransform[0]) / adfGeoTransform[1]); + int yMin = (int)((maxLat - adfGeoTransform[3]) / adfGeoTransform[5]); + int yMax = (int)((minLat - adfGeoTransform[3]) / adfGeoTransform[5]); + + // 创建裁剪区域的目标栅格数据集 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (poDriver == nullptr) { + std::cerr << "Failed to get GTiff driver." << std::endl; + GDALClose(poDataset); + return; + } + + // 创建输出栅格数据集,指定尺寸 + int width = xMax - xMin; + int height = yMax - yMin; + GDALDataset* poOutDataset = poDriver->Create(outputFile, width, height, poDataset->GetRasterCount(), GDT_Float32, nullptr); + if (poOutDataset == nullptr) { + std::cerr << "Failed to create output raster." << std::endl; + GDALClose(poDataset); + return; + } + + // 设置输出栅格的投影信息和地理变换 + poOutDataset->SetProjection(projection); + double newGeoTransform[6] = { adfGeoTransform[0] + xMin * adfGeoTransform[1], adfGeoTransform[1], 0.0, adfGeoTransform[3] + yMin * adfGeoTransform[5], 0.0, adfGeoTransform[5] }; + poOutDataset->SetGeoTransform(newGeoTransform); + + // 循环读取源数据并写入目标数据集 + for (int i = 0; i < poDataset->GetRasterCount(); ++i) { + GDALRasterBand* poBand = poDataset->GetRasterBand(i + 1); + GDALRasterBand* poOutBand = poOutDataset->GetRasterBand(i + 1); + + // 读取源数据 + int* pData = new int[width * height]; + poBand->RasterIO(GF_Read, xMin, yMin, width, height, pData, width, height, GDT_Int32, 0, 0); + + // 写入目标数据 + poOutBand->RasterIO(GF_Write, 0, 0, width, height, pData, width, height, GDT_Int32, 0, 0); + + delete[] pData; + } + + qDebug() << "Raster cropped and saved to: " << outputFile ; + + // 清理 + GDALClose(poDataset); + GDALClose(poOutDataset); +} + + +ErrorCode DEM2XYZRasterAndSlopRaster(QString dempath, QString demxyzpath, QString demsloperPath) +{ + gdalImage demds(dempath); + gdalImage demxyz = CreategdalImage(demxyzpath, demds.height, demds.width, 3, demds.gt, demds.projection, true, true);// X,Y,Z + + // 分块计算并转换为XYZ + + Eigen::MatrixXd demArr = demds.getData(0, 0, demds.height, demds.width, 1); + Eigen::MatrixXd demR = demArr; + Landpoint LandP{ 0,0,0 }; + Point3 GERpoint{ 0,0,0 }; + double R = 0; + double dem_row = 0, dem_col = 0, dem_alt = 0; + + long line_invert = 1000; + + double rowidx = 0; + double colidx = 0; + for (int max_rows_ids = 0; max_rows_ids < demds.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd demdata = demds.getData(max_rows_ids, 0, line_invert, demds.width, 1); + Eigen::MatrixXd xyzdata_x = demdata.array() * 0; + Eigen::MatrixXd xyzdata_y = demdata.array() * 0; + Eigen::MatrixXd xyzdata_z = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + rowidx = i + max_rows_ids; + colidx = j; + demds.getLandPoint(rowidx, colidx, demdata(i, j), LandP); // 获取地理坐标 + LLA2XYZ(LandP, GERpoint); // 经纬度转换为地心坐标系 + xyzdata_x(i, j) = GERpoint.x; + xyzdata_y(i, j) = GERpoint.y; + xyzdata_z(i, j) = GERpoint.z; + } + } + demxyz.saveImage(xyzdata_x, max_rows_ids, 0, 1); + demxyz.saveImage(xyzdata_y, max_rows_ids, 0, 2); + demxyz.saveImage(xyzdata_z, max_rows_ids, 0, 3); + } + + + // 计算坡向角 + gdalImage demsloperxyz = CreategdalImage(demsloperPath, demds.height, demds.width, 4, demds.gt, demds.projection, true, true);// X,Y,Z,cosangle + + line_invert = 1000; + long start_ids = 0; + long dem_rows = 0, dem_cols = 0; + + for (start_ids = 1; start_ids < demds.height; start_ids = start_ids + line_invert) { + Eigen::MatrixXd demdata = demds.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 1); + long startlineid = start_ids; + Eigen::MatrixXd demsloper_x = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 1); + Eigen::MatrixXd demsloper_y = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 2); + Eigen::MatrixXd demsloper_z = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 3); + Eigen::MatrixXd demsloper_angle = demsloperxyz.getData(start_ids - 1, 0, line_invert + 2, demxyz.width, 4); + + Landpoint p0, p1, p2, p3, p4, pslopeVector, pp; + Vector3D slopeVector; + + dem_rows = demsloper_y.rows(); + dem_cols = demsloper_y.cols(); + double sloperAngle = 0; + Vector3D Zaxis = { 0,0,1 }; + + double rowidx = 0, colidx = 0; + + for (long i = 1; i < dem_rows - 1; i++) { + for (long j = 1; j < dem_cols - 1; j++) { + rowidx = i + startlineid; + colidx = j; + demds.getLandPoint(rowidx, colidx, demdata(i, j), p0); + demds.getLandPoint(rowidx - 1, colidx, demdata(i - 1, j), p1); + demds.getLandPoint(rowidx, colidx - 1, demdata(i, j - 1), p2); + demds.getLandPoint(rowidx + 1, colidx, demdata(i + 1, j), p3); + demds.getLandPoint(rowidx, colidx + 1, demdata(i, j + 1), p4); + + pslopeVector = getSlopeVector(p0, p1, p2, p3, p4); // 地面坡向矢量 + slopeVector = { pslopeVector.lon,pslopeVector.lat,pslopeVector.ati }; + pp = LLA2XYZ(p0); + Zaxis.x = pp.lon; + Zaxis.y = pp.lat; + Zaxis.z = pp.ati; + sloperAngle = getCosAngle(slopeVector, Zaxis); // 地面坡向角 + + demsloper_x(i, j) = slopeVector.x; + demsloper_y(i, j) = slopeVector.y; + demsloper_z(i, j) = slopeVector.z; + demsloper_angle(i, j) = sloperAngle; + } + } + demsloperxyz.saveImage(demsloper_x, start_ids - 1, 0, 1); + demsloperxyz.saveImage(demsloper_y, start_ids - 1, 0, 2); + demsloperxyz.saveImage(demsloper_z, start_ids - 1, 0, 3); + demsloperxyz.saveImage(demsloper_angle, start_ids - 1, 0, 4); + } + + + return ErrorCode::SUCCESS; +} + + +void ConvertCoordinateSystem(QString inRasterPath, QString outRasterPath, long outepsgcode) { + // 注册所有GDAL驱动 + GDALAllRegister(); + + // 打开输入栅格文件 + GDALDataset* srcDataset = (GDALDataset*)GDALOpen(inRasterPath.toUtf8().constData(), GA_ReadOnly); + if (!srcDataset) { + // 错误处理:输出文件打开失败 + // qDebug() << "无法打开输入文件:" << inRasterPath; + return; + } + + // 创建目标坐标系 + OGRSpatialReference targetSRS; + if (targetSRS.importFromEPSG(outepsgcode) != OGRERR_NONE) { + GDALClose(srcDataset); + // qDebug() << "无效的EPSG代码:" << outepsgcode; + return; + } + GDALDataType datetype = srcDataset->GetRasterBand(1)->GetRasterDataType(); + // 获取目标坐标系的WKT表示 + char* targetSRSWkt = nullptr; + targetSRS.exportToWkt(&targetSRSWkt); + + bool flag = (datetype == GDT_Byte || datetype == GDT_Int8 || datetype == GDT_Int16 ||datetype == GDT_UInt16 || datetype == GDT_Int32 || datetype == GDT_UInt32 || datetype == GDT_Int64 || datetype == GDT_UInt64); + + // 创建重投影后的虚拟数据集(Warped VRT) + GDALDataset* warpedVRT = flag? (GDALDataset*)GDALAutoCreateWarpedVRT( + srcDataset, + nullptr, // 输入坐标系(默认使用源数据) + targetSRSWkt, // 目标坐标系 + GRA_NearestNeighbour, // 重采样方法:双线性插值 + 0.0, // 最大误差(0表示自动计算) + nullptr // 其他选项 + ) :(GDALDataset*)GDALAutoCreateWarpedVRT( + srcDataset, + nullptr, // 输入坐标系(默认使用源数据) + targetSRSWkt, // 目标坐标系 + GRA_Bilinear, // 重采样方法:双线性插值 + 0.0, // 最大误差(0表示自动计算) + nullptr // 其他选项 + ); + CPLFree(targetSRSWkt); // 释放WKT内存 + + if (!warpedVRT) { + GDALClose(srcDataset); + qDebug() << u8"创建投影转换VRT失败"; + return; + } + + // 获取输出驱动(GeoTIFF格式) + QString filesuffer = getFileExtension(outRasterPath).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* driver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + if (!driver) { + GDALClose(warpedVRT); + GDALClose(srcDataset); + // qDebug() << "无法获取GeoTIFF驱动"; + return; + } + + // 创建输出栅格文件 + GDALDataset* dstDataset = driver->CreateCopy( + outRasterPath.toUtf8().constData(), // 输出文件路径 + warpedVRT, // 输入数据集(VRT) + false, // 是否严格复制 + nullptr, // 创建选项 + nullptr, // 进度回调 + nullptr // 回调参数 + ); + + if (!dstDataset) { + // qDebug() << "创建输出文件失败:" << outRasterPath; + GDALClose(warpedVRT); + GDALClose(srcDataset); + return; + } + + // 释放资源 + GDALClose(dstDataset); + GDALClose(warpedVRT); + GDALClose(srcDataset); +} + + +void ResampleByReferenceRasterB(QString pszSrcFile, QString RefrasterBPath, QString pszOutFile, GDALResampleAlg eResample) { + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile.toLocal8Bit().constData(), GA_ReadOnly); + if (pDSrc == NULL) { + qDebug() << u8"do not open In Raster file: " << pszSrcFile; + return ; + } + + GDALDataset* pDRef = (GDALDataset*)GDALOpen(RefrasterBPath.toLocal8Bit().constData(), GA_ReadOnly); + if (pDRef == NULL) { + qDebug() << u8"do not open Ref Raster file: " << RefrasterBPath; + return; + } + + QString filesuffer = getFileExtension(pszOutFile).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* pDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + + if (pDriver == NULL) { + qDebug() << "not open driver"; + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return ; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + // 锟斤拷锟矫伙拷锟酵队帮拷锟斤拷锟轿?拷锟斤拷锟揭伙拷锟?1锟?7 + if (strlen(pszSrcWKT) <= 0) { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + // oSRS.SetUTM(50, true); //锟斤拷锟斤拷锟斤拷 锟斤拷锟斤拷120锟斤拷 + // oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + } + + char* pdstSrcWKT = NULL; + pdstSrcWKT = const_cast(pDRef->GetProjectionRef()); + + // 锟斤拷锟矫伙拷锟酵队帮拷锟斤拷锟轿?拷锟斤拷锟揭伙拷锟?1锟?7 + if (strlen(pdstSrcWKT) <= 0) + { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + // oSRS.SetUTM(50, true); //锟斤拷锟斤拷锟斤拷 锟斤拷锟斤拷120锟斤拷 + // oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pdstSrcWKT); + } + + + int new_width = pDRef->GetRasterXSize(); + int new_height = pDRef->GetRasterYSize(); + double gt[6] ; + pDRef->GetGeoTransform(gt); + + // GDALDestroyGenImgProjTransformer(hTransformArg); + qDebug() << "create init GDALDataset "; + GDALDataset* pDDst = + pDriver->Create(pszOutFile.toLocal8Bit().constData(), new_width, new_height, nBandCount, dataType, NULL); + if (pDDst == NULL) { + qDebug() << "not create init GDALDataset "; + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)pDRef); + return ; + } + + pDDst->SetProjection(pdstSrcWKT); + pDDst->SetGeoTransform(gt); + + + qDebug() << "GDALCreateGenImgProjTransformer " << Qt::endl; + void* hTransformArg; + hTransformArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, NULL, pszSrcWKT, + FALSE, 0.0, 1); + qDebug() << "no proj "; + //(没锟斤拷投影锟斤拷影锟斤拷锟斤拷锟斤拷锟斤拷卟锟酵?拷锟?1锟?7) + if (hTransformArg == NULL) { + qDebug() << "hTransformArg create failure"; + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)pDRef); + return; + } + qDebug() << "has proj "; + double dGeoTrans[6] = { 0 }; + int nNewWidth = 0, nNewHeight = 0; + if (GDALSuggestedWarpOutput((GDALDatasetH)pDSrc, GDALGenImgProjTransform, hTransformArg, + dGeoTrans, &nNewWidth, &nNewHeight) + != CE_None) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)pDRef); + return ; + } + + + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + CPLSetConfigOption("GDAL_NUM_THREADS", "ALL_CPUS"); // 使用所有可用的CPU核心 + CPLSetConfigOption("GDAL_CACHEMAX", "16000"); // 设置缓存大小为500MB + // psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + + + + psWo->eResampleAlg = eResample; + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + qDebug() << "GDALCreateGenImgProjTransformer" ; + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = GDALCreateGenImgProjTransformer( + (GDALDatasetH)pDSrc, pszSrcWKT, (GDALDatasetH)pDDst, pszSrcWKT, FALSE, 0.0, 1); + ; + + qDebug() << "GDALCreateGenImgProjTransformer has created" << Qt::endl; + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)pDRef); + return ; + } + qDebug() << "ChunkAndWarpImage:" << new_width << "," << new_height << Qt::endl; + oWo.ChunkAndWarpMulti(0, 0, new_width, new_height); + GDALFlushCache(pDDst); + qDebug() << "ChunkAndWarpImage over" << Qt::endl; + // GDALDestroyGenImgProjTransformer(psWo->pTransformerArg); + // GDALDestroyWarpOptions(psWo); + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + GDALClose((GDALDatasetH)(GDALDatasetH)pDRef); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return ; +} + + + +void ResampleByReferenceRasterB(QString InrasterAPath, QString RefrasterBPath, QString OutrasterCPath) { + // 注册所有GDAL驱动 + GDALAllRegister(); + + // 打开参考栅格B + GDALDataset* refDS = (GDALDataset*)GDALOpen(RefrasterBPath.toUtf8().constData(), GA_ReadOnly); + if (!refDS) { + qDebug() << "无法打开参考栅格B:" << RefrasterBPath; + return; + } + + // 获取参考栅格的地理变换、投影和尺寸 + double geotransform[6]; + if (refDS->GetGeoTransform(geotransform) != CE_None) { + qDebug() << "获取参考栅格的地理变换失败。"; + GDALClose(refDS); + return; + } + + const char* proj = refDS->GetProjectionRef(); + int cols = refDS->GetRasterXSize(); + int rows = refDS->GetRasterYSize(); + GDALClose(refDS); // 获取信息后关闭参考栅格 + + // 打开输入栅格A + GDALDataset* srcDS = (GDALDataset*)GDALOpen(InrasterAPath.toUtf8().constData(), GA_ReadOnly); + if (!srcDS) { + qDebug() << "无法打开输入栅格A:" << InrasterAPath; + return; + } + + // 获取输入栅格的波段数和数据类型 + int nBands = srcDS->GetRasterCount(); + if (nBands == 0) { + qDebug() << "输入栅格没有波段数据。"; + GDALClose(srcDS); + return; + } + GDALDataType dataType = srcDS->GetRasterBand(1)->GetRasterDataType(); + + // 创建输出栅格C + GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (!driver) { + qDebug() << "无法获取GeoTIFF驱动。"; + GDALClose(srcDS); + return; + } + + GDALDataset* dstDS = driver->Create( + OutrasterCPath.toUtf8().constData(), + cols, + rows, + nBands, + dataType, + nullptr + ); + if (!dstDS) { + qDebug() << "无法创建输出栅格:" << OutrasterCPath; + GDALClose(srcDS); + return; + } + + // 设置输出栅格的地理变换和投影 + dstDS->SetGeoTransform(geotransform); + dstDS->SetProjection(proj); + + // 配置GDAL Warp选项 + GDALWarpOptions* psWO = GDALCreateWarpOptions(); + psWO->hSrcDS = srcDS; + psWO->hDstDS = dstDS; + psWO->nBandCount = nBands; + psWO->panSrcBands = (int*)CPLMalloc(nBands * sizeof(int)); + psWO->panDstBands = (int*)CPLMalloc(nBands * sizeof(int)); + for (int i = 0; i < nBands; ++i) { + psWO->panSrcBands[i] = i + 1; + psWO->panDstBands[i] = i + 1; + } + psWO->eResampleAlg = GRA_NearestNeighbour; // 使用最近邻重采样 + + // 初始化坐标转换器 + psWO->pfnTransformer = GDALGenImgProjTransform; + psWO->pTransformerArg = GDALCreateGenImgProjTransformer( + srcDS, GDALGetProjectionRef(srcDS), + dstDS, GDALGetProjectionRef(dstDS), + FALSE, 0.0, 1 + ); + if (!psWO->pTransformerArg) { + qDebug() << "创建坐标转换器失败。"; + GDALDestroyWarpOptions(psWO); + GDALClose(srcDS); + GDALClose(dstDS); + return; + } + + // 执行Warp操作 + GDALWarpOperation oWarp; + if (oWarp.Initialize(psWO) != CE_None) { + qDebug() << "初始化Warp操作失败。"; + GDALDestroyGenImgProjTransformer(psWO->pTransformerArg); + GDALDestroyWarpOptions(psWO); + GDALClose(srcDS); + GDALClose(dstDS); + return; + } + + CPLErr eErr = oWarp.ChunkAndWarpImage(0, 0, cols, rows); + if (eErr != CE_None) { + qDebug() << "执行Warp操作失败。"; + } + + // 清理资源 + GDALDestroyGenImgProjTransformer(psWO->pTransformerArg); + GDALDestroyWarpOptions(psWO); + GDALClose(srcDS); + GDALClose(dstDS); + + qDebug() << "重采样完成,结果已保存至:" << OutrasterCPath; +} + + +void CreateSARIntensityByLookTable(QString IntensityRasterPath, + QString LookTableRasterPath, + QString SARIntensityPath, + long min_rid, long max_rid, + long min_cid, long max_cid, + std::function processBarShow +) +{ + gdalImage looktableds(LookTableRasterPath); + gdalImage geoIntensity(IntensityRasterPath); + gdalImage SARIntensity= CreategdalImageDouble(SARIntensityPath,max_rid-min_rid,max_cid-min_cid,1); + + long blockYSize = Memory1GB / looktableds.width / 8 * 2; + + Eigen::MatrixXd SARData = SARIntensity.getData(0, 0, SARIntensity.height, SARIntensity.width, 1); + SARData = SARData.array() * 0; + // 分块处理 + for (int yOff = 0; yOff < looktableds.height; yOff += blockYSize) + { + processBarShow(yOff, looktableds.height); + qDebug() << "Process : [" << yOff * 100.0 / looktableds.height << " % ]"; + Eigen::MatrixXd rowData = looktableds.getData(yOff, 0, blockYSize, looktableds.width, 1); + Eigen::MatrixXd colData = looktableds.getData(yOff, 0, blockYSize, looktableds.width, 2); + Eigen::MatrixXd geoData = geoIntensity.getData(yOff, 0, blockYSize, looktableds.width, 1); + + for (long i = 0; i < rowData.rows(); i++) { + for (long j = 0; j < rowData.cols(); j++) { + long r =round( rowData(i,j))-min_rid; + long c = round(colData(i, j))-min_cid; + + if (r >= 0 && r < SARIntensity.height && c >= 0 && c < SARIntensity.width) { + SARData(r, c) = SARData(r, c) + geoData(i, j); + } + } + } + } + SARIntensity.saveImage(SARData, 0, 0, 1); + qDebug() << "Process : [ 100 % ]"; + processBarShow(1000,1000); +} + + +bool saveEigenMatrixXd2Bin(Eigen::MatrixXd data, QString dataStrPath) +{ + + Eigen::MatrixXd gt = Eigen::MatrixXd::Zero(2, 3); + + gdalImage img = CreategdalImageDouble(dataStrPath, data.rows(), data.cols(), 1, gt, "", false, true, true); + + img.saveImage(data, 0, 0, 1); + + return true; +} + + + + diff --git a/BaseTool/ImageOperatorBase.h b/BaseTool/ImageOperatorBase.h new file mode 100644 index 0000000..3af8396 --- /dev/null +++ b/BaseTool/ImageOperatorBase.h @@ -0,0 +1,631 @@ +#pragma once +/** + * 影像数据操作项 + * 所有数据相关的操作,都是基于ENVI的数据格式 + * 影像读写操作时基于 GDAL 库 + * **/ + + + +#ifndef IMAGEOPERATORBASE_H +#define IMAGEOPERATORBASE_H +#include "BaseConstVariable.h" +#include "GeoOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for CPLMalloc() +#include "LogInfoCls.h" +#include +#include +#include +#include "ShowProessAbstract.h" + + + +enum ProjectStripDelta { + Strip_6, // 6度带 + Strip_3 +}; + +enum CoordinateSystemType { // 坐标系类型 + GeoCoordinateSystem, + ProjectCoordinateSystem, + UNKNOW +}; + +struct PointRaster { // 影像坐标点 + double x; + double y; + double z; +}; + + +struct PointXYZ { + double x, y, z; +}; + +struct PointGeo { + double lon, lat, ati; +}; + +struct PointImage { + double pixel_x, pixel_y; +}; + + + +struct ImageGEOINFO { + int width; + int height; + int bandnum; +}; + + +enum GDALREADARRCOPYMETHOD { + MEMCPYMETHOD, // 直接拷贝 + VARIABLEMETHOD // 变量赋值 + +}; + + + + + + +/// 根据经纬度获取 +/// EPSG代码,根据经纬度返回对应投影坐标系统,其中如果在中华人民共和国境内,默认使用 +/// CGCS2000坐标系统(EPSG 4502 ~ 4512 6度带,EPSG 4534 ~ 4554 3度带),其余地方使用WGS坐标系统, +/// 投影方法 高斯克吕格(国内), 高斯克吕格 +/// \param long 经度 +/// \param lat 纬度 +/// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误 +long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState= ProjectStripDelta::Strip_6); + +long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat); + +long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat); + + +QString BASECONSTVARIABLEAPI GetProjectionNameFromEPSG(long epsgCode); + + +long BASECONSTVARIABLEAPI GetEPSGFromRasterFile(QString filepath); + +std::shared_ptr BASECONSTVARIABLEAPI GetCenterPointInRaster(QString filepath); + +CoordinateSystemType BASECONSTVARIABLEAPI getCoordinateSystemTypeByEPSGCode(long EPSGCODE); + + +// 文件打开 // 当指令销毁时,调用GDALClose 销毁类型 +std::shared_ptr BASECONSTVARIABLEAPI OpenDataset(const QString& in_path, GDALAccess rwmode = GA_ReadOnly); +void BASECONSTVARIABLEAPI CloseDataset(GDALDataset* ptr); + +// 数据格式转换 +int BASECONSTVARIABLEAPI TIFF2ENVI(QString in_tiff_path, QString out_envi_path); +int BASECONSTVARIABLEAPI ENVI2TIFF(QString in_envi_path, QString out_tiff_path); + +// 保存影像数据 --直接保存 ENVI 文件 + +int BASECONSTVARIABLEAPI CreateDataset(QString new_file_path, int height, int width, int band_num, double* gt, QString projection, GDALDataType gdal_dtype, bool need_gt); // 创建文件 + +int BASECONSTVARIABLEAPI saveDataset(QString new_file_path, int start_line, int start_cols, int band_ids, int datacols, int datarows, void* databuffer); + +// 根据限制条件估算分块大小 +int BASECONSTVARIABLEAPI block_num_pre_memory(int width, int height, GDALDataType gdal_dtype, double memey_size); + +// 将结果转换为复数 或者 实数 +Eigen::Matrix BASECONSTVARIABLEAPI ReadComplexMatrixData(int start_line, int width, int line_num, std::shared_ptr rasterDataset, GDALDataType gdal_datatype); + +Eigen::Matrix BASECONSTVARIABLEAPI ReadMatrixDoubleData(int start_line, int width, int line_num, std::shared_ptr rasterDataset, GDALDataType gdal_datatype, int band_idx); + +Eigen::MatrixXd BASECONSTVARIABLEAPI getGeoTranslationArray(QString in_path); +ImageGEOINFO BASECONSTVARIABLEAPI getImageINFO(QString in_path); + +GDALDataType BASECONSTVARIABLEAPI getGDALDataType(QString fileptah); + + +struct RasterExtend { + double min_x; + double min_y; + double max_x; + double max_y; +}; + + + + + +/// +/// gdalImage图像操作类 +/// + +class BASECONSTVARIABLEAPI gdalImage +{ + +public: // 方法 + gdalImage(); + gdalImage(const QString& raster_path); + ~gdalImage(); + virtual void setHeight(int); + virtual void setWidth(int); + virtual void setTranslationMatrix(Eigen::MatrixXd gt); + virtual void setData(Eigen::MatrixXd, int data_band_ids = 1); + virtual Eigen::MatrixXd getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + virtual Eigen::MatrixXf getDataf(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + virtual Eigen::MatrixXi getDatai(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + virtual ErrorCode getData(double* data, int start_row, int start_col, int rows_count, int cols_count, int band_ids); + virtual ErrorCode getData(long* data, int start_row, int start_col, int rows_count, int cols_count, int band_ids); + virtual Eigen::MatrixXd getGeoTranslation(); + virtual GDALDataType getDataType(); + virtual void saveImage(Eigen::MatrixXd, int start_row, int start_col, int band_ids); + virtual void saveImage(Eigen::MatrixXf, int start_row, int start_col, int band_ids); + virtual void saveImage(Eigen::MatrixXi, int start_row, int start_col, int band_ids); + virtual void saveImage(std::shared_ptr, int start_row, int start_col,int rowcount,int colcount, int band_ids); + virtual void saveImage(std::shared_ptr, int start_row, int start_col, int rowcount, int colcount, int band_ids); + virtual void saveImage(std::shared_ptr, int start_row, int start_col, int rowcount, int colcount, int band_ids); + + virtual void saveImage(); + virtual void setNoDataValue(double nodatavalue, int band_ids); + virtual void setNoDataValuei(int nodatavalue, int band_ids); + virtual double getNoDataValue(int band_ids); + virtual int getNoDataValuei(int band_ids); + virtual int InitInv_gt(); + virtual Landpoint getRow_Col(double lon, double lat); + virtual Landpoint getLandPoint(double i, double j, double ati); + + virtual void getLandPoint(double i, double j, double ati, Landpoint& Lp); + + virtual double mean(int bandids = 1); + double BandmaxValue(int bandids = 1); + double BandminValue(int bandids = 1); + virtual GDALRPCInfo getRPC(); + virtual Eigen::MatrixXd getLandPoint(Eigen::MatrixXd points); + + virtual Eigen::MatrixXd getHist(int bandids); + + virtual RasterExtend getExtend(); + + + + + +public: + QString img_path; // 图像文件 + int height; // 高 + int width; // 宽 + int band_num;// 波段数 + int start_row;// + int start_col;// + int data_band_ids; + Eigen::MatrixXd gt; // 变换矩阵 + Eigen::MatrixXd inv_gt; // 逆变换矩阵 + Eigen::MatrixXd data; + QString projection; +}; + + + +/// +/// gdalImage图像操作类 +/// +class BASECONSTVARIABLEAPI gdalImageComplex :public gdalImage +{ + +public: // 方法 + gdalImageComplex(const QString& raster_path); + ~gdalImageComplex(); + void setData(Eigen::MatrixXcd); + void saveImage(Eigen::MatrixXcd data, int start_row, int start_col, int band_ids); + void saveImage(std::shared_ptr> data, long start_row, long start_col, long rowCount, long colCount, int band_ids); + void saveImage(std::complex* data, long start_row, long start_col, long rowcount, long colcount, int banids); + + Eigen::MatrixXcd getDataComplex(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + std::shared_ptr> getDataComplexSharePtr(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + + void saveComplexImage();//override; + void savePreViewImage(); +public: + Eigen::MatrixXcd data; +}; + + +bool BASECONSTVARIABLEAPI CopyProjectTransformMatrixFromRasterAToRasterB(QString RasterAPath, QString RasterBPath); + + +// 创建影像 +gdalImage BASECONSTVARIABLEAPI CreategdalImageDouble(QString& img_path, int height, int width, int band_num, bool overwrite = false, bool isEnvi = false); +gdalImage BASECONSTVARIABLEAPI CreategdalImageFloat(QString& img_path, int height, int width, int band_num, bool overwrite = false, bool isEnvi = false); +gdalImage BASECONSTVARIABLEAPI CreategdalImageDouble(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection, bool need_gt = true, bool overwrite = false, bool isEnvi = false); +gdalImage BASECONSTVARIABLEAPI CreategdalImage(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection,bool need_gt = true, bool overwrite = false, bool isEnvi = false, GDALDataType datetype = GDT_Float32); +gdalImage BASECONSTVARIABLEAPI CreategdalImage(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, long espgcode, GDALDataType eType = GDT_Float32, bool need_gt = true, bool overwrite = false, bool isENVI = false); + +gdalImageComplex BASECONSTVARIABLEAPI CreategdalImageComplex(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection, bool need_gt = true, bool overwrite = false); +gdalImageComplex BASECONSTVARIABLEAPI CreategdalImageComplexNoProj(const QString& img_path, int height, int width, int band_num, bool overwrite = true); + +gdalImageComplex BASECONSTVARIABLEAPI CreateEchoComplex(const QString& img_path, int height, int width, int band_num); + +ErrorCode BASECONSTVARIABLEAPI DEM2XYZRasterAndSlopRaster(QString dempath, QString demxyzpath, QString demsloperPath); + +int BASECONSTVARIABLEAPI ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample); + +void BASECONSTVARIABLEAPI resampleRaster(const char* inputRaster, const char* outputRaster, double targetPixelSizeX, double targetPixelSizeY); + +void BASECONSTVARIABLEAPI cropRasterByLatLon(const char* inputFile, const char* outputFile, double minLon, double maxLon, double minLat, double maxLat); + +int BASECONSTVARIABLEAPI ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample = GRIORA_Bilinear); + +void BASECONSTVARIABLEAPI transformRaster(const char* inputFile, const char* outputFile, int sourceEPSG, int targetEPSG); + +ErrorCode BASECONSTVARIABLEAPI transformCoordinate(double x, double y, int sourceEPSG, int targetEPSG, Point2& p); + +int BASECONSTVARIABLEAPI alignRaster(QString inputPath, QString referencePath, QString outputPath, GDALResampleAlg eResample); + + +void BASECONSTVARIABLEAPI ResampleByReferenceRasterB(QString pszSrcFile, QString RefrasterBPath, QString pszOutFile, GDALResampleAlg eResample); + +//--------------------- 保存文博 ------------------------------- + +int BASECONSTVARIABLEAPI saveMatrixXcd2TiFF(Eigen::MatrixXcd data, QString out_tiff_path); + +//---------------------------------------------------- + +void BASECONSTVARIABLEAPI clipRaster(QString inRasterPath, QString outRasterPath, long minRow, long maxRow, long minCol, long maxCol); + +// 坐标系转换 +void BASECONSTVARIABLEAPI ConvertCoordinateSystem(QString inRasterPath, QString outRasterPath, long outepsgcode); + +//--------------------- 图像合并流程 ------------------------------ +enum MERGEMODE +{ + MERGE_GEOCODING, +}; + +void BASECONSTVARIABLEAPI MergeTiffs(QList inputFiles, QString outputFile); + +ErrorCode BASECONSTVARIABLEAPI MergeRasterProcess(QVector filepath, QString outfileptah, QString mainString, MERGEMODE mergecode = MERGEMODE::MERGE_GEOCODING, bool isENVI = false, ShowProessAbstract* dia = nullptr); + + +ErrorCode BASECONSTVARIABLEAPI MergeRasterInGeoCoding(QVector inimgs, gdalImage resultimg, gdalImage maskimg, ShowProessAbstract* dia = nullptr); + + +// 保存矩阵转换为envi文件,默认数据格式为double +bool BASECONSTVARIABLEAPI saveEigenMatrixXd2Bin(Eigen::MatrixXd data, QString dataStrPath); + + +// 测试 +void BASECONSTVARIABLEAPI testOutAntPatternTrans(QString antpatternfilename, double* antPatternArr, double starttheta, double deltetheta, double startphi, double deltaphi, long thetanum, long phinum); +void BASECONSTVARIABLEAPI testOutAmpArr(QString filename, float* amp, long rowcount, long colcount); +void BASECONSTVARIABLEAPI testOutAmpArr(QString filename, double* amp, long rowcount, long colcount); +void BASECONSTVARIABLEAPI testOutClsArr(QString filename, long* amp, long rowcount, long colcount); +void BASECONSTVARIABLEAPI testOutComplexDoubleArr(QString filename, std::complex* data, long rowcount, long colcount); +void BASECONSTVARIABLEAPI testOutDataArr(QString filename, double* data, long rowcount, long colcount); +void BASECONSTVARIABLEAPI testOutDataArr(QString filename, float* data, long rowcount, long colcount); +void BASECONSTVARIABLEAPI testOutDataArr(QString filename, long* data, long rowcount, long colcount); + + + +void BASECONSTVARIABLEAPI CreateSARIntensityByLookTable(QString IntensityRasterPath, QString LookTableRasterPath, QString SARIntensityPath, long min_rid, long max_rid, long min_cid, long max_cid, std::function processBarShow = {}); + +bool BASECONSTVARIABLEAPI ConvertVrtToEnvi(QString vrtPath, QString outPath); + + + + +void BASECONSTVARIABLEAPI MultiLookRaster(QString inRasterPath, QString outRasterPath, long looklineNumrow, long looklineNumCol); +ErrorCode BASECONSTVARIABLEAPI Complex2PhaseRaster(QString inComplexPath, QString outRasterPath); +ErrorCode BASECONSTVARIABLEAPI Complex2dBRaster(QString inComplexPath, QString outRasterPath); +ErrorCode BASECONSTVARIABLEAPI Complex2AmpRaster(QString inComplexPath, QString outRasterPath); +ErrorCode BASECONSTVARIABLEAPI amp2dBRaster(QString inPath, QString outRasterPath); + + +ErrorCode BASECONSTVARIABLEAPI ResampleDEM(QString indemPath, QString outdemPath, double gridx, double gridy); + + +void BASECONSTVARIABLEAPI CloseAllGDALRaster(); + + + +//--------------------- 图像文件读写 ------------------------------ + + + +template +inline std::shared_ptr readDataArr(gdalImage& imgds, long start_row, long start_col, long& rows_count, long& cols_count, int band_ids, GDALREADARRCOPYMETHOD method) +{ + std::shared_ptr result = nullptr; + + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(imgds.img_path.toUtf8().constData(), GA_ReadOnly)); // 锟斤拷只斤拷式锟斤拷取斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= imgds.height ? rows_count : imgds.height - start_row; + cols_count = start_col + cols_count <= imgds.width ? cols_count : imgds.width - start_col; + + int64_t pixel_count64 = static_cast(rows_count)* static_cast(cols_count); + + + //Eigen::MatrixXd datamatrix(rows_count, cols_count); + + if (gdal_datatype == GDT_Byte) { + char* temp = new char[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + + delete[] temp; + } + else if (gdal_datatype == GDT_UInt16) { + unsigned short* temp = new unsigned short[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int16) { + short* temp = new short[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt32) { + unsigned int* temp = new unsigned int[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int32) { + int* temp = new int[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + delete[] temp; + } + // else if (gdal_datatype == GDT_UInt64) { + // unsigned long* temp = new unsigned long[pixel_count64]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + //rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { for (int j = 0; j < + //cols_count; j++) { datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + // } + // else if (gdal_datatype == GDT_Int64) { + // long* temp = new long[pixel_count64]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + //rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { for (int j = 0; j < + //cols_count; j++) { datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + // } + else if (gdal_datatype == GDT_Float32) { + float* temp = new float[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Float64) { + double* temp = new double[pixel_count64]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i]); + } + } + delete[] temp; + } + //else if (gdal_datatype == GDT_CFloat32) { + // if (std::is_same>::value || std::is_same>::value) { + // float* temp = new float[pixel_count64 * 2]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + // result = std::shared_ptr(new T[pixel_count64], delArrPtr); + // if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + // std::memcpy(result.get(), temp, pixel_count64); + // } + // else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + // long count = pixel_count64; + // for (long i = 0; i < count; i++) { + // result.get()[i] = T(temp[i * 2], + // temp[i * 2 + 1]); + // } + // } + // delete[] temp; + // } + // else { + // result = nullptr; + // } + //} + //else if (gdal_datatype == GDT_CFloat64 ) { + // if (std::is_same>::value || std::is_same>::value) { + // double* temp = new double[pixel_count64 * 2]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + // result = std::shared_ptr(new T[pixel_count64], delArrPtr); + // if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + // std::memcpy(result.get(), temp, pixel_count64); + // } + // else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + // long count = pixel_count64; + // for (long i = 0; i < count; i++) { + // result.get()[i] = T(temp[i * 2], + // temp[i * 2 + 1]); + // } + // } + // delete[] temp; + // } + // else { + // result = nullptr; + // } + //} + else { + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // 锟酵放伙拷斤拷 + omp_destroy_lock(&lock); // 劫伙拷斤拷 + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return result; +}; + +template +inline std::shared_ptr readDataArrComplex(gdalImageComplex& imgds, long start_row, long start_col, long& rows_count, long& cols_count, int band_ids, GDALREADARRCOPYMETHOD method) +{ + std::shared_ptr result = nullptr; + + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(imgds.img_path.toUtf8().constData(), GA_ReadOnly)); // 锟斤拷只斤拷式锟斤拷取斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= imgds.height ? rows_count : imgds.height - start_row; + cols_count = start_col + cols_count <= imgds.width ? cols_count : imgds.width - start_col; + + int64_t pixel_count64 = static_cast(rows_count) * static_cast(cols_count); + + //Eigen::MatrixXd datamatrix(rows_count, cols_count); + + if (gdal_datatype == GDT_CFloat32) { + if (std::is_same>::value || std::is_same>::value) { + float* temp = new float[pixel_count64 * 2]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i * 2], + temp[i * 2 + 1]); + } + } + delete[] temp; + } + else { + result = nullptr; + } + } + else if (gdal_datatype == GDT_CFloat64) { + if (std::is_same>::value || std::is_same>::value) { + double* temp = new double[pixel_count64 * 2]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + result = std::shared_ptr(new T[pixel_count64], delArrPtr); + if (method == GDALREADARRCOPYMETHOD::MEMCPYMETHOD) { + std::memcpy(result.get(), temp, pixel_count64); + } + else if (method == GDALREADARRCOPYMETHOD::VARIABLEMETHOD) { + long count = pixel_count64; + for (long i = 0; i < count; i++) { + result.get()[i] = T(temp[i * 2], + temp[i * 2 + 1]); + } + } + delete[] temp; + } + else { + result = nullptr; + } + } + else { + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // 锟酵放伙拷斤拷 + omp_destroy_lock(&lock); // 劫伙拷斤拷 + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return result; +}; + + + + +//--------------------- 图像分块 ------------------------------ + + + + + + + +#endif + diff --git a/BaseTool/LogInfoCls.cpp b/BaseTool/LogInfoCls.cpp new file mode 100644 index 0000000..a569c7e --- /dev/null +++ b/BaseTool/LogInfoCls.cpp @@ -0,0 +1,233 @@ +#include "stdafx.h" +#include "LogInfoCls.h" + +std::string errorCode2errInfo(ErrorCode e) +{ + switch (e) + { + _CASE_STR(SUCCESS); + _CASE_STR(VIRTUALABSTRACT); + _CASE_STR(FAIL); + _CASE_STR(FILENOFOUND); + _CASE_STR(OrbitNodeNotEnough); + _CASE_STR(XYDataPointNotEqual); + _CASE_STR(FILEOPENFAIL ); + _CASE_STR(XMLPARSEFAIL ); + _CASE_STR(XMLNOTFOUNDElEMENT ); + _CASE_STR(FILEPATHISEMPTY); + _CASE_STR(FOLDER_NOT_EXIST); + _CASE_STR(FILE_NOT_EXIST); + _CASE_STR(FIND_ID_ERROR); + _CASE_STR(INSERT_ID_ERROR); + _CASE_STR(EPSGCODE_NOTSAME); + _CASE_STR(EPSGCODE_NOTSUPPORT); + _CASE_STR(RASTERBAND_NOTEQUAL); + _CASE_STR(RASTER_DATETYPE_NOTSAME); + //GSL 1xx + _CASE_STR(Error_GSL_FAILURE ); + _CASE_STR(Error_GSL_CONTINUE ); + _CASE_STR(Error_GSL_EDOM ); + _CASE_STR(Error_GSL_ERANGE ); + _CASE_STR(Error_GSL_EFAULT ); + _CASE_STR(Error_GSL_EINVAL ); + _CASE_STR(Error_GSL_EFAILED ); + _CASE_STR(Error_GSL_EFACTOR ); + _CASE_STR(Error_GSL_ESANITY ); + _CASE_STR(Error_GSL_ENOMEM ); + _CASE_STR(Error_GSL_EBADFUNC ); + _CASE_STR(Error_GSL_ERUNAWAY ); + _CASE_STR(Error_GSL_EMAXITER ); + _CASE_STR(Error_GSL_EZERODIV ); + _CASE_STR(Error_GSL_EBADTOL ); + _CASE_STR(Error_GSL_ETOL ); + _CASE_STR(Error_GSL_EUNDRFLW ); + _CASE_STR(Error_GSL_EOVRFLW ); + _CASE_STR(Error_GSL_ELOSS ); + _CASE_STR(Error_GSL_EROUND ); + _CASE_STR(Error_GSL_EBADLEN ); + _CASE_STR(Error_GSL_ENOTSQR ); + _CASE_STR(Error_GSL_ESING ); + _CASE_STR(Error_GSL_EDIVERGE ); + _CASE_STR(Error_GSL_EUNSUP ); + _CASE_STR(Error_GSL_EUNIMPL ); + _CASE_STR(Error_GSL_ECACHE ); + _CASE_STR(Error_GSL_ETABLE ); + _CASE_STR(Error_GSL_ENOPROG ); + _CASE_STR(Error_GSL_ENOPROGJ ); + _CASE_STR(Error_GSL_ETOLF ); + _CASE_STR(Error_GSL_ETOLX ); + _CASE_STR(Error_GSL_ETOLG ); + _CASE_STR(Error_GSL_EOF ); + // RFPC + _CASE_STR(RFPC_PARAMSISEMPTY); + _CASE_STR(ECHO_L0DATA_NOTOPEN); + _CASE_STR(ECHO_L0DATA_ROW_COL_NOEQUAL); + _CASE_STR(ECHO_L0DATA_PRFIDXOUTRANGE); + _CASE_STR(ECHO_L0DATA_GPSFILEFORMATERROR); + _CASE_STR(ECHO_L0DATA_ECHOFILEFORMATERROR); + _CASE_STR(ECHO_L0DATA_ECHOFILENOTOPEN); + _CASE_STR(ECHO_L0DATA_GPSFILEFNOTOPEN); + _CASE_STR(ECHO_L0DATA_XMLFILENOTOPEN); + _CASE_STR(OUTOFRANGE); + _CASE_STR(ECHO_L0DATA_XMLNAMEERROR); + // + _CASE_STR(TBP_L0OPENFAIL); + + // + _CASE_STR(IMAGE_L1DATA_XMLNAMEERROR); + _CASE_STR(IMAGE_L1DATA_XMLNAMEOPENERROR); + + + default: + break; + } + return "UNKNOW_EVENT!"; +} + +ErrorCode GSLState2ErrorCode(int gslState) +{ + + switch (gslState) + { + case 0: + return ErrorCode::SUCCESS; + break; + case -1: + return ErrorCode::Error_GSL_FAILURE; + break; + case -2: + return ErrorCode::Error_GSL_CONTINUE; + break; + case 1: + return ErrorCode::Error_GSL_EDOM; // sqrt(-1) + break; + + case 2: + return ErrorCode::Error_GSL_ERANGE; // Χ exp(1e100) + break; + + case 3: + return ErrorCode::Error_GSL_EFAULT; // Чָ + break; + + case 4: + return ErrorCode::Error_GSL_EINVAL; // ûṩЧ + break; + + case 5: + return ErrorCode::Error_GSL_EFAILED; // ͨʧ + break; + + case 6: + return ErrorCode::Error_GSL_EFACTOR; // ӷֽʧ + break; + + case 7: + return ErrorCode::Error_GSL_ESANITY; // ǼʧܣͨӦ÷ + break; + + case 8: + return ErrorCode::Error_GSL_ENOMEM; // ڴʧ + break; + + case 9: + return ErrorCode::Error_GSL_EBADFUNC; // ûṩĺ + break; + + case 10: + return ErrorCode::Error_GSL_ERUNAWAY; // ʧ + break; + + case 11: + return ErrorCode::Error_GSL_EMAXITER; // + break; + + case 12: + return ErrorCode::Error_GSL_EZERODIV; // Խ + break; + + case 13: + return ErrorCode::Error_GSL_EBADTOL; // û̶ָЧ + break; + + case 14: + return ErrorCode::Error_GSL_ETOL; // δܴﵽ̶ָ + break; + + case 15: + return ErrorCode::Error_GSL_EUNDRFLW; // + break; + + case 16: + return ErrorCode::Error_GSL_EOVRFLW; // + break; + + case 17: + return ErrorCode::Error_GSL_ELOSS; // ʧ + break; + + case 18: + return ErrorCode::Error_GSL_EROUND; // ʧ + break; + + case 19: + return ErrorCode::Error_GSL_EBADLEN; // Ȳƥ + break; + + case 20: + return ErrorCode::Error_GSL_ENOTSQR; // Ƿ + break; + + case 21: + return ErrorCode::Error_GSL_ESING; // ⵽Ե + break; + + case 22: + return ErrorCode::Error_GSL_EDIVERGE; // ֻɢ + break; + + case 23: + return ErrorCode::Error_GSL_EUNSUP; // ԲӲ֧ + break; + + case 24: + return ErrorCode::Error_GSL_EUNIMPL; // δʵ + break; + + case 25: + return ErrorCode::Error_GSL_ECACHE; // + break; + + case 26: + return ErrorCode::Error_GSL_ETABLE; // + break; + + case 27: + return ErrorCode::Error_GSL_ENOPROG; // δܳȡýչ + break; + + case 28: + return ErrorCode::Error_GSL_ENOPROGJ; // ſɱδܸƽ + break; + + case 29: + return ErrorCode::Error_GSL_ETOLF; // ޷ﵽ F ̶ָ + break; + + case 30: + return ErrorCode::Error_GSL_ETOLX; // ޷ﵽ X ̶ָ + break; + + case 31: + return ErrorCode::Error_GSL_ETOLG; // ޷ﵽݶȵ̶ָ + break; + + case 32: + return ErrorCode::Error_GSL_EOF; // ļ + break; + + default: + return ErrorCode::Error_GSL_FAILURE; // δ֪󣬷һʧ + break; + } +} diff --git a/BaseTool/LogInfoCls.h b/BaseTool/LogInfoCls.h new file mode 100644 index 0000000..a906cfb --- /dev/null +++ b/BaseTool/LogInfoCls.h @@ -0,0 +1,103 @@ +#pragma once +/*****************************************************************//** + * \file LogInfoCls.h + * \brief ö࣬ԼشϢ + * + * \author + * \date October 2024 + *********************************************************************/ +#include "BaseConstVariable.h" +#include + +// 任 +#define _CASE_STR(x) case x : return #x; break; + + +enum ErrorCode { + SUCCESS = -1,// ִгɹ + VIRTUALABSTRACT = -2,// virtual abstract function not implement + FAIL=0, + FILENOFOUND = 1, + OrbitNodeNotEnough = 2, + XYDataPointNotEqual = 3, + FILEOPENFAIL = 4, + XMLPARSEFAIL = 5, + XMLNOTFOUNDElEMENT = 6, + FILEPATHISEMPTY = 7, + FOLDER_NOT_EXIST = 8, + FILE_NOT_EXIST = 9, + FIND_ID_ERROR = 10, + INSERT_ID_ERROR = 11, + EPSGCODE_NOTSAME = 12, + EPSGCODE_NOTSUPPORT = 13, + RASTERBAND_NOTEQUAL = 14, + RASTER_DATETYPE_NOTSAME = 15, + //GSL 1xx + Error_GSL_FAILURE = -101, + Error_GSL_CONTINUE = -102, /* iteration has not converged */ + Error_GSL_EDOM = 101, /* input domain error, e.g sqrt(-1) */ + Error_GSL_ERANGE = 102, /* output range error, e.g. exp(1e100) */ + Error_GSL_EFAULT = 103, /* invalid pointer */ + Error_GSL_EINVAL = 104, /* invalid argument supplied by user */ + Error_GSL_EFAILED = 105, /* generic failure */ + Error_GSL_EFACTOR = 106, /* factorization failed */ + Error_GSL_ESANITY = 107, /* sanity check failed - shouldn't happen */ + Error_GSL_ENOMEM = 108, /* malloc failed */ + Error_GSL_EBADFUNC = 109, /* problem with user-supplied function */ + Error_GSL_ERUNAWAY = 110, /* iterative process is out of control */ + Error_GSL_EMAXITER = 111, /* exceeded max number of iterations */ + Error_GSL_EZERODIV = 112, /* tried to divide by zero */ + Error_GSL_EBADTOL = 113, /* user specified an invalid tolerance */ + Error_GSL_ETOL = 114, /* failed to reach the specified tolerance */ + Error_GSL_EUNDRFLW = 115, /* underflow */ + Error_GSL_EOVRFLW = 116, /* overflow */ + Error_GSL_ELOSS = 117, /* loss of accuracy */ + Error_GSL_EROUND = 118, /* failed because of roundoff error */ + Error_GSL_EBADLEN = 119, /* matrix, vector lengths are not conformant */ + Error_GSL_ENOTSQR = 120, /* matrix not square */ + Error_GSL_ESING = 121, /* apparent singularity detected */ + Error_GSL_EDIVERGE = 122, /* integral or series is divergent */ + Error_GSL_EUNSUP = 123, /* requested feature is not supported by the hardware */ + Error_GSL_EUNIMPL = 124, /* requested feature not (yet) implemented */ + Error_GSL_ECACHE = 125, /* cache limit exceeded */ + Error_GSL_ETABLE = 126, /* table limit exceeded */ + Error_GSL_ENOPROG = 127, /* iteration is not making progress towards solution */ + Error_GSL_ENOPROGJ = 128, /* jacobian evaluations are not improving the solution */ + Error_GSL_ETOLF = 129, /* cannot reach the specified tolerance in F */ + Error_GSL_ETOLX = 130, /* cannot reach the specified tolerance in X */ + Error_GSL_ETOLG = 131, /* cannot reach the specified tolerance in gradient */ + Error_GSL_EOF = 132, /* end of file */ + + // RFPC + RFPC_PARAMSISEMPTY = 201, + // L0 + ECHO_L0DATA_NOTOPEN = 202, + ECHO_L0DATA_ROW_COL_NOEQUAL = 203, // л + ECHO_L0DATA_PRFIDXOUTRANGE = 204, // PRF Χ + ECHO_L0DATA_GPSFILEFORMATERROR = 205, // GPSļ + ECHO_L0DATA_ECHOFILEFORMATERROR = 206, // زļʽ + ECHO_L0DATA_ECHOFILENOTOPEN = 207, // زļ򿪴 + ECHO_L0DATA_GPSFILEFNOTOPEN = 208, // GPSļ򿪴 + ECHO_L0DATA_XMLFILENOTOPEN = 209, // xmlļ򿪴 + OUTOFRANGE = 210, // Χ + ECHO_L0DATA_XMLNAMEERROR = 211, // Χ + // BP + TBP_L0OPENFAIL = 301, // 0ļ򿪴 + + // L1ͼ + IMAGE_L1DATA_XMLNAMEERROR = 401, + IMAGE_L1DATA_XMLNAMEOPENERROR = 402, + IMAGE_L1DATA_XMLNAMEPARASEERROR = 403, + + METAXMLFOUNDERROR +}; + + + +std::string BASECONSTVARIABLEAPI errorCode2errInfo(ErrorCode code); + + +ErrorCode BASECONSTVARIABLEAPI GSLState2ErrorCode(int gslState); + + + diff --git a/BaseTool/MergeRasterOperator.cpp b/BaseTool/MergeRasterOperator.cpp new file mode 100644 index 0000000..f8144e7 --- /dev/null +++ b/BaseTool/MergeRasterOperator.cpp @@ -0,0 +1,488 @@ +#include "stdafx.h" +#include "ImageOperatorBase.h" +#include "BaseTool.h" +#include "GeoOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FileOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include // OGRSpatialReference ڿռοת +#include // GDALWarp + +ErrorCode MergeRasterProcess(QVector filepaths, QString outfileptah, QString mainString, MERGEMODE mergecode, bool isENVI, ShowProessAbstract* dia) +{ + // + if (!isExists(mainString)) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::FILENOFOUND)) << "\t" << mainString; + return ErrorCode::FILENOFOUND; + } + else {} + gdalImage mainimg(mainString); + QVector imgdslist(filepaths.count()); + for (long i = 0; i < filepaths.count(); i++) { + if (!isExists(filepaths[i])) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::FILENOFOUND)) << "\t" << filepaths[i]; + return ErrorCode::FILENOFOUND; + } + else { + imgdslist[i] = gdalImage(filepaths[i]); + if (imgdslist[i].band_num != mainimg.band_num) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::RASTERBAND_NOTEQUAL)) << "\t" << imgdslist[i].band_num << " != " << mainimg.band_num; + return ErrorCode::RASTERBAND_NOTEQUAL; + } + } + } + + // ϵǷͳһ + long EPSGCode = GetEPSGFromRasterFile(mainString); + long tempCode = 0; + for (long i = 0; i < filepaths.count(); i++) { + tempCode = GetEPSGFromRasterFile(filepaths[i]); + if (EPSGCode != tempCode) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::EPSGCODE_NOTSAME)) << "\t" << EPSGCode << "!=" << tempCode; + return ErrorCode::EPSGCODE_NOTSAME; + } + } + + // ӰǷͳһ + GDALDataType mainType = mainimg.getDataType(); + for (long i = 0; i < imgdslist.count(); i++) { + if (mainType != imgdslist[i].getDataType()) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::RASTER_DATETYPE_NOTSAME)) << "\t" << mainType << "!=" << imgdslist[i].getDataType(); + return ErrorCode::RASTER_DATETYPE_NOTSAME; + } + } + + Eigen::MatrixXd maingt = mainimg.getGeoTranslation(); + Eigen::MatrixXd rgt = Eigen::MatrixXd::Zero(2, 3); + RasterExtend mainExtend = mainimg.getExtend(); + rgt(0, 1) = (mainExtend.max_x - mainExtend.min_x) / (mainimg.width - 1); //dx + rgt(1, 2) = -1 * std::abs(((mainExtend.max_y - mainExtend.min_y) / (mainimg.height - 1)));//dy + QVector extendlist(imgdslist.count()); + for (long i = 0; i < imgdslist.count(); i++) { + extendlist[i] = imgdslist[i].getExtend(); + mainExtend.min_x = mainExtend.min_x < extendlist[i].min_x ? mainExtend.min_x : extendlist[i].min_x; + mainExtend.max_x = mainExtend.max_x > extendlist[i].max_x ? mainExtend.max_x : extendlist[i].max_x; + mainExtend.min_y = mainExtend.min_y < extendlist[i].min_y ? mainExtend.min_y : extendlist[i].min_y; + mainExtend.max_y = mainExtend.max_y > extendlist[i].max_y ? mainExtend.max_y : extendlist[i].max_y; + } + + rgt(0, 0) = mainExtend.min_x; + rgt(1, 0) = mainExtend.max_y; + + // + + long width = std::ceil((mainExtend.max_x - mainExtend.min_x) / rgt(0, 1) + 1); + long height = std::ceil(std::abs((mainExtend.min_y - mainExtend.max_y) / rgt(1, 2)) + 1); + OGRSpatialReference oSRS; + if (oSRS.importFromEPSG(EPSGCode) != OGRERR_NONE) { + qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::EPSGCODE_NOTSUPPORT)) << "\t" << EPSGCode; + return ErrorCode::EPSGCODE_NOTSUPPORT; + } + + gdalImage resultImage = CreategdalImage(outfileptah, height, width, mainimg.band_num, rgt, EPSGCode, mainType, true, true, isENVI); + + QString resultMaskString = addMaskToFileName(outfileptah, QString("_MASK")); + gdalImage maskImage = CreategdalImage(resultMaskString, height, width, 1, rgt, EPSGCode, GDT_Int32, true, true, isENVI); + + // ʼ + long resultline = Memory1MB * 500 / 8 / resultImage.width; + resultline = resultline < 10000 ? resultline : 10000; // 100 + resultline = resultline > 0 ? resultline : 2; + long bandnum = resultImage.band_num + 1; + long starti = 0; + long rasterCount = imgdslist.count(); + + + + QProgressDialog progressDialog(u8"ʼӰ", u8"ֹ", 0, resultImage.height); + progressDialog.setWindowTitle(u8"ʼӰ"); + progressDialog.setWindowModality(Qt::WindowModal); + progressDialog.setAutoClose(true); + progressDialog.setValue(0); + progressDialog.setMaximum(resultImage.height); + progressDialog.setMinimum(0); + progressDialog.show(); + + + for (starti = 0; starti < resultImage.height; starti = starti + resultline) { + long blocklines = resultline; + blocklines = starti + blocklines < resultImage.height ? blocklines : resultImage.height - starti; + for (long b = 1; b < bandnum; b++) { + Eigen::MatrixXd data = resultImage.getData(starti, 0, blocklines, resultImage.width, b); + Eigen::MatrixXi maskdata = maskImage.getDatai(starti, 0, blocklines, resultImage.width, b); + data = data.array() * 0; + maskdata = maskdata.array() * 0; + resultImage.saveImage(data, starti, 0, b); + maskImage.saveImage(maskdata, starti, 0, b); + } + if (nullptr != dia) { + dia->showProcess(starti * 1.0 / resultImage.height, u8"ʼӰ"); + } + progressDialog.setValue(starti + blocklines); + } + progressDialog.close(); + + + + switch (mergecode) + { + case MERGE_GEOCODING: + return MergeRasterInGeoCoding(imgdslist, resultImage, maskImage, dia); + default: + break; + } + + + return ErrorCode::SUCCESS; +} + +ErrorCode MergeRasterInGeoCoding(QVector imgdslist, gdalImage resultimg, gdalImage maskimg, ShowProessAbstract* dia) +{ + omp_set_num_threads(Paral_num_thread); + // ϲ + QVector extendlist(imgdslist.count()); + for (long i = 0; i < imgdslist.count(); i++) { + extendlist[i] = imgdslist[i].getExtend(); + imgdslist[i].InitInv_gt(); + } + + // ֿ + long resultline = Memory1MB * 1000 / 8 / resultimg.width; + resultline = resultline < 300 ? resultline : 300; // 100 + + long bandnum = resultimg.band_num + 1; + long starti = 0; + long rasterCount = imgdslist.count(); + + long processNumber = 0; + QProgressDialog progressDialog(u8"ϲӰ", u8"ֹ", 0, resultimg.height); + progressDialog.setWindowTitle(u8"ϲӰ"); + progressDialog.setWindowModality(Qt::WindowModal); + progressDialog.setAutoClose(true); + progressDialog.setValue(0); + progressDialog.setMaximum(resultimg.height); + progressDialog.setMinimum(0); + progressDialog.show(); + omp_lock_t lock; + omp_init_lock(&lock); + +#pragma omp parallel for + for (starti = 0; starti < resultimg.height; starti = starti + resultline) { + long blocklines = resultline; + blocklines = starti + blocklines < resultimg.height ? blocklines : resultimg.height - starti; + + long rid = starti; + long cid = 0; + + Landpoint pp = { 0,0,0 }; + Landpoint lp = { 0,0,0 }; + + for (long ir = 0; ir < rasterCount; ir++) {// Ӱ + long minRid = imgdslist[ir].height; + long maxRid = 0; + + Eigen::MatrixXd ridlist = resultimg.getData(starti, 0, blocklines, resultimg.width, 1); + ridlist = ridlist.array() * 0; + Eigen::MatrixXd cidlist = ridlist.array() * 0; + + for (long i = 0; i < blocklines; i++) {// к + rid = starti + i; + for (long j = 0; j < resultimg.width; j++) {// к + cid = j; + resultimg.getLandPoint(rid, cid, 0, pp); + lp = imgdslist[ir].getRow_Col(pp.lon, pp.lat); // ȡ + ridlist(i, j) = lp.lat; + cidlist(i, j) = lp.lon; + } + } + + //ImageShowDialogClass* dialog = new ImageShowDialogClass; + //dialog->show(); + //dialog->load_double_MatrixX_data(cidlist, u8""); + + //dialog->exec(); + + + if (ridlist.maxCoeff() < 0 || ridlist.minCoeff() >= imgdslist[ir].height) { + continue; + } + + if (cidlist.maxCoeff() < 0 || cidlist.minCoeff() >= imgdslist[ir].width) { + continue; + } + + minRid = std::floor(ridlist.minCoeff()); + maxRid = std::ceil(ridlist.maxCoeff()); + minRid = minRid < 0 ? 0 : minRid; + maxRid = maxRid < imgdslist[ir].height ? maxRid : imgdslist[ir].height - 1; + + long rowlen = maxRid - minRid + 1; + if (rowlen <= 0) { + continue; + } + // ȡ + Landpoint p0{ 0,0,0 }, p11{ 0,0,0 }, p21{ 0,0,0 }, p12{ 0,0,0 }, p22{ 0,0,0 }, p{ 0,0,0 }; + + + long rowcount = 0; + long colcount = 0; + double ridtemp = 0, cidtemp = 0; + + long lastr = 0, nextr = 0; + long lastc = 0, nextc = 0; + + double r0 = 0, c0 = 0; + + for (long b = 1; b < bandnum; b++) { + Eigen::MatrixXd resultdata = resultimg.getData(starti, 0, blocklines, resultimg.width, b); + Eigen::MatrixXi resultmask = maskimg.getDatai(starti, 0, blocklines, resultimg.width, b); + Eigen::MatrixXd data = imgdslist[ir].getData(minRid, 0, rowlen, imgdslist[ir].width, b); + + double nodata = imgdslist[ir].getNoDataValue(b); + for (long ii = 0; ii < data.rows(); ii++) { + for (long jj = 0; jj < data.cols(); jj++) { + if (std::abs(data(ii, jj) - nodata) < 1e-6) { + data(ii, jj) = 0; + } + } + } + rowcount = ridlist.rows(); + colcount = ridlist.cols(); + double Bileanervalue = 0; + for (long i = 0; i < rowcount; i++) { + for (long j = 0; j < colcount; j++) { + ridtemp = ridlist(i, j); + cidtemp = cidlist(i, j); + + lastr = std::floor(ridtemp); + nextr = std::ceil(ridtemp); + lastc = std::floor(cidtemp); + nextc = std::ceil(cidtemp); + + if (lastr < 0 || lastr >= imgdslist[ir].height + || nextr < 0 || nextr >= imgdslist[ir].height + || lastc < 0 || lastc >= imgdslist[ir].width + || nextc < 0 || nextc >= imgdslist[ir].width) { + continue; + } + else {} + + r0 = ridtemp - std::floor(ridtemp); + c0 = cidtemp - std::floor(cidtemp); + + lastr = lastr - minRid; + nextr = nextr - minRid; + + p0 = Landpoint{ c0,r0,0 }; + p11 = Landpoint{ 0,0,data(lastr,lastc) }; + p21 = Landpoint{ 0,1,data(nextr,lastc) }; + p12 = Landpoint{ 1,0,data(lastr,nextc) }; + p22 = Landpoint{ 1,1,data(nextr,nextc) }; + Bileanervalue = Bilinear_interpolation(p0, p11, p21, p12, p22); + if (std::abs(Bileanervalue) < 1e-6 || resultmask(i, j) > 0) { + continue; + } + resultdata(i, j) = resultdata(i, j) + Bileanervalue; + resultmask(i, j) = resultmask(i, j) + 1; + } + } + resultimg.saveImage(resultdata, starti, 0, b); + maskimg.saveImage(resultmask, starti, 0, b); + } + } + + omp_set_lock(&lock); + processNumber = processNumber + blocklines; + qDebug() << "\rprocess bar:\t" << processNumber * 100.0 / resultimg.height << " % " << "\t\t\t"; + if (nullptr != dia) { + dia->showProcess(processNumber * 1.0 / resultimg.height, u8"ϲͼ"); + } + if (progressDialog.maximum() <= processNumber) { + processNumber = progressDialog.maximum() - 1; + } + progressDialog.setValue(processNumber); + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); + + progressDialog.setWindowTitle(u8"ӰĤ"); + progressDialog.setLabelText(u8"ӰĤ"); + for (starti = 0; starti < resultimg.height; starti = starti + resultline) { + long blocklines = resultline; + blocklines = starti + blocklines < resultimg.height ? blocklines : resultimg.height - starti; + for (long b = 1; b < bandnum; b++) { + Eigen::MatrixXd data = resultimg.getData(starti, 0, blocklines, resultimg.width, b); + Eigen::MatrixXd maskdata = maskimg.getData(starti, 0, blocklines, maskimg.width, b); + + for (long i = 0; i < data.rows(); i++) { + for (long j = 0; j < data.cols(); j++) { + if (maskdata(i, j) == 0) { + data(i, j) = -9999; + continue; + } + data(i, j) = data(i, j) / maskdata(i, j); + } + } + + resultimg.saveImage(data, starti, 0, b); + maskimg.saveImage(maskdata, starti, 0, b); + } + if (nullptr != dia) { + dia->showProcess((starti + blocklines) * 1.0 / resultimg.height, u8"ӰĤ"); + } + progressDialog.setValue(starti + blocklines); + } + + + progressDialog.close(); + return ErrorCode::SUCCESS; +} + + +void MergeTiffs(QList inputFiles, QString outputFile) { + GDALAllRegister(); + + if (inputFiles.isEmpty()) { + fprintf(stderr, "No input files provided.\n"); + return; + } + + // Open the first file to determine the data type and coordinate system + GDALDataset* poFirstDS = (GDALDataset*)GDALOpen(inputFiles.first().toUtf8().constData(), GA_ReadOnly); + if (poFirstDS == nullptr) { + fprintf(stderr, "Failed to open the first file %s\n", inputFiles.first().toUtf8().constData()); + return; + } + + double adfGeoTransform[6]; + CPLErr eErr = poFirstDS->GetGeoTransform(adfGeoTransform); + if (eErr != CE_None) { + fprintf(stderr, "Failed to get GeoTransform for the first file %s\n", inputFiles.first().toUtf8().constData()); + GDALClose(poFirstDS); + return; + } + + int nXSize = 0; + int nYSize = 0; + double minX = std::numeric_limits::max(); + double minY = std::numeric_limits::max(); + double maxX = std::numeric_limits::lowest(); + double maxY = std::numeric_limits::lowest(); + double pixelWidth = adfGeoTransform[1]; + double pixelHeight = adfGeoTransform[5]; + + // Determine the bounding box and size of the output raster + for (const QString& inputFile : inputFiles) { + GDALDataset* poSrcDS = (GDALDataset*)GDALOpen(inputFile.toUtf8().constData(), GA_ReadOnly); + if (poSrcDS == nullptr) { + fprintf(stderr, "Failed to open %s\n", inputFile.toUtf8().constData()); + continue; + } + + double adfThisTransform[6]; + eErr = poSrcDS->GetGeoTransform(adfThisTransform); + if (eErr != CE_None) { + fprintf(stderr, "Failed to get GeoTransform for %s\n", inputFile.toUtf8().constData()); + GDALClose(poSrcDS); + continue; + } + + minX = std::min(minX, adfThisTransform[0]); + minY = std::min(minY, adfThisTransform[3] + adfThisTransform[5] * poSrcDS->GetRasterYSize()); + maxX = std::max(maxX, adfThisTransform[0] + adfThisTransform[1] * poSrcDS->GetRasterXSize()); + maxY = std::max(maxY, adfThisTransform[3]); + + GDALClose(poSrcDS); + } + + nXSize = static_cast(std::ceil((maxX - minX) / pixelWidth)); + nYSize = static_cast(std::ceil((maxY - minY) / (-pixelHeight))); + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (poDriver == nullptr) { + fprintf(stderr, "GTiff driver not available.\n"); + GDALClose(poFirstDS); + return; + } + + char** papszOptions = nullptr; + GDALDataset* poDstDS = poDriver->Create(outputFile.toUtf8().constData(), nXSize, nYSize, 1, poFirstDS->GetRasterBand(1)->GetRasterDataType(), papszOptions); + if (poDstDS == nullptr) { + fprintf(stderr, "Creation of output file failed.\n"); + GDALClose(poFirstDS); + return; + } + + poDstDS->SetGeoTransform(adfGeoTransform); + + const OGRSpatialReference* oSRS = poFirstDS->GetSpatialRef(); + poDstDS->SetSpatialRef(oSRS); + + float fillValue = std::numeric_limits::quiet_NaN(); + void* pafScanline = CPLMalloc(GDALGetDataTypeSizeBytes(poFirstDS->GetRasterBand(1)->GetRasterDataType()) * nXSize); + memset(pafScanline, 0, GDALGetDataTypeSizeBytes(poFirstDS->GetRasterBand(1)->GetRasterDataType()) * nXSize); + + // Initialize all pixels to NaN + for (int iY = 0; iY < nYSize; ++iY) { + GDALRasterBand* poBand = poDstDS->GetRasterBand(1); + poBand->RasterIO(GF_Write, 0, iY, nXSize, 1, pafScanline, nXSize, 1, poFirstDS->GetRasterBand(1)->GetRasterDataType(), 0, 0); + } + + CPLFree(pafScanline); + + // Read each source image and write into the destination image + for (const QString& inputFile : inputFiles) { + GDALDataset* poSrcDS = (GDALDataset*)GDALOpen(inputFile.toUtf8().constData(), GA_ReadOnly); + if (poSrcDS == nullptr) { + fprintf(stderr, "Failed to open %s\n", inputFile.toUtf8().constData()); + continue; + } + + double adfThisTransform[6]; + poSrcDS->GetGeoTransform(adfThisTransform); + + int srcXSize = poSrcDS->GetRasterXSize(); + int srcYSize = poSrcDS->GetRasterYSize(); + + int dstXOffset = static_cast(std::round((adfThisTransform[0] - minX) / pixelWidth)); + int dstYOffset = static_cast(std::round((maxY - adfThisTransform[3]) / (-pixelHeight))); + + GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1); + GDALRasterBand* poDstBand = poDstDS->GetRasterBand(1); + + void* pafBuffer = CPLMalloc(GDALGetDataTypeSizeBytes(poFirstDS->GetRasterBand(1)->GetRasterDataType()) * srcXSize * srcYSize); + poSrcBand->RasterIO(GF_Read, 0, 0, srcXSize, srcYSize, pafBuffer, srcXSize, srcYSize, poFirstDS->GetRasterBand(1)->GetRasterDataType(), 0, 0); + + poDstBand->RasterIO(GF_Write, dstXOffset, dstYOffset, srcXSize, srcYSize, pafBuffer, srcXSize, srcYSize, poFirstDS->GetRasterBand(1)->GetRasterDataType(), 0, 0); + + CPLFree(pafBuffer); + GDALClose(poSrcDS); + } + + GDALClose(poDstDS); + GDALClose(poFirstDS); + +} + + + diff --git a/BaseTool/PrintMsgToQDebug.cpp b/BaseTool/PrintMsgToQDebug.cpp new file mode 100644 index 0000000..5d7d190 --- /dev/null +++ b/BaseTool/PrintMsgToQDebug.cpp @@ -0,0 +1,36 @@ +#include "PrintMsgToQDebug.h" +#include +BASECONSTVARIABLEAPI void PrintMsgToQDebug(char* msg) +{ + qDebug() << QString(msg); + return ; +} + +BASECONSTVARIABLEAPI void PrintfToQDebug(const char* msg) +{ + qDebug() << QString(msg); + return; +} + +BASECONSTVARIABLEAPI void PrintTipMsgToQDebug(const char* tip, const char* msg) +{ + qDebug() < +extern "C" BASECONSTVARIABLEAPI void PrintMsgToQDebug(char* msg); +extern "C" BASECONSTVARIABLEAPI void PrintfToQDebug(const char* msg); +extern "C" BASECONSTVARIABLEAPI void PrintTipMsgToQDebug(const char* tip, const char* msg); +extern "C" BASECONSTVARIABLEAPI void printfinfo(const char* format, ...); + + + +#endif // !PRINTMSGTOQDEBUG_H_ + + + \ No newline at end of file diff --git a/BaseTool/QToolProcessBarDialog.cpp b/BaseTool/QToolProcessBarDialog.cpp new file mode 100644 index 0000000..a39fd57 --- /dev/null +++ b/BaseTool/QToolProcessBarDialog.cpp @@ -0,0 +1,24 @@ +#include "QToolProcessBarDialog.h" +#include "ui_QToolProcessBarDialog.h" + +QToolProcessBarDialog::QToolProcessBarDialog(QWidget *parent) + : ui(new Ui::QToolProcessBarDialogClass), QDialog(parent) +{ + ui->setupUi(this); + ui->progressBar->setRange(0, 100); +} + +QToolProcessBarDialog::~QToolProcessBarDialog() +{} + +void QToolProcessBarDialog::showProcess(double precent, QString tip) +{ + ui->progressBar->setValue(std::ceil(precent * 100)); + ui->labelTip->setText(tip); + this->update(); +} + +void QToolProcessBarDialog::showToolInfo(QString tip) +{ + ui->textEditTip->append("\n"+tip); +} diff --git a/BaseTool/QToolProcessBarDialog.h b/BaseTool/QToolProcessBarDialog.h new file mode 100644 index 0000000..8b1d5bf --- /dev/null +++ b/BaseTool/QToolProcessBarDialog.h @@ -0,0 +1,23 @@ +#pragma once +#include "BaseConstVariable.h" +#include + +#include "ImageOperatorBase.h" + +namespace Ui { + class QToolProcessBarDialogClass; +} + +class BASECONSTVARIABLEAPI QToolProcessBarDialog : public QDialog, public ShowProessAbstract +{ + Q_OBJECT +public: + QToolProcessBarDialog(QWidget *parent = nullptr); + ~QToolProcessBarDialog(); + +private: + Ui::QToolProcessBarDialogClass* ui; +public: + virtual void showProcess(double precent, QString tip) override; + virtual void showToolInfo(QString tip) override; +}; diff --git a/BaseTool/QToolProcessBarDialog.ui b/BaseTool/QToolProcessBarDialog.ui new file mode 100644 index 0000000..400efab --- /dev/null +++ b/BaseTool/QToolProcessBarDialog.ui @@ -0,0 +1,73 @@ + + + QToolProcessBarDialogClass + + + + 0 + 0 + 600 + 400 + + + + QToolProcessBarDialog + + + + + + + + + + 120 + 26 + + + + + 120 + 26 + + + + 退出 + + + + + + + 提示 + + + + + + + 24 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BaseTool/RasterToolBase.cpp b/BaseTool/RasterToolBase.cpp new file mode 100644 index 0000000..5debe6f --- /dev/null +++ b/BaseTool/RasterToolBase.cpp @@ -0,0 +1,276 @@ +/** + * @file RasterProjectBase.cpp + * @brief None + * @author 陈增辉 (3045316072@qq.com) + * @version 2.5.0 + * @date 24-6-4 + * @copyright Copyright (c) Since 2024 中科卫星应用研究院 All rights reserved. + */ + +#include +#include "RasterToolBase.h" +#include "gdal_priv.h" +#include "ogr_spatialref.h" +#include "cpl_conv.h" // for CPLMalloc() +#include +#include +#include +#include "SARSimulationImageL1.h" +#include + +namespace RasterToolBase { + long getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState) + { + long EPSGCode = 0; + switch(stripState) { + case ProjectStripDelta::Strip_3: { + break; + }; + case ProjectStripDelta::Strip_6: { + break; + } + default: { + EPSGCode = -1; + break; + } + } + qDebug() << QString(" EPSG code : %1").arg(EPSGCode); + return EPSGCode; + } + long getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat) + { + // EPSG 4534 ~ 4554 3 度带 + // 首先判断是否是在 中国带宽范围 + // 中心经度范围 :75E ~ 135E 实际范围 73.5E ~ 136.5E, + // 纬度范围 3N ~ 54N,放宽到 0N~ 60N + if(73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内 + long code = trunc((lon - 73.5) / 3) + 4534; + return code; + } else { // 非中国境内 使用 高斯克吕格 + bool isSouth = lat < 0; // 简单判断南北半球,这里仅为示例,实际应用可能需要更细致的逻辑 + long prefix = isSouth ? 327000 : 326000; + // std::string prefix = isSouth ? "327" : "326"; + lon = fmod(lon + 360.0, 360.0); + long zone = std::floor((lon + 180.0) / 3.0); + prefix = prefix + zone; + return prefix; + } + return 0; + } + long getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat) + { + // EPSG 4502 ~ 4512 6度带 + // 首先判断是否是在 中国带宽范围 + // 中心经度范围 :75E ~ 135E 实际范围 72.0E ~ 138E, + // 纬度范围 3N ~ 54N,放宽到 0N~ 60N + if(73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内 + long code = trunc((lon - 72.0) / 6) + 4502; + return code; + } else { // 非中国境内 使用 UTM// 确定带号,6度带从1开始到60,每6度一个带 + int zone = static_cast((lon + 180.0) / 6.0) + 1; + bool isSouth = lon < 0; // 判断是否在南半球 + long epsgCodeBase = isSouth ? 32700 : 32600; // 计算EPSG代码 + long prefix = static_cast(epsgCodeBase + zone); + return prefix; + } + return 0; + } + + QString GetProjectionNameFromEPSG(long epsgCode) + { + qDebug() << "============= GetProjectionNameFromEPSG ======================"; + OGRSpatialReference oSRS; + + // 设置EPSG代码 + if(oSRS.importFromEPSG(epsgCode) != OGRERR_NONE) { + qDebug() << "epsgcode not recognition"; + return ""; + } + + // 获取并输出坐标系的描述(名称) + const char* pszName = oSRS.GetAttrValue("GEOGCS"); + if(pszName) { + qDebug() << "Coordinate system name for EPSG " + QString::number(epsgCode) + << " is: " + QString::fromStdString(pszName); + return QString::fromStdString(pszName); + } else { + qDebug() << "Unable to retrieve the name for EPSG " + QString::number(epsgCode); + return ""; + } + + // char* wkt = NULL; + // // 转换为WKT格式 + // oSRS.exportToWkt(&wkt); + // + // qDebug() << wkt; + // + // // 从WKT中解析投影名称,这里简化处理,实际可能需要更复杂的逻辑来准确提取名称 + // std::string wktStr(wkt); + // long start = wktStr.find("PROJCS[\"") + 8; // 找到"PROJCS["后的第一个双引号位置 + // // 从start位置开始找下一个双引号,这之间的内容即为投影名称 + // int end = wktStr.find('\"', start); + // QString projName = QString::fromStdString(wktStr.substr(start, end - start)); + // + // // 释放WKT字符串内存 + // CPLFree(wkt); + + // return projName; + } + long GetEPSGFromRasterFile(QString filepath) + { + qDebug() << "============= GetEPSGFromRasterFile ======================"; + // QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器 + // QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray + //,这个应该会自动释放 const char* charArray = byteArray.constData(); // + // 获取QByteArray的const char*指针 + + { + if(QFile(filepath).exists()){ + qDebug() << "info: the image found.\n"; + }else{ + return -1; + } + + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 注册GDAL驱动 + // qDebug()<GetProjectionRef(); + + qDebug() << QString::fromUtf8(pszProjection); + + // 创建SpatialReference对象 + OGRSpatialReference oSRS; + if(oSRS.importFromWkt((char**)&pszProjection) != OGRERR_NONE) { + qDebug() << ("Error: Unable to import projection information.\n"); + GDALClose(poDataset); + return -1; + } + + long epsgCode = atoi(oSRS.GetAuthorityCode(nullptr)); // 获取EPSG代码 + + if(epsgCode != 0) { + GDALClose(poDataset); + qDebug() << QString("file %1 :epsg Code %2").arg(filepath).arg(epsgCode); + return epsgCode; + } else { + qDebug() << "EPSG code could not be determined from the spatial reference."; + GDALClose(poDataset); + return -1; + } + } + } + std::shared_ptr GetCenterPointInRaster(QString filepath) + { + qDebug() << "============= GetCenterPointInRaster ======================"; + // QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器 + // QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray + //,这个应该会自动释放 const char* charArray = byteArray.constData(); // + // 获取QByteArray的const char*指针 + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + // qDebug()<GetGeoTransform(adfGeoTransform) != CE_None) { + qDebug() << "Failed to get GeoTransform"; + return nullptr; + } + + double dfWidth = poDataset->GetRasterXSize(); + double dfHeight = poDataset->GetRasterYSize(); + + // 计算中心点坐标(像素坐标) + double dfCenterX = adfGeoTransform[0] + dfWidth * adfGeoTransform[1] / 2.0 + + dfHeight * adfGeoTransform[2] / 2.0; + double dfCenterY = adfGeoTransform[3] + dfWidth * adfGeoTransform[4] / 2.0 + + dfHeight * adfGeoTransform[5] / 2.0; + + OGRSpatialReference oSRS; + oSRS.importFromWkt(poDataset->GetProjectionRef()); + + if(oSRS.IsGeographic()) { + qDebug() << "Center coords (already in geographic): (" + QString::number(dfCenterX) + + ", " + QString::number(dfCenterY) + ")"; + flag = true; + x = dfCenterX; + y = dfCenterY; + } else { + // 如果不是地理坐标系,转换到WGS84 + OGRSpatialReference oSRS_WGS84; + oSRS_WGS84.SetWellKnownGeogCS("WGS84"); + + OGRCoordinateTransformation* poCT = + OGRCreateCoordinateTransformation(&oSRS, &oSRS_WGS84); + if(poCT == nullptr) { + qDebug() << "Failed to create coordinate transformation"; + return nullptr; + } + + // double dfLon, dfLat; + if(poCT->Transform(1, &dfCenterX, &dfCenterY)) { + qDebug() << "Center coords (transformed to WGS84): (" + + QString::number(dfCenterX) + ", " + QString::number(dfCenterY) + << ")"; + flag = true; + x = dfCenterX; + y = dfCenterY; + } else { + qDebug() << "Transformation failed."; + } + OGRCoordinateTransformation::DestroyCT(poCT); + } + } + if(nullptr==poDataset||NULL==poDataset){}else{ + GDALClose(poDataset); + } + + if(flag) { + std::shared_ptr RasterCenterPoint = std::make_shared(); + RasterCenterPoint->x = x; + RasterCenterPoint->y = y; + RasterCenterPoint->z = 0; + return RasterCenterPoint; + } else { + return nullptr; + } + } + CoordinateSystemType getCoordinateSystemTypeByEPSGCode(long epsg_code) + { + OGRSpatialReference oSRS; + if(oSRS.importFromEPSG(epsg_code) == OGRERR_NONE) { + if(oSRS.IsGeographic()) { + return CoordinateSystemType::GeoCoordinateSystem; + } else if(oSRS.IsProjected()) { + return CoordinateSystemType::ProjectCoordinateSystem; + } + else { + return CoordinateSystemType::UNKNOW; + } + } else { + return CoordinateSystemType::UNKNOW; + } + } +}; // namespace RasterToolBase + + + diff --git a/BaseTool/RasterToolBase.h b/BaseTool/RasterToolBase.h new file mode 100644 index 0000000..254d4bb --- /dev/null +++ b/BaseTool/RasterToolBase.h @@ -0,0 +1,96 @@ +/** + * @file RasterProjectBase.h + * @brief None + * @author 陈增辉 (3045316072@qq.com) + * @version 2.5.0 + * @date 24-6-4 + * @copyright Copyright (c) Since 2024 中科卫星应用研究院 All rights reserved. + */ + +#ifndef LAMPCAE_RASTERTOOLBASE_H +#define LAMPCAE_RASTERTOOLBASE_H +#include "BaseConstVariable.h" +#include "gdal_priv.h" +#include +#include "LogInfoCls.h" + + +namespace RasterToolBase { + + static bool GDALAllRegisterEnable = false; + + + enum ProjectStripDelta { + Strip_6, // 6度带 + Strip_3 + }; + + enum CoordinateSystemType { // 坐标系类型 + GeoCoordinateSystem, + ProjectCoordinateSystem, + UNKNOW + }; + + struct PointRaster { // 影像坐标点 + double x; + double y; + double z; + }; + + + struct PointXYZ { + double x, y, z; + }; + + struct PointGeo { + double lon, lat, ati; + }; + + struct PointImage { + double pixel_x, pixel_y; + }; + + /// 根据经纬度获取 + /// EPSG代码,根据经纬度返回对应投影坐标系统,其中如果在中华人民共和国境内,默认使用 + /// CGCS2000坐标系统(EPSG 4502 ~ 4512 6度带,EPSG 4534 ~ 4554 3度带),其余地方使用WGS坐标系统, + /// 投影方法 高斯克吕格(国内), 高斯克吕格 + /// \param long 经度 + /// \param lat 纬度 + /// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误 + long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat(double long, double lat, + ProjectStripDelta stripState = ProjectStripDelta::Strip_3); + + long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat); + + long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat); + + + QString BASECONSTVARIABLEAPI GetProjectionNameFromEPSG(long epsgCode); + + + long BASECONSTVARIABLEAPI GetEPSGFromRasterFile(QString filepath); + + std::shared_ptr BASECONSTVARIABLEAPI GetCenterPointInRaster(QString filepath); + + CoordinateSystemType BASECONSTVARIABLEAPI getCoordinateSystemTypeByEPSGCode(long EPSGCODE); + +};// namespace RasterProjectConvertor + + + + +// 遥感类常用数据 + + + + + + + + + + + + + +#endif // LAMPCAE_RASTERTOOLBASE_H diff --git a/BaseTool/SARSimulationImageL1.cpp b/BaseTool/SARSimulationImageL1.cpp new file mode 100644 index 0000000..d14f97f --- /dev/null +++ b/BaseTool/SARSimulationImageL1.cpp @@ -0,0 +1,1001 @@ +#include "stdafx.h" +#include "SARSimulationImageL1.h" +#include "LogInfoCls.h" +#include +#include +#include +#include + +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 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); + } + + else 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 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); // + } + + + else if (this->Rasterlevel == RasterLevel::RasterL1B || 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 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); + } + + + 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.completeBaseName(); // ȡ׺ļ + 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, 'e', 18)); + xmlWriter.writeTextElement("Rfar", QString::number(this->Rfar, 'e', 18)); + xmlWriter.writeTextElement("Rref", QString::number(this->Rref, 'e', 18)); + xmlWriter.writeTextElement("CenterFreq", QString::number(this->centerFreq, 'e', 18)); + xmlWriter.writeTextElement("Fs", QString::number(this->Fs, 'e', 18)); + xmlWriter.writeTextElement("PRF", QString::number(this->prf, 'e', 18)); + xmlWriter.writeTextElement("CenterAngle", QString::number(this->CenterAngle, 'e', 18)); + 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, 'e', 18)); // time + xmlWriter.writeTextElement("Px", QString::number(this->sateposes[i].Px, 'e', 18)); // Px + xmlWriter.writeTextElement("Py", QString::number(this->sateposes[i].Py, 'e', 18)); // Py + xmlWriter.writeTextElement("Pz", QString::number(this->sateposes[i].Pz, 'e', 18)); // Pz + xmlWriter.writeTextElement("Vx", QString::number(this->sateposes[i].Vx, 'e', 18)); // Vx + xmlWriter.writeTextElement("Vy", QString::number(this->sateposes[i].Vy, 'e', 18)); // Vy + xmlWriter.writeTextElement("Vz", QString::number(this->sateposes[i].Vz, 'e', 18)); // Vz + xmlWriter.writeTextElement("AntDirectX", QString::number(this->sateposes[i].AntDirectX, 'e', 18)); // AntDirectX + xmlWriter.writeTextElement("AntDirectY", QString::number(this->sateposes[i].AntDirectY, 'e', 18)); // AntDirectY + xmlWriter.writeTextElement("AntDirectZ", QString::number(this->sateposes[i].AntDirectZ, 'e', 18)); // AntDirectZ + xmlWriter.writeTextElement("AVx", QString::number(this->sateposes[i].AVx, 'e', 18)); // AVx + xmlWriter.writeTextElement("AVy", QString::number(this->sateposes[i].AVy, 'e', 18)); // AVy + xmlWriter.writeTextElement("AVz", QString::number(this->sateposes[i].AVz, 'e', 18)); // AVz + xmlWriter.writeTextElement("lon", QString::number(this->sateposes[i].lon, 'e', 18)); // lon + xmlWriter.writeTextElement("lat", QString::number(this->sateposes[i].lat, 'e', 18)); // lat + xmlWriter.writeTextElement("ati", QString::number(this->sateposes[i].ati, 'e', 18)); // ati + xmlWriter.writeEndElement(); // + } + + xmlWriter.writeTextElement("ImageStartTime", QString::number(this->startImageTime, 'e', 18)); + xmlWriter.writeTextElement("ImageEndTime", QString::number(this->EndImageTime, 'e', 18)); + + xmlWriter.writeTextElement("incidenceAngleNearRange", QString::number(this->incidenceAngleNearRange, 'e', 18)); + xmlWriter.writeTextElement("incidenceAngleFarRange", QString::number(this->incidenceAngleFarRange, 'e', 18)); + xmlWriter.writeTextElement("TotalProcessedAzimuthBandWidth", QString::number(this->TotalProcessedAzimuthBandWidth, 'e', 18)); + xmlWriter.writeTextElement("DopplerParametersReferenceTime", QString::number(this->DopplerParametersReferenceTime, 'e', 18)); + + xmlWriter.writeStartElement("DopplerCentroidCoefficients"); + xmlWriter.writeTextElement("d0", QString::number(this->d0, 'e', 18)); + xmlWriter.writeTextElement("d1", QString::number(this->d1, 'e', 18)); + xmlWriter.writeTextElement("d2", QString::number(this->d2, 'e', 18)); + xmlWriter.writeTextElement("d3", QString::number(this->d3, 'e', 18)); + xmlWriter.writeTextElement("d4", QString::number(this->d4, 'e', 18)); + xmlWriter.writeEndElement(); // DopplerCentroidCoefficients + + xmlWriter.writeStartElement("DopplerRateValuesCoefficients"); + xmlWriter.writeTextElement("r0", QString::number(this->r0, 'e', 18)); + xmlWriter.writeTextElement("r1", QString::number(this->r1, 'e', 18)); + xmlWriter.writeTextElement("r2", QString::number(this->r2, 'e', 18)); + xmlWriter.writeTextElement("r3", QString::number(this->r3, 'e', 18)); + xmlWriter.writeTextElement("r4", QString::number(this->r4, 'e', 18)); + xmlWriter.writeEndElement(); // DopplerRateValuesCoefficients + + + xmlWriter.writeTextElement("latitude_center", QString::number(this->latitude_center, 'e', 18)); + xmlWriter.writeTextElement("longitude_center", QString::number(this->longitude_center, 'e', 18)); + xmlWriter.writeTextElement("latitude_topLeft", QString::number(this->latitude_topLeft, 'e', 18)); + xmlWriter.writeTextElement("longitude_topLeft", QString::number(this->longitude_topLeft, 'e', 18)); + xmlWriter.writeTextElement("latitude_topRight", QString::number(this->latitude_topRight, 'e', 18)); + xmlWriter.writeTextElement("longitude_topRight", QString::number(this->longitude_topRight, 'e', 18)); + xmlWriter.writeTextElement("latitude_bottomLeft", QString::number(this->latitude_bottomLeft, 'e', 18)); + xmlWriter.writeTextElement("longitude_bottomLeft", QString::number(this->longitude_bottomLeft, 'e', 18)); + xmlWriter.writeTextElement("latitude_bottomRight", QString::number(this->latitude_bottomRight, 'e', 18)); + xmlWriter.writeTextElement("longitude_bottomRight", QString::number(this->longitude_bottomRight, 'e', 18)); + + 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() == "PRF") { + this->prf = 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 SARSimulationImageL1Dataset::getAntPos() +{ + if (this->Rasterlevel == RasterLevel::RasterL2) { + return nullptr; + } + + + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + // ȡļ + std::shared_ptr 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 temp = nullptr; + + if (gdal_datatype == GDT_Float64) { + temp = std::shared_ptr(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 ptr) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + // ȡļ + std::shared_ptr 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> SARSimulationImageL1Dataset::getImageRaster() +{ + if (this->Rasterlevel != RasterLevel::RasterSLC) { + return nullptr; + } + + return this->getImageRaster(0, this->rowCount); +} + +ErrorCode SARSimulationImageL1Dataset::saveImageRaster(std::shared_ptr> 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 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> 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 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> 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>(new std::complex[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> 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> data(new std::complex[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 SARSimulationImageL1Dataset::getXmlSateAntPos() +{ + if (this->Rasterlevel == RasterLevel::RasterL2) { + return QVector(0); + } + return this->sateposes; +} + +void SARSimulationImageL1Dataset::setSateAntPos(QVector 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 SARSimulationImageL1Dataset::getDopplerParams() +{ + QVector 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 SARSimulationImageL1Dataset::getDopplerCenterCoff() +{ + QVector 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; +} diff --git a/BaseTool/SARSimulationImageL1.h b/BaseTool/SARSimulationImageL1.h new file mode 100644 index 0000000..6d8325a --- /dev/null +++ b/BaseTool/SARSimulationImageL1.h @@ -0,0 +1,218 @@ +#pragma once + +#include "BaseConstVariable.h" + +#include "BaseTool.h" +#include "ImageOperatorBase.h" +#include "GeoOperator.h" +#include "FileOperator.h" +#include "LogInfoCls.h" + +enum RasterLevel { + RasterSLC, + RasterL1B, + RasterL2 +}; + +class BASECONSTVARIABLEAPI SARSimulationImageL1Dataset +{ +public: + SARSimulationImageL1Dataset(RasterLevel Rasterlevel= RasterLevel::RasterSLC); + ~SARSimulationImageL1Dataset(); + +private: + RasterLevel Rasterlevel; +public: + RasterLevel getRasterLevel(); + + +private : + QString outFolderPath; + QString L1DatasetName; + QString xmlfileName; + QString xmlFilePath; + QString ImageRasterName; + QString ImageRasterPath; + QString GPSPointFilename; + QString GPSPointFilePath; + +public: + QString getoutFolderPath(); + QString getDatesetName(); + QString getxmlfileName(); + QString getxmlFilePath(); + QString getImageRasterName(); + QString getImageRasterPath(); + QString getGPSPointFilename(); // GPS + QString getGPSPointFilePath(); + + +public: + ErrorCode OpenOrNew(QString folder, QString filename, long rowCount, long colCount); + ErrorCode Open(QString folderPath, QString Name); + ErrorCode Open(QString xmlPath); +public: + void saveToXml(); + ErrorCode loadFromXml(); + std::shared_ptr getAntPos(); + ErrorCode saveAntPos(std::shared_ptr ptr); // עΣգдǰǷȷ + + std::shared_ptr> getImageRaster(); + ErrorCode saveImageRaster(std::shared_ptr> echoPtr, long startPRF, long PRFLen); + std::shared_ptr> getImageRaster(long startPRF, long PRFLen); + + Eigen::MatrixXcd getImageRasterMatrix(); + ErrorCode saveImageRaster(Eigen::MatrixXcd& data, long startPRF); + + gdalImage getImageRasterGdalImage(); + +private: // xmlв + + long rowCount; + long colCount; + + double Rnear; + double Rfar; + double Rref; + + double centerFreq; + double Fs; + double prf; + + double CenterAngle; + QString LookSide; + QVector sateposes; + + double startImageTime; + double EndImageTime; + +public: + + void setStartImageTime(double imageTime); + double getStartImageTime(); + + void setEndImageTime(double imageTime); + double getEndImageTime(); + + + QVector getXmlSateAntPos(); + void setSateAntPos(QVector pos); + + long getrowCount(); + void setrowCount(long rowCount); + + long getcolCount(); + void setcolCount(long pulsePoints); + + double getNearRange(); + void setNearRange(double nearRange); + + double getFarRange(); + void setFarRange(double farRange); + + double getRefRange(); + void setRefRange(double refRange); + + double getCenterFreq(); + void setCenterFreq(double freq); + + double getFs(); + void setFs(double samplingFreq); + + double getPRF(); + void setPRF(double PRF); + + double getCenterAngle(); + void setCenterAngle(double angle); + + QString getLookSide(); + void setLookSide(QString lookside); + +public:// ղ + double TotalProcessedAzimuthBandWidth, DopplerParametersReferenceTime; + double d0, d1, d2, d3, d4; + double r0, r1, r2, r3, r4; + double DEM; + double incidenceAngleNearRange, incidenceAngleFarRange; + +public: + + double getTotalProcessedAzimuthBandWidth(); + void setTotalProcessedAzimuthBandWidth(double v); + + double getDopplerParametersReferenceTime(); + void setDopplerParametersReferenceTime(double v); + + // ղ + QVector getDopplerParams(); + void setDopplerParams(double d0, double d1, double d2, double d3, double d4); + + // ϵ + QVector getDopplerCenterCoff(); + void setDopplerCenterCoff(double r0, double r1, double r2, double r3, double r4); + + + double getIncidenceAngleNearRange(); + void setIncidenceAngleNearRangeet(double angle); + + double getIncidenceAngleFarRange(); + void setIncidenceAngleFarRange(double angle); + +private: + double latitude_center, longitude_center, + latitude_topLeft, longitude_topLeft, + latitude_topRight, longitude_topRight, + latitude_bottomLeft, longitude_bottomLeft, + latitude_bottomRight, longitude_bottomRight; +public: + // Getter and Setter functions + double getLatitudeCenter(); + void setLatitudeCenter(double value); + + double getLongitudeCenter(); + void setLongitudeCenter(double value); + + double getLatitudeTopLeft(); + void setLatitudeTopLeft(double value); + + double getLongitudeTopLeft(); + void setLongitudeTopLeft(double value); + + double getLatitudeTopRight(); + void setLatitudeTopRight(double value); + + double getLongitudeTopRight(); + void setLongitudeTopRight(double value); + + double getLatitudeBottomLeft(); + void setLatitudeBottomLeft(double value); + + double getLongitudeBottomLeft(); + void setLongitudeBottomLeft(double value); + + double getLatitudeBottomRight(); + void setLatitudeBottomRight(double value); + + double getLongitudeBottomRight(); + void setLongitudeBottomRight(double value); +public: + DemBox getExtend(); + + +public: + double getdrange(); + void setdrange(double dr); + + double getdAz(); + void setdAz(double dAz); +private: + double dr, dAz; + +}; + + + + + + + diff --git a/BaseTool/ShowProessAbstract.cpp b/BaseTool/ShowProessAbstract.cpp new file mode 100644 index 0000000..e862722 --- /dev/null +++ b/BaseTool/ShowProessAbstract.cpp @@ -0,0 +1,18 @@ +#include "stdafx.h" +#include "ShowProessAbstract.h" +#include "BaseTool.h" +#include "GeoOperator.h" +#include "FileOperator.h" +#include + + +void ShowProessAbstract::showProcess(double precent, QString tip) +{ + +} + +void ShowProessAbstract::showToolInfo(QString tip) +{ +} + + diff --git a/BaseTool/TestImageOperator.cpp b/BaseTool/TestImageOperator.cpp new file mode 100644 index 0000000..d2c9819 --- /dev/null +++ b/BaseTool/TestImageOperator.cpp @@ -0,0 +1,146 @@ +#include "stdafx.h" +#include "ImageOperatorBase.h" +#include "BaseTool.h" +#include "GeoOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FileOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include // OGRSpatialReference ڿռοת +#include // GDALWarp + + + +void testOutAmpArr(QString filename, float* amp, long rowcount, long colcount) +{ + + + Eigen::MatrixXd h_amp_img = Eigen::MatrixXd::Zero(rowcount, colcount); + + for (long hii = 0; hii < rowcount; hii++) { + for (long hjj = 0; hjj < colcount; hjj++) { + h_amp_img(hii, hjj) = amp[hii * colcount + hjj]; + } + } + QString ampPath = getDebugDataPath(filename); + saveEigenMatrixXd2Bin(h_amp_img, ampPath); + qDebug() << filename.toLocal8Bit().constData(); + qDebug() << "max:\t" << h_amp_img.maxCoeff(); + qDebug() << "min:\t" << h_amp_img.minCoeff(); +} + +void testOutAmpArr(QString filename, double* amp, long rowcount, long colcount) +{ + + + Eigen::MatrixXd h_amp_img = Eigen::MatrixXd::Zero(rowcount, colcount); + + for (long hii = 0; hii < rowcount; hii++) { + for (long hjj = 0; hjj < colcount; hjj++) { + h_amp_img(hii, hjj) = amp[hii * colcount + hjj]; + } + } + QString ampPath = getDebugDataPath(filename); + saveEigenMatrixXd2Bin(h_amp_img, ampPath); + qDebug() << filename.toLocal8Bit().constData(); + qDebug() << "max:\t" << h_amp_img.maxCoeff(); + qDebug() << "min:\t" << h_amp_img.minCoeff(); +} + + +void testOutClsArr(QString filename, long* amp, long rowcount, long colcount) { + + Eigen::MatrixXd h_amp_img = Eigen::MatrixXd::Zero(rowcount, colcount); + + for (long hii = 0; hii < rowcount; hii++) { + for (long hjj = 0; hjj < colcount; hjj++) { + h_amp_img(hii, hjj) = amp[hii * colcount + hjj]; + } + } + QString ampPath = getDebugDataPath(filename); + saveEigenMatrixXd2Bin(h_amp_img, ampPath); + qDebug() << filename.toLocal8Bit().constData(); + qDebug() << "max:\t" << h_amp_img.maxCoeff(); + qDebug() << "min:\t" << h_amp_img.minCoeff(); + +} + +void testOutComplexDoubleArr(QString filename, std::complex* data, long rowcount, long colcount) +{ + QString ampPath = getDebugDataPath(filename); + gdalImageComplex compleximg = CreateEchoComplex(ampPath, rowcount, colcount, 1); + compleximg.saveImage(data, 0, 0, rowcount, colcount, 1); + + return; +} + +void testOutDataArr(QString filename, double* data, long rowcount, long colcount) +{ + return testOutAmpArr(filename, data, rowcount, colcount); +} + +void testOutDataArr(QString filename, float* data, long rowcount, long colcount) +{ + return testOutAmpArr(filename, data, rowcount, colcount); +} + +void testOutDataArr(QString filename, long* data, long rowcount, long colcount) +{ + return testOutClsArr(filename, data, rowcount, colcount); +} + +void testOutAntPatternTrans(QString antpatternfilename, double* antPatternArr, + double starttheta, double deltetheta, + double startphi, double deltaphi, + long thetanum, long phinum) +{ + + + Eigen::MatrixXd antPatternMatrix(thetanum, phinum); + for (long t = 0; t < thetanum; ++t) { + for (long p = 0; p < phinum; ++p) { + long index = t * phinum + p; + if (index < thetanum * phinum) { + antPatternMatrix(t, p) = static_cast(antPatternArr[index]); // Copy to Eigen matrix + } + } + } + + Eigen::MatrixXd gt(2, 3); + gt(0, 0) = startphi;//x + gt(0, 1) = deltaphi; + gt(0, 2) = 0; + + gt(1, 0) = starttheta; + gt(1, 1) = 0; + gt(1, 2) = deltetheta; + + QString antpatternfilepath = getDebugDataPath(antpatternfilename); + gdalImage ds = CreategdalImageDouble(antpatternfilepath, thetanum, phinum, 1, gt, "", true, true, true); + ds.saveImage(antPatternMatrix, 0, 0, 1); +} + + + + + + diff --git a/BaseTool/gdalImageComplexOperator.cpp b/BaseTool/gdalImageComplexOperator.cpp new file mode 100644 index 0000000..7d0df86 --- /dev/null +++ b/BaseTool/gdalImageComplexOperator.cpp @@ -0,0 +1,547 @@ +#include "stdafx.h" +#include "ImageOperatorBase.h" +#include "BaseTool.h" +#include "GeoOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FileOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include // OGRSpatialReference ڿռοת +#include // GDALWarp + + + + + + + + + +gdalImageComplex::gdalImageComplex(const QString& raster_path) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + this->img_path = raster_path; + + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen( + raster_path.toUtf8().constData(), GA_ReadOnly)); + this->width = rasterDataset->GetRasterXSize(); + this->height = rasterDataset->GetRasterYSize(); + this->band_num = rasterDataset->GetRasterCount(); + + double* gt = new double[6]; + rasterDataset->GetGeoTransform(gt); + this->gt = Eigen::MatrixXd(2, 3); + this->gt << gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]; + + double a = this->gt(0, 0); + double b = this->gt(0, 1); + double c = this->gt(0, 2); + double d = this->gt(1, 0); + double e = this->gt(1, 1); + double f = this->gt(1, 2); + + this->projection = rasterDataset->GetProjectionRef(); + + // ͷͶӰ + GDALFlushCache((GDALDatasetH)rasterDataset); + GDALClose((GDALDatasetH)rasterDataset); + rasterDataset = NULL; // ָÿ� + this->InitInv_gt(); + delete[] gt; + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + +gdalImageComplex::~gdalImageComplex() {} + +void gdalImageComplex::setData(Eigen::MatrixXcd data) +{ + this->data = data; +} + +void gdalImageComplex::saveImage(Eigen::MatrixXcd data, int start_row, int start_col, int band_ids) +{ + + + + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + data.rows() > this->height || start_col + data.cols() > this->width) { + QString tip = u8"file path: " + this->img_path; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_CFloat64, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + //delete[] gt_ptr; + } + + int datarows = data.rows(); + int datacols = data.cols(); + + if (this->getDataType() == GDT_CFloat64) + { + + double* databuffer = new double[data.size() * 2]; + for (int i = 0; i < data.rows(); i++) { + for (int j = 0; j < data.cols(); j++) { + databuffer[i * data.cols() * 2 + j * 2] = data(i, j).real(); + databuffer[i * data.cols() * 2 + j * 2 + 1] = data(i, j).imag(); + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, GDT_CFloat64, 0, 0); + GDALFlushCache(poDstDS); + delete databuffer; + + } + else if (this->getDataType() == GDT_CFloat32) { + + float* databuffer = new float[data.size() * 2]; + for (int i = 0; i < data.rows(); i++) { + for (int j = 0; j < data.cols(); j++) { + databuffer[i * data.cols() * 2 + j * 2] = float(data(i, j).real()); + databuffer[i * data.cols() * 2 + j * 2 + 1] =float( data(i, j).imag()); + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, GDT_CFloat32, 0, 0); + GDALFlushCache(poDstDS); + delete databuffer; + } + else { + throw std::exception("gdalImageComplex::saveImage: data type error"); + } + + + + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // +} + +void gdalImageComplex::saveImage(std::shared_ptr> data, long start_row, long start_col, long rowCount, long colCount, int band_ids) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + rowCount > this->height || start_col + colCount > this->width) { + QString tip = u8"file path: " + this->img_path; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + return; + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_CFloat64, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + //delete[] gt_ptr; + } + + double* databuffer = new double[rowCount * colCount * 2]; + for (long i = 0; i < rowCount; i++) { + for (long j = 0; j < colCount; j++) { + databuffer[i * colCount * 2 + j * 2] = data.get()[i * colCount + j].real(); + databuffer[i * colCount * 2 + j * 2 + 1] = data.get()[i * colCount + j].imag(); + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, colCount, rowCount, + databuffer, colCount, rowCount, GDT_CFloat64, 0, 0); + GDALFlushCache(poDstDS); + delete databuffer; + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // + +} + +void gdalImageComplex::saveImage(std::complex* data, long start_row, long start_col, long rowCount, long colCount, int band_ids) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + rowCount > this->height || start_col + colCount > this->width) { + QString tip = u8"file path: " + this->img_path; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + return; + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_CFloat64, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + //delete[] gt_ptr; + } + + double* databuffer = new double[rowCount * colCount * 2]; + for (long i = 0; i < rowCount; i++) { + for (long j = 0; j < colCount; j++) { + databuffer[i * colCount * 2 + j * 2] = data[i * colCount + j].real(); + databuffer[i * colCount * 2 + j * 2 + 1] = data[i * colCount + j].imag(); + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, colCount, rowCount, + databuffer, colCount, rowCount, GDT_CFloat64, 0, 0); + GDALFlushCache(poDstDS); + delete databuffer; + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // +} + +Eigen::MatrixXcd gdalImageComplex::getDataComplex(int start_row, int start_col, int rows_count, + int cols_count, int band_ids) +{ + GDALDataset* poDataset; + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + + // TIFFļ + poDataset = (GDALDataset*)GDALOpen(this->img_path.toUtf8().constData(), GA_ReadOnly); + if (poDataset == nullptr) { + QMessageBox::warning(nullptr, u8"", u8"޷ļ" + this->img_path); + qDebug() << u8"޷ļ" + this->img_path; + } + + // ȡݼĵһ + GDALRasterBand* poBand; + poBand = poDataset->GetRasterBand(1); + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + // ȡϢǸ + int nXSize = cols_count; poBand->GetXSize(); + int nYSize = rows_count; poBand->GetYSize(); + Eigen::MatrixXcd rasterData(nYSize, nXSize); // ʹEigenMatrixXcd + if (this->getDataType() == GDT_CFloat64) + { + long long pixelCount =long long( nXSize) *long long( nYSize); + double* databuffer = new double[pixelCount * 2]; + poBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, databuffer, cols_count, rows_count, GDT_CFloat64, 0, 0); + GDALClose((GDALDatasetH)poDataset); + + for (long long i = 0; i < nYSize; i++) { + for (long long j = 0; j < nXSize; j++) { + rasterData(i, j) = std::complex(databuffer[i * nXSize * 2 + j * 2], + databuffer[i * nXSize * 2 + j * 2 + 1]); + } + } + + delete[] databuffer; + } + else if(this->getDataType()==GDT_CFloat32) + { + long long pixelCount = long long(nXSize) * long long(nYSize); + float* databuffer = new float[pixelCount * 2]; + poBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, databuffer, cols_count, rows_count, GDT_CFloat32, 0, 0); + GDALClose((GDALDatasetH)poDataset); + + for (long long i = 0; i < nYSize; i++) { + for (long long j = 0; j < nXSize; j++) { + rasterData(i, j) = std::complex(databuffer[i * nXSize * 2 + j * 2], + databuffer[i * nXSize * 2 + j * 2 + 1]); + } + } + + delete[] databuffer; + } + + + return rasterData; +} + +std::shared_ptr> gdalImageComplex::getDataComplexSharePtr(int start_row, int start_col, int rows_count, int cols_count, int band_ids) +{ + GDALDataset* poDataset; + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + + // TIFFļ + poDataset = (GDALDataset*)GDALOpen(this->img_path.toUtf8().constData(), GA_ReadOnly); + if (poDataset == nullptr) { + QMessageBox::warning(nullptr, u8"", u8"޷ļ" + this->img_path); + qDebug() << u8"޷ļ" + this->img_path; + } + + // ȡݼĵһ + GDALRasterBand* poBand; + poBand = poDataset->GetRasterBand(1); + + // ȡϢǸ + + + double* databuffer = new double[rows_count * cols_count * 2]; + poBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, databuffer, cols_count, + rows_count, GDT_CFloat64, 0, 0); + GDALClose((GDALDatasetH)poDataset); + + std::shared_ptr> rasterData(new std::complex[rows_count * cols_count], delArrPtr); + + for (size_t i = 0; i < rows_count; i++) { + for (size_t j = 0; j < cols_count; j++) { + rasterData.get()[i * cols_count + j] = std::complex(databuffer[i * cols_count * 2 + j * 2], + databuffer[i * cols_count * 2 + j * 2 + 1]); + } + } + + delete[] databuffer; + return rasterData; +} + +void gdalImageComplex::saveComplexImage() +{ + this->saveImage(this->data, this->start_row, this->start_col, this->data_band_ids); +} +void gdalImageComplex::savePreViewImage() +{ + qDebug() << "void gdalImageComplex::savePreViewImage()"; + Eigen::MatrixXd data_abs = Eigen::MatrixXd::Zero(this->height, this->width); + data_abs = (this->data.array().real().pow(2) + this->data.array().imag().pow(2)) + .array() + .log10() * 10.0; // + + double min_abs = data_abs.minCoeff(); // ֵ + double max_abs = data_abs.maxCoeff(); // Сֵ + double delta = (max_abs - min_abs) / 1000; // 1000λ + Eigen::MatrixX data_idx = + ((data_abs.array() - min_abs).array() / delta).array().floor().cast(); + + // ʼ + double hist[1001]; + for (size_t i = 0; i < 1001; i++) { + hist[i] = 0; // ʼ + } + for (size_t i = 0; i < this->height; i++) { + for (size_t j = 0; j < this->width; j++) { + hist[data_idx(i, j)]++; + } + } + + // ͳ + size_t count = this->height * this->width; + double precent = 0; + size_t curCount = 0; + double pre2 = 0; + bool findprec_2 = true; + double pre98 = 0; + bool findprec_98 = true; + for (size_t i = 0; i < 1001; i++) { + precent = precent + hist[i]; + if (findprec_2 & precent / count > 0.02) { + pre2 = i * delta + min_abs; + findprec_2 = false; + } + if (findprec_98 & precent / count > 0.98) { + pre98 = (i - 1) * delta + min_abs; + findprec_98 = false; + } + } + // + delta = (pre98 - pre2) / 200; + data_idx = + ((data_abs.array() - pre2).array() / delta).array().floor().cast(); + + for (size_t i = 0; i < this->height; i++) { + for (size_t j = 0; j < this->width; j++) { + if (data_idx(i, j) < 0) { + data_idx(i, j) = 0; + } + else if (data_idx(i, j) > 255) { + data_idx(i, j) = 255; + } + else { + + } + } + } + + // ֵ + QString filePath = this->img_path; + QFile file(filePath); + QFileInfo fileInfo(file); + + QString directory = fileInfo.absolutePath(); + qDebug() << "ļĿ¼" << directory; + QString baseName = fileInfo.completeBaseName(); + qDebug() << "޺׺ļ" << baseName; + + // ļ· + QString previewImagePath = JoinPath(directory, baseName + "_preview.png"); + cv::Mat img(this->height, this->width, CV_8U, cv::Scalar(0)); + + for (size_t i = 0; i < this->height; i++) { + for (size_t j = 0; j < this->width; j++) { + img.at(i, j) = (uchar)(data_idx(i, j)); + } + } + //std::string outimgpath=previewImagePath.toUtf8().data(); + cv::imwrite(previewImagePath.toUtf8().data(), img); +} + + + +gdalImageComplex CreategdalImageComplex(const QString& img_path, int height, int width, + int band_num, Eigen::MatrixXd gt, QString projection, + bool need_gt, bool overwrite) +{ + if (exists_test(img_path.toUtf8().constData())) { + if (overwrite) { + gdalImageComplex result_img(img_path); + return result_img; + } + else { + throw "file has exist!!!"; + exit(1); + } + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = poDriver->Create(img_path.toUtf8().constData(), width, height, band_num, + GDT_CFloat64, NULL); + if (need_gt) { + poDstDS->SetProjection(projection.toUtf8().constData()); + + // ����ת������ + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + //for(int i = 1; i <= band_num; i++) { + // poDstDS->GetRasterBand(i)->SetNoDataValue(0); // ز + //} + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImageComplex result_img(img_path); + return result_img; +} + +gdalImageComplex CreategdalImageComplexNoProj(const QString& img_path, int height, int width, int band_num, bool overwrite) +{ + + // ļ + 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(img_path.toUtf8().constData(), width, height, band_num, GDT_CFloat64, NULL)); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + //poDstDS.reset(); + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // + + gdalImageComplex result_img(img_path); + return result_img; +} + +gdalImageComplex CreateEchoComplex(const QString& img_path, int height, int width, int band_num) +{ + // ͼ + Eigen::MatrixXd gt = Eigen::MatrixXd::Zero(2, 3); + //Xgeo = GeoTransform[0] + Xpixel * GeoTransform[1] + Ypixel * GeoTransform[2] + //Ygeo = GeoTransform[3] + Xpixel * GeoTransform[4] + Ypixel * GeoTransform[5] + // X + gt(0, 0) = 0; gt(0, 2) = 1; gt(0, 2) = 0; + gt(1, 0) = 0; gt(1, 1) = 0; gt(1, 2) = 1; + // Y + QString projection = ""; + gdalImageComplex echodata = CreategdalImageComplex(img_path, height, width, 1, gt, projection, false, true); + return echodata; + +} + diff --git a/BaseTool/gdalImageOperator.cpp b/BaseTool/gdalImageOperator.cpp new file mode 100644 index 0000000..e596e8e --- /dev/null +++ b/BaseTool/gdalImageOperator.cpp @@ -0,0 +1,1530 @@ +#include "stdafx.h" +#include "ImageOperatorBase.h" +#include "BaseTool.h" +#include "GeoOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FileOperator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include // OGRSpatialReference ڿռοת +#include // GDALWarp + + + + + +gdalImage::gdalImage() +{ + this->height = 0; + this->width = 0; + this->data_band_ids = 1; + this->start_row = 0; + this->start_col = 0; +} + +/// +/// �ͼȡӰ�?1?7 +/// +/// +gdalImage::gdalImage(const QString& raster_path) +{ + omp_lock_t lock; + omp_init_lock(&lock); // ��ʼ�� + omp_set_lock(&lock); // ��û�?1?7 + this->img_path = raster_path; + + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // עʽ��?1?7 + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + // ��DEMӰ�� + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(raster_path.toUtf8().constData(), GA_ReadOnly)); + if (nullptr == rasterDataset || NULL == rasterDataset) { + QMessageBox::warning(nullptr, u8"", QString(u8"ļ޷򿪣") + QString(raster_path)); + exit(1); + } + this->width = rasterDataset->GetRasterXSize(); + this->height = rasterDataset->GetRasterYSize(); + this->band_num = rasterDataset->GetRasterCount(); + + double* gt = new double[6]; + // ��÷��� + rasterDataset->GetGeoTransform(gt); + this->gt = Eigen::MatrixXd(2, 3); + this->gt << gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]; + + this->projection = rasterDataset->GetProjectionRef(); + // �� + // double* inv_gt = new double[6];; + // GDALInvGeoTransform(gt, inv_gt); // �� + // �ͶӰ + GDALFlushCache((GDALDatasetH)rasterDataset); + GDALClose((GDALDatasetH)rasterDataset); + rasterDataset = NULL; // ָÿ� + this->InitInv_gt(); + delete[] gt; + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + +gdalImage::~gdalImage() {} + +void gdalImage::setHeight(int height) +{ + this->height = height; +} + +void gdalImage::setWidth(int width) +{ + this->width = width; +} + +void gdalImage::setTranslationMatrix(Eigen::MatrixXd gt) +{ + this->gt = gt; +} + +void gdalImage::setData(Eigen::MatrixXd, int data_band_ids) +{ + this->data = data; + this->data_band_ids = data_band_ids; +} + +Eigen::MatrixXd gdalImage::getData(int start_row, int start_col, int rows_count, int cols_count, + int band_ids = 1) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen( + this->img_path.toUtf8().constData(), GA_ReadOnly)); // ��ֻ�ʽ��ȡ�Ӱ�� + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + Eigen::MatrixXd datamatrix(rows_count, cols_count); + + if (gdal_datatype == GDT_Byte) { + char* temp = new char[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = long(temp[i * cols_count + j]) * 1.0; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt16) { + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = long(temp[i * cols_count + j]) * 1.0; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int16) { + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = long(temp[i * cols_count + j]) * 1.0; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt32) { + unsigned int* temp = new unsigned int[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int32) { + int* temp = new int[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = long(temp[i * cols_count + j]) * 1.0; + } + } + delete[] temp; + } + //else if (gdal_datatype == GDT_UInt64) { + // unsigned long* temp = new unsigned long[rows_count * cols_count]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + // rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { + // for (int j = 0; j < + // cols_count; j++) { + // datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + //} + //else if (gdal_datatype == GDT_Int64) { + // long* temp = new long[rows_count * cols_count]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + // rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { + // for (int j = 0; j < + // cols_count; j++) { + // datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + //} + else if (gdal_datatype == GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Float64) { + double* temp = new double[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else { + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return datamatrix; +} + +Eigen::MatrixXf gdalImage::getDataf(int start_row, int start_col, int rows_count, int cols_count, + int band_ids = 1) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen( + this->img_path.toUtf8().constData(), GA_ReadOnly)); // ��ֻ�ʽ��ȡ�Ӱ�� + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + Eigen::MatrixXf datamatrix(rows_count, cols_count); + + if (gdal_datatype == GDT_Byte) { + char* temp = new char[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt16) { + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int16) { + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt32) { + unsigned int* temp = new unsigned int[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int32) { + int* temp = new int[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + //else if (gdal_datatype == GDT_UInt64) { + // unsigned long* temp = new unsigned long[rows_count * cols_count]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + // rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { + // for (int j = 0; j < + // cols_count; j++) { + // datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + //} + //else if (gdal_datatype == GDT_Int64) { + // long* temp = new long[rows_count * cols_count]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + // rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { + // for (int j = 0; j < + // cols_count; j++) { + // datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + //} + else if (gdal_datatype == GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Float64) { + double* temp = new double[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else { + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return datamatrix; +} + + + +Eigen::MatrixXi gdalImage::getDatai(int start_row, int start_col, int rows_count, int cols_count, int band_ids) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen( + this->img_path.toUtf8().constData(), GA_ReadOnly)); // ��ֻ�ʽ��ȡ�Ӱ�� + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + Eigen::MatrixXi datamatrix(rows_count, cols_count); + + if (gdal_datatype == GDT_Byte) { + char* temp = new char[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt16) { + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int16) { + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_UInt32) { + unsigned int* temp = new unsigned int[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Int32) { + int* temp = new int[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + //else if (gdal_datatype == GDT_UInt64) { + // unsigned long* temp = new unsigned long[rows_count * cols_count]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + // rows_count, gdal_datatype, 0, 0); for (int i = 0; i < rows_count; i++) { + // for (int j = 0; j < + // cols_count; j++) { + // datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + //} + //else if (gdal_datatype == GDT_Int64) { + // long* temp = new long[rows_count * cols_count]; + // demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + // for (int i = 0; i < rows_count; i++) { + // for (int j = 0; j < cols_count; j++) { + // datamatrix(i, j) = temp[i * cols_count + j]; + // } + // } + // delete[] temp; + //} + else if (gdal_datatype == GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDT_Float64) { + double* temp = new double[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, + rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else { + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return datamatrix; +} + +ErrorCode gdalImage::getData(double* data, int start_row, int start_col, int rows_count, int cols_count, int band_ids) +{ + ErrorCode state = ErrorCode::SUCCESS; + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_ReadOnly)); // ��ֻ�ʽ��ȡ�Ӱ�� + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + + + if (gdal_datatype == GDT_Float64) { + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, data, cols_count, rows_count, gdal_datatype, 0, 0); + } + else { + state = ErrorCode::FAIL; + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� + return state; +} + +ErrorCode gdalImage::getData(long* data, int start_row, int start_col, int rows_count, int cols_count, int band_ids) +{ + ErrorCode state = ErrorCode::SUCCESS; + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_ReadOnly)); // ��ֻ�ʽ��ȡ�Ӱ�� + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + if (gdal_datatype == GDT_Int32) { + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, data, cols_count, rows_count, gdal_datatype, 0, 0); + } + else { + state = ErrorCode::FAIL; + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� + return state; +} + +Eigen::MatrixXd gdalImage::getGeoTranslation() +{ + return this->gt; +} + +GDALDataType gdalImage::getDataType() +{ + GDALDataset* rasterDataset = + (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_ReadOnly)); + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + return gdal_datatype; +} + +/// +/// +/// +/// +/// +/// +/// +void gdalImage::saveImage(Eigen::MatrixXd data, int start_row = 0, int start_col = 0, + int band_ids = 1) +{ + GDALDataType datetype = this->getDataType(); + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + data.rows() > this->height || start_col + data.cols() > this->width) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + data.rows()) + ", " + QString::number(start_col + data.cols()) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + + QString filesuffer = getFileExtension(this->img_path).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* poDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, datetype, NULL); // ��� + + if (nullptr == poDstDS) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + data.rows()) + ", " + QString::number(start_col + data.cols()) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + return; + } + + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + //delete gt_ptr; + } + + + int datarows = data.rows(); + int datacols = data.cols(); + void* databuffer = nullptr; + if (datetype == GDT_Float32) { + databuffer = new float[datarows * datacols]; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ((float*)databuffer)[i * datacols + j] = float(data(i, j)); + } + } + + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + } + else if (datetype == GDT_Float64) { + databuffer = new double[datarows * datacols]; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ((double*)databuffer)[i * datacols + j] = double(data(i, j)); + } + } + + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + } + else { + + } + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); // + omp_destroy_lock(&lock); // +} + +void gdalImage::saveImage(Eigen::MatrixXf data, int start_row = 0, int start_col = 0, + int band_ids = 1) +{ + GDALDataType datetype = this->getDataType(); + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + data.rows() > this->height || start_col + data.cols() > this->width) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + data.rows()) + ", " + QString::number(start_col + data.cols()) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + QString filesuffer = getFileExtension(this->img_path).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* poDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, datetype, NULL); // ��� + + if (nullptr == poDstDS) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + data.rows()) + ", " + QString::number(start_col + data.cols()) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + return; + } + + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + //delete gt_ptr; + } + + + int datarows = data.rows(); + int datacols = data.cols(); + void* databuffer = nullptr; + if (datetype == GDT_Float32) { + databuffer = new float[datarows * datacols]; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ((float*)databuffer)[i * datacols + j] = float(data(i, j)); + } + } + + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + } + else if (datetype == GDT_Float64) { + databuffer = new double[datarows * datacols]; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ((double*)databuffer)[i * datacols + j] = double(data(i, j)); + } + } + + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + } + else { + + } + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + + +void gdalImage::saveImage(Eigen::MatrixXi data, int start_row, int start_col, int band_ids) +{ + GDALDataType datetype = this->getDataType(); + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + data.rows() > this->height || start_col + data.cols() > this->width) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + data.rows()) + ", " + QString::number(start_col + data.cols()) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + QString filesuffer = getFileExtension(this->img_path).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* poDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_Float32, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + //delete gt_ptr; + } + + long datarows = data.rows(); + long datacols = data.cols(); + + long* databuffer = new long[datarows * datacols]; // (float*)malloc(datarows * datacols * sizeof(float)); + + for (long i = 0; i < datarows; i++) { + for (long j = 0; j < datacols; j++) { + databuffer[i * datacols + j] = data(i, j); + } + } + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + +void gdalImage::saveImage(std::shared_ptr data, int start_row, int start_col, int rowcount, int colcount, int band_ids) +{ + GDALDataType datetype = this->getDataType(); + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + rowcount > this->height || start_col + colcount > this->width) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + rowcount) + ", " + QString::number(start_col + colcount) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + QString filesuffer = getFileExtension(this->img_path).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* poDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_Float64, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + + long datarows = rowcount; + long datacols = colcount; + double* databuffer = new double[datarows * datacols]; + if (datetype == GDT_Float64) { + memcpy(databuffer, data.get(), sizeof(double) * datarows * datacols); + } + else { + for (long i = 0; i < datarows; i++) { + for (long j = 0; j < datacols; j++) { + databuffer[i * datacols + j] = data.get()[i * datacols + j]; + } + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + +void gdalImage::saveImage(std::shared_ptr data, int start_row, int start_col, int rowcount, int colcount, int band_ids) +{ + GDALDataType datetype = this->getDataType(); + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + rowcount > this->height || start_col + colcount > this->width) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + rowcount) + ", " + QString::number(start_col + colcount) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + QString filesuffer = getFileExtension(this->img_path).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* poDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_Float32, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + + long datarows = rowcount; + long datacols = colcount; + float* databuffer = new float[datarows * datacols]; + if (datetype == GDT_Float32) { + memcpy(databuffer, data.get(), sizeof(float) * datarows * datacols); + } + else { + for (long i = 0; i < datarows; i++) { + for (long j = 0; j < datacols; j++) { + databuffer[i * datacols + j] = data.get()[i * datacols + j]; + } + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + //delete poDstDS; + //poDstDS = nullptr; + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + + +void gdalImage::saveImage(std::shared_ptr data, int start_row, int start_col, int rowcount, int colcount, int band_ids) +{ + GDALDataType datetype = this->getDataType(); + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + if (start_row + rowcount > this->height || start_col + colcount > this->width) { + QString tip = u8"file path: " + this->img_path + " image size :( " + QString::number(this->height) + " , " + QString::number(this->width) + " ) " + " input size (" + QString::number(start_row + rowcount) + ", " + QString::number(start_col + colcount) + ") "; + qDebug() << tip; + throw std::exception(tip.toUtf8().constData()); + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); + QString filesuffer = getFileExtension(this->img_path).toLower(); + bool isTiff = filesuffer.contains("tif"); + GDALDriver* poDriver = isTiff ? GetGDALDriverManager()->GetDriverByName("GTiff") : GetGDALDriverManager()->GetDriverByName("ENVI"); + GDALDataset* poDstDS = nullptr; + if (exists_test(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.toUtf8().constData(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.toUtf8().constData(), this->width, this->height, + this->band_num, GDT_Float32, NULL); // ��� + poDstDS->SetProjection(this->projection.toUtf8().constData()); + + double gt_ptr[6]; + for (int i = 0; i < this->gt.rows(); i++) { + for (int j = 0; j < this->gt.cols(); j++) { + gt_ptr[i * 3 + j] = this->gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + + long datarows = rowcount; + long datacols = colcount; + int* databuffer = new int[datarows * datacols]; + if (datetype == GDT_Int32) { + memcpy(databuffer, data.get(), sizeof(int) * datarows * datacols); + } + else { + for (long i = 0; i < datarows; i++) { + for (long j = 0; j < datacols; j++) { + databuffer[i * datacols + j] = data.get()[i * datacols + j]; + } + } + } + + // poDstDS->RasterIO(GF_Write,start_col, start_row, datacols, datarows, databuffer, datacols, + // datarows, GDT_Float32,band_ids, num,0,0,0); + poDstDS->GetRasterBand(band_ids)->RasterIO(GF_Write, start_col, start_row, datacols, datarows, + databuffer, datacols, datarows, datetype, 0, 0); + + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); // �ͷŻ�� + omp_destroy_lock(&lock); // ٻ�� +} + + +void gdalImage::saveImage() +{ + this->saveImage(this->data, this->start_row, this->start_col, this->data_band_ids); +} + + + + +void gdalImage::setNoDataValue(double nodatavalue = -9999, int band_ids = 1) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // עʽ��?1?7 + // GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.toUtf8().constData(), GA_Update)); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(nodatavalue); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); +} + +void gdalImage::setNoDataValuei(int nodatavalue, int band_ids) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // עʽ��?1?7 + // GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.toUtf8().constData(), GA_Update)); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(nodatavalue); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); +} + +double gdalImage::getNoDataValue(int band_ids) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // עʽ��?1?7 + // GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.toUtf8().constData(), GA_Update)); + double v = poDstDS->GetRasterBand(band_ids)->GetNoDataValue(); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + return v; +} + +int gdalImage::getNoDataValuei(int band_ids) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // עʽ��?1?7 + // GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.toUtf8().constData(), GA_Update)); + int v = poDstDS->GetRasterBand(band_ids)->GetNoDataValue(); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + return v; +} + + +int gdalImage::InitInv_gt() +{ + // 1 lon lat = x + // 1 lon lat = y + Eigen::MatrixXd temp = Eigen::MatrixXd::Zero(2, 3); + this->inv_gt = temp; + double a = this->gt(0, 0); + double b = this->gt(0, 1); + double c = this->gt(0, 2); + double d = this->gt(1, 0); + double e = this->gt(1, 1); + double f = this->gt(1, 2); + double g = 1; + double det_gt = b * f - c * e; + if (det_gt == 0) { + return 0; + } + this->inv_gt(0, 0) = (c * d - a * f) / det_gt; // 2 + this->inv_gt(0, 1) = f / det_gt; // lon + this->inv_gt(0, 2) = -c / det_gt; // lat + this->inv_gt(1, 0) = (a * e - b * d) / det_gt; // 1 + this->inv_gt(1, 1) = -e / det_gt; // lon + this->inv_gt(1, 2) = b / det_gt; // lat + return 1; +} + +Landpoint gdalImage::getRow_Col(double lon, double lat) +{ + Landpoint p{ 0, 0, 0 }; + p.lon = this->inv_gt(0, 0) + lon * this->inv_gt(0, 1) + lat * this->inv_gt(0, 2); // x + p.lat = this->inv_gt(1, 0) + lon * this->inv_gt(1, 1) + lat * this->inv_gt(1, 2); // y + return p; +} + +Landpoint gdalImage::getLandPoint(double row, double col, double ati = 0) +{ + Landpoint p{ 0, 0, 0 }; + p.lon = this->gt(0, 0) + col * this->gt(0, 1) + row * this->gt(0, 2); // x + p.lat = this->gt(1, 0) + col * this->gt(1, 1) + row * this->gt(1, 2); // y + p.ati = ati; + return p; +} + +void gdalImage::getLandPoint(double row, double col, double ati, Landpoint& Lp) +{ + Lp.lon = this->gt(0, 0) + col * this->gt(0, 1) + row * this->gt(0, 2); // x + Lp.lat = this->gt(1, 0) + col * this->gt(1, 1) + row * this->gt(1, 2); // y + Lp.ati = ati; + +} + + + + + + +double gdalImage::mean(int bandids) +{ + double mean_value = 0; + double count = this->height * this->width; + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + mean_value = mean_value + sar_a.sum() / count; + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return mean_value; +} + +double gdalImage::BandmaxValue(int bandids) +{ + double max_value = 0; + bool state_max = true; + int line_invert = 100; + int start_ids = 0; + double temp_max = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_max) { + state_max = false; + max_value = sar_a.maxCoeff(); + } + else { + temp_max = sar_a.maxCoeff(); + if (max_value < temp_max) { + max_value = temp_max; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return max_value; +} + +double gdalImage::BandminValue(int bandids) +{ + double min_value = 0; + bool state_min = true; + int line_invert = 100; + int start_ids = 0; + double temp_min = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_min) { + state_min = false; + min_value = sar_a.minCoeff(); + } + else { + temp_min = sar_a.minCoeff(); + if (min_value < temp_min) { + min_value = temp_min; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return min_value; +} + +GDALRPCInfo gdalImage::getRPC() +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ע��� + // ��� + GDALDataset* pDS = (GDALDataset*)GDALOpen(this->img_path.toUtf8().constData(), GA_ReadOnly); + // ��Ԫ��л�ȡRPC��Ϣ + char** papszRPC = pDS->GetMetadata("RPC"); + + // �ȡ��RPC��Ϣ�ɽṹ�?1?7 + GDALRPCInfo oInfo; + GDALExtractRPCInfo(papszRPC, &oInfo); + + GDALClose((GDALDatasetH)pDS); + + return oInfo; +} + +Eigen::MatrixXd gdalImage::getLandPoint(Eigen::MatrixXd points) +{ + if (points.cols() != 3) { + throw new std::exception("the size of points is equit 3!!!"); + } + + Eigen::MatrixXd result(points.rows(), 3); + result.col(2) = points.col(2); // �߳� + points.col(2) = points.col(2).array() * 0 + 1; + points.col(0).swap(points.col(2)); // � + Eigen::MatrixXd gts(3, 2); + gts.col(0) = this->gt.row(0); + gts.col(1) = this->gt.row(1); + + result.block(0, 0, points.rows(), 2) = points * gts; + return result; +} + +Eigen::MatrixXd gdalImage::getHist(int bandids) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // עʽ��?1?7 + // ��DEMӰ�� + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen( + this->img_path.toUtf8().constData(), GA_ReadOnly)); // ��ֻ�ʽ��ȡ�Ӱ�� + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* xBand = rasterDataset->GetRasterBand(bandids); + + double dfMin = this->BandminValue(bandids); + double dfMax = this->BandmaxValue(bandids); + int count = int((dfMax - dfMin) / 0.01); + count = count > 255 ? count : 255; + GUIntBig* panHistogram = new GUIntBig[count]; + xBand->GetHistogram(dfMin, dfMax, count, panHistogram, TRUE, FALSE, NULL, NULL); + Eigen::MatrixXd result(count, 2); + double delta = (dfMax - dfMin) / count; + for (int i = 0; i < count; i++) { + result(i, 0) = dfMin + i * delta; + result(i, 1) = double(panHistogram[i]); + } + delete[] panHistogram; + GDALClose((GDALDatasetH)rasterDataset); + return result; +} + +RasterExtend gdalImage::getExtend() +{ + RasterExtend extend{ 0,0,0,0 }; + double x1 = this->gt(0, 0); + double y1 = this->gt(1, 0); + + double x2 = this->gt(0, 0) + (this->width - 1) * gt(0, 1) + (0) * gt(0, 2); // + double y2 = this->gt(1, 0) + (this->width - 1) * gt(1, 1) + (0) * gt(1, 2); // γ + + double x3 = this->gt(0, 0) + (0) * gt(0, 1) + (this->height - 1) * gt(0, 2); + double y3 = this->gt(1, 0) + (0) * gt(1, 1) + (this->height - 1) * gt(1, 2); + + double x4 = this->gt(0, 0) + (this->width - 1) * gt(0, 1) + (this->height - 1) * gt(0, 2); + double y4 = this->gt(1, 0) + (this->width - 1) * gt(1, 1) + (this->height - 1) * gt(1, 2); + + + extend.min_x = x1 < x2 ? x1 : x2; + extend.max_x = x1 < x2 ? x2 : x1; + extend.min_y = y1 < y2 ? y1 : y2; + extend.max_y = y1 < y2 ? y2 : y1; + + + extend.min_x = extend.min_x < x3 ? extend.min_x : x3; + extend.max_x = extend.max_x > x3 ? extend.max_x : x3; + extend.min_y = extend.min_y < y3 ? extend.min_y : y3; + extend.max_y = extend.max_y > y3 ? extend.max_y : y3; + + + extend.min_x = extend.min_x < x4 ? extend.min_x : x4; + extend.max_x = extend.max_x > x4 ? extend.max_x : x4; + extend.min_y = extend.min_y < y4 ? extend.min_y : y4; + extend.max_y = extend.max_y > y4 ? extend.max_y : y4; + + return extend; +} + + + + + + +gdalImage CreategdalImageDouble(QString& img_path, int height, int width, int band_num, bool overwrite, bool isEnvi) +{ + + if (exists_test(img_path.toUtf8().constData())) { + if (overwrite) { + gdalImage result_img(img_path); + return result_img; + } + else { + throw "file has exist!!!"; + exit(1); + } + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ע���ʽ�����?1?7 + GDALDriver* poDriver = nullptr; + if (isEnvi) { + poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + } + else { + poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + } + + + GDALDataset* poDstDS = poDriver->Create(img_path.toUtf8().constData(), width, height, band_num, GDT_Float64, NULL); // ������ + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; + +} + +gdalImage CreategdalImageFloat(QString& img_path, int height, int width, int band_num, bool overwrite, bool isEnvi) +{ + + if (exists_test(img_path.toUtf8().constData())) { + if (overwrite) { + gdalImage result_img(img_path); + return result_img; + } + else { + throw "file has exist!!!"; + exit(1); + } + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ע���ʽ�����?1?7 + GDALDriver* poDriver = nullptr; + if (isEnvi) { + poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + } + else { + poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + } + + + GDALDataset* poDstDS = poDriver->Create(img_path.toUtf8().constData(), width, height, band_num, GDT_Float32, NULL); // ������ + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + +gdalImage CreategdalImageDouble(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection, bool need_gt, bool overwrite, bool isEnvi) +{ + if (exists_test(img_path.toUtf8().constData())) { + if (overwrite) { + gdalImage result_img(img_path); + return result_img; + } + else { + throw "file has exist!!!"; + exit(1); + } + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ע���ʽ�����?1?7 + GDALDriver* poDriver = nullptr; + if (isEnvi) { + poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + } + else { + poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + } + + + GDALDataset* poDstDS = poDriver->Create(img_path.toUtf8().constData(), width, height, band_num, + GDT_Float64, NULL); // ������ + if (need_gt) { + if (!projection.isEmpty()) { + poDstDS->SetProjection(projection.toUtf8().constData()); + } + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + for (int i = 1; i <= band_num; i++) { + poDstDS->GetRasterBand(i)->SetNoDataValue(-9999); + } + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + +gdalImage CreategdalImage(const QString& img_path, int height, int width, int band_num, + Eigen::MatrixXd gt, QString projection, bool need_gt, bool overwrite, bool isEnvi, GDALDataType datetype) +{ + if (exists_test(img_path.toUtf8().constData())) { + if (overwrite) { + gdalImage result_img(img_path); + return result_img; + } + else { + throw "file has exist!!!"; + exit(1); + } + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ע���ʽ�����?1?7 + GDALDriver* poDriver = nullptr; + if (isEnvi) { + poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); + } + else { + poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + } + + + GDALDataset* poDstDS = poDriver->Create(img_path.toUtf8().constData(), width, height, band_num, + datetype, NULL); // ������ + + if (NULL == poDstDS) + { + qDebug() << "Create image failed!"; + throw "Create image failed!"; + exit(1); + } + + + if (need_gt) { + if (!projection.isEmpty()) { + poDstDS->SetProjection(projection.toUtf8().constData()); + } + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + for (int i = 1; i <= band_num; i++) { + poDstDS->GetRasterBand(i)->SetNoDataValue(-9999); + } + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + +gdalImage CreategdalImage(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, long epsgCode, GDALDataType eType, bool need_gt, bool overwrite, bool isENVI) +{ + if (exists_test(img_path.toUtf8().constData())) { + if (overwrite) { + gdalImage result_img(img_path); + return result_img; + } + else { + throw "file has exist!!!"; + exit(1); + } + } + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // ע���ʽ�����?1?7 + GDALDriver* poDriver = isENVI ? GetGDALDriverManager()->GetDriverByName("ENVI") : GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = poDriver->Create(img_path.toUtf8().constData(), width, height, band_num, eType, NULL); // ������ + if (need_gt) { + OGRSpatialReference oSRS; + + if (oSRS.importFromEPSG(epsgCode) != OGRERR_NONE) { + qDebug() << "Failed to import EPSG code " << epsgCode; + throw "Failed to import EPSG code "; + exit(1); + } + char* pszWKT = NULL; + oSRS.exportToWkt(&pszWKT); + qDebug() << "WKT of EPSG:" << epsgCode << " :\n" << pszWKT; + poDstDS->SetProjection(pszWKT); + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + for (int i = 1; i <= band_num; i++) { + poDstDS->GetRasterBand(i)->SetNoDataValue(-9999); + } + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + + +bool CopyProjectTransformMatrixFromRasterAToRasterB(QString RasterAPath, QString RasterBPath) { + // עGDAL + GDALAllRegister(); + + // ӰAֻģʽ + GDALDataset* ds_a = (GDALDataset*)GDALOpen(RasterAPath.toUtf8().constData(), GA_ReadOnly); + if (ds_a == nullptr) { + std::cerr << "޷ӰA" << std::endl; + return false; + } + + // ȡAķͶӰϢ + double geotransform[6]; + ds_a->GetGeoTransform(geotransform); // 任 + const char* projection = ds_a->GetProjectionRef(); // WKTʽͶӰ + + // ӰBģʽ + GDALDataset* ds_b = (GDALDataset*)GDALOpen(RasterBPath.toUtf8().constData(), GA_Update); + if (ds_b == nullptr) { + std::cerr << "޷ӰB" << std::endl; + GDALClose(ds_a); + return false; + } + + // ÷ + if (ds_b->SetGeoTransform(geotransform) != CE_None) { + std::cerr << "÷ʧ" << std::endl; + } + + // ͶӰϵ + if (ds_b->SetProjection(projection) != CE_None) { + std::cerr << "ͶӰʧ" << std::endl; + } + + // ͷԴ + GDALClose(ds_a); + GDALClose(ds_b); + + return true; + + + + + +} + + + + diff --git a/BaseTool/stdafx.cpp b/BaseTool/stdafx.cpp new file mode 100644 index 0000000..fd4f341 --- /dev/null +++ b/BaseTool/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/BaseTool/stdafx.h b/BaseTool/stdafx.h new file mode 100644 index 0000000..e69de29 diff --git a/ToolAbstract/QToolAbstract.cpp b/ToolAbstract/QToolAbstract.cpp new file mode 100644 index 0000000..a20a9c5 --- /dev/null +++ b/ToolAbstract/QToolAbstract.cpp @@ -0,0 +1,41 @@ +#include "QToolAbstract.h" + +QToolAbstract::QToolAbstract(QObject* parent) +:QObject(parent) +{ + +} + +QToolAbstract::~QToolAbstract() +{ + +} + +void QToolAbstract::setToolXpath(QVector intoolPath) +{ + this->toolPath = intoolPath; +} + +void QToolAbstract::setToolName(QString intoolname) +{ + this->toolname = intoolname; +} + +QVector QToolAbstract::getToolXpath() +{ + return this->toolPath; +} + +QString QToolAbstract::getToolName() +{ + return this->toolname; +} + +void QToolAbstract::excute() +{ + this->run(); +} + +void QToolAbstract::run() +{ +} diff --git a/ToolAbstract/QToolAbstract.h b/ToolAbstract/QToolAbstract.h new file mode 100644 index 0000000..fda74f6 --- /dev/null +++ b/ToolAbstract/QToolAbstract.h @@ -0,0 +1,40 @@ +#pragma once +#ifndef QToolAbstract_H_ +#define QToolAbstract_H_ + +#include "BaseConstVariable.h" +#include +#include +#include +#include +#include +#include +#include + + +// Զ QTreeWidgetItem ̳ +class BASECONSTVARIABLEAPI QToolAbstract : public QObject { + Q_OBJECT +public: + QToolAbstract(QObject* parent=nullptr); + ~QToolAbstract(); +public slots: + virtual void excute(); + virtual void setToolXpath(QVector toolPath); + virtual void setToolName(QString toolname); + virtual QVector getToolXpath(); + virtual QString getToolName(); +public: + QVector toolPath; + QString toolname; +public: + virtual void run(); +}; + +/* +// עṤ +PluginTool_*.dll +void RegisterPreToolBox(RasterProcessTool* mainWindows); +extern "C" void RegisterPreToolBox(LAMPMainWidget::RasterMainWidget* mainwindows,ToolBoxWidget* toolbox); +*/ +#endif // !1 \ No newline at end of file