Merge pull request 'RFPC-dev-a2806' (#10) from RFPC-dev-a2806 into Release
Reviewed-on: http://123.153.4.249:22779/LAMPSARToolSoftware/RasterProcessTool/pulls/10Release
commit
b8ca064e79
|
@ -196,9 +196,6 @@
|
|||
<ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj">
|
||||
<Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ImageshowTool\ImageshowTool.vcxproj">
|
||||
<Project>{8c8ca066-a93a-4098-9a46-b855efeaadf2}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LAMPDataProcessEXE\LAMPDataProcessEXE.vcxproj">
|
||||
<Project>{4e6e79a3-048c-4fb4-bbb0-43c518a3e6d4}</Project>
|
||||
</ProjectReference>
|
||||
|
@ -211,9 +208,6 @@
|
|||
<ProjectReference Include="..\Toolbox\BaseToolbox\BaseToolbox.vcxproj">
|
||||
<Project>{070c157e-3c30-4e2b-a80c-cbc7b74df03f}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Toolbox\LAMPScatterTool\LAMPScatterTool.vcxproj">
|
||||
<Project>{d603a623-132d-4304-ab03-638fc438f084}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Toolbox\SimulationSARTool\SimulationSARTool.vcxproj">
|
||||
<Project>{ed06dfcd-4b9f-41f7-8f25-1823c2398142}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -220,10 +220,13 @@
|
|||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<OpenMPSupport>true</OpenMPSupport>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -274,11 +277,12 @@
|
|||
<ClInclude Include="BaseTool\GeoOperator.h" />
|
||||
<ClInclude Include="BaseTool\ImageOperatorBase.h" />
|
||||
<ClInclude Include="BaseTool\LogInfoCls.h" />
|
||||
<QtMoc Include="ToolAbstract\QToolAbstract.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\RasterToolBase.h" />
|
||||
<ClInclude Include="BaseTool\SARSimulationImageL1.h" />
|
||||
<ClInclude Include="BaseTool\stdafx.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
|
@ -287,15 +291,20 @@
|
|||
<ClCompile Include="BaseTool\BaseTool.cpp" />
|
||||
<ClCompile Include="BaseTool\EchoDataFormat.cpp" />
|
||||
<ClCompile Include="BaseTool\FileOperator.cpp" />
|
||||
<ClCompile Include="BaseTool\gdalImageComplexOperator.cpp" />
|
||||
<ClCompile Include="BaseTool\gdalImageOperator.cpp" />
|
||||
<ClCompile Include="BaseTool\GeoOperator.cpp" />
|
||||
<ClCompile Include="BaseTool\ImageOperatorBase.cpp" />
|
||||
<ClCompile Include="BaseTool\LogInfoCls.cpp" />
|
||||
<ClCompile Include="BaseTool\MergeRasterOperator.cpp" />
|
||||
<ClCompile Include="BaseTool\PrintMsgToQDebug.cpp" />
|
||||
<ClCompile Include="BaseTool\QToolProcessBarDialog.cpp" />
|
||||
<ClCompile Include="BaseTool\RasterToolBase.cpp" />
|
||||
<ClCompile Include="BaseTool\SARSimulationImageL1.cpp" />
|
||||
<ClCompile Include="BaseTool\ShowProessAbstract.cpp" />
|
||||
<ClCompile Include="BaseTool\stdafx.cpp" />
|
||||
<ClCompile Include="BaseTool\TestImageOperator.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="ImageOperatorFuntion.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||
|
|
|
@ -33,33 +33,36 @@
|
|||
<ClInclude Include="BaseTool\BaseTool.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\EchoDataFormat.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\FileOperator.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\GeoOperator.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\ImageOperatorBase.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\LogInfoCls.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\RasterToolBase.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\SARSimulationImageL1.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\stdafx.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BaseTool\PrintMsgToQDebug.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</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>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
|
@ -71,30 +74,18 @@
|
|||
<ClCompile Include="BaseTool\BaseTool.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\EchoDataFormat.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\FileOperator.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\GeoOperator.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\ImageOperatorBase.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\LogInfoCls.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\QToolProcessBarDialog.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\RasterToolBase.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\SARSimulationImageL1.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BaseTool\stdafx.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</ClCompile>
|
||||
|
@ -104,16 +95,45 @@
|
|||
<ClCompile Include="BaseTool\PrintMsgToQDebug.cpp">
|
||||
<Filter>BaseTool</Filter>
|
||||
</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>
|
||||
<QtMoc Include="BaseTool\QToolProcessBarDialog.h">
|
||||
<Filter>头文件</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="ToolAbstract\QToolAbstract.h">
|
||||
<Filter>ToolAbstract</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="BaseTool\QToolProcessBarDialog.h">
|
||||
<Filter>BaseTool</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="BaseTool\QToolProcessBarDialog.ui" />
|
||||
<QtUic Include="BaseTool\QToolProcessBarDialog.ui">
|
||||
<Filter>BaseTool</Filter>
|
||||
</QtUic>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -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_LAPACK
|
||||
#define EIGEN_VECTORIZE_SSE2
|
||||
//
|
||||
//#define EIGEN_USE_BLAS
|
||||
//#define EIGEN_USE_LAPACK
|
||||
//#define EIGEN_VECTORIZE_SSE2
|
||||
|
||||
//#define DEBUGSHOWDIALOG
|
||||
|
||||
|
@ -49,7 +52,7 @@ inline char* get_cur_time() {
|
|||
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; }
|
||||
};
|
||||
|
||||
struct Point_3d {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct DemBox {
|
||||
double min_lon;
|
||||
double max_lon;
|
||||
|
@ -154,7 +165,7 @@ struct Vector3_single {
|
|||
|
||||
|
||||
/*********************************************** FEKO仿真参数 ********************************************************************/
|
||||
struct SatellitePos {
|
||||
extern "C" struct SatellitePos {
|
||||
double time;
|
||||
double Px ;
|
||||
double Py ;
|
||||
|
@ -165,7 +176,7 @@ struct SatellitePos {
|
|||
};
|
||||
|
||||
|
||||
struct SatelliteAntPos {
|
||||
extern "C" struct SatelliteAntPos {
|
||||
double time; // 0
|
||||
double Px;
|
||||
double Py;
|
||||
|
@ -188,7 +199,7 @@ struct SatelliteAntPos {
|
|||
};
|
||||
|
||||
|
||||
struct PatternImageDesc {
|
||||
extern "C" struct PatternImageDesc {
|
||||
long phinum;
|
||||
long thetanum;
|
||||
double startTheta;
|
||||
|
@ -307,7 +318,7 @@ inline void delArrPtr(void* p)
|
|||
}
|
||||
delete[] p;
|
||||
p = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
inline void delPointer(void* p)
|
||||
{
|
||||
|
@ -316,28 +327,34 @@ inline void delPointer(void* p)
|
|||
}
|
||||
delete p;
|
||||
p = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
inline void PrintTime() {
|
||||
time_t current_time;
|
||||
time(¤t_time);
|
||||
printf("Current timestamp in seconds: %ld\n", (long)current_time);
|
||||
}
|
||||
};
|
||||
|
||||
/** 计算分块 ******************************************************************/
|
||||
|
||||
inline long getBlockRows(long sizeMB, long cols,long sizeMeta,long maxRows) {
|
||||
long rownum= (round(Memory1MB * 1.0 / sizeMeta / cols * sizeMB) + cols - 1);
|
||||
inline long getBlockRows(long sizeMB, long cols, long sizeMeta, long maxRows) {
|
||||
long rownum = (round(Memory1MB * 1.0 / sizeMeta / cols * sizeMB) + cols - 1);
|
||||
rownum = rownum < 0 ? 1 : rownum;
|
||||
rownum =rownum < maxRows ? rownum : maxRows;
|
||||
rownum = rownum < maxRows ? rownum : maxRows;
|
||||
return rownum;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline long nextpow2(long n) {
|
||||
long en = ceil(log2(n));
|
||||
return pow(2,en);
|
||||
}
|
||||
return pow(2, en);
|
||||
};
|
||||
|
||||
inline void releaseVoidArray(void* a)
|
||||
{
|
||||
free(a);
|
||||
a = NULL;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "stdafx.h"
|
||||
#define EIGEN_USE_BLAS
|
||||
//#define EIGEN_USE_BLAS
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
//#include <mkl.h>
|
||||
|
||||
|
@ -38,7 +38,10 @@
|
|||
#include <xmmintrin.h> // 包含SSE指令集头文件
|
||||
#include <emmintrin.h> // 包含SSE2指令集头文件
|
||||
#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) {
|
||||
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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
#include <QDebug>
|
||||
#include <iomanip>
|
||||
#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);
|
||||
|
||||
|
||||
QDateTime BASECONSTVARIABLEAPI parseCustomDateTime(const QString& dateTimeStr);
|
||||
/// <summary>
|
||||
/// list 应该是按照从小到大的顺序排好
|
||||
/// </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::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>
|
||||
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++) {
|
||||
ptr.get()[i] = ti;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline void memcpyArray(std::shared_ptr<T> srct, std::shared_ptr<T> dest, long arrcount) {
|
||||
for (long i = 0; i < arrcount; i++) {
|
||||
dest.get()[i] = srct.get()[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
@ -159,7 +187,7 @@ inline void minValueInArr(T* ptr, long arrcount, T& minvalue) {
|
|||
minvalue = ptr[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -182,7 +210,7 @@ inline void maxValueInArr(T* ptr, long arrcount, T& maxvalue) {
|
|||
template<typename T>
|
||||
inline T complexAbs(std::complex<T> ccdata) {
|
||||
return T(sqrt(pow(ccdata.real(), 2) + pow(ccdata.imag(), 2)));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
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]));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -234,6 +234,7 @@ ErrorCode EchoL0Dataset::Open(QString folder, QString filename)
|
|||
{
|
||||
return ErrorCode::ECHO_L0DATA_ECHOFILEFORMATERROR;
|
||||
}
|
||||
return ErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
QString EchoL0Dataset::getxmlName()
|
||||
|
@ -511,6 +512,19 @@ ErrorCode EchoL0Dataset::loadFromXml() {
|
|||
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()
|
||||
{
|
||||
omp_lock_t lock;
|
||||
|
@ -592,6 +606,66 @@ std::shared_ptr<std::complex<double>> EchoL0Dataset::getEchoArr(long startPRF, l
|
|||
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()
|
||||
{
|
||||
return this->getEchoArr(0,this->PluseCount);
|
||||
|
@ -674,8 +748,10 @@ ErrorCode EchoL0Dataset::saveEchoArr(std::shared_ptr<std::complex<double>> echoP
|
|||
}
|
||||
GDALClose(rasterDataset);
|
||||
rasterDataset = nullptr;
|
||||
GDALDestroy();
|
||||
omp_unset_lock(&lock); //
|
||||
omp_destroy_lock(&lock); //
|
||||
|
||||
return ErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,9 +209,11 @@ public: //
|
|||
|
||||
public:
|
||||
// 读取文件
|
||||
std::shared_ptr< SatelliteAntPos> getAntPosVelc();
|
||||
std::shared_ptr<double> getAntPos();
|
||||
std::shared_ptr<std::complex<double>> getEchoArr(long startPRF, long& PRFLen);
|
||||
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 saveEchoArr(std::shared_ptr<std::complex<double>> echoPtr, long startPRF, long PRFLen);
|
||||
|
|
|
@ -93,7 +93,8 @@ QString getFileNameFromPath(const QString& path)
|
|||
QString getFileNameWidthoutExtend(QString path)
|
||||
{
|
||||
QFileInfo fileInfo(path);
|
||||
QString fileNameWithoutExtension = fileInfo.baseName(); // 获取无后缀文件名
|
||||
QString fileNameWithoutExtension = fileInfo.completeBaseName(); // 获取无后缀文件名
|
||||
qDebug() << u8"File name without extension: " << fileNameWithoutExtension;
|
||||
return fileNameWithoutExtension;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ unsigned long BASECONSTVARIABLEAPI convertToULong(const QString& input);
|
|||
/// <param name="folderpath"></param>
|
||||
/// <param name="FilenameExtension"></param>
|
||||
/// <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);
|
||||
|
||||
|
@ -41,11 +41,11 @@ QString BASECONSTVARIABLEAPI getFileExtension(QString path);
|
|||
|
||||
int BASECONSTVARIABLEAPI write_binfile(char* filepath, char* data, size_t data_len);
|
||||
|
||||
char* read_textfile(char* text_path, int* length);
|
||||
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);
|
||||
void BASECONSTVARIABLEAPI copyFile(const QString& sourcePath, const QString& destinationPath);
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
#include <fstream>
|
||||
#include <proj.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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -408,3 +448,53 @@ double getlocalIncAngle(Vector3D& satepoint, Vector3D& landpoint, Vector3D& slop
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ Eigen::MatrixXd BASECONSTVARIABLEAPI LLA2XYZ(Eigen::MatrixXd landpoint);
|
|||
/// <returns>经纬度--degree</returns>
|
||||
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);
|
||||
|
||||
|
@ -123,4 +124,24 @@ CartesianCoordinates BASECONSTVARIABLEAPI sphericalToCartesian(const Spheric
|
|||
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
|
File diff suppressed because it is too large
Load Diff
|
@ -28,6 +28,9 @@
|
|||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <functional>
|
||||
#include "ShowProessAbstract.h"
|
||||
|
||||
|
||||
|
||||
enum ProjectStripDelta {
|
||||
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 lat 纬度
|
||||
/// \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);
|
||||
|
||||
|
@ -139,10 +135,10 @@ GDALDataType BASECONSTVARIABLEAPI getGDALDataType(QString fileptah);
|
|||
|
||||
|
||||
struct RasterExtend {
|
||||
double min_x; //纬度
|
||||
double min_y;//经度
|
||||
double max_x;//纬度
|
||||
double max_y;//经度
|
||||
double min_x;
|
||||
double min_y;
|
||||
double max_x;
|
||||
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<int>, int start_row, int start_col, int rowcount, int colcount, int band_ids);
|
||||
|
||||
|
||||
|
||||
virtual void saveImage();
|
||||
virtual void setNoDataValue(double nodatavalue, int band_ids);
|
||||
virtual void setNoDataValuei(int nodatavalue, int band_ids);
|
||||
|
@ -201,6 +195,10 @@ public: // 方法
|
|||
|
||||
virtual RasterExtend getExtend();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
QString img_path; // 图像文件
|
||||
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);
|
||||
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();
|
||||
public:
|
||||
Eigen::MatrixXcd data;
|
||||
};
|
||||
|
||||
|
||||
bool BASECONSTVARIABLEAPI CopyProjectTransformMatrixFromRasterAToRasterB(QString RasterAPath, QString RasterBPath);
|
||||
|
||||
|
||||
// 创建影像
|
||||
gdalImage BASECONSTVARIABLEAPI CreategdalImageDouble(QString& img_path, int height, int width, int band_num, bool overwrite = false, bool isEnvi = false);
|
||||
gdalImage BASECONSTVARIABLEAPI 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 CreategdalImageFloat(QString& img_path, int height, int width, int band_num, bool overwrite = false, bool isEnvi = false);
|
||||
gdalImage BASECONSTVARIABLEAPI CreategdalImageDouble(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection, bool need_gt = true, bool overwrite = false, bool isEnvi = false);
|
||||
gdalImage BASECONSTVARIABLEAPI CreategdalImage(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection,bool need_gt = true, bool overwrite = false, bool isEnvi = false, GDALDataType datetype = GDT_Float32);
|
||||
gdalImage BASECONSTVARIABLEAPI CreategdalImage(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, long espgcode, GDALDataType eType = GDT_Float32, bool need_gt = true, bool overwrite = false, bool isENVI = false);
|
||||
|
||||
gdalImageComplex BASECONSTVARIABLEAPI CreategdalImageComplex(const QString& img_path, int height, int width, int band_num, Eigen::MatrixXd gt, QString projection, bool need_gt = true, bool overwrite = false);
|
||||
gdalImageComplex BASECONSTVARIABLEAPI CreategdalImageComplexNoProj(const QString& img_path, int height, int width, int band_num, bool overwrite = true);
|
||||
|
@ -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 = {});
|
||||
|
||||
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>
|
||||
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); // 劫伙拷斤拷
|
||||
GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
|
@ -586,7 +609,7 @@ inline std::shared_ptr<T> readDataArrComplex(gdalImageComplex& imgds, long start
|
|||
omp_destroy_lock(&lock); // 劫伙拷斤拷
|
||||
GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -15,6 +15,8 @@
|
|||
#include <QTextCodec>
|
||||
#include <iostream>
|
||||
#include <QFile>
|
||||
#include "SARSimulationImageL1.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace RasterToolBase {
|
||||
long getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState)
|
||||
|
@ -261,8 +263,14 @@ namespace RasterToolBase {
|
|||
} else if(oSRS.IsProjected()) {
|
||||
return CoordinateSystemType::ProjectCoordinateSystem;
|
||||
}
|
||||
else {
|
||||
return CoordinateSystemType::UNKNOW;
|
||||
}
|
||||
} else {
|
||||
return CoordinateSystemType::UNKNOW;
|
||||
}
|
||||
}
|
||||
} // namespace RasterToolBase
|
||||
}; // namespace RasterToolBase
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -12,40 +12,42 @@
|
|||
#include "BaseConstVariable.h"
|
||||
#include "gdal_priv.h"
|
||||
#include <memory>
|
||||
#include "LogInfoCls.h"
|
||||
|
||||
|
||||
namespace RasterToolBase {
|
||||
|
||||
static bool GDALAllRegisterEnable=false;
|
||||
static bool GDALAllRegisterEnable = false;
|
||||
|
||||
|
||||
enum ProjectStripDelta{
|
||||
enum ProjectStripDelta {
|
||||
Strip_6, // 6度带
|
||||
Strip_3
|
||||
};
|
||||
|
||||
enum CoordinateSystemType{ // 坐标系类型
|
||||
enum CoordinateSystemType { // 坐标系类型
|
||||
GeoCoordinateSystem,
|
||||
ProjectCoordinateSystem,
|
||||
UNKNOW
|
||||
};
|
||||
|
||||
struct PointRaster{ // 影像坐标点
|
||||
struct PointRaster { // 影像坐标点
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
};
|
||||
|
||||
|
||||
struct PointXYZ{
|
||||
double x,y,z;
|
||||
struct PointXYZ {
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
struct PointGeo{
|
||||
double lon,lat,ati;
|
||||
struct PointGeo {
|
||||
double lon, lat, ati;
|
||||
};
|
||||
|
||||
struct PointImage{
|
||||
double pixel_x,pixel_y;
|
||||
struct PointImage {
|
||||
double pixel_x, pixel_y;
|
||||
};
|
||||
|
||||
/// 根据经纬度获取
|
||||
|
@ -56,14 +58,14 @@ namespace RasterToolBase {
|
|||
/// \param lat 纬度
|
||||
/// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误
|
||||
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_inStrip6(double lon, double lat);
|
||||
|
||||
|
||||
QString BASECONSTVARIABLEAPI GetProjectionNameFromEPSG(long epsgCode) ;
|
||||
QString BASECONSTVARIABLEAPI GetProjectionNameFromEPSG(long epsgCode);
|
||||
|
||||
|
||||
long BASECONSTVARIABLEAPI GetEPSGFromRasterFile(QString filepath);
|
||||
|
@ -72,9 +74,23 @@ namespace RasterToolBase {
|
|||
|
||||
CoordinateSystemType BASECONSTVARIABLEAPI getCoordinateSystemTypeByEPSGCode(long EPSGCODE);
|
||||
|
||||
};// namespace RasterProjectConvertor
|
||||
|
||||
|
||||
|
||||
|
||||
// 遥感类常用数据
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace RasterProjectConvertor
|
||||
|
||||
#endif // LAMPCAE_RASTERTOOLBASE_H
|
||||
|
|
|
@ -106,7 +106,7 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
|
|||
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_init_lock(&lock);
|
||||
|
@ -122,7 +122,7 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
|
|||
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;
|
||||
|
@ -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;
|
||||
|
@ -150,11 +150,11 @@ ErrorCode SARSimulationImageL1Dataset::OpenOrNew(QString folder, QString filenam
|
|||
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
||||
|
||||
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("ENVI");
|
||||
std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->ImageRasterPath.toUtf8().constData(), colCount, rowCount, 1, GDT_CFloat32, NULL));
|
||||
std::shared_ptr<GDALDataset> poDstDS(poDriver->Create(this->GPSPointFilePath.toUtf8().constData(), 19, rowCount, 1, GDT_Float64, NULL));
|
||||
GDALFlushCache((GDALDatasetH)poDstDS.get());
|
||||
poDstDS.reset();
|
||||
omp_unset_lock(&lock); //
|
||||
omp_destroy_lock(&lock); //
|
||||
omp_unset_lock(&lock);
|
||||
omp_destroy_lock(&lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,7 +203,7 @@ ErrorCode SARSimulationImageL1Dataset::Open(QString xmlPath)
|
|||
QFileInfo fileInfo(xmlPath);
|
||||
QString fileName = fileInfo.fileName(); // 获取文件名
|
||||
QString fileSuffix = fileInfo.suffix(); // 获取后缀名
|
||||
QString fileNameWithoutSuffix = fileInfo.baseName(); // »ñÈ¡²»´øºó׺µÄÎļþÃû
|
||||
QString fileNameWithoutSuffix = fileInfo.completeBaseName(); // »ñÈ¡²»´øºó׺µÄÎļþÃû
|
||||
QString directoryPath = fileInfo.path(); // 获取文件夹路径
|
||||
if (fileSuffix.toLower() == "xml" || fileSuffix.toLower() == ".xml") {
|
||||
return this->Open(directoryPath, fileNameWithoutSuffix);
|
||||
|
@ -246,12 +246,13 @@ void SARSimulationImageL1Dataset::saveToXml()
|
|||
|
||||
xmlWriter.writeTextElement("RowCount", QString::number(this->rowCount));
|
||||
xmlWriter.writeTextElement("ColCount", QString::number(this->colCount));
|
||||
xmlWriter.writeTextElement("Rnear", QString::number(this->Rnear));
|
||||
xmlWriter.writeTextElement("Rfar", QString::number(this->Rfar));
|
||||
xmlWriter.writeTextElement("Rref", QString::number(this->Rref));
|
||||
xmlWriter.writeTextElement("CenterFreq", QString::number(this->centerFreq));
|
||||
xmlWriter.writeTextElement("Fs", QString::number(this->Fs));
|
||||
xmlWriter.writeTextElement("CenterAngle", QString::number(this->CenterAngle));
|
||||
xmlWriter.writeTextElement("Rnear", QString::number(this->Rnear, 'e', 18));
|
||||
xmlWriter.writeTextElement("Rfar", QString::number(this->Rfar, 'e', 18));
|
||||
xmlWriter.writeTextElement("Rref", QString::number(this->Rref, 'e', 18));
|
||||
xmlWriter.writeTextElement("CenterFreq", QString::number(this->centerFreq, 'e', 18));
|
||||
xmlWriter.writeTextElement("Fs", QString::number(this->Fs, 'e', 18));
|
||||
xmlWriter.writeTextElement("PRF", QString::number(this->prf, 'e', 18));
|
||||
xmlWriter.writeTextElement("CenterAngle", QString::number(this->CenterAngle, 'e', 18));
|
||||
xmlWriter.writeTextElement("LookSide", this->LookSide);
|
||||
|
||||
// 保存sateantpos
|
||||
|
@ -259,60 +260,60 @@ void SARSimulationImageL1Dataset::saveToXml()
|
|||
|
||||
for (long i = 0; i < this->sateposes.count(); i++) {
|
||||
xmlWriter.writeStartElement("AntPosParam");
|
||||
xmlWriter.writeTextElement("time", QString::number(this->sateposes[i].time)); // time
|
||||
xmlWriter.writeTextElement("Px", QString::number(this->sateposes[i].Px)); // Px
|
||||
xmlWriter.writeTextElement("Py", QString::number(this->sateposes[i].Py)); // Py
|
||||
xmlWriter.writeTextElement("Pz", QString::number(this->sateposes[i].Pz)); // Pz
|
||||
xmlWriter.writeTextElement("Vx", QString::number(this->sateposes[i].Vx)); // Vx
|
||||
xmlWriter.writeTextElement("Vy", QString::number(this->sateposes[i].Vy)); // Vy
|
||||
xmlWriter.writeTextElement("Vz", QString::number(this->sateposes[i].Vz)); // Vz
|
||||
xmlWriter.writeTextElement("AntDirectX", QString::number(this->sateposes[i].AntDirectX)); // AntDirectX
|
||||
xmlWriter.writeTextElement("AntDirectY", QString::number(this->sateposes[i].AntDirectY)); // AntDirectY
|
||||
xmlWriter.writeTextElement("AntDirectZ", QString::number(this->sateposes[i].AntDirectZ)); // AntDirectZ
|
||||
xmlWriter.writeTextElement("AVx", QString::number(this->sateposes[i].AVx)); // AVx
|
||||
xmlWriter.writeTextElement("AVy", QString::number(this->sateposes[i].AVy)); // AVy
|
||||
xmlWriter.writeTextElement("AVz", QString::number(this->sateposes[i].AVz)); // AVz
|
||||
xmlWriter.writeTextElement("lon", QString::number(this->sateposes[i].lon)); // lon
|
||||
xmlWriter.writeTextElement("lat", QString::number(this->sateposes[i].lat)); // lat
|
||||
xmlWriter.writeTextElement("ati", QString::number(this->sateposes[i].ati)); // ati
|
||||
xmlWriter.writeTextElement("time", QString::number(this->sateposes[i].time, 'e', 18)); // time
|
||||
xmlWriter.writeTextElement("Px", QString::number(this->sateposes[i].Px, 'e', 18)); // Px
|
||||
xmlWriter.writeTextElement("Py", QString::number(this->sateposes[i].Py, 'e', 18)); // Py
|
||||
xmlWriter.writeTextElement("Pz", QString::number(this->sateposes[i].Pz, 'e', 18)); // Pz
|
||||
xmlWriter.writeTextElement("Vx", QString::number(this->sateposes[i].Vx, 'e', 18)); // Vx
|
||||
xmlWriter.writeTextElement("Vy", QString::number(this->sateposes[i].Vy, 'e', 18)); // Vy
|
||||
xmlWriter.writeTextElement("Vz", QString::number(this->sateposes[i].Vz, 'e', 18)); // Vz
|
||||
xmlWriter.writeTextElement("AntDirectX", QString::number(this->sateposes[i].AntDirectX, 'e', 18)); // AntDirectX
|
||||
xmlWriter.writeTextElement("AntDirectY", QString::number(this->sateposes[i].AntDirectY, 'e', 18)); // AntDirectY
|
||||
xmlWriter.writeTextElement("AntDirectZ", QString::number(this->sateposes[i].AntDirectZ, 'e', 18)); // AntDirectZ
|
||||
xmlWriter.writeTextElement("AVx", QString::number(this->sateposes[i].AVx, 'e', 18)); // AVx
|
||||
xmlWriter.writeTextElement("AVy", QString::number(this->sateposes[i].AVy, 'e', 18)); // AVy
|
||||
xmlWriter.writeTextElement("AVz", QString::number(this->sateposes[i].AVz, 'e', 18)); // AVz
|
||||
xmlWriter.writeTextElement("lon", QString::number(this->sateposes[i].lon, 'e', 18)); // lon
|
||||
xmlWriter.writeTextElement("lat", QString::number(this->sateposes[i].lat, 'e', 18)); // lat
|
||||
xmlWriter.writeTextElement("ati", QString::number(this->sateposes[i].ati, 'e', 18)); // ati
|
||||
xmlWriter.writeEndElement(); // 结束 <AntPosParam>
|
||||
}
|
||||
|
||||
xmlWriter.writeTextElement("ImageStartTime", QString::number(this->startImageTime));
|
||||
xmlWriter.writeTextElement("ImageEndTime", QString::number(this->EndImageTime));
|
||||
xmlWriter.writeTextElement("ImageStartTime", QString::number(this->startImageTime, 'e', 18));
|
||||
xmlWriter.writeTextElement("ImageEndTime", QString::number(this->EndImageTime, 'e', 18));
|
||||
|
||||
xmlWriter.writeTextElement("incidenceAngleNearRange", QString::number(this->incidenceAngleNearRange));
|
||||
xmlWriter.writeTextElement("incidenceAngleFarRange", QString::number(this->incidenceAngleFarRange));
|
||||
xmlWriter.writeTextElement("TotalProcessedAzimuthBandWidth", QString::number(this->TotalProcessedAzimuthBandWidth));
|
||||
xmlWriter.writeTextElement("DopplerParametersReferenceTime", QString::number(this->DopplerParametersReferenceTime));
|
||||
xmlWriter.writeTextElement("incidenceAngleNearRange", QString::number(this->incidenceAngleNearRange, 'e', 18));
|
||||
xmlWriter.writeTextElement("incidenceAngleFarRange", QString::number(this->incidenceAngleFarRange, 'e', 18));
|
||||
xmlWriter.writeTextElement("TotalProcessedAzimuthBandWidth", QString::number(this->TotalProcessedAzimuthBandWidth, 'e', 18));
|
||||
xmlWriter.writeTextElement("DopplerParametersReferenceTime", QString::number(this->DopplerParametersReferenceTime, 'e', 18));
|
||||
|
||||
xmlWriter.writeStartElement("DopplerCentroidCoefficients");
|
||||
xmlWriter.writeTextElement("d0", QString::number(this->d0));
|
||||
xmlWriter.writeTextElement("d1", QString::number(this->d1));
|
||||
xmlWriter.writeTextElement("d2", QString::number(this->d2));
|
||||
xmlWriter.writeTextElement("d3", QString::number(this->d3));
|
||||
xmlWriter.writeTextElement("d4", QString::number(this->d4));
|
||||
xmlWriter.writeTextElement("d0", QString::number(this->d0, 'e', 18));
|
||||
xmlWriter.writeTextElement("d1", QString::number(this->d1, 'e', 18));
|
||||
xmlWriter.writeTextElement("d2", QString::number(this->d2, 'e', 18));
|
||||
xmlWriter.writeTextElement("d3", QString::number(this->d3, 'e', 18));
|
||||
xmlWriter.writeTextElement("d4", QString::number(this->d4, 'e', 18));
|
||||
xmlWriter.writeEndElement(); // DopplerCentroidCoefficients
|
||||
|
||||
xmlWriter.writeStartElement("DopplerRateValuesCoefficients");
|
||||
xmlWriter.writeTextElement("r0", QString::number(this->r0));
|
||||
xmlWriter.writeTextElement("r1", QString::number(this->r1));
|
||||
xmlWriter.writeTextElement("r2", QString::number(this->r2));
|
||||
xmlWriter.writeTextElement("r3", QString::number(this->r3));
|
||||
xmlWriter.writeTextElement("r4", QString::number(this->r4));
|
||||
xmlWriter.writeTextElement("r0", QString::number(this->r0, 'e', 18));
|
||||
xmlWriter.writeTextElement("r1", QString::number(this->r1, 'e', 18));
|
||||
xmlWriter.writeTextElement("r2", QString::number(this->r2, 'e', 18));
|
||||
xmlWriter.writeTextElement("r3", QString::number(this->r3, 'e', 18));
|
||||
xmlWriter.writeTextElement("r4", QString::number(this->r4, 'e', 18));
|
||||
xmlWriter.writeEndElement(); // DopplerRateValuesCoefficients
|
||||
|
||||
|
||||
xmlWriter.writeTextElement("latitude_center", QString::number(this->latitude_center));
|
||||
xmlWriter.writeTextElement("longitude_center", QString::number(this->longitude_center));
|
||||
xmlWriter.writeTextElement("latitude_topLeft", QString::number(this->latitude_topLeft));
|
||||
xmlWriter.writeTextElement("longitude_topLeft", QString::number(this->longitude_topLeft));
|
||||
xmlWriter.writeTextElement("latitude_topRight", QString::number(this->latitude_topRight));
|
||||
xmlWriter.writeTextElement("longitude_topRight", QString::number(this->longitude_topRight));
|
||||
xmlWriter.writeTextElement("latitude_bottomLeft", QString::number(this->latitude_bottomLeft));
|
||||
xmlWriter.writeTextElement("longitude_bottomLeft", QString::number(this->longitude_bottomLeft));
|
||||
xmlWriter.writeTextElement("latitude_bottomRight", QString::number(this->latitude_bottomRight));
|
||||
xmlWriter.writeTextElement("longitude_bottomRight", QString::number(this->longitude_bottomRight));
|
||||
xmlWriter.writeTextElement("latitude_center", QString::number(this->latitude_center, 'e', 18));
|
||||
xmlWriter.writeTextElement("longitude_center", QString::number(this->longitude_center, 'e', 18));
|
||||
xmlWriter.writeTextElement("latitude_topLeft", QString::number(this->latitude_topLeft, 'e', 18));
|
||||
xmlWriter.writeTextElement("longitude_topLeft", QString::number(this->longitude_topLeft, 'e', 18));
|
||||
xmlWriter.writeTextElement("latitude_topRight", QString::number(this->latitude_topRight, 'e', 18));
|
||||
xmlWriter.writeTextElement("longitude_topRight", QString::number(this->longitude_topRight, 'e', 18));
|
||||
xmlWriter.writeTextElement("latitude_bottomLeft", QString::number(this->latitude_bottomLeft, 'e', 18));
|
||||
xmlWriter.writeTextElement("longitude_bottomLeft", QString::number(this->longitude_bottomLeft, 'e', 18));
|
||||
xmlWriter.writeTextElement("latitude_bottomRight", QString::number(this->latitude_bottomRight, 'e', 18));
|
||||
xmlWriter.writeTextElement("longitude_bottomRight", QString::number(this->longitude_bottomRight, 'e', 18));
|
||||
|
||||
xmlWriter.writeEndElement(); // Parameters
|
||||
xmlWriter.writeEndDocument();
|
||||
|
@ -371,6 +372,9 @@ ErrorCode SARSimulationImageL1Dataset::loadFromXml()
|
|||
else if (xmlReader.name() == "Fs") {
|
||||
this->Fs = xmlReader.readElementText().toDouble();
|
||||
}
|
||||
else if (xmlReader.name() == "PRF") {
|
||||
this->prf = xmlReader.readElementText().toDouble();
|
||||
}
|
||||
else if(xmlReader.name() == "ImageStartTime"){
|
||||
this->startImageTime = xmlReader.readElementText().toDouble();
|
||||
}
|
||||
|
@ -873,6 +877,7 @@ QVector<double> SARSimulationImageL1Dataset::getDopplerParams()
|
|||
result[2] = d2;
|
||||
result[3] = d3;
|
||||
result[4] = d4;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -888,11 +893,13 @@ void SARSimulationImageL1Dataset::setDopplerParams(double id0, double id1, doubl
|
|||
QVector<double> SARSimulationImageL1Dataset::getDopplerCenterCoff()
|
||||
{
|
||||
QVector<double> result(5);
|
||||
result[0]=r0;
|
||||
result[1]=r1;
|
||||
result[2]=r2;
|
||||
result[3]=r3;
|
||||
result[4]=r4;
|
||||
result[0] = r0;
|
||||
result[1] = r1;
|
||||
result[2] = r2;
|
||||
result[3] = r3;
|
||||
result[4] = r4;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,9 +143,11 @@ public:
|
|||
double getDopplerParametersReferenceTime();
|
||||
void setDopplerParametersReferenceTime(double v);
|
||||
|
||||
// 多普勒参数
|
||||
QVector<double> getDopplerParams();
|
||||
void setDopplerParams(double d0, double d1, double d2, double d3, double d4);
|
||||
|
||||
// 多普勒中心系数
|
||||
QVector<double> getDopplerCenterCoff();
|
||||
void setDopplerCenterCoff(double r0, double r1, double r2, double r3, double r4);
|
||||
|
||||
|
@ -208,3 +210,9 @@ private:
|
|||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
@ -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
|
|
@ -32,5 +32,10 @@ QString QToolAbstract::getToolName()
|
|||
}
|
||||
|
||||
void QToolAbstract::excute()
|
||||
{
|
||||
this->run();
|
||||
}
|
||||
|
||||
void QToolAbstract::run()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ public slots:
|
|||
public:
|
||||
QVector<QString> toolPath;
|
||||
QString toolname;
|
||||
public:
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,10 +27,13 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CudaCompile Include="GPUTool\GPUDouble32.cu" />
|
||||
<CudaCompile Include="GPUTool\GPUTool.cu" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GPUTool\GPUBaseLibAPI.h" />
|
||||
<ClInclude Include="GPUTool\GPUBaseTool.h" />
|
||||
<ClInclude Include="GPUTool\GPUDouble32.cuh" />
|
||||
<CudaCompile Include="GPUTool\GPUTool.cuh" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -38,6 +41,9 @@
|
|||
<Project>{872ecd6f-30e3-4a1b-b17c-15e87d373ff6}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GPUTool\GPUBaseTool.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
|
@ -178,7 +184,7 @@
|
|||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;GPUBASELIB_API;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;GPUBASELIB_API;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
|
@ -193,6 +199,9 @@
|
|||
<CudaCompile>
|
||||
<GenerateRelocatableDeviceCode>true</GenerateRelocatableDeviceCode>
|
||||
<CodeGeneration>compute_86,sm_86</CodeGeneration>
|
||||
<InterleaveSourceInPTX>true</InterleaveSourceInPTX>
|
||||
<NvccCompilation>compile</NvccCompilation>
|
||||
<Optimization>O3</Optimization>
|
||||
</CudaCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
|
|
|
@ -24,10 +24,24 @@
|
|||
<CudaCompile Include="GPUTool\GPUTool.cuh">
|
||||
<Filter>GPUTool</Filter>
|
||||
</CudaCompile>
|
||||
<CudaCompile Include="GPUTool\GPUDouble32.cu">
|
||||
<Filter>GPUTool</Filter>
|
||||
</CudaCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GPUTool\GPUBaseLibAPI.h">
|
||||
<Filter>GPUTool</Filter>
|
||||
</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>
|
||||
</Project>
|
|
@ -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);
|
||||
}
|
|
@ -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__
|
|
@ -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"); }
|
|
@ -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__
|
|
@ -353,18 +353,40 @@ extern "C" void FreeCUDAHost(void* ptr) {
|
|||
ptr = nullptr;
|
||||
}
|
||||
|
||||
// GPU参数内存声明
|
||||
extern "C" void* mallocCUDADevice(size_t memsize) {
|
||||
void* ptr;
|
||||
cudaMalloc(&ptr, memsize);
|
||||
#ifdef __CUDADEBUG__
|
||||
cudaError_t err = cudaGetLastError();
|
||||
if (err != cudaSuccess) {
|
||||
printf("mallocCUDADevice CUDA Error: %s, malloc memory : %d byte\n", cudaGetErrorString(err), memsize);
|
||||
exit(2);
|
||||
// 多GPU内存分配函数
|
||||
void* mallocCUDADevice(size_t memsize, int device_id )
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
cudaError_t err;
|
||||
|
||||
// 1. 检查设备ID有效性
|
||||
int num_devices;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,17 @@
|
|||
#define CUDAMEMORY Memory1MB*100
|
||||
|
||||
#define LAMP_CUDA_PI 3.141592653589793238462643383279
|
||||
#define PI4POW2 157.91367041742973
|
||||
|
||||
// SHAREMEMORY_FLOAT_HALF_STEP * BLOCK_SIZE = SHAREMEMORY_FLOAT_HALF
|
||||
/** CUDA 调用参数 ************************************************************************************/
|
||||
#define BLOCK_SIZE 256
|
||||
#define SHAREMEMORY_BYTE 49152
|
||||
#define SHAREMEMORY_FLOAT_HALF 6144
|
||||
#define SHAREMEMORY_FLOAT_HALF_STEP 24
|
||||
#define SHAREMEMORY_FLOAT_HALF_STEP 2
|
||||
#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 内存函数
|
||||
extern "C" GPUBASELIBAPI void* mallocCUDAHost(size_t memsize); // 主机内存声明
|
||||
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 HostToDevice(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 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);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RasterMainWidgetGUI", "Rast
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageshowTool", "ImageshowTool\ImageshowTool.vcxproj", "{8C8CA066-A93A-4098-9A46-B855EFEAADF2}"
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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|x86.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -181,6 +209,7 @@ Global
|
|||
{B8B40C54-F7FE-4809-B6FB-8BC014570D7B} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||
{E56B3878-A3DC-41A4-ABF3-B628816D0D64} = {6505E2BA-06A2-447B-BC85-8CF1A81359BC}
|
||||
{8C8CA066-A93A-4098-9A46-B855EFEAADF2} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||
{80A5854F-6F80-4EC2-9F73-84E0F4DB8D7E} = {2768F9D6-D410-4E88-A479-8336DAF97072}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {179F0A62-C631-4667-AD03-3780ADE09F41}
|
||||
|
|
|
@ -196,8 +196,8 @@
|
|||
<ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj">
|
||||
<Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ImageshowTool\ImageshowTool.vcxproj">
|
||||
<Project>{8c8ca066-a93a-4098-9a46-b855efeaadf2}</Project>
|
||||
<ProjectReference Include="..\pluginToolboxLibrary\pluginToolboxLibrary.vcxproj">
|
||||
<Project>{667625a5-8de2-4373-99f0-8bad2cced011}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\RasterMainWidgetGUI\RasterMainWidgetGUI.vcxproj">
|
||||
<Project>{e56b3878-a3dc-41a4-abf3-b628816d0d64}</Project>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "FileOperator.h"
|
||||
|
||||
#include "RasterWidgetMessageShow.h"
|
||||
|
||||
#include "ImageOperatorBase.h"
|
||||
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
|
@ -59,7 +59,7 @@ RasterMainWidget::RasterMainWidget(QWidget *parent)
|
|||
//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");
|
||||
}
|
||||
|
||||
void RasterMainWidget::onactioncloseAllRasterFile_triggered()
|
||||
{
|
||||
CloseAllGDALRaster();
|
||||
}
|
||||
|
||||
QTableWidget* RasterMainWidget::getTaskTable()
|
||||
{
|
||||
return this->mUi->taskTable;
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace LAMPMainWidget {
|
|||
private slots:
|
||||
void on_drawArea_triggered();
|
||||
void on_addPlaneaction_triggered();
|
||||
|
||||
void onactioncloseAllRasterFile_triggered();
|
||||
private:
|
||||
Ui::RasterMainWidget* mUi;
|
||||
MapCanvas* mMapConvas;
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>906</width>
|
||||
<height>23</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="projectMenu">
|
||||
|
@ -117,6 +117,7 @@
|
|||
<property name="title">
|
||||
<string>工具</string>
|
||||
</property>
|
||||
<addaction name="actioncloseAllRasterFile"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="helpMenu">
|
||||
<property name="title">
|
||||
|
@ -513,6 +514,11 @@ p, li { white-space: pre-wrap; }
|
|||
<string>飞机</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actioncloseAllRasterFile">
|
||||
<property name="text">
|
||||
<string>释放影像文件</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../RasterMainWidgetGUI.qrc"/>
|
||||
|
|
|
@ -265,9 +265,6 @@
|
|||
<ProjectReference Include="..\GPUBaseLib\GPUBaseLib.vcxproj">
|
||||
<Project>{b8b40c54-f7fe-4809-b6fb-8bc014570d7b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ImageshowTool\ImageshowTool.vcxproj">
|
||||
<Project>{8c8ca066-a93a-4098-9a46-b855efeaadf2}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\RasterProcessToolWidget\RasterProcessTool.vcxproj">
|
||||
<Project>{7ef67daa-dbc0-4b7f-80e8-11b4d2cb7ec2}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
@ -25,6 +25,7 @@ ToolBoxWidget::ToolBoxWidget(LAMPMainWidget::RasterMainWidget* mainWindows, QWid
|
|||
ui->setupUi(this);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu); // <20>零塘숩우쌥꽉데
|
||||
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* currentItem = nullptr;
|
||||
|
@ -171,7 +203,17 @@ QTreeWidgetItem* ToolBoxWidget::findChildItemByName(QTreeWidgetItem* parentItem,
|
|||
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()
|
||||
|
|
|
@ -49,9 +49,11 @@ private:
|
|||
|
||||
signals:
|
||||
void addBoxToolItemSIGNAL(QToolAbstract* item);
|
||||
void addBoxToolItemInPathSIGNAL(QVector<QString> xnodepath, QToolAbstract* item);
|
||||
|
||||
public slots:
|
||||
void addBoxToolItemSLOT(QToolAbstract* item);
|
||||
void addBoxToolItemInPathSLOT(QVector<QString> xnodepath, QToolAbstract* item);
|
||||
QTreeWidgetItem* findOrCreateParentItem( QVector<QString>& path);
|
||||
QTreeWidgetItem* findOrCreateTopLevelItem( QString& name);
|
||||
QTreeWidgetItem* findChildItemByName(QTreeWidgetItem* parentItem, QString& name);
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
|
||||
|
|
@ -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();
|
||||
//}
|
|
@ -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 )
|
|
@ -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"
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
#include "DecayedException.h"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
#include "SatelliteException.h"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
#include "TleException.h"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -11,6 +11,11 @@
|
|||
#include "DEMLLA2XYZTool.h"
|
||||
#include "QConvertCoordinateSystemDialog.h"
|
||||
#include "QResampleRefrenceRaster.h"
|
||||
#include "QtLookTableCorrectOffsetDialog.h"
|
||||
#include "QtCreateGPSPointsDialog.h"
|
||||
#include "RasterVRT2ENVIdataDialog.h"
|
||||
|
||||
#include "SARSatalliteSimulationWorkflow.h" // 大场景仿真
|
||||
|
||||
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 QConvertCoordinateSystemToolButton(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)
|
||||
{
|
||||
this->toolPath = QVector<QString>(0);
|
||||
this->toolPath.push_back(u8"»ù´¡´¦Àí");
|
||||
this->toolname = QString(u8"DEMÖØ²ÉÑù");
|
||||
this->toolname = QString(u8"栅格重采样");
|
||||
}
|
||||
|
||||
QDEMResampleDialogToolButton::~QDEMResampleDialogToolButton()
|
||||
|
@ -180,3 +200,52 @@ void QResampleRefrenceRasterToolButton::excute()
|
|||
QResampleRefrenceRaster* dialog = new QResampleRefrenceRaster;
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace LAMPMainWidget {
|
|||
class ToolBoxWidget;
|
||||
|
||||
|
||||
extern "C" BASETOOLBOX_EXPORT void RegisterPreToolBox(LAMPMainWidget::RasterMainWidget* mainwindows, ToolBoxWidget* toolbox);
|
||||
|
||||
class BASETOOLBOX_EXPORT GF3ImportDataToolButton : public QToolAbstract {
|
||||
Q_OBJECT
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -60,12 +60,12 @@
|
|||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
|
||||
<QtInstall>tools_qt5</QtInstall>
|
||||
<QtModules>core</QtModules>
|
||||
<QtModules>core;gui;widgets</QtModules>
|
||||
<QtBuildConfig>debug</QtBuildConfig>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="QtSettings">
|
||||
<QtInstall>tools_qt5</QtInstall>
|
||||
<QtModules>core</QtModules>
|
||||
<QtModules>core;gui;widgets</QtModules>
|
||||
<QtBuildConfig>debug</QtBuildConfig>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
|
||||
|
@ -103,7 +103,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
</PropertyGroup>
|
||||
<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>
|
||||
<TargetName>PluginTool_$(ProjectName)</TargetName>
|
||||
<CopyLocalProjectReference>true</CopyLocalProjectReference>
|
||||
|
@ -122,6 +122,7 @@
|
|||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
|
@ -205,10 +206,15 @@
|
|||
<ClCompile Include="BaseToolbox\QOrthSlrRaster.cpp" />
|
||||
<ClCompile Include="BaseToolbox\QRDOrthProcessClass.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\SateOrbit.cpp" />
|
||||
<ClCompile Include="BaseToolbox\simptsn.cpp" />
|
||||
<ClCompile Include="BaseToolbox\WGS84_J2000.cpp" />
|
||||
<ClCompile Include="SARSatalliteSimulationWorkflow.cpp" />
|
||||
<QtMoc Include="SARSatalliteSimulationWorkflow.h" />
|
||||
<QtMoc Include="BaseToolbox\DEMLLA2XYZTool.h" />
|
||||
<ClInclude Include="BaseToolbox\GF3CalibrationAndGeocodingClass.h" />
|
||||
<ClInclude Include="BaseToolbox\GF3PSTNClass.h" />
|
||||
|
@ -221,6 +227,9 @@
|
|||
<QtMoc Include="BaseToolbox\QDEMResampleDialog.h" />
|
||||
<QtMoc Include="BaseToolbox\QConvertCoordinateSystemDialog.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\SateOrbit.h" />
|
||||
<ClInclude Include="BaseToolbox\simptsn.h" />
|
||||
|
@ -240,6 +249,9 @@
|
|||
<QtUic Include="BaseToolbox\QOrthSlrRaster.ui" />
|
||||
<QtUic Include="BaseToolbox\QRDOrthProcessClass.ui" />
|
||||
<QtUic Include="BaseToolbox\QResampleRefrenceRaster.ui" />
|
||||
<QtUic Include="BaseToolbox\QtCreateGPSPointsDialog.ui" />
|
||||
<QtUic Include="BaseToolbox\QtLookTableCorrectOffsetDialog.ui" />
|
||||
<QtUic Include="BaseToolbox\RasterVRT2ENVIdataDialog.ui" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\BaseCommonLibrary\BaseCommonLibrary.vcxproj">
|
||||
|
@ -254,6 +266,9 @@
|
|||
<ProjectReference Include="..\..\RasterProcessToolWidget\RasterProcessTool.vcxproj">
|
||||
<Project>{7ef67daa-dbc0-4b7f-80e8-11b4d2cb7ec2}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\SPG4Tool\SPG4Tool.vcxproj">
|
||||
<Project>{80a5854f-6f80-4ec2-9f73-84e0f4db8d7e}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||
|
|
|
@ -100,6 +100,18 @@
|
|||
<ClCompile Include="BaseToolbox\QResampleRefrenceRaster.cpp">
|
||||
<Filter>BaseToolbox</Filter>
|
||||
</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>
|
||||
<QtMoc Include="BaseToolbox\DEMLLA2XYZTool.h">
|
||||
|
@ -135,6 +147,18 @@
|
|||
<QtMoc Include="BaseToolbox\QResampleRefrenceRaster.h">
|
||||
<Filter>BaseToolbox</Filter>
|
||||
</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>
|
||||
<QtUic Include="BaseToolbox\DEMLLA2XYZTool.ui">
|
||||
|
@ -167,5 +191,14 @@
|
|||
<QtUic Include="BaseToolbox\QResampleRefrenceRaster.ui">
|
||||
<Filter>BaseToolbox</Filter>
|
||||
</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>
|
||||
</Project>
|
|
@ -110,7 +110,7 @@ void DEMLLA2XYZTool::onaccept()
|
|||
Vector3D Zaxis = { 0,0,1 };
|
||||
|
||||
double rowidx = 0, colidx = 0;
|
||||
#pragma omp parallel for
|
||||
//#pragma omp parallel for
|
||||
for (long i = 1; i < dem_rows - 1; i++) {
|
||||
for (long j = 1; j < dem_cols - 1; j++) {
|
||||
rowidx = i + startlineid;
|
||||
|
|
|
@ -26,7 +26,7 @@ ErrorCode GF3CalibrationRaster(QString inRasterPath, QString outRasterPath, doub
|
|||
|
||||
double quayCoff = Qualifyvalue * 1.0 / 32767;
|
||||
double caliCoff = std::pow(10.0, (calibrationConst * 1.0 / 20));
|
||||
qDebug() << "定标系数:\t" << quayCoff / caliCoff;
|
||||
qDebug() << u8"定标系数:\t" << quayCoff / caliCoff;
|
||||
long startrow = 0;
|
||||
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;
|
||||
outraster.saveImage(imgArr, startrow, 0, 1);
|
||||
}
|
||||
qDebug() << "影像写入到:" << outRasterPath;
|
||||
qDebug() << u8"影像写入到:" << outRasterPath;
|
||||
return ErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -80,29 +80,29 @@ ErrorCode ImportGF3L1ARasterToWorkspace(QString inMetaxmlPath, QString inRasterP
|
|||
QString outRasterpath = l1dataset.getImageRasterPath();
|
||||
|
||||
ErrorCode errorcode = ErrorCode::SUCCESS;
|
||||
qDebug() << "导入数据:\t" << inRasterPath;
|
||||
qDebug() << u8"导入数据:\t" << inRasterPath;
|
||||
switch (polsartype)
|
||||
{
|
||||
case POLARHH:
|
||||
qDebug() << "极化:HH";
|
||||
qDebug() << u8"极化:HH";
|
||||
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.HH_QualifyValue, gf3xml.HH_CalibrationConst);
|
||||
break;
|
||||
case POLARHV:
|
||||
qDebug() << "极化:HH";
|
||||
qDebug() << u8"极化:HH";
|
||||
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.HV_QualifyValue, gf3xml.HV_CalibrationConst);
|
||||
break;
|
||||
case POLARVH:
|
||||
qDebug() << "极化:VH";
|
||||
qDebug() << u8"极化:VH";
|
||||
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.VH_QualifyValue, gf3xml.VH_CalibrationConst);
|
||||
break;
|
||||
case POLARVV:
|
||||
qDebug() << "极化:VV";
|
||||
qDebug() << u8"极化:VV";
|
||||
errorcode = GF3CalibrationRaster(inRasterPath, outRasterpath, gf3xml.VV_QualifyValue, gf3xml.VV_CalibrationConst);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
qDebug() << "导入数据状态:\t" << QString::fromStdString(errorCode2errInfo(errorcode));
|
||||
qDebug() << u8"导入数据状态:\t" << QString::fromStdString(errorCode2errInfo(errorcode));
|
||||
|
||||
return errorcode;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ QVector<QString> SearchGF3DataTiff(QString inMetaxmlPath)
|
|||
// 获取路径所在的目录
|
||||
QDir directory(absPath);
|
||||
if (!directory.exists()) {
|
||||
qDebug() << "Directory does not exist:" << directory.absolutePath();
|
||||
qDebug() << u8"Directory does not exist:" << directory.absolutePath();
|
||||
return QVector<QString>(0);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ QVector<QString> SearchGF3DataTiff(QString inMetaxmlPath)
|
|||
filters << "*.tif" << "*.TIF" << "*.tiff" << "*.TIFF";
|
||||
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);
|
||||
|
||||
for (long i = 0; i < files.count(); i++) {
|
||||
|
@ -144,7 +144,7 @@ POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName)
|
|||
if (match.hasMatch()) {
|
||||
polarization = match.captured(1);
|
||||
polarization = polarization.toLower().replace("_", "");
|
||||
qDebug() << "Polarization extracted:" << polarization;
|
||||
qDebug() << u8"Polarization extracted:" << polarization;
|
||||
if (polarization == "hh") {
|
||||
return POLARTYPEENUM::POLARHH;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName)
|
|||
}
|
||||
}
|
||||
else {
|
||||
qDebug() << "No polarization found in the path.";
|
||||
qDebug() << u8"No polarization found in the path.";
|
||||
return POLARTYPEENUM::POLARUNKOWN;
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ ErrorCode ImportGF3L1AProcess(QString inMetaxmlPath, QString outWorkDirPath)
|
|||
break;
|
||||
}
|
||||
if (errorcode == ErrorCode::SUCCESS) {
|
||||
return errorcode;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(nullptr, u8"错误", u8"数据导入错误");
|
||||
|
@ -209,94 +209,10 @@ ErrorCode ImportGF3L1AProcess(QString inMetaxmlPath, QString outWorkDirPath)
|
|||
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)
|
||||
{
|
||||
double dt = 1e-6;
|
||||
double dt = 1e-4;
|
||||
double inct = 0;
|
||||
bool antfalg = false;
|
||||
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++) {
|
||||
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));
|
||||
dplerTheory1 = (-2 / lamda) * (((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tz) + (node.Pz - tz) * (node.Vz - 0)) / R1);
|
||||
dplerR = (R1 - refrange) * 1e6 / LIGHTSPEED;
|
||||
//dplerTheory1 = (-2 / lamda / R1) * ((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tx) + (node.Pz - tz) * (node.Vz - 0));
|
||||
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;
|
||||
|
||||
timeR2 = timeR + dt;
|
||||
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));
|
||||
dplerTheory2 = (-2 / lamda) * (((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tz) + (node.Pz - tz) * (node.Vz - 0)) / R2);
|
||||
dplerR = (R2 - refrange) * 1e6 / LIGHTSPEED;
|
||||
dplerNumber2 = d0 + dplerR * d1 + std::pow(dplerR, 2) * d2 + std::pow(dplerR, 3) * d3 + std::pow(dplerR, 4) * d4;
|
||||
//dplerTheory2 = (-2 / lamda/R2) * ((node.Px - tx) * (node.Vx + EARTHWE * ty) + (node.Py - ty) * (node.Vy - EARTHWE * tx) + (node.Pz - tz) * (node.Vz - 0));
|
||||
dplerTheory2 = (-2 / lamda/R2) * ((node.Px - tx) * (node.Vx +0) + (node.Py - ty) * (node.Vy -0) + (node.Pz - tz) * (node.Vz - 0));
|
||||
//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);
|
||||
if (std::abs(dplerTheory1 - dplerTheory2) < 1e-9 || std::abs(inct) < dt) {
|
||||
inct = dt*(dplerTheory2-dplerNumber1) / (dplerTheory2 - dplerTheory1);
|
||||
if (std::abs(dplerNumber1 - dplerTheory2) < 1e-6 || std::abs(inct) < 1.0e-4) {
|
||||
break;
|
||||
}
|
||||
inct = std::abs(inct) < 10 ?inct:inct*1e-2;
|
||||
timeR = timeR - inct;
|
||||
}
|
||||
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 localincangleRaster;
|
||||
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 d4 = dopplers[4];
|
||||
|
||||
double fs = l1dataset.getFs();// Fs采样
|
||||
double prf = (l1dataset.getEndImageTime() - l1dataset.getStartImageTime()) / (l1dataset.getrowCount() - 1);// PRF 采样
|
||||
double fs = l1dataset.getFs()*1e6;// Fs采样
|
||||
double prf = l1dataset.getPRF();// PRF 采样
|
||||
|
||||
double nearRange = l1dataset.getNearRange();
|
||||
double imagestarttime = l1dataset.getStartImageTime();
|
||||
double imageendtime = l1dataset.getEndImageTime();
|
||||
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;
|
||||
QVector < SatelliteAntPos > antposes = l1dataset.getXmlSateAntPos();
|
||||
polyfitmodel.setSatelliteOribtStartTime(imagestarttime);
|
||||
polyfitmodel.setSatelliteOribtStartTime((imagestarttime+imageendtime)/2);
|
||||
for (long i = 0; i < antposes.size(); i++) {
|
||||
SatelliteOribtNode node;
|
||||
node.time = antposes[i].time;
|
||||
node.Px = antposes[i].Px;
|
||||
node.Py = antposes[i].Py;
|
||||
node.Pz = antposes[i].Pz;
|
||||
node.Vx = antposes[i].Vx;
|
||||
node.Vy = antposes[i].Vy;
|
||||
node.Vz = antposes[i].Vz;
|
||||
polyfitmodel.addOribtNode(node);
|
||||
if (antposes[i].time > imagestarttime - 5 && antposes[i].time < imageendtime + 5) {
|
||||
SatelliteOribtNode node;
|
||||
node.time = antposes[i].time;
|
||||
node.Px = antposes[i].Px;
|
||||
node.Py = antposes[i].Py;
|
||||
node.Pz = antposes[i].Pz;
|
||||
node.Vx = antposes[i].Vx;
|
||||
node.Vy = antposes[i].Vy;
|
||||
node.Vz = antposes[i].Vz;
|
||||
polyfitmodel.addOribtNode(node);
|
||||
}
|
||||
}
|
||||
polyfitmodel.polyFit(3, false);
|
||||
|
||||
qDebug() << "-----------------------------------";
|
||||
qDebug() << "satellite polyfit model params:\n";
|
||||
qDebug() << u8"satellite polyfit model params:\n";
|
||||
qDebug() << polyfitmodel.getSatelliteOribtModelParamsString();
|
||||
qDebug() << "-----------------------------------";
|
||||
|
||||
// 开始计算查找表
|
||||
//1.计算分块
|
||||
long cpucore_num = std::thread::hardware_concurrency();
|
||||
long blockline = Memory1MB * 500 / 8 / cpucore_num / 4 / l1dataset.getcolCount();
|
||||
blockline = blockline < 50 ? 50 : blockline;
|
||||
long blocklineinit = Memory1MB / 8 / cpucore_num / 4 / l1dataset.getcolCount() * 8000;
|
||||
blocklineinit = blocklineinit < 50 ? 50 : blocklineinit;
|
||||
//2.迭代计算
|
||||
long colcount = l1dataset.getcolCount();
|
||||
long rowcount = l1dataset.getrowCount();
|
||||
long colcount = rasterRC.width;//l1dataset.getcolCount();
|
||||
long rowcount = rasterRC.height;//l1dataset.getrowCount();
|
||||
long startRId = 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_c = rasterRC.getData(startRId, 0, blockline, colcount, 2);
|
||||
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_z = demxyz.getData(startRId, 0, blockline, colcount, 3);
|
||||
|
||||
// 逐像素迭代计算
|
||||
double timeR = 0;
|
||||
|
||||
long blockrows = sar_r.rows();
|
||||
long blockcols = sar_r.cols();
|
||||
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;
|
||||
|
||||
#pragma omp parallel for
|
||||
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++) {
|
||||
|
||||
tx = dem_x(i, j);
|
||||
ty = dem_y(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) {
|
||||
sar_r(i, j) = timeR * prf;
|
||||
sar_c(i, j) = ((R - nearRange) / 2 / LIGHTSPEED) * fs;
|
||||
sar_r(i, j) =( timeR+ (imagestarttime + imageendtime) / 2 -imagestarttime) * prf;
|
||||
sar_c(i, j) = ((R - nearRange) * 2 / LIGHTSPEED) * fs;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
if (localincAngleFlag) {
|
||||
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 slopeR = 0;
|
||||
#pragma omp parallel for
|
||||
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++) {
|
||||
timeR = sar_r(i, j) / prf;
|
||||
slopex = demslope_x(i, j);
|
||||
|
@ -482,18 +450,25 @@ ErrorCode GF3RDCreateLookTable(QString inxmlPath, QString indemPath, QString out
|
|||
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);
|
||||
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;
|
||||
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) {
|
||||
processNumber = progressDialog.maximum() - 1;
|
||||
}
|
||||
|
@ -511,16 +486,17 @@ ErrorCode GF3OrthSLC( QString inRasterPath, QString inlooktablePath, QString out
|
|||
|
||||
gdalImage slcRaster(inRasterPath);//
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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_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);
|
||||
|
||||
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 j = 0; j < lookCols; j++) {
|
||||
p0 = {sar_r(i,j),sar_c(i,j),0};
|
||||
|
||||
lastr = std::floor(sar_r(i, j));
|
||||
nextr = std::ceil(sar_r(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) {
|
||||
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) };
|
||||
p21 = Landpoint{ 0,1,slcImg(nextr,lastc) };
|
||||
p12 = Landpoint{ 1,0,slcImg(lastr,nextc) };
|
||||
p22 = Landpoint{ 1,1,slcImg(nextr,nextc) };
|
||||
|
||||
Bileanervalue = Bilinear_interpolation(p0, p11, p21, p12, p22);
|
||||
outImg(i, j) = Bileanervalue;
|
||||
}
|
||||
|
@ -585,6 +563,35 @@ ErrorCode GF3RDProcess(QString inxmlPath, QString indemPath, QString outworkdir,
|
|||
double minlon = box.min_lon - dlon;
|
||||
double maxlat = box.max_lat + dlat;
|
||||
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
|
||||
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");
|
||||
cropRasterByLatLon(indemPath.toUtf8().constData(), clipDEMPath.toUtf8().constData(), minlon, maxlon, minlat, maxlat);
|
||||
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 outlocalAnglePath = JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_localAngle.tif");
|
||||
|
||||
QString outOrthPath=JoinPath(outworkdir, getFileNameWidthoutExtend(l1dataset.getxmlFilePath()) + "_orth.tif");
|
||||
if (GF3RDCreateLookTable(inxmlPath, resampleDEMPath, outworkdir, outlooktablePath, outlocalAnglePath,true) != ErrorCode::SUCCESS) {
|
||||
qDebug() << "查找表生成错误:\t" + getFileNameWidthoutExtend(inxmlPath);
|
||||
if (GF3RDCreateLookTable(inxmlPath, resampleDEMPath, outworkdir, outlooktablePath, outlocalAnglePath,true) != ErrorCode::SUCCESS) {
|
||||
qDebug() << u8"查找表生成错误:\t" + getFileNameWidthoutExtend(inxmlPath);
|
||||
return ErrorCode::FAIL;
|
||||
}
|
||||
return ErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,14 +17,7 @@ QVector<QString> SearchGF3DataTiff(QString inMetaxmlPath);
|
|||
POLARTYPEENUM getDatasetGF3FilePolsarType(QString fileName);
|
||||
|
||||
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 Ëã·¨Àà
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ QString GF3PolyfitSatelliteOribtModel::getSatelliteOribtModelParamsString()
|
|||
result += QString::number(this->polyfitVz[i], 'e', 6) + "\n";
|
||||
}
|
||||
result += "------------------------------------------------------\n";
|
||||
|
||||
printf("%s\n", result.toUtf8().constData());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,16 +5,20 @@
|
|||
#include "BaseTool.h"
|
||||
#include "SARSimulationImageL1.h"
|
||||
#include "GF3CalibrationAndGeocodingClass.h"
|
||||
#include "RasterToolBase.h"
|
||||
|
||||
QComplex2AmpPhase::QComplex2AmpPhase(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
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.radioButtonPhase, SIGNAL(toggled(bool)), this, SLOT(radioButtonPhasetoggled(bool)));
|
||||
QObject::connect(ui.radioButtonSigma0, SIGNAL(toggled(bool)), this, SLOT(radioButtonSigma0toggled(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(accept()), this, SLOT(accept()));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
QObject::connect(ui.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(onpushButtonWorkSpaceClicked(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
|
||||
//toggled(bool )
|
||||
}
|
||||
|
||||
|
@ -24,7 +28,7 @@ QComplex2AmpPhase::~QComplex2AmpPhase()
|
|||
|
||||
}
|
||||
|
||||
void QComplex2AmpPhase::accept()
|
||||
void QComplex2AmpPhase::onaccept()
|
||||
{
|
||||
QProgressDialog progressDialog(u8"¸´Êýת»»", u8"ÖÕÖ¹", 0, ui.listWidgetImg->count());
|
||||
progressDialog.setWindowTitle(u8"¸´Êýת»»");
|
||||
|
@ -44,26 +48,26 @@ void QComplex2AmpPhase::accept()
|
|||
slcl1.Open(folderpath, filename);
|
||||
QString l2bfilename = filename + ui.lineEditHZ->text();
|
||||
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 tarxmlpath = l1B.getxmlFilePath();
|
||||
copyAndReplaceFile(srcxmlpath, tarxmlpath);
|
||||
l1B.loadFromXml();
|
||||
if (ui.radioButtonAmp->isChecked()) {
|
||||
Complex2AmpRaster(imgfilepath, slcl1.getImageRasterPath());
|
||||
Complex2AmpRaster(imgfilepath, l1B.getImageRasterPath());
|
||||
}
|
||||
else if (ui.radioButtonPhase->isChecked()) {
|
||||
Complex2PhaseRaster(imgfilepath, slcl1.getImageRasterPath());
|
||||
Complex2PhaseRaster(imgfilepath, l1B.getImageRasterPath());
|
||||
}
|
||||
else if (ui.radioButtonSigma0->isChecked()) {
|
||||
Complex2dBRaster(imgfilepath, slcl1.getImageRasterPath());
|
||||
Complex2dBRaster(imgfilepath, l1B.getImageRasterPath());
|
||||
}
|
||||
progressDialog.setValue(i);
|
||||
}
|
||||
progressDialog.close();
|
||||
}
|
||||
|
||||
void QComplex2AmpPhase::reject()
|
||||
void QComplex2AmpPhase::onreject()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ public:
|
|||
|
||||
public slots:
|
||||
|
||||
void accept();
|
||||
void reject();
|
||||
void onaccept();
|
||||
void onreject();
|
||||
void onpushButtonAddClicked(bool);
|
||||
void onpushButtonRemoveClicked(bool);
|
||||
void onpushButtonWorkSpaceClicked(bool);
|
||||
|
|
|
@ -55,6 +55,7 @@ void QDEMResampleDialog::onoutDEMSelectBtnClicked(bool flag)
|
|||
|
||||
void QDEMResampleDialog::onAccepted()
|
||||
{
|
||||
this->hide();
|
||||
double gridx = ui->doubleSpinBoxGridX->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);
|
||||
|
||||
qDebug() << "DEM ReSample finished!!!";
|
||||
this->show();
|
||||
QMessageBox::information(this, tr(u8"Ìáʾ"), tr(u8"completed!!!"));
|
||||
}
|
||||
|
||||
void QDEMResampleDialog::onRejected()
|
||||
|
|
|
@ -7,11 +7,11 @@ QImportGF3StripL1ADataset::QImportGF3StripL1ADataset(QWidget *parent)
|
|||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
QListWidget* listWidgetMetaxml;
|
||||
QObject::connect( ui.pushButtonAdd,SIGNAL(clicked(clicked)),this,SLOT(onpushButtonAddClicked(bool)));
|
||||
QObject::connect(ui.pushButtonRemove, SIGNAL(clicked(clicked)), this, SLOT(onpushButtonRemoveClicked(bool)));
|
||||
QObject::connect(ui.pushButtonWorkSpace, SIGNAL(clicked(clicked)), this, SLOT(onpushButtonWorkSpaceClicked(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
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.pushButtonWorkSpace, SIGNAL(clicked(bool)), this, SLOT(onpushButtonWorkSpaceClicked(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
|
||||
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());
|
||||
progressDialog.setWindowTitle(u8"µ¼ÈëGF3Ìõ´øL1AÓ°Ïñ");
|
||||
|
@ -40,7 +40,7 @@ void QImportGF3StripL1ADataset::accept()
|
|||
progressDialog.close();
|
||||
}
|
||||
|
||||
void QImportGF3StripL1ADataset::reject()
|
||||
void QImportGF3StripL1ADataset::onreject()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ public:
|
|||
~QImportGF3StripL1ADataset();
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
void reject();
|
||||
void onaccept();
|
||||
void onreject();
|
||||
void onpushButtonAddClicked(bool);
|
||||
void onpushButtonRemoveClicked(bool);
|
||||
void onpushButtonWorkSpaceClicked(bool);
|
||||
|
|
|
@ -14,15 +14,16 @@ QOrthSlrRaster::QOrthSlrRaster(QWidget *parent)
|
|||
|
||||
connect(ui.pushButtonAdd, SIGNAL(clicked(bool)), this, SLOT(onpushButtonAddClicked(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(pushButtonDEMSelectClicked(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(ui.pushButtonDEMSelect, 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(onreject()));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
|
||||
}
|
||||
|
||||
QOrthSlrRaster::~QOrthSlrRaster()
|
||||
{}
|
||||
|
||||
void QOrthSlrRaster::accept()
|
||||
void QOrthSlrRaster::onaccept()
|
||||
{
|
||||
QToolProcessBarDialog* processdialog = new QToolProcessBarDialog(this);
|
||||
processdialog->show();
|
||||
|
@ -49,7 +50,7 @@ void QOrthSlrRaster::accept()
|
|||
processdialog->close();
|
||||
}
|
||||
|
||||
void QOrthSlrRaster::reject()
|
||||
void QOrthSlrRaster::onreject()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
@ -60,7 +61,7 @@ void QOrthSlrRaster::onpushButtonAddClicked(bool)
|
|||
this, // 父窗口
|
||||
tr(u8"选择xml文件"), // 标题
|
||||
QString(), // 默认路径
|
||||
tr(u8"xml Files (*.xml);;All Files (*)") // Îļþ¹ýÂËÆ÷
|
||||
tr(ENVI_FILE_FORMAT_FILTER) // Îļþ¹ýÂËÆ÷
|
||||
);
|
||||
|
||||
// 如果用户选择了文件
|
||||
|
|
|
@ -16,8 +16,8 @@ private:
|
|||
|
||||
public slots:
|
||||
|
||||
void accept();
|
||||
void reject();
|
||||
void onaccept();
|
||||
void onreject();
|
||||
void onpushButtonAddClicked(bool);
|
||||
void onpushButtonRemoveClicked(bool);
|
||||
void onpushButtonWorkSpaceClicked(bool);
|
||||
|
|
|
@ -10,9 +10,10 @@ QRDOrthProcessClass::QRDOrthProcessClass(QWidget *parent)
|
|||
|
||||
connect(ui.pushButtonAdd,SIGNAL(clicked(bool)),this,SLOT(onpushButtonAddClicked(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(pushButtonDEMSelectClicked(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(ui.pushButtonWorkSpace,SIGNAL(clicked(bool)),this,SLOT(onpushButtonWorkSpaceClicked(bool)));
|
||||
connect(ui.pushButtonDEMSelect, SIGNAL(clicked(bool)), this, SLOT(pushButtonDEMSelectClicked(bool)));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(onreject()));
|
||||
QObject::connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(onaccept()));
|
||||
// QDialogButtonBox* buttonBox;
|
||||
//QLineEdit* lineEditDEM;
|
||||
//QLineEdit* lineEditWorkDir;
|
||||
|
@ -22,7 +23,7 @@ QRDOrthProcessClass::QRDOrthProcessClass(QWidget *parent)
|
|||
QRDOrthProcessClass::~QRDOrthProcessClass()
|
||||
{}
|
||||
|
||||
void QRDOrthProcessClass::accept()
|
||||
void QRDOrthProcessClass::onaccept()
|
||||
{
|
||||
QToolProcessBarDialog* processdialog = new QToolProcessBarDialog(this);
|
||||
processdialog->show();
|
||||
|
@ -52,7 +53,7 @@ void QRDOrthProcessClass::accept()
|
|||
processdialog->close();
|
||||
}
|
||||
|
||||
void QRDOrthProcessClass::reject()
|
||||
void QRDOrthProcessClass::onreject()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue