Merge pull request 'RFPC-dev-a2806' (#10) from RFPC-dev-a2806 into Release

Reviewed-on: http://123.153.4.249:22779/LAMPSARToolSoftware/RasterProcessTool/pulls/10
Release
chenzenghui 2025-04-21 14:53:17 +08:00
commit b8ca064e79
190 changed files with 24185 additions and 4281 deletions

View File

@ -196,9 +196,6 @@
<ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj"> <ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj">
<Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project> <Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\ImageshowTool\ImageshowTool.vcxproj">
<Project>{8c8ca066-a93a-4098-9a46-b855efeaadf2}</Project>
</ProjectReference>
<ProjectReference Include="..\LAMPDataProcessEXE\LAMPDataProcessEXE.vcxproj"> <ProjectReference Include="..\LAMPDataProcessEXE\LAMPDataProcessEXE.vcxproj">
<Project>{4e6e79a3-048c-4fb4-bbb0-43c518a3e6d4}</Project> <Project>{4e6e79a3-048c-4fb4-bbb0-43c518a3e6d4}</Project>
</ProjectReference> </ProjectReference>
@ -211,9 +208,6 @@
<ProjectReference Include="..\Toolbox\BaseToolbox\BaseToolbox.vcxproj"> <ProjectReference Include="..\Toolbox\BaseToolbox\BaseToolbox.vcxproj">
<Project>{070c157e-3c30-4e2b-a80c-cbc7b74df03f}</Project> <Project>{070c157e-3c30-4e2b-a80c-cbc7b74df03f}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Toolbox\LAMPScatterTool\LAMPScatterTool.vcxproj">
<Project>{d603a623-132d-4304-ab03-638fc438f084}</Project>
</ProjectReference>
<ProjectReference Include="..\Toolbox\SimulationSARTool\SimulationSARTool.vcxproj"> <ProjectReference Include="..\Toolbox\SimulationSARTool\SimulationSARTool.vcxproj">
<Project>{ed06dfcd-4b9f-41f7-8f25-1823c2398142}</Project> <Project>{ed06dfcd-4b9f-41f7-8f25-1823c2398142}</Project>
</ProjectReference> </ProjectReference>

View File

@ -220,10 +220,13 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
<OpenMPSupport>true</OpenMPSupport> <OpenMPSupport>true</OpenMPSupport>
<LanguageStandard>stdcpp14</LanguageStandard> <LanguageStandard>stdcpp14</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C> <LanguageStandard_C>stdc11</LanguageStandard_C>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<WholeProgramOptimization>false</WholeProgramOptimization>
<Optimization>MaxSpeed</Optimization>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -274,11 +277,12 @@
<ClInclude Include="BaseTool\GeoOperator.h" /> <ClInclude Include="BaseTool\GeoOperator.h" />
<ClInclude Include="BaseTool\ImageOperatorBase.h" /> <ClInclude Include="BaseTool\ImageOperatorBase.h" />
<ClInclude Include="BaseTool\LogInfoCls.h" /> <ClInclude Include="BaseTool\LogInfoCls.h" />
<QtMoc Include="ToolAbstract\QToolAbstract.h" />
<QtMoc Include="BaseTool\QToolProcessBarDialog.h" /> <QtMoc Include="BaseTool\QToolProcessBarDialog.h" />
<ClInclude Include="BaseTool\SARSimulationImageL1.h" />
<ClInclude Include="ShowProessAbstract.h" />
<QtMoc Include="ToolAbstract\QToolAbstract.h" />
<ClInclude Include="BaseTool\PrintMsgToQDebug.h" /> <ClInclude Include="BaseTool\PrintMsgToQDebug.h" />
<ClInclude Include="BaseTool\RasterToolBase.h" /> <ClInclude Include="BaseTool\RasterToolBase.h" />
<ClInclude Include="BaseTool\SARSimulationImageL1.h" />
<ClInclude Include="BaseTool\stdafx.h" /> <ClInclude Include="BaseTool\stdafx.h" />
<ClInclude Include="framework.h" /> <ClInclude Include="framework.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
@ -287,15 +291,20 @@
<ClCompile Include="BaseTool\BaseTool.cpp" /> <ClCompile Include="BaseTool\BaseTool.cpp" />
<ClCompile Include="BaseTool\EchoDataFormat.cpp" /> <ClCompile Include="BaseTool\EchoDataFormat.cpp" />
<ClCompile Include="BaseTool\FileOperator.cpp" /> <ClCompile Include="BaseTool\FileOperator.cpp" />
<ClCompile Include="BaseTool\gdalImageComplexOperator.cpp" />
<ClCompile Include="BaseTool\gdalImageOperator.cpp" />
<ClCompile Include="BaseTool\GeoOperator.cpp" /> <ClCompile Include="BaseTool\GeoOperator.cpp" />
<ClCompile Include="BaseTool\ImageOperatorBase.cpp" />
<ClCompile Include="BaseTool\LogInfoCls.cpp" /> <ClCompile Include="BaseTool\LogInfoCls.cpp" />
<ClCompile Include="BaseTool\MergeRasterOperator.cpp" />
<ClCompile Include="BaseTool\PrintMsgToQDebug.cpp" /> <ClCompile Include="BaseTool\PrintMsgToQDebug.cpp" />
<ClCompile Include="BaseTool\QToolProcessBarDialog.cpp" /> <ClCompile Include="BaseTool\QToolProcessBarDialog.cpp" />
<ClCompile Include="BaseTool\RasterToolBase.cpp" /> <ClCompile Include="BaseTool\RasterToolBase.cpp" />
<ClCompile Include="BaseTool\SARSimulationImageL1.cpp" /> <ClCompile Include="BaseTool\SARSimulationImageL1.cpp" />
<ClCompile Include="BaseTool\ShowProessAbstract.cpp" />
<ClCompile Include="BaseTool\stdafx.cpp" /> <ClCompile Include="BaseTool\stdafx.cpp" />
<ClCompile Include="BaseTool\TestImageOperator.cpp" />
<ClCompile Include="dllmain.cpp" /> <ClCompile Include="dllmain.cpp" />
<ClCompile Include="ImageOperatorFuntion.cpp" />
<ClCompile Include="pch.cpp"> <ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>

View File

@ -33,33 +33,36 @@
<ClInclude Include="BaseTool\BaseTool.h"> <ClInclude Include="BaseTool\BaseTool.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="BaseTool\EchoDataFormat.h">
<Filter>BaseTool</Filter>
</ClInclude>
<ClInclude Include="BaseTool\FileOperator.h"> <ClInclude Include="BaseTool\FileOperator.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="BaseTool\GeoOperator.h"> <ClInclude Include="BaseTool\GeoOperator.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="BaseTool\ImageOperatorBase.h">
<Filter>BaseTool</Filter>
</ClInclude>
<ClInclude Include="BaseTool\LogInfoCls.h"> <ClInclude Include="BaseTool\LogInfoCls.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="BaseTool\RasterToolBase.h"> <ClInclude Include="BaseTool\RasterToolBase.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="BaseTool\SARSimulationImageL1.h">
<Filter>BaseTool</Filter>
</ClInclude>
<ClInclude Include="BaseTool\stdafx.h"> <ClInclude Include="BaseTool\stdafx.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="BaseTool\PrintMsgToQDebug.h"> <ClInclude Include="BaseTool\PrintMsgToQDebug.h">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ShowProessAbstract.h">
<Filter>BaseTool</Filter>
</ClInclude>
<ClInclude Include="BaseTool\ImageOperatorBase.h">
<Filter>BaseTool</Filter>
</ClInclude>
<ClInclude Include="BaseTool\EchoDataFormat.h">
<Filter>BaseTool</Filter>
</ClInclude>
<ClInclude Include="BaseTool\SARSimulationImageL1.h">
<Filter>BaseTool</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
@ -71,30 +74,18 @@
<ClCompile Include="BaseTool\BaseTool.cpp"> <ClCompile Include="BaseTool\BaseTool.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseTool\EchoDataFormat.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\FileOperator.cpp"> <ClCompile Include="BaseTool\FileOperator.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseTool\GeoOperator.cpp"> <ClCompile Include="BaseTool\GeoOperator.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseTool\ImageOperatorBase.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\LogInfoCls.cpp"> <ClCompile Include="BaseTool\LogInfoCls.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseTool\QToolProcessBarDialog.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\RasterToolBase.cpp"> <ClCompile Include="BaseTool\RasterToolBase.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseTool\SARSimulationImageL1.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\stdafx.cpp"> <ClCompile Include="BaseTool\stdafx.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
@ -104,16 +95,45 @@
<ClCompile Include="BaseTool\PrintMsgToQDebug.cpp"> <ClCompile Include="BaseTool\PrintMsgToQDebug.cpp">
<Filter>BaseTool</Filter> <Filter>BaseTool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseTool\ShowProessAbstract.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\gdalImageOperator.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\gdalImageComplexOperator.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="ImageOperatorFuntion.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\QToolProcessBarDialog.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\EchoDataFormat.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\SARSimulationImageL1.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\TestImageOperator.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
<ClCompile Include="BaseTool\MergeRasterOperator.cpp">
<Filter>BaseTool</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="BaseTool\QToolProcessBarDialog.h">
<Filter>头文件</Filter>
</QtMoc>
<QtMoc Include="ToolAbstract\QToolAbstract.h"> <QtMoc Include="ToolAbstract\QToolAbstract.h">
<Filter>ToolAbstract</Filter> <Filter>ToolAbstract</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="BaseTool\QToolProcessBarDialog.h">
<Filter>BaseTool</Filter>
</QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtUic Include="BaseTool\QToolProcessBarDialog.ui" /> <QtUic Include="BaseTool\QToolProcessBarDialog.ui">
<Filter>BaseTool</Filter>
</QtUic>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -15,12 +15,15 @@
/** 定义常见文件格式*********/
#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_BLAS
#define EIGEN_USE_LAPACK //#define EIGEN_USE_LAPACK
#define EIGEN_VECTORIZE_SSE2 //#define EIGEN_VECTORIZE_SSE2
//#define DEBUGSHOWDIALOG //#define DEBUGSHOWDIALOG
@ -49,7 +52,7 @@ inline char* get_cur_time() {
return s; return s;
} }
#define PRINT(fmt, ...) printf("%s " fmt, get_cur_time(), ##__VA_ARGS__) #define PRINT(fmt, ...) printf("%s " fmt, get_cur_time(), ##__VA_ARGS__);
@ -136,6 +139,14 @@ struct Point3 {
void setZ(double iz) { z = iz; } void setZ(double iz) { z = iz; }
}; };
struct Point_3d {
double x;
double y;
double z;
};
struct DemBox { struct DemBox {
double min_lon; double min_lon;
double max_lon; double max_lon;
@ -154,7 +165,7 @@ struct Vector3_single {
/*********************************************** FEKO仿真参数 ********************************************************************/ /*********************************************** FEKO仿真参数 ********************************************************************/
struct SatellitePos { extern "C" struct SatellitePos {
double time; double time;
double Px ; double Px ;
double Py ; double Py ;
@ -165,7 +176,7 @@ struct SatellitePos {
}; };
struct SatelliteAntPos { extern "C" struct SatelliteAntPos {
double time; // 0 double time; // 0
double Px; double Px;
double Py; double Py;
@ -188,7 +199,7 @@ struct SatelliteAntPos {
}; };
struct PatternImageDesc { extern "C" struct PatternImageDesc {
long phinum; long phinum;
long thetanum; long thetanum;
double startTheta; double startTheta;
@ -307,7 +318,7 @@ inline void delArrPtr(void* p)
} }
delete[] p; delete[] p;
p = nullptr; p = nullptr;
} };
inline void delPointer(void* p) inline void delPointer(void* p)
{ {
@ -316,28 +327,34 @@ inline void delPointer(void* p)
} }
delete p; delete p;
p = nullptr; p = nullptr;
} };
inline void PrintTime() { inline void PrintTime() {
time_t current_time; time_t current_time;
time(&current_time); time(&current_time);
printf("Current timestamp in seconds: %ld\n", (long)current_time); printf("Current timestamp in seconds: %ld\n", (long)current_time);
} };
/** 计算分块 ******************************************************************/ /** 计算分块 ******************************************************************/
inline long getBlockRows(long sizeMB, long cols,long sizeMeta,long maxRows) { inline long getBlockRows(long sizeMB, long cols, long sizeMeta, long maxRows) {
long rownum= (round(Memory1MB * 1.0 / sizeMeta / cols * sizeMB) + cols - 1); long rownum = (round(Memory1MB * 1.0 / sizeMeta / cols * sizeMB) + cols - 1);
rownum = rownum < 0 ? 1 : rownum; rownum = rownum < 0 ? 1 : rownum;
rownum =rownum < maxRows ? rownum : maxRows; rownum = rownum < maxRows ? rownum : maxRows;
return rownum; return rownum;
} };
inline long nextpow2(long n) { inline long nextpow2(long n) {
long en = ceil(log2(n)); long en = ceil(log2(n));
return pow(2,en); return pow(2, en);
} };
inline void releaseVoidArray(void* a)
{
free(a);
a = NULL;
};

View File

@ -1,5 +1,5 @@
#include "stdafx.h" #include "stdafx.h"
#define EIGEN_USE_BLAS //#define EIGEN_USE_BLAS
#define EIGEN_VECTORIZE_SSE4_2 #define EIGEN_VECTORIZE_SSE4_2
//#include <mkl.h> //#include <mkl.h>
@ -38,7 +38,10 @@
#include <xmmintrin.h> // 包含SSE指令集头文件 #include <xmmintrin.h> // 包含SSE指令集头文件
#include <emmintrin.h> // 包含SSE2指令集头文件 #include <emmintrin.h> // 包含SSE2指令集头文件
#include <omp.h> // 包含OpenMP头文件 #include <omp.h> // 包含OpenMP头文件
#include <iostream>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/conversion.hpp>
QString longDoubleToQStringScientific(long double value) { QString longDoubleToQStringScientific(long double value) {
std::ostringstream stream; std::ostringstream stream;
@ -679,4 +682,94 @@ void initializeMatrixWithSSE2(Eigen::MatrixXf& mat, const float* data, long rowc
} }
} }
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 };
}

View File

@ -31,7 +31,8 @@
#include <QDebug> #include <QDebug>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <QDatetime>
#include <boost/cstdint.hpp>
///////////////////////////////////// 基础数学函数 ///////////////////////////////////////////////////////////// ///////////////////////////////////// 基础数学函数 /////////////////////////////////////////////////////////////
@ -101,7 +102,7 @@ Eigen::Matrix3d BASECONSTVARIABLEAPI rotationMatrix(const Eigen::Vector3d& axis
long double BASECONSTVARIABLEAPI convertToMilliseconds(const std::string& dateTimeStr); long double BASECONSTVARIABLEAPI convertToMilliseconds(const std::string& dateTimeStr);
QDateTime BASECONSTVARIABLEAPI parseCustomDateTime(const QString& dateTimeStr);
/// <summary> /// <summary>
/// list 应该是按照从小到大的顺序排好 /// list 应该是按照从小到大的顺序排好
/// </summary> /// </summary>
@ -129,27 +130,54 @@ Eigen::VectorXd BASECONSTVARIABLEAPI linspace(double start, double stop, int nu
void initializeMatrixWithSSE2(Eigen::MatrixXd& mat, const double* data, long rowcount, long colcount); void initializeMatrixWithSSE2(Eigen::MatrixXd& mat, const double* data, long rowcount, long colcount);
void initializeMatrixWithSSE2(Eigen::MatrixXf& mat, const float* 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<typename T> template<typename T>
inline void memsetInitArray(std::shared_ptr<T> ptr, long arrcount,T ti) { inline void memsetInitArray(std::shared_ptr<T> ptr, long arrcount, T ti) {
for (long i = 0; i < arrcount; i++) { for (long i = 0; i < arrcount; i++) {
ptr.get()[i] = ti; ptr.get()[i] = ti;
} }
} };
template<typename T> template<typename T>
inline void memcpyArray(std::shared_ptr<T> srct, std::shared_ptr<T> dest, long arrcount) { inline void memcpyArray(std::shared_ptr<T> srct, std::shared_ptr<T> dest, long arrcount) {
for (long i = 0; i < arrcount; i++) { for (long i = 0; i < arrcount; i++) {
dest.get()[i] = srct.get()[i]; dest.get()[i] = srct.get()[i];
} }
} };
template<typename T> template<typename T>
inline void minValueInArr(T* ptr, long arrcount, T& minvalue) { inline void minValueInArr(T* ptr, long arrcount, T& minvalue) {
if (arrcount == 0)return; if (arrcount == 0)return;
@ -159,7 +187,7 @@ inline void minValueInArr(T* ptr, long arrcount, T& minvalue) {
minvalue = ptr[i]; minvalue = ptr[i];
} }
} }
} };
template<typename T> template<typename T>
inline void maxValueInArr(T* ptr, long arrcount, T& maxvalue) { inline void maxValueInArr(T* ptr, long arrcount, T& maxvalue) {
@ -172,7 +200,7 @@ inline void maxValueInArr(T* ptr, long arrcount, T& maxvalue) {
maxvalue = ptr[i]; maxvalue = ptr[i];
} }
} }
} };
@ -182,7 +210,7 @@ inline void maxValueInArr(T* ptr, long arrcount, T& maxvalue) {
template<typename T> template<typename T>
inline T complexAbs(std::complex<T> ccdata) { inline T complexAbs(std::complex<T> ccdata) {
return T(sqrt(pow(ccdata.real(), 2) + pow(ccdata.imag(), 2))); return T(sqrt(pow(ccdata.real(), 2) + pow(ccdata.imag(), 2)));
} };
template<typename T> template<typename T>
inline void complex2dB(std::complex<T>* ccdata, T* outdata, long long count) { inline void complex2dB(std::complex<T>* ccdata, T* outdata, long long count) {
@ -191,7 +219,7 @@ inline void complex2dB(std::complex<T>* ccdata, T* outdata, long long count) {
outdata[i] = 20 * log10(complexAbs(ccdata[i])); outdata[i] = 20 * log10(complexAbs(ccdata[i]));
} }
} };

View File

@ -234,6 +234,7 @@ ErrorCode EchoL0Dataset::Open(QString folder, QString filename)
{ {
return ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR; return ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR;
} }
return ErrorCode::SUCCESS;
} }
QString EchoL0Dataset::getxmlName() QString EchoL0Dataset::getxmlName()
@ -511,6 +512,19 @@ ErrorCode EchoL0Dataset::loadFromXml() {
return ErrorCode::SUCCESS; return ErrorCode::SUCCESS;
} }
std::shared_ptr<SatelliteAntPos> EchoL0Dataset::getAntPosVelc()
{
omp_lock_t lock;
omp_init_lock(&lock);
omp_set_lock(&lock);
long prfcount = this->PluseCount;
std::shared_ptr<SatelliteAntPos> antposlist= SatelliteAntPosOperator::readAntPosFile(this->GPSPointFilePath, prfcount);
omp_unset_lock(&lock); //
omp_destroy_lock(&lock); //
return antposlist;
}
std::shared_ptr<double> EchoL0Dataset::getAntPos() std::shared_ptr<double> EchoL0Dataset::getAntPos()
{ {
omp_lock_t lock; omp_lock_t lock;
@ -592,6 +606,66 @@ std::shared_ptr<std::complex<double>> EchoL0Dataset::getEchoArr(long startPRF, l
return temp; return temp;
} }
std::vector<std::complex<double>> EchoL0Dataset::getEchoArrVector(long startPRF, long& PRFLen) {
if (!(startPRF < this->PluseCount)) {
qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_PRFIDXOUTRANGE)) << startPRF << " " << this->PluseCount;
return std::vector<std::complex<double>>(0);
}
else {}
omp_lock_t lock;
omp_init_lock(&lock);
omp_set_lock(&lock);
std::shared_ptr<GDALDataset> rasterDataset = OpenDataset(this->echoDataFilePath, GDALAccess::GA_ReadOnly);
GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType();
GDALRasterBand* poBand = rasterDataset->GetRasterBand(1);
if (NULL == poBand || nullptr == poBand) {
omp_lock_t lock;
omp_init_lock(&lock);
omp_set_lock(&lock);
qDebug() << QString::fromStdString(errorCode2errInfo(ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR));
return std::vector<std::complex<double>>(0);
}
else {}
long width = rasterDataset->GetRasterXSize();
long height = rasterDataset->GetRasterYSize();
long band_num = rasterDataset->GetRasterCount();
PRFLen = (PRFLen + startPRF) < height ? PRFLen : height - startPRF;
std::vector<std::complex<double>> 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<std::complex<double>> temp(new std::complex<double>[PRFLen * width], delArrPtr);
poBand->RasterIO(GF_Read, 0, startPRF, width, PRFLen, temp.get(), width, PRFLen, GDT_CFloat64, 0, 0);
GDALFlushCache((GDALDatasetH)rasterDataset.get());
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<std::complex<double>> EchoL0Dataset::getEchoArr() std::shared_ptr<std::complex<double>> EchoL0Dataset::getEchoArr()
{ {
return this->getEchoArr(0,this->PluseCount); return this->getEchoArr(0,this->PluseCount);
@ -674,8 +748,10 @@ ErrorCode EchoL0Dataset::saveEchoArr(std::shared_ptr<std::complex<double>> echoP
} }
GDALClose(rasterDataset); GDALClose(rasterDataset);
rasterDataset = nullptr; rasterDataset = nullptr;
GDALDestroy();
omp_unset_lock(&lock); // omp_unset_lock(&lock); //
omp_destroy_lock(&lock); // omp_destroy_lock(&lock); //
return ErrorCode::SUCCESS; return ErrorCode::SUCCESS;
} }

View File

@ -209,9 +209,11 @@ public: //
public: public:
// 读取文件 // 读取文件
std::shared_ptr< SatelliteAntPos> getAntPosVelc();
std::shared_ptr<double> getAntPos(); std::shared_ptr<double> getAntPos();
std::shared_ptr<std::complex<double>> getEchoArr(long startPRF, long& PRFLen); std::shared_ptr<std::complex<double>> getEchoArr(long startPRF, long& PRFLen);
std::shared_ptr<std::complex<double>> getEchoArr(); std::shared_ptr<std::complex<double>> getEchoArr();
std::vector<std::complex<double>> getEchoArrVector(long startPRF, long& PRFLen);
//保存文件 //保存文件
ErrorCode saveAntPos(std::shared_ptr<double> ptr); // 注意这个方法很危险,请写入前检查数据是否正确 ErrorCode saveAntPos(std::shared_ptr<double> ptr); // 注意这个方法很危险,请写入前检查数据是否正确
ErrorCode saveEchoArr(std::shared_ptr<std::complex<double>> echoPtr, long startPRF, long PRFLen); ErrorCode saveEchoArr(std::shared_ptr<std::complex<double>> echoPtr, long startPRF, long PRFLen);

View File

@ -93,7 +93,8 @@ QString getFileNameFromPath(const QString& path)
QString getFileNameWidthoutExtend(QString path) QString getFileNameWidthoutExtend(QString path)
{ {
QFileInfo fileInfo(path); QFileInfo fileInfo(path);
QString fileNameWithoutExtension = fileInfo.baseName(); // 获取无后缀文件名 QString fileNameWithoutExtension = fileInfo.completeBaseName(); // 获取无后缀文件名
qDebug() << u8"File name without extension: " << fileNameWithoutExtension;
return fileNameWithoutExtension; return fileNameWithoutExtension;
} }

View File

@ -29,7 +29,7 @@ unsigned long BASECONSTVARIABLEAPI convertToULong(const QString& input);
/// <param name="folderpath"></param> /// <param name="folderpath"></param>
/// <param name="FilenameExtension"></param> /// <param name="FilenameExtension"></param>
/// <returns></returns> /// <returns></returns>
std::vector<QString> BASECONSTVARIABLEAPI getFilelist(const QString& folderpath, const QString& FilenameExtension = ".*",int (*logfun)(QString logtext,int value)=nullptr); std::vector<QString> BASECONSTVARIABLEAPI getFilelist(const QString& folderpath, const QString& FilenameExtension = ".*", int (*logfun)(QString logtext, int value) = nullptr);
QString BASECONSTVARIABLEAPI getParantFolderNameFromPath(const QString& path); QString BASECONSTVARIABLEAPI getParantFolderNameFromPath(const QString& path);
@ -41,11 +41,11 @@ QString BASECONSTVARIABLEAPI getFileExtension(QString path);
int BASECONSTVARIABLEAPI write_binfile(char* filepath, char* data, size_t data_len); int BASECONSTVARIABLEAPI write_binfile(char* filepath, char* data, size_t data_len);
char* read_textfile(char* text_path, int* length); char* read_textfile(char* text_path, int* length);
bool BASECONSTVARIABLEAPI exists_test(const QString& name); bool BASECONSTVARIABLEAPI exists_test(const QString& name);
size_t BASECONSTVARIABLEAPI fsize(FILE* fp); size_t BASECONSTVARIABLEAPI fsize(FILE* fp);
QString BASECONSTVARIABLEAPI getParantFromPath(const QString& path); QString BASECONSTVARIABLEAPI getParantFromPath(const QString& path);
void BASECONSTVARIABLEAPI copyFile(const QString& sourcePath, const QString& destinationPath); void BASECONSTVARIABLEAPI copyFile(const QString& sourcePath, const QString& destinationPath);

View File

@ -18,7 +18,9 @@
#include <fstream> #include <fstream>
#include <proj.h> #include <proj.h>
#include "GeoOperator.h" #include "GeoOperator.h"
#include <ogr_spatialref.h> // OGRSpatialReference 用于空间参考转换
#include <gdal_alg.h> // 用于 GDALWarp 操作
#include <ogr_spatialref.h>
Landpoint operator +(const Landpoint& p1, const Landpoint& p2) Landpoint operator +(const Landpoint& p1, const Landpoint& p2)
@ -135,6 +137,44 @@ Landpoint XYZ2LLA(const Landpoint& XYZ) {
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 getAngle(const Landpoint& a, const Landpoint& b)
{ {
@ -408,3 +448,53 @@ double getlocalIncAngle(Vector3D& satepoint, Vector3D& landpoint, Vector3D& slop
return angle; 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;
}

View File

@ -30,6 +30,7 @@ Eigen::MatrixXd BASECONSTVARIABLEAPI LLA2XYZ(Eigen::MatrixXd landpoint);
/// <returns>经纬度--degree</returns> /// <returns>经纬度--degree</returns>
Landpoint BASECONSTVARIABLEAPI XYZ2LLA(const Landpoint& XYZ); 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);
@ -123,4 +124,24 @@ CartesianCoordinates BASECONSTVARIABLEAPI sphericalToCartesian(const Spheric
double BASECONSTVARIABLEAPI getlocalIncAngle(Vector3D& satepoint, Vector3D& landpoint, Vector3D& slopeVector); 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 #endif

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,9 @@
#include <QObject> #include <QObject>
#include <QList> #include <QList>
#include <functional> #include <functional>
#include "ShowProessAbstract.h"
enum ProjectStripDelta { enum ProjectStripDelta {
Strip_6, // 6度带 Strip_6, // 6度带
@ -76,13 +79,6 @@ enum GDALREADARRCOPYMETHOD {
class BASECONSTVARIABLEAPI ShowProessAbstract {
public:
virtual void showProcess(double precent, QString tip);
virtual void showToolInfo(QString tip);
};
@ -93,7 +89,7 @@ public:
/// \param long 经度 /// \param long 经度
/// \param lat 纬度 /// \param lat 纬度
/// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误 /// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误
long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat(double long, double lat, ProjectStripDelta stripState); 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_inStrip3(double lon, double lat);
@ -139,10 +135,10 @@ GDALDataType BASECONSTVARIABLEAPI getGDALDataType(QString fileptah);
struct RasterExtend { struct RasterExtend {
double min_x; //纬度 double min_x;
double min_y;//经度 double min_y;
double max_x;//纬度 double max_x;
double max_y;//经度 double max_y;
}; };
@ -178,8 +174,6 @@ public: // 方法
virtual void saveImage(std::shared_ptr<float>, int start_row, int start_col, int rowcount, int colcount, int band_ids); virtual void saveImage(std::shared_ptr<float>, int start_row, int start_col, int rowcount, int colcount, int band_ids);
virtual void saveImage(std::shared_ptr<int>, int start_row, int start_col, int rowcount, int colcount, int band_ids); virtual void saveImage(std::shared_ptr<int>, int start_row, int start_col, int rowcount, int colcount, int band_ids);
virtual void saveImage(); virtual void saveImage();
virtual void setNoDataValue(double nodatavalue, int band_ids); virtual void setNoDataValue(double nodatavalue, int band_ids);
virtual void setNoDataValuei(int nodatavalue, int band_ids); virtual void setNoDataValuei(int nodatavalue, int band_ids);
@ -201,6 +195,10 @@ public: // 方法
virtual RasterExtend getExtend(); virtual RasterExtend getExtend();
public: public:
QString img_path; // 图像文件 QString img_path; // 图像文件
int height; // 高 int height; // 高
@ -234,18 +232,22 @@ public: // 方法
Eigen::MatrixXcd getDataComplex(int start_row, int start_col, int rows_count, int cols_count, int band_ids); Eigen::MatrixXcd getDataComplex(int start_row, int start_col, int rows_count, int cols_count, int band_ids);
std::shared_ptr<std::complex<double>> getDataComplexSharePtr(int start_row, int start_col, int rows_count, int cols_count, int band_ids); std::shared_ptr<std::complex<double>> getDataComplexSharePtr(int start_row, int start_col, int rows_count, int cols_count, int band_ids);
void saveImage() override; void saveComplexImage();//override;
void savePreViewImage(); void savePreViewImage();
public: public:
Eigen::MatrixXcd data; 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 CreategdalImageDouble(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 CreategdalImageFloat(QString& img_path, int height, int width, int band_num, 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 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); 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 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 CreategdalImageComplexNoProj(const QString& img_path, int height, int width, int band_num, bool overwrite = true);
@ -314,8 +316,29 @@ void BASECONSTVARIABLEAPI testOutDataArr(QString filename, long* data, long row
void BASECONSTVARIABLEAPI CreateSARIntensityByLookTable(QString IntensityRasterPath, QString LookTableRasterPath, QString SARIntensityPath, long min_rid, long max_rid, long min_cid, long max_cid, std::function<void(long, long)> processBarShow = {}); void BASECONSTVARIABLEAPI CreateSARIntensityByLookTable(QString IntensityRasterPath, QString LookTableRasterPath, QString SARIntensityPath, long min_rid, long max_rid, long min_cid, long max_cid, std::function<void(long, long)> 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<typename T> template<typename T>
inline std::shared_ptr<T> readDataArr(gdalImage& imgds, long start_row, long start_col, long& rows_count, long& cols_count, int band_ids, GDALREADARRCOPYMETHOD method) inline std::shared_ptr<T> readDataArr(gdalImage& imgds, long start_row, long start_col, long& rows_count, long& cols_count, int band_ids, GDALREADARRCOPYMETHOD method)
{ {
@ -513,7 +536,7 @@ inline std::shared_ptr<T> readDataArr(gdalImage& imgds, long start_row, long sta
omp_destroy_lock(&lock); // 劫伙拷斤拷 omp_destroy_lock(&lock); // 劫伙拷斤拷
GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH
return result; return result;
} };
template<typename T> template<typename T>
inline std::shared_ptr<T> readDataArrComplex(gdalImageComplex& imgds, long start_row, long start_col, long& rows_count, long& cols_count, int band_ids, GDALREADARRCOPYMETHOD method) inline std::shared_ptr<T> readDataArrComplex(gdalImageComplex& imgds, long start_row, long start_col, long& rows_count, long& cols_count, int band_ids, GDALREADARRCOPYMETHOD method)
@ -586,7 +609,7 @@ inline std::shared_ptr<T> readDataArrComplex(gdalImageComplex& imgds, long start
omp_destroy_lock(&lock); // 劫伙拷斤拷 omp_destroy_lock(&lock); // 劫伙拷斤拷
GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH
return result; return result;
} };

View File

@ -0,0 +1,488 @@
#include "stdafx.h"
#include "ImageOperatorBase.h"
#include "BaseTool.h"
#include "GeoOperator.h"
#include <Eigen/Core>
#include <Eigen/Dense>
#include <omp.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <gdal.h>
#include <gdal_utils.h>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <proj.h>
#include <string.h>
#include <memory>
#include <iostream>
#include "FileOperator.h"
#include <opencv2/opencv.hpp>
#include <QMessageBox>
#include <QDir>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <QProgressDialog>
#include <gdal_priv.h>
#include <ogr_spatialref.h> // OGRSpatialReference 用于空间参考转换
#include <gdal_alg.h> // 用于 GDALWarp 操作
ErrorCode MergeRasterProcess(QVector<QString> 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<gdalImage> 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<RasterExtend> 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<gdalImage> imgdslist, gdalImage resultimg, gdalImage maskimg, ShowProessAbstract* dia)
{
omp_set_num_threads(Paral_num_thread);
// 逐点合并计算
QVector<RasterExtend> 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<QString> 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<double>::max();
double minY = std::numeric_limits<double>::max();
double maxX = std::numeric_limits<double>::lowest();
double maxY = std::numeric_limits<double>::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<int>(std::ceil((maxX - minX) / pixelWidth));
nYSize = static_cast<int>(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<float>::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<int>(std::round((adfThisTransform[0] - minX) / pixelWidth));
int dstYOffset = static_cast<int>(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);
}

View File

@ -15,6 +15,8 @@
#include <QTextCodec> #include <QTextCodec>
#include <iostream> #include <iostream>
#include <QFile> #include <QFile>
#include "SARSimulationImageL1.h"
#include <QMessageBox>
namespace RasterToolBase { namespace RasterToolBase {
long getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState) long getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState)
@ -261,8 +263,14 @@ namespace RasterToolBase {
} else if(oSRS.IsProjected()) { } else if(oSRS.IsProjected()) {
return CoordinateSystemType::ProjectCoordinateSystem; return CoordinateSystemType::ProjectCoordinateSystem;
} }
else {
return CoordinateSystemType::UNKNOW;
}
} else { } else {
return CoordinateSystemType::UNKNOW; return CoordinateSystemType::UNKNOW;
} }
} }
} // namespace RasterToolBase }; // namespace RasterToolBase

View File

@ -12,40 +12,42 @@
#include "BaseConstVariable.h" #include "BaseConstVariable.h"
#include "gdal_priv.h" #include "gdal_priv.h"
#include <memory> #include <memory>
#include "LogInfoCls.h"
namespace RasterToolBase { namespace RasterToolBase {
static bool GDALAllRegisterEnable=false; static bool GDALAllRegisterEnable = false;
enum ProjectStripDelta{ enum ProjectStripDelta {
Strip_6, // 6度带 Strip_6, // 6度带
Strip_3 Strip_3
}; };
enum CoordinateSystemType{ // 坐标系类型 enum CoordinateSystemType { // 坐标系类型
GeoCoordinateSystem, GeoCoordinateSystem,
ProjectCoordinateSystem, ProjectCoordinateSystem,
UNKNOW UNKNOW
}; };
struct PointRaster{ // 影像坐标点 struct PointRaster { // 影像坐标点
double x; double x;
double y; double y;
double z; double z;
}; };
struct PointXYZ{ struct PointXYZ {
double x,y,z; double x, y, z;
}; };
struct PointGeo{ struct PointGeo {
double lon,lat,ati; double lon, lat, ati;
}; };
struct PointImage{ struct PointImage {
double pixel_x,pixel_y; double pixel_x, pixel_y;
}; };
/// 根据经纬度获取 /// 根据经纬度获取
@ -56,14 +58,14 @@ namespace RasterToolBase {
/// \param lat 纬度 /// \param lat 纬度
/// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误 /// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误
long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat(double long, double lat, long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat(double long, double lat,
ProjectStripDelta stripState = ProjectStripDelta::Strip_3); ProjectStripDelta stripState = ProjectStripDelta::Strip_3);
long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat); long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat);
long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat); long BASECONSTVARIABLEAPI getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat);
QString BASECONSTVARIABLEAPI GetProjectionNameFromEPSG(long epsgCode) ; QString BASECONSTVARIABLEAPI GetProjectionNameFromEPSG(long epsgCode);
long BASECONSTVARIABLEAPI GetEPSGFromRasterFile(QString filepath); long BASECONSTVARIABLEAPI GetEPSGFromRasterFile(QString filepath);
@ -72,9 +74,23 @@ namespace RasterToolBase {
CoordinateSystemType BASECONSTVARIABLEAPI getCoordinateSystemTypeByEPSGCode(long EPSGCODE); CoordinateSystemType BASECONSTVARIABLEAPI getCoordinateSystemTypeByEPSGCode(long EPSGCODE);
};// namespace RasterProjectConvertor
// 遥感类常用数据
} // namespace RasterProjectConvertor
#endif // LAMPCAE_RASTERTOOLBASE_H #endif // LAMPCAE_RASTERTOOLBASE_H

View File

@ -106,7 +106,7 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
this->saveToXml(); this->saveToXml();
} }
if (this->Rasterlevel!=RasterL2||QFile(this->GPSPointFilePath).exists() == false) { if (this->Rasterlevel==RasterL2||QFile(this->GPSPointFilePath).exists() == false) {
// 创建新文件 // 创建新文件
omp_lock_t lock; omp_lock_t lock;
omp_init_lock(&lock); omp_init_lock(&lock);
@ -122,7 +122,7 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
omp_destroy_lock(&lock); omp_destroy_lock(&lock);
} }
if (this->Rasterlevel == RasterLevel::RasterSLC || QFile(this->ImageRasterPath).exists() == false) { else if (this->Rasterlevel == RasterLevel::RasterSLC || QFile(this->ImageRasterPath).exists() == false) {
// 创建新文件 // 创建新文件
omp_lock_t lock; omp_lock_t lock;
@ -140,7 +140,7 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
} }
if (this->Rasterlevel != RasterLevel::RasterSLC || QFile(this->ImageRasterPath).exists() == false) { else if (this->Rasterlevel == RasterLevel::RasterL1B || QFile(this->ImageRasterPath).exists() == false) {
// 创建新文件 // 创建新文件
omp_lock_t lock; omp_lock_t lock;
@ -150,11 +150,11 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI");
std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->ImageRasterPath.toUtf8().constData(), colCount, rowCount, 1, GDT_CFloat32, NULL)); std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->GPSPointFilePath.toUtf8().constData(), 19, rowCount, 1, GDT_Float64, NULL));
GDALFlushCache((GDALDatasetH)poDstDS.get()); GDALFlushCache((GDALDatasetH)poDstDS.get());
poDstDS.reset(); poDstDS.reset();
omp_unset_lock(&lock); // omp_unset_lock(&lock);
omp_destroy_lock(&lock); // omp_destroy_lock(&lock);
} }
@ -203,7 +203,7 @@ ErrorCode SARSimulationImageL1Dataset::Open(QString xmlPath)
QFileInfo fileInfo(xmlPath); QFileInfo fileInfo(xmlPath);
QString fileName = fileInfo.fileName(); // 获取文件名 QString fileName = fileInfo.fileName(); // 获取文件名
QString fileSuffix = fileInfo.suffix(); // 获取后缀名 QString fileSuffix = fileInfo.suffix(); // 获取后缀名
QString fileNameWithoutSuffix = fileInfo.baseName(); // »ñÈ¡²»´øºó׺µÄÎļþÃû QString fileNameWithoutSuffix = fileInfo.completeBaseName(); // »ñÈ¡²»´øºó׺µÄÎļþÃû
QString directoryPath = fileInfo.path(); // 获取文件夹路径 QString directoryPath = fileInfo.path(); // 获取文件夹路径
if (fileSuffix.toLower() == "xml" || fileSuffix.toLower() == ".xml") { if (fileSuffix.toLower() == "xml" || fileSuffix.toLower() == ".xml") {
return this->Open(directoryPath, fileNameWithoutSuffix); return this->Open(directoryPath, fileNameWithoutSuffix);
@ -246,12 +246,13 @@ void SARSimulationImageL1Dataset::saveToXml()
xmlWriter.writeTextElement("RowCount", QString::number(this->rowCount)); xmlWriter.writeTextElement("RowCount", QString::number(this->rowCount));
xmlWriter.writeTextElement("ColCount", QString::number(this->colCount)); xmlWriter.writeTextElement("ColCount", QString::number(this->colCount));
xmlWriter.writeTextElement("Rnear", QString::number(this->Rnear)); xmlWriter.writeTextElement("Rnear", QString::number(this->Rnear, 'e', 18));
xmlWriter.writeTextElement("Rfar", QString::number(this->Rfar)); xmlWriter.writeTextElement("Rfar", QString::number(this->Rfar, 'e', 18));
xmlWriter.writeTextElement("Rref", QString::number(this->Rref)); xmlWriter.writeTextElement("Rref", QString::number(this->Rref, 'e', 18));
xmlWriter.writeTextElement("CenterFreq", QString::number(this->centerFreq)); xmlWriter.writeTextElement("CenterFreq", QString::number(this->centerFreq, 'e', 18));
xmlWriter.writeTextElement("Fs", QString::number(this->Fs)); xmlWriter.writeTextElement("Fs", QString::number(this->Fs, 'e', 18));
xmlWriter.writeTextElement("CenterAngle", QString::number(this->CenterAngle)); xmlWriter.writeTextElement("PRF", QString::number(this->prf, 'e', 18));
xmlWriter.writeTextElement("CenterAngle", QString::number(this->CenterAngle, 'e', 18));
xmlWriter.writeTextElement("LookSide", this->LookSide); xmlWriter.writeTextElement("LookSide", this->LookSide);
// 保存sateantpos // 保存sateantpos
@ -259,60 +260,60 @@ void SARSimulationImageL1Dataset::saveToXml()
for (long i = 0; i < this->sateposes.count(); i++) { for (long i = 0; i < this->sateposes.count(); i++) {
xmlWriter.writeStartElement("AntPosParam"); xmlWriter.writeStartElement("AntPosParam");
xmlWriter.writeTextElement("time", QString::number(this->sateposes[i].time)); // time xmlWriter.writeTextElement("time", QString::number(this->sateposes[i].time, 'e', 18)); // time
xmlWriter.writeTextElement("Px", QString::number(this->sateposes[i].Px)); // Px xmlWriter.writeTextElement("Px", QString::number(this->sateposes[i].Px, 'e', 18)); // Px
xmlWriter.writeTextElement("Py", QString::number(this->sateposes[i].Py)); // Py xmlWriter.writeTextElement("Py", QString::number(this->sateposes[i].Py, 'e', 18)); // Py
xmlWriter.writeTextElement("Pz", QString::number(this->sateposes[i].Pz)); // Pz xmlWriter.writeTextElement("Pz", QString::number(this->sateposes[i].Pz, 'e', 18)); // Pz
xmlWriter.writeTextElement("Vx", QString::number(this->sateposes[i].Vx)); // Vx xmlWriter.writeTextElement("Vx", QString::number(this->sateposes[i].Vx, 'e', 18)); // Vx
xmlWriter.writeTextElement("Vy", QString::number(this->sateposes[i].Vy)); // Vy xmlWriter.writeTextElement("Vy", QString::number(this->sateposes[i].Vy, 'e', 18)); // Vy
xmlWriter.writeTextElement("Vz", QString::number(this->sateposes[i].Vz)); // Vz xmlWriter.writeTextElement("Vz", QString::number(this->sateposes[i].Vz, 'e', 18)); // Vz
xmlWriter.writeTextElement("AntDirectX", QString::number(this->sateposes[i].AntDirectX)); // AntDirectX xmlWriter.writeTextElement("AntDirectX", QString::number(this->sateposes[i].AntDirectX, 'e', 18)); // AntDirectX
xmlWriter.writeTextElement("AntDirectY", QString::number(this->sateposes[i].AntDirectY)); // AntDirectY xmlWriter.writeTextElement("AntDirectY", QString::number(this->sateposes[i].AntDirectY, 'e', 18)); // AntDirectY
xmlWriter.writeTextElement("AntDirectZ", QString::number(this->sateposes[i].AntDirectZ)); // AntDirectZ xmlWriter.writeTextElement("AntDirectZ", QString::number(this->sateposes[i].AntDirectZ, 'e', 18)); // AntDirectZ
xmlWriter.writeTextElement("AVx", QString::number(this->sateposes[i].AVx)); // AVx xmlWriter.writeTextElement("AVx", QString::number(this->sateposes[i].AVx, 'e', 18)); // AVx
xmlWriter.writeTextElement("AVy", QString::number(this->sateposes[i].AVy)); // AVy xmlWriter.writeTextElement("AVy", QString::number(this->sateposes[i].AVy, 'e', 18)); // AVy
xmlWriter.writeTextElement("AVz", QString::number(this->sateposes[i].AVz)); // AVz xmlWriter.writeTextElement("AVz", QString::number(this->sateposes[i].AVz, 'e', 18)); // AVz
xmlWriter.writeTextElement("lon", QString::number(this->sateposes[i].lon)); // lon xmlWriter.writeTextElement("lon", QString::number(this->sateposes[i].lon, 'e', 18)); // lon
xmlWriter.writeTextElement("lat", QString::number(this->sateposes[i].lat)); // lat xmlWriter.writeTextElement("lat", QString::number(this->sateposes[i].lat, 'e', 18)); // lat
xmlWriter.writeTextElement("ati", QString::number(this->sateposes[i].ati)); // ati xmlWriter.writeTextElement("ati", QString::number(this->sateposes[i].ati, 'e', 18)); // ati
xmlWriter.writeEndElement(); // 结束 <AntPosParam> xmlWriter.writeEndElement(); // 结束 <AntPosParam>
} }
xmlWriter.writeTextElement("ImageStartTime", QString::number(this->startImageTime)); xmlWriter.writeTextElement("ImageStartTime", QString::number(this->startImageTime, 'e', 18));
xmlWriter.writeTextElement("ImageEndTime", QString::number(this->EndImageTime)); xmlWriter.writeTextElement("ImageEndTime", QString::number(this->EndImageTime, 'e', 18));
xmlWriter.writeTextElement("incidenceAngleNearRange", QString::number(this->incidenceAngleNearRange)); xmlWriter.writeTextElement("incidenceAngleNearRange", QString::number(this->incidenceAngleNearRange, 'e', 18));
xmlWriter.writeTextElement("incidenceAngleFarRange", QString::number(this->incidenceAngleFarRange)); xmlWriter.writeTextElement("incidenceAngleFarRange", QString::number(this->incidenceAngleFarRange, 'e', 18));
xmlWriter.writeTextElement("TotalProcessedAzimuthBandWidth", QString::number(this->TotalProcessedAzimuthBandWidth)); xmlWriter.writeTextElement("TotalProcessedAzimuthBandWidth", QString::number(this->TotalProcessedAzimuthBandWidth, 'e', 18));
xmlWriter.writeTextElement("DopplerParametersReferenceTime", QString::number(this->DopplerParametersReferenceTime)); xmlWriter.writeTextElement("DopplerParametersReferenceTime", QString::number(this->DopplerParametersReferenceTime, 'e', 18));
xmlWriter.writeStartElement("DopplerCentroidCoefficients"); xmlWriter.writeStartElement("DopplerCentroidCoefficients");
xmlWriter.writeTextElement("d0", QString::number(this->d0)); xmlWriter.writeTextElement("d0", QString::number(this->d0, 'e', 18));
xmlWriter.writeTextElement("d1", QString::number(this->d1)); xmlWriter.writeTextElement("d1", QString::number(this->d1, 'e', 18));
xmlWriter.writeTextElement("d2", QString::number(this->d2)); xmlWriter.writeTextElement("d2", QString::number(this->d2, 'e', 18));
xmlWriter.writeTextElement("d3", QString::number(this->d3)); xmlWriter.writeTextElement("d3", QString::number(this->d3, 'e', 18));
xmlWriter.writeTextElement("d4", QString::number(this->d4)); xmlWriter.writeTextElement("d4", QString::number(this->d4, 'e', 18));
xmlWriter.writeEndElement(); // DopplerCentroidCoefficients xmlWriter.writeEndElement(); // DopplerCentroidCoefficients
xmlWriter.writeStartElement("DopplerRateValuesCoefficients"); xmlWriter.writeStartElement("DopplerRateValuesCoefficients");
xmlWriter.writeTextElement("r0", QString::number(this->r0)); xmlWriter.writeTextElement("r0", QString::number(this->r0, 'e', 18));
xmlWriter.writeTextElement("r1", QString::number(this->r1)); xmlWriter.writeTextElement("r1", QString::number(this->r1, 'e', 18));
xmlWriter.writeTextElement("r2", QString::number(this->r2)); xmlWriter.writeTextElement("r2", QString::number(this->r2, 'e', 18));
xmlWriter.writeTextElement("r3", QString::number(this->r3)); xmlWriter.writeTextElement("r3", QString::number(this->r3, 'e', 18));
xmlWriter.writeTextElement("r4", QString::number(this->r4)); xmlWriter.writeTextElement("r4", QString::number(this->r4, 'e', 18));
xmlWriter.writeEndElement(); // DopplerRateValuesCoefficients xmlWriter.writeEndElement(); // DopplerRateValuesCoefficients
xmlWriter.writeTextElement("latitude_center", QString::number(this->latitude_center)); xmlWriter.writeTextElement("latitude_center", QString::number(this->latitude_center, 'e', 18));
xmlWriter.writeTextElement("longitude_center", QString::number(this->longitude_center)); xmlWriter.writeTextElement("longitude_center", QString::number(this->longitude_center, 'e', 18));
xmlWriter.writeTextElement("latitude_topLeft", QString::number(this->latitude_topLeft)); xmlWriter.writeTextElement("latitude_topLeft", QString::number(this->latitude_topLeft, 'e', 18));
xmlWriter.writeTextElement("longitude_topLeft", QString::number(this->longitude_topLeft)); xmlWriter.writeTextElement("longitude_topLeft", QString::number(this->longitude_topLeft, 'e', 18));
xmlWriter.writeTextElement("latitude_topRight", QString::number(this->latitude_topRight)); xmlWriter.writeTextElement("latitude_topRight", QString::number(this->latitude_topRight, 'e', 18));
xmlWriter.writeTextElement("longitude_topRight", QString::number(this->longitude_topRight)); xmlWriter.writeTextElement("longitude_topRight", QString::number(this->longitude_topRight, 'e', 18));
xmlWriter.writeTextElement("latitude_bottomLeft", QString::number(this->latitude_bottomLeft)); xmlWriter.writeTextElement("latitude_bottomLeft", QString::number(this->latitude_bottomLeft, 'e', 18));
xmlWriter.writeTextElement("longitude_bottomLeft", QString::number(this->longitude_bottomLeft)); xmlWriter.writeTextElement("longitude_bottomLeft", QString::number(this->longitude_bottomLeft, 'e', 18));
xmlWriter.writeTextElement("latitude_bottomRight", QString::number(this->latitude_bottomRight)); xmlWriter.writeTextElement("latitude_bottomRight", QString::number(this->latitude_bottomRight, 'e', 18));
xmlWriter.writeTextElement("longitude_bottomRight", QString::number(this->longitude_bottomRight)); xmlWriter.writeTextElement("longitude_bottomRight", QString::number(this->longitude_bottomRight, 'e', 18));
xmlWriter.writeEndElement(); // Parameters xmlWriter.writeEndElement(); // Parameters
xmlWriter.writeEndDocument(); xmlWriter.writeEndDocument();
@ -371,6 +372,9 @@ ErrorCode SARSimulationImageL1Dataset::loadFromXml()
else if (xmlReader.name() == "Fs") { else if (xmlReader.name() == "Fs") {
this->Fs = xmlReader.readElementText().toDouble(); this->Fs = xmlReader.readElementText().toDouble();
} }
else if (xmlReader.name() == "PRF") {
this->prf = xmlReader.readElementText().toDouble();
}
else if(xmlReader.name() == "ImageStartTime"){ else if(xmlReader.name() == "ImageStartTime"){
this->startImageTime = xmlReader.readElementText().toDouble(); this->startImageTime = xmlReader.readElementText().toDouble();
} }
@ -873,6 +877,7 @@ QVector<double> SARSimulationImageL1Dataset::getDopplerParams()
result[2] = d2; result[2] = d2;
result[3] = d3; result[3] = d3;
result[4] = d4; result[4] = d4;
return result; return result;
} }
@ -888,11 +893,13 @@ void SARSimulationImageL1Dataset::setDopplerParams(double id0, double id1, doubl
QVector<double> SARSimulationImageL1Dataset::getDopplerCenterCoff() QVector<double> SARSimulationImageL1Dataset::getDopplerCenterCoff()
{ {
QVector<double> result(5); QVector<double> result(5);
result[0]=r0; result[0] = r0;
result[1]=r1; result[1] = r1;
result[2]=r2; result[2] = r2;
result[3]=r3; result[3] = r3;
result[4]=r4; result[4] = r4;
return result; return result;
} }

View File

@ -143,9 +143,11 @@ public:
double getDopplerParametersReferenceTime(); double getDopplerParametersReferenceTime();
void setDopplerParametersReferenceTime(double v); void setDopplerParametersReferenceTime(double v);
// 多普勒参数
QVector<double> getDopplerParams(); QVector<double> getDopplerParams();
void setDopplerParams(double d0, double d1, double d2, double d3, double d4); void setDopplerParams(double d0, double d1, double d2, double d3, double d4);
// 多普勒中心系数
QVector<double> getDopplerCenterCoff(); QVector<double> getDopplerCenterCoff();
void setDopplerCenterCoff(double r0, double r1, double r2, double r3, double r4); void setDopplerCenterCoff(double r0, double r1, double r2, double r3, double r4);
@ -208,3 +210,9 @@ private:
}; };

View File

@ -0,0 +1,18 @@
#include "stdafx.h"
#include "ShowProessAbstract.h"
#include "BaseTool.h"
#include "GeoOperator.h"
#include "FileOperator.h"
#include <QString>
void ShowProessAbstract::showProcess(double precent, QString tip)
{
}
void ShowProessAbstract::showToolInfo(QString tip)
{
}

View File

@ -0,0 +1,146 @@
#include "stdafx.h"
#include "ImageOperatorBase.h"
#include "BaseTool.h"
#include "GeoOperator.h"
#include <Eigen/Core>
#include <Eigen/Dense>
#include <omp.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <gdal.h>
#include <gdal_utils.h>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <proj.h>
#include <string.h>
#include <memory>
#include <iostream>
#include "FileOperator.h"
#include <opencv2/opencv.hpp>
#include <QMessageBox>
#include <QDir>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <QProgressDialog>
#include <gdal_priv.h>
#include <ogr_spatialref.h> // OGRSpatialReference 用于空间参考转换
#include <gdal_alg.h> // 用于 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<double>* 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<double>(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);
}

View File

@ -0,0 +1,547 @@
#include "stdafx.h"
#include "ImageOperatorBase.h"
#include "BaseTool.h"
#include "GeoOperator.h"
#include <Eigen/Core>
#include <Eigen/Dense>
#include <omp.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <gdal.h>
#include <gdal_utils.h>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <proj.h>
#include <string.h>
#include <memory>
#include <iostream>
#include "FileOperator.h"
#include <opencv2/opencv.hpp>
#include <QMessageBox>
#include <QDir>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <QProgressDialog>
#include <gdal_priv.h>
#include <ogr_spatialref.h> // OGRSpatialReference 用于空间参考转换
#include <gdal_alg.h> // 用于 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<std::complex<double>> 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<double>* 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); // 使用Eigen的MatrixXcd
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<double>(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<double>(databuffer[i * nXSize * 2 + j * 2],
databuffer[i * nXSize * 2 + j * 2 + 1]);
}
}
delete[] databuffer;
}
return rasterData;
}
std::shared_ptr<std::complex<double>> 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<std::complex<double>> rasterData(new std::complex<double>[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<double>(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<size_t> data_idx =
((data_abs.array() - min_abs).array() / delta).array().floor().cast<size_t>();
// 初始化
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<size_t>();
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<uchar>(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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
#ifndef __SHOWPROCESSABSTRACT_H__
#define __SHOWPROCESSABSTRACT_H__
#include "BaseConstVariable.h"
#include <QString>
class BASECONSTVARIABLEAPI ShowProessAbstract {
public:
virtual void showProcess(double precent, QString tip);
virtual void showToolInfo(QString tip);
};
#endif

View File

@ -32,5 +32,10 @@ QString QToolAbstract::getToolName()
} }
void QToolAbstract::excute() void QToolAbstract::excute()
{
this->run();
}
void QToolAbstract::run()
{ {
} }

View File

@ -27,6 +27,8 @@ public slots:
public: public:
QVector<QString> toolPath; QVector<QString> toolPath;
QString toolname; QString toolname;
public:
virtual void run();
}; };
/* /*

View File

@ -27,10 +27,13 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CudaCompile Include="GPUTool\GPUDouble32.cu" />
<CudaCompile Include="GPUTool\GPUTool.cu" /> <CudaCompile Include="GPUTool\GPUTool.cu" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="GPUTool\GPUBaseLibAPI.h" /> <ClInclude Include="GPUTool\GPUBaseLibAPI.h" />
<ClInclude Include="GPUTool\GPUBaseTool.h" />
<ClInclude Include="GPUTool\GPUDouble32.cuh" />
<CudaCompile Include="GPUTool\GPUTool.cuh" /> <CudaCompile Include="GPUTool\GPUTool.cuh" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -38,6 +41,9 @@
<Project>{872ecd6f-30e3-4a1b-b17c-15e87d373ff6}</Project> <Project>{872ecd6f-30e3-4a1b-b17c-15e87d373ff6}</Project>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClCompile Include="GPUTool\GPUBaseTool.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
@ -178,7 +184,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;GPUBASELIB_API;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;GPUBASELIB_API;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp14</LanguageStandard> <LanguageStandard>stdcpp14</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C> <LanguageStandard_C>stdc11</LanguageStandard_C>
@ -193,6 +199,9 @@
<CudaCompile> <CudaCompile>
<GenerateRelocatableDeviceCode>true</GenerateRelocatableDeviceCode> <GenerateRelocatableDeviceCode>true</GenerateRelocatableDeviceCode>
<CodeGeneration>compute_86,sm_86</CodeGeneration> <CodeGeneration>compute_86,sm_86</CodeGeneration>
<InterleaveSourceInPTX>true</InterleaveSourceInPTX>
<NvccCompilation>compile</NvccCompilation>
<Optimization>O3</Optimization>
</CudaCompile> </CudaCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">

View File

@ -24,10 +24,24 @@
<CudaCompile Include="GPUTool\GPUTool.cuh"> <CudaCompile Include="GPUTool\GPUTool.cuh">
<Filter>GPUTool</Filter> <Filter>GPUTool</Filter>
</CudaCompile> </CudaCompile>
<CudaCompile Include="GPUTool\GPUDouble32.cu">
<Filter>GPUTool</Filter>
</CudaCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="GPUTool\GPUBaseLibAPI.h"> <ClInclude Include="GPUTool\GPUBaseLibAPI.h">
<Filter>GPUTool</Filter> <Filter>GPUTool</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GPUTool\GPUDouble32.cuh">
<Filter>GPUTool</Filter>
</ClInclude>
<ClInclude Include="GPUTool\GPUBaseTool.h">
<Filter>GPUTool</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="GPUTool\GPUBaseTool.cpp">
<Filter>GPUTool</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,56 @@
#include "GPUBaseTool.h"
// »ñÈ¡Îļþ´óС
extern "C" size_t getfsize(FILE* fp)
{
fseek(fp, 0L, SEEK_END);
size_t size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
return size;
}
extern "C" unsigned char* loadBinFromPath(char* binPath, size_t* binpath_len)
{
FILE* fd = fopen(binPath, "rb");
if (NULL == fd)
{
perror("Failed to open file");
return NULL;
}
size_t f_len = getfsize(fd);
*binpath_len = f_len;
unsigned char* buffer = (unsigned char*)malloc(f_len * sizeof(unsigned char));
if (buffer == NULL)
{
perror("Failed to allocate memory");
fclose(fd);
return NULL;
}
size_t fread_count = fread(buffer, 1, f_len, fd);
fclose(fd);
if (fread_count != f_len)
{
releaseVoidArray(buffer);
return NULL;
}
return buffer;
}
extern "C" void writeComplexDataBinFile(char* dataPath, size_t datalen, cuComplex* data)
{
FILE* pd = fopen(dataPath, "w");
double* tempdata = (double*)malloc(datalen * 2 * sizeof(double));
for (long i = 0; i < datalen; i++)
{
tempdata[i * 2 + 0] = data[i].x;
tempdata[i * 2 + 1] = data[i].y;
}
fwrite(tempdata, sizeof(double), datalen * 2, pd);
fclose(pd);
}

View File

@ -0,0 +1,25 @@
#ifndef __GPUBASETOOL_H__
#define __GPUBASETOOL_H__
#include "GPUBaseLibAPI.h"
#include "BaseConstVariable.h"
#include <iostream>
#include <memory>
#include <complex>
#include "GPUTool.cuh"
extern "C" GPUBASELIBAPI size_t getfsize(FILE* fp);
extern "C" GPUBASELIBAPI unsigned char* loadBinFromPath(char* binPath, size_t* binpath_len);
extern "C" GPUBASELIBAPI void writeComplexDataBinFile(char* dataPath, size_t datalen, cuComplex* data);
template<typename T>
inline std::shared_ptr<T> CPUToHost(std::shared_ptr<T> CPUArr, size_t len) {
std::shared_ptr<T> result = std::shared_ptr<T>((T*)mallocCUDAHost(len*sizeof(T)), FreeCUDAHost);
for (size_t i = 0; i < len; i++) {
result.get()[i] = CPUArr.get()[i];
}
return result;
}
#endif // !__GPUBASETOOL_H__

View File

@ -0,0 +1,560 @@
#include <iostream>
#include <memory>
#include <cmath>
#include <complex>
#include <sm_20_atomic_functions.h>
#include <device_double_functions.h>
#include <device_launch_parameters.h>
#include <cuda_runtime.h>
#include <math_functions.h>
#include <cufft.h>
#include <cufftw.h>
#include <cufftXt.h>
#include <cublas_v2.h>
#include <cuComplex.h>
#include <chrono>
#include "BaseConstVariable.h"
#include "GPUTool.cuh"
#include "GPUDouble32.cuh"
#include "PrintMsgToQDebug.h"
// 将 double 转换为 double32
// 方法一使用CUDA内置快速除法指令
__device__ float fast_reciprocal(float x) {
return __fdividef(1.0f, x); // 精确度约21位
}
// 方法二PTX指令级实现更快但精度略低
__device__ float ptx_reciprocal(float x) {
float r;
asm("rcp.approx.ftz.f32 %0, %1;" : "=f"(r) : "f"(x));
return r; // 精确度约20位
}
// 快速双32位运算核心算法
__device__ __host__ double32 two_sum(float a, float b) {
float s = a + b;
float v = s - a;
float e = (a - (s - v)) + (b - v);
return double32(s, e);
}
__device__ __host__ double32 quick_two_sum(float a, float b) {
float s = a + b;
float e = b - (s - a);
return double32(s, e);
}
__device__ double32 double_to_double32(double value) {
const float SCALE_FACTOR = 1u << 12 + 1; // 4097.0f
const float INV_SCALE = 1.0f / SCALE_FACTOR;
// Step 1: 分割双精度值为高低两部分
float high = __double2float_rd(value);
double residual = value - __double2float_rd(high);
// Step 2: 使用Dekker算法精确分解余数
float temp = SCALE_FACTOR * __double2float_ru(residual);
float res_hi = temp - (temp - __double2float_ru(residual));
float res_lo = __double2float_ru(residual) - res_hi;
// Step 3: 合并结果
float low = (res_hi + (res_lo + (residual - __double2float_rd(residual)))) * INV_SCALE;
// Step 4: 规范化处理
float s = high + low;
float e = low - (s - high);
return double32(s, e);
}
// 将 double32 转换为 double
__device__ __host__ double double32_to_double(const double32& value) {
// 分步转换确保精度不丢失
const double high_part = static_cast<double>(value.high);
const double low_part = static_cast<double>(value.low);
// Kahan式加法补偿舍入误差
const double sum = high_part + low_part;
const double err = (high_part - sum) + low_part;
return sum + err;
}
// 使用加法函数
__device__ double32 double32_add(const double32& a, const double32& b) {
double32 s = two_sum(a.high, b.high);
s.low += a.low + b.low;
return quick_two_sum(s.high, s.low);
}
// 使用减法函数
__device__ double32 double32_sub(const double32& a, const double32& b) {
// 步骤1高位部分相减核心计算
float high_diff = a.high - b.high;
// 步骤2误差补偿计算参考Dekker算法
float temp = (a.high - (high_diff + b.high)) + (b.high - (a.high - high_diff));
// 步骤3低位综合计算结合参考的精度保护机制
float low_diff = (a.low - b.low) + temp;
// 步骤4重正规化处理关键精度保障参考
float sum = high_diff + low_diff;
float residual = low_diff - (sum - high_diff);
return { sum, residual };
}
// 使用乘法函数
__device__ double32 double32_mul(const double32& a, const double32& b) {
const float split = 4097.0f; // 2^12 + 1
float c = split * a.high;
float a_hi = c - (c - a.high);
float a_lo = a.high - a_hi;
c = split * b.high;
float b_hi = c - (c - b.high);
float b_lo = b.high - b_hi;
float p = a.high * b.high;
float e = (((a_hi * b_hi - p) + a_hi * b_lo) + a_lo * b_hi) + a_lo * b_lo;
e += a.high * b.low + a.low * b.high;
return quick_two_sum(p, e);
}
// 使用除法函数
__device__ double32 double32_div(const double32& x, const double32& y) {
// 步骤1使用改进的牛顿迭代法
float y_hi = y.high;
float inv_hi = fast_reciprocal(y_hi);
// 一次牛顿迭代提升精度需要2次FMA
inv_hi = __fmaf_rn(inv_hi, __fmaf_rn(-y_hi, inv_hi, 1.0f), inv_hi);
// 步骤2计算商的高位部分
float q_hi = x.high * inv_hi;
// 步骤3误差补偿计算
double32 p = double32_mul(y, double32(q_hi, 0));
double32 r = double32_sub(x, p);
// 步骤4精确计算低位部分
float q_lo = (r.high + r.low) * inv_hi;
q_lo = __fmaf_rn(-q_hi, y.low, q_lo) * inv_hi;
// 步骤5规范化结果
return quick_two_sum(q_hi, q_lo);
}
// 使用 sin 函数
__device__ double32 double32_sin(const double32& a) {
double32 result;
result.high = sinf(a.high);
result.low = sinf(a.low);
return result;
}
// 使用 cos 函数
__device__ double32 double32_cos(const double32& a) {
double32 result;
result.high = cosf(a.high);
result.low = cosf(a.low);
return result;
}
// 使用 log2 函数
__device__ double32 double32_log2(const double32& a) {
double32 result;
result.high = log2f(a.high);
result.low = log2f(a.low);
return result;
}
// 使用 log10 函数
__device__ double32 double32_log10(const double32& a) {
double32 result;
result.high = log10f(a.high);
result.low = log10f(a.low);
return result;
}
// 使用 ln 函数
__device__ double32 double32_ln(const double32& a) {
double32 result;
result.high = logf(a.high);
result.low = logf(a.low);
return result;
}
// 使用 exp 函数
__device__ double32 double32_exp(const double32& a) {
double32 result;
result.high = expf(a.high);
result.low = expf(a.low);
return result;
}
// 使用 pow 函数
__device__ double32 double32_pow(const double32& a, const double32& b) {
double32 result;
result.high = powf(a.high, b.high);
result.low = powf(a.low, b.low);
return result;
}
// 使用 sqrt 函数
__device__ double32 double32_sqrt(const double32& a) {
double32 result;
result.high = sqrtf(a.high);
result.low = sqrtf(a.low);
return result;
}
__global__ void test_double_to_double32_kernel(double* d_input, double* d_output, int size) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < size) {
double value = d_input[idx];
d_output[idx] = double32_to_double(double_to_double32(value))-value;
}
}
__global__ void test_kernel(double* d_input, double* d_output, int size, int operation) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < size) {
double va = d_input[idx];
double vb = va + 1.0;
double32 a = double_to_double32(va);
double32 b = double_to_double32(vb); // 用于二元操作的第二个操作数
switch (operation) {
case 0: d_output[idx] = double32_to_double(double32_add(a, b)) - (va + vb); break;
case 1: d_output[idx] = double32_to_double(double32_sub(a, b)) - (va - vb); break;
case 2: d_output[idx] = double32_to_double(double32_mul(a, b)) - (va * vb); break;
case 3: d_output[idx] = double32_to_double(double32_div(a, b)) - (va / vb); break;
case 4: d_output[idx] = double32_to_double(double32_sin(a))-sin(va); break;
case 5: d_output[idx] = double32_to_double(double32_cos(a))-cos(va); break;
case 6: d_output[idx] = double32_to_double(double32_log2(a))-log2(va); break;
case 7: d_output[idx] = double32_to_double(double32_log10(a))-log10(va); break;
case 8: d_output[idx] = double32_to_double(double32_ln(a))-log(va); break;
case 9: d_output[idx] = double32_to_double(double32_exp(a))-exp(va); break;
case 10: d_output[idx] = double32_to_double(double32_pow(a, b))-pow(va,vb); break;
case 11: d_output[idx] = double32_to_double(double32_sqrt(a))-sqrt(va); break;
}
if (idx == 1) {
switch (operation) {
case 0: d_output[idx] = printf("add, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 1: d_output[idx] = printf("sub, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 2: d_output[idx] = printf("mul, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 3: d_output[idx] = printf("div, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 4: d_output[idx] = printf("sin, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 5: d_output[idx] = printf("cos, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 6: d_output[idx] = printf("log2, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 7: d_output[idx] = printf("log10, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 8: d_output[idx] = printf("ln, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 9: d_output[idx] = printf("exp, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 10: d_output[idx] = printf("pow, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
case 11: d_output[idx] = printf("sqrt, \tva=%f,vb=%f,d_output=%e\n", va, vb, d_output[idx]);; break;
}
}
}
}
void test_function(int operation, const char* operation_name) {
const int size = 1024;
double* h_input = new double[size];
double* h_output = new double[size];
double* d_input;
double* d_output;
// 初始化数据
for (int i = 0; i < size; ++i) {
h_input[i] = static_cast<double>(i)*100000.0 + 0.1234564324324232421421421421* 100000.0;
}
// 分配设备内存
cudaMalloc(&d_input, size * sizeof(double));
cudaMalloc(&d_output, size * sizeof(double));
cudaMemcpy(d_input, h_input, size * sizeof(double), cudaMemcpyHostToDevice);
// 启动 CUDA 内核
auto start = std::chrono::high_resolution_clock::now();
test_kernel << <(size + 255) / 256, 256 >> > (d_input, d_output, size, operation);
cudaDeviceSynchronize();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
std::cout << operation_name << " time: " << elapsed.count() << " seconds" << std::endl;
// 复制结果回主机
cudaMemcpy(h_output, d_output, size * sizeof(double), cudaMemcpyDeviceToHost);
// 计算精度
double total_error = 0.0;
for (int i = 0; i < size; ++i) {
double error = std::abs(h_output[i]);
total_error += error;
}
double average_error = total_error / size;
std::cout << operation_name << " average error: " << average_error << std::endl;
std::cout << operation_name << " average error: " << average_error << std::endl;
// 释放内存
delete[] h_input;
delete[] h_output;
cudaFree(d_input);
cudaFree(d_output);
}
__global__ void time_test_kernel(double* d_input, double* d_output, int size, int operation) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < size) {
double va = d_input[idx];
double vb = va + 1.0;
double32 a = double_to_double32(va);
double32 b = double_to_double32(vb); // 用于二元操作的第二个操作数
double result = 0.0;
for (long i = 0; i< 1000000; i++) {
switch (operation) {
case 0: result+= (double32_add(a, b).high); break;
case 1: result+= (double32_sub(a, b).high); break;
case 2: result+= (double32_mul(a, b).high); break;
case 3: result+= (double32_div(a, b).high); break;
case 4: result+= (double32_sin(a).high); break;
case 5: result+= (double32_cos(a).high); break;
case 6: result+= (double32_log2(a).high); break;
case 7: result+= (double32_log10(a).high); break;
case 8: result+= (double32_ln(a).high); break;
case 9: result+= (double32_exp(a).high); break;
case 10: result+= (double32_pow(a, b).high); break;
case 11: result+= (double32_sqrt(a).high); break;
}
}
d_output[idx]=result;
}
}
__global__ void time_test_double_kernel(double* d_input, double* d_output, int size, int operation) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < size) {
double va = d_input[idx];
double vb = va + 1.0;
double32 a = double_to_double32(va);
double32 b = double_to_double32(vb); // 用于二元操作的第二个操作数
double result = 0.0;
for (long i = 0; i < 1000000; i++) {
switch (operation) {
case 0: result+= (va + vb); break;
case 1: result+= (va - vb); break;
case 2: result+= (va * vb); break;
case 3: result+= (va / vb); break;
case 4: result+= sin(va); break;
case 5: result+= cos(va); break;
case 6: result+= log2(va); break;
case 7: result+= log10(va); break;
case 8: result+= log(va); break;
case 9: result+= exp(va); break;
case 10:result+= pow(va, vb); break;
case 11:result+= sqrt(va); break;
}
}
d_output[idx] = result;
}
}
void test_double_to_double32() {
const int size = 1024;
double* h_input = new double[size];
double* h_output = new double[size];
double* d_input;
double* d_output;
// 初始化数据
for (int i = 0; i < size; ++i) {
h_input[i] = static_cast<double>(i) * 1000000.0 + 0.123456789011 * 1000000.0;
}
// 分配设备内存
cudaMalloc(&d_input, size * sizeof(double));
cudaMalloc(&d_output, size * sizeof(double));
cudaMemcpy(d_input, h_input, size * sizeof(double), cudaMemcpyHostToDevice);
// 启动 CUDA 内核
auto start = std::chrono::high_resolution_clock::now();
test_double_to_double32_kernel << <(size + 255) / 256, 256 >> > (d_input, d_output, size);
cudaDeviceSynchronize();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
std::cout << "double_to_double32 conversion time: " << elapsed.count() << " seconds" << std::endl;
// 复制结果回主机
cudaMemcpy(h_output, d_output, size * sizeof(double), cudaMemcpyDeviceToHost);
// 计算精度
double total_error = 0.0;
for (int i = 0; i < size; ++i) {
double error = std::abs(h_output[i]);
total_error += error;
}
double average_error = total_error / size;
std::cout << "double_to_double32 average error: " << average_error << std::endl;
// 计算有效位数
double effective_digits = -std::log10(average_error);
std::cout << "double_to_double32 effective digits: " << effective_digits << std::endl;
// 释放内存
delete[] h_input;
delete[] h_output;
cudaFree(d_input);
cudaFree(d_output);
}
void time_test_function(int operation, const char* operation_name) {
const int size = 1024;
double* h_input = new double[size];
double* h_output = new double[size];
double* d_input;
double* d_output;
// 初始化数据
for (int i = 0; i < size; ++i) {
h_input[i] = static_cast<double>(i) * 100000.0 + 0.1234564324324232421421421421 * 100000.0;
}
// 分配设备内存
cudaMalloc(&d_input, size * sizeof(double));
cudaMalloc(&d_output, size * sizeof(double));
cudaMemcpy(d_input, h_input, size * sizeof(double), cudaMemcpyHostToDevice);
// 启动 CUDA 内核 (double32)
auto start = std::chrono::high_resolution_clock::now();
time_test_kernel << <(size + 255) / 256, 256 >> > (d_input, d_output, size, operation);
cudaDeviceSynchronize();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
std::cout << operation_name << " (double32) time: " << elapsed.count() << " seconds" << std::endl;
// 复制结果回主机
cudaMemcpy(h_output, d_output, size * sizeof(double), cudaMemcpyDeviceToHost);
// 计算精度
double total_error = 0.0;
for (int i = 0; i < size; ++i) {
double error = std::abs(h_output[i]);
total_error += error;
}
double average_error = total_error / size;
std::cout << operation_name << " (double32) average error: " << average_error << std::endl;
// 启动 CUDA 内核 (double)
start = std::chrono::high_resolution_clock::now();
time_test_double_kernel << <(size + 255) / 256, 256 >> > (d_input, d_output, size, operation);
cudaDeviceSynchronize();
end = std::chrono::high_resolution_clock::now();
elapsed = end - start;
std::cout << operation_name << " (double) time: " << elapsed.count() << " seconds" << std::endl;
// 复制结果回主机
cudaMemcpy(h_output, d_output, size * sizeof(double), cudaMemcpyDeviceToHost);
// 计算精度
total_error = 0.0;
for (int i = 0; i < size; ++i) {
double error = std::abs(h_output[i]);
total_error += error;
}
average_error = total_error / size;
std::cout << operation_name << " (double) average error: " << average_error << std::endl;
// 释放内存
delete[] h_input;
delete[] h_output;
cudaFree(d_input);
cudaFree(d_output);
}
void time_test_double_to_double32() {
const int size = 1024;
double* h_input = new double[size];
double* h_output = new double[size];
double* d_input;
double* d_output;
// 初始化数据
for (int i = 0; i < size; ++i) {
h_input[i] = static_cast<double>(i) * 1000000.0 + 0.123456789011 * 1000000.0;
}
// 分配设备内存
cudaMalloc(&d_input, size * sizeof(double));
cudaMalloc(&d_output, size * sizeof(double));
cudaMemcpy(d_input, h_input, size * sizeof(double), cudaMemcpyHostToDevice);
// 启动 CUDA 内核
auto start = std::chrono::high_resolution_clock::now();
test_double_to_double32_kernel << <(size + 255) / 256, 256 >> > (d_input, d_output, size);
cudaDeviceSynchronize();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
std::cout << "double_to_double32 conversion time: " << elapsed.count() << " seconds" << std::endl;
// 复制结果回主机
cudaMemcpy(h_output, d_output, size * sizeof(double), cudaMemcpyDeviceToHost);
// 计算精度
double total_error = 0.0;
for (int i = 0; i < size; ++i) {
double error = std::abs(h_output[i]);
total_error += error;
}
double average_error = total_error / size;
std::cout << "double_to_double32 average error: " << average_error << std::endl;
// 计算有效位数
double effective_digits = -std::log10(average_error);
std::cout << "double_to_double32 effective digits: " << effective_digits << std::endl;
// 释放内存
delete[] h_input;
delete[] h_output;
cudaFree(d_input);
cudaFree(d_output);
}
void time_test_add() { time_test_function(0, "Addition"); }
void time_test_sub() { time_test_function(1, "Subtraction"); }
void time_test_mul() { time_test_function(2, "Multiplication"); }
void time_test_div() { time_test_function(3, "Division"); }
void time_test_sin() { time_test_function(4, "Sine"); }
void time_test_cos() { time_test_function(5, "Cosine"); }
void time_test_log2() { time_test_function(6, "Log2"); }
void time_test_log10() { time_test_function(7, "Log10"); }
void time_test_ln() { time_test_function(8, "Natural Logarithm"); }
void time_test_exp() { time_test_function(9, "Exponential"); }
void time_test_pow() { time_test_function(10, "Power"); }
void time_test_sqrt() { time_test_function(11, "Square Root"); }

View File

@ -0,0 +1,76 @@
#ifndef __GPUDOUBLE32__H__
#define __GPUDOUBLE32__H__
// 定义double32 struct ,使用fp32模拟double
struct double32{
float high;
float low;
__device__ __host__ double32(float h = 0, float l = 0) : high(h), low(l) {}
};
extern __device__ double32 double_to_double32(double value);
extern __device__ __host__ double double32_to_double(const double32& value);
// 使用 PTX 优化的加法函数
extern __device__ double32 double32_add(const double32& a, const double32& b);
// 使用 PTX 优化的减法函数
extern __device__ double32 double32_sub(const double32& a, const double32& b);
// 使用 PTX 优化的乘法函数
extern __device__ double32 double32_mul(const double32& a, const double32& b);
// 使用 PTX 优化的除法函数
extern __device__ double32 double32_div(const double32& a, const double32& b);
// 使用 PTX 优化的 sin 函数
extern __device__ double32 double32_sin(const double32& a);
// 使用 PTX 优化的 cos 函数
extern __device__ double32 double32_cos(const double32& a);
// 使用 PTX 优化的 log2 函数
extern __device__ double32 double32_log2(const double32& a);
// 使用 PTX 优化的 log10 函数
extern __device__ double32 double32_log10(const double32& a);
// 使用 PTX 优化的 ln 函数
extern __device__ double32 double32_ln(const double32& a);
// 使用 PTX 优化的 exp 函数
extern __device__ double32 double32_exp(const double32& a);
// 使用 PTX 优化的 pow 函数
extern __device__ double32 double32_pow(const double32& a, const double32& b);
// 使用 PTX 优化的 sqrt 函数
extern __device__ double32 double32_sqrt(const double32& a);
extern "C" GPUBASELIBAPI void test_double_to_double32();
extern "C" GPUBASELIBAPI void test_function(int operation, const char* operation_name);
extern "C" GPUBASELIBAPI void time_test_add();
extern "C" GPUBASELIBAPI void time_test_sub();
extern "C" GPUBASELIBAPI void time_test_mul();
extern "C" GPUBASELIBAPI void time_test_div();
extern "C" GPUBASELIBAPI void time_test_sin();
extern "C" GPUBASELIBAPI void time_test_cos();
extern "C" GPUBASELIBAPI void time_test_log2();
extern "C" GPUBASELIBAPI void time_test_log10();
extern "C" GPUBASELIBAPI void time_test_ln();
extern "C" GPUBASELIBAPI void time_test_exp();
extern "C" GPUBASELIBAPI void time_test_pow();
extern "C" GPUBASELIBAPI void time_test_sqrt();
#endif // !__GPUDOUBLE32__H__

View File

@ -353,18 +353,40 @@ extern "C" void FreeCUDAHost(void* ptr) {
ptr = nullptr; ptr = nullptr;
} }
// GPU参数内存声明 // 多GPU内存分配函数
extern "C" void* mallocCUDADevice(size_t memsize) { void* mallocCUDADevice(size_t memsize, int device_id )
void* ptr; {
cudaMalloc(&ptr, memsize); void* ptr = nullptr;
#ifdef __CUDADEBUG__ cudaError_t err;
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) { // 1. 检查设备ID有效性
printf("mallocCUDADevice CUDA Error: %s, malloc memory : %d byte\n", cudaGetErrorString(err), memsize); int num_devices;
exit(2); cudaGetDeviceCount(&num_devices);
if (device_id < 0 || device_id >= num_devices)
{
printfinfo("Invalid device ID: %d\n", device_id);
return nullptr;
} }
#endif // __CUDADEBUG__
cudaDeviceSynchronize(); // 2. 切换目标GPU设备
err = cudaSetDevice(device_id);
if (err != cudaSuccess)
{
PrintLasterError("cudaSetDevice");
return nullptr;
}
// 3. 分配显存
err = cudaMalloc(&ptr, memsize);
if (err != cudaSuccess)
{
PrintLasterError("cudaMalloc");
return nullptr;
}
// 4. 可选:同步设备(视需求决定是否保留)
// cudaDeviceSynchronize();
return ptr; return ptr;
} }

View File

@ -14,12 +14,17 @@
#define CUDAMEMORY Memory1MB*100 #define CUDAMEMORY Memory1MB*100
#define LAMP_CUDA_PI 3.141592653589793238462643383279 #define LAMP_CUDA_PI 3.141592653589793238462643383279
#define PI4POW2 157.91367041742973
// SHAREMEMORY_FLOAT_HALF_STEP * BLOCK_SIZE = SHAREMEMORY_FLOAT_HALF // SHAREMEMORY_FLOAT_HALF_STEP * BLOCK_SIZE = SHAREMEMORY_FLOAT_HALF
/** CUDA 调用参数 ************************************************************************************/
#define BLOCK_SIZE 256 #define BLOCK_SIZE 256
#define SHAREMEMORY_BYTE 49152 #define SHAREMEMORY_BYTE 49152
#define SHAREMEMORY_FLOAT_HALF 6144 #define SHAREMEMORY_FLOAT_HALF_STEP 2
#define SHAREMEMORY_FLOAT_HALF_STEP 24 #define SHAREMEMORY_FLOAT_HALF 512
#define SHAREMEMORY_DEM_STEP 768
#define SHAREMEMORY_Reflect 612
@ -77,7 +82,7 @@ extern "C" GPUBASELIBAPI void checkCudaError(cudaError_t err, const char* msg);
// GPU 内存函数 // GPU 内存函数
extern "C" GPUBASELIBAPI void* mallocCUDAHost(size_t memsize); // 主机内存声明 extern "C" GPUBASELIBAPI void* mallocCUDAHost(size_t memsize); // 主机内存声明
extern "C" GPUBASELIBAPI void FreeCUDAHost(void* ptr); extern "C" GPUBASELIBAPI void FreeCUDAHost(void* ptr);
extern "C" GPUBASELIBAPI void* mallocCUDADevice(size_t memsize); // GPUÄÚ´æÉùÃ÷ extern "C" GPUBASELIBAPI void* mallocCUDADevice(size_t memsize, int device_id = 0); // GPU内存声明
extern "C" GPUBASELIBAPI void FreeCUDADevice(void* ptr); extern "C" GPUBASELIBAPI void FreeCUDADevice(void* ptr);
extern "C" GPUBASELIBAPI void HostToDevice(void* hostptr, void* deviceptr, size_t memsize);//GPU 内存数据转移 设备 -> GPU extern "C" GPUBASELIBAPI void HostToDevice(void* hostptr, void* deviceptr, size_t memsize);//GPU 内存数据转移 设备 -> GPU
extern "C" GPUBASELIBAPI void DeviceToHost(void* hostptr, void* deviceptr, size_t memsize);//GPU 内存数据转移 GPU -> 设备 extern "C" GPUBASELIBAPI void DeviceToHost(void* hostptr, void* deviceptr, size_t memsize);//GPU 内存数据转移 GPU -> 设备
@ -110,6 +115,10 @@ extern "C" GPUBASELIBAPI void CUDAIFFT(cuComplex* inArr, cuComplex* outArr, long
extern "C" GPUBASELIBAPI void FFTShift1D(cuComplex* d_data, int batch_size, int signal_length); extern "C" GPUBASELIBAPI void FFTShift1D(cuComplex* d_data, int batch_size, int signal_length);
extern "C" GPUBASELIBAPI void shared_complexPtrToHostCuComplex(std::complex<double>* src, cuComplex* dst, size_t len); extern "C" GPUBASELIBAPI void shared_complexPtrToHostCuComplex(std::complex<double>* src, cuComplex* dst, size_t len);
extern "C" GPUBASELIBAPI void HostCuComplexToshared_complexPtr(cuComplex* src, std::complex<double>* dst, size_t len); extern "C" GPUBASELIBAPI void HostCuComplexToshared_complexPtr(cuComplex* src, std::complex<double>* dst, size_t len);
#endif #endif
#endif #endif

View File

@ -38,6 +38,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RasterMainWidgetGUI", "Rast
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageshowTool", "ImageshowTool\ImageshowTool.vcxproj", "{8C8CA066-A93A-4098-9A46-B855EFEAADF2}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageshowTool", "ImageshowTool\ImageshowTool.vcxproj", "{8C8CA066-A93A-4098-9A46-B855EFEAADF2}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pluginToolboxLibrary", "pluginToolboxLibrary\pluginToolboxLibrary.vcxproj", "{667625A5-8DE2-4373-99F0-8BAD2CCED011}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPG4Tool", "SPG4Tool\SPG4Tool.vcxproj", "{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM Debug|ARM = Debug|ARM
@ -168,6 +172,30 @@ Global
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x64.Build.0 = Release|x64 {8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x64.Build.0 = Release|x64
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.ActiveCfg = Release|x64 {8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.ActiveCfg = Release|x64
{8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.Build.0 = Release|x64 {8C8CA066-A93A-4098-9A46-B855EFEAADF2}.Release|x86.Build.0 = Release|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Debug|ARM.ActiveCfg = Debug|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Debug|ARM.Build.0 = Debug|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Debug|x64.ActiveCfg = Debug|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Debug|x64.Build.0 = Debug|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Debug|x86.ActiveCfg = Debug|Win32
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Debug|x86.Build.0 = Debug|Win32
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Release|ARM.ActiveCfg = Release|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Release|ARM.Build.0 = Release|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Release|x64.ActiveCfg = Release|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Release|x64.Build.0 = Release|x64
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Release|x86.ActiveCfg = Release|Win32
{667625A5-8DE2-4373-99F0-8BAD2CCED011}.Release|x86.Build.0 = Release|Win32
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|ARM.ActiveCfg = Debug|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|ARM.Build.0 = Debug|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x64.ActiveCfg = Debug|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x64.Build.0 = Debug|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x86.ActiveCfg = Debug|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Debug|x86.Build.0 = Debug|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|ARM.ActiveCfg = Release|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|ARM.Build.0 = Release|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x64.ActiveCfg = Release|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x64.Build.0 = Release|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x86.ActiveCfg = Release|x64
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}.Release|x86.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -181,6 +209,7 @@ Global
{B8B40C54-F7FE-4809-B6FB-8BC014570D7B} = {2768F9D6-D410-4E88-A479-8336DAF97072} {B8B40C54-F7FE-4809-B6FB-8BC014570D7B} = {2768F9D6-D410-4E88-A479-8336DAF97072}
{E56B3878-A3DC-41A4-ABF3-B628816D0D64} = {6505E2BA-06A2-447B-BC85-8CF1A81359BC} {E56B3878-A3DC-41A4-ABF3-B628816D0D64} = {6505E2BA-06A2-447B-BC85-8CF1A81359BC}
{8C8CA066-A93A-4098-9A46-B855EFEAADF2} = {2768F9D6-D410-4E88-A479-8336DAF97072} {8C8CA066-A93A-4098-9A46-B855EFEAADF2} = {2768F9D6-D410-4E88-A479-8336DAF97072}
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E} = {2768F9D6-D410-4E88-A479-8336DAF97072}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {179F0A62-C631-4667-AD03-3780ADE09F41} SolutionGuid = {179F0A62-C631-4667-AD03-3780ADE09F41}

View File

@ -196,8 +196,8 @@
<ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj"> <ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj">
<Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project> <Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\ImageshowTool\ImageshowTool.vcxproj"> <ProjectReference Include="..\pluginToolboxLibrary\pluginToolboxLibrary.vcxproj">
<Project>{8c8ca066-a93a-4098-9a46-b855efeaadf2}</Project> <Project>{667625a5-8de2-4373-99f0-8bad2cced011}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\RasterMainWidgetGUI\RasterMainWidgetGUI.vcxproj"> <ProjectReference Include="..\RasterMainWidgetGUI\RasterMainWidgetGUI.vcxproj">
<Project>{e56b3878-a3dc-41a4-abf3-b628816d0d64}</Project> <Project>{e56b3878-a3dc-41a4-abf3-b628816d0d64}</Project>

View File

@ -14,7 +14,7 @@
#include "FileOperator.h" #include "FileOperator.h"
#include "RasterWidgetMessageShow.h" #include "RasterWidgetMessageShow.h"
#include "ImageOperatorBase.h"
#pragma execution_character_set("utf-8") #pragma execution_character_set("utf-8")
@ -59,7 +59,7 @@ RasterMainWidget::RasterMainWidget(QWidget *parent)
//mUi->layerList->setCurrentItem(mLayerList.first()); //mUi->layerList->setCurrentItem(mLayerList.first());
connect(mUi->actioncloseAllRasterFile, SIGNAL(triggered()), this, SLOT(onactioncloseAllRasterFile_triggered()));
} }
@ -341,6 +341,11 @@ void RasterMainWidget::on_addPlaneaction_triggered()
mMapConvas->selectTool("addplane_tool"); mMapConvas->selectTool("addplane_tool");
} }
void RasterMainWidget::onactioncloseAllRasterFile_triggered()
{
CloseAllGDALRaster();
}
QTableWidget* RasterMainWidget::getTaskTable() QTableWidget* RasterMainWidget::getTaskTable()
{ {
return this->mUi->taskTable; return this->mUi->taskTable;

View File

@ -77,7 +77,7 @@ namespace LAMPMainWidget {
private slots: private slots:
void on_drawArea_triggered(); void on_drawArea_triggered();
void on_addPlaneaction_triggered(); void on_addPlaneaction_triggered();
void onactioncloseAllRasterFile_triggered();
private: private:
Ui::RasterMainWidget* mUi; Ui::RasterMainWidget* mUi;
MapCanvas* mMapConvas; MapCanvas* mMapConvas;

View File

@ -85,7 +85,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>906</width> <width>906</width>
<height>23</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="projectMenu"> <widget class="QMenu" name="projectMenu">
@ -117,6 +117,7 @@
<property name="title"> <property name="title">
<string>工具</string> <string>工具</string>
</property> </property>
<addaction name="actioncloseAllRasterFile"/>
</widget> </widget>
<widget class="QMenu" name="helpMenu"> <widget class="QMenu" name="helpMenu">
<property name="title"> <property name="title">
@ -513,6 +514,11 @@ p, li { white-space: pre-wrap; }
<string>飞机</string> <string>飞机</string>
</property> </property>
</action> </action>
<action name="actioncloseAllRasterFile">
<property name="text">
<string>释放影像文件</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="../RasterMainWidgetGUI.qrc"/> <include location="../RasterMainWidgetGUI.qrc"/>

View File

@ -265,9 +265,6 @@
<ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj"> <ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj">
<Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project> <Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\ImageshowTool\ImageshowTool.vcxproj">
<Project>{8c8ca066-a93a-4098-9a46-b855efeaadf2}</Project>
</ProjectReference>
<ProjectReference Include="..\RasterProcessToolWidget\RasterProcessTool.vcxproj"> <ProjectReference Include="..\RasterProcessToolWidget\RasterProcessTool.vcxproj">
<Project>{7ef67daa-dbc0-4b7f-80e8-11b4d2cb7ec2}</Project> <Project>{7ef67daa-dbc0-4b7f-80e8-11b4d2cb7ec2}</Project>
</ProjectReference> </ProjectReference>

View File

@ -25,6 +25,7 @@ ToolBoxWidget::ToolBoxWidget(LAMPMainWidget::RasterMainWidget* mainWindows, QWid
ui->setupUi(this); ui->setupUi(this);
setContextMenuPolicy(Qt::CustomContextMenu); // <20>零塘숩우쌥꽉데 setContextMenuPolicy(Qt::CustomContextMenu); // <20>零塘숩우쌥꽉데
QObject::connect(this, SIGNAL(addBoxToolItemSIGNAL(QToolAbstract*)), this, SLOT(addBoxToolItemSLOT(QToolAbstract*))); QObject::connect(this, SIGNAL(addBoxToolItemSIGNAL(QToolAbstract*)), this, SLOT(addBoxToolItemSLOT(QToolAbstract*)));
QObject::connect(this, SIGNAL(addBoxToolItemInPathSIGNAL(QVector<QString> , QToolAbstract* )), this, SLOT(addBoxToolItemInPathSLOT(QVector<QString>, QToolAbstract * )));
} }
@ -122,6 +123,37 @@ void ToolBoxWidget::addBoxToolItemSLOT(QToolAbstract* item)
} }
void ToolBoxWidget::addBoxToolItemInPathSLOT(QVector<QString> xnodepath, QToolAbstract* item)
{
QString toolName = item->getToolName();
QTreeWidgetItem* parentItem = findOrCreateParentItem(xnodepath);
// 检查该父项是否已经绑定了 toolButton
if (parentItem && ui->treeWidgetToolBox->itemWidget(parentItem, 0) == nullptr) {
toollist.append(QToolboxTreeWidgetItem(ui->treeWidgetToolBox, parentItem, item));
//QTreeWidgetItem* actionItem = new QTreeWidgetItem(parentItem);
//parentItem->addChild(actionItem);
//actionItem->setText(0,toolName);
//QIcon icon(QString::fromUtf8(":/ToolBoxWidget/toolicon"));
//QPushButton* button = new QPushButton(ui->treeWidgetToolBox);
//button->setIcon(icon);
//button->setText(toolName);
//button->setLayoutDirection(Qt::LeftToRight);
//button->setStyleSheet("QPushButton { text-align: left; }");
//ui->treeWidgetToolBox->setItemWidget(actionItem, 0, button);
//connect(button, SIGNAL(clicked()), item, SLOT(excute()));
//item->setParent(ui->treeWidgetToolBox);
//qDebug() << "ToolButton bound to parent:" << actionItem->text(0);
}
else {
qDebug() << "ToolButton already bound to parent:" << parentItem->text(0);
}
}
// 몽앴쨌쓺꿴冷샀눼쉔만淃 // 몽앴쨌쓺꿴冷샀눼쉔만淃
QTreeWidgetItem* ToolBoxWidget::findOrCreateParentItem( QVector<QString>& path) { QTreeWidgetItem* ToolBoxWidget::findOrCreateParentItem( QVector<QString>& path) {
QTreeWidgetItem* currentItem = nullptr; QTreeWidgetItem* currentItem = nullptr;
@ -171,7 +203,17 @@ QTreeWidgetItem* ToolBoxWidget::findChildItemByName(QTreeWidgetItem* parentItem,
return childItem; return childItem;
} }
} }
return nullptr;
// 如果没有找到,创建新的顶级节点
QTreeWidgetItem* newItem = new QTreeWidgetItem(parentItem);
QIcon icon(QString::fromUtf8(":/RasterProcessTool/toolboxIcon"));
newItem->setIcon(0, icon);
newItem->setTextAlignment(0, Qt::AlignLeft);
newItem->setText(0, name);
parentItem->addChild(newItem);
return newItem;
// return nullptr;
} }
void ToolBoxWidget::OpenToolboxManagerWidget() void ToolBoxWidget::OpenToolboxManagerWidget()

View File

@ -49,9 +49,11 @@ private:
signals: signals:
void addBoxToolItemSIGNAL(QToolAbstract* item); void addBoxToolItemSIGNAL(QToolAbstract* item);
void addBoxToolItemInPathSIGNAL(QVector<QString> xnodepath, QToolAbstract* item);
public slots: public slots:
void addBoxToolItemSLOT(QToolAbstract* item); void addBoxToolItemSLOT(QToolAbstract* item);
void addBoxToolItemInPathSLOT(QVector<QString> xnodepath, QToolAbstract* item);
QTreeWidgetItem* findOrCreateParentItem( QVector<QString>& path); QTreeWidgetItem* findOrCreateParentItem( QVector<QString>& path);
QTreeWidgetItem* findOrCreateTopLevelItem( QString& name); QTreeWidgetItem* findOrCreateTopLevelItem( QString& name);
QTreeWidgetItem* findChildItemByName(QTreeWidgetItem* parentItem, QString& name); QTreeWidgetItem* findChildItemByName(QTreeWidgetItem* parentItem, QString& name);

402
SPG4Tool/PassPredict.cpp Normal file
View File

@ -0,0 +1,402 @@
#include <Observer.h>
#include <SGP4.h>
#include <Util.h>
#include <CoordTopocentric.h>
#include <CoordGeodetic.h>
#include <cmath>
#include <iostream>
#include <list>
#include <QDate>
#include <QDateTime>
#include <iomanip>
#include <sstream>
#include "SPG4Function.h"
struct PassDetails
{
libsgp4::DateTime aos;
libsgp4::DateTime los;
double max_elevation;
};
double FindMaxElevation(
const libsgp4::CoordGeodetic& user_geo,
libsgp4::SGP4& sgp4,
const libsgp4::DateTime& aos,
const libsgp4::DateTime& los)
{
libsgp4::Observer obs(user_geo);
bool running;
double time_step = (los - aos).TotalSeconds() / 9.0;
libsgp4::DateTime current_time(aos); //! current time
libsgp4::DateTime time1(aos); //! start time of search period
libsgp4::DateTime time2(los); //! end time of search period
double max_elevation; //! max elevation
running = true;
do
{
running = true;
max_elevation = -99999999999999.0;
while (running && current_time < time2)
{
/*
* find position
*/
libsgp4::Eci eci = sgp4.FindPosition(current_time);
libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (topo.elevation > max_elevation)
{
/*
* still going up
*/
max_elevation = topo.elevation;
/*
* move time along
*/
current_time = current_time.AddSeconds(time_step);
if (current_time > time2)
{
/*
* dont go past end time
*/
current_time = time2;
}
}
else
{
/*
* stop
*/
running = false;
}
}
/*
* make start time to 2 time steps back
*/
time1 = current_time.AddSeconds(-2.0 * time_step);
/*
* make end time to current time
*/
time2 = current_time;
/*
* current time to start time
*/
current_time = time1;
/*
* recalculate time step
*/
time_step = (time2 - time1).TotalSeconds() / 9.0;
} while (time_step > 1.0);
return max_elevation;
}
libsgp4::DateTime FindCrossingPoint(
const libsgp4::CoordGeodetic& user_geo,
libsgp4::SGP4& sgp4,
const libsgp4::DateTime& initial_time1,
const libsgp4::DateTime& initial_time2,
bool finding_aos)
{
libsgp4::Observer obs(user_geo);
bool running;
int cnt;
libsgp4::DateTime time1(initial_time1);
libsgp4::DateTime time2(initial_time2);
libsgp4::DateTime middle_time;
running = true;
cnt = 0;
while (running && cnt++ < 16)
{
middle_time = time1.AddSeconds((time2 - time1).TotalSeconds() / 2.0);
/*
* calculate satellite position
*/
libsgp4::Eci eci = sgp4.FindPosition(middle_time);
libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (topo.elevation > 0.0)
{
/*
* satellite above horizon
*/
if (finding_aos)
{
time2 = middle_time;
}
else
{
time1 = middle_time;
}
}
else
{
if (finding_aos)
{
time1 = middle_time;
}
else
{
time2 = middle_time;
}
}
if ((time2 - time1).TotalSeconds() < 1.0)
{
/*
* two times are within a second, stop
*/
running = false;
/*
* remove microseconds
*/
int us = middle_time.Microsecond();
middle_time = middle_time.AddMicroseconds(-us);
/*
* step back into the pass by 1 second
*/
middle_time = middle_time.AddSeconds(finding_aos ? 1 : -1);
}
}
/*
* go back/forward 1second until below the horizon
*/
running = true;
cnt = 0;
while (running && cnt++ < 6)
{
libsgp4::Eci eci = sgp4.FindPosition(middle_time);
libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (topo.elevation > 0)
{
middle_time = middle_time.AddSeconds(finding_aos ? -1 : 1);
}
else
{
running = false;
}
}
return middle_time;
}
std::list<struct PassDetails> GeneratePassList(
const libsgp4::CoordGeodetic& user_geo,
libsgp4::SGP4& sgp4,
const libsgp4::DateTime& start_time,
const libsgp4::DateTime& end_time,
const int time_step)
{
std::list<struct PassDetails> pass_list;
libsgp4::Observer obs(user_geo);
libsgp4::DateTime aos_time;
libsgp4::DateTime los_time;
bool found_aos = false;
libsgp4::DateTime previous_time(start_time);
libsgp4::DateTime current_time(start_time);
while (current_time < end_time)
{
bool end_of_pass = false;
/*
* calculate satellite position
*/
libsgp4::Eci eci = sgp4.FindPosition(current_time);
libsgp4::CoordTopocentric topo = obs.GetLookAngle(eci);
if (!found_aos && topo.elevation > 0.0)
{
/*
* aos hasnt occured yet, but the satellite is now above horizon
* this must have occured within the last time_step
*/
if (start_time == current_time)
{
/*
* satellite was already above the horizon at the start,
* so use the start time
*/
aos_time = start_time;
}
else
{
/*
* find the point at which the satellite crossed the horizon
*/
aos_time = FindCrossingPoint(
user_geo,
sgp4,
previous_time,
current_time,
true);
}
found_aos = true;
}
else if (found_aos && topo.elevation < 0.0)
{
found_aos = false;
/*
* end of pass, so move along more than time_step
*/
end_of_pass = true;
/*
* already have the aos, but now the satellite is below the horizon,
* so find the los
*/
los_time = FindCrossingPoint(
user_geo,
sgp4,
previous_time,
current_time,
false);
struct PassDetails pd;
pd.aos = aos_time;
pd.los = los_time;
pd.max_elevation = FindMaxElevation(
user_geo,
sgp4,
aos_time,
los_time);
pass_list.push_back(pd);
}
/*
* save current time
*/
previous_time = current_time;
if (end_of_pass)
{
/*
* at the end of the pass move the time along by 30mins
*/
current_time = current_time + libsgp4::TimeSpan(0, 30, 0);
}
else
{
/*
* move the time along by the time step value
*/
current_time = current_time + libsgp4::TimeSpan(0, 0, time_step);
}
if (current_time > end_time)
{
/*
* dont go past end time
*/
current_time = end_time;
}
};
if (found_aos)
{
/*
* satellite still above horizon at end of search period, so use end
* time as los
*/
struct PassDetails pd;
pd.aos = aos_time;
pd.los = end_time;
pd.max_elevation = FindMaxElevation(user_geo, sgp4, aos_time, end_time);
pass_list.push_back(pd);
}
return pass_list;
}
bool PassPredict(std::vector<QDateTime>& aos, std::vector<QDateTime>& los, std::string line1, std::string line2, double startTime, double predictDayLen, double lon, double lat, double ati) {
libsgp4::CoordGeodetic geo(lat, lon, ati);
libsgp4::Tle tle("GALILEO-PFM (GSAT0101) ",
line1,
line2);
libsgp4::SGP4 sgp4(tle);
std::vector<QDateTime> result;
// 将 double 时间戳转为 QDateTime
QDateTime dateTime = QDateTime::fromSecsSinceEpoch(static_cast<qint64>(startTime*1000));
libsgp4::DateTime start_date(
dateTime.date().year(),
dateTime.date().month(),
dateTime.date().day(),
dateTime.time().hour(),
dateTime.time().minute(),
dateTime.time().second(),
dateTime.time().msec() * 1000);
libsgp4::DateTime end_date(start_date.AddDays(predictDayLen));
std::list<struct PassDetails> pass_list;
pass_list = GeneratePassList(geo, sgp4, start_date, end_date, 180);
if (pass_list.begin() == pass_list.end())
{
return false;
}
else
{
std::stringstream ss;
ss << std::right << std::setprecision(1) << std::fixed;
std::list<struct PassDetails>::const_iterator itr = pass_list.begin();
do
{
ss << "AOS: " << itr->aos
<< ", LOS: " << itr->los
<< ", Max El: " << std::setw(4) << libsgp4::Util::RadiansToDegrees(itr->max_elevation)
<< ", Duration: " << (itr->los - itr->aos)
<< std::endl;
// 构造AOS时间
QDate aosDate(itr->aos.Year(), itr->aos.Month(), itr->aos.Day());
QTime aosTimePart(itr->aos.Hour(), itr->aos.Minute(), itr->aos.Second(), itr->aos.Microsecond());
QDateTime aosDateTime(aosDate, aosTimePart, Qt::UTC); //
// 构造LOS时间
QDate losDate(itr->los.Year(), itr->los.Month(), itr->los.Day());
QTime losTimePart(itr->los.Hour(), itr->los.Minute(), itr->los.Second(), itr->los.Microsecond());
QDateTime losDateTime(losDate, losTimePart, Qt::UTC); //
aos.push_back(aosDateTime);
los.push_back(losDateTime);
} while (++itr != pass_list.end());
std::cout << ss.str();
return true;
}
return false;
}

178
SPG4Tool/SPG4Function.cpp Normal file
View File

@ -0,0 +1,178 @@
#include "SPG4Function.h"
#include "SPG4Tool.h"
#include <Tle.h>
#include <SGP4.h>
#include <Observer.h>
#include <CoordGeodetic.h>
#include <CoordTopocentric.h>
#include <list>
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <QDate>
#include <QDateTime>
std::vector<SatelliteAntPos> RunTle(libsgp4::Tle tle, double start, double end, double inc, bool printfinfoflag, bool running, bool first_run)
{
std::cout << "RunTle\t" ;
std::cout << "Start time:\t" << start;
std::cout << "End time:\t" << end;
std::cout << "inc time:\t" << inc << std::endl;
std::vector<SatelliteAntPos> resultpos(0);
double current = start;
libsgp4::SGP4 model(tle);
//bool running = true;
//bool first_run = true;
std::cout << std::setprecision(0) << tle.NoradNumber() << " xx"
<< std::endl;
while (running)
{
bool error = false;
libsgp4::Vector position;
libsgp4::Vector velocity;
double tsince;
try
{
if (first_run && current != 0.0)
{
/*
* make sure first run is always as zero
*/
tsince = 0.0;
}
else
{
/*
* otherwise run as normal
*/
tsince = current;
}
libsgp4::Eci eci = model.FindPosition(tsince);
position = eci.Position();
velocity = eci.Velocity();
}
catch (libsgp4::SatelliteException& e)
{
std::cerr << "SatelliteException:\t" << e.what() << std::endl;
error = true;
running = false;
}
catch (libsgp4::DecayedException& e)
{
std::cerr <<"DecayedException:\t" << e.what() << std::endl;
position = e.Position();
velocity = e.Velocity();
if (!first_run)
{
// print out position on first run
error = true;
}
running = false;
}
if (!error)
{
SatelliteAntPos antpos{};
antpos.time = tsince;
antpos.Px = position.x;
antpos.Py = position.y;
antpos.Pz = position.z;
antpos.Vx = velocity.x;
antpos.Vy = velocity.y;
antpos.Vz = velocity.z;
resultpos.push_back(antpos);
if (printfinfoflag) {
std::cout << std::setprecision(8) << std::fixed;
std::cout.width(17);
std::cout << tsince << " ";
std::cout.width(16);
std::cout << position.x << " ";
std::cout.width(16);
std::cout << position.y << " ";
std::cout.width(16);
std::cout << position.z << " ";
std::cout << std::setprecision(9) << std::fixed;
std::cout.width(14);
std::cout << velocity.x << " ";
std::cout.width(14);
std::cout << velocity.y << " ";
std::cout.width(14);
std::cout << velocity.z << std::endl;
}
}
if ((first_run && current == 0.0) || !first_run)
{
if (current == end)
{
running = false;
}
else if ((current + inc) > end)
{
current = end;
}
else
{
current += inc;
}
}
first_run = false;
}
return resultpos;
}
std::vector<SatelliteAntPos> getGPSPoints(std::string line1, std::string line2, double start, double end, double inc, bool printfinfoflag, bool running , bool first_run )
{
libsgp4::Tle tle("satellites", line1, line2);
std::cout << "Start time:\t" << start;
std::cout << "End time:\t" << end;
std::cout << "inc time:\t" << inc << std::endl;
std::vector<SatelliteAntPos> result= RunTle(tle, start, end, inc, printfinfoflag,running,first_run);
return result;
}
double parseTLETimeOffset(const std::string& tle) {
// 假设TLE字符串的时间信息在特定位置
// 例如TLE的第19到32个字符表示纪元时间
if (tle.length() < 32) {
return 0.0;
}
std::string epochStr = tle.substr(18, 14);
int year = std::stoi(epochStr.substr(0, 2));
double dayOfYear = std::stod(epochStr.substr(2));
// 将两位数年份转换为四位数年份
if (year < 57) {
year += 2000;
}
else {
year += 1900;
}
// 计算从纪元开始到指定日期的毫秒数
QDate date(year, 1, 1);
QDateTime dateTime(date.addDays(static_cast<int>(dayOfYear) - 1), QTime(0, 0), Qt::UTC);
qint64 millisecondsSinceEpoch = dateTime.toMSecsSinceEpoch() + static_cast<qint64>((dayOfYear - static_cast<int>(dayOfYear)) * 86400000);
return millisecondsSinceEpoch / 1000.0;
}

29
SPG4Tool/SPG4Function.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#ifndef __SPG4FUNCTION__H__
#define __SPG4FUNCTION__H__
#include "SPG4Tool_global.h"
#include "BaseConstVariable.h"
#include <vector>
#include <QDateTime>
//void RunTle(libsgp4::Tle tle, double start, double end, double inc);
SPG4TOOL_EXPORT double parseTLETimeOffset(const std::string& tle);
/// <summary>
/// 根据两行根数生成坐标与速度,请注意返回的单位是 km
/// </summary>
/// <param name="line1"></param>
/// <param name="line2"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="inc"></param>
/// <param name="printfinfoflag"></param>
/// <param name="running"></param>
/// <param name="first_run"></param>
/// <returns></returns>
SPG4TOOL_EXPORT std::vector<SatelliteAntPos> getGPSPoints(std::string line1, std::string line2, double start, double end, double inc, bool printfinfoflag = false, bool running = true, bool first_run = true);
SPG4TOOL_EXPORT bool PassPredict(std::vector<QDateTime>& aos, std::vector<QDateTime>& los, std::string line1, std::string line2, double startTime, double predictDayLen, double lon, double lat, double ati);
#endif

18
SPG4Tool/SPG4Tool.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <Tle.h>
#include <SGP4.h>
#include <Observer.h>
#include <CoordGeodetic.h>
#include <CoordTopocentric.h>
#include <vector>
#include <list>
#include <string>
#include "BaseConstVariable.h"
#include <Observer.h>
#include <SGP4.h>
#include <Util.h>
#include <CoordTopocentric.h>
#include <CoordGeodetic.h>
std::vector<SatelliteAntPos> RunTle(libsgp4::Tle tle, double start, double end, double inc, bool printfinfoflag, bool running = true, bool first_run = true);

154
SPG4Tool/SPG4Tool.vcxproj Normal file
View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
<QtInstall>tools_qt5</QtInstall>
<QtModules>core</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
<QtInstall>tools_qt5</QtInstall>
<QtModules>core</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<IncludePath>.\libsgp4;..\BaseCommonLibrary\BaseTool;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;SPG4TOOL_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="libsgp4\CoordGeodetic.cc" />
<ClCompile Include="libsgp4\CoordTopocentric.cc" />
<ClCompile Include="libsgp4\DateTime.cc" />
<ClCompile Include="libsgp4\DecayedException.cc" />
<ClCompile Include="libsgp4\Eci.cc" />
<ClCompile Include="libsgp4\Globals.cc" />
<ClCompile Include="libsgp4\Observer.cc" />
<ClCompile Include="libsgp4\OrbitalElements.cc" />
<ClCompile Include="libsgp4\SatelliteException.cc" />
<ClCompile Include="libsgp4\SGP4.cc" />
<ClCompile Include="libsgp4\SolarPosition.cc" />
<ClCompile Include="libsgp4\TimeSpan.cc" />
<ClCompile Include="libsgp4\Tle.cc" />
<ClCompile Include="libsgp4\TleException.cc" />
<ClCompile Include="libsgp4\Util.cc" />
<ClCompile Include="libsgp4\Vector.cc" />
<ClCompile Include="PassPredict.cpp" />
<ClCompile Include="SPG4Toolmain.cpp" />
<ClCompile Include="SPG4Function.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="libsgp4\CoordGeodetic.h" />
<ClInclude Include="libsgp4\CoordTopocentric.h" />
<ClInclude Include="libsgp4\DateTime.h" />
<ClInclude Include="libsgp4\DecayedException.h" />
<ClInclude Include="libsgp4\Eci.h" />
<ClInclude Include="libsgp4\Globals.h" />
<ClInclude Include="libsgp4\Observer.h" />
<ClInclude Include="libsgp4\OrbitalElements.h" />
<ClInclude Include="libsgp4\SatelliteException.h" />
<ClInclude Include="libsgp4\SGP4.h" />
<ClInclude Include="libsgp4\SolarPosition.h" />
<ClInclude Include="libsgp4\TimeSpan.h" />
<ClInclude Include="libsgp4\Tle.h" />
<ClInclude Include="libsgp4\TleException.h" />
<ClInclude Include="libsgp4\Util.h" />
<ClInclude Include="libsgp4\Vector.h" />
<ClInclude Include="SPG4Function.h" />
<ClInclude Include="SPG4Tool.h" />
<ClInclude Include="SPG4Tool_global.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BaseCommonLibrary\BaseCommonLibrary.vcxproj">
<Project>{872ecd6f-30e3-4a1b-b17c-15e87d373ff6}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
<Filter Include="libsgp4">
<UniqueIdentifier>{fd21014a-ae49-484d-bbcf-92b5b994c075}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="SPG4Toolmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="libsgp4\CoordGeodetic.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\CoordTopocentric.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\DateTime.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\DecayedException.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\Eci.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\Globals.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\Observer.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\OrbitalElements.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\SatelliteException.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\SGP4.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\SolarPosition.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\TimeSpan.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\Tle.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\TleException.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\Util.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="libsgp4\Vector.cc">
<Filter>libsgp4</Filter>
</ClCompile>
<ClCompile Include="SPG4Function.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PassPredict.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="libsgp4\CoordGeodetic.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\CoordTopocentric.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\DateTime.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\DecayedException.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\Eci.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\Globals.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\Observer.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\OrbitalElements.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\SatelliteException.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\SGP4.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\SolarPosition.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\TimeSpan.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\Tle.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\TleException.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\Util.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="libsgp4\Vector.h">
<Filter>libsgp4</Filter>
</ClInclude>
<ClInclude Include="SPG4Function.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SPG4Tool_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SPG4Tool.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
#pragma once
#ifndef __SPG4TOOL_GLOBAL__H__
#define __SPG4TOOL_GLOBAL__H__
#include <QtCore/qglobal.h>
#ifdef SPG4TOOL_LIB
#define SPG4TOOL_EXPORT Q_DECL_EXPORT
#else
#define SPG4TOOL_EXPORT Q_DECL_IMPORT
#endif
#endif

38
SPG4Tool/SPG4Toolmain.cpp Normal file
View File

@ -0,0 +1,38 @@
#include <QtCore/QCoreApplication>
#include <iostream>
#include <fstream>
#include "Tle.h"
#include "SGP4.h"
#include "Observer.h"
#include "CoordGeodetic.h"
#include "CoordTopocentric.h"
#include <string>
#include "SPG4Function.h"
#include "SPG4Tool.h"
/**
½̽ËĺÅ01ÐÇÎÀÐǹìµÀ
1 57624U 23120A 25064.58152700 -.00000191 00000-0 00000+0 0 9998
2 57624 15.4792 205.4597 0004587 123.7538 133.1804 1.00272901 5837
*/
//int main(int argc, char *argv[])
//{
//
// std::string line1="1 57624U 23120A 25064.58152700 -.00000191 00000-0 00000+0 0 9998";
// std::string line2="2 57624 15.4792 205.4597 0004587 123.7538 133.1804 1.00272901 5837";
//
// libsgp4::Tle tle("GF3", line1, line2);
//
// double start = 0;
// double end = 1;
// double inc = 1/60.0;
//
// RunTle(tle, start, end, inc,true);
// //QCoreApplication a(argc, argv);
//
// //return a.exec();
//}

View File

@ -0,0 +1,41 @@
set(SRCS
CoordGeodetic.cc
CoordTopocentric.cc
DateTime.cc
DecayedException.cc
Eci.cc
Globals.cc
Observer.cc
OrbitalElements.cc
SGP4.cc
SatelliteException.cc
SolarPosition.cc
TimeSpan.cc
Tle.cc
TleException.cc
Util.cc
Vector.cc)
set(INCS
CoordGeodetic.h
CoordTopocentric.h
DateTime.h
DecayedException.h
Eci.h
Globals.h
Observer.h
OrbitalElements.h
SatelliteException.h
SGP4.h
SolarPosition.h
TimeSpan.h
TleException.h
Tle.h
Util.h
Vector.h
)
add_library(sgp4 STATIC ${SRCS} ${INCS})
add_library(sgp4s SHARED ${SRCS} ${INCS})
install( TARGETS sgp4s LIBRARY DESTINATION lib )
install( FILES ${INCS} DESTINATION include/libsgp4 )

View File

@ -0,0 +1,18 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "CoordGeodetic.h"

View File

@ -0,0 +1,126 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "Util.h"
#include <string>
#include <sstream>
#include <iomanip>
namespace libsgp4
{
/**
* @brief Stores a geodetic location (latitude, longitude, altitude).
*
* Internally the values are stored in radians and kilometres.
*/
struct CoordGeodetic
{
public:
/**
* Default constructor
*/
CoordGeodetic() = default;
/**
* Constructor
* @param[in] lat the latitude (degrees by default)
* @param[in] lon the longitude (degrees by default)
* @param[in] alt the altitude in kilometers
* @param[in] is_radians whether the latitude/longitude is in radians
*/
CoordGeodetic(
double lat,
double lon,
double alt,
bool is_radians = false)
{
if (is_radians)
{
latitude = lat;
longitude = lon;
}
else
{
latitude = Util::DegreesToRadians(lat);
longitude = Util::DegreesToRadians(lon);
}
altitude = alt;
}
/**
* Copy constructor
* @param[in] geo object to copy from
*/
CoordGeodetic(const CoordGeodetic& geo)
{
latitude = geo.latitude;
longitude = geo.longitude;
altitude = geo.altitude;
}
/**
* Assignment operator
* @param[in] geo object to copy from
*/
CoordGeodetic& operator=(const CoordGeodetic& geo)
{
if (this != &geo)
{
latitude = geo.latitude;
longitude = geo.longitude;
altitude = geo.altitude;
}
return *this;
}
/**
* Dump this object to a string
* @returns string
*/
std::string ToString() const
{
std::stringstream ss;
ss << std::right << std::fixed << std::setprecision(3);
ss << "Lat: " << std::setw(8) << Util::RadiansToDegrees(latitude);
ss << ", Lon: " << std::setw(8) << Util::RadiansToDegrees(longitude);
ss << ", Alt: " << std::setw(10) << altitude;
return ss.str();
}
/** latitude in radians (-PI >= latitude < PI) */
double latitude{};
/** latitude in radians (-PI/2 >= latitude <= PI/2) */
double longitude{};
/** altitude in kilometers */
double altitude{};
};
/**
* Dump a Coordgeodetic to a stream
* @param[in,out] strm stream to output to
* @param[in] g the CoordGeodetic to print
*/
inline std::ostream& operator<<(std::ostream& strm, const CoordGeodetic& g)
{
return strm << g.ToString();
}
} // namespace libsgp4

View File

@ -0,0 +1,18 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "CoordTopocentric.h"

View File

@ -0,0 +1,122 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "Util.h"
#include <string>
#include <sstream>
#include <iomanip>
namespace libsgp4
{
/**
* @brief Stores a topocentric location (azimuth, elevation, range and range
* rate).
*
* Azimuth and elevation are stored in radians. Range in kilometres. Range
* rate in kilometres/second.
*/
struct CoordTopocentric
{
public:
/**
* Default constructor
*/
CoordTopocentric() = default;
/**
* Constructor
* @param[in] az azimuth in radians
* @param[in] el elevation in radians
* @param[in] rnge range in kilometers
* @param[in] rnge_rate range rate in kilometers per second
*/
CoordTopocentric(
double az,
double el,
double rnge,
double rnge_rate)
: azimuth(az)
, elevation(el)
, range(rnge)
, range_rate(rnge_rate)
{
}
/**
* Copy constructor
* @param[in] topo object to copy from
*/
CoordTopocentric(const CoordTopocentric& topo)
{
azimuth = topo.azimuth;
elevation = topo.elevation;
range = topo.range;
range_rate = topo.range_rate;
}
/**
* Assignment operator
* @param[in] topo object to copy from
*/
CoordTopocentric& operator=(const CoordTopocentric& topo)
{
if (this != &topo)
{
azimuth = topo.azimuth;
elevation = topo.elevation;
range = topo.range;
range_rate = topo.range_rate;
}
return *this;
}
/**
* Dump this object to a string
* @returns string
*/
std::string ToString() const
{
std::stringstream ss;
ss << std::right << std::fixed << std::setprecision(3);
ss << "Az: " << std::setw(8) << Util::RadiansToDegrees(azimuth);
ss << ", El: " << std::setw(8) << Util::RadiansToDegrees(elevation);
ss << ", Rng: " << std::setw(10) << range;
ss << ", Rng Rt: " << std::setw(7) << range_rate;
return ss.str();
}
/** azimuth in radians */
double azimuth{};
/** elevations in radians */
double elevation{};
/** range in kilometers */
double range{};
/** range rate in kilometers per second */
double range_rate{};
};
inline std::ostream& operator<<(std::ostream& strm, const CoordTopocentric& t)
{
return strm << t.ToString();
}
} // namespace libsgp4

View File

@ -0,0 +1,149 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "DateTime.h"
#if 0
bool jd_dmy(int JD, int c_year, int c_month, int c_day)
{
// For the Gregorian calendar:
int a = JD + 32044;
int b = (4 * a + 3) / 146097;
int c = a - (b * 146097) / 4;
// Then, for both calendars:
int d = (4 * c + 3) / 1461;
int e = c - (1461 * d) / 4;
int m = (5 * e + 2) / 153;
int day = e - (153 * m + 2) / 5 + 1;
int month = m + 3 - 12 * (m / 10);
int year = b * 100 + d - 4800 + m / 10;
if (c_year != year || c_month != month || c_day != day)
{
std::cout << year << " " << month << " " << day << std::endl;
return false;
}
else
{
return true;
}
}
int main()
{
for (int year = 1; year <= 9999; year++)
{
for (int month = 1; month <= 12; month++)
{
for (int day = 1; day <= DateTime::DaysInMonth(year, month); day++)
{
int hour = 23;
int minute = 59;
int second = 59;
int microsecond = 999999;
DateTime dt(year, month, day, hour, minute, second, microsecond);
if (dt.Year() != year ||
dt.Month() != month ||
dt.Day() != day ||
dt.Hour() != hour ||
dt.Minute() != minute ||
dt.Second() != second ||
dt.Microsecond() != microsecond)
{
std::cout << "failed" << std::endl;
std::cout << "Y " << dt.Year() << " " << year << std::endl;
std::cout << "M " << dt.Month() << " " << month << std::endl;
std::cout << "D " << dt.Day() << " " << day << std::endl;
std::cout << "H " << dt.Hour() << " " << hour << std::endl;
std::cout << "M " << dt.Minute() << " " << minute << std::endl;
std::cout << "S " << dt.Second() << " " << second << std::endl;
std::cout << "F " << dt.Microsecond() << " " << microsecond << std::endl;
return 0;
}
if (!jd_dmy(dt.Julian() + 0.5, year, month, day))
{
std::cout << "julian" << std::endl;
return 0;
}
}
}
}
for (int hour = 1; hour < 24; hour++)
{
std::cout << hour << std::endl;
for (int minute = 0; minute < 60; minute++)
{
for (int second = 0; second < 60; second++)
{
for (int microsecond = 0; microsecond < 1000000; microsecond += 10000)
{
int year = 1000;
int month = 10;
int day = 23;
DateTime dt(year, month, day, hour, minute, second, microsecond);
if (dt.Year() != year ||
dt.Month() != month ||
dt.Day() != day ||
dt.Hour() != hour ||
dt.Minute() != minute ||
dt.Second() != second ||
dt.Microsecond() != microsecond)
{
std::cout << "failed" << std::endl;
std::cout << "Y " << dt.Year() << " " << year << std::endl;
std::cout << "M " << dt.Month() << " " << month << std::endl;
std::cout << "D " << dt.Day() << " " << day << std::endl;
std::cout << "H " << dt.Hour() << " " << hour << std::endl;
std::cout << "M " << dt.Minute() << " " << minute << std::endl;
std::cout << "S " << dt.Second() << " " << second << std::endl;
std::cout << "F " << dt.Microsecond() << " " << microsecond << std::endl;
return 0;
}
}
}
}
}
jd_dmy(1721425.5, 0, 0, 0);
DateTime d1(1000, 1, 1);
DateTime d2(2000, 1, 1);
DateTime d3(4000, 1, 1);
DateTime d4(6000, 1, 1);
DateTime d5(8000, 1, 1);
std::cout << std::setprecision(20);
std::cout << d1.Julian() << std::endl;
std::cout << d2.Julian() << std::endl;
std::cout << d3.Julian() << std::endl;
std::cout << d4.Julian() << std::endl;
std::cout << d5.Julian() << std::endl;
return 0;
}
#endif

721
SPG4Tool/libsgp4/DateTime.h Normal file
View File

@ -0,0 +1,721 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <iomanip>
#include <iostream>
#include <sstream>
#include <chrono>
#include <algorithm>
#include <cassert>
#include "TimeSpan.h"
#include "Util.h"
namespace libsgp4
{
namespace
{
static int daysInMonth[2][13] = {
// 1 2 3 4 5 6 7 8 9 10 11 12
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
static int cumulDaysInMonth[2][13] = {
// 1 2 3 4 5 6 7 8 9 10 11 12
{0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
};
}
/**
* @brief Represents an instance in time.
*/
class DateTime
{
public:
/**
* Default contructor
* Initialise to 0001/01/01 00:00:00.000000
*/
DateTime()
{
Initialise(1, 1, 1, 0, 0, 0, 0);
}
/**
* Constructor
* @param[in] ticks raw tick value
*/
explicit DateTime(int64_t ticks)
: m_encoded(ticks)
{
}
/**
* Constructor
* @param[in] year the year
* @param[in] doy the day of the year
*/
DateTime(unsigned int year, double doy)
{
m_encoded = TimeSpan(
static_cast<int64_t>(AbsoluteDays(year, doy) * TicksPerDay)).Ticks();
}
/**
* Constructor
* @param[in] year the year
* @param[in] month the month
* @param[in] day the day
*/
DateTime(int year, int month, int day)
{
Initialise(year, month, day, 0, 0, 0, 0);
}
/**
* Constructor
* @param[in] year the year
* @param[in] month the month
* @param[in] day the day
* @param[in] hour the hour
* @param[in] minute the minute
* @param[in] second the second
*/
DateTime(int year, int month, int day, int hour, int minute, int second)
{
Initialise(year, month, day, hour, minute, second, 0);
}
/**
* Constructor
* @param[in] year the year
* @param[in] month the month
* @param[in] day the day
* @param[in] hour the hour
* @param[in] minute the minute
* @param[in] second the second
* @param[in] microsecond the microsecond
*/
DateTime(int year, int month, int day, int hour, int minute, int second, int microsecond)
{
Initialise(year, month, day, hour, minute, second, microsecond);
}
/**
* Initialise to the given data and time.
* @param[in] year the year
* @param[in] month the month
* @param[in] day the day
* @param[in] hour the hour
* @param[in] minute the minute
* @param[in] second the second
* @param[in] microsecond the microsecond
*/
void Initialise(int year,
int month,
int day,
int hour,
int minute,
int second,
int microsecond)
{
if (!IsValidYearMonthDay(year, month, day) ||
hour < 0 || hour > 23 ||
minute < 0 || minute > 59 ||
second < 0 || second > 59 ||
microsecond < 0 || microsecond > 999999)
{
assert(false && "Invalid date");
}
m_encoded = TimeSpan(
AbsoluteDays(year, month, day),
hour,
minute,
second,
microsecond).Ticks();
}
/**
* Return the current time
* @param[in] microseconds whether to set the microsecond component
* @returns a DateTime object set to the current date and time
*/
static DateTime Now(bool useMicroseconds = false)
{
using namespace std::chrono;
if (useMicroseconds)
{
return DateTime(UnixEpoch +
duration_cast<microseconds>(system_clock::now()
.time_since_epoch()).count() * TicksPerMicrosecond);
}
else
{
return DateTime(UnixEpoch +
duration_cast<seconds>(system_clock::now()
.time_since_epoch()).count() * TicksPerSecond);
}
}
/**
* Find whether a year is a leap year
* @param[in] year the year to check
* @returns whether the year is a leap year
*/
static bool IsLeapYear(int year)
{
if (!IsValidYear(year))
{
assert(false && "Invalid year");
}
return (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0);
}
/**
* Checks whether the given year is valid
* @param[in] year the year to check
* @returns whether the year is valid
*/
static bool IsValidYear(int year)
{
bool valid = true;
if (year < 1 || year > 9999)
{
valid = false;
}
return valid;
}
/**
* Check whether the year/month is valid
* @param[in] year the year to check
* @param[in] month the month to check
* @returns whether the year/month is valid
*/
static bool IsValidYearMonth(int year, int month)
{
bool valid = true;
if (IsValidYear(year))
{
if (month < 1 || month > 12)
{
valid = false;
}
}
else
{
valid = false;
}
return valid;
}
/**
* Check whether the year/month/day is valid
* @param[in] year the year to check
* @param[in] month the month to check
* @param[in] day the day to check
* @returns whether the year/month/day is valid
*/
static bool IsValidYearMonthDay(int year, int month, int day)
{
bool valid = true;
if (IsValidYearMonth(year, month))
{
if (day < 1 || day > DaysInMonth(year, month))
{
valid = false;
}
}
else
{
valid = false;
}
return valid;
}
/**
* Find the number of days in a month given the year/month
* @param[in] year the year
* @param[in] month the month
* @returns the days in the given month
*/
static int DaysInMonth(int year, int month)
{
if (!IsValidYearMonth(year, month))
{
assert(false && "Invalid year and month");
}
const int* daysInMonthPtr;
if (IsLeapYear(year))
{
daysInMonthPtr = daysInMonth[1];
}
else
{
daysInMonthPtr = daysInMonth[0];
}
return daysInMonthPtr[month];
}
/**
* Find the day of the year given the year/month/day
* @param[in] year the year
* @param[in] month the month
* @param[in] day the day
* @returns the day of the year
*/
int DayOfYear(int year, int month, int day) const
{
if (!IsValidYearMonthDay(year, month, day))
{
assert(false && "Invalid year, month and day");
}
int daysThisYear = day;
if (IsLeapYear(year))
{
daysThisYear += cumulDaysInMonth[1][month];
}
else
{
daysThisYear += cumulDaysInMonth[0][month];
}
return daysThisYear;
}
/**
*
*/
double AbsoluteDays(unsigned int year, double doy) const
{
int64_t previousYear = year - 1;
/*
* + days in previous years ignoring leap days
* + Julian leap days before this year
* - minus prior century years
* + plus prior years divisible by 400 days
*/
int64_t daysSoFar = 365 * previousYear
+ previousYear / 4LL
- previousYear / 100LL
+ previousYear / 400LL;
return static_cast<double>(daysSoFar) + doy - 1.0;
}
int AbsoluteDays(int year, int month, int day) const
{
int previousYear = year - 1;
/*
* days this year (0 - ...)
* + days in previous years ignoring leap days
* + Julian leap days before this year
* - minus prior century years
* + plus prior years divisible by 400 days
*/
int result = DayOfYear(year, month, day) - 1
+ 365 * previousYear
+ previousYear / 4
- previousYear / 100
+ previousYear / 400;
return result;
}
TimeSpan TimeOfDay() const
{
return TimeSpan(Ticks() % TicksPerDay);
}
int DayOfWeek() const
{
/*
* The fixed day 1 (January 1, 1 Gregorian) is Monday.
* 0 Sunday
* 1 Monday
* 2 Tuesday
* 3 Wednesday
* 4 Thursday
* 5 Friday
* 6 Saturday
*/
return static_cast<int>(((m_encoded / TicksPerDay) + 1LL) % 7LL);
}
bool Equals(const DateTime& dt) const
{
return (m_encoded == dt.m_encoded);
}
int Compare(const DateTime& dt) const
{
int ret = 0;
if (m_encoded < dt.m_encoded)
{
return -1;
}
else if (m_encoded > dt.m_encoded)
{
return 1;
}
return ret;
}
DateTime AddYears(const int years) const
{
return AddMonths(years * 12);
}
DateTime AddMonths(const int months) const
{
int year;
int month;
int day;
FromTicks(year, month, day);
month += months % 12;
year += months / 12;
if (month < 1)
{
month += 12;
--year;
}
else if (month > 12)
{
month -= 12;
++year;
}
int maxday = DaysInMonth(year, month);
day = std::min(day, maxday);
return DateTime(year, month, day).Add(TimeOfDay());
}
/**
* Add a TimeSpan to this DateTime
* @param[in] t the TimeSpan to add
* @returns a DateTime which has the given TimeSpan added
*/
DateTime Add(const TimeSpan& t) const
{
return AddTicks(t.Ticks());
}
DateTime AddDays(const double days) const
{
return AddMicroseconds(days * 86400000000.0);
}
DateTime AddHours(const double hours) const
{
return AddMicroseconds(hours * 3600000000.0);
}
DateTime AddMinutes(const double minutes) const
{
return AddMicroseconds(minutes * 60000000.0);
}
DateTime AddSeconds(const double seconds) const
{
return AddMicroseconds(seconds * 1000000.0);
}
DateTime AddMicroseconds(const double microseconds) const
{
auto ticks = static_cast<int64_t>(microseconds * TicksPerMicrosecond);
return AddTicks(ticks);
}
DateTime AddTicks(int64_t ticks) const
{
return DateTime(m_encoded + ticks);
}
/**
* Get the number of ticks
* @returns the number of ticks
*/
int64_t Ticks() const
{
return m_encoded;
}
void FromTicks(int& year, int& month, int& day) const
{
int totalDays = static_cast<int>(m_encoded / TicksPerDay);
/*
* number of 400 year cycles
*/
int num400 = totalDays / 146097;
totalDays -= num400 * 146097;
/*
* number of 100 year cycles
*/
int num100 = totalDays / 36524;
if (num100 == 4)
{
/*
* last day of the last leap century
*/
num100 = 3;
}
totalDays -= num100 * 36524;
/*
* number of 4 year cycles
*/
int num4 = totalDays / 1461;
totalDays -= num4 * 1461;
/*
* number of years
*/
int num1 = totalDays / 365;
if (num1 == 4)
{
/*
* last day of the last leap olympiad
*/
num1 = 3;
}
totalDays -= num1 * 365;
/*
* find year
*/
year = (num400 * 400) + (num100 * 100) + (num4 * 4) + num1 + 1;
/*
* convert day of year to month/day
*/
const int* daysInMonthPtr;
if (IsLeapYear(year))
{
daysInMonthPtr = daysInMonth[1];
}
else
{
daysInMonthPtr = daysInMonth[0];
}
month = 1;
while (totalDays >= daysInMonthPtr[month] && month <= 12)
{
totalDays -= daysInMonthPtr[month++];
}
day = totalDays + 1;
}
int Year() const
{
int year;
int month;
int day;
FromTicks(year, month, day);
return year;
}
int Month() const
{
int year;
int month;
int day;
FromTicks(year, month, day);
return month;
}
int Day() const
{
int year;
int month;
int day;
FromTicks(year, month, day);
return day;
}
/**
* Hour component
* @returns the hour component
*/
int Hour() const
{
return static_cast<int>(m_encoded % TicksPerDay / TicksPerHour);
}
/**
* Minute component
* @returns the minute component
*/
int Minute() const
{
return static_cast<int>(m_encoded % TicksPerHour / TicksPerMinute);
}
/**
* Second component
* @returns the Second component
*/
int Second() const
{
return static_cast<int>(m_encoded % TicksPerMinute / TicksPerSecond);
}
/**
* Microsecond component
* @returns the microsecond component
*/
int Microsecond() const
{
return static_cast<int>(m_encoded % TicksPerSecond / TicksPerMicrosecond);
}
/**
* Convert to a julian date
* @returns the julian date
*/
double ToJulian() const
{
auto ts = TimeSpan(Ticks());
return ts.TotalDays() + 1721425.5;
}
/**
* Convert to greenwich sidereal time
* @returns the greenwich sidereal time
*/
double ToGreenwichSiderealTime() const
{
// julian date of previous midnight
double jd0 = floor(ToJulian() + 0.5) - 0.5;
// julian centuries since epoch
double t = (jd0 - 2451545.0) / 36525.0;
double jdf = ToJulian() - jd0;
double gt = 24110.54841 + t * (8640184.812866 + t * (0.093104 - t * 6.2E-6));
gt += jdf * 1.00273790935 * 86400.0;
// 360.0 / 86400.0 = 1.0 / 240.0
return Util::WrapTwoPI(Util::DegreesToRadians(gt / 240.0));
}
/**
* Return the modified julian date since the j2000 epoch
* January 1, 2000, at 12:00 TT
* @returns the modified julian date
*/
double ToJ2000() const
{
return ToJulian() - 2415020.0;
}
/**
* Convert to local mean sidereal time (GMST plus the observer's longitude)
* @param[in] lon observers longitude
* @returns the local mean sidereal time
*/
double ToLocalMeanSiderealTime(const double lon) const
{
return Util::WrapTwoPI(ToGreenwichSiderealTime() + lon);
}
std::string ToString() const
{
std::stringstream ss;
int year;
int month;
int day;
FromTicks(year, month, day);
ss << std::right << std::setfill('0');
ss << std::setw(4) << year << "-";
ss << std::setw(2) << month << "-";
ss << std::setw(2) << day << " ";
ss << std::setw(2) << Hour() << ":";
ss << std::setw(2) << Minute() << ":";
ss << std::setw(2) << Second() << ".";
ss << std::setw(6) << Microsecond() << " UTC";
return ss.str();
}
private:
int64_t m_encoded{};
};
inline std::ostream& operator<<(std::ostream& strm, const DateTime& dt)
{
return strm << dt.ToString();
}
inline DateTime operator+(const DateTime& dt, TimeSpan ts)
{
return DateTime(dt.Ticks() + ts.Ticks());
}
inline DateTime operator-(const DateTime& dt, const TimeSpan& ts)
{
return DateTime(dt.Ticks() - ts.Ticks());
}
inline TimeSpan operator-(const DateTime& dt1, const DateTime& dt2)
{
return TimeSpan(dt1.Ticks() - dt2.Ticks());
}
inline bool operator==(const DateTime& dt1, const DateTime& dt2)
{
return dt1.Equals(dt2);
}
inline bool operator>(const DateTime& dt1, const DateTime& dt2)
{
return (dt1.Compare(dt2) > 0);
}
inline bool operator>=(const DateTime& dt1, const DateTime& dt2)
{
return (dt1.Compare(dt2) >= 0);
}
inline bool operator!=(const DateTime& dt1, const DateTime& dt2)
{
return !dt1.Equals(dt2);
}
inline bool operator<(const DateTime& dt1, const DateTime& dt2)
{
return (dt1.Compare(dt2) < 0);
}
inline bool operator<=(const DateTime& dt1, const DateTime& dt2)
{
return (dt1.Compare(dt2) <= 0);
}
} // namespace libsgp4

View File

@ -0,0 +1 @@
#include "DecayedException.h"

View File

@ -0,0 +1,79 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "DateTime.h"
#include "Vector.h"
#include <stdexcept>
#include <string>
namespace libsgp4
{
/**
* @brief The exception that the SGP4 class throws when a satellite decays.
*/
class DecayedException : public std::runtime_error
{
public:
/**
* Constructor
* @param[in] dt time of the event
* @param[in] pos position of the satellite at dt
* @param[in] vel velocity of the satellite at dt
*/
DecayedException(const DateTime& dt, const Vector& pos, const Vector& vel)
: runtime_error("Satellite decayed")
, _dt(dt)
, _pos(pos)
, _vel(vel)
{
}
/**
* @returns the date
*/
DateTime Decayed() const
{
return _dt;
}
/**
* @returns the position
*/
Vector Position() const
{
return _pos;
}
/**
* @returns the velocity
*/
Vector Velocity() const
{
return _vel;
}
private:
DateTime _dt;
Vector _pos;
Vector _vel;
};
} // namespace libsgp4

111
SPG4Tool/libsgp4/Eci.cc Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Eci.h"
#include "Globals.h"
#include "Util.h"
namespace libsgp4
{
/**
* Converts a DateTime and Geodetic position to Eci coordinates
* @param[in] dt the date
* @param[in] geo the geodetic position
*/
void Eci::ToEci(const DateTime& dt, const CoordGeodetic &geo)
{
/*
* set date
*/
m_dt = dt;
static const double mfactor = kTWOPI * (kOMEGA_E / kSECONDS_PER_DAY);
/*
* Calculate Local Mean Sidereal Time for observers longitude
*/
const double theta = m_dt.ToLocalMeanSiderealTime(geo.longitude);
/*
* take into account earth flattening
*/
const double c = 1.0
/ sqrt(1.0 + kF * (kF - 2.0) * pow(sin(geo.latitude), 2.0));
const double s = pow(1.0 - kF, 2.0) * c;
const double achcp = (kXKMPER * c + geo.altitude) * cos(geo.latitude);
/*
* X position in km
* Y position in km
* Z position in km
* W magnitude in km
*/
m_position.x = achcp * cos(theta);
m_position.y = achcp * sin(theta);
m_position.z = (kXKMPER * s + geo.altitude) * sin(geo.latitude);
m_position.w = m_position.Magnitude();
/*
* X velocity in km/s
* Y velocity in km/s
* Z velocity in km/s
* W magnitude in km/s
*/
m_velocity.x = -mfactor * m_position.y;
m_velocity.y = mfactor * m_position.x;
m_velocity.z = 0.0;
m_velocity.w = m_velocity.Magnitude();
}
/**
* @returns the position in geodetic form
*/
CoordGeodetic Eci::ToGeodetic() const
{
const double theta = Util::AcTan(m_position.y, m_position.x);
const double lon = Util::WrapNegPosPI(theta
- m_dt.ToGreenwichSiderealTime());
const double r = sqrt((m_position.x * m_position.x)
+ (m_position.y * m_position.y));
static const double e2 = kF * (2.0 - kF);
double lat = Util::AcTan(m_position.z, r);
double phi = 0.0;
double c = 0.0;
int cnt = 0;
do
{
phi = lat;
const double sinphi = sin(phi);
c = 1.0 / sqrt(1.0 - e2 * sinphi * sinphi);
lat = Util::AcTan(m_position.z + kXKMPER * c * e2 * sinphi, r);
cnt++;
}
while (fabs(lat - phi) >= 1e-10 && cnt < 10);
const double alt = r / cos(lat) - kXKMPER * c;
return CoordGeodetic(lat, lon, alt, true);
}
} // namespace libsgp4

146
SPG4Tool/libsgp4/Eci.h Normal file
View File

@ -0,0 +1,146 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "CoordGeodetic.h"
#include "Vector.h"
#include "DateTime.h"
namespace libsgp4
{
/**
* @brief Stores an Earth-centered inertial position for a particular time.
*/
class Eci
{
public:
/**
* @param[in] dt the date to be used for this position
* @param[in] latitude the latitude in degrees
* @param[in] longitude the longitude in degrees
* @param[in] altitude the altitude in kilometers
*/
Eci(const DateTime& dt,
const double latitude,
const double longitude,
const double altitude)
{
ToEci(dt, CoordGeodetic(latitude, longitude, altitude));
}
/**
* @param[in] dt the date to be used for this position
* @param[in] geo the position
*/
Eci(const DateTime& dt, const CoordGeodetic& geo)
{
ToEci(dt, geo);
}
/**
* @param[in] dt the date to be used for this position
* @param[in] position the position
*/
Eci(const DateTime &dt, const Vector &position)
: m_dt(dt)
, m_position(position)
{
}
/**
* @param[in] dt the date to be used for this position
* @param[in] position the position
* @param[in] velocity the velocity
*/
Eci(const DateTime &dt, const Vector &position, const Vector &velocity)
: m_dt(dt)
, m_position(position)
, m_velocity(velocity)
{
}
/**
* Equality operator
* @param dt the date to compare
* @returns true if the object matches
*/
bool operator==(const DateTime& dt) const
{
return m_dt == dt;
}
/**
* Inequality operator
* @param dt the date to compare
* @returns true if the object doesn't match
*/
bool operator!=(const DateTime& dt) const
{
return m_dt != dt;
}
/**
* Update this object with a new date and geodetic position
* @param dt new date
* @param geo new geodetic position
*/
void Update(const DateTime& dt, const CoordGeodetic& geo)
{
ToEci(dt, geo);
}
/**
* @returns the position
*/
Vector Position() const
{
return m_position;
}
/**
* @returns the velocity
*/
Vector Velocity() const
{
return m_velocity;
}
/**
* @returns the date
*/
DateTime GetDateTime() const
{
return m_dt;
}
/**
* @returns the position in geodetic form
*/
CoordGeodetic ToGeodetic() const;
private:
void ToEci(const DateTime& dt, const CoordGeodetic& geo);
DateTime m_dt;
Vector m_position;
Vector m_velocity;
};
} // namespace libsgp4

View File

@ -0,0 +1,18 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Globals.h"

View File

@ -0,0 +1,77 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cmath>
namespace libsgp4
{
const double kAE = 1.0;
const double kQ0 = 120.0;
const double kS0 = 78.0;
const double kMU = 398600.8;
const double kXKMPER = 6378.135;
const double kXJ2 = 1.082616e-3;
const double kXJ3 = -2.53881e-6;
const double kXJ4 = -1.65597e-6;
/*
* alternative XKE
* affects final results
* aiaa-2006-6573
* const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
* dundee
* const double kXKE = 7.43669161331734132e-2;
*/
const double kXKE = 60.0 / sqrt(kXKMPER * kXKMPER * kXKMPER / kMU);
const double kCK2 = 0.5 * kXJ2 * kAE * kAE;
const double kCK4 = -0.375 * kXJ4 * kAE * kAE * kAE * kAE;
/*
* alternative QOMS2T
* affects final results
* aiaa-2006-6573
* #define QOMS2T (pow(((Q0 - S0) / XKMPER), 4.0))
* dundee
* #define QOMS2T (1.880279159015270643865e-9)
*/
const double kQOMS2T = pow(((kQ0 - kS0) / kXKMPER), 4.0);
const double kS = kAE * (1.0 + kS0 / kXKMPER);
const double kPI = 3.14159265358979323846264338327950288419716939937510582;
const double kTWOPI = 2.0 * kPI;
const double kTWOTHIRD = 2.0 / 3.0;
const double kTHDT = 4.37526908801129966e-3;
/*
* earth flattening
*/
const double kF = 1.0 / 298.26;
/*
* earth rotation per sideral day
*/
const double kOMEGA_E = 1.00273790934;
const double kAU = 1.49597870691e8;
const double kSECONDS_PER_DAY = 86400.0;
const double kMINUTES_PER_DAY = 1440.0;
const double kHOURS_PER_DAY = 24.0;
const double kA3OVK2 = -kXJ3 / kCK2 * kAE * kAE * kAE;
} // namespace libsgp4

View File

@ -0,0 +1,86 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Observer.h"
#include "CoordTopocentric.h"
namespace libsgp4
{
/*
* calculate lookangle between the observer and the passed in Eci object
*/
CoordTopocentric Observer::GetLookAngle(const Eci &eci)
{
/*
* update the observers Eci to match the time of the Eci passed in
* if necessary
*/
Update(eci.GetDateTime());
/*
* calculate differences
*/
Vector range_rate = eci.Velocity() - m_eci.Velocity();
Vector range = eci.Position() - m_eci.Position();
range.w = range.Magnitude();
/*
* Calculate Local Mean Sidereal Time for observers longitude
*/
double theta = eci.GetDateTime().ToLocalMeanSiderealTime(m_geo.longitude);
double sin_lat = sin(m_geo.latitude);
double cos_lat = cos(m_geo.latitude);
double sin_theta = sin(theta);
double cos_theta = cos(theta);
double top_s = sin_lat * cos_theta * range.x
+ sin_lat * sin_theta * range.y - cos_lat * range.z;
double top_e = -sin_theta * range.x
+ cos_theta * range.y;
double top_z = cos_lat * cos_theta * range.x
+ cos_lat * sin_theta * range.y + sin_lat * range.z;
double az = atan(-top_e / top_s);
if (top_s > 0.0)
{
az += kPI;
}
if (az < 0.0)
{
az += 2.0 * kPI;
}
double el = asin(top_z / range.w);
double rate = range.Dot(range_rate) / range.w;
/*
* azimuth in radians
* elevation in radians
* range in km
* range rate in km/s
*/
return CoordTopocentric(az,
el,
range.w,
rate);
}
} // namespace libsgp4

103
SPG4Tool/libsgp4/Observer.h Normal file
View File

@ -0,0 +1,103 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "CoordGeodetic.h"
#include "Eci.h"
namespace libsgp4
{
class DateTime;
struct CoordTopocentric;
/**
* @brief Stores an observers location in Eci coordinates.
*/
class Observer
{
public:
/**
* Constructor
* @param[in] latitude observers latitude in degrees
* @param[in] longitude observers longitude in degrees
* @param[in] altitude observers altitude in kilometers
*/
Observer(const double latitude,
const double longitude,
const double altitude)
: m_geo(latitude, longitude, altitude)
, m_eci(DateTime(), m_geo)
{
}
/**
* Constructor
* @param[in] geo the observers position
*/
explicit Observer(const CoordGeodetic &geo)
: m_geo(geo)
, m_eci(DateTime(), geo)
{
}
/**
* Set the observers location
* @param[in] geo the observers position
*/
void SetLocation(const CoordGeodetic& geo)
{
m_geo = geo;
m_eci.Update(m_eci.GetDateTime(), m_geo);
}
/**
* Get the observers location
* @returns the observers position
*/
CoordGeodetic GetLocation() const
{
return m_geo;
}
/**
* Get the look angle for the observers position to the object
* @param[in] eci the object to find the look angle to
* @returns the lookup angle
*/
CoordTopocentric GetLookAngle(const Eci &eci);
private:
/**
* @param[in] dt the date to update the observers position for
*/
void Update(const DateTime &dt)
{
if (m_eci != dt)
{
m_eci.Update(dt, m_geo);
}
}
/** the observers position */
CoordGeodetic m_geo;
/** the observers Eci for a particular time */
Eci m_eci;
};
} // namespace libsgp4

View File

@ -0,0 +1,70 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "OrbitalElements.h"
#include "Tle.h"
namespace libsgp4
{
OrbitalElements::OrbitalElements(const Tle& tle)
{
/*
* extract and format tle data
*/
mean_anomoly_ = tle.MeanAnomaly(false);
ascending_node_ = tle.RightAscendingNode(false);
argument_perigee_ = tle.ArgumentPerigee(false);
eccentricity_ = tle.Eccentricity();
inclination_ = tle.Inclination(false);
mean_motion_ = tle.MeanMotion() * kTWOPI / kMINUTES_PER_DAY;
bstar_ = tle.BStar();
epoch_ = tle.Epoch();
/*
* recover original mean motion (xnodp) and semimajor axis (aodp)
* from input elements
*/
const double a1 = pow(kXKE / MeanMotion(), kTWOTHIRD);
const double cosio = cos(Inclination());
const double theta2 = cosio * cosio;
const double x3thm1 = 3.0 * theta2 - 1.0;
const double eosq = Eccentricity() * Eccentricity();
const double betao2 = 1.0 - eosq;
const double betao = sqrt(betao2);
const double temp = (1.5 * kCK2) * x3thm1 / (betao * betao2);
const double del1 = temp / (a1 * a1);
const double a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
const double del0 = temp / (a0 * a0);
recovered_mean_motion_ = MeanMotion() / (1.0 + del0);
/*
* alternative way to calculate
* doesnt affect final results
* recovered_semi_major_axis_ = pow(XKE / RecoveredMeanMotion(), TWOTHIRD);
*/
recovered_semi_major_axis_ = a0 / (1.0 - del0);
/*
* find perigee and period
*/
perigee_ = (RecoveredSemiMajorAxis() * (1.0 - Eccentricity()) - kAE) * kXKMPER;
period_ = kTWOPI / RecoveredMeanMotion();
}
} // namespace libsgp4

View File

@ -0,0 +1,147 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "Util.h"
#include "DateTime.h"
namespace libsgp4
{
class Tle;
/**
* @brief The extracted orbital elements used by the SGP4 propagator.
*/
class OrbitalElements
{
public:
explicit OrbitalElements(const Tle& tle);
/*
* XMO
*/
double MeanAnomoly() const
{
return mean_anomoly_;
}
/*
* XNODEO
*/
double AscendingNode() const
{
return ascending_node_;
}
/*
* OMEGAO
*/
double ArgumentPerigee() const
{
return argument_perigee_;
}
/*
* EO
*/
double Eccentricity() const
{
return eccentricity_;
}
/*
* XINCL
*/
double Inclination() const
{
return inclination_;
}
/*
* XNO
*/
double MeanMotion() const
{
return mean_motion_;
}
/*
* BSTAR
*/
double BStar() const
{
return bstar_;
}
/*
* AODP
*/
double RecoveredSemiMajorAxis() const
{
return recovered_semi_major_axis_;
}
/*
* XNODP
*/
double RecoveredMeanMotion() const
{
return recovered_mean_motion_;
}
/*
* PERIGE
*/
double Perigee() const
{
return perigee_;
}
/*
* Period in minutes
*/
double Period() const
{
return period_;
}
/*
* EPOCH
*/
DateTime Epoch() const
{
return epoch_;
}
private:
double mean_anomoly_;
double ascending_node_;
double argument_perigee_;
double eccentricity_;
double inclination_;
double mean_motion_;
double bstar_;
double recovered_semi_major_axis_;
double recovered_mean_motion_;
double perigee_;
double period_;
DateTime epoch_;
};
} // namespace libsgp4

1353
SPG4Tool/libsgp4/SGP4.cc Normal file

File diff suppressed because it is too large Load Diff

260
SPG4Tool/libsgp4/SGP4.h Normal file
View File

@ -0,0 +1,260 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "Tle.h"
#include "OrbitalElements.h"
#include "Eci.h"
#include "SatelliteException.h"
#include "DecayedException.h"
namespace libsgp4
{
/**
* @mainpage
*
* This documents the SGP4 tracking library.
*/
/**
* @brief The simplified perturbations model 4 propagater.
*/
class SGP4
{
public:
explicit SGP4(const Tle& tle)
: elements_(tle)
{
Initialise();
}
void SetTle(const Tle& tle);
Eci FindPosition(double tsince) const;
Eci FindPosition(const DateTime& date) const;
private:
struct CommonConstants
{
double cosio;
double sinio;
double eta;
double t2cof;
double x1mth2;
double x3thm1;
double x7thm1;
double aycof;
double xlcof;
double xnodcf;
double c1;
double c4;
double omgdot; // secular rate of omega (radians/sec)
double xnodot; // secular rate of xnode (radians/sec)
double xmdot; // secular rate of xmo (radians/sec)
};
struct NearSpaceConstants
{
double c5;
double omgcof;
double xmcof;
double delmo;
double sinmo;
double d2;
double d3;
double d4;
double t3cof;
double t4cof;
double t5cof;
};
struct DeepSpaceConstants
{
double gsto;
double zmol;
double zmos;
/*
* lunar / solar constants for epoch
* applied during DeepSpaceSecular()
*/
double sse;
double ssi;
double ssl;
double ssg;
double ssh;
/*
* lunar / solar constants
* used during DeepSpaceCalculateLunarSolarTerms()
*/
double se2;
double si2;
double sl2;
double sgh2;
double sh2;
double se3;
double si3;
double sl3;
double sgh3;
double sh3;
double sl4;
double sgh4;
double ee2;
double e3;
double xi2;
double xi3;
double xl2;
double xl3;
double xl4;
double xgh2;
double xgh3;
double xgh4;
double xh2;
double xh3;
/*
* used during DeepSpaceCalcDotTerms()
*/
double d2201;
double d2211;
double d3210;
double d3222;
double d4410;
double d4422;
double d5220;
double d5232;
double d5421;
double d5433;
double del1;
double del2;
double del3;
/*
* integrator constants
*/
double xfact;
double xlamo;
enum TOrbitShape
{
NONE,
RESONANCE,
SYNCHRONOUS
} shape;
};
struct IntegratorParams
{
/*
* integrator values
*/
double xli;
double xni;
double atime;
};
void Initialise();
static void RecomputeConstants(const double xinc,
double& sinio,
double& cosio,
double& x3thm1,
double& x1mth2,
double& x7thm1,
double& xlcof,
double& aycof);
Eci FindPositionSDP4(const double tsince) const;
Eci FindPositionSGP4(double tsince) const;
static Eci CalculateFinalPositionVelocity(
const DateTime& date,
const double e,
const double a,
const double omega,
const double xl,
const double xnode,
const double xinc,
const double xlcof,
const double aycof,
const double x3thm1,
const double x1mth2,
const double x7thm1,
const double cosio,
const double sinio);
/**
* Deep space initialisation
*/
void DeepSpaceInitialise(
const double eosq,
const double sinio,
const double cosio,
const double betao,
const double theta2,
const double betao2,
const double xmdot,
const double omgdot,
const double xnodot);
/**
* Calculate lunar / solar periodics and apply
*/
static void DeepSpacePeriodics(
const double tsince,
const DeepSpaceConstants& ds_constants,
double& em,
double& xinc,
double& omgasm,
double& xnodes,
double& xll);
/**
* Deep space secular effects
*/
static void DeepSpaceSecular(
const double tsince,
const OrbitalElements& elements,
const CommonConstants& c_constants,
const DeepSpaceConstants& ds_constants,
IntegratorParams& integ_params,
double& xll,
double& omgasm,
double& xnodes,
double& em,
double& xinc,
double& xn);
/**
* Reset
*/
void Reset();
/*
* the constants used
*/
struct CommonConstants common_consts_;
struct NearSpaceConstants nearspace_consts_;
struct DeepSpaceConstants deepspace_consts_;
mutable struct IntegratorParams integrator_params_;
/*
* the orbit data
*/
OrbitalElements elements_;
/*
* flags
*/
bool use_simple_model_;
bool use_deep_space_;
};
} // namespace libsgp4

View File

@ -0,0 +1 @@
#include "SatelliteException.h"

View File

@ -0,0 +1,38 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdexcept>
#include <string>
namespace libsgp4
{
/**
* @brief The exception that the SGP4 class throws upon an error.
*/
class SatelliteException : public std::runtime_error
{
public:
explicit SatelliteException(const char* message)
: runtime_error(message)
{
}
};
} // namespace libsgp4

View File

@ -0,0 +1,68 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SolarPosition.h"
#include "Globals.h"
#include "Util.h"
#include <cmath>
namespace libsgp4
{
Eci SolarPosition::FindPosition(const DateTime& dt)
{
const double mjd = dt.ToJ2000();
const double year = 1900 + mjd / 365.25;
const double T = (mjd + Delta_ET(year) / kSECONDS_PER_DAY) / 36525.0;
const double M = Util::DegreesToRadians(Util::Wrap360(358.47583
+ Util::Wrap360(35999.04975 * T)
- (0.000150 + 0.0000033 * T) * T * T));
const double L = Util::DegreesToRadians(Util::Wrap360(279.69668
+ Util::Wrap360(36000.76892 * T)
+ 0.0003025 * T*T));
const double e = 0.01675104 - (0.0000418 + 0.000000126 * T) * T;
const double C = Util::DegreesToRadians((1.919460
- (0.004789 + 0.000014 * T) * T) * sin(M)
+ (0.020094 - 0.000100 * T) * sin(2 * M)
+ 0.000293 * sin(3 * M));
const double O = Util::DegreesToRadians(
Util::Wrap360(259.18 - 1934.142 * T));
const double Lsa = Util::WrapTwoPI(L + C
- Util::DegreesToRadians(0.00569 - 0.00479 * sin(O)));
const double nu = Util::WrapTwoPI(M + C);
double R = 1.0000002 * (1 - e * e) / (1 + e * cos(nu));
const double eps = Util::DegreesToRadians(23.452294 - (0.0130125
+ (0.00000164 - 0.000000503 * T) * T) * T + 0.00256 * cos(O));
R = R * kAU;
Vector solar_position(R * cos(Lsa),
R * sin(Lsa) * cos(eps),
R * sin(Lsa) * sin(eps),
R);
return Eci(dt, solar_position);
}
double SolarPosition::Delta_ET(double year) const
{
return 26.465 + 0.747622 * (year - 1950) + 1.886913
* sin(kTWOPI * (year - 1975) / 33);
}
} // namespace libsgp4

View File

@ -0,0 +1,40 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "DateTime.h"
#include "Eci.h"
namespace libsgp4
{
/**
* @brief Find the position of the sun
*/
class SolarPosition
{
public:
SolarPosition() = default;
Eci FindPosition(const DateTime& dt);
private:
double Delta_ET(double year) const;
};
} // namespace libsgp4

View File

@ -0,0 +1,18 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "TimeSpan.h"

259
SPG4Tool/libsgp4/TimeSpan.h Normal file
View File

@ -0,0 +1,259 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdint>
namespace libsgp4
{
namespace
{
static const int64_t TicksPerDay = 86400000000LL;
static const int64_t TicksPerHour = 3600000000LL;
static const int64_t TicksPerMinute = 60000000LL;
static const int64_t TicksPerSecond = 1000000LL;
static const int64_t TicksPerMillisecond = 1000LL;
static const int64_t TicksPerMicrosecond = 1LL;
static const int64_t UnixEpoch = 62135596800000000LL;
static const int64_t MaxValueTicks = 315537897599999999LL;
// 1582-Oct-15
static const int64_t GregorianStart = 49916304000000000LL;
}
/**
* @brief Represents a time interval.
*
* Represents a time interval (duration/elapsed) that is measured as a positive
* or negative number of days, hours, minutes, seconds, and fractions
* of a second.
*/
class TimeSpan
{
public:
explicit TimeSpan(int64_t ticks)
: m_ticks(ticks)
{
}
TimeSpan(int hours, int minutes, int seconds)
{
CalculateTicks(0, hours, minutes, seconds, 0);
}
TimeSpan(int days, int hours, int minutes, int seconds)
{
CalculateTicks(days, hours, minutes, seconds, 0);
}
TimeSpan(int days, int hours, int minutes, int seconds, int microseconds)
{
CalculateTicks(days, hours, minutes, seconds, microseconds);
}
TimeSpan Add(const TimeSpan& ts) const
{
return TimeSpan(m_ticks + ts.m_ticks);
}
TimeSpan Subtract(const TimeSpan& ts) const
{
return TimeSpan(m_ticks - ts.m_ticks);
}
int Compare(const TimeSpan& ts) const
{
int ret = 0;
if (m_ticks < ts.m_ticks)
{
ret = -1;
}
if (m_ticks > ts.m_ticks)
{
ret = 1;
}
return ret;
}
bool Equals(const TimeSpan& ts) const
{
return m_ticks == ts.m_ticks;
}
int Days() const
{
return static_cast<int>(m_ticks / TicksPerDay);
}
int Hours() const
{
return static_cast<int>(m_ticks % TicksPerDay / TicksPerHour);
}
int Minutes() const
{
return static_cast<int>(m_ticks % TicksPerHour / TicksPerMinute);
}
int Seconds() const
{
return static_cast<int>(m_ticks % TicksPerMinute / TicksPerSecond);
}
int Milliseconds() const
{
return static_cast<int>(m_ticks % TicksPerSecond / TicksPerMillisecond);
}
int Microseconds() const
{
return static_cast<int>(m_ticks % TicksPerSecond / TicksPerMicrosecond);
}
int64_t Ticks() const
{
return m_ticks;
}
double TotalDays() const
{
return static_cast<double>(m_ticks) / TicksPerDay;
}
double TotalHours() const
{
return static_cast<double>(m_ticks) / TicksPerHour;
}
double TotalMinutes() const
{
return static_cast<double>(m_ticks) / TicksPerMinute;
}
double TotalSeconds() const
{
return static_cast<double>(m_ticks) / TicksPerSecond;
}
double TotalMilliseconds() const
{
return static_cast<double>(m_ticks) / TicksPerMillisecond;
}
double TotalMicroseconds() const
{
return static_cast<double>(m_ticks) / TicksPerMicrosecond;
}
std::string ToString() const
{
std::stringstream ss;
ss << std::right << std::setfill('0');
if (m_ticks < 0)
{
ss << '-';
}
if (Days() != 0)
{
ss << std::setw(2) << std::abs(Days()) << '.';
}
ss << std::setw(2) << std::abs(Hours()) << ':';
ss << std::setw(2) << std::abs(Minutes()) << ':';
ss << std::setw(2) << std::abs(Seconds());
if (Microseconds() != 0)
{
ss << '.' << std::setw(6) << std::abs(Microseconds());
}
return ss.str();
}
private:
int64_t m_ticks{};
void CalculateTicks(int days,
int hours,
int minutes,
int seconds,
int microseconds)
{
m_ticks = days * TicksPerDay +
(hours * 3600LL + minutes * 60LL + seconds) * TicksPerSecond +
microseconds * TicksPerMicrosecond;
}
};
inline std::ostream& operator<<(std::ostream& strm, const TimeSpan& t)
{
return strm << t.ToString();
}
inline TimeSpan operator+(const TimeSpan& ts1, const TimeSpan& ts2)
{
return ts1.Add(ts2);
}
inline TimeSpan operator-(const TimeSpan& ts1, const TimeSpan& ts2)
{
return ts1.Subtract(ts2);
}
inline bool operator==(const TimeSpan& ts1, TimeSpan& ts2)
{
return ts1.Equals(ts2);
}
inline bool operator>(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) > 0);
}
inline bool operator>=(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) >= 0);
}
inline bool operator!=(const TimeSpan& ts1, const TimeSpan& ts2)
{
return !ts1.Equals(ts2);
}
inline bool operator<(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) < 0);
}
inline bool operator<=(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) <= 0);
}
} // namespace libsgp4

376
SPG4Tool/libsgp4/Tle.cc Normal file
View File

@ -0,0 +1,376 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Tle.h"
#include <locale>
namespace libsgp4
{
namespace
{
static const unsigned int TLE1_COL_NORADNUM = 2;
static const unsigned int TLE1_LEN_NORADNUM = 5;
static const unsigned int TLE1_COL_INTLDESC_A = 9;
static const unsigned int TLE1_LEN_INTLDESC_A = 2;
// static const unsigned int TLE1_COL_INTLDESC_B = 11;
static const unsigned int TLE1_LEN_INTLDESC_B = 3;
// static const unsigned int TLE1_COL_INTLDESC_C = 14;
static const unsigned int TLE1_LEN_INTLDESC_C = 3;
static const unsigned int TLE1_COL_EPOCH_A = 18;
static const unsigned int TLE1_LEN_EPOCH_A = 2;
static const unsigned int TLE1_COL_EPOCH_B = 20;
static const unsigned int TLE1_LEN_EPOCH_B = 12;
static const unsigned int TLE1_COL_MEANMOTIONDT2 = 33;
static const unsigned int TLE1_LEN_MEANMOTIONDT2 = 10;
static const unsigned int TLE1_COL_MEANMOTIONDDT6 = 44;
static const unsigned int TLE1_LEN_MEANMOTIONDDT6 = 8;
static const unsigned int TLE1_COL_BSTAR = 53;
static const unsigned int TLE1_LEN_BSTAR = 8;
// static const unsigned int TLE1_COL_EPHEMTYPE = 62;
// static const unsigned int TLE1_LEN_EPHEMTYPE = 1;
// static const unsigned int TLE1_COL_ELNUM = 64;
// static const unsigned int TLE1_LEN_ELNUM = 4;
static const unsigned int TLE2_COL_NORADNUM = 2;
static const unsigned int TLE2_LEN_NORADNUM = 5;
static const unsigned int TLE2_COL_INCLINATION = 8;
static const unsigned int TLE2_LEN_INCLINATION = 8;
static const unsigned int TLE2_COL_RAASCENDNODE = 17;
static const unsigned int TLE2_LEN_RAASCENDNODE = 8;
static const unsigned int TLE2_COL_ECCENTRICITY = 26;
static const unsigned int TLE2_LEN_ECCENTRICITY = 7;
static const unsigned int TLE2_COL_ARGPERIGEE = 34;
static const unsigned int TLE2_LEN_ARGPERIGEE = 8;
static const unsigned int TLE2_COL_MEANANOMALY = 43;
static const unsigned int TLE2_LEN_MEANANOMALY = 8;
static const unsigned int TLE2_COL_MEANMOTION = 52;
static const unsigned int TLE2_LEN_MEANMOTION = 11;
static const unsigned int TLE2_COL_REVATEPOCH = 63;
static const unsigned int TLE2_LEN_REVATEPOCH = 5;
}
/**
* Initialise the tle object.
* @exception TleException
*/
void Tle::Initialize()
{
if (!IsValidLineLength(line_one_))
{
throw TleException("Invalid length for line one");
}
if (!IsValidLineLength(line_two_))
{
throw TleException("Invalid length for line two");
}
if (line_one_[0] != '1')
{
throw TleException("Invalid line beginning for line one");
}
if (line_two_[0] != '2')
{
throw TleException("Invalid line beginning for line two");
}
unsigned int sat_number_1;
unsigned int sat_number_2;
ExtractInteger(line_one_.substr(TLE1_COL_NORADNUM,
TLE1_LEN_NORADNUM), sat_number_1);
ExtractInteger(line_two_.substr(TLE2_COL_NORADNUM,
TLE2_LEN_NORADNUM), sat_number_2);
if (sat_number_1 != sat_number_2)
{
throw TleException("Satellite numbers do not match");
}
norad_number_ = sat_number_1;
if (name_.empty())
{
name_ = line_one_.substr(TLE1_COL_NORADNUM, TLE1_LEN_NORADNUM);
}
int_designator_ = line_one_.substr(TLE1_COL_INTLDESC_A,
TLE1_LEN_INTLDESC_A + TLE1_LEN_INTLDESC_B + TLE1_LEN_INTLDESC_C);
unsigned int year = 0;
double day = 0.0;
ExtractInteger(line_one_.substr(TLE1_COL_EPOCH_A,
TLE1_LEN_EPOCH_A), year);
ExtractDouble(line_one_.substr(TLE1_COL_EPOCH_B,
TLE1_LEN_EPOCH_B), 4, day);
ExtractDouble(line_one_.substr(TLE1_COL_MEANMOTIONDT2,
TLE1_LEN_MEANMOTIONDT2), 2, mean_motion_dt2_);
ExtractExponential(line_one_.substr(TLE1_COL_MEANMOTIONDDT6,
TLE1_LEN_MEANMOTIONDDT6), mean_motion_ddt6_);
ExtractExponential(line_one_.substr(TLE1_COL_BSTAR,
TLE1_LEN_BSTAR), bstar_);
/*
* line 2
*/
ExtractDouble(line_two_.substr(TLE2_COL_INCLINATION,
TLE2_LEN_INCLINATION), 4, inclination_);
ExtractDouble(line_two_.substr(TLE2_COL_RAASCENDNODE,
TLE2_LEN_RAASCENDNODE), 4, right_ascending_node_);
ExtractDouble(line_two_.substr(TLE2_COL_ECCENTRICITY,
TLE2_LEN_ECCENTRICITY), -1, eccentricity_);
ExtractDouble(line_two_.substr(TLE2_COL_ARGPERIGEE,
TLE2_LEN_ARGPERIGEE), 4, argument_perigee_);
ExtractDouble(line_two_.substr(TLE2_COL_MEANANOMALY,
TLE2_LEN_MEANANOMALY), 4, mean_anomaly_);
ExtractDouble(line_two_.substr(TLE2_COL_MEANMOTION,
TLE2_LEN_MEANMOTION), 3, mean_motion_);
ExtractInteger(line_two_.substr(TLE2_COL_REVATEPOCH,
TLE2_LEN_REVATEPOCH), orbit_number_);
if (year < 57)
{
year += 2000;
}
else
{
year += 1900;
}
epoch_ = DateTime(year, day);
}
/**
* Check
* @param str The string to check
* @returns Whether true of the string has a valid length
*/
bool Tle::IsValidLineLength(const std::string& str)
{
return str.length() == LineLength() ? true : false;
}
/**
* Convert a string containing an integer
* @param[in] str The string to convert
* @param[out] val The result
* @exception TleException on conversion error
*/
void Tle::ExtractInteger(const std::string& str, unsigned int& val)
{
bool found_digit = false;
unsigned int temp = 0;
for (auto& i : str)
{
if (isdigit(i))
{
found_digit = true;
temp = (temp * 10) + static_cast<unsigned int>(i - '0');
}
else if (found_digit)
{
throw TleException("Unexpected non digit");
}
else if (i != ' ')
{
throw TleException("Invalid character");
}
}
if (!found_digit)
{
val = 0;
}
else
{
val = temp;
}
}
/**
* Convert a string containing an double
* @param[in] str The string to convert
* @param[in] point_pos The position of the decimal point. (-1 if none)
* @param[out] val The result
* @exception TleException on conversion error
*/
void Tle::ExtractDouble(const std::string& str, int point_pos, double& val)
{
std::string temp;
bool found_digit = false;
for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
{
/*
* integer part
*/
if (point_pos >= 0 && i < str.begin() + point_pos - 1)
{
bool done = false;
if (i == str.begin())
{
if(*i == '-' || *i == '+')
{
/*
* first character could be signed
*/
temp += *i;
done = true;
}
}
if (!done)
{
if (isdigit(*i))
{
found_digit = true;
temp += *i;
}
else if (found_digit)
{
throw TleException("Unexpected non digit");
}
else if (*i != ' ')
{
throw TleException("Invalid character");
}
}
}
/*
* decimal point
*/
else if (point_pos >= 0 && i == str.begin() + point_pos - 1)
{
if (temp.length() == 0)
{
/*
* integer part is blank, so add a '0'
*/
temp += '0';
}
if (*i == '.')
{
/*
* decimal point found
*/
temp += *i;
}
else
{
throw TleException("Failed to find decimal point");
}
}
/*
* fraction part
*/
else
{
if (i == str.begin() && point_pos == -1)
{
/*
* no decimal point expected, add 0. beginning
*/
temp += '0';
temp += '.';
}
/*
* should be a digit
*/
if (isdigit(*i))
{
temp += *i;
}
else
{
throw TleException("Invalid digit");
}
}
}
if (!Util::FromString<double>(temp, val))
{
throw TleException("Failed to convert value to double");
}
}
/**
* Convert a string containing an exponential
* @param[in] str The string to convert
* @param[out] val The result
* @exception TleException on conversion error
*/
void Tle::ExtractExponential(const std::string& str, double& val)
{
std::string temp;
for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
{
if (i == str.begin())
{
if (*i == '-' || *i == '+' || *i == ' ')
{
if (*i == '-')
{
temp += *i;
}
temp += '0';
temp += '.';
}
else
{
throw TleException("Invalid sign");
}
}
else if (i == str.end() - 2)
{
if (*i == '-' || *i == '+')
{
temp += 'e';
temp += *i;
}
else
{
throw TleException("Invalid exponential sign");
}
}
else
{
if (isdigit(*i))
{
temp += *i;
}
else
{
throw TleException("Invalid digit");
}
}
}
if (!Util::FromString<double>(temp, val))
{
throw TleException("Failed to convert value to double");
}
}
} // namespace libsgp4

341
SPG4Tool/libsgp4/Tle.h Normal file
View File

@ -0,0 +1,341 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "Util.h"
#include "DateTime.h"
#include "TleException.h"
namespace libsgp4
{
/**
* @brief Processes a two-line element set used to convey OrbitalElements.
*
* Used to extract the various raw fields from a two-line element set.
*/
class Tle
{
public:
/**
* @details Initialise given the two lines of a tle
* @param[in] line_one Tle line one
* @param[in] line_two Tle line two
*/
Tle(std::string line_one, std::string line_two)
: line_one_(std::move(line_one))
, line_two_(std::move(line_two))
{
Initialize();
}
/**
* @details Initialise given the satellite name and the two lines of a tle
* @param[in] name Satellite name
* @param[in] line_one Tle line one
* @param[in] line_two Tle line two
*/
Tle(std::string name, std::string line_one, std::string line_two)
: name_(std::move(name))
, line_one_(std::move(line_one))
, line_two_(std::move(line_two))
{
Initialize();
}
/**
* Copy constructor
* @param[in] tle Tle object to copy from
*/
Tle(const Tle& tle)
{
name_ = tle.name_;
line_one_ = tle.line_one_;
line_two_ = tle.line_two_;
norad_number_ = tle.norad_number_;
int_designator_ = tle.int_designator_;
epoch_ = tle.epoch_;
mean_motion_dt2_ = tle.mean_motion_dt2_;
mean_motion_ddt6_ = tle.mean_motion_ddt6_;
bstar_ = tle.bstar_;
inclination_ = tle.inclination_;
right_ascending_node_ = tle.right_ascending_node_;
eccentricity_ = tle.eccentricity_;
argument_perigee_ = tle.argument_perigee_;
mean_anomaly_ = tle.mean_anomaly_;
mean_motion_ = tle.mean_motion_;
orbit_number_ = tle.orbit_number_;
}
/**
* Get the satellite name
* @returns the satellite name
*/
std::string Name() const
{
return name_;
}
/**
* Get the first line of the tle
* @returns the first line of the tle
*/
std::string Line1() const
{
return line_one_;
}
/**
* Get the second line of the tle
* @returns the second line of the tle
*/
std::string Line2() const
{
return line_two_;
}
/**
* Get the norad number
* @returns the norad number
*/
unsigned int NoradNumber() const
{
return norad_number_;
}
/**
* Get the international designator
* @returns the international designator
*/
std::string IntDesignator() const
{
return int_designator_;
}
/**
* Get the tle epoch
* @returns the tle epoch
*/
DateTime Epoch() const
{
return epoch_;
}
/**
* Get the first time derivative of the mean motion divided by two
* @returns the first time derivative of the mean motion divided by two
*/
double MeanMotionDt2() const
{
return mean_motion_dt2_;
}
/**
* Get the second time derivative of mean motion divided by six
* @returns the second time derivative of mean motion divided by six
*/
double MeanMotionDdt6() const
{
return mean_motion_ddt6_;
}
/**
* Get the BSTAR drag term
* @returns the BSTAR drag term
*/
double BStar() const
{
return bstar_;
}
/**
* Get the inclination
* @param in_degrees Whether to return the value in degrees or radians
* @returns the inclination
*/
double Inclination(bool in_degrees) const
{
if (in_degrees)
{
return inclination_;
}
else
{
return Util::DegreesToRadians(inclination_);
}
}
/**
* Get the right ascension of the ascending node
* @param in_degrees Whether to return the value in degrees or radians
* @returns the right ascension of the ascending node
*/
double RightAscendingNode(const bool in_degrees) const
{
if (in_degrees)
{
return right_ascending_node_;
}
else
{
return Util::DegreesToRadians(right_ascending_node_);
}
}
/**
* Get the eccentricity
* @returns the eccentricity
*/
double Eccentricity() const
{
return eccentricity_;
}
/**
* Get the argument of perigee
* @param in_degrees Whether to return the value in degrees or radians
* @returns the argument of perigee
*/
double ArgumentPerigee(const bool in_degrees) const
{
if (in_degrees)
{
return argument_perigee_;
}
else
{
return Util::DegreesToRadians(argument_perigee_);
}
}
/**
* Get the mean anomaly
* @param in_degrees Whether to return the value in degrees or radians
* @returns the mean anomaly
*/
double MeanAnomaly(const bool in_degrees) const
{
if (in_degrees)
{
return mean_anomaly_;
}
else
{
return Util::DegreesToRadians(mean_anomaly_);
}
}
/**
* Get the mean motion
* @returns the mean motion (revolutions per day)
*/
double MeanMotion() const
{
return mean_motion_;
}
/**
* Get the orbit number
* @returns the orbit number
*/
unsigned int OrbitNumber() const
{
return orbit_number_;
}
/**
* Get the expected tle line length
* @returns the tle line length
*/
static unsigned int LineLength()
{
return TLE_LEN_LINE_DATA;
}
/**
* Dump this object to a string
* @returns string
*/
std::string ToString() const
{
std::stringstream ss;
ss << std::right << std::fixed;
ss << "Norad Number: " << NoradNumber() << std::endl;
ss << "Int. Designator: " << IntDesignator() << std::endl;
ss << "Epoch: " << Epoch() << std::endl;
ss << "Orbit Number: " << OrbitNumber() << std::endl;
ss << std::setprecision(8);
ss << "Mean Motion Dt2: ";
ss << std::setw(12) << MeanMotionDt2() << std::endl;
ss << "Mean Motion Ddt6: ";
ss << std::setw(12) << MeanMotionDdt6() << std::endl;
ss << "Eccentricity: ";
ss << std::setw(12) << Eccentricity() << std::endl;
ss << "BStar: ";
ss << std::setw(12) << BStar() << std::endl;
ss << "Inclination: ";
ss << std::setw(12) << Inclination(true) << std::endl;
ss << "Right Ascending Node: ";
ss << std::setw(12) << RightAscendingNode(true) << std::endl;
ss << "Argument Perigee: ";
ss << std::setw(12) << ArgumentPerigee(true) << std::endl;
ss << "Mean Anomaly: ";
ss << std::setw(12) << MeanAnomaly(true) << std::endl;
ss << "Mean Motion: ";
ss << std::setw(12) << MeanMotion() << std::endl;
return ss.str();
}
private:
void Initialize();
static bool IsValidLineLength(const std::string& str);
void ExtractInteger(const std::string& str, unsigned int& val);
void ExtractDouble(const std::string& str, int point_pos, double& val);
void ExtractExponential(const std::string& str, double& val);
private:
std::string name_;
std::string line_one_;
std::string line_two_;
std::string int_designator_;
DateTime epoch_;
double mean_motion_dt2_{};
double mean_motion_ddt6_{};
double bstar_{};
double inclination_{};
double right_ascending_node_{};
double eccentricity_{};
double argument_perigee_{};
double mean_anomaly_{};
double mean_motion_{};
unsigned int norad_number_{};
unsigned int orbit_number_{};
static const unsigned int TLE_LEN_LINE_DATA = 69;
static const unsigned int TLE_LEN_LINE_NAME = 22;
};
inline std::ostream& operator<<(std::ostream& strm, const Tle& t)
{
return strm << t.ToString();
}
} // namespace libsgp4

View File

@ -0,0 +1 @@
#include "TleException.h"

View File

@ -0,0 +1,44 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdexcept>
#include <string>
namespace libsgp4
{
/**
* @brief The exception that the Tle class throws on an error.
*
* The exception that the Tle decoder will throw on an error.
*/
class TleException : public std::runtime_error
{
public:
/**
* Constructor
* @param message Exception message
*/
explicit TleException(const char* message)
: runtime_error(message)
{
}
};
} // namespace libsgp4

45
SPG4Tool/libsgp4/Util.cc Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Util.h"
#include <algorithm>
#include <locale>
#include <functional>
namespace libsgp4
{
namespace Util {
void TrimLeft(std::string& s)
{
s.erase(s.begin(),
std::find_if(s.begin(), s.end(), [](unsigned char c) { return std::isgraph(c) != 0; }));
}
void TrimRight(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c) { return std::isgraph(c) != 0; }).base(),
s.end());
}
void Trim(std::string& s)
{
TrimLeft(s);
TrimRight(s);
}
}
} // namespace libsgp4::Util

111
SPG4Tool/libsgp4/Util.h Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "Globals.h"
#include <sstream>
namespace libsgp4
{
namespace Util
{
template
<typename T>
bool FromString(const std::string& str, T& val)
{
std::stringstream ss(str);
return !(ss >> val).fail();
}
/*
* always positive result
* Mod(-3,4)= 1 fmod(-3,4)= -3
*/
inline double Mod(const double x, const double y)
{
if (y == 0.0)
{
return x;
}
return x - y * floor(x / y);
}
inline double WrapNegPosPI(const double a)
{
return Mod(a + kPI, kTWOPI) - kPI;
}
inline double WrapTwoPI(const double a)
{
return Mod(a, kTWOPI);
}
inline double WrapNegPos180(const double a)
{
return Mod(a + 180.0, 360.0) - 180.0;
}
inline double Wrap360(const double a)
{
return Mod(a, 360.0);
}
inline double DegreesToRadians(const double degrees)
{
return degrees * kPI / 180.0;
}
inline double RadiansToDegrees(const double radians)
{
return radians * 180.0 / kPI;
}
inline double AcTan(const double sinx, const double cosx)
{
if (cosx == 0.0)
{
if (sinx > 0.0)
{
return kPI / 2.0;
}
else
{
return 3.0 * kPI / 2.0;
}
}
else
{
if (cosx > 0.0)
{
return atan(sinx / cosx);
}
else
{
return kPI + atan(sinx / cosx);
}
}
}
void TrimLeft(std::string& s);
void TrimRight(std::string& s);
void Trim(std::string& s);
} // namespace Util
} // namespace libsgp4

View File

@ -0,0 +1,18 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Vector.h"

160
SPG4Tool/libsgp4/Vector.h Normal file
View File

@ -0,0 +1,160 @@
/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cmath>
#include <string>
#include <sstream>
#include <iomanip>
namespace libsgp4
{
/**
* @brief Generic vector
*
* Stores x, y, z, w
*/
struct Vector
{
public:
/**
* Default constructor
*/
Vector() = default;
/**
* Constructor
* @param arg_x x value
* @param arg_y y value
* @param arg_z z value
*/
Vector(const double arg_x,
const double arg_y,
const double arg_z)
: x(arg_x), y(arg_y), z(arg_z)
{
}
/**
* Constructor
* @param arg_x x value
* @param arg_y y value
* @param arg_z z value
* @param arg_w w value
*/
Vector(const double arg_x,
const double arg_y,
const double arg_z,
const double arg_w)
: x(arg_x), y(arg_y), z(arg_z), w(arg_w)
{
}
/**
* Copy constructor
* @param v value to copy from
*/
Vector(const Vector& v)
{
x = v.x;
y = v.y;
z = v.z;
w = v.w;
}
/**
* Assignment operator
* @param v value to copy from
*/
Vector& operator=(const Vector& v)
{
if (this != &v)
{
x = v.x;
y = v.y;
z = v.z;
w = v.w;
}
return *this;
}
/**
* Subtract operator
* @param v value to suctract from
*/
Vector operator-(const Vector& v)
{
return Vector(x - v.x,
y - v.y,
z - v.z,
0.0);
}
/**
* Calculates the magnitude of the vector
* @returns magnitude of the vector
*/
double Magnitude() const
{
return sqrt(x * x + y * y + z * z);
}
/**
* Calculates the dot product
* @returns dot product
*/
double Dot(const Vector& vec) const
{
return (x * vec.x) +
(y * vec.y) +
(z * vec.z);
}
/**
* Converts this vector to a string
* @returns this vector as a string
*/
std::string ToString() const
{
std::stringstream ss;
ss << std::right << std::fixed << std::setprecision(3);
ss << "X: " << std::setw(9) << x;
ss << ", Y: " << std::setw(9) << y;
ss << ", Z: " << std::setw(9) << z;
ss << ", W: " << std::setw(9) << w;
return ss.str();
}
/** x value */
double x{};
/** y value */
double y{};
/** z value */
double z{};
/** w value */
double w{};
};
inline std::ostream& operator<<(std::ostream& strm, const Vector& v)
{
return strm << v.ToString();
}
} // namespace libsgp4

View File

@ -11,6 +11,11 @@
#include "DEMLLA2XYZTool.h" #include "DEMLLA2XYZTool.h"
#include "QConvertCoordinateSystemDialog.h" #include "QConvertCoordinateSystemDialog.h"
#include "QResampleRefrenceRaster.h" #include "QResampleRefrenceRaster.h"
#include "QtLookTableCorrectOffsetDialog.h"
#include "QtCreateGPSPointsDialog.h"
#include "RasterVRT2ENVIdataDialog.h"
#include "SARSatalliteSimulationWorkflow.h" // 大场景仿真
GF3ImportDataToolButton::GF3ImportDataToolButton(QWidget* parent) :QToolAbstract(parent) GF3ImportDataToolButton::GF3ImportDataToolButton(QWidget* parent) :QToolAbstract(parent)
{ {
@ -111,13 +116,28 @@ void RegisterPreToolBox(LAMPMainWidget::RasterMainWidget* mainwindows, ToolBoxWi
emit toolbox->addBoxToolItemSIGNAL(new QDEMLLA2XYZToolToolButton(toolbox)); emit toolbox->addBoxToolItemSIGNAL(new QDEMLLA2XYZToolToolButton(toolbox));
emit toolbox->addBoxToolItemSIGNAL(new QConvertCoordinateSystemToolButton(toolbox)); emit toolbox->addBoxToolItemSIGNAL(new QConvertCoordinateSystemToolButton(toolbox));
emit toolbox->addBoxToolItemSIGNAL(new QResampleRefrenceRasterToolButton(toolbox)); emit toolbox->addBoxToolItemSIGNAL(new QResampleRefrenceRasterToolButton(toolbox));
emit toolbox->addBoxToolItemSIGNAL(new QLookTableCorrectOffsetToolButton(toolbox));
emit toolbox->addBoxToolItemSIGNAL(new QCreateGPSPointsToolButton(toolbox));
emit toolbox->addBoxToolItemSIGNAL(new RasterVRT2ENVIdataDialogToolButton(toolbox));
// 大场景仿真流程
#ifdef __BASETOOLBOX__SARSATALLITESIMULATIONWORKFLOW__H__
initBaseToolSARSateSimulationWorkflow(toolbox);
#endif // __BASETOOLBOX__SARSATALLITESIMULATIONWORKFLOW__H__
} }
QDEMResampleDialogToolButton::QDEMResampleDialogToolButton(QWidget* parent) QDEMResampleDialogToolButton::QDEMResampleDialogToolButton(QWidget* parent)
{ {
this->toolPath = QVector<QString>(0); this->toolPath = QVector<QString>(0);
this->toolPath.push_back(u8"»ù´¡´¦Àí"); this->toolPath.push_back(u8"»ù´¡´¦Àí");
this->toolname = QString(u8"DEMÖØ²ÉÑù"); this->toolname = QString(u8"栅格重采样");
} }
QDEMResampleDialogToolButton::~QDEMResampleDialogToolButton() QDEMResampleDialogToolButton::~QDEMResampleDialogToolButton()
@ -180,3 +200,52 @@ void QResampleRefrenceRasterToolButton::excute()
QResampleRefrenceRaster* dialog = new QResampleRefrenceRaster; QResampleRefrenceRaster* dialog = new QResampleRefrenceRaster;
dialog->show(); dialog->show();
} }
QLookTableCorrectOffsetToolButton::QLookTableCorrectOffsetToolButton(QWidget* parent)
{
this->toolPath = QVector<QString>(0);
this->toolPath.push_back(u8"基础处理");
this->toolname = QString(u8"查找表偏移校正");
}
QLookTableCorrectOffsetToolButton::~QLookTableCorrectOffsetToolButton()
{
}
void QLookTableCorrectOffsetToolButton::excute()
{
QtLookTableCorrectOffsetDialog* dialog = new QtLookTableCorrectOffsetDialog;
dialog->show();
}
QCreateGPSPointsToolButton::QCreateGPSPointsToolButton(QWidget* parent)
{
this->toolPath = QVector<QString>(0);
this->toolPath.push_back(u8"基础处理");
this->toolname = QString(u8"两行根数生成轨道节点");
}
QCreateGPSPointsToolButton::~QCreateGPSPointsToolButton()
{
}
void QCreateGPSPointsToolButton::excute()
{
QtCreateGPSPointsDialog* dialog = new QtCreateGPSPointsDialog;
dialog->show();
}
RasterVRT2ENVIdataDialogToolButton::RasterVRT2ENVIdataDialogToolButton(QWidget* parent)
{
this->toolPath = QVector<QString>(0);
this->toolPath.push_back(u8"基础处理");
this->toolname = QString(u8"vrt文件转换envi数据格式");
}
RasterVRT2ENVIdataDialogToolButton::~RasterVRT2ENVIdataDialogToolButton()
{
}
void RasterVRT2ENVIdataDialogToolButton::run()
{
RasterVRT2ENVIdataDialog* dialog = new RasterVRT2ENVIdataDialog;
dialog->show();
}

View File

@ -10,6 +10,8 @@ namespace LAMPMainWidget {
class ToolBoxWidget; class ToolBoxWidget;
extern "C" BASETOOLBOX_EXPORT void RegisterPreToolBox(LAMPMainWidget::RasterMainWidget* mainwindows, ToolBoxWidget* toolbox);
class BASETOOLBOX_EXPORT GF3ImportDataToolButton : public QToolAbstract { class BASETOOLBOX_EXPORT GF3ImportDataToolButton : public QToolAbstract {
Q_OBJECT Q_OBJECT
public: public:
@ -109,4 +111,41 @@ public slots:
}; };
extern "C" BASETOOLBOX_EXPORT void RegisterPreToolBox(LAMPMainWidget::RasterMainWidget* mainwindows, ToolBoxWidget* toolbox); class BASETOOLBOX_EXPORT QLookTableCorrectOffsetToolButton : public QToolAbstract {
Q_OBJECT
public:
QLookTableCorrectOffsetToolButton(QWidget* parent = nullptr);
~QLookTableCorrectOffsetToolButton();
public slots:
virtual void excute() override;
};
class BASETOOLBOX_EXPORT QCreateGPSPointsToolButton : public QToolAbstract {
Q_OBJECT
public:
QCreateGPSPointsToolButton(QWidget* parent = nullptr);
~QCreateGPSPointsToolButton();
public slots:
virtual void excute() override;
};
class BASETOOLBOX_EXPORT RasterVRT2ENVIdataDialogToolButton : public QToolAbstract {
Q_OBJECT
public:
RasterVRT2ENVIdataDialogToolButton(QWidget* parent = nullptr);
~RasterVRT2ENVIdataDialogToolButton();
public :
virtual void run() override;
};

View File

@ -60,12 +60,12 @@
</ImportGroup> </ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
<QtInstall>tools_qt5</QtInstall> <QtInstall>tools_qt5</QtInstall>
<QtModules>core</QtModules> <QtModules>core;gui;widgets</QtModules>
<QtBuildConfig>debug</QtBuildConfig> <QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="QtSettings"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="QtSettings">
<QtInstall>tools_qt5</QtInstall> <QtInstall>tools_qt5</QtInstall>
<QtModules>core</QtModules> <QtModules>core;gui;widgets</QtModules>
<QtBuildConfig>debug</QtBuildConfig> <QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
@ -103,7 +103,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<IncludePath>..\..\BaseCommonLibrary;..\..\BaseCommonLibrary\BaseTool;..\..\BaseCommonLibrary\ToolAbstract;..\..\GPUBaseLib\GPUTool;.\BaseToolbox;..\..\RasterMainWidgetGUI\RasterMainWidget;..\..\RasterMainWidgetGUI;..\..\RasterProcessToolWidget;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> <IncludePath>..\..\BaseCommonLibrary;..\..\BaseCommonLibrary\BaseTool;..\..\BaseCommonLibrary\ToolAbstract;..\..\GPUBaseLib\GPUTool;.\BaseToolbox;..\..\RasterMainWidgetGUI\RasterMainWidget;..\..\RasterMainWidgetGUI;..\..\SPG4Tool;..\..\RasterProcessToolWidget;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\Toolbox\</OutDir> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\Toolbox\</OutDir>
<TargetName>PluginTool_$(ProjectName)</TargetName> <TargetName>PluginTool_$(ProjectName)</TargetName>
<CopyLocalProjectReference>true</CopyLocalProjectReference> <CopyLocalProjectReference>true</CopyLocalProjectReference>
@ -122,6 +122,7 @@
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<LanguageStandard>stdcpp14</LanguageStandard> <LanguageStandard>stdcpp14</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C> <LanguageStandard_C>stdc11</LanguageStandard_C>
<Optimization>Disabled</Optimization>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
@ -205,10 +206,15 @@
<ClCompile Include="BaseToolbox\QOrthSlrRaster.cpp" /> <ClCompile Include="BaseToolbox\QOrthSlrRaster.cpp" />
<ClCompile Include="BaseToolbox\QRDOrthProcessClass.cpp" /> <ClCompile Include="BaseToolbox\QRDOrthProcessClass.cpp" />
<ClCompile Include="BaseToolbox\QResampleRefrenceRaster.cpp" /> <ClCompile Include="BaseToolbox\QResampleRefrenceRaster.cpp" />
<ClCompile Include="BaseToolbox\QtCreateGPSPointsDialog.cpp" />
<ClCompile Include="BaseToolbox\QtLookTableCorrectOffsetDialog.cpp" />
<ClCompile Include="BaseToolbox\RasterVRT2ENVIdataDialog.cpp" />
<ClCompile Include="BaseToolbox\SatelliteGF3xmlParser.cpp" /> <ClCompile Include="BaseToolbox\SatelliteGF3xmlParser.cpp" />
<ClCompile Include="BaseToolbox\SateOrbit.cpp" /> <ClCompile Include="BaseToolbox\SateOrbit.cpp" />
<ClCompile Include="BaseToolbox\simptsn.cpp" /> <ClCompile Include="BaseToolbox\simptsn.cpp" />
<ClCompile Include="BaseToolbox\WGS84_J2000.cpp" /> <ClCompile Include="BaseToolbox\WGS84_J2000.cpp" />
<ClCompile Include="SARSatalliteSimulationWorkflow.cpp" />
<QtMoc Include="SARSatalliteSimulationWorkflow.h" />
<QtMoc Include="BaseToolbox\DEMLLA2XYZTool.h" /> <QtMoc Include="BaseToolbox\DEMLLA2XYZTool.h" />
<ClInclude Include="BaseToolbox\GF3CalibrationAndGeocodingClass.h" /> <ClInclude Include="BaseToolbox\GF3CalibrationAndGeocodingClass.h" />
<ClInclude Include="BaseToolbox\GF3PSTNClass.h" /> <ClInclude Include="BaseToolbox\GF3PSTNClass.h" />
@ -221,6 +227,9 @@
<QtMoc Include="BaseToolbox\QDEMResampleDialog.h" /> <QtMoc Include="BaseToolbox\QDEMResampleDialog.h" />
<QtMoc Include="BaseToolbox\QConvertCoordinateSystemDialog.h" /> <QtMoc Include="BaseToolbox\QConvertCoordinateSystemDialog.h" />
<QtMoc Include="BaseToolbox\QResampleRefrenceRaster.h" /> <QtMoc Include="BaseToolbox\QResampleRefrenceRaster.h" />
<QtMoc Include="BaseToolbox\QtLookTableCorrectOffsetDialog.h" />
<QtMoc Include="BaseToolbox\QtCreateGPSPointsDialog.h" />
<QtMoc Include="BaseToolbox\RasterVRT2ENVIdataDialog.h" />
<ClInclude Include="BaseToolbox\SatelliteGF3xmlParser.h" /> <ClInclude Include="BaseToolbox\SatelliteGF3xmlParser.h" />
<ClInclude Include="BaseToolbox\SateOrbit.h" /> <ClInclude Include="BaseToolbox\SateOrbit.h" />
<ClInclude Include="BaseToolbox\simptsn.h" /> <ClInclude Include="BaseToolbox\simptsn.h" />
@ -240,6 +249,9 @@
<QtUic Include="BaseToolbox\QOrthSlrRaster.ui" /> <QtUic Include="BaseToolbox\QOrthSlrRaster.ui" />
<QtUic Include="BaseToolbox\QRDOrthProcessClass.ui" /> <QtUic Include="BaseToolbox\QRDOrthProcessClass.ui" />
<QtUic Include="BaseToolbox\QResampleRefrenceRaster.ui" /> <QtUic Include="BaseToolbox\QResampleRefrenceRaster.ui" />
<QtUic Include="BaseToolbox\QtCreateGPSPointsDialog.ui" />
<QtUic Include="BaseToolbox\QtLookTableCorrectOffsetDialog.ui" />
<QtUic Include="BaseToolbox\RasterVRT2ENVIdataDialog.ui" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\BaseCommonLibrary\BaseCommonLibrary.vcxproj"> <ProjectReference Include="..\..\BaseCommonLibrary\BaseCommonLibrary.vcxproj">
@ -254,6 +266,9 @@
<ProjectReference Include="..\..\RasterProcessToolWidget\RasterProcessTool.vcxproj"> <ProjectReference Include="..\..\RasterProcessToolWidget\RasterProcessTool.vcxproj">
<Project>{7ef67daa-dbc0-4b7f-80e8-11b4d2cb7ec2}</Project> <Project>{7ef67daa-dbc0-4b7f-80e8-11b4d2cb7ec2}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\SPG4Tool\SPG4Tool.vcxproj">
<Project>{80a5854f-6f80-4ec2-9f73-84e0f4db8d7e}</Project>
</ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')"> <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">

View File

@ -100,6 +100,18 @@
<ClCompile Include="BaseToolbox\QResampleRefrenceRaster.cpp"> <ClCompile Include="BaseToolbox\QResampleRefrenceRaster.cpp">
<Filter>BaseToolbox</Filter> <Filter>BaseToolbox</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="BaseToolbox\QtLookTableCorrectOffsetDialog.cpp">
<Filter>BaseToolbox</Filter>
</ClCompile>
<ClCompile Include="BaseToolbox\QtCreateGPSPointsDialog.cpp">
<Filter>BaseToolbox</Filter>
</ClCompile>
<ClCompile Include="BaseToolbox\RasterVRT2ENVIdataDialog.cpp">
<Filter>BaseToolbox</Filter>
</ClCompile>
<ClCompile Include="SARSatalliteSimulationWorkflow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="BaseToolbox\DEMLLA2XYZTool.h"> <QtMoc Include="BaseToolbox\DEMLLA2XYZTool.h">
@ -135,6 +147,18 @@
<QtMoc Include="BaseToolbox\QResampleRefrenceRaster.h"> <QtMoc Include="BaseToolbox\QResampleRefrenceRaster.h">
<Filter>BaseToolbox</Filter> <Filter>BaseToolbox</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="BaseToolbox\QtLookTableCorrectOffsetDialog.h">
<Filter>BaseToolbox</Filter>
</QtMoc>
<QtMoc Include="BaseToolbox\QtCreateGPSPointsDialog.h">
<Filter>BaseToolbox</Filter>
</QtMoc>
<QtMoc Include="BaseToolbox\RasterVRT2ENVIdataDialog.h">
<Filter>BaseToolbox</Filter>
</QtMoc>
<QtMoc Include="SARSatalliteSimulationWorkflow.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtUic Include="BaseToolbox\DEMLLA2XYZTool.ui"> <QtUic Include="BaseToolbox\DEMLLA2XYZTool.ui">
@ -167,5 +191,14 @@
<QtUic Include="BaseToolbox\QResampleRefrenceRaster.ui"> <QtUic Include="BaseToolbox\QResampleRefrenceRaster.ui">
<Filter>BaseToolbox</Filter> <Filter>BaseToolbox</Filter>
</QtUic> </QtUic>
<QtUic Include="BaseToolbox\QtLookTableCorrectOffsetDialog.ui">
<Filter>BaseToolbox</Filter>
</QtUic>
<QtUic Include="BaseToolbox\QtCreateGPSPointsDialog.ui">
<Filter>BaseToolbox</Filter>
</QtUic>
<QtUic Include="BaseToolbox\RasterVRT2ENVIdataDialog.ui">
<Filter>BaseToolbox</Filter>
</QtUic>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -110,7 +110,7 @@ void DEMLLA2XYZTool::onaccept()
Vector3D Zaxis = { 0,0,1 }; Vector3D Zaxis = { 0,0,1 };
double rowidx = 0, colidx = 0; double rowidx = 0, colidx = 0;
#pragma omp parallel for //#pragma omp parallel for
for (long i = 1; i < dem_rows - 1; i++) { for (long i = 1; i < dem_rows - 1; i++) {
for (long j = 1; j < dem_cols - 1; j++) { for (long j = 1; j < dem_cols - 1; j++) {
rowidx = i + startlineid; rowidx = i + startlineid;

View File

@ -26,7 +26,7 @@ ErrorCode GF3CalibrationRaster(QString inRasterPath, QString outRasterPath, doub
double quayCoff = Qualifyvalue * 1.0 / 32767; double quayCoff = Qualifyvalue * 1.0 / 32767;
double caliCoff = std::pow(10.0, (calibrationConst * 1.0 / 20)); double caliCoff = std::pow(10.0, (calibrationConst * 1.0 / 20));
qDebug() << "定标系数:\t" << quayCoff / caliCoff; qDebug() << u8"定标系数:\t" << quayCoff / caliCoff;
long startrow = 0; long startrow = 0;
for (startrow = 0; startrow < imgraster.height; startrow = startrow + blocklines) { for (startrow = 0; startrow < imgraster.height; startrow = startrow + blocklines) {
@ -37,7 +37,7 @@ ErrorCode GF3CalibrationRaster(QString inRasterPath, QString outRasterPath, doub
imgArr.imag() = imgArrb2.array() * quayCoff / caliCoff; imgArr.imag() = imgArrb2.array() * quayCoff / caliCoff;
outraster.saveImage(imgArr, startrow, 0, 1); outraster.saveImage(imgArr, startrow, 0, 1);
} }
qDebug() << "影像写入到:" << outRasterPath; qDebug() << u8"影像写入到:" << outRasterPath;
return ErrorCode::SUCCESS; return ErrorCode::SUCCESS;
} }
@ -80,29 +80,29 @@ ErrorCode ImportGF3L1ARasterToWorkspace(QString inMetaxmlPath, QString inRasterP
QString outRasterpath = l1dataset.getImageRasterPath(); QString outRasterpath = l1dataset.getImageRasterPath();
ErrorCode errorcode = ErrorCode::SUCCESS; ErrorCode errorcode = ErrorCode::SUCCESS;
qDebug() << "导入数据:\t" << inRasterPath; qDebug() << u8"导入数据:\t" << inRasterPath;
switch (polsartype) switch (polsartype)
{ {
case POLARHH: case POLARHH:
qDebug() << "极化HH"; qDebug() << u8"极化HH";
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.HH_QualifyValue, gf3xml.HH_CalibrationConst); errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.HH_QualifyValue, gf3xml.HH_CalibrationConst);
break; break;
case POLARHV: case POLARHV:
qDebug() << "极化HH"; qDebug() << u8"极化HH";
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.HV_QualifyValue, gf3xml.HV_CalibrationConst); errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.HV_QualifyValue, gf3xml.HV_CalibrationConst);
break; break;
case POLARVH: case POLARVH:
qDebug() << "极化VH"; qDebug() << u8"极化VH";
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.VH_QualifyValue, gf3xml.VH_CalibrationConst); errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.VH_QualifyValue, gf3xml.VH_CalibrationConst);
break; break;
case POLARVV: case POLARVV:
qDebug() << "极化VV"; qDebug() << u8"极化VV";
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.VV_QualifyValue, gf3xml.VV_CalibrationConst); errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.VV_QualifyValue, gf3xml.VV_CalibrationConst);
break; break;
default: default:
break; break;
} }
qDebug() << "导入数据状态:\t" << QString::fromStdString(errorCode2errInfo(errorcode)); qDebug() << u8"导入数据状态:\t" << QString::fromStdString(errorCode2errInfo(errorcode));
return errorcode; return errorcode;
} }
@ -115,7 +115,7 @@ QVector<QString> SearchGF3DataTiff(QString inMetaxmlPath)
// 获取路径所在的目录 // 获取路径所在的目录
QDir directory(absPath); QDir directory(absPath);
if (!directory.exists()) { if (!directory.exists()) {
qDebug() << "Directory does not exist:" << directory.absolutePath(); qDebug() << u8"Directory does not exist:" << directory.absolutePath();
return QVector<QString>(0); return QVector<QString>(0);
} }
@ -124,7 +124,7 @@ QVector<QString> SearchGF3DataTiff(QString inMetaxmlPath)
filters << "*.tif" << "*.TIF" << "*.tiff" << "*.TIFF"; filters << "*.tif" << "*.TIF" << "*.tiff" << "*.TIFF";
QStringList files = directory.entryList(filters, QDir::Files); QStringList files = directory.entryList(filters, QDir::Files);
qDebug() << "TIFF Files in the directory" << directory.absolutePath() << ":"; qDebug() << u8"TIFF Files in the directory" << directory.absolutePath() << ":";
QVector<QString> filepath(0); QVector<QString> filepath(0);
for (long i = 0; i < files.count(); i++) { for (long i = 0; i < files.count(); i++) {
@ -144,7 +144,7 @@ POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName)
if (match.hasMatch()) { if (match.hasMatch()) {
polarization = match.captured(1); polarization = match.captured(1);
polarization = polarization.toLower().replace("_", ""); polarization = polarization.toLower().replace("_", "");
qDebug() << "Polarization extracted:" << polarization; qDebug() << u8"Polarization extracted:" << polarization;
if (polarization == "hh") { if (polarization == "hh") {
return POLARTYPEENUM::POLARHH; return POLARTYPEENUM::POLARHH;
} }
@ -162,7 +162,7 @@ POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName)
} }
} }
else { else {
qDebug() << "No polarization found in the path."; qDebug() << u8"No polarization found in the path.";
return POLARTYPEENUM::POLARUNKOWN; return POLARTYPEENUM::POLARUNKOWN;
} }
@ -199,7 +199,7 @@ ErrorCode ImportGF3L1AProcess(QString inMetaxmlPath, QString outWorkDirPath)
break; break;
} }
if (errorcode == ErrorCode::SUCCESS) { if (errorcode == ErrorCode::SUCCESS) {
return errorcode; continue;
} }
else { else {
QMessageBox::warning(nullptr, u8"错误", u8"数据导入错误"); QMessageBox::warning(nullptr, u8"错误", u8"数据导入错误");
@ -209,94 +209,10 @@ ErrorCode ImportGF3L1AProcess(QString inMetaxmlPath, QString outWorkDirPath)
return errorcode; return errorcode;
} }
ErrorCode Complex2AmpRaster(QString inComplexPath, QString outRasterPath)
{
gdalImageComplex inimg(inComplexPath);
gdalImage ampimg = CreategdalImage(outRasterPath, inimg.height, inimg.width, inimg.band_num, inimg.gt, inimg.projection, true, true);
long blocklines = Memory1GB * 2 / 8 / inimg.width;
blocklines = blocklines < 100 ? 100 : blocklines;
Eigen::MatrixXd imgArrb1 = Eigen::MatrixXd::Zero(blocklines, ampimg.width);
Eigen::MatrixXcd imgArr = Eigen::MatrixXcd::Zero(blocklines, inimg.width);
long startrow = 0;
for (startrow = 0; startrow < inimg.height; startrow = startrow + blocklines) {
imgArrb1 = ampimg.getData(startrow, 0, blocklines, inimg.width, 1);
imgArr = inimg.getData(startrow, 0, blocklines, inimg.width, 2);
imgArrb1 = imgArr.array().abs();
ampimg.saveImage(imgArrb1, startrow, 0, 1);
}
qDebug() << "影像写入到:" << outRasterPath;
return ErrorCode::SUCCESS;
}
ErrorCode Complex2PhaseRaster(QString inComplexPath, QString outRasterPath)
{
gdalImageComplex inimg(inComplexPath);
gdalImage ampimg = CreategdalImage(outRasterPath, inimg.height, inimg.width, inimg.band_num, inimg.gt, inimg.projection, true, true);
long blocklines = Memory1GB * 2 / 8 / inimg.width;
blocklines = blocklines < 100 ? 100 : blocklines;
Eigen::MatrixXd imgArrb1 = Eigen::MatrixXd::Zero(blocklines, ampimg.width);
Eigen::MatrixXcd imgArr = Eigen::MatrixXcd::Zero(blocklines, inimg.width);
long startrow = 0;
for (startrow = 0; startrow < inimg.height; startrow = startrow + blocklines) {
imgArrb1 = ampimg.getData(startrow, 0, blocklines, inimg.width, 1);
imgArr = inimg.getData(startrow, 0, blocklines, inimg.width, 2);
imgArrb1 = imgArr.array().arg();
ampimg.saveImage(imgArrb1, startrow, 0, 1);
}
qDebug() << "影像写入到:" << outRasterPath;
return ErrorCode::SUCCESS;
}
ErrorCode Complex2dBRaster(QString inComplexPath, QString outRasterPath)
{
gdalImageComplex inimg(inComplexPath);
gdalImage ampimg = CreategdalImage(outRasterPath, inimg.height, inimg.width, inimg.band_num, inimg.gt, inimg.projection, true, true);
long blocklines = Memory1GB * 2 / 8 / inimg.width;
blocklines = blocklines < 100 ? 100 : blocklines;
Eigen::MatrixXd imgArrb1 = Eigen::MatrixXd::Zero(blocklines, ampimg.width);
Eigen::MatrixXcd imgArr = Eigen::MatrixXcd::Zero(blocklines, inimg.width);
long startrow = 0;
for (startrow = 0; startrow < inimg.height; startrow = startrow + blocklines) {
imgArrb1 = ampimg.getData(startrow, 0, blocklines, inimg.width, 1);
imgArr = inimg.getData(startrow, 0, blocklines, inimg.width, 2);
imgArrb1 = imgArr.array().abs().log10() * 20.0;
ampimg.saveImage(imgArrb1, startrow, 0, 1);
}
qDebug() << "影像写入到:" << outRasterPath;
return ErrorCode::SUCCESS;
}
ErrorCode ResampleDEM(QString indemPath, QString outdemPath, double gridx, double gridy)
{
double gridlat = gridy / 110000.0;
double gridlon = gridx / 100000.0;
long espgcode = GetEPSGFromRasterFile(indemPath.toUtf8().constData());
if (espgcode == 4326) {
resampleRaster(indemPath.toUtf8().constData(), outdemPath.toUtf8().constData(), gridlon, gridlat);
return ErrorCode::SUCCESS;
}
else {
QMessageBox::warning(nullptr, u8"警告", u8"请输入WGS84坐标的DEM影像");
return ErrorCode::FAIL;
}
}
ErrorCode RD_PSTN(double& refrange, double& lamda, double& timeR, double& R, double& tx, double& ty, double& tz, double& slopex, double& slopey, double& slopez, GF3PolyfitSatelliteOribtModel& polyfitmodel, SatelliteOribtNode& node, double& d0, double& d1, double& d2, double& d3, double& d4) ErrorCode RD_PSTN(double& refrange, double& lamda, double& timeR, double& R, double& tx, double& ty, double& tz, double& slopex, double& slopey, double& slopez, GF3PolyfitSatelliteOribtModel& polyfitmodel, SatelliteOribtNode& node, double& d0, double& d1, double& d2, double& d3, double& d4)
{ {
double dt = 1e-6; double dt = 1e-4;
double inct = 0; double inct = 0;
bool antfalg = false; bool antfalg = false;
double timeR2 = 0; double timeR2 = 0;
@ -315,21 +231,24 @@ ErrorCode RD_PSTN(double& refrange, double& lamda, double& timeR, double& R, dou
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
polyfitmodel.getSatelliteOribtNode(timeR, node, antfalg); polyfitmodel.getSatelliteOribtNode(timeR, node, antfalg);
R1 = std::sqrt(std::pow(node.Px - tx, 2) + std::pow(node.Py - ty, 2) + std::pow(node.Pz - tz, 2)); R1 = std::sqrt(std::pow(node.Px - tx, 2) + std::pow(node.Py - ty, 2) + std::pow(node.Pz - tz, 2));
dplerTheory1 = (-2 / lamda) * (((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tz) + (node.Pz - tz) * (node.Vz - 0)) / R1); //dplerTheory1 = (-2 / lamda / R1) * ((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tx) + (node.Pz - tz) * (node.Vz - 0));
dplerR = (R1 - refrange) * 1e6 / LIGHTSPEED; dplerTheory1 = (-2 / lamda / R1) * ((node.Px - tx) * (node.Vx + 0) + (node.Py - ty) * (node.Vy -0) + (node.Pz - tz) * (node.Vz - 0));
dplerR = (R1 - refrange) * 1e6 / LIGHTSPEED; // GF3 计算公式
dplerNumber1 = d0 + dplerR * d1 + std::pow(dplerR, 2) * d2 + std::pow(dplerR, 3) * d3 + std::pow(dplerR, 4) * d4; dplerNumber1 = d0 + dplerR * d1 + std::pow(dplerR, 2) * d2 + std::pow(dplerR, 3) * d3 + std::pow(dplerR, 4) * d4;
timeR2 = timeR + dt; timeR2 = timeR + dt;
polyfitmodel.getSatelliteOribtNode(timeR2, node, antfalg); polyfitmodel.getSatelliteOribtNode(timeR2, node, antfalg);
R2 = std::sqrt(std::pow(node.Px - tx, 2) + std::pow(node.Py - ty, 2) + std::pow(node.Pz - tz, 2)); R2 = std::sqrt(std::pow(node.Px - tx, 2) + std::pow(node.Py - ty, 2) + std::pow(node.Pz - tz, 2));
dplerTheory2 = (-2 / lamda) * (((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tz) + (node.Pz - tz) * (node.Vz - 0)) / R2); //dplerTheory2 = (-2 / lamda/R2) * ((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tx) + (node.Pz - tz) * (node.Vz - 0));
dplerR = (R2 - refrange) * 1e6 / LIGHTSPEED; dplerTheory2 = (-2 / lamda/R2) * ((node.Px - tx) * (node.Vx +0) + (node.Py - ty) * (node.Vy -0) + (node.Pz - tz) * (node.Vz - 0));
dplerNumber2 = d0 + dplerR * d1 + std::pow(dplerR, 2) * d2 + std::pow(dplerR, 3) * d3 + std::pow(dplerR, 4) * d4; //dplerR = (R2 - refrange) * 1e6 / LIGHTSPEED; // GF3 计算公式
//dplerNumber2 = d0 + dplerR * d1 + std::pow(dplerR, 2) * d2 + std::pow(dplerR, 3) * d3 + std::pow(dplerR, 4) * d4;
inct = dt * (dplerTheory2 - dplerNumber1) / (dplerTheory1 - dplerTheory2); inct = dt*(dplerTheory2-dplerNumber1) / (dplerTheory2 - dplerTheory1);
if (std::abs(dplerTheory1 - dplerTheory2) < 1e-9 || std::abs(inct) < dt) { if (std::abs(dplerNumber1 - dplerTheory2) < 1e-6 || std::abs(inct) < 1.0e-4) {
break; break;
} }
inct = std::abs(inct) < 10 ?inct:inct*1e-2;
timeR = timeR - inct; timeR = timeR - inct;
} }
R = R1; // 斜距 R = R1; // 斜距
@ -349,7 +268,7 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
gdalImage rasterRC = CreategdalImage(outlooktablePath, demxyz.height, demxyz.width, 2, demxyz.gt, demxyz.projection, true, true);// X,Y,Z gdalImage rasterRC = CreategdalImage(outlooktablePath, demxyz.height, demxyz.width, 2, demxyz.gt, demxyz.projection, true, true);// X,Y,Z
gdalImage localincangleRaster; gdalImage localincangleRaster;
if (localincAngleFlag) { if (localincAngleFlag) {
localincangleRaster = CreategdalImage(outLocalIncidenceAnglePath, demxyz.height, demxyz.width, 2, demxyz.gt, demxyz.projection, true, true);// X,Y,Z localincangleRaster = CreategdalImage(outLocalIncidenceAnglePath, demxyz.height, demxyz.width, 1, demxyz.gt, demxyz.projection, true, true);// X,Y,Z
} }
@ -363,44 +282,64 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
double d3 = dopplers[3]; double d3 = dopplers[3];
double d4 = dopplers[4]; double d4 = dopplers[4];
double fs = l1dataset.getFs();// Fs采样 double fs = l1dataset.getFs()*1e6;// Fs采样
double prf = (l1dataset.getEndImageTime() - l1dataset.getStartImageTime()) / (l1dataset.getrowCount() - 1);// PRF 采样 double prf = l1dataset.getPRF();// PRF 采样
double nearRange = l1dataset.getNearRange(); double nearRange = l1dataset.getNearRange();
double imagestarttime = l1dataset.getStartImageTime(); double imagestarttime = l1dataset.getStartImageTime();
double imageendtime = l1dataset.getEndImageTime();
double refrange = l1dataset.getRefRange(); double refrange = l1dataset.getRefRange();
double lamda = (LIGHTSPEED*1e-6)/ l1dataset.getCenterFreq(); double lamda = (LIGHTSPEED*1.0e-9)/ l1dataset.getCenterFreq();
// 打印参数
qDebug() << "Fs:\t" << fs;
qDebug() << "prf:\t" << prf;
qDebug() << "nearRange:\t" << nearRange;
qDebug() << "imagestarttime:\t" << imagestarttime;
qDebug() << "imageendtime:\t" << imageendtime;
qDebug() << "refrange:\t" << refrange;
qDebug() << "lamda:\t" << lamda;
//打印多普累参数
qDebug() << u8"-----------------------------------";
qDebug() << u8"多普勒参数:\n";
qDebug() << u8"d0:\t" << d0;
qDebug() << u8"d1:\t" << d1;
qDebug() << u8"d2:\t" << d2;
qDebug() << u8"d3:\t" << d3;
qDebug() << u8"d4:\t" << d4;
qDebug() << u8"-----------------------------------";
// 构建轨道模型 // 构建轨道模型
GF3PolyfitSatelliteOribtModel polyfitmodel; GF3PolyfitSatelliteOribtModel polyfitmodel;
QVector < SatelliteAntPos > antposes = l1dataset.getXmlSateAntPos(); QVector < SatelliteAntPos > antposes = l1dataset.getXmlSateAntPos();
polyfitmodel.setSatelliteOribtStartTime(imagestarttime); polyfitmodel.setSatelliteOribtStartTime((imagestarttime+imageendtime)/2);
for (long i = 0; i < antposes.size(); i++) { for (long i = 0; i < antposes.size(); i++) {
SatelliteOribtNode node; if (antposes[i].time > imagestarttime - 5 && antposes[i].time < imageendtime + 5) {
node.time = antposes[i].time; SatelliteOribtNode node;
node.Px = antposes[i].Px; node.time = antposes[i].time;
node.Py = antposes[i].Py; node.Px = antposes[i].Px;
node.Pz = antposes[i].Pz; node.Py = antposes[i].Py;
node.Vx = antposes[i].Vx; node.Pz = antposes[i].Pz;
node.Vy = antposes[i].Vy; node.Vx = antposes[i].Vx;
node.Vz = antposes[i].Vz; node.Vy = antposes[i].Vy;
polyfitmodel.addOribtNode(node); node.Vz = antposes[i].Vz;
polyfitmodel.addOribtNode(node);
}
} }
polyfitmodel.polyFit(3, false); polyfitmodel.polyFit(3, false);
qDebug() << "-----------------------------------"; qDebug() << "-----------------------------------";
qDebug() << "satellite polyfit model params:\n"; qDebug() << u8"satellite polyfit model params:\n";
qDebug() << polyfitmodel.getSatelliteOribtModelParamsString(); qDebug() << polyfitmodel.getSatelliteOribtModelParamsString();
qDebug() << "-----------------------------------"; qDebug() << "-----------------------------------";
// 开始计算查找表 // 开始计算查找表
//1.计算分块 //1.计算分块
long cpucore_num = std::thread::hardware_concurrency(); long cpucore_num = std::thread::hardware_concurrency();
long blockline = Memory1MB * 500 / 8 / cpucore_num / 4 / l1dataset.getcolCount(); long blocklineinit = Memory1MB / 8 / cpucore_num / 4 / l1dataset.getcolCount() * 8000;
blockline = blockline < 50 ? 50 : blockline; blocklineinit = blocklineinit < 50 ? 50 : blocklineinit;
//2.迭代计算 //2.迭代计算
long colcount = l1dataset.getcolCount(); long colcount = rasterRC.width;//l1dataset.getcolCount();
long rowcount = l1dataset.getrowCount(); long rowcount = rasterRC.height;//l1dataset.getrowCount();
long startRId = 0; long startRId = 0;
long processNumber = 0; long processNumber = 0;
@ -417,33 +356,41 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
#pragma omp parallel for num_threads(cpucore_num-1)
for (startRId = 0; startRId < rowcount; startRId = startRId + blockline) { for (startRId = 0; startRId < rowcount; startRId = startRId + blocklineinit) {
long blockline = blocklineinit;
if (startRId + blockline > rowcount) {
blockline = rowcount - startRId;
}
Eigen::MatrixXd sar_r = rasterRC.getData(startRId, 0, blockline, colcount, 1); Eigen::MatrixXd sar_r = rasterRC.getData(startRId, 0, blockline, colcount, 1);
Eigen::MatrixXd sar_c = rasterRC.getData(startRId, 0, blockline, colcount, 2); Eigen::MatrixXd sar_c = rasterRC.getData(startRId, 0, blockline, colcount, 2);
Eigen::MatrixXd dem_x = demxyz.getData(startRId, 0, blockline, colcount, 1); Eigen::MatrixXd dem_x = demxyz.getData(startRId, 0, blockline, colcount, 1);
Eigen::MatrixXd dem_y = demxyz.getData(startRId, 0, blockline, colcount, 2); Eigen::MatrixXd dem_y = demxyz.getData(startRId, 0, blockline, colcount, 2);
Eigen::MatrixXd dem_z = demxyz.getData(startRId, 0, blockline, colcount, 3); Eigen::MatrixXd dem_z = demxyz.getData(startRId, 0, blockline, colcount, 3);
// 逐像素迭代计算
double timeR = 0;
long blockrows = sar_r.rows(); long blockrows = sar_r.rows();
long blockcols = sar_r.cols(); long blockcols = sar_r.cols();
double tx = 0;
double ty = 0; #pragma omp parallel for
double tz = 0;
double R = 0;
double slopex=0, slopey=0, slopez=0;
SatelliteOribtNode node{0,0,0,0,0,0,0,0};
bool antflag = false;
for (long i = 0; i < blockrows; i++) { for (long i = 0; i < blockrows; i++) {
// 逐像素迭代计算
double timeR = 0;
double tx = 0;
double ty = 0;
double tz = 0;
double R = 0;
double slopex = 0, slopey = 0, slopez = 0;
SatelliteOribtNode node{ 0,0,0,0,0,0,0,0 };
bool antflag = false;
for (long j = 0; j < blockcols; j++) { for (long j = 0; j < blockcols; j++) {
tx = dem_x(i, j); tx = dem_x(i, j);
ty = dem_y(i, j); ty = dem_y(i, j);
tz = dem_z(i, j); tz = dem_z(i, j);
if (RD_PSTN(refrange,lamda, timeR,R,tx,ty,tz,slopex,slopey,slopez,polyfitmodel,node,d0,d1,d2,d3,d4) == ErrorCode::SUCCESS) { if (RD_PSTN(refrange,lamda, timeR,R,tx,ty,tz,slopex,slopey,slopez,polyfitmodel,node,d0,d1,d2,d3,d4) == ErrorCode::SUCCESS) {
sar_r(i, j) = timeR * prf; sar_r(i, j) =( timeR+ (imagestarttime + imageendtime) / 2 -imagestarttime) * prf;
sar_c(i, j) = ((R - nearRange) / 2 / LIGHTSPEED) * fs; sar_c(i, j) = ((R - nearRange) * 2 / LIGHTSPEED) * fs;
} }
else { else {
sar_r(i, j) = -1; sar_r(i, j) = -1;
@ -452,6 +399,14 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
} }
} }
// 保存结果
omp_set_lock(&lock);
rasterRC.saveImage(sar_r, startRId, 0, 1);
rasterRC.saveImage(sar_c, startRId, 0, 2);
omp_unset_lock(&lock);
Eigen::MatrixXd Angle_Arr = Eigen::MatrixXd::Zero(dem_x.rows(),dem_x.cols()).array()+181; Eigen::MatrixXd Angle_Arr = Eigen::MatrixXd::Zero(dem_x.rows(),dem_x.cols()).array()+181;
if (localincAngleFlag) { if (localincAngleFlag) {
Eigen::MatrixXd demslope_x = demslope.getData(startRId, 0, blockline, colcount, 1); Eigen::MatrixXd demslope_x = demslope.getData(startRId, 0, blockline, colcount, 1);
@ -461,7 +416,20 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
double Rst_x = 0, Rst_y = 0, Rst_z = 0, localangle = 0; double Rst_x = 0, Rst_y = 0, Rst_z = 0, localangle = 0;
double slopeR = 0; double slopeR = 0;
#pragma omp parallel for
for (long i = 0; i < blockrows; i++) { for (long i = 0; i < blockrows; i++) {
// 逐像素迭代计算
double timeR = 0;
double tx = 0;
double ty = 0;
double tz = 0;
double R = 0;
double slopex = 0, slopey = 0, slopez = 0;
SatelliteOribtNode node{ 0,0,0,0,0,0,0,0 };
bool antflag = false;
for (long j = 0; j < blockcols; j++) { for (long j = 0; j < blockcols; j++) {
timeR = sar_r(i, j) / prf; timeR = sar_r(i, j) / prf;
slopex = demslope_x(i, j); slopex = demslope_x(i, j);
@ -482,18 +450,25 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
Angle_Arr(i, j) = localangle; Angle_Arr(i, j) = localangle;
} }
} }
// 保存结果
omp_set_lock(&lock);
if (localincAngleFlag) {
localincangleRaster.saveImage(Angle_Arr, startRId, 0, 1);
}
else {}
omp_unset_lock(&lock);
} }
// 保存结果 // 保存结果
omp_set_lock(&lock); omp_set_lock(&lock);
rasterRC.saveImage(sar_r, startRId, 0, 1);
rasterRC.saveImage(sar_c, startRId, 0, 2);
if (localincAngleFlag) {
localincangleRaster.saveImage(Angle_Arr, startRId, 0, 1);
}
else {}
processNumber = processNumber + blockrows; processNumber = processNumber + blockrows;
qDebug() << "\rprocess bar:\t" << processNumber * 100.0 / rowcount << " % " << "\t\t\t"; qDebug() << u8"\rprocess bar:\t" << processNumber * 100.0 / rowcount << " % " << "\t\t\t";
if (progressDialog.maximum() <= processNumber) { if (progressDialog.maximum() <= processNumber) {
processNumber = progressDialog.maximum() - 1; processNumber = progressDialog.maximum() - 1;
} }
@ -511,16 +486,17 @@ ErrorCode GF3OrthSLC( QString inRasterPath, QString inlooktablePath, QString out
gdalImage slcRaster(inRasterPath);// gdalImage slcRaster(inRasterPath);//
gdalImage looktableRaster(inlooktablePath);// gdalImage looktableRaster(inlooktablePath);//
gdalImage outRaster(outRasterPath);// gdalImage outRaster = CreategdalImage(outRasterPath, looktableRaster.height, looktableRaster.width, 1, looktableRaster.gt, looktableRaster.projection, true, true);// X,Y,Z
//gdalImage outRaster(outRasterPath);//
if (outRaster.height != looktableRaster.height || outRaster.width != looktableRaster.width) { if (outRaster.height != looktableRaster.height || outRaster.width != looktableRaster.width) {
qDebug() << "look table size is not same as outRaster size"<< looktableRaster.height <<"!="<<outRaster.height<<" "<<looktableRaster.width<<"!="<<outRaster.width; qDebug() << u8"look table size is not same as outRaster size"<< looktableRaster.height <<"!="<<outRaster.height<<" "<<looktableRaster.width<<"!="<<outRaster.width;
return ErrorCode::FAIL; return ErrorCode::FAIL;
} }
Eigen::MatrixXd slcImg = slcRaster.getData(0, 0, slcRaster.height, slcRaster.width, 1); Eigen::MatrixXd slcImg = slcRaster.getData(0, 0, slcRaster.height, slcRaster.width, 1);
Eigen::MatrixXd sar_r = looktableRaster.getData(0, 0, looktableRaster.height, looktableRaster.width, 1); Eigen::MatrixXd sar_r = looktableRaster.getData(0, 0, looktableRaster.height, looktableRaster.width, 1);
Eigen::MatrixXd sar_c = looktableRaster.getData(0, 0, looktableRaster.height, looktableRaster.width, 1); Eigen::MatrixXd sar_c = looktableRaster.getData(0, 0, looktableRaster.height, looktableRaster.width, 2);
Eigen::MatrixXd outImg = outRaster.getData(0, 0, outRaster.height, outRaster.width, 1); Eigen::MatrixXd outImg = outRaster.getData(0, 0, outRaster.height, outRaster.width, 1);
long lookRows = sar_r.rows(); long lookRows = sar_r.rows();
@ -549,7 +525,7 @@ ErrorCode GF3OrthSLC( QString inRasterPath, QString inlooktablePath, QString out
for (long i = 0; i < lookRows; i++) { for (long i = 0; i < lookRows; i++) {
for (long j = 0; j < lookCols; j++) { for (long j = 0; j < lookCols; j++) {
p0 = {sar_r(i,j),sar_c(i,j),0};
lastr = std::floor(sar_r(i, j)); lastr = std::floor(sar_r(i, j));
nextr = std::ceil(sar_r(i, j)); nextr = std::ceil(sar_r(i, j));
lastc = std::floor(sar_c(i, j)); lastc = std::floor(sar_c(i, j));
@ -557,11 +533,13 @@ ErrorCode GF3OrthSLC( QString inRasterPath, QString inlooktablePath, QString out
if (lastr < 0 || lastc < 0 || nextr >= slcRows || nextc >= slcCols) { if (lastr < 0 || lastc < 0 || nextr >= slcRows || nextc >= slcCols) {
continue; continue;
} }
p11 = { sar_r(i,j),sar_c(i,j),0 };
p0 = { sar_c(i,j)-lastc, sar_r(i,j)-lastr,0 };
p11 = Landpoint{ 0,0,slcImg(lastr,lastc) }; p11 = Landpoint{ 0,0,slcImg(lastr,lastc) };
p21 = Landpoint{ 0,1,slcImg(nextr,lastc) }; p21 = Landpoint{ 0,1,slcImg(nextr,lastc) };
p12 = Landpoint{ 1,0,slcImg(lastr,nextc) }; p12 = Landpoint{ 1,0,slcImg(lastr,nextc) };
p22 = Landpoint{ 1,1,slcImg(nextr,nextc) }; p22 = Landpoint{ 1,1,slcImg(nextr,nextc) };
Bileanervalue = Bilinear_interpolation(p0, p11, p21, p12, p22); Bileanervalue = Bilinear_interpolation(p0, p11, p21, p12, p22);
outImg(i, j) = Bileanervalue; outImg(i, j) = Bileanervalue;
} }
@ -585,6 +563,35 @@ ErrorCode GF3RDProcess(QString inxmlPath, QString indemPath, QString outworkdir,
double minlon = box.min_lon - dlon; double minlon = box.min_lon - dlon;
double maxlat = box.max_lat + dlat; double maxlat = box.max_lat + dlat;
double maxlon = box.max_lon + dlon; double maxlon = box.max_lon + dlon;
qDebug() << u8"影像范围:";
qDebug() << u8"Bounding Box:";
qDebug() << u8"Latitude:" << minlat <<" - "<< maxlat;
qDebug() << u8"Longitude:" << minlon <<" - "<< maxlon;
double centerlat = (minlat + maxlat) / 2;
double centerlon = (minlon + maxlon) / 2;
long sourceespgcode = getProjectEPSGCodeByLon_Lat(centerlon, centerlat);
long demespgcode = GetEPSGFromRasterFile(indemPath);
double grid_resolution = gridx < gridy ? gridx : gridy;
double degreePerPixelX = grid_resolution / 110000.0;
double degreePerPixelY = grid_resolution / 110000.0;
bool meter2degreeflag = ConvertResolutionToDegrees(
sourceespgcode,
grid_resolution,
centerlon,
centerlat,
degreePerPixelX,
degreePerPixelY
);
if (!meter2degreeflag) {
qDebug() << u8"转换分辨率为经纬度失败";
degreePerPixelX = grid_resolution / 110000.0;
degreePerPixelY = grid_resolution / 110000.0;
}
qDebug() << u8"DEM影像范围:";
qDebug() << u8"输入分辨率:"<<gridx<<" \t" << gridy;
qDebug() << u8"影像分辨率:\t" << grid_resolution;
qDebug() << u8"分辨率转换为经纬度:\t" << degreePerPixelX << "\t" << degreePerPixelY;
// 计算DEM的分辨率
// 裁剪DEM // 裁剪DEM
QString filename = getFileNameWidthoutExtend(l1dataset.getxmlFilePath()); QString filename = getFileNameWidthoutExtend(l1dataset.getxmlFilePath());
@ -592,20 +599,16 @@ ErrorCode GF3RDProcess(QString inxmlPath, QString indemPath, QString outworkdir,
QString clipDEMPath = JoinPath(outworkdir, getFileNameWidthoutExtend(indemPath) + filename + "_clip.tif"); QString clipDEMPath = JoinPath(outworkdir, getFileNameWidthoutExtend(indemPath) + filename + "_clip.tif");
cropRasterByLatLon(indemPath.toUtf8().constData(), clipDEMPath.toUtf8().constData(), minlon, maxlon, minlat, maxlat); cropRasterByLatLon(indemPath.toUtf8().constData(), clipDEMPath.toUtf8().constData(), minlon, maxlon, minlat, maxlat);
QString resampleDEMPath = JoinPath(outworkdir, getFileNameWidthoutExtend(indemPath) + filename + "_clip_resample.tif"); QString resampleDEMPath = JoinPath(outworkdir, getFileNameWidthoutExtend(indemPath) + filename + "_clip_resample.tif");
resampleRaster(clipDEMPath.toUtf8().constData(), resampleDEMPath.toUtf8().constData(), gridx, gridy); resampleRaster(clipDEMPath.toUtf8().constData(), resampleDEMPath.toUtf8().constData(), degreePerPixelX, degreePerPixelY);
QString outlooktablePath = JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_looktable.tif"); QString outlooktablePath = JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_looktable.tif");
QString outlocalAnglePath = JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_localAngle.tif"); QString outlocalAnglePath = JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_localAngle.tif");
QString outOrthPath=JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_orth.tif"); QString outOrthPath=JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_orth.tif");
if (GF3RDCreateLookTable(inxmlPath, resampleDEMPath, outworkdir, outlooktablePath, outlocalAnglePath,true) != ErrorCode::SUCCESS) { if (GF3RDCreateLookTable(inxmlPath, resampleDEMPath, outworkdir, outlooktablePath, outlocalAnglePath,true) != ErrorCode::SUCCESS) {
qDebug() << "查找表生成错误:\t" + getFileNameWidthoutExtend(inxmlPath); qDebug() << u8"查找表生成错误:\t" + getFileNameWidthoutExtend(inxmlPath);
return ErrorCode::FAIL; return ErrorCode::FAIL;
} }
return ErrorCode::SUCCESS; return ErrorCode::SUCCESS;
} }

View File

@ -17,14 +17,7 @@ QVector<QString> SearchGF3DataTiff(QString inMetaxmlPath);
POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName); POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName);
ErrorCode ImportGF3L1AProcess(QString inMetaxmlPath, QString outWorkDirPath); ErrorCode ImportGF3L1AProcess(QString inMetaxmlPath, QString outWorkDirPath);
// 复数转实部
ErrorCode Complex2AmpRaster(QString inComplexPath, QString outRasterPath);
//复数转相位
ErrorCode Complex2PhaseRaster(QString inComplexPath, QString outRasterPath);
ErrorCode Complex2dBRaster(QString inComplexPath, QString outRasterPath);
ErrorCode ResampleDEM(QString indemPath, QString outdemPath, double gridx, double gridy);
// RD Ëã·¨Àà // RD Ëã·¨Àà
ErrorCode RD_PSTN(double& refrange,double& lamda, double& timeR, double& R, double& tx, double& ty, double& tz, double& slopex, double& slopey, double& slopez, GF3PolyfitSatelliteOribtModel& polyfitmodel, SatelliteOribtNode& node,double& d0,double& d1, double& d2, double& d3, double& d4); ErrorCode RD_PSTN(double& refrange,double& lamda, double& timeR, double& R, double& tx, double& ty, double& tz, double& slopex, double& slopey, double& slopez, GF3PolyfitSatelliteOribtModel& polyfitmodel, SatelliteOribtNode& node,double& d0,double& d1, double& d2, double& d3, double& d4);
@ -36,6 +29,3 @@ ErrorCode GF3OrthSLC( QString inRasterPath, QString inlooktablePath, QString out
// ÕýÉä´¦ÀíÁ÷³Ì // ÕýÉä´¦ÀíÁ÷³Ì
ErrorCode GF3RDProcess(QString inxmlPath, QString indemPath, QString outworkdir, double gridx, double gridy); ErrorCode GF3RDProcess(QString inxmlPath, QString indemPath, QString outworkdir, double gridx, double gridy);

View File

@ -66,7 +66,7 @@ QString GF3PolyfitSatelliteOribtModel::getSatelliteOribtModelParamsString()
result += QString::number(this->polyfitVz[i], 'e', 6) + "\n"; result += QString::number(this->polyfitVz[i], 'e', 6) + "\n";
} }
result += "------------------------------------------------------\n"; result += "------------------------------------------------------\n";
printf("%s\n", result.toUtf8().constData());
return result; return result;
} }

View File

@ -5,16 +5,20 @@
#include "BaseTool.h" #include "BaseTool.h"
#include "SARSimulationImageL1.h" #include "SARSimulationImageL1.h"
#include "GF3CalibrationAndGeocodingClass.h" #include "GF3CalibrationAndGeocodingClass.h"
#include "RasterToolBase.h"
QComplex2AmpPhase::QComplex2AmpPhase(QWidget *parent) QComplex2AmpPhase::QComplex2AmpPhase(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
QObject::connect(ui.pushButtonAdd,SIGNAL(clicked(bool)),this,SLOT(onpushButtonAddClicked(bool)));
QObject::connect(ui.pushButtonRemove,SIGNAL(clicked(bool)),this,SLOT(onpushButtonRemoveClicked(bool)));
QObject::connect(ui.radioButtonAmp,SIGNAL(toggled(bool)),this,SLOT(radioButtonAmptoggled(bool))); QObject::connect(ui.radioButtonAmp,SIGNAL(toggled(bool)),this,SLOT(radioButtonAmptoggled(bool)));
QObject::connect(ui.radioButtonPhase, SIGNAL(toggled(bool)), this, SLOT(radioButtonPhasetoggled(bool))); QObject::connect(ui.radioButtonPhase, SIGNAL(toggled(bool)), this, SLOT(radioButtonPhasetoggled(bool)));
QObject::connect(ui.radioButtonSigma0, SIGNAL(toggled(bool)), this, SLOT(radioButtonSigma0toggled(bool))); QObject::connect(ui.radioButtonSigma0, SIGNAL(toggled(bool)), this, SLOT(radioButtonSigma0toggled(bool)));
QObject::connect(ui.buttonBox, SIGNAL(accept()), this, SLOT(accept())); QObject::connect(ui.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(onpushButtonWorkSpaceClicked(bool)));
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
//toggled(bool ) //toggled(bool )
} }
@ -24,7 +28,7 @@ QComplex2AmpPhase::~QComplex2AmpPhase()
} }
void QComplex2AmpPhase::accept() void QComplex2AmpPhase::onaccept()
{ {
QProgressDialog progressDialog(u8"¸´Êýת»»", u8"ÖÕÖ¹", 0, ui.listWidgetImg->count()); QProgressDialog progressDialog(u8"¸´Êýת»»", u8"ÖÕÖ¹", 0, ui.listWidgetImg->count());
progressDialog.setWindowTitle(u8"¸´Êýת»»"); progressDialog.setWindowTitle(u8"¸´Êýת»»");
@ -44,26 +48,26 @@ void QComplex2AmpPhase::accept()
slcl1.Open(folderpath, filename); slcl1.Open(folderpath, filename);
QString l2bfilename = filename + ui.lineEditHZ->text(); QString l2bfilename = filename + ui.lineEditHZ->text();
SARSimulationImageL1Dataset l1B(RasterLevel::RasterL1B); SARSimulationImageL1Dataset l1B(RasterLevel::RasterL1B);
slcl1.OpenOrNew(outworkdir, l2bfilename,slcl1.getrowCount(),slcl1.getcolCount()); l1B.OpenOrNew(outworkdir, l2bfilename,slcl1.getrowCount(),slcl1.getcolCount());
QString srcxmlpath = slcl1.getxmlFilePath(); QString srcxmlpath = slcl1.getxmlFilePath();
QString tarxmlpath = l1B.getxmlFilePath(); QString tarxmlpath = l1B.getxmlFilePath();
copyAndReplaceFile(srcxmlpath, tarxmlpath); copyAndReplaceFile(srcxmlpath, tarxmlpath);
l1B.loadFromXml(); l1B.loadFromXml();
if (ui.radioButtonAmp->isChecked()) { if (ui.radioButtonAmp->isChecked()) {
Complex2AmpRaster(imgfilepath, slcl1.getImageRasterPath()); Complex2AmpRaster(imgfilepath, l1B.getImageRasterPath());
} }
else if (ui.radioButtonPhase->isChecked()) { else if (ui.radioButtonPhase->isChecked()) {
Complex2PhaseRaster(imgfilepath, slcl1.getImageRasterPath()); Complex2PhaseRaster(imgfilepath, l1B.getImageRasterPath());
} }
else if (ui.radioButtonSigma0->isChecked()) { else if (ui.radioButtonSigma0->isChecked()) {
Complex2dBRaster(imgfilepath, slcl1.getImageRasterPath()); Complex2dBRaster(imgfilepath, l1B.getImageRasterPath());
} }
progressDialog.setValue(i); progressDialog.setValue(i);
} }
progressDialog.close(); progressDialog.close();
} }
void QComplex2AmpPhase::reject() void QComplex2AmpPhase::onreject()
{ {
this->close(); this->close();
} }

View File

@ -13,8 +13,8 @@ public:
public slots: public slots:
void accept(); void onaccept();
void reject(); void onreject();
void onpushButtonAddClicked(bool); void onpushButtonAddClicked(bool);
void onpushButtonRemoveClicked(bool); void onpushButtonRemoveClicked(bool);
void onpushButtonWorkSpaceClicked(bool); void onpushButtonWorkSpaceClicked(bool);

View File

@ -55,6 +55,7 @@ void QDEMResampleDialog::onoutDEMSelectBtnClicked(bool flag)
void QDEMResampleDialog::onAccepted() void QDEMResampleDialog::onAccepted()
{ {
this->hide();
double gridx = ui->doubleSpinBoxGridX->value(); double gridx = ui->doubleSpinBoxGridX->value();
double gridy = ui->doubleSpinBoxGridY->value(); double gridy = ui->doubleSpinBoxGridY->value();
@ -103,6 +104,8 @@ void QDEMResampleDialog::onAccepted()
outDEMPath.toLocal8Bit().constData(), gt.get(), new_width, new_height, GDALResampleAlg::GRA_Bilinear); outDEMPath.toLocal8Bit().constData(), gt.get(), new_width, new_height, GDALResampleAlg::GRA_Bilinear);
qDebug() << "DEM ReSample finished!!!"; qDebug() << "DEM ReSample finished!!!";
this->show();
QMessageBox::information(this, tr(u8"Ìáʾ"), tr(u8"completed!!!"));
} }
void QDEMResampleDialog::onRejected() void QDEMResampleDialog::onRejected()

View File

@ -7,11 +7,11 @@ QImportGF3StripL1ADataset::QImportGF3StripL1ADataset(QWidget *parent)
{ {
ui.setupUi(this); ui.setupUi(this);
QListWidget* listWidgetMetaxml; QObject::connect(ui.pushButtonAdd,SIGNAL(clicked(bool)),this,SLOT(onpushButtonAddClicked(bool)));
QObject::connect( ui.pushButtonAdd,SIGNAL(clicked(clicked)),this,SLOT(onpushButtonAddClicked(bool))); QObject::connect(ui.pushButtonRemove, SIGNAL(clicked(bool)), this, SLOT(onpushButtonRemoveClicked(bool)));
QObject::connect(ui.pushButtonRemove, SIGNAL(clicked(clicked)), this, SLOT(onpushButtonRemoveClicked(bool))); QObject::connect(ui.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(onpushButtonWorkSpaceClicked(bool)));
QObject::connect(ui.pushButtonWorkSpace, SIGNAL(clicked(clicked)), this, SLOT(onpushButtonWorkSpaceClicked(bool))); QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
} }
@ -20,7 +20,7 @@ QImportGF3StripL1ADataset::~QImportGF3StripL1ADataset()
} }
void QImportGF3StripL1ADataset::accept() void QImportGF3StripL1ADataset::onaccept()
{ {
QProgressDialog progressDialog(u8"µ¼ÈëGF3Ìõ´øL1AÓ°Ïñ", u8"ÖÕÖ¹", 0, ui.listWidgetMetaxml->count()); QProgressDialog progressDialog(u8"µ¼ÈëGF3Ìõ´øL1AÓ°Ïñ", u8"ÖÕÖ¹", 0, ui.listWidgetMetaxml->count());
progressDialog.setWindowTitle(u8"µ¼ÈëGF3Ìõ´øL1AÓ°Ïñ"); progressDialog.setWindowTitle(u8"µ¼ÈëGF3Ìõ´øL1AÓ°Ïñ");
@ -40,7 +40,7 @@ void QImportGF3StripL1ADataset::accept()
progressDialog.close(); progressDialog.close();
} }
void QImportGF3StripL1ADataset::reject() void QImportGF3StripL1ADataset::onreject()
{ {
this->close(); this->close();
} }

View File

@ -14,8 +14,8 @@ public:
~QImportGF3StripL1ADataset(); ~QImportGF3StripL1ADataset();
public slots: public slots:
void accept(); void onaccept();
void reject(); void onreject();
void onpushButtonAddClicked(bool); void onpushButtonAddClicked(bool);
void onpushButtonRemoveClicked(bool); void onpushButtonRemoveClicked(bool);
void onpushButtonWorkSpaceClicked(bool); void onpushButtonWorkSpaceClicked(bool);

View File

@ -14,15 +14,16 @@ QOrthSlrRaster::QOrthSlrRaster(QWidget *parent)
connect(ui.pushButtonAdd, SIGNAL(clicked(bool)), this, SLOT(onpushButtonAddClicked(bool))); connect(ui.pushButtonAdd, SIGNAL(clicked(bool)), this, SLOT(onpushButtonAddClicked(bool)));
connect(ui.pushButtonRemove, SIGNAL(clicked(bool)), this, SLOT(onpushButtonRemoveClicked(bool))); connect(ui.pushButtonRemove, SIGNAL(clicked(bool)), this, SLOT(onpushButtonRemoveClicked(bool)));
connect(ui.pushButtonDEMSelect, SIGNAL(clicked(bool)), this, SLOT(onpushButtonWorkSpaceClicked(bool))); connect(ui.pushButtonDEMSelect, SIGNAL(clicked(bool)), this, SLOT(pushButtonDEMSelectClicked(bool)));
connect(ui.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(pushButtonDEMSelectClicked(bool))); connect(ui.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(onpushButtonWorkSpaceClicked(bool)));
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
} }
QOrthSlrRaster::~QOrthSlrRaster() QOrthSlrRaster::~QOrthSlrRaster()
{} {}
void QOrthSlrRaster::accept() void QOrthSlrRaster::onaccept()
{ {
QToolProcessBarDialog* processdialog = new QToolProcessBarDialog(this); QToolProcessBarDialog* processdialog = new QToolProcessBarDialog(this);
processdialog->show(); processdialog->show();
@ -49,7 +50,7 @@ void QOrthSlrRaster::accept()
processdialog->close(); processdialog->close();
} }
void QOrthSlrRaster::reject() void QOrthSlrRaster::onreject()
{ {
this->close(); this->close();
} }
@ -60,7 +61,7 @@ void QOrthSlrRaster::onpushButtonAddClicked(bool)
this, // 父窗口 this, // 父窗口
tr(u8"选择xml文件"), // 标题 tr(u8"选择xml文件"), // 标题
QString(), // 默认路径 QString(), // 默认路径
tr(u8"xml Files (*.xml);;All Files (*)") // Îļþ¹ýÂËÆ÷ tr(ENVI_FILE_FORMAT_FILTER) // Îļþ¹ýÂËÆ÷
); );
// 如果用户选择了文件 // 如果用户选择了文件

View File

@ -16,8 +16,8 @@ private:
public slots: public slots:
void accept(); void onaccept();
void reject(); void onreject();
void onpushButtonAddClicked(bool); void onpushButtonAddClicked(bool);
void onpushButtonRemoveClicked(bool); void onpushButtonRemoveClicked(bool);
void onpushButtonWorkSpaceClicked(bool); void onpushButtonWorkSpaceClicked(bool);

View File

@ -10,9 +10,10 @@ QRDOrthProcessClass::QRDOrthProcessClass(QWidget *parent)
connect(ui.pushButtonAdd,SIGNAL(clicked(bool)),this,SLOT(onpushButtonAddClicked(bool))); connect(ui.pushButtonAdd,SIGNAL(clicked(bool)),this,SLOT(onpushButtonAddClicked(bool)));
connect(ui.pushButtonRemove,SIGNAL(clicked(bool)),this,SLOT(onpushButtonRemoveClicked(bool))); connect(ui.pushButtonRemove,SIGNAL(clicked(bool)),this,SLOT(onpushButtonRemoveClicked(bool)));
connect(ui.pushButtonDEMSelect,SIGNAL(clicked(bool)),this,SLOT(onpushButtonWorkSpaceClicked(bool))); connect(ui.pushButtonWorkSpace,SIGNAL(clicked(bool)),this,SLOT(onpushButtonWorkSpaceClicked(bool)));
connect(ui.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(pushButtonDEMSelectClicked(bool))); connect(ui.pushButtonDEMSelect, SIGNAL(clicked(bool)), this, SLOT(pushButtonDEMSelectClicked(bool)));
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
// QDialogButtonBox* buttonBox; // QDialogButtonBox* buttonBox;
//QLineEdit* lineEditDEM; //QLineEdit* lineEditDEM;
//QLineEdit* lineEditWorkDir; //QLineEdit* lineEditWorkDir;
@ -22,7 +23,7 @@ QRDOrthProcessClass::QRDOrthProcessClass(QWidget *parent)
QRDOrthProcessClass::~QRDOrthProcessClass() QRDOrthProcessClass::~QRDOrthProcessClass()
{} {}
void QRDOrthProcessClass::accept() void QRDOrthProcessClass::onaccept()
{ {
QToolProcessBarDialog* processdialog = new QToolProcessBarDialog(this); QToolProcessBarDialog* processdialog = new QToolProcessBarDialog(this);
processdialog->show(); processdialog->show();
@ -52,7 +53,7 @@ void QRDOrthProcessClass::accept()
processdialog->close(); processdialog->close();
} }
void QRDOrthProcessClass::reject() void QRDOrthProcessClass::onreject()
{ {
this->close(); this->close();
} }

Some files were not shown because too many files have changed in this diff Show More