diff --git a/simorthoprogram-orth_L_sar-strip/.gitattributes b/simorthoprogram-orth_L_sar-strip/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/simorthoprogram-orth_L_sar-strip/.gitignore b/simorthoprogram-orth_L_sar-strip/.gitignore new file mode 100644 index 0000000..85bed7a --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/.gitignore @@ -0,0 +1,56 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +*.dll + +x64/ +x64/* +.vs/ +.vs/* +/x64/* +/.vs/* +./x64/* +./.vs/* +./x64/* +/x64/* +*.ipch +*.db +*.pdb +*.tlog +*.log +*.pdb +*.db +*.tiff +*.tif +*.jpg + +Temporary*/ \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/ImageMatch.cpp b/simorthoprogram-orth_L_sar-strip/ImageMatch.cpp new file mode 100644 index 0000000..476eacc --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/ImageMatch.cpp @@ -0,0 +1,510 @@ +#pragma once +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include +#include +#include +#include +#include "ImageMatch.h" +#include +#include +using namespace std; +using namespace Eigen; +using namespace cv; +/// +/// cpnvert gdal to jpg +/// +/// +/// +/// +/// +int ImageMatch::gdal2JPG(std::string gdal_path, std::string jpg_path, int band_ids) +{ + std::cout << "convert gdal to jpg , beigining : \t" << getCurrentTimeString() << endl; + gdalImage gdalimg(gdal_path); + cv::Mat img(gdalimg.height, gdalimg.width, CV_8U); + { + + int start_ids = 0; + int line_invert = int(80000000 / gdalimg.width); + Eigen::MatrixXd temp(line_invert, gdalimg.width); + double min_value = 0, temp_min = 0; + double max_value = 0, temp_max = 0; + // 线性拉伸2% + Eigen::MatrixXd hist = gdalimg.getHist(band_ids); + + int count = 0; + int sum_count = gdalimg.height * gdalimg.width; + int rows = hist.rows(); + for (int i = 0; i < rows; i++) { + + if ((count+ hist(i, 1)) / sum_count > 0.01) { + min_value = hist(i, 0); + break; + } + count = count + hist(i, 1); + } + count = 0; + for (int i = rows - 1; i >= 0; i--) { + if ((count + hist(i, 1)) / sum_count > 0.01) { + max_value = hist(i, 0); + break; + } + count = count + hist(i, 1); + } + + // 重新缩放最大值,最小值 + std::cout << "min value :\t" << min_value << "\n"; + std::cout << "max value :\t" << max_value << "\n"; + start_ids = 0; + do { + line_invert = line_invert + start_ids < gdalimg.height ? line_invert : gdalimg.height - start_ids; + + temp = gdalimg.getData(start_ids, 0, line_invert, gdalimg.width, band_ids); + temp = (temp.array() - min_value) * 250 / (max_value - min_value); + for (int i = 0; i < line_invert; i++) { + for (int j = 0; j < gdalimg.width; j++) { + if (temp(i, j) < 0) { temp(i, j) = 0; } + if (temp(i, j) > 250) { temp(i, j) = 250; } + uchar tempvalue = uchar(temp(i, j));; + img.at(i + start_ids, j) = tempvalue; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < gdalimg.height); + cv::Mat result1(gdalimg.height, gdalimg.width, CV_8U); + result1 = img; + //bilateralFilter(img, result1, 10, 80, 50); + vector compression_params; + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); //选择jpeg + compression_params.push_back(100); //在这个填入你要的图片质量 + cv::Mat out = result1; + //cv::resize(img, out, cv::Size(img.cols, img.rows), cv::INTER_AREA); + + cv::imwrite(jpg_path, out, compression_params); + + } + std::cout << "convert gdal to jpg , overing : \t" << getCurrentTimeString() << endl; + std::cout << "=========================================\n"; + std::cout << " convert gdal to jpg :\n"; + std::cout << "input gdal img file path :\t" << gdal_path << "\n"; + std::cout << "input gdal img band :\t" << band_ids << "\n"; + std::cout << "out jpg file path :\t" << jpg_path << "\n"; + std::cout << "=========================================\n"; + return 0; +} + + + +/// +/// 获取模型匹配点 +/// +/// +/// +/// +Eigen::MatrixXd ImageMatch::ImageMatch_ori_sim(std::string ori_power_path, std::string sim_sum_path, int roughSize, int PreciseSize, int scale, int searchSize, int roughStep,int preciseStep) +{ + std::cout << "match point between ori and sim , overing : \t" << getCurrentTimeString() << endl; + std::cout << "match parameters : \n"; + std::cout << "rough match templet size : \t" << roughSize << endl; + std::cout << "Precise match templet size : \t" << PreciseSize << endl; + std::cout << "Precise match wait search size : \t" << searchSize << endl; + std::cout << "Precise match scale : \t" << scale << endl; + std::cout << "Precise match step : \t" << preciseStep << endl; + std::cout << "input ori image path : \t" << ori_power_path << endl; + std::cout << "input sim image path : \t" << sim_sum_path << endl; + + //读取影像 + + + cv::Mat ori = openJPG(ori_power_path); + cv::Mat sim = openJPG(sim_sum_path); + int sim_rows = sim.rows; + int sim_cols = sim.cols; + + int BlockCount = 0; + for (int i = 0; i < sim_rows; i=i+ roughSize) { + for (int j = 0; j < sim_cols; j=j+ roughSize) { + if (i + 2 * roughSize < sim_rows && j + 2 * roughSize < sim_cols) { + BlockCount++; + } + } + } + + Eigen::MatrixXd sim_block(BlockCount,3); + BlockCount = 0; + for (int i = 0; i < sim_rows; i = i + roughSize) { + for (int j = 0; j < sim_cols; j = j + roughSize) { + if (i + 2 * roughSize < sim_rows && j + 2 * roughSize < sim_cols) { + sim_block(BlockCount, 0) = i; + sim_block(BlockCount, 1) = j; + BlockCount++; + } + } + } + + Eigen::MatrixXd Tempmatchpoints(BlockCount, 6); + Tempmatchpoints = Tempmatchpoints.array() * 0; + int count = 0; +#pragma omp parallel for num_threads(8) + for (int ii = 0; ii < BlockCount; ii++) { + int i = sim_block(ii, 0); + int j = sim_block(ii, 1); + cv::Mat templet_mat = sim(Rect(j, i, 2 * roughSize, 2 * roughSize)); + cv::Scalar mean1; + cv::Mat stddevMat; + cv::meanStdDev(templet_mat, mean1, stddevMat); + double minvalue = 0; + double maxvalue = 0; + cv::minMaxLoc(templet_mat, &minvalue, &maxvalue, NULL, NULL);//用于检测矩阵中最大值和最小值的位置 + double sig = (stddevMat.at(0, 0)) / (maxvalue - minvalue); + if (sig >1) { + //continue; + } + + // 构建搜索域 + int search_i = i - 2 * searchSize >= 0 ? i - 2 * searchSize >= 0 : 0; + int search_j = j - 2 * searchSize >= 0 ? j - 2 * searchSize >= 0 : 0; + int len_i = search_i + 4 * searchSize; + int len_j = search_j + 4 * searchSize; + len_i = search_i + len_i < ori.rows ? len_i : ori.rows - search_i - 1; + len_j = search_j + len_j < ori.cols ? len_j : ori.rows - search_j - 1; + cv::Mat serch = ori(Rect(search_j, search_i, len_j, len_i)); + // 检索 + cv::Mat result; + matchTemplate(serch, templet_mat, result, cv::TM_CCOEFF_NORMED); + Point minLoc; + Point maxLoc; + Point matchLoc; + double tempminVal = 100, tempmaxVal = 0; + cv::minMaxLoc(result, &tempminVal, &tempmaxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + double offset_j = maxLoc.x + search_j; + double offset_i = maxLoc.y + search_i; + + //cv::Scalar mean1; + //cv::Mat stddevMat; + //cv::meanStdDev(templet_mat, mean1, stddevMat); + + + Tempmatchpoints(ii, 0) = double(j); //sim_x + Tempmatchpoints(ii, 1) = double(i); //sim_y + Tempmatchpoints(ii, 2) = offset_j; // sim_x + Tempmatchpoints(ii, 3) = offset_i; // sim_y + Tempmatchpoints(ii, 4) = tempmaxVal; // maxVal + Tempmatchpoints(ii, 5) = sig; // maxVal + + std::cout << 100.0*count/ BlockCount<<"\t:\t"<< count << " / " << BlockCount<<"\t" << Tempmatchpoints(ii, 0) << "\t" << Tempmatchpoints(ii, 1) << "\t" << Tempmatchpoints(ii, 2) + << "\t" << Tempmatchpoints(ii, 3) << "\t" << Tempmatchpoints(ii, 4) << "\t" << Tempmatchpoints(ii, 5) << endl; + count++; + } + + //BlockCount = 0; + count = 0; + for (int ii = 0; ii < BlockCount; ii++) { + if (Tempmatchpoints(ii, 4) > 0.7) { + std::cout << Tempmatchpoints(ii, 0) << "\t" << Tempmatchpoints(ii, 1) << "\t" << Tempmatchpoints(ii, 2) + << "\t" << Tempmatchpoints(ii, 3) << "\t" << Tempmatchpoints(ii, 4) << "\t" << Tempmatchpoints(ii, 5) << endl; + //BlockCount++; + count++; + } + } + + + + Eigen::MatrixXd matchpoints(count, 5); + count = 0; + for (int ii = 0; ii < BlockCount; ii++) { + if (Tempmatchpoints(ii, 4) > 0.7) { + matchpoints(count, 0)=Tempmatchpoints(ii, 0); //sim_x + matchpoints(count, 1) = Tempmatchpoints(ii, 1); //sim_y + matchpoints(count, 2) = Tempmatchpoints(ii, 2);// sim_x + matchpoints(count, 3) = Tempmatchpoints(ii, 3);// sim_y + matchpoints(count, 4) = Tempmatchpoints(ii, 4); // maxVal + count++; + } + } + + + /* + // step 1: 粗匹配,分块均匀匹配 + std::cout << "rough match , begining : \t" << getCurrentTimeString() << endl; + double offset_x = 0, offset_y = 0; + cv::Mat mask = sim; + cv::Mat temp_ori = ori; + int offsetcount = 0; + Eigen::MatrixXd matchpoints; + { + int row_count = ori.rows; + int col_count = ori.cols; + int count = 0; + for (int i = roughSize; i < row_count; i = i + roughSize + 500) { // y + for (int j = roughSize; j < col_count; j = j + roughSize + 200) { //x + count = count + 1; + } + } + matchpoints= Eigen::MatrixXd::Zero(count, 5);//ori_x,ori_y,sim_x,sim_y,maxval + + double minVal = 100, maxVal = 0.7; + omp_lock_t lock; + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + omp_init_lock(&lock); // 初始化互斥锁 + count = 0; + int search_count = 0; + #pragma omp parallel for num_threads(8) + for (int i = roughSize; i < row_count; i = i + roughSize+ 500) { // y + double tempminVal = 100, tempmaxVal = 0; + cv::Mat templet_mat; + cv::Mat result; + for (int j = roughSize; j < col_count; j = j + roughSize+ 200) { //x + templet_mat = ori(Rect(j - roughSize, i - roughSize, roughSize, roughSize)); + matchTemplate(sim, templet_mat, result, cv::TM_CCOEFF_NORMED); + //normalize(result, result, 1, 0, cv::NORM_MINMAX); + // 通过函数 minMaxLoc 定位最匹配的位置; + omp_set_lock(&lock); //获得互斥器 + Point minLoc; + Point maxLoc; + Point matchLoc; + cv::minMaxLoc(result, &tempminVal, &tempmaxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + if (tempmaxVal >= maxVal) { + offset_x = maxLoc.x - (j - roughSize); + offset_y = maxLoc.y - (i - roughSize); + //maxVal = tempmaxVal; + + matchpoints(count, 0) = (j - roughSize); //ori_x + matchpoints(count, 1) = (i - roughSize); //ori_y + double temp= maxLoc.x; + matchpoints(count, 2) = temp; // sim_x + temp = maxLoc.y; + matchpoints(count, 3) = temp; // sim_y + matchpoints(count, 4) = tempmaxVal; // maxVal + count = count + 1; + + offsetcount += 1; + } + search_count = search_count + 1; + std::cout << j - roughSize << "\t" << i - roughSize << "\t" << maxLoc.x << "\t" << maxLoc.y << "\t" << tempmaxVal << "\t" << search_count << "\t" << matchpoints.rows() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + } + omp_destroy_lock(&lock); //销毁互斥器 + offset_x = offset_x*1.0 / offsetcount; + offset_y = offset_y * 1.0 / offsetcount; + std::cout << "rough match point : "<< offsetcount <<"\n" << endl; + std::cout << "offset X : \t" << offset_x << endl; + std::cout << "offset Y : \t" << offset_y << endl; + std::cout << "maxVal : \t" << maxVal << endl; + } + std::cout << "rough match out : \t" << getCurrentTimeString() << endl; + // step1.1: 粗匹配绘制结果 + + std::string rough_math_path = sim_sum_path; + boost::algorithm::replace_last(rough_math_path, ".", "_ori_in_sim."); + std::cout << "ori in sim :\t" << rough_math_path << endl; + cv::Mat ori_in_sim = sim; + cv::rectangle(ori_in_sim, cv::Point(offset_x, offset_y), Point(offset_x + ori.cols, offset_y + ori.rows), Scalar(0, 255, 0), 2, 8, 0); + + vector compression_params; + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); //选择jpeg + compression_params.push_back(100); //在这个填入你要的图片质量 + cv::Mat out = ori_in_sim; + cv::imwrite(rough_math_path, out, compression_params); + + + if (offsetcount == 0) { // 表示全局粗匹配失败,无法进行精校准,考虑直接定位法 + std::cout << "there are not effective point in rought match \t" << endl; + return Eigen::MatrixXd(0, 5); + } + + Eigen::MatrixXd matchpointstemp(offsetcount,5); + for (int i = 0; i < matchpoints.rows(); i++) { + if (matchpoints(i, 4) > 0.7) { + for (int j = 0; j < matchpoints.cols(); j++) { + matchpointstemp(i, j) = matchpoints(i, j); + } + } + } + matchpoints = matchpointstemp; + */ + + + //std::cout << "rough match , overing : \t" << getCurrentTimeString() << endl; + //// step 2: 精匹配, + //std::cout << "Precise match , begining : \t" << getCurrentTimeString() << endl; + //Eigen::MatrixXd matchpoints; + //{ + + // int row_count = ori.rows; + // int col_count = ori.cols; + + // int count = 0; + + // for (int i = PreciseSize; i < row_count; i = i + preciseStep) { // y + // for (int j = PreciseSize; j < col_count; j = j + preciseStep) { //x + // count = count + 1; + // } + // } + + // matchpoints(count, 5);//ori_x,ori_y,sim_x,sim_y,maxval + // double templeta_size = PreciseSize * scale; + // double search_size = searchSize * scale; + // count = 0; + // double ori_start_x, ori_start_y; + // double sim_start_x, sim_start_y; + // row_count = row_count - PreciseSize; + // col_count = col_count - PreciseSize; + // omp_lock_t lock; + // omp_init_lock(&lock); // 初始化互斥锁 + // // 以搜索范围为核心计算 + // #pragma omp parallel for num_threads(8) + // for (int i = searchSize + offset_y; i < row_count; i = i + preciseStep) { // y + // cv::Mat templet_mat; + // cv::Mat search_mat; + // cv::Mat resample_templet_mat; + // cv::Mat resample_search_mat; + // cv::Mat result; + // double minVal = 100, maxVal = 0; + // for (int j = searchSize + offset_x; j < col_count; j = j + preciseStep) { //x + // // 计算 起始点 + // sim_start_x = j - searchSize; + // sim_start_y = i - searchSize; + + // ori_start_x = (j - searchSize / 2) - PreciseSize / 2; + // ori_start_y = (i - searchSize / 2) - PreciseSize / 2; + // // 匹配模板,待匹配模板 + // templet_mat = ori(Rect(ori_start_x, ori_start_y, PreciseSize, PreciseSize)); + // search_mat = ori(Rect(sim_start_x, sim_start_y, searchSize, searchSize)); + + // resample_templet_mat = resampledMat(templet_mat, templeta_size); + // resample_search_mat = resampledMat(search_mat, search_size); + + // matchTemplate(sim, templet_mat, result, cv::TM_CCORR_NORMED); + // // 通过函数 minMaxLoc 定位最匹配的位置; + // cv::Point minLoc; cv::Point maxLoc; + // cv::Point matchLoc; + // cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + // if (maxVal > 0.7) { + // omp_set_lock(&lock); //获得互斥器 + // + // matchpoints(count, 0) = ori_start_x; //ori_x + // matchpoints(count, 1) = ori_start_y; //ori_y + + // matchpoints(count, 2) = sim_start_x + maxLoc.x * 1.0 / scale; // sim_x + // matchpoints(count, 3) = sim_start_y + maxLoc.y * 1.0 / scale; // sim_y + // matchpoints(count, 4) = maxVal; // maxVal + // count = count + 1; + // + // omp_unset_lock(&lock); //释放互斥器 + // } + // } + // } + // omp_destroy_lock(&lock); //销毁互斥器 + + //} + // + std::cout << "Precise match , ending : \t" << getCurrentTimeString() << endl; + std::cout << "=======================================================================" << endl; + std::cout << "match point result: \t" << getCurrentTimeString() << endl; + std::cout << "=======================================================================" << endl; + + { + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + int count = matchpoints.rows(); + for (int i = 0; i < count; i++) { + std::cout << matchpoints(i, 0) << "\t" << matchpoints(i, 1) << "\t" << matchpoints(i, 2) << "\t" << matchpoints(i, 3) << "\t" << matchpoints(i, 4) << endl; + } + + } + std::cout << "=======================================================================" << endl; + return matchpoints; +} + +Eigen::MatrixXd ImageMatch::CreateMatchModel(Eigen::MatrixXd offsetXY_matrix) +{ + // ori_x,oir_y,to_x,to_y,maxval + // 0 1 2 3 4 + Eigen::MatrixXd offset_x= offsetXY_matrix.col(2) - offsetXY_matrix.col(0); + Eigen::MatrixXd offset_y = offsetXY_matrix.col(3) - offsetXY_matrix.col(1); + // 计算最小二乘法模型 + + Eigen::MatrixXd temp(offset_x.rows(), 6); + temp.col(0) = temp.col(0).array()*0+1; //1 + temp.col(1) = offsetXY_matrix.col(3).array(); // r + temp.col(2) = offsetXY_matrix.col(2).array(); // c + temp.col(3) = offsetXY_matrix.col(3).array().pow(2);//r2 + temp.col(4) = offsetXY_matrix.col(2).array().pow(2);//c2 + temp.col(5) = offsetXY_matrix.col(2).array()* offsetXY_matrix.col(3).array();//r*c + Eigen::MatrixXd matchmodel(2, 6); + Eigen::MatrixXd tempx= temp.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(offset_x);//x c + Eigen::MatrixXd tempy = temp.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(offset_y);//y r + matchmodel.row(1) = tempx; + matchmodel.row(0) = tempy; + return matchmodel; +} + +Eigen::MatrixXd ImageMatch::correctMatchModel(Eigen::MatrixXd r, Eigen::MatrixXd c) +{ + Eigen::MatrixXd a0 = Eigen::MatrixXd::Ones(1,r.cols()); + Eigen::MatrixXd a1 = r.array(); + Eigen::MatrixXd a2 = c.array(); + Eigen::MatrixXd a3 = r.array().pow(2); + Eigen::MatrixXd a4 = c.array().pow(2); + Eigen::MatrixXd a5 = r.array() * c.array(); + + + Eigen::MatrixXd offset(2, r.cols());//r,c + offset.row(0) = r.array() + this->match_model(0, 0) * a0.array() + this->match_model(0, 1) * a1.array() + this->match_model(0, 2) * a2.array() + this->match_model(0, 3) * a3.array() + this->match_model(0, 4) * a4.array() + this->match_model(0, 5) * a5.array(); + offset.row(1) = c.array() + this->match_model(1, 0) * a0.array() + this->match_model(1, 1) * a1.array() + this->match_model(1, 2) * a2.array() + this->match_model(1, 3) * a3.array() + this->match_model(1, 4) * a4.array() + this->match_model(1, 5) * a5.array(); + + return offset; +} + +int ImageMatch::outMatchModel(std::string matchmodel_path) +{ + ofstream fout(matchmodel_path, ios::trunc); + fout << "model:" << endl; + fout << this->match_model(0, 0) << " " << this->match_model(0, 1) << " " << this->match_model(0, 2) << " " << this->match_model(0, 3) << " " << this->match_model(0, 4) << " " << this->match_model(0, 5) << endl; + fout << this->match_model(1, 0) << " " << this->match_model(1, 1) << " " << this->match_model(1, 2) << " " << this->match_model(1, 3) << " " << this->match_model(1, 4) << " " << this->match_model(1, 5) << endl; + fout << "model_points:" << endl; + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + int count = this->offsetXY_matrix.rows(); + for (int i = 0; i < count; i++) { + std::cout << this->offsetXY_matrix(i, 0) << "\t" << this->offsetXY_matrix(i, 1) << "\t" << this->offsetXY_matrix(i, 2) << "\t" << this->offsetXY_matrix(i, 3) << "\t" << this->offsetXY_matrix(i, 4) << endl; + } + fout.close(); + return 0; +} + +/// +/// 读取jpg 文件 +/// +/// +/// +cv::Mat openJPG(std::string jpg_path) +{ + cv::Mat image = cv::imread(jpg_path); + if (image.data == nullptr) //nullptr是c++11新出现的空指针常量 + { + throw new exception("图片文件不存在"); + } + return image; +} + +cv::Mat resampledMat(cv::Mat& image, int targetSize, int interpolation) +{ + cv::Mat out; + cv::resize(image, out, cv::Size(targetSize, targetSize), interpolation); + return out; +} diff --git a/simorthoprogram-orth_L_sar-strip/ImageMatch.h b/simorthoprogram-orth_L_sar-strip/ImageMatch.h new file mode 100644 index 0000000..0ec0a56 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/ImageMatch.h @@ -0,0 +1,39 @@ +#pragma once +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include +#include +#include +#include + +using namespace std; +using namespace Eigen; +class ImageMatch +{ +public: + int gdal2JPG(std::string gdal_path,std::string jpg_path,int band_ids); + Eigen::MatrixXd ImageMatch_ori_sim(std::string ori_power_path, std::string sim_sum_path, int roughSize=500, int Precise=300,int scale=5, int searchSize=1000,int roughStep=400 ,int preciseStep=300); + Eigen::MatrixXd CreateMatchModel(Eigen::MatrixXd offsetXY_matrix); + + Eigen::MatrixXd correctMatchModel(Eigen::MatrixXd r, Eigen::MatrixXd c); + + int outMatchModel(std::string matchmodel_path); + //参数 + Eigen::MatrixXd offsetXY_matrix; + Eigen::MatrixXd match_model; +}; + +cv::Mat openJPG(std::string jpg_path); +cv::Mat resampledMat(cv::Mat& templet, int targetSize, int interpolation = cv::INTER_AREA); diff --git a/simorthoprogram-orth_L_sar-strip/OctreeNode.cpp b/simorthoprogram-orth_L_sar-strip/OctreeNode.cpp new file mode 100644 index 0000000..027e74e --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/OctreeNode.cpp @@ -0,0 +1 @@ +#include "OctreeNode.h" diff --git a/simorthoprogram-orth_L_sar-strip/OctreeNode.h b/simorthoprogram-orth_L_sar-strip/OctreeNode.h new file mode 100644 index 0000000..4378f3f --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/OctreeNode.h @@ -0,0 +1,264 @@ +#pragma once +#include +using namespace std; +//定义八叉树节点类 +template +struct OctreeNode +{ + T data; //节点数据 + T xmin, xmax; //节点坐标,即六面体个顶点的坐标 + T ymin, ymax; + T zmin, zmax; + OctreeNode * top_left_front, * top_left_back; //该节点的个子结点 + OctreeNode * top_right_front, * top_right_back; + OctreeNode * bottom_left_front, * bottom_left_back; + OctreeNode * bottom_right_front, * bottom_right_back; + OctreeNode //节点类 + (T nodeValue = T(), + T xminValue = T(), T xmaxValue = T(), + T yminValue = T(), T ymaxValue = T(), + T zminValue = T(), T zmaxValue = T(), + OctreeNode* top_left_front_Node = NULL, + OctreeNode* top_left_back_Node = NULL, + OctreeNode* top_right_front_Node = NULL, + OctreeNode* top_right_back_Node = NULL, + OctreeNode* bottom_left_front_Node = NULL, + OctreeNode* bottom_left_back_Node = NULL, + OctreeNode* bottom_right_front_Node = NULL, + OctreeNode* bottom_right_back_Node = NULL) + :data(nodeValue), + xmin(xminValue), xmax(xmaxValue), + ymin(yminValue), ymax(ymaxValue), + zmin(zminValue), zmax(zmaxValue), + top_left_front(top_left_front_Node), + top_left_back(top_left_back_Node), + top_right_front(top_right_front_Node), + top_right_back(top_right_back_Node), + bottom_left_front(bottom_left_front_Node), + bottom_left_back(bottom_left_back_Node), + bottom_right_front(bottom_right_front_Node), + bottom_right_back(bottom_right_back_Node) {} +}; +//创建八叉树 +template +void createOctree(OctreeNode*& root, int maxdepth, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) +{ + //cout<<"处理中,请稍候……"<= 0) + { + root = new OctreeNode(); + //cout << "请输入节点值:"; + //root->data =9;//为节点赋值,可以存储节点信息,如物体可见性。由于是简单实现八叉树功能,简单赋值为9。 + cin >> root->data; //为节点赋值 + root->xmin = xmin; //为节点坐标赋值 + root->xmax = xmax; + root->ymin = ymin; + root->ymax = ymax; + root->zmin = zmin; + root->zmax = zmax; + double xm = (xmax - xmin) / 2;//计算节点个维度上的半边长 + double ym = (ymax - ymin) / 2; + double zm = (ymax - ymin) / 2; + //递归创建子树,根据每一个节点所处(是几号节点)的位置决定其子结点的坐标。 + createOctree(root->top_left_front, maxdepth, xmin, xmax - xm, ymax - ym, ymax, zmax - zm, zmax); + createOctree(root->top_left_back, maxdepth, xmin, xmax - xm, ymin, ymax - ym, zmax - zm, zmax); + createOctree(root->top_right_front, maxdepth, xmax - xm, xmax, ymax - ym, ymax, zmax - zm, zmax); + createOctree(root->top_right_back, maxdepth, xmax - xm, xmax, ymin, ymax - ym, zmax - zm, zmax); + createOctree(root->bottom_left_front, maxdepth, xmin, xmax - xm, ymax - ym, ymax, zmin, zmax - zm); + createOctree(root->bottom_left_back, maxdepth, xmin, xmax - xm, ymin, ymax - ym, zmin, zmax - zm); + createOctree(root->bottom_right_front, maxdepth, xmax - xm, xmax, ymax - ym, ymax, zmin, zmax - zm); + createOctree(root->bottom_right_back, maxdepth, xmax - xm, xmax, ymin, ymax - ym, zmin, zmax - zm); + } +} +int i = 1; +//先序遍历八叉树 +template +void preOrder(OctreeNode*& p) +{ + if (p) + { + //cout << i << ".当前节点的值为:" << p->data << "\n坐标为:"; + //cout << "xmin: " << p->xmin << " xmax: " << p->xmax; + //cout << "ymin: " << p->ymin << " ymax: " << p->ymax; + //cout << "zmin: " << p->zmin << " zmax: " << p->zmax; + i += 1; + cout << endl; + preOrder(p->top_left_front); + preOrder(p->top_left_back); + preOrder(p->top_right_front); + preOrder(p->top_right_back); + preOrder(p->bottom_left_front); + preOrder(p->bottom_left_back); + preOrder(p->bottom_right_front); + preOrder(p->bottom_right_back); + cout << endl; + } +} +//求八叉树的深度 +template +int depth(OctreeNode*& p) +{ + if (p == NULL) + return -1; + int h = depth(p->top_left_front); + return h + 1; +} +template +int num(OctreeNode*& p) +{ + if (p == NULL) + return 0; + return 1 + num(p->top_left_front) + num(p->top_left_back) + num(p->top_right_back) + num(p->top_right_front) + num(p->bottom_left_back) + num(p->bottom_left_front) + num(p->bottom_right_back) + num(p->bottom_right_front); +} +//计算单位长度,为查找点做准备 +int cal(int num) +{ + int result = 1; + if (1 == num) + result = 1; + else + { + for (int i = 1; i < num; i++) + result = 2 * result; + } + return result; +} + +template +int find(OctreeNode*& p, double x, double y, double z) +{ + //查找点 + int maxdepth = 0; + int times = 0; + static double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0; + int tmaxdepth = 0; + double txm = 1, tym = 1, tzm = 1; + + double xm = (p->xmax - p->xmin) / 2; + double ym = (p->ymax - p->ymin) / 2; + double zm = (p->ymax - p->ymin) / 2; + times++; + if (x > xmax || xymax || yzmax || z < zmin) + { + //cout << "该点不在场景中!" << endl; + return 0; + } + if (x <= p->xmin + txm && x >= p->xmax - txm && y <= p->ymin + tym && y >= p->ymax - tym && z <= p->zmin + tzm && z >= p->zmax - tzm) + { + //cout << endl << "找到该点!" << "该点位于" << endl; + //cout << "xmin: " << p->xmin << " xmax: " << p->xmax; + //cout << "ymin: " << p->ymin << " ymax: " << p->ymax; + //cout << "zmin: " << p->zmin << " zmax: " << p->zmax; + //cout << "节点内!" << endl; + //cout << "共经过" << times << "次递归!" << endl; + return 1; + } + else if (x < (p->xmax - xm) && y < (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_left_back, x, y, z); + } + else if (x < (p->xmax - xm) && y<(p->ymax - ym) && z>(p->zmax - zm)) + { + find(p->top_left_back, x, y, z); + } + else if (x > (p->xmax - xm) && y < (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_right_back, x, y, z); + } + else if (x > (p->xmax - xm) && y<(p->ymax - ym) && z>(p->zmax - zm)) + { + find(p->top_right_back, x, y, z); + } + else if (x<(p->xmax - xm) && y>(p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_left_front, x, y, z); + } + else if (x<(p->xmax - xm) && y>(p->ymax - ym) && z > (p->zmax - zm)) + { + find(p->top_left_front, x, y, z); + } + else if (x > (p->xmax - xm) && y > (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_right_front, x, y, z); + } + else if (x > (p->xmax - xm) && y > (p->ymax - ym) && z > (p->zmax - zm)) + { + find(p->top_right_front, x, y, z); + } +} +//main函数 +/* +int main() +{ + OctreeNode* rootNode = NULL; + int choiced = 0; + cout << "系统开始前请先创建八叉树" << endl; + cout << "请输入最大递归深度:" << endl; + cin >> maxdepth; + cout << "请输入外包盒坐标,顺序如下:xmin,xmax,ymin,ymax,zmin,zmax" << endl; + cin >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax; + if (maxdepth >= 0 || xmax > xmin || ymax > ymin || zmax > zmin || xmin > 0 || ymin > 0 || zmin > 0) + { + tmaxdepth = cal(maxdepth); + txm = (xmax - xmin) / tmaxdepth; + tym = (ymax - ymin) / tmaxdepth; + tzm = (zmax - zmin) / tmaxdepth; + createOctree(rootNode, maxdepth, xmin, xmax, ymin, ymax, zmin, zmax); + } + while (true) + { + system("cls"); + + cout << "请选择操作:\n"; + cout << "\t1.计算空间中区域的个数\n"; + cout << "\t2.先序遍历八叉树\n"; + cout << "\t3.查看树深度\n"; + cout << "\t4.查找节点 \n"; + cout << "\t0.退出\n"; + cin >> choiced; + + if (choiced == 0) + return 0; + if (choiced == 1) + { + system("cls"); + cout << "空间区域个数" << endl; + cout << num(rootNode); + } + + if (choiced == 2) + { + system("cls"); + cout << "先序遍历八叉树结果:/n"; + i = 1; + preOrder(rootNode); + cout << endl; + system("pause"); + } + if (choiced == 3) + { + system("cls"); + int dep = depth(rootNode); + cout << "此八叉树的深度为" << dep + 1 << endl; + system("pause"); + } + if (choiced == 4) + { + system("cls"); + cout << "请输入您希望查找的点的坐标,顺序如下:x,y,z\n"; + double x, y, z; + cin >> x >> y >> z; + times = 0; + cout << endl << "开始搜寻该点……" << endl; + find(rootNode, x, y, z); + system("pause"); + } + else + { + system("cls"); + cout << "\n\n错误选择!\n"; + system("pause"); + } + } +*/ \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp new file mode 100644 index 0000000..653016f --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp @@ -0,0 +1,49 @@ +锘// ConsoleApplication1.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + + + +#include +#include +#include +#include + +//#include + +//using namespace arma; +using namespace std; +using namespace Eigen; + +int main(int argc, char* argv[]) +{ + cout << cos(30) << endl; + cout << cos(45) << endl; + cout << cos(60) << endl; + cout << pow(1, 3) << endl; + cout << pow(2, 3) << endl; + + Eigen::MatrixXd a = Eigen::MatrixXd::Ones(6, 3); // 闅忔満鍒濆鍖栫煩闃 + Eigen::MatrixXd b = Eigen::MatrixXd::Ones(6,3).array()*2; + Eigen::Vector3d p(3, 1, 2); + double start = clock(); + Eigen::MatrixXd c = (a.array()/b.array());// .rowwise().sum(); + double endd = clock(); + double thisTime = (double)(endd - start) / CLOCKS_PER_SEC; + + cout << thisTime << endl; + cout << c.rows() << "," << c.cols() << endl; + cout << c(Eigen::all, { 0,1}) << endl; + system("PAUSE"); + return 0; +} + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj new file mode 100644 index 0000000..e8a092c --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {db6d05f9-271e-4954-98ed-591ab27bb05e} + ConsoleApplication1 + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + Parallel + + + + + + + + + + + + + + + + + + + + + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files %28x86%29\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;C:\Program Files %28x86%29\Intel\oneAPI\mkl\2022.1.0\lib\intel64;$(oneMKLOmpLibDir);$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + mkl_scalapack_ilp64.lib;mkl_cdft_core.lib;mkl_intel_ilp64.lib;mkl_sequential.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;impi.lib;mkl_intel_thread.lib;libiomp5md.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters new file mode 100644 index 0000000..18f4605 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters @@ -0,0 +1,22 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp new file mode 100644 index 0000000..490b3e3 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp @@ -0,0 +1,191 @@ +锘// PSTM_simulation_windows.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + +#include +#include +#include +#include +#include +#include +#include "ParameterInFile.h" +#include 銆銆 +#include +// +// 寮曠敤鍙橀噺鐨勭┖闂 +// +using namespace std; + + +int test(ParameterInFile parmas) { + cout << parmas.doppler_para[0] << endl; + return 0; +} + +/// +/// 妫鏌ョ幆澧冿紝涓昏妫鏌ュ唴瀛樻儏鍐 +/// +/// +/// +bool check(ParameterInFile& parmas) { + + return true; +} + +sim_block testsimblock(int a = 1) { + sim_block result(1, 2, 1, 2, 1, 1); + return result; +} + +int Fmaintest() { + sim_block temp = testsimblock(1); + point lla = point{ 110,22,33 }; + point xyz = point{ -2023567.6297546995,5559706.3694903487,2374425.2573203994 }; + point ttxyz = LLA2XYZ(lla); + point ttlla = XYZ2LLA(xyz); + VectorPoint v1 = getVector(xyz, ttxyz); + VectorPoint v2 = getVector(lla, ttlla); + cout << getModule(v1) << std::endl; + cout << getModule(v2) << std::endl; + return 0; +} + + + + +int main(int argc, char* argv[]) +{ + // try { + testPP(); + + + std::cout << "PSTM_simulation_windows.exe [mode] [pars_path] [resample_para] [--thead_num]" << endl;// 杈撳嚭甯姪鏂囨。 + std::cout << "[mode]: 璋冪敤妯″潡 0,1,2 " << endl; + std::cout << " 0:榛樿璺緞 " << endl; + std::cout << " 1:璁$畻姝e皠妯℃嫙鍥 " << endl; + std::cout << " 2:璁$畻姝e皠鏍℃鎻掑肩畻娉曚笌寮哄害鍥剧敓鎴 " << endl; + std::cout << "[para_path]:蹇呴 姝e皠妯℃嫙鍙傛暟鏂囦欢 " << endl; + std::cout << "[resample_para]:褰搈ode==2鏃讹紝蹇呴夛紱 璁$畻姝e皠鏍℃鎻掑肩畻娉曚笌寮哄害鍥剧敓鎴愬弬鏁版枃浠 " << endl; + std::cout << "[--thead_num]:鍙 绾跨▼鏁帮紝榛樿鏄8" << endl; + std::cout << "example:" << endl; + std::cout << "PSTM_simulation_windows.exe 2 C:\\sim_sar_paras.txt D:\\resample_para.txt --thead_num 8" << endl; + int mode = -1; + int thread_num = 6; + std::string pars_path = ""; //閰嶇疆鏂囦欢浠g爜 + std::string resample_para = ""; + std::string thread_str = "--thead_num"; + try { + if (argc < 3) { + std::cout << "缂哄皯鍙傛暟" << endl; + //return 0; + } + for (int i = 1; i < argc; i++) { + if (i == 1) { + mode = stoi(argv[1]); + if (mode == 0) { + pars_path = "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace4\\sim_sar_paras.txt"; + resample_para = "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace4\\resample_para.txt"; + mode = 2; + break; + } + } + if (i == 2) { + pars_path= argv[2]; + } + if (i == 3) { + if (mode == 1) { + break; + } + else { + resample_para = argv[3]; + } + } + } + + for (int i = 1; i < argc; i++) { + std::string temp = argv[i]; + + + if (temp== thread_str) { + i = i + 1; + + if (i >= argc) { break; } + else { + thread_num = stoi(argv[i]); + + } + } + } + } + catch(exception ex) { + std::cout << "鍙傛暟瑙f瀽閿欒" << endl; + // 寮濮媡est妯″紡 + + return -1; + + } + if (1) { + pars_path = "D:\\MicroWorkspace\\C-SAR\\Ortho\\Temporary\\sim_sar_paras.txt"; + resample_para = "";// "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace\\resample_para.txt"; + mode = 1; + } + + std::cout << "绾跨▼鏁帮細" << thread_num << endl; + //Fmaintest(); + + cout << mode << "\n"; + int d=round(3.13); + if (mode == 1) { + cout << "sim_sar program run....\n"; + cout << pars_path << "\n"; + ParameterInFile parmas(pars_path); + //testPTSN(parmas); + if (!check(parmas)) { + throw "涓嶇鍚堣繍琛屾潯浠"; + return 0; + } + //SimProcess(parmas, 32); + SimProcess_LVY(parmas, thread_num); + // ResamplingSim(parmas); + // 妫鏌ヨВ鏋愮粨鏋 + cout << "programover" << "\n"; + } + + else if (mode == 2) { + try { + ConvertResampleParameter converPara(resample_para); + ParameterInFile parmas(pars_path); + testPTSN(pars_path); + SimProcess_Calsim2ori(parmas, converPara, thread_num); + SimProcess_ResamplingOri2Orth(parmas, converPara, thread_num); + SimProcess_Calspow(parmas, converPara, thread_num); + } + catch(exception& ex) { + std::cout << ex.what() << std::endl; + return -1; + } + //SimProcess_CalXYZ(parmas, converPara,16); + //ConverOri2Sim(parmas, converPara); + //CalCoondinaryXYZOfSAR(parmas, converPara); + } + + + // } + //catch (exception ex) { + // 闃叉鍐呭瓨娉勯湶锛屼繚璇佸唴瀛樿兘澶熻璋冪敤 + // throw "error"; + // } + +} + + + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln new file mode 100644 index 0000000..86e7524 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln @@ -0,0 +1,41 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32602.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSTM_simulation_windows", "PSTM_simulation_windows.vcxproj", "{418EA1F3-8583-4728-ABC4-45B98FC053BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConsoleApplication1", "..\ConsoleApplication1\ConsoleApplication1.vcxproj", "{DB6D05F9-271E-4954-98ED-591AB27BB05E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x64.ActiveCfg = Debug|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x64.Build.0 = Debug|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x86.ActiveCfg = Debug|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x86.Build.0 = Debug|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x64.ActiveCfg = Release|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x64.Build.0 = Release|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x86.ActiveCfg = Release|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x86.Build.0 = Release|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x64.ActiveCfg = Debug|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x64.Build.0 = Debug|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x86.ActiveCfg = Debug|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x86.Build.0 = Debug|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x64.ActiveCfg = Release|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x64.Build.0 = Release|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x86.ActiveCfg = Release|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2C843D5-F54A-4745-908B-8387B47D60A3} + EndGlobalSection +EndGlobal diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj new file mode 100644 index 0000000..6a2d7a8 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj @@ -0,0 +1,169 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {418ea1f3-8583-4728-abc4-45b98fc053bf} + PSTMsimulationwindows + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + No + + + Application + false + v143 + true + Unicode + Parallel + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + $(ExternalIncludePath) + $(SolutionDir)bin\$(Platform)\$(Configuration) + + + false + $(ExternalIncludePath) + $(LibraryPath) + $(SolutionDir)bin\$(Platform)\$(Configuration) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + MultiThreaded + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + + + Console + true + true + true + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp new file mode 100644 index 0000000..7dfb32e --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp @@ -0,0 +1,2100 @@ +#include "ParameterInFile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +////gdal +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "common.h" + + +using namespace std; +// +// 参数文件解析 +// + +//参数文件标准格式 +// 文件值 类型 对应的代号 +// DEM文件的路径 str dem_path +// 模拟影像输出路径 str sar_sim_path +// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path +// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path +// 采样率 long double sample_f +// 近斜距 long double R0 +// 成像起始时间 long double starttime ---UTC 时间 +// 光速 long double +// 波长 long double +// 多普勒参考时间 long double TO ---UTC 时间 +// 脉冲重复频率 long double PRF +// 斜距采样间隔 long double delta_R +// 多普勒系数个数 int +// 多普勒系数1 long double +// 多普勒系数2 long double +// .... +// 卫星轨道模型是否为多项式模型 +// 卫星轨道模型多项式次数 int 4 5 +// 卫星轨道模型X值系数1 long double +// .... +// 卫星轨道模型Y值系数1 long double +// ... +// 卫星轨道模型Z值系数1 long double +// ... +// 卫星轨道模型Vx值系数1 long double +// ... +// 卫星轨道模型Vy值系数1 long double +// ... +// 卫星轨道模型Vz值系数1 long double +// ... +// +// + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +point XYZ2LLA(point& XYZ) { + long double tmpX = XYZ.x; + long double temY = XYZ.y; + long double temZ = XYZ.z; + + long double curB = 0; + long double N = 0; + long double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + long double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + long double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + point result = { 0,0,0 }; + result.x = atan2(temY, tmpX) * r2d; + result.y = curB * r2d; + result.z = temZ / sinCurB - N * (1 - eSquare); + return result; +} + + +ParameterInFile::ParameterInFile(std::string infile_path) +{ + // 解析文件 + ifstream infile(infile_path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + getline(infile, buf); this->dem_path = buf; + getline(infile, buf); this->out_sar_sim_path = buf; + getline(infile, buf); this->out_sar_sim_dem_path = buf; + getline(infile, buf); this->out_sar_sim_resampling_path = buf; + getline(infile, buf); this->out_sar_sim_resampling_rc = buf; + getline(infile, buf); this->sim_height = stoi(buf); + getline(infile, buf); this->sim_width = stoi(buf); + getline(infile, buf); this->sar_sim_match_point_path = buf; + getline(infile, buf); this->sar_sim_match_point_xyz_path = buf; + + getline(infile, buf); this->sample_f = stoi(buf); + getline(infile, buf); this->R0 = stod(buf); + getline(infile, buf); this->LightSpeed = stod(buf); + getline(infile, buf); this->lamda = stod(buf); + getline(infile, buf); this->delta_R = stod(buf); + getline(infile, buf); this->imgStartTime = stod(buf); + getline(infile, buf); this->PRF = stod(buf); + getline(infile, buf); this->delta_t = stod(buf); + getline(infile, buf); this->refrange = stod(buf); + getline(infile, buf); this->widthspace = stod(buf); + getline(infile, buf); cout << buf << endl; + + getline(infile, buf); this->doppler_paramenter_number = stoi(buf); + + // 读取多普勒系数 + this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double)); + if (this->doppler_para) { + for (int i = 0; i < this->doppler_paramenter_number; i++) { + getline(infile, buf); + this->doppler_para[i] = stod(buf); + } + } + else { + throw "内存不足"; + } + // 读取卫星轨道 + getline(infile, buf); this->polySatelliteModel = stoi(buf); + if (this->polySatelliteModel != 1) { + throw "不是多项式轨道模型"; + } + getline(infile, buf); this->polynum = stoi(buf) + 1; // 多项式项数 + getline(infile, buf); this->SatelliteModelStartTime = stod(buf); // 轨道模型起始时间 + + this->polySatellitePara = (long double*)calloc(this->polynum * 6, sizeof(long double)); + if (this->polySatellitePara) { + for (int i = 0; i < this->polynum * 6; i++) { + getline(infile, buf); + this->polySatellitePara[i] = stod(buf); + } + } + else { + throw "内存不足"; + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); +} + +ParameterInFile::ParameterInFile(const ParameterInFile& paras) +{ + //参数组 + this->dem_path = paras.dem_path; + this->out_sar_sim_path = paras.out_sar_sim_path; + this->out_sar_sim_dem_path = paras.out_sar_sim_dem_path; + this->out_sar_sim_resampling_path = paras.out_sar_sim_resampling_path; + this->out_sar_sim_resampling_rc = paras.out_sar_sim_resampling_rc; + this->sim_height = paras.sim_height; + this->sim_width = paras.sim_width; + this->sar_sim_match_point_path = paras.sar_sim_match_point_path; + this->sar_sim_match_point_xyz_path = paras.sar_sim_match_point_xyz_path; + this->sample_f = paras.sample_f; + this->R0 = paras.R0; + this->LightSpeed = paras.LightSpeed; + this->lamda = paras.lamda; + + this->delta_R = paras.delta_R; + this->imgStartTime = paras.imgStartTime; + this->PRF = paras.PRF; + this->delta_t = paras.delta_t; + this->refrange = paras.refrange; + // 多普勒 + this->widthspace = paras.widthspace; + this->doppler_paramenter_number = paras.doppler_paramenter_number; + //卫星轨道模型 + this->polySatelliteModel = paras.polySatelliteModel; + this->polynum = paras.polynum; + this->SatelliteModelStartTime = paras.SatelliteModelStartTime; + this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double)); + memcpy(this->doppler_para, paras.doppler_para, paras.doppler_paramenter_number * sizeof(long double)); + this->polySatellitePara = (long double*)calloc(paras.polynum * 6, sizeof(long double)); + memcpy(this->polySatellitePara, paras.polySatellitePara, paras.polynum * 6 * sizeof(long double)); +} + +ParameterInFile::~ParameterInFile() +{ + // 析构函数 + free(this->doppler_para); + free(this->polySatellitePara); +} + + +/// +/// 根据卫星轨道模型计算卫星 +/// +/// 卫星轨道点时间 +/// 卫星轨道模型起始时间 +/// 卫星轨道X坐标模型参数 +/// 卫星轨道Y坐标模型参数 +/// 卫星轨道Z坐标模型参数 +/// 卫星轨道Vx坐标模型参数 +/// 卫星轨道Vy坐标模型参数 +/// 卫星轨道Vz坐标模型参数 +/// 多项式项数 +/// +inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4) +{ + satelliteTime = satelliteTime - SatelliteModelStartTime; + SatelliteSpacePoint result_point = { 0,0,0,0,0,0 }; + + if (polynum <= 0)return result_point; + int ptr_indx = 0; + int yStep = polynum; + int zStep = polynum*2; + int vxStep = polynum*3; + int vyStep = polynum*4; + int vzStep = polynum*5; + //x + result_point.x += polySatellitePara[ptr_indx]; + result_point.y += polySatellitePara[ptr_indx + yStep]; + result_point.z += polySatellitePara[ptr_indx + zStep]; + result_point.vx += polySatellitePara[ptr_indx + vxStep]; + result_point.vy += polySatellitePara[ptr_indx + vyStep]; + result_point.vz += polySatellitePara[ptr_indx + vzStep]; + if (polynum == 1)return result_point; + ptr_indx++; + long double powTime = satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 2)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 3)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 4)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + ptr_indx++; + if (polynum == 5)return result_point; + for (int i = 5; i < polynum; i++) { + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx+ yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + ptr_indx++; + } + return result_point; +} + +inline SatelliteSpacePoint getSatellitePostion_orange(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4) +{ + satelliteTime = satelliteTime - SatelliteModelStartTime; + SatelliteSpacePoint result_point = { 0,0,0,0,0,0 }; + int ptr_indx = 0; + //x + for (int i = 0; i < polynum; i++) { + result_point.x += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + + //y + for (int i = 0; i < polynum; i++) { + result_point.y += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //z + for (int i = 0; i < polynum; i++) { + result_point.z += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vx + for (int i = 0; i < polynum; i++) { + result_point.vx += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vy + for (int i = 0; i < polynum; i++) { + result_point.vy += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vz + for (int i = 0; i < polynum; i++) { + result_point.vz += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + + return result_point; +} + +/// +/// 数值模拟法计算多普勒频移值 +/// 修改时间:2022.07.03 +/// +/// 斜距 +/// 光速 +/// 多普勒参考时间 +/// 多普勒参数 +/// 多普勒频移值 +inline long double calNumericalDopplerValue(long double R, long double LightSpeed, long double refrange, long double* doppler_para, int doppler_paramenter_number) +{ + //R = R * 2 / LightSpeed - T0; + long double result = 0; + result = doppler_para[0]; + R = (R - refrange) * (1000000 / LightSpeed); + for (int i = 1; i < doppler_paramenter_number; i++) { + result =result+ doppler_para[i]*pow(R,i); + } + return result; +} +/// +/// 根据理论模型计算多普勒频移值 +/// +/// 斜距 +/// 波长 +/// 地面->卫星的空间向量 +/// 地面->卫星之间的速度向量 +/// 多普勒频移值 +inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl) +{ + long double result = -2 * (R_sl.x * V_sl.x + R_sl.y * V_sl.y + R_sl.z * V_sl.z) / (lamda * R); + return result; +} + +/// +/// 根据地面点求解对应的sar影像坐标 +/// 修改2022.07.03 +/// +/// 地面点的坐标--地固坐标系 +/// 影片开始成像时间 +/// 波长 +/// 多普勒参考斜距 +/// 光速 +/// 时间间隔 +/// 近斜距 +/// 斜距间隔 +/// 卫星轨道模型时间 +/// 卫星轨道坐标模型参数 +/// 卫星轨道模型项数 +/// 多普勒模型数 +/// 影像坐标(x:行号,y:列号,z:成像时刻) +inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double refrange, long double* doppler_para, long double LightSpeed, long double prf, long double R0, long double widthspace, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum, int doppler_paramenter_number) +{ + long double ti = Starttime; + long double dt = 0.01; + long double R = 0; + long double FdThory1 = 0; + long double FdThory2 = 0; + long double FdNumber = 0; + long double FdTheory_grad = 0; + SatelliteSpacePoint spacepoint{ 0,0,0,0,0,0 }; + VectorPoint R_sl{ 0,0,0 }; + VectorPoint V_sl{ 0,0,0 }; + long double int_time = 0; + long double endfactor = 1e-4;//exp((floor(log10(1/prf))-1)* 2.302585092994046); + long double error = 0; + for (int i = 0; i < 100; i++) { + spacepoint = getSatellitePostion(ti + dt, SatelliteModelStartTime, polySatellitePara, polynum); + R_sl.x = spacepoint.x - landpoint.x; // 卫星->地面坐标 + R_sl.y = spacepoint.y - landpoint.y; // + R_sl.z = spacepoint.z - landpoint.z; + V_sl.x = spacepoint.vx; + V_sl.y = spacepoint.vy; + V_sl.z = spacepoint.vz; + R = getModule(R_sl); + FdThory1 = calTheoryDopplerValue(R, lamda, R_sl, V_sl); + spacepoint = getSatellitePostion(ti, SatelliteModelStartTime, polySatellitePara, polynum); + R_sl.x = spacepoint.x - landpoint.x; + R_sl.y = spacepoint.y - landpoint.y; + R_sl.z = spacepoint.z - landpoint.z; + V_sl.x = spacepoint.vx; + V_sl.y = spacepoint.vy; + V_sl.z = spacepoint.vz; + R = getModule(R_sl); + FdThory2 = calTheoryDopplerValue(R, lamda, R_sl, V_sl); + FdNumber = calNumericalDopplerValue(R, LightSpeed, refrange, doppler_para, doppler_paramenter_number); + FdTheory_grad = (FdThory1 - FdThory2); + error = FdNumber - FdThory2; + int_time = error * dt / FdTheory_grad; + if (abs(error) < endfactor) { + ti = ti + int_time; + break; + } + ti = ti + int_time; + } + point result{ 0,0,0 }; + result.x = (ti - Starttime) * prf; + result.y = (R - R0) / widthspace; + result.z = ti; + return result; +} + + +/// +/// 双线性插值 +/// 11 12 +/// c +/// 21 22 +/// +/// c的x,y坐标以左上角的行列号为起始点 +/// +/// +/// +/// +/// +inline point bilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22) +{ + long double r = 1 - p.x; + long double c = 1 - p.y; + + long double rc = r * c; + long double r_c_1 = r * p.y;// r* (1 - c); + long double r_1_c = p.x * c; //(1 - r) * c; + long double r_1_c_1 = p.x * p.y;// (1 - r)* (1 - c); + // 计算插值结果 + p.x = rc * p11.x + r_c_1 * p12.x + r_1_c * p21.x + r_1_c_1 * p22.x; + p.y = rc * p11.y + r_c_1 * p12.y + r_1_c * p21.y + r_1_c_1 * p22.y; + p.z = rc * p11.z + r_c_1 * p12.z + r_1_c * p21.z + r_1_c_1 * p22.z; + return p; +} + +/// +/// 三次卷积插值 +/// 11 12 13 14 +/// 21 22 23 24 +/// c +/// 31 32 33 34 +/// 41 42 43 44 +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +inline point cubicInterpolation(point& p, point& p11, point& p12, point& p13, point& p14, point& p21, point& p22, point& p23, point& p24, point& p31, point& p32, point& p33, point& p34, point& p41, point& p42, point& p43, point& p44) +{ + long double r = p.x; + long double c = p.y; + long double r1 = r, r2 = r - 1, r3 = 2 - r, r4 = 3 - r; + long double c1 = c, c2 = c - 1, c3 = 2 - c, c4 = 3 - c; + long double wr1 = 4 - 8 * r1 + 5 * r1 * r1 - r1 * r1 * r1; + long double wr2 = 1 - 2 * r2 * r2 + r2 * r2 * r2; + long double wr3 = 1 - 2 * r3 * r3 + r3 * r3 * r3; + long double wr4 = 4 - 8 * r4 + 5 * r4 * r4 - r4 * r4 * r4; + + long double wc1 = 4 - 8 * c1 + 5 * c1 * c1 - c1 * c1 * c1; + long double wc2 = 1 - 2 * c2 * c2 + c2 * c2 * c2; + long double wc3 = 1 - 2 * c3 * c3 + c3 * c3 * c3; + long double wc4 = 4 - 8 * c4 + 5 * c4 * c4 - c4 * c4 * c4; + + long double wr1_wc1 = wr1 * wc1; + long double wr2_wc1 = wr2 * wc1; + long double wr3_wc1 = wr3 * wc1; + long double wr4_wc1 = wr4 * wc1; + + long double wr1_wc2 = wr1 * wc2; + long double wr2_wc2 = wr2 * wc2; + long double wr3_wc2 = wr3 * wc2; + long double wr4_wc2 = wr4 * wc2; + + long double wr1_wc3 = wr1 * wc3; + long double wr2_wc3 = wr2 * wc3; + long double wr3_wc3 = wr3 * wc3; + long double wr4_wc3 = wr4 * wc3; + + long double wr1_wc4 = wr1 * wc4; + long double wr2_wc4 = wr2 * wc4; + long double wr3_wc4 = wr3 * wc4; + long double wr4_wc4 = wr4 * wc4; + + p.x = 0; + p.x = p.x + wr1_wc1 * p11.x + wr1_wc2 * p12.x + wr1_wc3 * p13.x + wr1_wc4 * p14.x; + p.x = p.x + wr2_wc1 * p11.x + wr2_wc2 * p12.x + wr2_wc3 * p13.x + wr2_wc4 * p14.x; + p.x = p.x + wr3_wc1 * p11.x + wr3_wc2 * p12.x + wr3_wc3 * p13.x + wr3_wc4 * p14.x; + p.x = p.x + wr4_wc1 * p11.x + wr4_wc2 * p12.x + wr4_wc3 * p13.x + wr4_wc4 * p14.x; + + p.y = 0; + p.y = p.y + wr1_wc1 * p11.y + wr1_wc2 * p12.y + wr1_wc3 * p13.y + wr1_wc4 * p14.y; + p.y = p.y + wr2_wc1 * p11.y + wr2_wc2 * p12.y + wr2_wc3 * p13.y + wr2_wc4 * p14.y; + p.y = p.y + wr3_wc1 * p11.y + wr3_wc2 * p12.y + wr3_wc3 * p13.y + wr3_wc4 * p14.y; + p.y = p.y + wr4_wc1 * p11.y + wr4_wc2 * p12.y + wr4_wc3 * p13.y + wr4_wc4 * p14.y; + + + p.z = 0; + p.z = p.z + wr1_wc1 * p11.z + wr1_wc2 * p12.z + wr1_wc3 * p13.z + wr1_wc4 * p14.z; + p.z = p.z + wr2_wc1 * p11.z + wr2_wc2 * p12.z + wr2_wc3 * p13.z + wr2_wc4 * p14.z; + p.z = p.z + wr3_wc1 * p11.z + wr3_wc2 * p12.z + wr3_wc3 * p13.z + wr3_wc4 * p14.z; + p.z = p.z + wr4_wc1 * p11.z + wr4_wc2 * p12.z + wr4_wc3 * p13.z + wr4_wc4 * p14.z; + + return p; +} + +// +// GDAL 数组操作---内置函数不进入头文件声明 +// + +float* ReadRasterArray(GDALRasterBand* demBand, int arrayWidth, int arrayHeight, GDALDataType gdal_datatype) { + + + float* result = new float[arrayWidth * arrayHeight]; // 别忘了释放内存 + if (gdal_datatype == GDALDataType::GDT_UInt16) { + unsigned short* temp = (unsigned short*)calloc(arrayHeight * arrayWidth, sizeof(unsigned short)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + short* temp = (short*)calloc(arrayHeight * arrayWidth, sizeof(short)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = (float*)calloc(arrayHeight * arrayWidth, sizeof(float)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + + return result; +} + + + +int WriteMatchPoint(string path, std::vector* matchps) { + std::cout << "输出匹配文件中:" << path; + fstream f; + //追加写入,在原来基础上加了ios::app + f.open(path, ios::out | ios::app); + for (int i = 0; i < matchps->size(); i++) { + matchPoint matchP = (*matchps)[i]; + //f << matchP.r << "," << matchP.c << "," << matchP.ti << "," << matchP.x << "," << matchP.y << "," << matchP.z << "\n"; + } + f.close(); + std::cout << "输出匹配文件over:" << path; + return 0; +} + + +sim_block::sim_block(int start_row, int end_row, int start_col, int end_col, int height, int width) +{ + this->start_row = start_row; + this->end_row = end_row; + this->start_col = start_col; + this->end_col = end_col; + this->height = height; + this->width = width; + this->size = height * width; + this->block = (short*)calloc(this->size, sizeof(short)); + this->distanceblock = (long double*)calloc(this->size, sizeof(long double)); + this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint)); + for (int i = 0; i < this->size; i++) { + this->distanceblock[i] = -1; + } +} + +/// +/// 深度拷贝 +/// +/// +sim_block::sim_block(const sim_block& sim_blocks) +{ + this->height = sim_blocks.width; + this->width = sim_blocks.height; + this->start_row = sim_blocks.start_row; + this->start_col = sim_blocks.start_col; + this->end_col = sim_blocks.end_col; + this->end_row = sim_blocks.end_row; + this->size = sim_blocks.size; + // 声明块 + this->block = (short*)calloc(this->size, sizeof(short)); + this->distanceblock = (long double*)calloc(this->size, sizeof(long double)); + this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint)); + // 移动并复制块 + memcpy(this->block, sim_blocks.block, this->size * sizeof(short)); + memcpy(this->distanceblock, sim_blocks.distanceblock, this->size * sizeof(long double)); + memcpy(this->pointblock, sim_blocks.pointblock, this->size * sizeof(matchPoint)); + +} + +sim_block::~sim_block() +{ + if (this->block) { + free(this->block); + this->block = NULL; + } + if (this->distanceblock) { + free(this->distanceblock); + this->distanceblock = NULL; + } + if (this->pointblock) { + free(this->pointblock); + this->pointblock = NULL; + } +} + +int sim_block::rowcol2blockids(int row_ids, int col_ids) +{ + if (this->start_row > row_ids && this->end_row <= row_ids && this->start_col > col_ids && this->end_col <= col_ids) { + return -1; + } + int ids = (row_ids - this->start_row) * this->width + col_ids - this->start_col; + return ids; +} + +/// +/// 根据行列号设置指定块的数值 +/// +/// 行号 +/// 列号 +/// 设置的值 +/// +int sim_block::setsimblock(int row_ids, int col_ids, short value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->block[ids] = value; + /* + try { + this->block[ids] = value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + +int sim_block::addsimblock(int row_ids, int col_ids, short value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->block[ids] += value; + /* + try { + this->block[ids] += value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + + +/// +/// 根据行列号,获取指定行列号块的数值 +/// +/// 行号 +/// 列号 +/// +short sim_block::getsimblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + short result; + result = this->block[ids]; + /* + try { + result = this->block[ids]; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return result; +} + +/// +/// 获取模拟坐标对应的点坐标 +/// +/// 行号 +/// 列号 +/// +matchPoint sim_block::getpointblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + throw "坐标错误"; + return matchPoint{ 0,0,0,0,0,0 }; + } + matchPoint result = this->pointblock[ids]; + return result; +} + +/// +/// 设置模拟块对应的点坐标 +/// +/// 行号 +/// 列号 +/// 坐标点 +/// 更新结果 +int sim_block::setpointblock(int row_ids, int col_ids, matchPoint value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { return -1; } + this->pointblock[ids] = value; + return 0; +} + +long double sim_block::getdistanceblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + long double result; + result = this->distanceblock[ids]; + /* + try { + result = this->distanceblock[ids]; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return result; +} + +int sim_block::setdistanceblock(int row_ids, int col_ids, long double value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->distanceblock[ids] = value; + /* + try { + this->distanceblock[ids] = value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + + +/// +/// 初始化dem_block +/// +/// +/// +/// +/// +/// +/// +/// +dem_block::dem_block(int all_start_row, int all_start_col, int start_row, int end_row, int start_col, int end_col, int height, int width, int sample_f) +{ + this->all_start_row = all_start_row; + this->all_start_col = all_start_col; + this->start_row = start_row; + this->end_row = end_row; + this->start_col = start_col; + this->end_col = end_col; + this->height = height; + this->width = width; + this->size = height * width; + this->pointblock = (point*)calloc(this->size, sizeof(point)); + this->sample_f = sample_f; +} + +dem_block::dem_block(const dem_block& demblocks) +{ + this->all_start_row = demblocks.all_start_row; + this->all_start_col = demblocks.all_start_col; + this->start_row = demblocks.start_row; + this->end_row = demblocks.end_row; + this->start_col = demblocks.start_col; + this->end_col = demblocks.end_col; + this->height = demblocks.height; + this->width = demblocks.width; + this->size = this->height * this->width; + this->pointblock = (point*)calloc(this->size, sizeof(point)); + this->sample_f = sample_f; + memcpy(this->pointblock, demblocks.pointblock, this->size * sizeof(point)); +} + +dem_block::~dem_block() +{ + if (this->pointblock) { + free(this->pointblock); + this->pointblock = NULL; + //delete this; + } + +} + +/// +/// 重采样dem--三次卷积插值-- 必须在地理坐标系下进行(经纬度) +/// 为了保证采样左右各舍弃了1格 +/// +/// +//dem_block dem_block::resample_dem() +//{ +// int height = this->height -2;//[1,2 ....., n-1,n] +// int width = this->width -2;//[1,2 ....., n-1,n] +// height = height * this->sample_f; //重采样之后的高度 +// width = width * this->sample_f; // 重采样之后的宽度 +// +// int start_row = (this->start_row-1) * this ->sample_f; +// int start_col = (this->start_col-1) * this->sample_f; +// int end_row = (this->end_row-1) * this->sample_f; +// int end_col = (this->end_col-1) * this->sample_f; +// dem_block resample_dem = dem_block(start_row, end_row, start_col, end_col, height, width, this->sample_f); +// +// // 执行dem重采样,采用双曲线插值 +// for (int i = sample_f; i < height; i++) { // 行 从第一行 +// int ori_i_2 = i / sample_f; +// int ori_i_1, ori_i_3, ori_i_4; +// if (ori_i_2 - 1 < 0) { continue; } +// ori_i_1 = ori_i_2 - 1; +// if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; } +// ori_i_3 = ori_i_2 + 1; +// ori_i_4 = ori_i_2 + 2; +// for (int j = sample_f; j < width; j++) { //列 从第一列 +// point p{0,0,0}; +// int ori_j_2 = j / sample_f; +// int ori_j_1, ori_j_3, ori_j_4; +// if (ori_i_2 - 1 < 0) { continue; } +// ori_j_1 = ori_j_2 - 1; +// if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; } +// ori_j_3 = ori_j_2 + 1; +// ori_j_4 = ori_j_2 + 2; +// // 获取插值需要的数据--三次重采样差值 +// p.x = (i % sample_f) * 1.0 / sample_f; p.x = p.x + 1; +// p.y = (j % sample_f) * 1.0 / sample_f; p.y = p.y + 1; +// point p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44; +// // 获取对应节点 +// p11 = this->getpointblock(ori_i_1, ori_j_1); +// p12 = this->getpointblock(ori_i_1, ori_j_2); +// p13 = this->getpointblock(ori_i_1, ori_j_3); +// p14 = this->getpointblock(ori_i_1, ori_j_4); +// p21 = this->getpointblock(ori_i_2, ori_j_1); +// p22 = this->getpointblock(ori_i_2, ori_j_2); +// p23 = this->getpointblock(ori_i_2, ori_j_3); +// p24 = this->getpointblock(ori_i_2, ori_j_4); +// p31 = this->getpointblock(ori_i_3, ori_j_1); +// p32 = this->getpointblock(ori_i_3, ori_j_2); +// p33 = this->getpointblock(ori_i_3, ori_j_3); +// p34 = this->getpointblock(ori_i_3, ori_j_4); +// p41 = this->getpointblock(ori_i_4, ori_j_1); +// p42 = this->getpointblock(ori_i_4, ori_j_2); +// p43 = this->getpointblock(ori_i_4, ori_j_3); +// p44 = this->getpointblock(ori_i_4, ori_j_4); +// p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44); +// // 计算p 对应的行列号 +// resample_dem.setpointblock(i - sample_f, j - sample_f, p); +// } +// } +// +// +// return resample_dem; +//} +/* -------需要优化的方法--------*/ +dem_block dem_block::resample_dem() { + int height = this->height - 2;//[1,2 ....., n-1,n] + int width = this->width - 2;//[1,2 ....., n-1,n] + height = height * this->sample_f; //重采样之后的高度 + width = width * this->sample_f; // 重采样之后的宽度 + + int start_row = (this->start_row - 1) * this->sample_f; + int start_col = (this->start_col - 1) * this->sample_f; + int end_row = (this->end_row - 1) * this->sample_f; + int end_col = (this->end_col - 1) * this->sample_f; + dem_block resample_dem = dem_block(all_start_row,all_start_col,start_row, end_row, start_col, end_col, height, width, this->sample_f); + long double sample_f_1 = 1.0 / sample_f; + // 执行dem重采样,采用双曲线插值 + + int ori_i_2 =0; + int ori_i_1, ori_i_3, ori_i_4; + point p{ 0,0,0 }; + point p11, p12, p13, p14; + + for (int i = sample_f; i < height; i++) { // 行 从第一行 + ori_i_2 = i * sample_f_1; + if (ori_i_2 - 1 < 0) { continue; } + ori_i_1 = ori_i_2 - 1; + if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; } + ori_i_3 = ori_i_2 + 1; + ori_i_4 = ori_i_2 + 2; + for (int j = sample_f; j < width; j++) { //列 从第一列 + p={ 0,0,0 }; + int ori_j_2 = j * sample_f_1; + int ori_j_1, ori_j_3, ori_j_4; + if (ori_i_2 - 1 < 0) { continue; } + ori_j_1 = ori_j_2 - 1; + if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; } + ori_j_3 = ori_j_2 + 1; + ori_j_4 = ori_j_2 + 2; + // 获取插值需要的数据--三次重采样差值 + p.x = (i % sample_f) * sample_f_1 + 1; + //p.x = p.x + 1; + p.y = (j % sample_f) * sample_f_1 + 1; + //p.y = p.y + 1; + + // 获取对应节点 + p11 = this->getpointblock(ori_i_2, ori_j_2); + p12 = this->getpointblock(ori_i_2, ori_j_3); + p13 = this->getpointblock(ori_i_3, ori_j_2); + p14 = this->getpointblock(ori_i_3, ori_j_3); + p = bilineadInterpolation(p, p11, p12, p13, p14); // ----- 优化 + // 计算p 对应的行列号 + resample_dem.setpointblock(i - sample_f, j - sample_f, p); + } + } + return resample_dem; +} + + +/// +/// 根据重采样结果获取对应行列号的坡面法式向量( +/// 必须提前调用UpdatePointCoodinarary()方法,保证坐标系为地固坐标系 +/// +/// 行号 +/// 列号 +/// +VectorPoint dem_block::getslopeVector(int row_ids, int col_ids) +{ + if (row_ids == 0 || col_ids == 0 || row_ids > this->height - 1 || col_ids > this->width - 1) { return VectorPoint{ 0,0,0 }; } // 无效值 + VectorPoint result{ 0,0,0 }; + // 计算向量值,注意向量值的计算初值结果 + point p1 = this->getpointblock(row_ids - 1, col_ids); + point p2 = this->getpointblock(row_ids, col_ids - 1); + point p3 = this->getpointblock(row_ids + 1, col_ids); + point p4 = this->getpointblock(row_ids, col_ids + 1); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + result = VectorFork(n24, n31); // 目标向量 + return result; +} + +int dem_block::rowcol2blockids(int row_ids, int col_ids) +{ + return row_ids * this->width + col_ids; +} + + +/// +/// 根据行列号获取对应的点 +/// +/// +/// +/// +point dem_block::getpointblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + //try { + return this->pointblock[ids]; + //} + //catch (exception e) { + //throw "error"; + //return point{ -1,-1,-1 }; + //} +} + +/// +/// 根据行列号更新值 +/// +/// +/// +/// +/// +int dem_block::setpointblock(int row_ids, int col_ids, point& value) +{ + this->pointblock[row_ids * this->width + col_ids]= value; + /* + int ids = this->rowcol2blockids(row_ids, col_ids); + try { + this->pointblock[ids] = value; + } + catch (exception ex) { + throw "error"; + return -1; + } + + */ + return 0; +} + +point dem_block::getpointblock(int ids) +{ + return this->pointblock[ids]; + /*try { + point result = this->pointblock[ids]; + return result; + } + catch (exception e) { + throw "error"; + return point{ -1,-1,-1 }; + }*/ +} + +int dem_block::setpointblock(int ids, point& value) +{ + this->pointblock[ids] = value; + /* + try { + this->pointblock[ids] = value; + } + catch (exception ex) { + throw "error"; + return -1; + } + */ + return 0; +} + +/// +/// 将点坐标由经纬度->地固坐标系 +/// +/// +/// +int dem_block::UpdatePointCoodinarary() +{ + for (int i = 0; i < this->size; i++) { + this->pointblock[i] = LLA2XYZ(this->pointblock[i]); + } + return 0; +} + + + + +ConvertResampleParameter::ConvertResampleParameter(string path) +{ + + // 解析文件 + ifstream infile(path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + getline(infile, buf); this->in_ori_dem_path = buf; + getline(infile, buf); this->ori_sim = buf; + getline(infile, buf); this->out_sar_xyz_path = buf; + getline(infile, buf); this->out_sar_xyz_incidence_path = buf; + getline(infile, buf); this->out_orth_sar_incidence_path = buf; + getline(infile, buf); this->out_orth_sar_local_incidence_path = buf; + getline(infile, buf); this->outFolder_path = buf; + getline(infile, buf); this->file_count = stoi(buf); + this->inputFile_paths = std::vector(this->file_count); + this->outFile_paths = std::vector(this->file_count); + this->outFile_pow_paths = std::vector(this->file_count); + for (int i = 0; i < this->file_count; i++) { + getline(infile, buf); this->inputFile_paths[i] = buf; + getline(infile, buf); this->outFile_paths[i] = buf; + getline(infile, buf); this->outFile_pow_paths[i] = buf; + } + + getline(infile, buf); this->ori2sim_num = stoi(buf); + + this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double)); + for (int i = 0; i < this->ori2sim_num; i++) { + getline(infile, buf); + this->ori2sim_paras[i] = stod(buf); + } + getline(infile, buf); this->sim2ori_num = stoi(buf); + this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double)); + for (int i = 0; i < this->sim2ori_num; i++) { + getline(infile, buf); + this->sim2ori_paras[i] = stod(buf); + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); + + +} + +ConvertResampleParameter::ConvertResampleParameter(const ConvertResampleParameter& para) +{ + this->in_ori_dem_path = para.in_ori_dem_path; + this->ori_sim = para.ori_sim; + this->out_sar_xyz_path = para.out_sar_xyz_path; + this->out_sar_xyz_incidence_path = para.out_sar_xyz_incidence_path; + this->out_orth_sar_incidence_path = para.out_orth_sar_incidence_path; + this->out_orth_sar_local_incidence_path = para.out_orth_sar_local_incidence_path; + this->outFolder_path = para.outFolder_path; + this->file_count = para.file_count; + this->inputFile_paths = std::vector(this->file_count); + this->outFile_paths = std::vector(this->file_count); + this->outFile_pow_paths = std::vector(this->file_count); + for (int i = 0; i < this->file_count; i++) { + this->inputFile_paths[i] = para.inputFile_paths[i]; + this->outFile_paths[i] = para.outFile_paths[i]; + this->outFile_pow_paths[i] = para.outFile_pow_paths[i]; + } + this->ori2sim_num = para.ori2sim_num; + this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double)); + memcpy(this->ori2sim_paras, para.ori2sim_paras, this->ori2sim_num * sizeof(long double)); + this->sim2ori_num = para.sim2ori_num; + this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double)); + memcpy(this->sim2ori_paras, para.sim2ori_paras, this->sim2ori_num * sizeof(long double)); +} + +ConvertResampleParameter::~ConvertResampleParameter() +{ + free(this->sim2ori_paras); + free(this->ori2sim_paras); + this->outFile_paths.clear(); + this->outFile_paths.swap(this->outFile_paths); + this->inputFile_paths.clear(); + this->inputFile_paths.swap(this->inputFile_paths); + this->outFile_pow_paths.clear(); + this->outFile_pow_paths.swap(this->outFile_pow_paths); +} + +#include "threadpool.hpp" +//int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount) + +// 插值算法 + + + +/// +/// 分块模拟求解 +/// T0 变更为 refrange, delta_R: widthspace +/// +/// +/// +/// +int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount) +{ + long double Starttime = paras.imgStartTime; + long double lamda = paras.lamda; + long double refrange = paras.refrange; + long double* doppler_para = paras.doppler_para; + long double LightSpeed = paras.LightSpeed; + long double delta_t = paras.delta_t; + long double prf = paras.PRF; + long double R0 = paras.R0; + long double widthspace = paras.widthspace; + long double SatelliteModelStartTime = paras.SatelliteModelStartTime; + long double* polySatellitePara = paras.polySatellitePara; + int sim_sar_width = paras.sim_width; + int sim_sar_height = paras.sim_height; + int polynum = paras.polynum; + int doppler_paramenter_number = paras.doppler_paramenter_number; + + + bool haspoint = true; + for (int i = 0; i < demblock.size; i++) { + point tempPoint = demblock.getpointblock(i); + tempPoint = LLA2XYZ(tempPoint); + // T0 变更为 refrange, delta_R: widthspace + point pixelpoint = PSTN(tempPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number); + if (pixelpoint.x >= -3000-paras.sample_f*5 && pixelpoint.x < paras.sim_height + paras.sample_f * 5 && pixelpoint.y >= -paras.sample_f * 5 && pixelpoint.y < paras.sim_width + paras.sample_f * 5) { + haspoint = false; + break; + } + } + + if (haspoint) { + *Pcount = -1; + return -1; + } + + // dem重采样 + demblock.sample_f = paras.sample_f; + dem_block resample = demblock.resample_dem(); // 重采样的时候经纬度, + resample.UpdatePointCoodinarary(); // 可以优化 + + //声明 + int sim_height = resample.end_row - resample.start_row; + int sim_width = resample.end_col - resample.start_col; + int sim_pixel_count = sim_width * sim_height; + + // 计算对应的行列号 + int ids = 0; + SatelliteSpacePoint satepoint_; + *Pcount = 0; + try { + // 计算间接定位法结果 + for (int i = resample.start_row; i < resample.end_row; i++) { + for (int j = resample.start_col; j < resample.end_col; j++) { + point landPoint = resample.getpointblock(i, j); + point pixelpoint = PSTN(landPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number); + point temppoint{ round(pixelpoint.x),round(pixelpoint.y),pixelpoint.z }; + if (temppoint.x < -3000 || temppoint.x >= paras.sim_height || temppoint.y < 0 || temppoint.y >= paras.sim_width) { + continue; + } + VectorPoint n = resample.getslopeVector(i, j); + satepoint_ = getSatellitePostion(pixelpoint.z, SatelliteModelStartTime, polySatellitePara, polynum); + point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标 + IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n); + if (pixelIncidence.localincidenceAngle >= 0 && pixelIncidence.localincidenceAngle <= 1) + { + matchPoint matchp{ temppoint.x, temppoint.y, pixelpoint.z,0,0,0,0,pixelIncidence.incidenceAngle,pixelIncidence.localincidenceAngle}; + result_shared[ids] = matchp; + *Pcount = *Pcount + 1; + ids = ids + 1; + } + } + } + return 0; + } + catch (exception e) { + //free(pixelpoints); + throw "计算错误"; + return -1; + } +} + +static std::mutex s_sim_dem_Mutex; //数据锁 +void taskFunc(ParameterInFile& paras, int dem_block_size, int width, short* sim_dem, int count_cure, int count_sum, + int i, int j, int block_height, int block_width, int end_row_ex, int end_col_ex, float* demarray, translateArray& gtt, translateArray& inv_gtt) +{ + //dem_block *demblock, + int Pcount = 0; + dem_block* demblock = new dem_block(i - 3, j - 3, 3, block_height - 3, 3, block_width - 3, block_height, block_width, paras.sample_f);// 构建块结构 + for (int ii = i - 3; ii < end_row_ex; ii++) { + for (int jj = j - 3; jj < end_col_ex; jj++) { + // 构建点集 + int dem_ids = ii * width + jj; + point tempPoint = Translation(ii, jj, demarray[dem_ids], gtt); + demblock->setpointblock(ii - i + 3, jj - j + 3, tempPoint); + } + } + + matchPoint* result_shared = (matchPoint*)calloc((dem_block_size + 7) * (dem_block_size + 7) * paras.sample_f * paras.sample_f, sizeof(matchPoint)); + int nRet= SimProcessBlock(*demblock, paras,result_shared, &Pcount); + + int tempstate = Pcount; + + int row_ids = 0; + int col_ids = 0; + int ids = 0; + matchPoint* pixelpoint = NULL; + { + //std::lock_guard guard(s_sim_dem_Mutex); + s_sim_dem_Mutex.lock(); + for (int ii = 0; ii < tempstate; ii++) { + pixelpoint = &result_shared[ii]; + row_ids = int(pixelpoint->r)+3000; + col_ids = int(pixelpoint->c); + ids = row_ids *paras.sim_width + col_ids; + sim_dem[ids] ++; + } + s_sim_dem_Mutex.unlock(); + } + //根据匹配结果,尝试计算插值结果 + delete demblock; + free(result_shared); + +} + + +void taskFunc_Calsim2ori(ParameterInFile& paras, ConvertResampleParameter& conveparas, + int start_row, int end_row, int start_col, int end_col, + int dem_width,int dem_height, + float* sar_local_angle, float* sar_angle, float* sar_dem_x, float* sar_dem_y, + float* demarray, translateArray& gtt, translateArray& inv_gtt) +{ + /* + // 计算向量值,注意向量值的计算初值结果 + point p1 = this->getpointblock(row_ids - 1, col_ids); + point p2 = this->getpointblock(row_ids, col_ids - 1); + point p3 = this->getpointblock(row_ids + 1, col_ids); + point p4 = this->getpointblock(row_ids, col_ids + 1); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + result = // 目标向量 + */ + double templocalincidenceAngle = 0; + double tempincidenceAngle = 0; + double templocalincidenceAngle1 = 0; + double tempincidenceAngle1 = 0; + for (int i = start_row; i <= end_row; i++) { + if (i - 1 < 0 || i + 1 >= dem_height) { + continue; + } + for (int j = start_col; j <= end_col; j++) { + if (j - 1 < 0 || j + 1 >= dem_width) { + continue; + } + int dem_ids = i * dem_width + j; + point landPoint = Translation(i, j, demarray[dem_ids], gtt); + landPoint =LLA2XYZ(landPoint); + point pixelpoint = PSTN(landPoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + long double r, c; // 结果的行列号 + sim2ori(pixelpoint.x, pixelpoint.y, r, c, conveparas.sim2ori_paras); // 计算得到的行列号 --> + + // 计算向量1 + dem_ids = (i - 1) * dem_width + j; point p1 = Translation(i - 1, j, demarray[dem_ids], gtt); p1 = LLA2XYZ(p1); + dem_ids = i * dem_width + (j - 1); point p2 = Translation(i, j - 1, demarray[dem_ids], gtt); p2 = LLA2XYZ(p2); + dem_ids = (i + 1) * dem_width + j; point p3 = Translation(i + 1, j, demarray[dem_ids], gtt); p3 = LLA2XYZ(p3); + dem_ids = i * dem_width + (j + 1); point p4 = Translation(i, j + 1, demarray[dem_ids], gtt); p4 = LLA2XYZ(p4); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + VectorPoint n = VectorFork(n24, n31); + + long double satelliteTime =r / paras.PRF + paras.imgStartTime;// pixelpoint.z;// + SatelliteSpacePoint satepoint_ = getSatellitePostion(satelliteTime, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum); + point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标 + IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n); + + dem_ids = i * dem_width + j; + sar_local_angle[dem_ids] = acos(pixelIncidence.localincidenceAngle) * r2d; + sar_angle[dem_ids] =90- acos(pixelIncidence.incidenceAngle) * r2d; + + sar_dem_x[dem_ids] = r; + sar_dem_y[dem_ids] = c; + } + } + //std::cout << "\r" << end_row << "/" << dem_height << "," << end_col << "/" << dem_width << "," << end_row*100.0 * end_col / (dem_width * dem_height) << " ------------------"; +} + +int SimProcess_LVY(ParameterInFile paras, int thread_num) +{ + std::cout << "begin time:" << getCurrentTimeString() << std::endl; + GDALAllRegister();// 注册格式的驱动 + // 打开DEM影像 + GDALDataset* demDataset = (GDALDataset*)(GDALOpen(paras.dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int width = demDataset->GetRasterXSize(); + int height = demDataset->GetRasterYSize(); + int nCount = demDataset->GetRasterCount(); + + double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + + demDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double* inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = demDataset->GetProjectionRef(); + GDALRasterBand* demBand = demDataset->GetRasterBand(1); + float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype); + int dem_pixel_count = width * height; + int psize = (paras.sim_height+3000) * paras.sim_width; + short* sim_dem = (short*)calloc(psize, sizeof(short)); + + + //// 计算每个块的尺寸 + int dem_block_size = int(ceil(sqrt(10*1024* 1024 / (paras.sample_f* paras.sample_f *sizeof(gdal_datatype))))); // 获取每块dem的尺寸 + + //构建内存储空间对象 +// try { + int a = 2; + + int i = 3; + int j = 3; + int thread_ids = 0; + bool hasfullpool = false; + int count_sum = height * width / (dem_block_size * dem_block_size); + int count_cure = 0; + + // 标志文件是否正在写出 + //bool outmatchpointing = false; + //std::vector outmatchpointthread(0); + int tempstate = 0; + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + int start_row =0; + int start_col =0; + + int end_row = 0; + int end_col = 0; + // 扩充 + int end_row_ex = 0; + int end_col_ex = 0; + + int block_height = 0; + int block_width = 0; + while (i < height - 1) { + j = 3; + while (j < width - 1) + { + count_cure++; + // 计算起始行列数 + start_row = i; + start_col = j; + + end_row = start_row + dem_block_size; + end_col = start_col + dem_block_size; + // 扩充 + end_row_ex = end_row + 3; + end_col_ex = end_col + 3; + + if (end_row_ex > height) { + end_row = height - 3; + end_row_ex = height; + } + if (end_col_ex > width) { + end_col = width - 3; + end_col_ex = width; + } + + block_height = end_row - start_row + 6; + block_width = end_col - start_col + 6; + poolPtr->append(std::bind(taskFunc, paras, dem_block_size, width, sim_dem, count_cure, count_sum, + i, j, block_height, block_width, end_row_ex, end_col_ex, demarray, gtt, inv_gtt)); + thread_ids++; + j = j + dem_block_size; + } + i = i + dem_block_size; + } + + std::cout << "SimProcess doing"<waiteFinish(); + // 输出文件 + std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl; + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + const char* out_sar_sim = paras.out_sar_sim_path.c_str(); + + GDALDataset* poDstDS = poDriver->Create(out_sar_sim, paras.sim_width, paras.sim_height + 3000, 1, GDT_Int16, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, paras.sim_width, paras.sim_height + 3000, sim_dem, paras.sim_width, paras.sim_height + 3000, GDT_Int16, 0, 0); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + free(sim_dem); + GDALClose(demDataset); + delete demarray; + std::cout << "输出成果文件-over" << std::endl; + + std::cout << "end time:" << getCurrentTimeString() << std::endl; + return 0; +} + +int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num) +{ + std::cout << "begin time:" << getCurrentTimeString() << std::endl; + GDALAllRegister();// 注册格式的驱动 + // 打开DEM影像 + GDALDataset* demDataset = (GDALDataset*)(GDALOpen(conveparas.in_ori_dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int width = demDataset->GetRasterXSize(); + int height = demDataset->GetRasterYSize(); + int nCount = demDataset->GetRasterCount(); + double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + demDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = demDataset->GetProjectionRef(); + GDALRasterBand* demBand = demDataset->GetRasterBand(1); + float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype); + int dem_pixel_count = width * height; + int psize = width * height; + float* sar_local_angle = (float*)calloc(psize, sizeof(float)); + float* sar_angle = (float*)calloc(psize, sizeof(float)); + float* sar_dem_x = (float*)calloc(psize, sizeof(float)); + float* sar_dem_y = (float*)calloc(psize, sizeof(float)); + + for (int i = 0; i < psize; i++) { + sar_dem_x[i] = -100000; + sar_dem_y[i] = -100000; + sar_local_angle[i] = -9999; + sar_angle[i] = -9999; + } + + int blocksize =1000 ; // 获取每块dem的尺寸 + int tempstate = 0; + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + for (int start_row = 1; start_row = height-2 )? height-2 : (start_row + blocksize); + + for(int start_col =1; start_col < width -2;) + { + int end_col = (start_col + blocksize >= width-2) ? width-2 : (start_col + blocksize); + + poolPtr->append(std::bind(taskFunc_Calsim2ori, paras, conveparas, + start_row, end_row, start_col, end_col,width, height, + sar_local_angle,sar_angle, sar_dem_x,sar_dem_y, + demarray, gtt, inv_gtt)); + start_col = end_col; + } + start_row = end_row; + } + + std::cout << "doing...." << std::endl; + poolPtr->waiteFinish(); + // 输出文件; + + std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl; + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + const char* out_sar_sim = paras.out_sar_sim_path.c_str(); + + poolPtr->stop(); + GDALClose(demDataset); + + delete demarray, demBand, subthreadPool; + + out_sar_sim = conveparas.ori_sim.c_str(); + GDALDataset* poDstDS = poDriver->Create(out_sar_sim, width, height, 2, GDT_Float32, NULL); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_x, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-100000); + poDstDS->GetRasterBand(2)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_y, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(2)->SetNoDataValue(-100000); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + poDstDS = poDriver->Create(conveparas.out_orth_sar_local_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_local_angle, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + poDstDS = poDriver->Create(conveparas.out_orth_sar_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_angle, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + std::cout << "输出成果文件-over" << std::endl; + + std::cout << "end time:" << getCurrentTimeString() << std::endl; + free(sar_dem_x); + free(sar_dem_y); + free(sar_local_angle); + free(sar_angle); + free(gt); + free(inv_gt); + return 0; +} + +/* +11 12 13 14 +21 22 23 24 +31 32 33 34 +41 42 43 44 +*/ +//分块重采样 +int orth_ReSampling(int start_row,int end_row,int start_col,int end_col, + int width,int height,int ori_width,int ori_height , + float* ori_array, float* result_arr, float* ori_r_array, float* ori_c_array) { + for (int i = start_row; i < end_row; i++) { + for (int j = start_col; j < end_col; j++) { + int ori_ids = i * width + j; + int p_ids = 0; + point p{ ori_r_array[ori_ids] ,ori_c_array[ori_ids],0 }; + point p22 { floor(ori_r_array[ori_ids]),floor(ori_c_array[ori_ids]),0 }; + if (p22.x < 0 || p22.y < 0 || p22.x >= ori_height - 1 || p22.y >= ori_width - 1) { + continue; + } + else if (p22.x < 1 || p22.y < 1 || p22.x >= ori_height - 2 || p22.y >= ori_width - 2) { + //双线性 + point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids]; + point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids]; + point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids]; + p.x = p.x - p22.x; + p.y = p.y - p22.y; + p=bilineadInterpolation(p, p22, p23, p32, p33); + result_arr[ori_ids] = p.z; + } + else { // p22.x >= 1 && p22.y >= 1 && p22.x < ori_height - 2&& p22.y < ori_width - 2 + // 三次 + point p11{ p22.x - 1,p22.y - 1,0 }; p_ids = p11.x * ori_width + p11.y; p11.z = ori_array[p_ids]; + point p12{ p22.x - 1,p22.y ,0 }; p_ids = p12.x * ori_width + p12.y; p12.z = ori_array[p_ids]; + point p13{ p22.x - 1,p22.y + 1,0 }; p_ids = p13.x * ori_width + p13.y; p13.z = ori_array[p_ids]; + point p14{ p22.x - 1,p22.y + 2,0 }; p_ids = p14.x * ori_width + p14.y; p14.z = ori_array[p_ids]; + + point p21{ p22.x ,p22.y - 1,0 }; p_ids = p21.x * ori_width + p21.y; p21.z = ori_array[p_ids]; + point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids]; + point p24{ p22.x ,p22.y + 2,0 }; p_ids = p24.x * ori_width + p24.y; p24.z = ori_array[p_ids]; + + point p31{ p22.x + 1,p22.y - 1,0 }; p_ids = p31.x * ori_width + p31.y; p31.z = ori_array[p_ids]; + point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids]; + point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids]; + point p34{ p22.x + 1,p22.y + 2,0 }; p_ids = p34.x * ori_width + p34.y; p34.z = ori_array[p_ids]; + + point p41{ p22.x + 2,p22.y - 1,0 }; p_ids = p41.x * ori_width + p41.y; p41.z = ori_array[p_ids]; + point p42{ p22.x + 2,p22.y ,0 }; p_ids = p42.x * ori_width + p42.y; p42.z = ori_array[p_ids]; + point p43{ p22.x + 2,p22.y + 1,0 }; p_ids = p43.x * ori_width + p43.y; p43.z = ori_array[p_ids]; + point p44{ p22.x + 2,p22.y + 2,0 }; p_ids = p44.x * ori_width + p44.y; p44.z = ori_array[p_ids]; + p.x = p.x - p11.x; + p.y = p.y - p11.y; + p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44); + result_arr[ori_ids] = p.z; + } + } + } + + //std::cout << "\r" << end_row << "/" << height << "," << end_col << "/" << width << ","<GetRasterXSize(); + int height = sim2oriDataset->GetRasterYSize(); + int nCount = sim2oriDataset->GetRasterCount(); + double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + sim2oriDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = sim2oriDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = sim2oriDataset->GetProjectionRef(); + GDALRasterBand* ori_r_Band = sim2oriDataset->GetRasterBand(1); + float* ori_r_array = ReadRasterArray(ori_r_Band, width, height, gdal_datatype); + GDALRasterBand* ori_c_Band = sim2oriDataset->GetRasterBand(2); + float* ori_c_array = ReadRasterArray(ori_c_Band, width, height, gdal_datatype); + // 读取行列号 + delete ori_r_Band, ori_c_Band; + + + for (int t = 0; t < conveparas.file_count; t++) { + // 读 + // 创建 + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + string in_file_path = conveparas.inputFile_paths[t]; + string out_file_path = conveparas.outFile_paths[t]; + + GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly)); + int orth_width = inDataset->GetRasterXSize(); + int orth_height = inDataset->GetRasterYSize(); + int orth_num = inDataset->GetRasterCount(); + // 写 + + GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, orth_num, GDT_Float32, NULL); + outDstDS->SetGeoTransform(gt); + outDstDS->SetProjection(Projection); + + + float* result_arr = (float*)calloc(width * height, sizeof(float)); + int psize = width * height; + int blocksize = 1000; + for (int b = 1; b <= orth_num; b++) { + for (int i = 0; i < psize; i++) { + result_arr[i] = -9999; + } + GDALRasterBand* ori_Band = inDataset->GetRasterBand(b); + float* ori_arr= ReadRasterArray(ori_Band, orth_width, orth_height, gdal_datatype); + + // 线程池 + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + + // 三次样条重采样 + for (int start_row = 0; start_row < height; start_row = start_row + blocksize) { + int end_row = start_row + blocksize >= height ? height : start_row + blocksize; + for (int start_col = 0; start_col < width; start_col = start_col + blocksize) { + int end_col = start_col + blocksize >= width ? width : start_col + blocksize; + // 分块计算结果 + poolPtr->append(std::bind(orth_ReSampling,start_row,end_row,start_col,end_col,width,height, orth_width, orth_height, + ori_arr, result_arr, ori_r_array, ori_c_array)); + } + } + + std::cout << "resampling...." << std::endl; + poolPtr->waiteFinish(); + // 输出文件 + std::cout<GetRasterBand(b)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0); + outDstDS->GetRasterBand(b)->SetNoDataValue(-9999); + poolPtr->stop(); + delete ori_arr, ori_Band, subthreadPool; + } + free(result_arr); + GDALFlushCache(outDstDS); + GDALClose(outDstDS); + GDALClose(inDataset); + + } + free(gt); + free(inv_gt); + delete ori_r_array, ori_c_array;// , sim2oriDataset; + //GDALClose(sim2oriDataset); + return 0; +} + +/// +/// 生成影像的强度图 +/// +/// +/// +/// +/// +int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num) +{ + for (int t = 0; t < conveparas.file_count; t++) { + // 读 + // 创建 + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + string in_file_path = conveparas.outFile_paths[t]; + string out_file_path = conveparas.outFile_pow_paths[t]; + + GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly)); + int width = inDataset->GetRasterXSize(); + int height = inDataset->GetRasterYSize(); + int num = inDataset->GetRasterCount(); + double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + inDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + const char* Projection = inDataset->GetProjectionRef(); + + GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, 1, GDT_Float32, NULL); + outDstDS->SetGeoTransform(gt); + outDstDS->SetProjection(Projection); + GDALDataType gdal_datatype = inDataset->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* ori_Band = inDataset->GetRasterBand(1); + float* ori_a_array = ReadRasterArray(ori_Band, width, height, gdal_datatype); + ori_Band = inDataset->GetRasterBand(2); + float* ori_b_array = ReadRasterArray(ori_Band, width, height, gdal_datatype); + + + + float* result_arr = (float*)calloc(width * height, sizeof(float)); + int psize = width * height; + int blocksize = 1000; + for (int i = 0; i < psize; i++) { + result_arr[i] = -9999; + } + + // 线程池 + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + + // 三次样条重采样 + for (int start_row = 0; start_row < height; start_row = start_row + blocksize) { + int end_row = start_row + blocksize >= height ? height : start_row + blocksize; + for (int start_col = 0; start_col < width; start_col = start_col + blocksize) { + int end_col = start_col + blocksize >= width ? width : start_col + blocksize; + // 分块计算结果 + poolPtr->append(std::bind(orth_pow, start_row, end_row, start_col, end_col, width, height, + result_arr, ori_a_array, ori_b_array)); + } + } + + std::cout << "pow resampling ..." << std::endl; + poolPtr->waiteFinish(); + // 输出文件 + std::cout << t << " , " << 1 << ",输出成果文件:" << getCurrentTimeString() << std::endl; + outDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0); + outDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poolPtr->stop(); + delete ori_a_array, ori_b_array, ori_Band, subthreadPool; + free(gt); + free(inv_gt); + free(result_arr); + //GDALFlushCache(outDstDS); + //GDALClose(outDstDS); + //GDALClose(inDataset); + //delete poDriver; + + } + + //GDALClose(sim2oriDataset); + return 0; +} + +int ResamplingSim(ParameterInFile paras) +{ + GDALAllRegister(); + // 打开DEM影像 + GDALDataset* simDataset = (GDALDataset*)(GDALOpen(paras.out_sar_sim_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int ori_sim_width = simDataset->GetRasterXSize(); + int ori_sim_height = simDataset->GetRasterYSize(); + int width = paras.sim_width; + int height = paras.sim_height; + float width_scales = width * 1.0 / ori_sim_width; + float height_scales = height * 1.0 / ori_sim_height; + + GDALClose(simDataset); + ResampleGDAL(paras.out_sar_sim_path.c_str(), paras.out_sar_sim_resampling_path.c_str(), width_scales, height_scales, GDALResampleAlg::GRA_CubicSpline); + return 0; +} + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX = 1.0, float fResY = 1.0, GDALResampleAlg eResample = GRA_Bilinear) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if (pDSrc == NULL) + { + return -1; + } + + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = GDALDataType::GDT_Float32;// pDSrc->GetRasterBand(1)->GetRasterDataType(); + + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + + double dGeoTrans[6] = { 0 }; + int nNewWidth = width, nNewHeight = height; + pDSrc->GetGeoTransform(dGeoTrans); + + + bool bNoGeoRef = false; + long double dOldGeoTrans0 = dGeoTrans[0]; + //如果没有投影,人为设置一个 + if (strlen(pszSrcWKT) <= 0) + { + //OGRSpatialReference oSRS; + //oSRS.SetUTM(50,true); //北半球 东经120度 + //oSRS.SetWellKnownGeogCS("WGS84"); + //oSRS.exportToWkt(&pszSrcWKT); + //pDSrc->SetProjection(pszSrcWKT); + + + ////////////////////////////////////////////////////////////////////////// + dGeoTrans[0] = 1.0; + pDSrc->SetGeoTransform(dGeoTrans); + ////////////////////////////////////////////////////////////////////////// + + + bNoGeoRef = true; + } + + + //adfGeoTransform[0] /* top left x */ + //adfGeoTransform[1] /* w-e pixel resolution */ + //adfGeoTransform[2] /* rotation, 0 if image is "north up" */ + //adfGeoTransform[3] /* top left y */ + //adfGeoTransform[4] /* rotation, 0 if image is "north up" */ + //adfGeoTransform[5] /* n-s pixel resolution */ + + + dGeoTrans[1] = dGeoTrans[1] / fResX; + dGeoTrans[5] = dGeoTrans[5] / fResY; + nNewWidth = static_cast(nNewWidth * fResX + 0.5); + nNewHeight = static_cast(nNewHeight * fResY + 0.5); + + + //创建结果数据集 + GDALDataset* pDDst = pDriver->Create(pszOutFile, nNewWidth, nNewHeight, nBandCount, dataType, NULL); + if (pDDst == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(dGeoTrans); + + + void* hTransformArg = NULL; + hTransformArg = GDALCreateGenImgProjTransformer2((GDALDatasetH)pDSrc, (GDALDatasetH)pDDst, NULL); //GDALCreateGenImgProjTransformer((GDALDatasetH) pDSrc,pszSrcWKT,(GDALDatasetH) pDDst,pszSrcWKT,FALSE,0.0,1); + + + if (hTransformArg == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return -3; + } + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + + psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + + + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = hTransformArg; + + + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) + { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) + { + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return -3; + } + + + oWo.ChunkAndWarpImage(0, 0, nNewWidth, nNewHeight); + + + GDALDestroyGenImgProjTransformer(hTransformArg); + GDALDestroyWarpOptions(psWo); + if (bNoGeoRef) + { + dGeoTrans[0] = dOldGeoTrans0; + pDDst->SetGeoTransform(dGeoTrans); + //pDDst->SetProjection(""); + } + GDALFlushCache(pDDst); + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return 0; +} + +/// +/// 根据地面坐标获取计算结果 +/// +/// +/// +/// +/// +point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas) +{ + long double Starttime = paras.imgStartTime; + long double lamda = paras.lamda; + long double refrange = paras.refrange; + long double* doppler_para = paras.doppler_para; + long double LightSpeed = paras.LightSpeed; + long double delta_t = paras.delta_t; + long double R0 = paras.R0; + long double delta_R = paras.delta_R; + long double SatelliteModelStartTime = paras.SatelliteModelStartTime; + long double* polySatellitePara = paras.polySatellitePara; + int sim_sar_width = paras.sim_width; + int sim_sar_height = paras.sim_height; + int polynum = paras.polynum; + int doppler_paramenter_number = paras.doppler_paramenter_number; + + point pixelpoint = PSTN(landp, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + long double r, c; + sim2ori(pixelpoint.x, pixelpoint.y, r, c, convparas.sim2ori_paras); + return point{ r,c,0 }; +} + +// 根据坐标变换求解行列号 +int calSARPosition(ParameterInFile paras, ConvertResampleParameter converPara) { + // + + return 0; + +} + + +/// +/// 测试代码 +/// + +int testPP() { + + point landpoint; + landpoint.x = -1945072.5; + landpoint.y = 5344083.0; + landpoint.z = 2878316.0; + point targetpoint; + targetpoint.x = 31; + targetpoint.y = 118; + targetpoint.z = 33; + + landpoint = LLA2XYZ(targetpoint); + std::cout << "PTSN\nX:" << landpoint.x<< "\nY:" << landpoint.y << "\nZ:" << landpoint.z << "\n"; // <0.1 + return 0; +} + +int testPTSN(ParameterInFile paras) { + point landpoint; + landpoint.x = -1945072.5; + landpoint.y = 5344083.0; + landpoint.z = 2878316.0; + point targetpoint; + targetpoint.x = 31; + targetpoint.y = 118; + targetpoint.z = 1592144812.73686337471008300781; + + landpoint=LLA2XYZ(targetpoint); + point pixelpoint = PSTN(landpoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + std::cout << "PTSN\nX:" << targetpoint.x - pixelpoint.x << "\nY:" << targetpoint.y - pixelpoint.y << "\nZ:" << targetpoint.z - pixelpoint.z << "\n"; // <0.1 + + SatelliteSpacePoint sateP = getSatellitePostion(1592144812.7368634, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum); + SatelliteSpacePoint sateT{ -3044863.2137617283, 5669112.1303918585, 3066571.1073331647, -26.15659591374557, 3600.8531673370803, -6658.59211430739 }; + std::cout << "Sate\nX:" << sateP.x - sateT.x << "\nY:" << sateP.y - sateT.y << "\nZ:" << sateP.z - sateT.z << "\nVx" << sateP.vx - sateT.vx << "\nVy:" << sateP.vy - sateT.vy << "\nVz:" << sateP.vz - sateT.vz << "\n"; + return 0; +} diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h new file mode 100644 index 0000000..7a11165 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h @@ -0,0 +1,576 @@ +#pragma once +#include +#include +#include +#include +#include +#include "gdalwarper.h" + +#define PI_180 180/3.141592653589793238462643383279; +#define T180_PI 3.141592653589793238462643383279/180; + +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI + +const long double PI=3.141592653589793238462643383279; +const long double epsilon = 0.000000000000001; +const long double pi = 3.14159265358979323846; +const long double d2r = pi / 180; +const long double r2d = 180 / pi; + +const long double a = 6378137.0; //椭球长半轴 +const long double f_inverse = 298.257223563; //扁率倒数 +const long double b = a - a / f_inverse; +const long double e = sqrt(a * a - b * b) / a; +const long double eSquare = e*e; + + + +int testPP(); + +using namespace std; +/// +/// 内敛函数 +/// + +struct point // 点 SAR影像的像素坐标; +{ + long double x; // 纬度 lat pixel_row + long double y; // 经度 lon pixel_col + long double z; // 高程 ati pixel_time +}; + +struct VectorPoint { + long double x; + long double y; + long double z; +}; +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +inline point LLA2XYZ(point& LLA) { + long double L = LLA.x * d2r; + long double B = LLA.y * d2r; + long double H = LLA.z; + + long double sinB = sin(B); + long double cosB = cos(B); + + //long double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + long double N = a / sqrt(1 - eSquare * sinB * sinB); + point result = { 0,0,0 }; + result.x = (N + H) * cosB * cos(L); + result.y = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.z = (N * (1 - eSquare) + H) * sinB; + return result; +} + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +point XYZ2LLA(point& XYZ); + +/// +/// 计算两个点之间的XY平面欧式距离的平方 +/// +/// +/// +/// +inline long double caldistanceXY(point& p1, point& p2) { + //return pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2); + return (p1.x - p2.x)* (p1.x - p2.x) + (p1.y - p2.y)* (p1.y - p2.y); +} + +/// +/// 使用两个点,生成向量 p1-->p2 +/// +/// p1 +/// p2 +/// 向量 +inline VectorPoint getVector(point& p1, point& p2) { + VectorPoint result = { 0,0,0 }; + result.x = p2.x - p1.x; + result.y = p2.y - p1.y; + result.z = p2.z - p1.z; + return result; +} + +/// +/// 获取向量的模 +/// +/// 向量 +/// 向量模 +inline long double getModule(VectorPoint& vector1) { + //return sqrt(pow(vector1.x, 2) + pow(vector1.y, 2) + pow(vector1.z, 2)); + return sqrt(vector1.x* vector1.x + vector1.y* vector1.y + vector1.z* vector1.z); +} + +inline long double getModuleV1V2(VectorPoint& v1, VectorPoint& v2) +{ + return sqrt((v1.x * v1.x + v1.y * v1.y + v1.z * v1.z) * (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z)); +} + +/// +/// 向量夹角的角度( 角度) +/// +/// 向量 +/// 向量夹角的角度 +inline long double getVectorAngle(VectorPoint& vector1,VectorPoint& vector2) { + //return Radians2Degrees( acos((vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModule(vector1) * getModule(vector2)))); + return Radians2Degrees(acos((vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModuleV1V2(vector1, vector2)))); + +} + + +/// +/// 向量的夹角值 +/// +/// 向量 +/// 向量夹角的角度 +inline long double getVectorAngleValue(VectorPoint& vector1, VectorPoint& vector2) { + //return (vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModule(vector1) * getModule(vector2)); + return (vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModuleV1V2(vector1, vector2)); +} +/// +/// 向量点乘 +/// +/// 向量1 +/// 向量2 +/// 点乘值 +inline long double Vectordot(VectorPoint& V1, VectorPoint& v2) { + return V1.x * v2.x + V1.y * v2.y + V1.z * v2.z; +} + +/// +/// 向量点乘 +/// +/// 向量1 +/// 系数值 +/// 向量与数之间的插值 +inline VectorPoint VectordotNumber(VectorPoint& V1, long double lamda) { + V1.x = V1.x * lamda; + V1.y = V1.y * lamda; + V1.z = V1.z * lamda; + return V1; +} + +/// +/// 向量叉乘 +/// 旋转方向:v1->v2 +/// +/// v1 +/// v2 +/// 叉乘的结果向量 +inline VectorPoint VectorFork(VectorPoint &v1, VectorPoint& v2) { + VectorPoint result{ 0,0,0 }; + result.x = v1.y * v2.z - v1.z * v2.y; + result.y =v1.z*v2.x -v1.x * v2.z; + result.z = v1.x * v2.y - v1.y * v2.x; + return result; +} + + +// +// 参数文件解析 +// + +//参数文件标准格式 +// 文件值 类型 对应的代号 +// DEM文件的路径 str dem_path +// 模拟影像输出路径 str sar_sim_path +// 模拟影像的宽 int +// 模拟影像的高 int +// 模拟影像的匹配坐标文件输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path +// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path +// 采样率 long double sample_f +// 近斜距 long double R0 +// 成像起始时间 long double starttime ---UTC 时间 +// 光速 long double +// 波长 long double +// 多普勒参考时间 long double TO ---UTC 时间 +// 脉冲重复频率 long double PRF +// 斜距采样间隔 long double delta_R +// 多普勒系数个数 int +// 多普勒系数1 long double +// 多普勒系数2 long double +// .... +// 卫星轨道模型是否为多项式模型 int 1 是。0 不是 +// 卫星轨道模型多项式次数 int 4 5 +// 卫星轨道模型起始时间 long double +// 卫星轨道模型X值系数1 long double +// .... +// 卫星轨道模型Y值系数1 long double +// ... +// 卫星轨道模型Z值系数1 long double +// ... +// 卫星轨道模型Vx值系数1 long double +// ... +// 卫星轨道模型Vy值系数1 long double +// ... +// 卫星轨道模型Vz值系数1 long double +// ... +// +// + +class ParameterInFile +{ +public: + ParameterInFile(std::string infile_path); + ParameterInFile(const ParameterInFile& paras); + ~ParameterInFile(); +public: + //参数组 + std::string dem_path; //dem 路径 + std::string out_sar_sim_path; // 输出模拟sar + std::string out_sar_sim_dem_path; // 输出模拟sar + std::string out_sar_sim_resampling_path; // 输出模拟sar + std::string out_sar_sim_resampling_rc; + int sim_height; // 模拟影像的高 + int sim_width; + long double widthspace;// 距离向分辨率 + std::string sar_sim_match_point_path; //输出模拟影像的地点x + std::string sar_sim_match_point_xyz_path; //输出模拟影像的地点x + int sample_f; //采样率 + long double R0; //近斜距 + long double LightSpeed;//光速 + long double lamda;//波长 + long double refrange;// 参考斜距 + + long double delta_R; // 斜距间隔 + long double imgStartTime; //成像起始时间 + long double PRF;// 脉冲重复率 + long double delta_t;// 时间间隔 + // 多普勒 + int doppler_paramenter_number;// 多普勒系数个数 + long double* doppler_para;//多普勒系数 + //卫星轨道模型 + int polySatelliteModel;// 是否为卫星多轨道模型 + int polynum;// 多项数 + long double SatelliteModelStartTime; + long double* polySatellitePara; +}; + +// 根据轨道模型计算卫星空间位置 +struct SatelliteSpacePoint { + long double x=0; + long double y=0; + long double z=0; + long double vx=0; + long double vy=0; + long double vz=0; + +}; + + +/// +/// 根据卫星轨道模型计算卫星 +/// +/// 卫星轨道点时间 +/// 卫星轨道模型起始时间 +/// 卫星轨道坐标模型参数 +/// 多项式项数 +/// +inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime,long double SatelliteModelStartTime,long double* polySatellitePara,int polynum); + +/// +/// 数值模拟法计算多普勒频移值 +/// +/// 斜距 +/// 光速 +/// 多普勒参考时间 +/// 多普勒参数 +/// 多普勒频移值 +inline long double calNumericalDopplerValue(long double R,long double LightSpeed,long double T0, long double* doppler_para,int doppler_paramenter_number); + +/// +/// 根据理论模型计算多普勒频移值 +/// +/// 斜距 +/// 波长 +/// 地面->卫星的空间向量 +/// 地面->卫星之间的速度向量 +/// 多普勒频移值 +inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl); + +/// +/// 根据地面点求解对应的sar影像坐标 +/// +/// 地面点的坐标--地固坐标系 +/// 影片开始成像时间 +/// 波长 +/// 多普勒参考时间 +/// 光速 +/// 时间间隔 +/// 近斜距 +/// 斜距间隔 +/// 卫星轨道模型时间 +/// 卫星轨道坐标模型参数 +/// 卫星轨道模型项数 +/// 多普勒模型数 +/// 影像坐标(x:行号,y:列号,z:成像时刻) +inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double T0, long double* doppler_para, long double LightSpeed, long double delta_t, long double R0, long double delta_R, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4, int doppler_paramenter_number = 5); + + + +struct translateArray { + long double a0, a1, a2; + long double b0, b1, b2; +}; +/// +/// 转换影像 +/// +/// +/// +/// +/// +/// +inline point Translation(long double row_ids,long double col_ids,long double value,translateArray& gt) { + + point result{ 0,0,0 }; + result.x = gt.a0 + gt.a1 * col_ids + gt.a2 * row_ids; + result.y = gt.b0 + gt.b1 * col_ids + gt.b2 * row_ids; + result.z = value; + return result; +} + +inline int Translation(long double& x, long double& y, long double& r, long double& c, translateArray& gt) { + + c = gt.a0 + gt.a1 * x + gt.a2 * y; + r = gt.b0 + gt.b1 * x + gt.b2 * y; + return 0; +} + +/// +/// dem块 +/// +class dem_block { + +public: + dem_block(int all_start_row,int all_start_col,int start_row, int end_row, int start_col, int end_col, int height, int width,int sample_f); + dem_block(const dem_block& demblocks); + ~dem_block(); + dem_block resample_dem(); + //dem_block resample_dem_cudic(); + int rowcol2blockids(int row_ids, int col_ids); + point getpointblock(int row_ids, int col_ids); + int setpointblock(int row_ids, int col_ids, point& value); + point getpointblock(int ids); + int setpointblock(int ids, point& value); + int UpdatePointCoodinarary(); + VectorPoint getslopeVector(int row_ids, int col_ids); +public: + int all_start_row; + int all_start_col; + int start_row; // 目标区域的起始行号 + int end_row; // + int start_col; // 目标区域的起始列号 + int end_col; + int height; + int width; + int size; + int sample_f; + point* pointblock; // 原始块 +}; + + + +inline point bilineadInterpolation(point& p,point& p11,point& p12,point& p21,point& p22); + +inline point cubicInterpolation(point& p, point& p11, point& p12,point& p13,point& p14, point& p21, point& p22,point& p23,point& p24,point& p31,point& p32,point& p33,point& p34,point& p41,point& p42,point& p43,point& p44); + +/// +/// 双线性插值方法 +/// +/// +/// +/// +/// +/// +/// +inline point SARbilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22) { + + + + +} +/// +/// 入射角 -- 弧度制 +/// +struct IncidenceAngle +{ + long double incidenceAngle; // 雷达入射角 + long double localincidenceAngle; // 局地入射角 +}; + +struct matchPoint { + long double r, c, ti; + long double land_x, land_y, land_z; + long double distance; + long double incidenceAngle, localincidenceAngle; +}; +/// +/// 模拟sar 的矩阵块,累加模块默认使用short 类型(累加上限: +/// +class sim_block { +public: + sim_block(int start_row,int end_row,int start_col,int end_col,int height,int width); + sim_block(const sim_block& sim_blocks); + ~sim_block(); + + int rowcol2blockids(int row_ids, int col_ids); + short getsimblock(int row_ids, int col_ids); + int setsimblock(int row_ids,int col_ids, short value); + int addsimblock(int row_ids, int col_ids,short value); + matchPoint getpointblock(int row_ids,int col_ids); + int setpointblock(int row_ids, int col_ids, matchPoint value); + // + long double getdistanceblock(int row_ids, int col_ids); + int setdistanceblock(int row_ids, int col_ids, long double value); + +public: + int start_row; + int end_row; + int start_col; + int end_col; + int height; + int width; + int size; + short* block; + long double* distanceblock; + matchPoint* pointblock; +}; + + +/// +/// 根据卫星坐标,地面坐标,地面法向量,求解对应的雷达入射角和局地入射角 +/// +/// 卫星空间坐标 +/// 地面坐标 +/// 地面坡度 +/// 入射角文件 +inline IncidenceAngle calIncidence(point satellitepoint,point landpoint,VectorPoint slopvector) { + + IncidenceAngle result; + VectorPoint R_ls = getVector(landpoint, satellitepoint); + result.localincidenceAngle = getVectorAngleValue(R_ls, slopvector); + VectorPoint R_s{ satellitepoint.x,satellitepoint.y,satellitepoint.z }; + result.incidenceAngle = getVectorAngleValue(R_s, R_ls); + return result; +} + + +int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount); + +int ResamplingSim(ParameterInFile paras); +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX, float fResY, GDALResampleAlg eResample); + +/// +/// 模拟sar的处理算法模块。 +/// 为了控制内存的取用 +/// 线程数:8 --以进程类的方式进行管理--使用队列的方法 +/// 线程内存:dem_block_size*sample_f*sample_f< 1 G +/// +/// 参数文件项 +/// 线程数默认为8 +/// 执行情况 +int SimProcess(ParameterInFile paras, int thread_num); +int SimProcess_LVY(ParameterInFile paras, int thread_num); +int WriteMatchPoint(string path, std::vector* matchps); +// 测试函数接口 + +int testPTSN(ParameterInFile paras); + + +/// +/// +/// 考虑影像的插值方案 +/// +/// + +class ConvertResampleParameter { +public: + ConvertResampleParameter(string path); + ConvertResampleParameter(const ConvertResampleParameter& para); + ~ConvertResampleParameter(); +public: + string in_ori_dem_path; + string ori_sim; + string out_sar_xyz_path; + string out_sar_xyz_incidence_path; + string out_orth_sar_incidence_path; + string out_orth_sar_local_incidence_path; + string outFolder_path; + int file_count; + std::vector inputFile_paths; + std::vector outFile_paths; + std::vector outFile_pow_paths; + int ori2sim_num; + long double* ori2sim_paras; + int sim2ori_num; + long double* sim2ori_paras; +}; + +inline int ori2sim(long double ori_x,long double ori_y,long double& sim_x,long double& sim_y,long double* conver_paras) { + long double xy = ori_x * ori_y; + long double x2 = ori_x * ori_x; + long double y2 = ori_y * ori_y; + + sim_x = conver_paras[0] + ori_x * conver_paras[1] + ori_y * conver_paras[2] + x2 * conver_paras[3] + y2 * conver_paras[4] + xy * conver_paras[5]; + sim_y = conver_paras[6] + ori_x * conver_paras[7] + ori_y * conver_paras[8] + x2 * conver_paras[9] + y2 * conver_paras[10] + xy * conver_paras[11]; + return 1; +} + +/// +/// 将模拟的行列号转换为目标行列号 +/// +/// 模拟的行号 +/// 模拟的列号 +/// 待计算的目标行号 +/// 待计算的目标列号 +/// 变换矩阵 +/// 默认:0 表示计算结束 +inline int sim2ori(long double sim_r,long double sim_c,long double& ori_r,long double& ori_c, long double* conver_paras) { + long double xy = sim_r * sim_c; + long double x2 = sim_r * sim_r; + long double y2 = sim_c * sim_c; + ori_r = conver_paras[0] + sim_r * conver_paras[1] + sim_c * conver_paras[2] + x2 * conver_paras[3] + y2 * conver_paras[4] + xy * conver_paras[5]; + ori_c = conver_paras[6] + sim_r * conver_paras[7] + sim_c * conver_paras[8] + x2 * conver_paras[9] + y2 * conver_paras[10] + xy * conver_paras[11]; + return 0; +} + +// 查询精确坐标 + +point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas); + +int SimProcessBlock_CalXYZ(dem_block demblock, ParameterInFile paras, ConvertResampleParameter converParas, matchPoint* result_shared, int* Pcount); +int SimProcess_CalXYZ(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); + + +/* + 正射模块思路 + dem->sim->ori(r,c) <-重采样-> ori + step1: 计算dem 对应的 ori 坐标,并保存-> ori_sim.tif (r,c,incidence,localincidence) + step2: 根据结果插值计算对应的a,b + +*/ +int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); // 正射模块 + + +/* +重采样: +step1:读取目标栅格,并根据目标栅格创建对象 +step2: +*/ +int SimProcess_ResamplingOri2Orth(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); + +/* +生成强度图 +*/ +int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); // 正射模块 \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp new file mode 100644 index 0000000..70e8eee --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp @@ -0,0 +1,30 @@ +锘#include "common.h" + +#include +#include +#include + +/** + * @brief GetCurrentTime 鑾峰彇褰撳墠鏃堕棿 + * @return + */ +std::string getCurrentTimeString() { + + std::time_t t = std::time(NULL); + char mbstr[100]; + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", + std::localtime(&t)); + std::string strTime = mbstr; + return strTime; +} + +std::string getCurrentShortTimeString() { + + std::time_t t = std::time(NULL); + char mbstr[100]; + std::strftime(mbstr, sizeof(mbstr), "%H:%M:%S", + std::localtime(&t)); + std::string strTime = mbstr; + return strTime; +} + diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h new file mode 100644 index 0000000..75fee08 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h @@ -0,0 +1,14 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include + +/** + * @brief GetCurrentTime 获取当前时间 + * @return + */ +std::string getCurrentTimeString(); +std::string getCurrentShortTimeString(); + +#endif \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props new file mode 100644 index 0000000..9535a71 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props @@ -0,0 +1,17 @@ + + + + + + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\bin\intel64;$(VC_ExecutablePath_x64);$(CommonExecutablePath) + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\include;C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\include;$(oneMKLIncludeDir);$(IncludePath) + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\lib\intel64;C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files (x86)\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;$(LibraryPath) + <_PropertySheetDisplayName>mkl_debug_x64 + + + + mkl_intel_ilp64.lib;mkl_intel_thread.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;libiomp5md.lib;impi.lib;mkl_sequential.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props new file mode 100644 index 0000000..d675cec --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props @@ -0,0 +1,16 @@ + + + + + + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\bin\intel64;$(VC_ExecutablePath_x64);$(CommonExecutablePath) + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\include;C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\include;$(oneMKLIncludeDir);$(IncludePath) + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\lib\intel64;C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files (x86)\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;$(LibraryPath) + + + + mkl_intel_ilp64.lib;mkl_intel_thread.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;libiomp5md.lib;impi.lib;mkl_sequential.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp new file mode 100644 index 0000000..18a154f --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp @@ -0,0 +1,11 @@ +锘#include "taskprocess.h" + +TaskProcess::TaskProcess() +{ + +} + +TaskProcess::~TaskProcess() +{ + +} diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h new file mode 100644 index 0000000..0688930 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h @@ -0,0 +1,15 @@ +锘#ifndef TASKPROCESS_H +#define TASKPROCESS_H + +class TaskProcess +{ +public: + TaskProcess(); + ~TaskProcess(); +private: + + +}; + + +#endif \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp new file mode 100644 index 0000000..2e4fae9 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp @@ -0,0 +1,182 @@ +锘#include "threadpool.hpp" + +#include +#include +//#include + +#include + +static const int MAX_THREADS = 10000; //鏈澶х嚎绋嬫暟鐩 +/** + * @brief ThreadPool + * @param number[in]绾跨▼鏁 *榛樿寮涓涓嚎绋 + * @param + * emptyQuit[in]绌虹嚎绋嬮鍑猴紝榛樿false銆傚鏋滀负true锛岄渶瑕佸厛娣诲姞浠诲姟锛屽啀start锛岀劧鍚巜aite瀹屾垚 + */ +ThreadPool::ThreadPool(int number, bool emptyQuit) + : m_StopFlag(false), m_EmptyQuit(emptyQuit), m_JoinFlag(false), m_QuitNum(0), m_EmptyQuitWaite(false) { + std::cout << "绾跨▼姹犱腑绾跨▼鏁帮細" << number << std::endl; + if (number <= 0 || number > MAX_THREADS) throw std::exception(); + m_ThreadNum = number; +} + +ThreadPool::~ThreadPool() { + // std::cout << "~ThreadPool()" << std::endl; + stop(); +} +/** + * @brief stop 鍋滄 + */ +void ThreadPool::stop() { + //淇濊瘉澶氱嚎绋嬫儏鍐典笅鍙皟鐢ㄤ竴娆topThreadGroup + std::call_once(m_CallStopSlag, [this] { stopThreadGroup(); }); +} +/** + * @brief stopThreadGroup 鍋滄绾跨▼缁 + */ +void ThreadPool::stopThreadGroup() { + m_StopFlag = true; + Sleep(500); + m_Condition.notify_all(); + waiteFinish(); //绛夊緟绾跨▼閫鍑 + std::thread* thread = NULL; + for (int i = 0; i < m_WorkThreads.size(); i++) + { + thread = m_WorkThreads[i]; + if (thread != NULL) + { + thread->join(); + delete thread; + thread = NULL; + } + m_WorkThreads[i] = NULL; + } + m_WorkThreads.clear(); +} +/** + * @brief startThread 鍚姩绾跨▼ + */ +void ThreadPool::startThread() { + for (int i = 0; i < m_ThreadNum; i++) { + std::thread* thread = new std::thread(ThreadPool::worker, this); + m_WorkThreads.push_back(thread); + } +} +/** + * @brief waiteThreadFinish 绛夊緟绾跨▼缁撴潫 + */ +void ThreadPool::waiteThreadFinish() { + if (m_JoinFlag) return; + if (m_EmptyQuit) + { + m_EmptyQuitWaite = true; + do + { + if (m_ThreadNum == m_QuitNum) + break; + Sleep(400); + + } while (true); + m_StopFlag = true; + m_Condition.notify_all(); + + } + /* for (int i = 0; i < work_threads.size(); i++) { + if (work_threads[i]) { work_threads[i]->join(); } + }*/ + m_JoinFlag = true; +} +/** + * @brief start 鍚姩 + */ +void ThreadPool::start() { + std::call_once(m_CallStartSlag, [this] { startThread(); }); +} +/** + * @brief waiteFinish 绛夊緟鎵鏈変换鍔$粨鏉,璁剧疆涓轰换鍔′负绌洪鍑烘椂璋冪敤 + */ +void ThreadPool::waiteFinish() { + std::call_once(m_CallWaiteFinisFlag, [this] { waiteThreadFinish(); }); +} +/** +* @brief 浠诲姟鏁 +*/ +int ThreadPool::taskNum() +{ + return m_TasksQueue.size(); +} +/** + * @brief append 寰璇锋眰闃熷垪锛渢ask_queue锛炰腑娣诲姞浠诲姟 + * @param task + * @return + */ +bool ThreadPool::append(Task task) { + /*鎿嶄綔宸ヤ綔闃熷垪鏃朵竴瀹氳鍔犻攣锛屽洜涓轰粬琚墍鏈夌嚎绋嬪叡浜*/ + m_DataMutex.lock(); + m_TasksQueue.push(task); + m_DataMutex.unlock(); + + m_Condition.notify_one(); //绾跨▼姹犳坊鍔犺繘鍘讳簡浠诲姟锛岃嚜鐒惰閫氱煡绛夊緟鐨勭嚎绋 + return true; +} +/** + * @brief worker 绾跨▼鍥炶皟鍑芥暟 + * @param arg + * @return + */ +void* ThreadPool::worker(void* arg) { + ThreadPool* pool = (ThreadPool*)arg; + pool->run(); + return pool; +} +/** + * @brief notEmpty 鏄惁绌 + * @return + */ +bool ThreadPool::notEmpty() { + bool empty = m_TasksQueue.empty(); + if (empty) { + // std::ostringstream oss; + // oss << std::this_thread::get_id(); + // printf("queue empty thread id %s waite...!\n", oss.str().c_str()); + } + return !empty; +} +/** + * @brief run 宸ヤ綔绾跨▼闇瑕佽繍琛岀殑鍑芥暟,涓嶆柇鐨勪粠浠诲姟闃熷垪涓彇鍑哄苟鎵ц + */ +void ThreadPool::run() { + bool flag = false; + int remainder = 0; + while (!m_StopFlag) { + flag = false; + { + std::unique_lock lk(this->m_QueueMutex); + /*銆unique_lock() 鍑轰綔鐢ㄥ煙浼氳嚜鍔ㄨВ閿併*/ + m_Condition.wait(lk, [this] { return m_StopFlag || notEmpty(); }); + } + + if (m_StopFlag) break; + Task task; + m_DataMutex.lock(); + //濡傛灉浠诲姟闃熷垪涓嶄负绌猴紝灏卞仠涓嬫潵绛夊緟鍞ら啋 + if (!this->m_TasksQueue.empty()) { + task = m_TasksQueue.front(); + m_TasksQueue.pop(); + remainder = m_TasksQueue.size(); + flag = true; + } + m_DataMutex.unlock(); + if (flag) task(); + //濡傛灉闃熷垪涓虹┖骞朵笖瀹屾垚閫鍑猴紝宸茬粡寮濮嬬瓑寰呴鍑哄氨閫鍑 + if (m_TasksQueue.empty() && m_EmptyQuit && m_EmptyQuitWaite) + { + break; + } + + } + m_QuitNum += 1; + std::ostringstream oss; + oss << std::this_thread::get_id(); + printf("thread %s end\n", oss.str().c_str()); +} diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp new file mode 100644 index 0000000..1a50eba --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp @@ -0,0 +1,102 @@ +锘#ifndef THREADPOOL_HPP +#define THREADPOOL_HPP + +#include +#include +#include +#include +#include //unique_ptr +#include +#include +#include +#include + +typedef std::function Task; + +class ThreadPool { +public: + /** + * @brief ThreadPool + * @param number[in]绾跨▼鏁 *榛樿寮涓涓嚎绋 + * @param + * emptyQuit[in]绌虹嚎绋嬮鍑猴紝榛樿false銆傚鏋滀负true锛岄渶瑕佸厛娣诲姞浠诲姟锛屽啀start锛岀劧鍚巜aite瀹屾垚 + */ + ThreadPool(int number = 1, bool emptyQuit = false); + ~ThreadPool(); + + /** + * @brief append 寰璇锋眰闃熷垪锛渢ask_queue锛炰腑娣诲姞浠诲姟 + * @param task + * @return + */ + bool append(Task task); + /** + * @brief start 鍚姩 + */ + void start(); + /** + * @brief stop 鍋滄 + */ + void stop(); + /** + * @brief waiteFinish 绛夊緟鎵鏈変换鍔$粨鏉,璁剧疆涓轰换鍔′负绌洪鍑烘椂璋冪敤 + */ + void waiteFinish(); + /** + * @brief 浠诲姟鏁 + */ + int taskNum(); +private: + /** + * @brief worker 绾跨▼鍥炶皟鍑芥暟 + * @param arg + * @return + */ + static void *worker(void *arg); + /** + * @brief run 宸ヤ綔绾跨▼闇瑕佽繍琛岀殑鍑芥暟,涓嶆柇鐨勪粠浠诲姟闃熷垪涓彇鍑哄苟鎵ц + */ + void run(); + /** + * @brief stopThreadGroup 鍋滄绾跨▼缁 + */ + void stopThreadGroup(); + /** + * @brief startThread 鍚姩绾跨▼ + */ + void startThread(); + /** + * @brief waiteThreadFinish 绛夊緟绾跨▼缁撴潫 + */ + void waiteThreadFinish(); + /** + * @brief notEmpty 鏄惁绌 + * @return + */ + bool notEmpty(); + +private: + std::vector m_WorkThreads; /*宸ヤ綔绾跨▼*/ + std::queue m_TasksQueue; /*浠诲姟闃熷垪*/ + + std::mutex m_QueueMutex; + std::condition_variable m_Condition; /*蹇呴』涓巙nique_lock閰嶅悎浣跨敤*/ + + std::recursive_mutex m_DataMutex; //鏁版嵁閿 + + std::atomic_bool m_StopFlag; //鏄惁鍋滄鏍囧織 + std::once_flag m_CallStopSlag; + std::once_flag m_CallStartSlag; + std::once_flag m_CallWaiteFinisFlag; + int m_ThreadNum; //绾跨▼鏁 + + std::atomic_bool m_EmptyQuit; //鏃犱换鍔¢鍑烘ā寮,鏀规ā寮忓厛娣诲姞浠诲姟锛屽啀鍚姩 + std::atomic_bool m_JoinFlag; //绾跨▼鏄惁Join + + std::atomic_bool m_EmptyQuitWaite;//寮濮嬮鍑虹瓑寰 + std::atomic_int m_QuitNum;//閫鍑虹殑绾跨▼璁℃暟 + +}; +typedef std::shared_ptr ThreadPoolPtr; + +#endif // THREADPOOL_HPP diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp new file mode 100644 index 0000000..54b39f6 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp @@ -0,0 +1,20 @@ +锘// testengiewithmkl.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + +#include + +int main() +{ + std::cout << "Hello World!\n"; +} + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj new file mode 100644 index 0000000..e99f8f9 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c26dab80-43be-4542-a2a3-7b5acb6e35e6} + testengiewithmkl + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters new file mode 100644 index 0000000..eab1303 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters @@ -0,0 +1,22 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/README.md b/simorthoprogram-orth_L_sar-strip/README.md new file mode 100644 index 0000000..f7f7324 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/README.md @@ -0,0 +1 @@ +# SIMOrthoProgram \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/RPC_Correct.cpp b/simorthoprogram-orth_L_sar-strip/RPC_Correct.cpp new file mode 100644 index 0000000..039a578 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/RPC_Correct.cpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" + +#include "RPC_Correct.h" + +using namespace std; +using namespace Eigen; + + + diff --git a/simorthoprogram-orth_L_sar-strip/RPC_Correct.h b/simorthoprogram-orth_L_sar-strip/RPC_Correct.h new file mode 100644 index 0000000..c500e94 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/RPC_Correct.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" +//#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +using namespace std; +using namespace Eigen; + + +// 专门用于解析RPC + + + + +class RPC_Correct +{ +}; + diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.aps b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.aps new file mode 100644 index 0000000..56cedc1 Binary files /dev/null and b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.aps differ diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.cpp b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.cpp new file mode 100644 index 0000000..c8be2e2 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.cpp @@ -0,0 +1,434 @@ +// SIMOrthoProgram.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 +// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + + + +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +#include "test_moudel.h" +#include +using namespace std; +using namespace Eigen; + +//mode 1 +void PreProcess(int argc, char* argv[]) +{ + // .\baseTool\x64\Release\SIMOrthoProgram.exe 1 D:\MicroWorkspace\C-SAR\Ortho\Temporary\unpack\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff + //输入参数 + std::cout << "==========================================================================" << endl; + std::cout << "预处理计算结果,可以计算出DEM 范围 " << endl; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path "; + std::string parameter_path = argv[2]; // 参数文件 + std::string dem_path = argv[3]; // dem 文件 + std::string in_sar_path = argv[4]; // 输入SAR文件 + std::string work_path = argv[5]; // 目标空间文件 + std::string taget_path = argv[6]; // 输出坐标映射文件 + + //std::string parameter_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package\\orth_para.txt"; // 参数文件 + //std::string dem_path = "D:\\micro\\LWork\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; // dem 文件 + //std::string in_sar_path = "D:\\micro\\LWork\\Ortho\\Temporary\\unpack\\LT1B_MONO_MYC_STRIP4_005860_E130.9_N47.7_20230327_SLC_AHV_L1A_0000086966\\LT1B_MONO_MYC_STRIP4_005860_E130.9_N47.7_20230327_SLC_HH_L1A_0000086966.tiff"; // 输入SAR文件 + //std::string work_path = "D:\\micro\\LWork\\Ortho\\Temporary"; // 目标空间文件 + //std::string taget_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package"; // 输出坐标映射文件 + //std::string Incident_path = argv[7];// 输出入射角文件 + + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the sar image:\n" << in_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + std::cout << "==========================================================================" << endl; + process.InitSimulationSAR(parameter_path, work_path, taget_path, dem_path, in_sar_path); + std::cout << "==========================================================================" << endl; +} + +//mode 2 +void calIncident_localIncident_angle(int argc, char* argv[]) { + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_rc_wgs84_path = argv[4]; + std::string out_incident_angle_path = argv[5]; + std::string out_local_incident_angle_path = argv[6]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.pstn = pstn; + process.calcalIncident_localIncident_angle(dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + +} + +// mode 3 +void calInterpolation_cubic_Wgs84_rc_sar(int argc, char* argv[]) { + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\package\\orth_para.txt"; argv[2]; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\dem_rc.tiff"; argv[3]; + std::string in_ori_sar_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\unpack\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_AHV_L10003514912\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_VV_L10003514912.tiff"; argv[4]; + std::string out_orth_sar_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\package\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_VV_L10003514912_GTC_rpc_geo.tif"; argv[5]; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + +// mode 4 处理 RPC的入射角 +void getRPC_Incident_localIncident_angle(int argc, char* argv[]) { + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string in_dem_path = argv[3]; + std::string in_rpc_rc_path = argv[4]; + std::string out_rpc_dem_path = argv[5]; + std::string out_incident_angle_path = argv[6]; + std::string out_local_incident_angle_path = argv[7]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + + process.CreateRPC_DEM(in_rpc_rc_path, in_dem_path, out_rpc_dem_path); + process.calcalIncident_localIncident_angle(out_rpc_dem_path, in_rpc_rc_path, out_incident_angle_path, out_local_incident_angle_path, pstn); +} + +//mode 5 +void cal_ori_2_power_tiff(int argc, char* argv[]) { + std::cout << "mode 5: convert ori tiff to power tiff:"; + std::cout << "SIMOrthoProgram.exe 5 in_ori_path out_power_path"; + std::string in_ori_path = argv[2]; + std::string out_power_path = argv[3]; + simProcess process; + process.ori_sar_power(in_ori_path, out_power_path); + +} + +// mode 6 +void cal_GEC_Incident_localIncident_angle(int argc, char* argv[]) { + std::cout << "mode 6: get gec incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 6 in_parameter_path in_dem_path in_gec_lon_lat_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_gec_lon_lat_path = argv[4]; + std::string out_incident_angle_path = argv[5]; + std::string out_local_incident_angle_path = argv[6]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.calGEC_Incident_localIncident_angle(dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, pstn); +} + +// mode 7 +void RPC_inangle(int argc, char* argv[]) { + std::cout << "mode 7: get rpc incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 7 in_parameter_path in_dem_path in_gec_lon_lat_path work_path taget_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_gec_lon_lat_path = argv[4]; + std::string work_path = argv[5]; + std::string taget_path = argv[6]; + std::string out_incident_angle_path = argv[7]; + std::string out_local_incident_angle_path = argv[8]; + std::string out_incident_angle_geo_path = argv[9]; + std::string out_local_incident_angle_geo_path = argv[10]; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.InitRPCIncAngle(parameter_path, work_path, taget_path, dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, out_incident_angle_geo_path, out_local_incident_angle_geo_path); + std::cout << "==========================================================================" << endl; +} + +// mode 9 +void calInterpolation_cubic_Wgs84_rc_sar_sigma(int argc, char* argv[]) { + + std::cout << "mode 9: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 9 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package\\RD_sim_ori.tif"; + std::string in_ori_sar_path = "D:\\micro\\LWork\\Ortho\\Temporary\\in_sar_power.tiff"; + std::string out_orth_sar_path = "D:\\micro\\LWork\\Ortho\\Temporary\\in_sar_power_GTC.tiff"; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar_sigma(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + +// mode 11 +void interpolation_bil_GTC_sar_sigma(int argc, char* argv[]) { + + std::cout << "mode 11: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 11 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\preprocessing\\GF3B_MYC_QPSI_008114_E121.6_N40.9_20230608_L1A_AHV_L10000196489-ortho\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\preprocessing\\GF3B_MYC_QPSI_008114_E121.6_N40.9_20230608_L1A_AHV_L10000196489-ortho\\sim_ori-ortho.tif"; + std::string in_ori_sar_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\SurfaceRoughnessProduct_temp.tif"; + std::string out_orth_sar_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\SurfaceRoughnessProduct_geo1.tif"; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_bil(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + + +// mode 12 +void lee_process_sar(int argc, char* argv[]) { + + std::cout << "mode 12: lee process:\n "; + std::cout << "SIMOrthoProgram.exe 12 in_sar_path out_sar_path win_size noise_var\n"; + std::string in_sar_path = "D:\\micro\\WorkSpace\\BackScattering\\Temporary\\preprocessing\\GF3_SAY_QPSI_011444_E118.9_N31.4_20181012_L1A_HH_L10003515422_DB.tif"; + std::string out_sar_path = "D:\\micro\\WorkSpace\\BackScattering\\Temporary\\preprocessed_lee.tif"; + int win_size = 5; + double noise_var = 0.25; + in_sar_path = argv[2]; + out_sar_path = argv[3]; + win_size = stoi(argv[4]); + noise_var = stod(argv[5]); + + simProcess process; + std::cout << "==========================================================================\n" << endl; + //std::cout << in_sar_path << endl; + //std::cout << out_sar_path << endl; + //std::cout << win_size << endl; + //std::cout << noise_var << endl; + process.lee_process(in_sar_path, out_sar_path, win_size, noise_var); +} + +void createRPC_lon_lat(int argc, char* argv[]) { + std::cout << "mode 8"; + std::cout << "SIMOrthoProgram.exe 8 in_rpc_tiff out_lon_lat_path"; + std::string in_rpc_tiff = argv[2]; + std::string in_dem_tiff = argv[3]; + std::string out_lon_lat_path = argv[4]; + + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.CreateRPC_refrenceTable(in_rpc_tiff, in_dem_tiff,out_lon_lat_path); + std::cout << "==========================================================================" << endl; +} + +void Scatter2Grid_lon_lat(int argc, char* argv[]) { + std::cout << "mode 10"; + std::cout << "SIMOrthoProgram.exe 10 lon_lat_path data_tiff grid_path space"; + std::string lon_lat_path = "F:\\orthtest\\ori_sim_preprocessed.tif"; + std::string data_tiff = "F:\\orthtest\\SoilMoistureProduct_geo.tif"; + std::string grid_path = "F:\\orthtest\\SoilMoistureProduct_geo_test.tif"; + double space = 5; + + lon_lat_path = argv[2]; + data_tiff = argv[3]; + grid_path = argv[4]; + space = stod(argv[5]); + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.Scatter2Grid(lon_lat_path, data_tiff, grid_path, space); + std::cout << "==========================================================================" << endl; +} + + +string GetExePath() +{ + char szFilePath[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA(NULL, szFilePath, MAX_PATH); + /* + strrchr:函数功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置), + 并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。 + 使用这个地址返回从最后一个字符c到str末尾的字符串。 + */ + (strrchr(szFilePath, '\\'))[0] = 0; // 删除文件名,只获得路径字串// + string path = szFilePath; + return path; +} + +/// +/// 初始化 +/// +void initProjEnv() { + PJ_CONTEXT* C; + C = proj_context_create(); + std::cout << "========================== init PROJ ================================================" << endl; + string exepath = GetExePath(); + char buffer[10240]; + int i; + for (i = 0; i < exepath.length(); i++) { + buffer[i] = exepath[i]; + } + buffer[i] = '\0'; + + const char* proj_share_path = buffer; + proj_context_set_search_paths(C, 1, &proj_share_path); + char* buf = nullptr; + size_t sz = 0; + + if (_dupenv_s(&buf, &sz, "PROJ_LIB") == 0 && buf != nullptr) + { + printf("PROJ_LIB = %s\n", buf); + std::string newEnv = "PROJ_LIB=" + std::string(buffer); + _putenv(newEnv.c_str()); + } + else { + std::string newEnv = "PROJ_LIB=" + std::string(buffer); + _putenv(newEnv.c_str()); + } + + if (_dupenv_s(&buf, &sz, "PROJ_LIB") == 0 && buf != nullptr) + { + std::cout << "after PROJ_LIB = " << buf << endl; + } + free(buf); + std::cout << "========================================================================================" << endl; +} + + +int main(int argc, char* argv[]) +{ + initProjEnv(); + //WGS84_J2000(); + cout << "test\t" << acos(-1) << endl; + cout << getAngle(Landpoint{ -3421843,5089485,3630606 }, Landpoint{ -2609414,4763328,3332879 }) << endl;; + Landpoint p2 = { -3421843,5089485,3630606 }; Landpoint p1 = { -2609414,4763328,3332879 }; + cout << getIncAngle(p2, p1) << endl;; + std::cout << "program start:\t" << getCurrentTimeString() << endl;; + int mode = 9; + GDALAllRegister(); + if (argc == 0) { // 测试参数 + // 算法说明 + std::cout << "========================== description ================================================" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + std::cout << "mode 1: Preprocess\n "; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path out_GEC_dem_path out_GTC_rc_path out_GEC_lon_lat_path out_clip_dem_path" << endl; + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + + std::cout << "mode 5: interpolation(cubic convolution) orth sar value by gec_lon_lat and dem and ori_sar image and sar model:"; + std::cout << "SIMOrthoProgram.exe 5 in_parameter_path in_gec_lon_lat_path in_dem_path in_sar_path out_orth_sar_path"; + + std::cout << "mode 6: get gec incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 6 in_parameter_path in_dem_path in_gec_lon_lat_path out_incident_angle_path out_local_incident_angle_path"; + if (mode == 10) { + Scatter2Grid_lon_lat(argc, argv); + } + else { + test_main(mode, "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary"); + } + //calInterpolation_cubic_Wgs84_rc_sar(argc, argv); + } + else if (argc > 1) { // 预处理模块 + + std::cout << "=============================description V2.0 =============================================" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + mode = stoi(argv[1]); + if (mode == 0) { + test_main(mode, argv[2]); + } + else if (mode == 1) { + PreProcess(argc, argv); // + } + else if (mode == 2) { // RPC 计算模块 + calIncident_localIncident_angle(argc, argv); + } + else if (mode == 3) { + calInterpolation_cubic_Wgs84_rc_sar(argc, argv); + } + else if (mode == 4) { + getRPC_Incident_localIncident_angle(argc, argv); + } + else if (mode == 5) { + cal_ori_2_power_tiff(argc, argv); + } + else if (mode == 6) { + cal_GEC_Incident_localIncident_angle(argc, argv); + } + else if (mode == 7) { + RPC_inangle(argc, argv); + } + else if (mode == 8) { + createRPC_lon_lat(argc, argv); + } + else if (mode == 9) { + calInterpolation_cubic_Wgs84_rc_sar_sigma(argc, argv); + } + else if (mode == 10) { + Scatter2Grid_lon_lat(argc, argv); + } + else if (mode == 11) { + interpolation_bil_GTC_sar_sigma(argc, argv); + } + else if (mode == 12){ + lee_process_sar(argc, argv); + } + } + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + std::cout << "program over:\t" << getCurrentTimeString() << endl; + + +} + +// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 +// 调试程序: F5 或调试 >“开始调试”菜单 + +// 入门使用技巧: +// 1. 使用解决方案资源管理器窗口添加/管理文件 +// 2. 使用团队资源管理器窗口连接到源代码管理 +// 3. 使用输出窗口查看生成输出和其他消息 +// 4. 使用错误列表窗口查看错误 +// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 +// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.rc b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.rc new file mode 100644 index 0000000..f8ef045 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// 涓枃(绠浣擄紝涓浗) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// + +#endif // 涓枃(绠浣擄紝涓浗) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.sln b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.sln new file mode 100644 index 0000000..469c9dd --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.sln @@ -0,0 +1,31 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32602.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SIMOrthoProgram", "SIMOrthoProgram.vcxproj", "{7722B0A9-572B-4E32-AFBE-4DC88898F8EE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x64.ActiveCfg = Debug|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x64.Build.0 = Debug|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x86.ActiveCfg = Debug|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x86.Build.0 = Debug|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x64.ActiveCfg = Release|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x64.Build.0 = Release|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x86.ActiveCfg = Release|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CE6D0980-E92A-4188-91CE-EEE5749F908C} + EndGlobalSection +EndGlobal diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj new file mode 100644 index 0000000..465f6c1 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj @@ -0,0 +1,201 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7722b0a9-572b-4e32-afbe-4dc88898f8ee} + SIMOrthoProgram + 10.0 + SIMOrthoProgram-L-SAR + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + false + v142 + Unicode + Sequential + + + Application + false + v142 + true + Unicode + Parallel + false + + + + + + + + + + + + + + + + + + + + + C:\ProgramData\Miniconda3\envs\orth\Library\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64;$(oneMKLOmpLibDir);$(LibraryPath) + true + false + C:\ProgramData\Miniconda3\envs\orth\Library\include;$(ExternalIncludePath) + + + true + true + true + $(IncludePath) + $(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(LibraryPath) + $(VC_ReferencesPath_x64); + $(WindowsSDK_MetadataPath); + true + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _CONSOLE;%(PreprocessorDefinitions) + true + true + Default + stdc11 + MultiThreaded + + + Console + true + %(AdditionalDependencies) + + + + + Level3 + + + false + true + _CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + Default + Default + MaxSpeed + Neither + false + false + true + /bigobj %(AdditionalOptions) + + + Console + true + true + true + + + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj.filters b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj.filters new file mode 100644 index 0000000..a443456 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj.filters @@ -0,0 +1,88 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + + + 璧勬簮鏂囦欢 + + + + + 璧勬簮鏂囦欢 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj.user b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SIMOrthoProgram.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/SateOrbit.cpp b/simorthoprogram-orth_L_sar-strip/SateOrbit.cpp new file mode 100644 index 0000000..f34405d --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SateOrbit.cpp @@ -0,0 +1,86 @@ +#include "SateOrbit.h" +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +#include +#include +#include +#include +//#include + +using namespace std; +using namespace Eigen; + + + +OrbitPoly::OrbitPoly() +{ +} + +OrbitPoly::OrbitPoly(int polynum, Eigen::MatrixX polySatellitePara, double SatelliteModelStartTime) +{ + if (polySatellitePara.rows() != polynum||polySatellitePara.cols()!=6) { + throw exception("?????????????????"); + } + this->polySatellitePara = polySatellitePara; + this->SatelliteModelStartTime = SatelliteModelStartTime; + this->polynum = polynum; +} + +OrbitPoly::~OrbitPoly() +{ +} + +Eigen::MatrixX OrbitPoly::SatelliteSpacePoint(Eigen::MatrixX satellitetime) +{ + Eigen::MatrixX result= SatelliteSpacePoints(satellitetime, this->SatelliteModelStartTime, this->polySatellitePara, this->polynum); + return result; +} + +Eigen::MatrixX OrbitPoly::SatelliteSpacePoint(long double satellitetime) { + + if (this->polySatellitePara.rows() != polynum || this->polySatellitePara.cols() != 6) { + throw exception("the size of satellitetime has error!! row: p1,p2,p3,p4 col: x,y,z,vx,vy,vz "); + } + // ????????? + double satellitetime2 =double( satellitetime - this->SatelliteModelStartTime); + Eigen::MatrixX satetime(1, polynum); + for (int i = 0; i < polynum; i++) { + satetime(0, i) = pow(satellitetime2, i); + } + + // ???? + Eigen::MatrixX satellitePoints(1, 6); + satellitePoints = satetime * polySatellitePara; + return satellitePoints; +} + +/// +/// ???????????????????? +/// +/// ??????? +/// ?????????? +/// ??????[x1,y1,z1,vx1,vy1,vz1; x2,y2,z2,vx2,vy2,vz2; ..... ] +/// ?????????? +/// ???????? +Eigen::MatrixX SatelliteSpacePoints(Eigen::MatrixX& satellitetime, double SatelliteModelStartTime, Eigen::MatrixX& polySatellitePara, int polynum) +{ + if (satellitetime.cols() != 1) { + throw exception("the size of satellitetime has error!!"); + } + if (polySatellitePara.rows() != polynum || polySatellitePara.cols() != 6) { + throw exception("the size of satellitetime has error!! row: p1,p2,p3,p4 col: x,y,z,vx,vy,vz "); + } + // ????????? + int satellitetime_num = satellitetime.rows(); + satellitetime = satellitetime.array() - SatelliteModelStartTime; + Eigen::MatrixX satelliteTime(satellitetime_num, polynum); + for (int i = 0; i < polynum; i++) { + satelliteTime.col(i) = satellitetime.array().pow(i); + } + + // ???? + Eigen::MatrixX satellitePoints(satellitetime_num, 6); + satellitePoints = satelliteTime * polySatellitePara; + return satellitePoints; +} diff --git a/simorthoprogram-orth_L_sar-strip/SateOrbit.h b/simorthoprogram-orth_L_sar-strip/SateOrbit.h new file mode 100644 index 0000000..b1e6daf --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/SateOrbit.h @@ -0,0 +1,53 @@ +#pragma once +/// +/// 计算卫星轨道 +/// + +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 +#include "baseTool.h" + +#include +#include +#include +#include +//#include +//#include + + +using namespace std; +using namespace Eigen; +//using namespace arma; + + +/// +/// 多项式轨道模型 +/// +class OrbitPoly { +public: + //OrbitPoly(std::string orbitModelPath); + OrbitPoly(); + OrbitPoly(int polynum, Eigen::MatrixX polySatellitePara, double SatelliteModelStartTime); + ~OrbitPoly(); + + Eigen::MatrixX SatelliteSpacePoint(Eigen::MatrixX satellitetime); + Eigen::MatrixX SatelliteSpacePoint(long double satellitetime); +public: + int polynum; + Eigen::MatrixX polySatellitePara; + double SatelliteModelStartTime; +}; + + + +/// +/// 获取指定时刻的卫星轨道坐标 +/// +/// 卫星时刻 +/// 模型起算时间 +/// 模型参数[x1,y1,z1,vx1,vy1,vz1; x2,y2,z2,vx2,vy2,vz2; ..... ] +/// 模型参数数量 +/// 卫星坐标 +Eigen::MatrixX SatelliteSpacePoints(Eigen::MatrixX &satellitetime, double SatelliteModelStartTime, Eigen::MatrixX& polySatellitePara, int polynum = 4); diff --git a/simorthoprogram-orth_L_sar-strip/WGS84_J2000.cpp b/simorthoprogram-orth_L_sar-strip/WGS84_J2000.cpp new file mode 100644 index 0000000..e868836 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/WGS84_J2000.cpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include"WGS84_J2000.h" diff --git a/simorthoprogram-orth_L_sar-strip/WGS84_J2000.h b/simorthoprogram-orth_L_sar-strip/WGS84_J2000.h new file mode 100644 index 0000000..ae3e496 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/WGS84_J2000.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include diff --git a/simorthoprogram-orth_L_sar-strip/baseTool.cpp b/simorthoprogram-orth_L_sar-strip/baseTool.cpp new file mode 100644 index 0000000..7f8c2fe --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/baseTool.cpp @@ -0,0 +1,1328 @@ +#pragma once +/// +/// 锟斤拷锟斤拷锟洁、锟斤拷锟斤拷锟斤拷锟斤拷 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + + +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include < io.h > +#include < stdio.h > +#include < stdlib.h > +#include +#include +#include +//#include +#include //#include "ogrsf_frmts.h" +#include +#include +#include +#include +#include + +#include "baseTool.h" +using namespace std; +using namespace Eigen; +using namespace cv; + + + +/** + * @brief GetCurrentTime 锟斤拷取锟斤拷前时锟斤拷 + * @return + */ +std::string getCurrentTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + std::string strTime = mbstr; + return strTime; +} + +std::string getCurrentShortTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + std::string strTime = mbstr; + return strTime; +} + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon + p2.lon,p1.lat + p2.lat,p1.ati + p2.ati }; +} + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon - p2.lon,p1.lat - p2.lat,p1.ati - p2.ati }; +} + +bool operator ==(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat == p2.lat && p1.lon == p2.lon && p1.ati == p2.ati; +} + + + +Landpoint operator *(const Landpoint& p, double scale) +{ + return Landpoint{ + p.lon * scale, + p.lat * scale, + p.ati * scale + }; +} + +double getAngle(const Landpoint& a, const Landpoint& b) +{ + double c = dot(a, b) / (getlength(a) * getlength(b)); + if (a.lon * b.lat - a.lat * b.lon >= 0) { + return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } + else { + return 360 - acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } +} + +double dot(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat * p2.lat + p1.lon * p2.lon + p1.ati * p2.ati; +} + +double getlength(const Landpoint& p1) { + + return sqrt(dot(p1, p1)); +} + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b) { + return Landpoint{ + a.lat * b.ati - a.ati * b.lat,//x + a.ati * b.lon - a.lon * b.ati,//y + a.lon * b.lat - a.lat * b.lon//z + }; +} + +/// +/// 锟斤拷锟斤拷乇锟斤拷露锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟姐都锟斤拷WGS84锟斤拷锟斤拷系锟斤拷锟斤拷p1为锟斤拷锟姐, +/// 锟斤拷 N +/// W p1 +/// p4 p0 p2 E +/// p3 S +/// n21=n2xn1 +/// n=(n21+n32+n43+n41)*0.25; +/// +/// 目锟斤拷锟?1锟?7 +/// 锟斤拷围锟斤拷1 +/// 锟斤拷围锟斤拷2 +/// 锟斤拷围锟斤拷3 +/// 锟斤拷围锟斤拷4 +/// 锟斤拷锟斤拷锟角讹拷 +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4) { + + Landpoint n0 = LLA2XYZ(p0), + n1 = LLA2XYZ(p1), + n2 = LLA2XYZ(p2), + n3 = LLA2XYZ(p3), + n4 = LLA2XYZ(p4); + Landpoint n01 = n1 - n0, n02 = n2 - n0, n03 = n3 - n0, n04 = n4 - n0; + // 锟斤拷n01为锟斤拷锟斤拷锟斤拷锟斤拷 + Landpoint np01 = p1-p0, np02 = p2-p0, np03 = p3-p0, np04 = p4-p0; + double a2 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np02.lon,np02.lat,0 });// 01->02 锟斤拷时锟斤拷 + double a3 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np03.lon,np03.lat,0 });// 01->03 锟斤拷时锟斤拷 + double a4 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np04.lon,np04.lat,0 });// 01->04 锟斤拷时锟斤拷 + //std::cout << a2 << "\t" << a3 << "\t" << a4 << endl; + a2 = 360 - a2; + a3 = 360 - a3; + a4 = 360 - a4; + Landpoint N, W, S, E; + N = n01; + if (a2 >= a3 && a2 >= a4) { + W = n02; + if (a3 >= a4) { + S = n03; + E = n04; + } + else { + S = n04; + E = n03; + } + } + else if (a3 >= a2 && a3 >= a4) { + W = n03; + if (a2 >= a4) { + S = n02; + E = n04; + } + else { + S = n04; + E = n02; + } + } + else if (a4 >= a2 && a4 >= a3) + { + W = n04; + if (a2 >= a3) { + S = n02; + E = n03; + } + else { + S = n03; + E = n02; + } + } + return (crossProduct(N, W) + crossProduct(W, S) + crossProduct(S, E) + crossProduct(E, N)) * 0.25; +} + +/// +/// 锟斤拷锟捷讹拷锟斤拷锟斤拷锟斤拷小 +/// p11 p12 p13 p14 +/// p21 p22 p23 p24 +/// p(2+u,2+v) +/// p31 p32 p33 p34 +/// p41 p42 p43 p44 +/// +/// 锟斤拷元锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟斤拷锟?1锟?7 +/// 锟斤拷元锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟斤拷锟?1锟?7 +/// 4x4 锟斤拷值锟斤拷锟斤拷 +/// +complex Cubic_Convolution_interpolation(double u, double v, Eigen::MatrixX> img) +{ + if (img.rows() != 4 || img.cols() != 4) { + throw exception("the size of img's block is not right"); + } + // 锟斤拷锟斤拷锟斤拷模锟斤拷 + Eigen::MatrixX> wrc(1, 4);// 使锟斤拷 complex 锟斤拷锟斤拷锟斤拷要原锟斤拷锟斤拷为锟剿伙拷取值 + Eigen::MatrixX> wcr(4, 1);// + for (int i = 0; i < 4; i++) { + wrc(0, i) = Cubic_kernel_weight(u+1-i); // u+1,u,u-1,u-2 + wcr(i, 0) = Cubic_kernel_weight(v + 1 - i); + } + + Eigen::MatrixX> interValue = wrc * img * wcr; + return interValue(0, 0); +} + +complex Cubic_kernel_weight(double s) +{ + s = abs(s); + if (s <= 1) { + return complex(1.5 * s * s * s - 2.5 * s * s + 1,0); + } + else if (s <= 2) { + return complex(-0.5 * s * s * s + 2.5 * s * s - 4 * s + 2,0); + } + else { + return complex(0,0); + } +} + +/// +/// p11 p12 -- x +/// p0(u,v) +/// p21 p22 +/// | +/// y +/// p11(0,0) +/// p21(0,1) +/// P12(1,0) +/// p22(1,1) +/// +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22) +{ + + return p11.ati * (1 - p0.lon) * (1 - p0.lat) + + p12.ati * p0.lon * (1 - p0.lat) + + p21.ati * (1 - p0.lon) * p0.lat + + p22.ati * p0.lon * p0.lat; +} + + + + + +/// +/// 锟斤拷锟斤拷纬锟斤拷转锟斤拷为锟截固诧拷锟斤拷锟斤拷锟斤拷系 +/// +/// 锟斤拷纬锟饺碉拷--degree +/// 投影锟斤拷锟斤拷系锟斤拷 +Landpoint LLA2XYZ(const Landpoint& LLA) { + double L = LLA.lon * d2r; + double B = LLA.lat * d2r; + double H = LLA.ati; + + double sinB = sin(B); + double cosB = cos(B); + + //double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + double N = a / sqrt(1 - eSquare * sinB * sinB); + Landpoint result = { 0,0,0 }; + result.lon = (N + H) * cosB * cos(L); + result.lat = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.ati = (N * (1 - 1/f_inverse)* (1 - 1 / f_inverse) + H) * sinB; + return result; +} + +/// +/// 锟斤拷锟斤拷n,3) lon,lat,ati +/// +/// +/// +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint) +{ + landpoint.col(0) = landpoint.col(0).array() * d2r; // lon + landpoint.col(1) = landpoint.col(1).array() * d2r; // lat + + Eigen::MatrixXd sinB = (landpoint.col(1).array().sin());//lat + Eigen::MatrixXd cosB = (landpoint.col(1).array().cos());//lat + + Eigen::MatrixXd N = a / ((1 - sinB.array().pow(2) * eSquare).array().sqrt()); + Eigen::MatrixXd result(landpoint.rows(), 3); + + result.col(0) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::cos(landpoint.col(0).array()).array(); //x + result.col(1) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::sin(landpoint.col(0).array()).array(); //y + + result.col(2) = (N.array() * (1 - 1/f_inverse)* (1 - 1 / f_inverse) + landpoint.col(2).array()) * sinB.array(); //z + + return result; +} + + +/// +/// 锟斤拷锟截固诧拷锟斤拷锟斤拷锟斤拷系转锟斤拷为锟斤拷纬锟斤拷 +/// +/// 锟教诧拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷纬锟斤拷--degree +Landpoint XYZ2LLA(const Landpoint& XYZ) { + double tmpX = XYZ.lon;// 锟斤拷锟斤拷 x + double temY = XYZ.lat;// 纬锟斤拷 y + double temZ = XYZ.ati; + + double curB = 0; + double N = 0; + double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + Landpoint result = { 0,0,0 }; + result.lon = atan2(temY, tmpX) * r2d; + result.lat = curB * r2d; + result.ati = temZ / sinCurB - N * (1 - eSquare); + return result; +} + +/// +/// 锟斤拷锟斤拷图锟斤拷锟饺∮帮拷锟?1锟?7 +/// +/// +gdalImage::gdalImage(string raster_path) +{ + omp_lock_t lock; + omp_init_lock(&lock); // 锟斤拷始锟斤拷锟斤拷锟斤拷锟斤拷 + omp_set_lock(&lock); //锟斤拷没锟斤拷锟斤拷锟?1锟?7 + this->img_path = raster_path; + + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + // 锟斤拷DEM影锟斤拷 + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(raster_path.c_str(), 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]; + + this->projection = rasterDataset->GetProjectionRef(); + // 锟斤拷锟斤拷锟斤拷锟斤拷 + //double* inv_gt = new double[6];; + //GDALInvGeoTransform(gt, inv_gt); // 锟斤拷锟斤拷锟斤拷锟斤拷 + // 锟斤拷锟斤拷投影 + GDALFlushCache((GDALDatasetH)rasterDataset); + GDALClose((GDALDatasetH)rasterDataset); + rasterDataset = NULL;// 指锟斤拷锟矫匡拷 + this->InitInv_gt(); + delete[] gt; + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 +} + +gdalImage::~gdalImage() +{ +} + +void gdalImage::setHeight(int height) +{ + this->height = height; +} + +void gdalImage::setWidth(int width) +{ + this->width = width; +} + +void gdalImage::setTranslationMatrix(Eigen::MatrixXd gt) +{ + this->gt = gt; +} + +void gdalImage::setData(Eigen::MatrixXd data) +{ + this->data = data; +} + +Eigen::MatrixXd gdalImage::getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids = 1) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_ReadOnly));//锟斤拷只锟斤拷锟斤拷式锟斤拷取锟斤拷锟斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + MatrixXd datamatrix(rows_count, cols_count); + + + if (gdal_datatype == GDALDataType::GDT_UInt16) { + + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 + //GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return datamatrix; + +} + +/// +/// 写锟斤拷遥锟斤拷影锟斤拷 +/// +/// +/// +/// +/// +void gdalImage::saveImage(Eigen::MatrixXd data, int start_row = 0, int start_col = 0, int band_ids = 1) +{ + 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) { + string tip = "file path: " + this->img_path; + throw exception(tip.c_str()); + } + GDALAllRegister(); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = nullptr; + if (boost::filesystem::exists(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.c_str(), this->width, this->height, this->band_num, GDT_Float32, NULL); // 锟斤拷锟斤拷锟斤拷 + poDstDS->SetProjection(this->projection.c_str()); + + + 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(); + + float* databuffer = new float[datarows * datacols];// (float*)malloc(datarows * datacols * sizeof(float)); + + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + float temp = float(data(i, j)); + databuffer[i * datacols + j] = temp; + } + } + //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_Float32, 0, 0); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(-9999); + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + //GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 +} + +void gdalImage::saveImage() +{ + this->saveImage(this->data, this->start_row, this->start_col, this->data_band_ids); +} + +void gdalImage::setNoDataValue(double nodatavalue = -9999, int band_ids = 1) +{ + + + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + //GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.c_str(), GA_Update)); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(nodatavalue); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); +} + +int gdalImage::InitInv_gt() +{ + //1 lon lat = x + //1 lon lat = y + Eigen::MatrixXd temp(2, 3); + this->inv_gt = temp; + double a = this->gt(0, 0); + double b = this->gt(0, 1); + double c = this->gt(0, 2); + double d = this->gt(1, 0); + double e = this->gt(1, 1); + double f = this->gt(1, 2); + double g = 1; + double det_gt = b * f - c * e; + if (det_gt == 0) { + return 0; + } + this->inv_gt(0, 0) = (c * d - a * f) / det_gt; //2 + this->inv_gt(0, 1) = f / det_gt; // lon + this->inv_gt(0, 2) = -c / det_gt; // lat + this->inv_gt(1, 0) = (a*e-b*d) / det_gt; //1 + this->inv_gt(1, 1) = -e / det_gt; // lon + this->inv_gt(1, 2) = b / det_gt; // lat + return 1; +} + +Landpoint gdalImage::getRow_Col(double lon, double lat) +{ + Landpoint p{ 0,0,0 }; + p.lon = this->inv_gt(0, 0) + lon * this->inv_gt(0, 1) + lat * this->inv_gt(0, 2); //x + p.lat = this->inv_gt(1, 0) + lon * this->inv_gt(1, 1) + lat * this->inv_gt(1, 2); //y + return p; +} + +Landpoint gdalImage::getLandPoint(double row, double col, double ati = 0) +{ + Landpoint p{ 0,0,0 }; + p.lon = this->gt(0, 0) + col * this->gt(0, 1) + row * this->gt(0, 2); //x + p.lat = this->gt(1, 0) + col * this->gt(1, 1) + row * this->gt(1, 2); //y + p.ati = ati; + return p; +} + +double gdalImage::mean(int bandids ) +{ + double mean_value = 0; + double count = this->height* this->width; + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + mean_value = mean_value+ sar_a.sum() / count; + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return mean_value; +} + +double gdalImage::max(int bandids) +{ + double max_value = 0; + bool state_max = true; + int line_invert = 100; + int start_ids = 0; + double temp_max = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_max) { + state_max = false; + max_value = sar_a.maxCoeff(); + } + else { + temp_max= sar_a.maxCoeff(); + if (max_value < temp_max) { + max_value = temp_max; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return max_value; +} + +double gdalImage::min(int bandids) +{ + double min_value = 0; + bool state_min = true; + int line_invert = 100; + int start_ids = 0; + double temp_min = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_min) { + state_min = false; + min_value = sar_a.minCoeff(); + } + else { + temp_min = sar_a.minCoeff(); + if (min_value < temp_min) { + min_value = temp_min; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return min_value; +} + +GDALRPCInfo gdalImage::getRPC() +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister();//注锟斤拷锟斤拷锟斤拷 + //锟斤拷锟斤拷锟斤拷 + GDALDataset* pDS = (GDALDataset*)GDALOpen(this->img_path.c_str(), GA_ReadOnly); + //锟斤拷元锟斤拷锟斤拷锟叫伙拷取RPC锟斤拷息 + char** papszRPC = pDS->GetMetadata("RPC"); + + //锟斤拷锟斤拷取锟斤拷RPC锟斤拷息锟斤拷锟斤拷山峁癸拷锟?1锟?7 + GDALRPCInfo oInfo; + GDALExtractRPCInfo(papszRPC, &oInfo); + + GDALClose((GDALDatasetH)pDS); + + return oInfo; +} + +Eigen::MatrixXd gdalImage::getLandPoint(Eigen::MatrixXd points) +{ + if (points.cols() != 3) { + throw new exception("the size of points is equit 3!!!"); + } + + Eigen::MatrixXd result(points.rows(), 3); + result.col(2) = points.col(2);// 锟竭筹拷 + points.col(2) = points.col(2).array() * 0 + 1; + points.col(0).swap(points.col(2));// 锟斤拷锟斤拷 + Eigen::MatrixXd gts(3, 2); + gts.col(0) = this->gt.row(0); + gts.col(1) = this->gt.row(1); + //cout << this->gt(0, 0) << "\t" << this->gt(0, 1) << "\t" << this->gt(0, 2) << endl;; + //cout << gts(0, 0) << "\t" << gts(1,0) << "\t" << gts(2, 0) << endl;; + //cout << this->gt(1, 0) << "\t" << this->gt(1, 1) << "\t" << this->gt(1, 2) << endl;; + //cout<< gts(0, 1) << "\t" << gts(1, 1) << "\t" << gts(2,1) << endl;; + //cout << points(3, 0) << "\t" << points(3, 1) << "\t" << points(3, 2) << endl;; + + + result.block(0, 0, points.rows(), 2) = points * gts; + return result; +} + +Eigen::MatrixXd gdalImage::getHist(int bandids) +{ + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + // 锟斤拷DEM影锟斤拷 + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_ReadOnly));//锟斤拷只锟斤拷锟斤拷式锟斤拷取锟斤拷锟斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* xBand = rasterDataset->GetRasterBand(bandids); + + //锟斤拷取图锟斤拷直锟斤拷图 + + double dfMin = this->min(bandids); + double dfMax = this->max(bandids); + int count = int((dfMax - dfMin) / 0.01); + count = count > 255 ? count : 255; + GUIntBig* panHistogram =new GUIntBig[count]; + xBand->GetHistogram(dfMin, dfMax, count, panHistogram, TRUE, FALSE, NULL, NULL); + Eigen::MatrixXd result(count, 2); + double delta = (dfMax - dfMin) / count; + for (int i = 0; i < count; i++) { + result(i, 0) = dfMin + i * delta; + result(i, 1) = double(panHistogram[i]); + } + delete[] panHistogram; + GDALClose((GDALDatasetH)rasterDataset); + return result; +} + + +gdalImage CreategdalImage(string img_path, int height, int width, int band_num, Eigen::MatrixXd gt, std::string projection, bool need_gt) { + + if (boost::filesystem::exists(img_path.c_str())) { + boost::filesystem::remove(img_path.c_str()); + } + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = poDriver->Create(img_path.c_str(), width, height, band_num, GDT_Float32, NULL); // 锟斤拷锟斤拷锟斤拷 + if (need_gt) { + poDstDS->SetProjection(projection.c_str()); + + // 锟斤拷锟斤拷转锟斤拷锟斤拷锟斤拷 + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + for (int i = 1; i <= band_num; i++) { + poDstDS->GetRasterBand(i)->SetNoDataValue(-9999); + } + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + + +/// +/// 锟矫硷拷DEM +/// +/// +/// +/// +/// +void clipGdalImage(string in_path, string out_path, DemBox box, double pixelinterval) { + + + + +} + + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if (pDSrc == NULL) + { + return -1; + } + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + //锟斤拷锟矫伙拷锟酵队帮拷锟斤拷锟轿?拷锟斤拷锟揭伙拷锟?1锟?7 + if (strlen(pszSrcWKT) <= 0) + { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + //oSRS.SetUTM(50, true); //锟斤拷锟斤拷锟斤拷 锟斤拷锟斤拷120锟斤拷 + //oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + } + std::cout << "GDALCreateGenImgProjTransformer " << endl; + void* hTransformArg; + hTransformArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, NULL, pszSrcWKT, FALSE, 0.0, 1); + std::cout << "no proj " << endl; + //(没锟斤拷投影锟斤拷影锟斤拷锟斤拷锟斤拷锟斤拷卟锟酵?拷锟?1锟?7) + if (hTransformArg == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + std::cout << "has proj " << endl; + double dGeoTrans[6] = { 0 }; + int nNewWidth = 0, nNewHeight = 0; + if (GDALSuggestedWarpOutput((GDALDatasetH)pDSrc, GDALGenImgProjTransform, hTransformArg, dGeoTrans, &nNewWidth, &nNewHeight) != CE_None) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + + //GDALDestroyGenImgProjTransformer(hTransformArg); + + //锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷菁锟?1锟?7 + GDALDataset* pDDst = pDriver->Create(pszOutFile, new_width, new_height, nBandCount, dataType, NULL); + if (pDDst == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(gt); + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + //psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + std::cout << "GDALCreateGenImgProjTransformer" << endl; + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, (GDALDatasetH)pDDst, pszSrcWKT, FALSE, 0.0, 1);; + + std::cout << "GDALCreateGenImgProjTransformer has created" << endl; + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) + { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + return -3; + } + std::cout << "ChunkAndWarpImage:"<< new_width<<","<< new_height << endl; + oWo.ChunkAndWarpMulti(0, 0, new_width, new_height); + GDALFlushCache(pDDst); + std::cout << "ChunkAndWarpImage over" << endl; + //GDALDestroyGenImgProjTransformer(psWo->pTransformerArg); + //GDALDestroyWarpOptions(psWo); + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return 0; +} + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_Update); + if (pDSrc == NULL) + { + return -1; + } + + GDALDataType gdal_datatype = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* demBand = pDSrc->GetRasterBand(band_ids); + + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int start_col = 0, start_row = 0, rows_count = 0, cols_count; + + int row_delta = int(120000000 / width); + + GDALRasterIOExtraArg psExtraArg; + INIT_RASTERIO_EXTRA_ARG(psExtraArg); + psExtraArg.eResampleAlg = eResample; + + do { + + rows_count = start_row + row_delta < height ? row_delta : height - start_row; + cols_count = width; + + if (gdal_datatype == GDALDataType::GDT_UInt16) { + + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + start_row = start_row + rows_count; + } while (start_row < height); + GDALClose((GDALDatasetH)pDSrc); + + + return 0; +} + + +string Convert(float Num) +{ + ostringstream oss; + oss << Num; + string str(oss.str()); + return str; +} + + + +std::string JoinPath(const std::string& path, const std::string& filename) +{ + int dir_size = path.size(); + + int last_sprt_index = path.find_last_of('\\'); + int last_is_sprt = (last_sprt_index == dir_size - 1); + + if (last_is_sprt) + { + return path + filename; + } + else + { + return path + "\\" + filename; + } +} + + + + +/// +////////////////////////////////////////////////////////////////////// WGS84 to J2000 ///////////////////////////////////////////////////////////////////////////////////////// +/// +/* +Eigen::Matrix WGS84_J2000::IAU2000ModelParams = Eigen::Matrix(); + +WGS84_J2000::WGS84_J2000() +{ + WGS84_J2000::IAU2000ModelParams << 0.0, 0.0, 0.0, 0.0, 1.0, -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0, + 0.0, 0.0, 2.0, -2.0, 2.0, -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0, + 0.0, 0.0, 2.0, 0.0, 2.0, -2276413.0, -234.0, 2796.0, 978459.0, -485.0, 1374.0, + 0.0, 0.0, 0.0, 0.0, 2.0, 2074554.0, 207.0, -698.0, -897492.0, 470.0, -291.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 1475877.0, -3633.0, 11817.0, 73871.0, -184.0, -1924.0, + 0.0, 1.0, 2.0, -2.0, 2.0, -516821.0, 1226.0, -524.0, 224386.0, -677.0, -174.0, + 1.0, 0.0, 0.0, 0.0, 0.0, 711159.0, 73.0, -872.0, -6750.0, 0.0, 358.0, + 0.0, 0.0, 2.0, 0.0, 1.0, -387298.0, -367.0, 380.0, 200728.0, 18.0, 318.0, + 1.0, 0.0, 2.0, 0.0, 2.0, -301461.0, -36.0, 816.0, 129025.0, -63.0, 367.0, + 0.0, -1.0, 2.0, -2.0, 2.0, 215829.0, -494.0, 111.0, -95929.0, 299.0, 132.0, + 0.0, 0.0, 2.0, -2.0, 1.0, 128227.0, 137.0, 181.0, -68982.0, -9.0, 39.0, + -1.0, 0.0, 2.0, 0.0, 2.0, 123457.0, 11.0, 19.0, -53311.0, 32.0, -4.0, + -1.0, 0.0, 0.0, 2.0, 0.0, 156994.0, 10.0, -168.0, -1235.0, 0.0, 82.0, + 1.0, 0.0, 0.0, 0.0, 1.0, 63110.0, 63.0, 27.0, -33228.0, 0.0, -9.0, + -1.0, 0.0, 0.0, 0.0, 1.0, -57976.0, -63.0, -189.0, 31429.0, 0.0, -75.0, + -1.0, 0.0, 2.0, 2.0, 2.0, -59641.0, -11.0, 149.0, 25543.0, -11.0, 66.0, + 1.0, 0.0, 2.0, 0.0, 1.0, -51613.0, -42.0, 129.0, 26366.0, 0.0, 78.0, + -2.0, 0.0, 2.0, 0.0, 1.0, 45893.0, 50.0, 31.0, -24236.0, -10.0, 20.0, + 0.0, 0.0, 0.0, 2.0, 0.0, 63384.0, 11.0, -150.0, -1220.0, 0.0, 29.0, + 0.0, 0.0, 2.0, 2.0, 2.0, -38571.0, -1.0, 158.0, 16452.0, -11.0, 68.0, + 0.0, -2.0, 2.0, -2.0, 2.0, 32481.0, 0.0, 0.0, -13870.0, 0.0, 0.0, + -2.0, 0.0, 0.0, 2.0, 0.0, -47722.0, 0.0, -18.0, 477.0, 0.0, -25.0, + 2.0, 0.0, 2.0, 0.0, 2.0, -31046.0, -1.0, 131.0, 13238.0, -11.0, 59.0, + 1.0, 0.0, 2.0, -2.0, 2.0, 28593.0, 0.0, -1.0, -12338.0, 10.0, -3.0, + -1.0, 0.0, 2.0, 0.0, 1.0, 20441.0, 21.0, 10.0, -10758.0, 0.0, -3.0, + 2.0, 0.0, 0.0, 0.0, 0.0, 29243.0, 0.0, -74.0, -609.0, 0.0, 13.0, + 0.0, 0.0, 2.0, 0.0, 0.0, 25887.0, 0.0, -66.0, -550.0, 0.0, 11.0, + 0.0, 1.0, 0.0, 0.0, 1.0, -14053.0, -25.0, 79.0, 8551.0, -2.0, -45.0, + -1.0, 0.0, 0.0, 2.0, 1.0, 15164.0, 10.0, 11.0, -8001.0, 0.0, -1.0, + 0.0, 2.0, 2.0, -2.0, 2.0, -15794.0, 72.0, -16.0, 6850.0, -42.0, -5.0, + 0.0, 0.0, -2.0, 2.0, 0.0, 21783.0, 0.0, 13.0, -167.0, 0.0, 13.0, + 1.0, 0.0, 0.0, -2.0, 1.0, -12873.0, -10.0, -37.0, 6953.0, 0.0, -14.0, + 0.0, -1.0, 0.0, 0.0, 1.0, -12654.0, 11.0, 63.0, 6415.0, 0.0, 26.0, + -1.0, 0.0, 2.0, 2.0, 1.0, -10204.0, 0.0, 25.0, 5222.0, 0.0, 15.0, + 0.0, 2.0, 0.0, 0.0, 0.0, 16707.0, -85.0, -10.0, 168.0, -1.0, 10.0, + 1.0, 0.0, 2.0, 2.0, 2.0, -7691.0, 0.0, 44.0, 3268.0, 0.0, 19.0, + -2.0, 0.0, 2.0, 0.0, 0.0, -11024.0, 0.0, -14.0, 104.0, 0.0, 2.0, + 0.0, 1.0, 2.0, 0.0, 2.0, 7566.0, -21.0, -11.0, -3250.0, 0.0, -5.0, + 0.0, 0.0, 2.0, 2.0, 1.0, -6637.0, -11.0, 25.0, 3353.0, 0.0, 14.0, + 0.0, -1.0, 2.0, 0.0, 2.0, -7141.0, 21.0, 8.0, 3070.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 2.0, 1.0, -6302.0, -11.0, 2.0, 3272.0, 0.0, 4.0, + 1.0, 0.0, 2.0, -2.0, 1.0, 5800.0, 10.0, 2.0, -3045.0, 0.0, -1.0, + 2.0, 0.0, 2.0, -2.0, 2.0, 6443.0, 0.0, -7.0, -2768.0, 0.0, -4.0, + -2.0, 0.0, 0.0, 2.0, 1.0, -5774.0, -11.0, -15.0, 3041.0, 0.0, -5.0, + 2.0, 0.0, 2.0, 0.0, 1.0, -5350.0, 0.0, 21.0, 2695.0, 0.0, 12.0, + 0.0, -1.0, 2.0, -2.0, 1.0, -4752.0, -11.0, -3.0, 2719.0, 0.0, -3.0, + 0.0, 0.0, 0.0, -2.0, 1.0, -4940.0, -11.0, -21.0, 2720.0, 0.0, -9.0, + -1.0, -1.0, 0.0, 2.0, 0.0, 7350.0, 0.0, -8.0, -51.0, 0.0, 4.0, + 2.0, 0.0, 0.0, -2.0, 1.0, 4065.0, 0.0, 6.0, -2206.0, 0.0, 1.0, + 1.0, 0.0, 0.0, 2.0, 0.0, 6579.0, 0.0, -24.0, -199.0, 0.0, 2.0, + 0.0, 1.0, 2.0, -2.0, 1.0, 3579.0, 0.0, 5.0, -1900.0, 0.0, 1.0, + 1.0, -1.0, 0.0, 0.0, 0.0, 4725.0, 0.0, -6.0, -41.0, 0.0, 3.0, + -2.0, 0.0, 2.0, 0.0, 2.0, -3075.0, 0.0, -2.0, 1313.0, 0.0, -1.0, + 3.0, 0.0, 2.0, 0.0, 2.0, -2904.0, 0.0, 15.0, 1233.0, 0.0, 7.0, + 0.0, -1.0, 0.0, 2.0, 0.0, 4348.0, 0.0, -10.0, -81.0, 0.0, 2.0, + 1.0, -1.0, 2.0, 0.0, 2.0, -2878.0, 0.0, 8.0, 1232.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 1.0, 0.0, -4230.0, 0.0, 5.0, -20.0, 0.0, -2.0, + -1.0, -1.0, 2.0, 2.0, 2.0, -2819.0, 0.0, 7.0, 1207.0, 0.0, 3.0, + -1.0, 0.0, 2.0, 0.0, 0.0, -4056.0, 0.0, 5.0, 40.0, 0.0, -2.0, + 0.0, -1.0, 2.0, 2.0, 2.0, -2647.0, 0.0, 11.0, 1129.0, 0.0, 5.0, + -2.0, 0.0, 0.0, 0.0, 1.0, -2294.0, 0.0, -10.0, 1266.0, 0.0, -4.0, + 1.0, 1.0, 2.0, 0.0, 2.0, 2481.0, 0.0, -7.0, -1062.0, 0.0, -3.0, + 2.0, 0.0, 0.0, 0.0, 1.0, 2179.0, 0.0, -2.0, -1129.0, 0.0, -2.0, + -1.0, 1.0, 0.0, 1.0, 0.0, 3276.0, 0.0, 1.0, -9.0, 0.0, 0.0, + 1.0, 1.0, 0.0, 0.0, 0.0, -3389.0, 0.0, 5.0, 35.0, 0.0, -2.0, + 1.0, 0.0, 2.0, 0.0, 0.0, 3339.0, 0.0, -13.0, -107.0, 0.0, 1.0, + -1.0, 0.0, 2.0, -2.0, 1.0, -1987.0, 0.0, -6.0, 1073.0, 0.0, -2.0, + 1.0, 0.0, 0.0, 0.0, 2.0, -1981.0, 0.0, 0.0, 854.0, 0.0, 0.0, + -1.0, 0.0, 0.0, 1.0, 0.0, 4026.0, 0.0, -353.0, -553.0, 0.0, -139.0, + 0.0, 0.0, 2.0, 1.0, 2.0, 1660.0, 0.0, -5.0, -710.0, 0.0, -2.0, + -1.0, 0.0, 2.0, 4.0, 2.0, -1521.0, 0.0, 9.0, 647.0, 0.0, 4.0, + -1.0, 1.0, 0.0, 1.0, 1.0, 1314.0, 0.0, 0.0, -700.0, 0.0, 0.0, + 0.0, -2.0, 2.0, -2.0, 1.0, -1283.0, 0.0, 0.0, 672.0, 0.0, 0.0, + 1.0, 0.0, 2.0, 2.0, 1.0, -1331.0, 0.0, 8.0, 663.0, 0.0, 4.0, + -2.0, 0.0, 2.0, 2.0, 2.0, 1383.0, 0.0, -2.0, -594.0, 0.0, -2.0, + -1.0, 0.0, 0.0, 0.0, 2.0, 1405.0, 0.0, 4.0, -610.0, 0.0, 2.0, + 1.0, 1.0, 2.0, -2.0, 2.0, 1290.0, 0.0, 0.0, -556.0, 0.0, 0.0; +} +WGS84_J2000::~WGS84_J2000() +{ + +} +/// +/// step1 WGS 84 转锟斤拷锟斤拷协锟斤拷锟斤拷锟斤拷锟斤拷锟较碉拷锟?1锟?7 +/// 锟斤拷鼐锟轿筹拷雀叱锟紹LH锟斤拷毓锟斤拷锟斤拷锟较碉拷锟阶?拷锟?1锟?7 BLH-- > XG +/// ECEF, Earth Centered Earth Fixed; 锟截癸拷锟斤拷锟斤拷系 锟轿匡拷平锟芥:平锟斤拷锟斤拷妫?拷锟斤拷锟斤拷锟斤拷模锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷CIO锟斤拷锟斤拷锟竭达拷直锟斤拷平锟芥。 +/// x锟斤拷为锟轿匡拷平锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟狡斤拷娼伙拷撸锟絲锟斤拷为锟斤拷锟斤拷指锟斤拷CIO锟姐。 +/// +/// B L H锟街憋拷为锟斤拷锟轿筹拷取锟斤拷锟截撅拷锟饺和达拷馗叱锟?1锟?7 锟斤拷锟斤拷锟斤拷锟轿狽 * 3锟斤拷锟斤拷 +/// XYZ 为锟截癸拷锟斤拷锟斤拷系锟斤拷 x y z锟斤拷锟斤拷锟斤拷锟斤拷锟轿狽 * 3锟斤拷锟斤拷 +Eigen::MatrixXd WGS84_J2000::WGS84TECEF(Eigen::MatrixXd LBH_deg_m) +{ + return LLA2XYZ(LBH_deg_m); +} +/// +/// step 2 协锟斤拷锟斤拷锟斤拷锟斤拷锟较?1锟?7 转锟斤拷为瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷锟斤拷要锟芥及锟斤拷询 锟斤拷锟斤拷时锟教碉拷 xp,yp , 锟斤拷锟皆诧拷询EOP锟侥硷拷锟斤拷茫锟斤拷锟斤拷氐锟街凤拷锟斤拷锟絟ttp://celestrak.com/spacedata/ +/// earthFixedXYZ=ordinateSingleRotate('x',yp)*ordinateSingleRotate('y',xp)*earthFixedXYZ; +/// +/// axis 锟斤拷示围锟斤拷锟斤拷转锟斤拷锟斤拷锟斤拷锟斤拷 '1' 锟斤拷示围锟斤拷 x锟斤拷锟斤拷时锟斤拷锟斤拷转;'2' 锟斤拷示围锟斤拷 y锟斤拷锟斤拷时锟斤拷锟斤拷转;'3'锟斤拷示围锟斤拷 z锟斤拷锟斤拷时锟斤拷锟斤拷转 +/// angle_deg 锟斤拷示锟斤拷转锟侥角讹拷 默锟斤拷 degree +/// +Eigen::MatrixXd WGS84_J2000::ordinateSingleRotate(int axis, double angle_deg) +{ + angle_deg = angle_deg * d2r; + Eigen::MatrixXd R = Eigen::MatrixXd::Ones(3, 3); + switch (axis) + { + case 1: // x + R << 1, 0.0, 0.0, + 0.0, cos(angle_deg), sin(angle_deg), + 0.0, -1 * sin(angle_deg), cos(angle_deg); + break; + case 2:// y + R << cos(angle_deg), 0.0, -1 * sin(angle_deg), + 0.0, 1, 0.0, + sin(angle_deg), 0.0, cos(angle_deg); + break; + case 3:// z + R << cos(angle_deg), sin(angle_deg), 0.0, + -1 * sin(angle_deg), cos(angle_deg), 0.0, + 0.0, 0.0, 1; + break; + default: + throw exception("Error Axis"); + exit(-1); + } + return R; +} + +/// +/// step 3 瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷为 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷utc时锟斤拷转锟斤拷为锟斤拷锟斤拷锟斤拷锟轿猴拷锟斤拷时 +/// xyz= ordinateSingleRotate('z',-gst_deg)*earthFixedXYZ; +/// UNTITLED 锟斤拷锟姐当锟截猴拷锟斤拷时,锟斤拷锟斤拷值锟斤拷时锟斤拷为锟斤拷位 +/// %dAT 锟斤拷锟斤拷锟斤拷 +/// % TAI锟斤拷锟斤拷原锟斤拷时锟斤拷 锟斤拷时锟斤拷锟斤拷准 TAI = UTC + dAT;% 锟斤拷锟斤拷原锟斤拷时锟斤拷 +/// % TT 锟斤拷锟斤拷时 TT = TAI + 32.184 锟斤拷2014锟斤拷锟绞憋拷锟?1锟?7; +/// % TDT 锟斤拷锟斤拷锟斤拷学时锟斤拷 +/// % ET 锟斤拷锟斤拷时锟斤拷 +/// % 锟斤拷锟斤拷时 = 锟斤拷锟斤拷锟斤拷学时锟斤拷 = 锟斤拷锟斤拷时锟斤拷 +/// %锟斤拷锟斤拷时=锟斤拷锟斤拷锟斤拷学时锟斤拷=锟斤拷锟斤拷时锟斤拷 +/// +/// 锟斤拷式为y m d 锟斤拷锟斤拷d锟斤拷锟斤拷值为小锟斤拷锟斤拷锟斤拷h m s 锟斤拷锟斤拷sec/3600+min/60+h)/24转锟斤拷锟斤拷小锟斤拷锟斤拷锟斤拷锟桔加碉拷day 锟斤拷 +/// dUT1 为ut1-utc 锟侥差,锟斤拷值锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷1锟诫,锟斤拷iers锟缴伙拷锟斤拷锟街?1锟?7 0 +/// 锟斤拷锟斤拷锟斤拷 37 +/// 锟斤拷锟斤拷原锟斤拷时锟斤拷 锟斤拷时锟斤拷锟斤拷准 TAI=UTC+dAT; %锟斤拷锟斤拷原锟斤拷时锟斤拷 +/// 锟斤拷锟斤拷时 TT = TAI+32.184 锟斤拷2014锟斤拷锟绞憋拷锟?1锟?7; +/// +int WGS84_J2000::utc2gst(Eigen::MatrixXd UTC, double dUT1, double dAT, double& gst_deg, double& JDTDB) +{ + + //function[gst_deg, JDTDB] = utc2gst(UTC, dUT1, dAT) + //% TDT 锟斤拷锟斤拷锟斤拷学时锟斤拷 + // % ET 锟斤拷锟斤拷时锟斤拷 + // % 锟斤拷锟斤拷时 = 锟斤拷锟斤拷锟斤拷学时锟斤拷 = 锟斤拷锟斤拷时锟斤拷 + double J2000 = 2451545; + + double JDutc = YMD2JD(UTC(0,0), UTC(0,1), UTC(0,2)); + double JDUT1 = JDutc + dUT1 / 86400;// % UT1 为锟斤拷锟斤拷时锟斤拷锟斤拷锟斤拷时锟斤拷锟斤拷锟斤拷转锟侥诧拷锟斤拷锟饺o拷锟斤拷锟斤拷锟経TC时锟斤拷锟斤拷dUT1锟侥诧拷锟絛UT1锟节革拷锟斤拷锟斤拷锟斤拷锟斤拷时锟脚猴拷锟叫伙拷锟斤拷0.1锟斤拷木锟斤拷雀锟斤拷锟絀ERS锟斤拷锟斤拷锟斤拷锟斤拷锟襟,伙拷锟斤拷1e - 5锟侥撅拷锟饺革拷锟斤拷锟斤拷 + double dT = 32.184 + dAT - dUT1; + double JDTT = JDUT1 + dT / 86400; + + + //% JDTT = YMD2JD(UTC(1), UTC(2), UTC(3)) + dUT1 / 86400; + //% 锟斤拷锟饺硷拷锟斤拷TDB, TDB锟斤拷锟斤拷锟侥讹拷锟斤拷学时锟斤拷锟斤拷太锟斤拷锟斤拷锟斤拷锟斤拷锟角碉拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟叫碉拷时锟斤拷叨锟?1锟?7 + double T = (JDTT - J2000) / 36525; + double temp = 0.001657 * sin(628.3076 * T + 6.2401) + + 0.000022 * sin(575.3385 * T + 4.2970) + + 0.000014 * sin(1256.6152 * T + 6.1969) + + 0.000005 * sin(606.9777 * T + 4.0212) + + 0.000005 * sin(52.9691 * T + 0.4444) + + 0.000002 * sin(21.3299 * T + 5.5431) + + 0.00001 * T * sin(628.3076 * T + 4.2490); + JDTDB = JDTT + temp / 86400; + + //% 锟斤拷锟斤拷锟斤拷锟経T2, UT2锟斤拷锟斤拷UT1锟侥伙拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟皆硷拷锟节变化锟斤拷玫锟斤拷锟斤拷锟斤拷锟绞憋拷锟?1锟?7 + // %% 锟斤拷锟斤拷UT1锟斤拷锟斤拷Tb, Tb为锟皆憋拷锟斤拷锟斤拷锟斤拷为锟斤拷位锟斤拷锟斤拷锟斤拷元B2000.0锟斤拷锟斤拷ff + // % B2000 = 2451544.033; + //% Tb = (YMD2JD(UT1(1), UT1(2), UT1(3)) - B2000) / 365.2422; + //% dTs = 0.022 * sin(2 * pi * Tb) - 0.012 * cos(2 * pi * Tb) - 0.006 * sin(4 * pi * Tb) + 0.007 * cos(4 * pi * Tb); + //% dTs = dTs / 86400; + //% UT2 = UT1 + [0 0 dTs]; + + //% 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷时GMST; 锟斤拷位为锟斤拷 + T = (JDTDB - J2000) / 36525; + double T2 = T * T; + double T3 = T2 * T; + double T4 = T3 * T; + double T5 = T4 * T; + double Du = JDUT1 - J2000; + double thita = 0.7790572732640 + 1.00273781191135448 * Du;//% 锟斤拷J2000锟斤拷锟斤拷锟阶?拷锟斤拷锟饺︼拷锟斤拷锟?1锟?7 + double GMST_deg = (-0.0000000368 * T5 - 0.000029956 * T4 - 0.00000044 * T3 + 1.3915817 * T2 + 4612.156534 * T + 0.014506) / 3600 + (thita - floor(thita)) * 360; + double epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg; + WGS84_J2000::nutationInLongitudeCaculate(JDTDB, epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg); + //[epthilongA_deg, dertaPthi_deg] = nutationInLongitudeCaculate(JDTDB); + + //% 锟斤拷锟斤拷嗑?拷露锟斤拷锟斤拷锟斤拷锟斤拷锟絜clipticObliquitygama锟斤拷锟斤拷位为锟斤拷锟斤拷 + //% 锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷锟?1锟?7 太锟斤拷平锟斤拷锟斤拷锟?1锟?7 锟斤拷锟斤拷纬锟饺凤拷锟斤拷 锟斤拷锟斤拷平锟角撅拷(锟斤拷锟斤拷平锟狡撅拷 - 太锟斤拷平锟狡撅拷锟斤拷 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟狡撅拷 锟斤拷位为锟斤拷锟斤拷 + double F_deg = (0.00000417 * T4 - 0.001037 * T3 - 12.7512 * T2 + 1739527262.8478 * T + 335779.526232) / 3600; + F_deg = fmod(F_deg, 360); + double D_deg = (-0.00003169 * T4 + 0.006593 * T3 - 6.3706 * T2 + 1602961601.2090 * T + 1072260.70369) / 3600; + D_deg = fmod(D_deg, 360); + double Omiga_deg = (-0.00005939 * T4 + 0.007702 * T3 + 7.4722 * T2 - 6962890.5431 * T + 450160.398036) / 3600; + Omiga_deg = fmod(Omiga_deg, 360); + + double epthilongGama_deg = dertaPthi_deg * cosd(epthilongA_deg) + + (0.00264096 * sind(Omiga_deg ) + + 0.00006352 * sind(2 * Omiga_deg ) + + 0.00001175 * sind(2 * F_deg - 2 * D_deg + 3 * Omiga_deg) + + 0.00001121 * sind(2 * F_deg - 2 * D_deg + Omiga_deg) + - 0.00000455 * sind(2 * F_deg - 2 * D_deg + 2 * Omiga_deg) + + 0.00000202 * sind(2 * F_deg + 3 * Omiga_deg) + + 0.00000198 * sind(2 * F_deg + Omiga_deg) + - 0.00000172 * sind(3 * Omiga_deg) + - 0.00000087 * T * sind(Omiga_deg)) / 3600; + gst_deg = epthilongGama_deg + GMST_deg; + return 0; +} + + +/// +/// step 4 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷瞬时平锟斤拷锟斤拷 锟斤拷锟斤拷系 +/// 锟斤拷锟斤拷平锟狡赤交锟角o拷锟狡撅拷锟铰讹拷锟斤拷锟酵斤拷锟斤拷锟铰讹拷锟斤拷瞬时锟狡赤交锟角★拷 +/// +/// 锟斤拷锟斤拷锟斤拷 +/// 锟斤拷示锟斤拷锟斤拷木锟斤拷锟揭?拷锟?1锟?7 锟斤拷值为锟斤拷normal锟斤拷 锟酵★拷high锟斤拷 锟斤拷锟斤拷锟斤拷'N'锟酵★拷H'锟斤拷示一锟姐精锟饺和高撅拷锟斤拷 锟斤拷默锟斤拷为锟竭撅拷锟饺硷拷锟斤拷 +/// 平锟狡赤交锟斤拷 +/// 锟狡撅拷锟铰讹拷 +/// 锟酵斤拷锟斤拷锟铰讹拷 +/// 瞬时锟狡赤交锟斤拷 +/// +int WGS84_J2000::nutationInLongitudeCaculate(double JD, double& epthilongA_deg, double& dertaPthi_deg, double& dertaEpthilong_deg, double& epthilong_deg) +{ + double T = (JD - 2451545) / 36525; + double T2 = T * T; + double T3 = T2 * T; + double T4 = T3 * T; + double T5 = T4 * T; + //% 锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷锟絣unarMeanAnomaly_deg(l_deg) 太锟斤拷平锟斤拷锟斤拷锟絊olarMeanAnomaly_deg(solarl_deg) + // % 锟斤拷锟斤拷纬锟饺凤拷锟斤拷lunarLatitudeAngle_deg(F_deg) 锟斤拷锟斤拷平锟角撅拷diffLunarSolarElestialLongitude_deg(D_deg锟斤拷锟斤拷平锟狡撅拷 - 太锟斤拷平锟狡撅拷锟斤拷 + // % 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟狡撅拷SolarAscendingNodeElestialLongitude_deg(Omiga_deg) + double l_deg = (-0.00024470 * T4 + 0.051635 * T3 + 31.8792 * T2 + 1717915923.2178 * T + 485868.249036) / 3600; + l_deg = fmod(l_deg, 360); + double solarl_deg = (-0.00001149 * T4 + 0.000136 * T3 - 0.5532 * T2 + 129596581.0481 * T + 1287104.79305) / 3600; + solarl_deg = fmod(solarl_deg, 360); + double F_deg = (0.00000417 * T4 - 0.001037 * T3 - 12.7512 * T2 + 1739527262.8478 * T + 335779.526232) / 3600; + F_deg = fmod(F_deg, 360); + double D_deg = (-0.00003169 * T4 + 0.006593 * T3 - 6.3706 * T2 + 1602961601.2090 * T + 1072260.70369) / 3600; + D_deg = fmod(D_deg, 360); + double Omiga_deg = (-0.00005939 * T4 + 0.007702 * T3 + 7.4722 * T2 - 6962890.5431 * T + 450160.398036) / 3600; + Omiga_deg = fmod(Omiga_deg, 360); + Eigen::MatrixXd basicAngle_deg = Eigen::Matrix{ l_deg,solarl_deg,F_deg,D_deg,Omiga_deg }; + + epthilongA_deg = (-0.0000000434 * T5 - 0.000000576 * T4 + 0.00200340 * T3 - 0.0001831 * T2 - 46.836769 * T + 84381.406) / 3600; + epthilongA_deg = epthilongA_deg - floor(epthilongA_deg / 360) * 360; + //% IAU2000模锟斤拷锟斤拷77锟斤拷 + Eigen::MatrixXd elestialLonNutation = WGS84_J2000::IAU2000ModelParams; + + dertaPthi_deg = -3.75e-08; + dertaEpthilong_deg = 0.388e-3 / 3600; + for (int i = 0; i < 77; i++) { + double sumAngle_deg = 0; + for (int j = 0; j < 5; j++) { + sumAngle_deg = sumAngle_deg + elestialLonNutation(i, j) * basicAngle_deg(j); + } + sumAngle_deg = sumAngle_deg - floor(sumAngle_deg / 360) * 360; + dertaPthi_deg = dertaPthi_deg + ((elestialLonNutation(i, 5) + elestialLonNutation(i, 6) * T) * sind(sumAngle_deg ) + elestialLonNutation(i, 7) * cosd(sumAngle_deg)) * 1e-7 / 3600; + dertaEpthilong_deg = dertaEpthilong_deg + ((elestialLonNutation(i, 8) + elestialLonNutation(i, 9) * T) * cosd(sumAngle_deg) + elestialLonNutation(i, 10) * sind(sumAngle_deg)) * 1e-7 / 3600; + } + epthilong_deg = epthilongA_deg + dertaEpthilong_deg; + return 0; +} + +/// +/// zA锟斤拷thitaA锟斤拷zetaA为锟斤拷锟斤拷锟斤拷锟?1锟?7, 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 +/// +/// +/// +/// +/// +/// +int WGS84_J2000::precessionAngle(double JDTDB, double& zetaA, double& thitaA, double& zA) +{ + double T = (JDTDB - 2451545) / 36525; + double T2 = T * T; + double T3 = T2 * T; + //% + //% zetaA = (2306.218 * T + 0.30188 * T2 + 0.017998 * T3) / 3600; + //% zA = (2306.218 * T + 1.09468 * T2 + 0.018203) / 3600; + //% thitaA = (2004.3109 * T - 0.42665 * T2 - 0.041833 * T3) / 3600; + double T4 = T3 * T; + double T5 = T4 * T; + zetaA = (-0.0000003173 * T5 - 0.000005971 * T4 + 0.01801828 * T3 + 0.2988499 * T2 + 2306.083227 * T + 2.650545) / 3600; + thitaA = (-0.0000001274 * T5 - 0.000007089 * T4 - 0.04182264 * T3 - 0.4294934 * T2 + 2004.191903 * T) / 3600; + zA = (-0.0000002904 * T5 - 0.000028596 * T4 + 0.01826837 * T3 + 1.0927348 * T2 + 2306.077181 * T - 2.650545) / 3600; + return 0; +} + +/// +/// 同时 YMD2JD锟斤拷锟斤拷为 锟斤拷锟斤拷锟斤拷转锟斤拷为锟斤拷锟斤拷锟秸o拷 +/// +/// +/// +/// +/// +double WGS84_J2000::YMD2JD(double y, double m, double d) +{ + int B = 0; + if (y > 1582 || (y == 1582 && m > 10) || (y == 1582 && m == 10 && d >= 15)) { + B = 2 - floor(y / 100) + floor(y / 400); + } + return floor(365.25 * (y + 4712)) + floor(30.6 * (m + 1)) + d - 63.5 + B; +} + +/// +/// WGS84 转 J2000 +/// +/// WGS84 锟斤拷纬锟斤拷 +/// 1x3 Y,m,d +/// EARTH ORIENTATION PARAMETER Xp +/// EARTH ORIENTATION PARAMETER Yp +/// Solar Weather Data dut1 +/// Solar Weather Data dat +/// +Eigen::MatrixXd WGS84_J2000::WGS842J2000(Eigen::MatrixXd BLH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat) +{ + //step 1 step1 WGS 84 转锟斤拷锟斤拷协锟斤拷锟斤拷锟斤拷锟斤拷锟较碉拷锟?1锟?7 + Eigen::MatrixXd earthFixedXYZ = WGS84_J2000::WGS84TECEF(BLH_deg_m).transpose(); + //step 2 协锟斤拷锟斤拷锟斤拷锟斤拷锟较?1锟?7 转锟斤拷为瞬时锟斤拷锟斤拷锟斤拷锟斤拷 + // 锟斤拷锟斤拷要锟芥及锟斤拷询 锟斤拷锟斤拷时锟教碉拷 xp,yp , 锟斤拷锟皆诧拷询EOP锟侥硷拷锟斤拷茫锟斤拷锟斤拷氐锟街凤拷锟斤拷锟絟ttp://celestrak.com/spacedata/ + earthFixedXYZ = ordinateSingleRotate(1, yp) * ordinateSingleRotate(2, xp) * earthFixedXYZ; + //step 3 瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷为 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 + // 锟矫诧拷锟斤拷锟斤拷要锟芥及锟斤拷锟斤拷锟斤拷锟斤拷锟轿猴拷锟斤拷时锟角的硷拷锟姐,锟斤拷锟节革拷锟斤拷锟斤拷锟轿猴拷锟斤拷时锟斤拷 锟斤拷锟姐方锟斤拷 锟杰多,锟斤拷锟斤拷锟斤拷锟?1锟?7 一锟斤拷锟斤拷为锟斤拷确锟侥硷拷锟姐方锟斤拷锟斤拷锟斤拷锟斤拷dut1 锟斤拷dat锟斤拷锟斤拷锟斤拷EOP锟侥硷拷锟斤拷锟叫★拷EOP锟侥硷拷锟斤拷锟截碉拷址锟斤拷锟斤拷 http://celestrak.org/spacedata/ + double gst_deg, JDTDB; + WGS84_J2000::utc2gst(UTC, dut1, dat, gst_deg, JDTDB); + Eigen::MatrixXd xyz = ordinateSingleRotate(3, -1 * gst_deg) * earthFixedXYZ; + //step 4 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷瞬时平锟斤拷锟斤拷 锟斤拷锟斤拷系 + double epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg; + WGS84_J2000::nutationInLongitudeCaculate(JDTDB, epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg); + xyz = ordinateSingleRotate(1, -epthilongA_deg) * ordinateSingleRotate(3, dertaPthi_deg) * ordinateSingleRotate(1, dertaEpthilong_deg + epthilongA_deg) * xyz; + //step5 瞬时平锟斤拷锟斤拷锟斤拷锟斤拷系转锟斤拷为协锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系锟斤拷J2000锟斤拷 + double zetaA, thitaA, zA; + WGS84_J2000::precessionAngle(JDTDB, zetaA, thitaA, zA); + xyz = ordinateSingleRotate(3, zetaA) * ordinateSingleRotate(2, -thitaA) * ordinateSingleRotate(3, zA) * xyz; + return xyz.transpose(); + //return Eigen::MatrixXd(); +} + +Landpoint WGS84_J2000::WGS842J2000(Landpoint p, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat) +{ + Eigen::MatrixXd blh = Eigen::MatrixXd(1, 3); + blh << p.lon, p.lat, p.ati; + blh = WGS84_J2000::WGS842J2000(blh, UTC, xp, yp, dut1, dat); + return Landpoint{ blh(0,0),blh(0,1) ,blh(0,0) }; + //return Landpoint(); +} +*/ + + + diff --git a/simorthoprogram-orth_L_sar-strip/baseTool.h b/simorthoprogram-orth_L_sar-strip/baseTool.h new file mode 100644 index 0000000..64e53cf --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/baseTool.h @@ -0,0 +1,397 @@ +#pragma once +/// +/// 基本类、基本函数 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; +using namespace Eigen; + +#define PI_180 180/3.141592653589793238462643383279 +#define T180_PI 3.141592653589793238462643383279/180 +#define LIGHTSPEED 299792458 + + +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI + + + + + + + + +const double PI = 3.141592653589793238462643383279; +const double epsilon = 0.000000000000001; +const double pi = 3.14159265358979323846; +const double d2r = pi / 180; +const double r2d = 180 / pi; + +const double a = 6378137.0; //椭球长半轴 +const double ae = 6378137.0; //椭球长半轴 +const double ee= 0.0818191910428;// 第一偏心率 +const double f_inverse = 298.257223563; //扁率倒数 +const double b = a - a / f_inverse; +const double eSquare = (a * a - b * b) / (a * a); +const double e = sqrt(eSquare); +const double earth_Re = 6378136.49; +const double earth_Rp = (1 - 1 / f_inverse) * earth_Re; +const double earth_We = 0.000072292115; +///////////////////////////////////// 运行时间打印 ////////////////////////////////////////////////////////// + + +std::string getCurrentTimeString(); +std::string getCurrentShortTimeString(); + + +/////////////////////////////// 基本图像类 ////////////////////////////////////////////////////////// + +/// +/// 三维向量,坐标表达 +/// +struct Landpoint // 点 SAR影像的像素坐标; +{ + /// + /// 经度x + /// + double lon; // 经度x lon pixel_col + /// + /// 纬度y + /// + double lat; // 纬度y lat pixel_row + /// + /// 高度z + /// + double ati; // 高程z ati pixel_time +}; +struct Point_3d { + double x; + double y; + double z; +}; + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2); + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2); + +bool operator ==(const Landpoint& p1, const Landpoint& p2); + +Landpoint operator *(const Landpoint& p, double scale); + +/// +/// 向量A,B的夹角,角度 +/// +/// +/// +/// 角度制 0-360度,逆时针 +double getAngle(const Landpoint& a, const Landpoint& b); + +/// +/// 点乘 +/// +/// +/// +/// +double dot(const Landpoint& p1, const Landpoint& p2); + +double getlength(const Landpoint& p1); + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b); + + + +struct DemBox { + double min_lat; //纬度 + double min_lon;//经度 + double max_lat;//纬度 + double max_lon;//经度 +}; + + +/// +/// gdalImage图像操作类 +/// +class gdalImage +{ + +public: // 方法 + gdalImage(string raster_path); + ~gdalImage(); + void setHeight(int); + void setWidth(int); + void setTranslationMatrix(Eigen::MatrixXd gt); + void setData(Eigen::MatrixXd); + Eigen::MatrixXd getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + void saveImage(Eigen::MatrixXd,int start_row,int start_col, int band_ids); + void saveImage(); + void setNoDataValue(double nodatavalue,int band_ids); + int InitInv_gt(); + Landpoint getRow_Col(double lon, double lat); + Landpoint getLandPoint(double i, double j, double ati); + double mean(int bandids=1); + double max(int bandids=1); + double min(int bandids=1); + GDALRPCInfo getRPC(); + Eigen::MatrixXd getLandPoint(Eigen::MatrixXd points); + + Eigen::MatrixXd getHist(int bandids); +public: + string img_path; // 图像文件 + int height; // 高 + int width; // 宽 + int band_num;// 波段数 + int start_row;// + int start_col;// + int data_band_ids; + Eigen::MatrixXd gt; // 变换矩阵 + Eigen::MatrixXd inv_gt; // 逆变换矩阵 + Eigen::MatrixXd data; + string projection; +}; + +gdalImage CreategdalImage(string img_path, int height, int width, int band_num, Eigen::MatrixXd gt, std::string projection, bool need_gt=true); + +void clipGdalImage(string in_path, string out_path, DemBox box, double pixelinterval); + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample); + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample=GRIORA_Bilinear); + + + +/////////////////////////////// 基本图像类 结束 ////////////////////////////////////////////////////////// + +string Convert(float Num); +std::string JoinPath(const std::string& path, const std::string& filename); + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + + +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +Landpoint LLA2XYZ(const Landpoint& LLA); +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint); + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +Landpoint XYZ2LLA(const Landpoint& XYZ); + + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + +/// +/// 计算地表坡度向量 +/// +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 向量角度 +//Landpoint getSlopeVector(Landpoint& p0, Landpoint& p1, Landpoint& p2, Landpoint& p3, Landpoint& p4, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4); + +////////////////////////////// 插值 //////////////////////////////////////////// + +complex Cubic_Convolution_interpolation(double u,double v,Eigen::MatrixX> img); + +complex Cubic_kernel_weight(double s); + +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22); + + + +inline float cross2d(Point_3d a, Point_3d b) { return a.x * b.y - a.y * b.x; } + +inline Point_3d operator-(Point_3d a, Point_3d b) { + return Point_3d{ a.x - b.x, a.y - b.y, a.z - b.z }; +}; + +inline Point_3d operator+(Point_3d a, Point_3d b) { + return Point_3d{ a.x + b.x, a.y +b.y, a.z + b.z }; +}; + +inline double operator/(Point_3d a, Point_3d b) { + return sqrt(pow(a.x,2)+ pow(a.y, 2))/sqrt(pow(b.x, 2)+ pow(b.y, 2)); +}; +inline bool onSegment(Point_3d Pi, Point_3d Pj, Point_3d Q) +{ + if ((Q.x - Pi.x) * (Pj.y - Pi.y) == (Pj.x - Pi.x) * (Q.y - Pi.y) //叉乘 + //保证Q点坐标在pi,pj之间 + && min(Pi.x, Pj.x) <= Q.x && Q.x <= max(Pi.x, Pj.x) + && min(Pi.y, Pj.y) <= Q.y && Q.y <= max(Pi.y, Pj.y)) + return true; + else + return false; +} + +inline Point_3d invBilinear(Point_3d p, Point_3d a, Point_3d b, Point_3d c, Point_3d d) +{ + Point_3d res ; + + Point_3d e = b - a; + Point_3d f = d - a; + Point_3d g = a - b + c - d; + Point_3d h = p - a; + + double k2 = cross2d(g, f); + double k1 = cross2d(e, f) + cross2d(h, g); + double k0 = cross2d(h, e); + double u, v; + // if edges are parallel, this is a linear equation + if (abs(k2) < 0.001) + { + v = -k0 / k1; + u = (h.x - f.x *v) / (e.x + g.x *v); + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + // otherwise, it's a quadratic + else + { + float w = k1 * k1 - 4.0 * k0 * k2; + if (w < 0.0){ + // 可能在边界上 + if (onSegment(a, b, p)) { + Point_3d tt = b - a; + Point_3d ttpa = p - a; + double scater=ttpa / tt; + if(scater<0||scater>1){ return { -9999,-9999,-9999 }; } + p.z = a.z + scater * tt.z; + return p; + } + else if (onSegment(b, c, p)) { + Point_3d tt = c-b; + Point_3d ttpa = p - b; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = b.z + scater * tt.z; + return p; + } + else if (onSegment(c, d, p)) { + Point_3d tt = d-c; + Point_3d ttpa = p - c; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = c.z + scater * tt.z; + return p; + } + else if (onSegment(d, a, p)) { + Point_3d tt = a-d; + Point_3d ttpa = p - d; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = d.z + scater * tt.z; + return p; + } + + return { -9999,-9999,-9999 }; + } + else { + w = sqrt(w); + + float ik2 = 0.5 / k2; + float v = (-k1 - w) * ik2; + float u = (h.x - f.x * v) / (e.x + g.x * v); + + if (u < 0.0 || u>1.0 || v < 0.0 || v>1.0) + { + v = (-k1 + w) * ik2; + u = (h.x - f.x * v) / (e.x + g.x * v); + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; +} + + + +// +// WGS84 到J2000 坐标系的变换 +// 参考网址:https://blog.csdn.net/hit5067/article/details/116894616 +// 资料网址:http://celestrak.org/spacedata/ +// 参数文件: +// a. Earth Orientation Parameter 文件: http://celestrak.org/spacedata/EOP-Last5Years.csv +// b. Space Weather Data 文件: http://celestrak.org/spacedata/SW-Last5Years.csv +// 备注:上述文件是自2017年-五年内 +/** +在wgs84 坐标系转到J2000 坐标系 主要 涉及到坐标的相互转换。一般给定的WGS坐标为 给定时刻的 t ,BLH +转换步骤: +step 1: WGS 84 转换到协议地球坐标系 +step 2: 协议地球坐标系 转换为瞬时地球坐标系 +step 3: 瞬时地球坐标系 转换为 瞬时真天球坐标系 +step 4: 瞬时真天球坐标系 转到瞬时平天球 坐标系 +step 5: 瞬时平天球坐标系转换为协议天球坐标系(J2000) +**/ + + +inline double sind(double degree) { + return sin(degree * d2r); +} + +inline double cosd(double d) { + return cos(d * d2r); +} + +/* +class WGS84_J2000 +{ +public: + WGS84_J2000(); + ~WGS84_J2000(); + +public: + // step1 WGS 84 转换到协议地球坐标系。 + static Eigen::MatrixXd WGS84TECEF(Eigen::MatrixXd WGS84_Lon_lat_ait); + //step 2 协议地球坐标系 转换为瞬时地球坐标系 + static Eigen::MatrixXd ordinateSingleRotate(int axis, double angle_deg); + // step 3 瞬时地球坐标系 转换为 瞬时真天球坐标系 + // xyz= ordinateSingleRotate('z',-gst_deg)*earthFixedXYZ; + static int utc2gst(Eigen::MatrixXd UTC, double dUT1, double dAT, double& gst_deg, double& JDTDB); + // step 4 瞬时真天球坐标系 转到瞬时平天球 坐标系 + static int nutationInLongitudeCaculate(double JD, double& epthilongA_deg, double& dertaPthi_deg, double& dertaEpthilong_deg, double& epthilong_deg); + // step5 瞬时平天球坐标系转换为协议天球坐标系(J2000)函数中 JDTDB 为给定时刻 的地球动力学时对应的儒略日,其计算方法由步骤三中的函数给出。 + // xyz=ordinateSingleRotate('Z',zetaA)*ordinateSingleRotate('y',-thitaA)*ordinateSingleRotate('z',zA)*xyz; + static int precessionAngle(double JDTDB, double& zetaA, double& thitaA, double& zA); + // YMD2JD 同时 YMD2JD函数为 年月日转换为儒略日,具体说明 见公元纪年法(儒略历-格里高历)转儒略日_${王小贱}的博客-CSDN博客_年积日计算公式 + static double YMD2JD(double y, double m, double d); + static Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd BLH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); + static Landpoint WGS842J2000(Landpoint LBH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); +public: + static std::string EOP_File_Path; + static std::string Space_Weather_Data; + // IAU2000模型有77项11列 + static Eigen::Matrix IAU2000ModelParams; +}; + +*/ \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/interpolation.cpp b/simorthoprogram-orth_L_sar-strip/interpolation.cpp new file mode 100644 index 0000000..4e1ce26 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/interpolation.cpp @@ -0,0 +1 @@ +#include "interpolation.h" diff --git a/simorthoprogram-orth_L_sar-strip/interpolation.h b/simorthoprogram-orth_L_sar-strip/interpolation.h new file mode 100644 index 0000000..70c1ae4 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/interpolation.h @@ -0,0 +1,10 @@ +#pragma once +/** +专门用于插值计算的类库 + +*/ +#include +#include +#include +#include +#include diff --git a/simorthoprogram-orth_L_sar-strip/linterp.h b/simorthoprogram-orth_L_sar-strip/linterp.h new file mode 100644 index 0000000..5e1cb67 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/linterp.h @@ -0,0 +1,423 @@ + +// +// Copyright (c) 2012 Ronaldo Carpio +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. The authors make no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +// + +/* +This is a C++ header-only library for N-dimensional linear interpolation on a rectangular grid. Implements two methods: +* Multilinear: Interpolate using the N-dimensional hypercube containing the point. Interpolation step is O(2^N) +* Simplicial: Interpolate using the N-dimensional simplex containing the point. Interpolation step is O(N log N), but less accurate. +Requires boost/multi_array library. + +For a description of the algorithms, see: +* Weiser & Zarantonello (1988), "A Note on Piecewise Linear and Multilinear Table Interpolation in Many Dimensions", _Mathematics of Computation_ 50 (181), p. 189-196 +* Davies (1996), "Multidimensional Triangulation and Interpolation for Reinforcement Learning", _Proceedings of Neural Information Processing Systems 1996_ +*/ + +#ifndef _linterp_h +#define _linterp_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using std::vector; +using std::array; +typedef unsigned int uint; +typedef vector iVec; +typedef vector dVec; + + +// TODO: +// - specify behavior past grid boundaries. +// 1) clamp +// 2) return a pre-determined value (e.g. NaN) + +// compile-time params: +// 1) number of dimensions +// 2) scalar type T +// 3) copy data or not (default: false). The grids will always be copied +// 4) ref count class (default: none) +// 5) continuous or not + +// run-time constructor params: +// 1) f +// 2) grids +// 3) behavior outside grid: default=clamp +// 4) value to return outside grid, defaut=nan + +struct EmptyClass {}; + +template +class NDInterpolator { +public: + typedef T value_type; + typedef ArrayRefCountT array_ref_count_type; + typedef GridRefCountT grid_ref_count_type; + + static const int m_N = N; + static const bool m_bCopyData = CopyData; + static const bool m_bContinuous = Continuous; + + typedef boost::numeric::ublas::array_adaptor grid_type; + typedef boost::const_multi_array_ref array_type; + typedef std::unique_ptr array_type_ptr; + + array_type_ptr m_pF; + ArrayRefCountT m_ref_F; // reference count for m_pF + vector m_F_copy; // if CopyData == true, this holds the copy of F + + vector m_grid_list; + vector m_grid_ref_list; // reference counts for grids + vector > m_grid_copy_list; // if CopyData == true, this holds the copies of the grids + + // constructors assume that [f_begin, f_end) is a contiguous array in C-order + // non ref-counted constructor. + template + NDInterpolator(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) { + init(grids_begin, grids_len_begin, f_begin, f_end); + } + + // ref-counted constructor + template + NDInterpolator(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT grid_refs_begin) { + init_refcount(grids_begin, grids_len_begin, f_begin, f_end, refF, grid_refs_begin); + } + + template + void init(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) { + set_grids(grids_begin, grids_len_begin, m_bCopyData); + set_f_array(f_begin, f_end, m_bCopyData); + } + template + void init_refcount(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT grid_refs_begin) { + set_grids(grids_begin, grids_len_begin, m_bCopyData); + set_grids_refcount(grid_refs_begin, grid_refs_begin + N); + set_f_array(f_begin, f_end, m_bCopyData); + set_f_refcount(refF); + } + + template + void set_grids(IterT1 grids_begin, IterT2 grids_len_begin, bool bCopy) { + m_grid_list.clear(); + m_grid_ref_list.clear(); + m_grid_copy_list.clear(); + for (int i=0; i(grids_begin[i], grids_begin[i] + grids_len_begin[i]) ); // make our own copy of the grid + T *begin = &(m_grid_copy_list[i][0]); + m_grid_list.push_back(grid_type(gridLength, begin)); // use our copy + } + } + } + template + void set_grids_refcount(RefCountIterT refs_begin, RefCountIterT refs_end) { + assert(refs_end - refs_begin == N); + m_grid_ref_list.assign(refs_begin, refs_begin + N); + } + + // assumes that [f_begin, f_end) is a contiguous array in C-order + template + void set_f_array(IterT f_begin, IterT f_end, bool bCopy) { + unsigned int nGridPoints = 1; + array sizes; + for (unsigned int i=0; i(f_begin, f_end); + m_pF.reset(new array_type(&m_F_copy[0], sizes)); + } + } + void set_f_refcount(ArrayRefCountT &refF) { + m_ref_F = refF; + } + + // -1 is before the first grid point + // N-1 (where grid.size() == N) is after the last grid point + int find_cell(int dim, T x) const { + grid_type const &grid(m_grid_list[dim]); + if (x < *(grid.begin())) return -1; + else if (x >= *(grid.end()-1)) return grid.size()-1; + else { + auto i_upper = std::upper_bound(grid.begin(), grid.end(), x); + return i_upper - grid.begin() - 1; + } + } + + // return the value of f at the given cell and vertex + T get_f_val(array const &cell_index, array const &v_index) const { + array f_index; + + if (m_bContinuous) { + for (int i=0; i= m_grid_list[i].size()-1) { + f_index[i] = m_grid_list[i].size()-1; + } else { + f_index[i] = cell_index[i] + v_index[i]; + } + } + } else { + for (int i=0; i= m_grid_list[i].size()-1) { + f_index[i] = (2*m_grid_list[i].size())-1; + } else { + f_index[i] = 1 + (2*cell_index[i]) + v_index[i]; + } + } + } + return (*m_pF)(f_index); + } + + T get_f_val(array const &cell_index, int v) const { + array v_index; + for (int dim=0; dim> (N-dim-1)) & 1; // test if the i-th bit is set + } + return get_f_val(cell_index, v_index); + } +}; + +template +class InterpSimplex : public NDInterpolator { +public: + typedef NDInterpolator super; + + template + InterpSimplex(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) + : super(grids_begin, grids_len_begin, f_begin, f_end) + {} + template + InterpSimplex(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT ref_begins) + : super(grids_begin, grids_len_begin, f_begin, f_end, refF, ref_begins) + {} + + template + T interp(IterT x_begin) const { + array result; + array< array, N > coord_iter; + for (int i=0; i + void interp_vec(int n, IterT1 coord_iter_begin, IterT1 coord_iter_end, IterT2 i_result) const { + assert(N == coord_iter_end - coord_iter_begin); + + array cell_index, v_index; + array,N> xipair; + int c; + T y, v0, v1; + //mexPrintf("%d\n", n); + for (int i=0; ifind_cell(dim, coord_iter_begin[dim][i]); + //mexPrintf("%d\n", c); + if (c == -1) { // before first grid point + y = 1.0; + } else if (c == grid.size()-1) { // after last grid point + y = 0.0; + } else { + //mexPrintf("%f %f\n", grid[c], grid[c+1]); + y = (coord_iter_begin[dim][i] - grid[c]) / (grid[c + 1] - grid[c]); + if (y < 0.0) y=0.0; + else if (y > 1.0) y=1.0; + } + xipair[dim].first = y; + xipair[dim].second = dim; + cell_index[dim] = c; + } + // sort xi's and get the permutation + std::sort(xipair.begin(), xipair.end(), [](std::pair const &a, std::pair const &b) { + return (a.first < b.first); + }); + // walk the vertices of the simplex determined by the permutation + for (int j=0; jget_f_val(cell_index, v_index); + y = v0; + for (int j=0; jget_f_val(cell_index, v_index); + y += (1.0 - xipair[j].first) * (v1-v0); // interpolate + v0 = v1; + } + *i_result++ = y; + } + } +}; + +template +class InterpMultilinear : public NDInterpolator { +public: + typedef NDInterpolator super; + + template + InterpMultilinear(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) + : super(grids_begin, grids_len_begin, f_begin, f_end) + {} + template + InterpMultilinear(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT ref_begins) + : super(grids_begin, grids_len_begin, f_begin, f_end, refF, ref_begins) + {} + + template + static T linterp_nd_unitcube(IterT1 f_begin, IterT1 f_end, IterT2 xi_begin, IterT2 xi_end) { + int n = xi_end - xi_begin; + int f_len = f_end - f_begin; + assert(1 << n == f_len); + T sub_lower, sub_upper; + if (n == 1) { + sub_lower = f_begin[0]; + sub_upper = f_begin[1]; + } else { + sub_lower = linterp_nd_unitcube(f_begin, f_begin + (f_len/2), xi_begin + 1, xi_end); + sub_upper = linterp_nd_unitcube(f_begin + (f_len/2), f_end, xi_begin + 1, xi_end); + } + T result = sub_lower + (*xi_begin)*(sub_upper - sub_lower); + return result; + } + + template + T interp(IterT x_begin) const { + array result; + array< array, N > coord_iter; + for (int i=0; i + void interp_vec(int n, IterT1 coord_iter_begin, IterT1 coord_iter_end, IterT2 i_result) const { + assert(N == coord_iter_end - coord_iter_begin); + array index; + int c; + T y, xi; + vector f(1 << N); + array x; + + for (int i=0; ifind_cell(dim, coord_iter_begin[dim][i]); + if (c == -1) { // before first grid point + y = 1.0; + } else if (c == grid.size()-1) { // after last grid point + y = 0.0; + } else { + y = (coord_iter_begin[dim][i] - grid[c]) / (grid[c + 1] - grid[c]); + if (y < 0.0) y=0.0; + else if (y > 1.0) y=1.0; + } + index[dim] = c; + x[dim] = y; + } + // copy f values at vertices + for (int v=0; v < (1 << N); v++) { // loop over each vertex of hypercube + f[v] = this->get_f_val(index, v); + } + *i_result++ = linterp_nd_unitcube(f.begin(), f.end(), x.begin(), x.end()); + } + } +}; + +typedef InterpSimplex<1,double> NDInterpolator_1_S; +typedef InterpSimplex<2,double> NDInterpolator_2_S; +typedef InterpSimplex<3,double> NDInterpolator_3_S; +typedef InterpSimplex<4,double> NDInterpolator_4_S; +typedef InterpSimplex<5,double> NDInterpolator_5_S; +typedef InterpMultilinear<1,double> NDInterpolator_1_ML; +typedef InterpMultilinear<2,double> NDInterpolator_2_ML; +typedef InterpMultilinear<3,double> NDInterpolator_3_ML; +typedef InterpMultilinear<4,double> NDInterpolator_4_ML; +typedef InterpMultilinear<5,double> NDInterpolator_5_ML; + +// C interface +extern "C" { + void linterp_simplex_1(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); + void linterp_simplex_2(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); + void linterp_simplex_3(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); +} + +void inline linterp_simplex_1(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=1; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + +void inline linterp_simplex_2(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=2; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + +void inline linterp_simplex_3(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=3; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + + + + +#endif //_linterp_h \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/resource.h b/simorthoprogram-orth_L_sar-strip/resource.h new file mode 100644 index 0000000..c8940a4 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 供 SIMOrthoProgram.rc 使用 +// +#define IDR_PROJ1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/simorthoprogram-orth_L_sar-strip/simptsn.cpp b/simorthoprogram-orth_L_sar-strip/simptsn.cpp new file mode 100644 index 0000000..e3516b5 --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/simptsn.cpp @@ -0,0 +1,3696 @@ +#pragma once +/// +/// 仿真成像算法 +/// + +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Eigen; + + + +PSTNAlgorithm::PSTNAlgorithm() +{ +} + +PSTNAlgorithm::PSTNAlgorithm(string infile_path) +{ + std::cout << "=========================================================================" << endl; + std::cout << "read parameters :\t" << infile_path << endl; + std::cout << "parameters files :\t" << infile_path << endl; + std::cout << "params file Format:" << endl; + std::cout << "height --- image height" << endl; + std::cout << "width --- image width" << endl; + std::cout << "R0 --- image nearRange" << endl; + std::cout << "near_in_angle " << endl; + std::cout << "far incident angle " << endl; + std::cout << "LightSpeed " << endl; + std::cout << "lamda" << endl; + std::cout << "imgStartTime" << endl; + std::cout << "PRF" << endl; + std::cout << "refrange" << endl; + std::cout << "fs" << endl; + std::cout << "doppler_reference_time" << endl; + std::cout << "doppler_paramenter_number " << endl; + std::cout << "doppler_paramenter 1 " << endl; + std::cout << "doppler_paramenter 2" << endl; + std::cout << "doppler_paramenter 3 " << endl; + std::cout << "doppler_paramenter 4 " << endl; + std::cout << "doppler_paramenter 5 " << endl; + std::cout << "ispolySatelliteModel" << endl; + std::cout << "sate polynum " << endl; + std::cout << "SatelliteModelStartTime" << endl; + std::cout << "orbit params list " << endl; + std::cout << "============================================================================" << endl; + + // 解析文件 + ifstream infile(infile_path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + + // 参数域 + getline(infile, buf); this->height = stoi(buf); + getline(infile, buf); this->width = stoi(buf); std::cout << "height,width\t" << this->height << "," << this->width << endl; + getline(infile, buf); this->R0 = stod(buf); std::cout <<""<< "R0\t" << this->R0 << endl; //近斜距 + getline(infile, buf); this->near_in_angle = stod(buf); std::cout << "near_in_angle\t" << this->near_in_angle << endl; //近入射角 + getline(infile, buf); this->far_in_angle = stod(buf); std::cout << "far_in_angle\t" << this->far_in_angle << endl; //远入射角 + + getline(infile, buf); this->LightSpeed = stod(buf); std::cout << "LightSpeed\t" << this->LightSpeed << endl; + getline(infile, buf); this->lamda = stod(buf); std::cout << "lamda\t" << this->lamda << endl; + getline(infile, buf); this->imgStartTime = stod(buf); std::cout << "imgStartTime\t" << this->imgStartTime << endl; + getline(infile, buf); this->PRF = stod(buf); std::cout << "PRF\t" << this->PRF << endl; + getline(infile, buf); this->refrange = stod(buf); std::cout << "refrange\t" << this->refrange << endl; + getline(infile, buf); this->fs = stod(buf); std::cout << "fs\t" << this->fs << endl; + getline(infile, buf); this->doppler_reference_time = stod(buf); std::cout << "doppler_reference_time\t" << this->doppler_reference_time << endl; + getline(infile, buf); this->doppler_paramenter_number = stoi(buf); std::cout << "doppler_paramenter_number\t" << this->doppler_paramenter_number << endl; + + // 读取多普勒系数 + this->doppler_paras = Eigen::MatrixX(this->doppler_paramenter_number, 1); + if (this->doppler_paramenter_number > 0) { + for (int i = 0; i < this->doppler_paramenter_number; i++) { + getline(infile, buf); + this->doppler_paras(i, 0) = stod(buf); + } + std::cout << "doppler_paramenter:\n" << this->doppler_paras << endl; + } + else { + throw "内存不足"; + } + // 读取卫星轨道 + getline(infile, buf); std::cout << "ispolySatelliteModel\t" << buf << endl; + if (stoi(buf) != 1) { + throw "不是多项式轨道模型"; + } + getline(infile, buf); int polynum = stoi(buf) + 1; // 多项式项数 + getline(infile, buf); double SatelliteModelStartTime = stod(buf); // 轨道模型起始时间 + + Eigen::MatrixX polySatellitePara(polynum, 6); + if (polynum >= 4) { + for (int i = 0; i < 6; i++) { + for (int j = 0; j < polynum; j++) { + getline(infile, buf); + polySatellitePara(j, i) = stod(buf); + std::cout << "orbit params " << i << " , " << j << buf << endl; + } + } + } + else { + throw "内存不足"; + } + OrbitPoly orbit(polynum, polySatellitePara, SatelliteModelStartTime); + this->orbit = orbit; + std::cout << "sate polynum\t" << polynum << endl; + std::cout << "sate polySatellitePara\n" << polySatellitePara << endl; + std::cout << "sate SatelliteModelStartTime\t" << SatelliteModelStartTime << endl; + + if (!infile.eof()) // 获取变换的函数 + { + double yy, mm, dd; + getline(infile, buf); + if (buf != "" || buf.length() > 3) { + yy = stod(buf); + getline(infile, buf); mm = stod(buf); + getline(infile, buf); dd = stod(buf); + this->UTC = Eigen::Matrix{ yy,mm,dd }; + std::cout << "UTC\t" << this->UTC << endl; + std::cout << "\nWGS84 to J2000 Params:\t" << endl; + getline(infile, buf); this->Xp = stod(buf); std::cout << "Xp\t" << this->Xp << endl; + getline(infile, buf); this->Yp = stod(buf); std::cout << "Yp\t" << this->Yp << endl; + getline(infile, buf); this->Dut1 = stod(buf); std::cout << "dut1\t" << this->Dut1 << endl; + getline(infile, buf); this->Dat = stod(buf); std::cout << "dat\t" << this->Dat << endl; + } + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); + std::cout << "============================================================================" << endl; +} + +PSTNAlgorithm::~PSTNAlgorithm() +{ +} + +/// +/// 将dem坐标转换为经纬文件 +/// +/// dem +/// 经度 +/// 纬度 +/// +int PSTNAlgorithm::dem2lat_lon(std::string dem_path, std::string lon_path, std::string lat_path) +{ + gdalImage dem_img(dem_path); + //gdalImage lon_img = CreategdalImage(lon_path, dem_img.height, dem_img.width); + //gdalImage lat_img = CreategdalImage(lat_path, dem_img.height, dem_img.width); + + + return 0; +} + +int PSTNAlgorithm::dem2SAR_RC(std::string dem_path, std::string sim_rc_path) +{ + return 0; +} + + +Eigen::MatrixX PSTNAlgorithm::calNumericalDopplerValue(Eigen::MatrixX R) +{ + Eigen::MatrixX t = (R.array() - this->refrange) * (1000000 / LIGHTSPEED); + Eigen::MatrixX tlist(t.rows(), this->doppler_paramenter_number);// nx5 + tlist.col(0) = Eigen::MatrixX::Ones(t.rows(), 1).col(0); + for (int i = 1; i < this->doppler_paramenter_number; i++) + { + tlist.col(i) = t.array().pow(i); + } + //return tlist.array()*this + return tlist * this->doppler_paras; //nx5,5x1 + //return Eigen::MatrixX(1, 1); +} + + +double PSTNAlgorithm::calNumericalDopplerValue(double R) +{ + //double t = (R - this->refrange) * (1e6 / LIGHTSPEED); GF3 + //double t = R / LIGHTSPEED - this->doppler_reference_time; //S_SAR公式 + //double temp = this->doppler_paras(0) + this->doppler_paras(1) * t + this->doppler_paras(2) * t * t + this->doppler_paras(3) * t * t * t + this->doppler_paras(4) * t * t * t * t; // GF3 HJ + //double temp = this->doppler_paras(0) + this->doppler_paras(1) * t + this->doppler_paras(2) * t * t + this->doppler_paras(3) * t * t * t; // LT + return 0; +} + + +Eigen::MatrixX PSTNAlgorithm::PSTN(Eigen::MatrixX landpoints, double ave_dem = 0, double dt = 0.001, bool isCol = false) +{ + //Eigen::MatrixX a(1, 1); + //a(0, 0) = 1554386455.999999; + //Eigen::MatrixX satestatetest = this->orbit.SatelliteSpacePoint(a); + //std::cout << satestatetest << endl; + + int point_num = landpoints.rows(); + Eigen::MatrixX SARPoint = Eigen::MatrixX::Ones(point_num, 3); + double L_T = 0; + double S_T = 0; + double R_T = 0; + double cos_theta = 0; + + Eigen::MatrixX landpoint = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + Eigen::MatrixX satevector = Eigen::MatrixX::Ones(1, 3);// 卫星速度 + Eigen::MatrixX sate_land = Eigen::MatrixX::Ones(1, 3); // 卫星-地面矢量 + double ti = this->orbit.SatelliteModelStartTime; + double R1 = 0;// 斜距 + double R2 = 0;// 斜距 + double FdTheory1 = 0; + double FdTheory2 = 0; + double FdNumberical = 0; + double inc_t = 0; + //double delta_angle = (this->far_in_angle - this->near_in_angle) / this->width; + //std::cout << landpoint(0, 0) << "\t" << landpoint(0, 1) << "\t" << landpoint(0, 2) << endl; + dt = dt / this->PRF; + Landpoint satePoints = { 0, 0, 0 }; + Landpoint landPoint = { 0, 0, 0 }; + // 开始迭代 + for (int j = 0; j < point_num; j++) { + landpoint = landpoints.row(j); + for (int i = 0; i < 50; i++) { + satestate = this->orbit.SatelliteSpacePoint(ti + dt); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satevector = satestate(Eigen::all, { 3,4,5 }); + sate_land = satepoint - landpoint; + //std::cout << sate_land << endl; + R1 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0];; + FdTheory1 = this->calTheoryDopplerValue(R1, sate_land, satevector); + + satestate = this->orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satevector = satestate(Eigen::all, { 3,4,5 }); + sate_land = satepoint - landpoint; + R2 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + FdNumberical = this->calNumericalDopplerValue(R2); + FdTheory2 = this->calTheoryDopplerValue(R2, sate_land, satevector); + + inc_t = dt * (FdTheory2 - FdNumberical) / (FdTheory1 - FdTheory2); + if (abs(FdTheory1 - FdTheory2) < 1e-9) { + break; + } + ti = ti - inc_t; + if (abs(inc_t) <= dt) { + break; + } + } + SARPoint(j, 0) = ti; + SARPoint(j, 1) = (ti - this->imgStartTime) * this->PRF; + + // 尝试使用入射角切分列号 + satestate = this->orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + sate_land = satepoint - landpoint; + R1 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0];; + //SARPoint(j, 2) = getIncAngle(satePoints, landPoint); + //SARPoint(j, 2) = (R1 - this->R0 - (this->refrange - this->R0) / 3) / this->widthspace; + + SARPoint(j, 2) = getRangeColumn(R1, this->R0, this->fs, this->lamda);// (R1 - this->R0) / this->widthspace; // + } + //std::cout <<"SARPoints(200, 0):\t" << SARPoint(200, 0) << "\t" << SARPoint(200, 1) << "\t" << SARPoint(200, 2) << "\t" << endl; + return SARPoint; +} + +/* +Eigen::MatrixXd PSTNAlgorithm::WGS842J2000(Eigen::MatrixXd blh) +{ + return WGS84_J2000::WGS842J2000(blh, this->UTC, this->Xp, this->Yp, this->Dut1, this->Dat); + //return Eigen::MatrixXd(); +} + +Landpoint PSTNAlgorithm::WGS842J2000(Landpoint p) +{ + Eigen::MatrixXd blh = Eigen::MatrixXd(1, 3); + blh<WGS842J2000(blh); + return Landpoint{ blh(0,0),blh(0,1) ,blh(0,0) }; +} +*/ + +/// +/// 计算理论多普勒距离 +/// +/// 斜距 +/// nx3 +/// nx3 +/// +Eigen::MatrixX PSTNAlgorithm::calTheoryDopplerValue(Eigen::MatrixX R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1) +{ + return (R_s1.array() * V_s1.array()).rowwise().sum().array() * (-2) / (R.array() * this->lamda); + //return Eigen::MatrixX(1, 1); +} + +double PSTNAlgorithm::calTheoryDopplerValue(double R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1) { + return ((R_s1.array() * V_s1.array()).rowwise().sum().array() * (-2) / (R * this->lamda))[0]; +} + + +simProcess::simProcess() +{ + +} +simProcess::~simProcess() +{ +} +/// +/// 参数解析 +/// +/// +/// +/// +int simProcess::parameters(int argc, char* argv[]) +{ + for (int i = 0; i < argc; i++) { + std::cout << argv[i] << endl; + } + return 0; +} +/// +/// 间接定位法,初始化参数 +/// +/// 参数文件路径 +/// 工作空间路径 +/// 输出空间路径 +/// 输入DEM文件路径 +/// 输入SAR影像文件路径 +/// 初始化姐u共 +int simProcess::InitSimulationSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_sar_path) +{ + + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + this->in_dem_path = in_dem_path; + this->dem_path = JoinPath(workspace_path, "SAR_dem.tiff");// 获取输入DEM + this->workSpace_path = workspace_path; + this->dem_r_path = JoinPath(workspace_path, "dem_r.tiff"); + + string dem_rcs_path = JoinPath(workspace_path, "dem_rcs.tiff"); + this->sar_sim_wgs_path = JoinPath(workspace_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(workspace_path, "sar_sim.tiff"); + this->ori_sim_count_tiff = JoinPath(workspace_path, "RD_ori_sim_count.tiff"); + this->in_sar_path = in_sar_path; + this->sar_power_path = JoinPath(workspace_path, "in_sar_power.tiff"); + this->outSpace_path = out_dir_path; + this->out_dem_slantRange_path = out_dir_path + "\\" + "dem_slantRange.tiff";// 地形斜距 + this->out_plant_slantRange_path = out_dir_path + "\\" + "flat_slantRange.tiff";// 平地斜距 + this->out_dem_rc_path = out_dir_path + "\\" + "WGS_SAR_map.tiff";// 经纬度与行列号映射 + + + this->out_incidence_path = out_dir_path + "\\" + "incidentAngle.tiff";// 入射角 + this->out_localIncidenct_path = out_dir_path + "\\" + "localincidentAngle.tiff";// 局地入射角 + this->out_ori_sim_tiff = out_dir_path + "\\" + "RD_ori_sim.tif";// 坐标变换 + this->out_sim_ori_tiff = out_dir_path + "\\" + "RD_sim_ori.tif";// 坐标变换 + this->dem_rc_path = this->out_sim_ori_tiff;// JoinPath(out_dir_path, "RD_sim_ori.tif"); + this->sar_sim_wgs_path = JoinPath(out_dir_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(out_dir_path, "sar_sim.tiff"); + + + this->in_rpc_lon_lat_path = this->out_ori_sim_tiff; + this->out_inc_angle_rpc_path = out_dir_path + "\\" + "RD_incidentAngle.tiff";// 局地入射角 + this->out_local_inc_angle_rpc_path = out_dir_path + "\\" + "RD_localincidentAngle.tiff";// 局地入射角 + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_sar_path" << ":\t" << this->in_sar_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "dem_path" << ":\t" << this->dem_path << endl; + std::cout << "sar_power_path" << ":\t" << this->sar_power_path << endl; + std::cout << "dem_r_path" << ":\t" << this->dem_r_path << endl; + std::cout << "dem_rc_path" << ":\t" << this->dem_rc_path << endl; + std::cout << "sar_sim_wgs_path" << ":\t" << this->sar_sim_wgs_path << endl; + std::cout << "sar_sim_path" << ":\t" << this->sar_sim_path << endl; + std::cout << "outSpace_path" << ":\t" << this->outSpace_path << endl; + std::cout << "out_dem_slantRange_path" << ":\t" << this->out_dem_slantRange_path << endl; + std::cout << "out_plant_slantRange_path" << ":\t" << this->out_plant_slantRange_path << endl; + std::cout << "out_dem_rc_path" << ":\t" << this->out_dem_rc_path << endl; + std::cout << "out_incidence_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_localIncidenct_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->CreateSARDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + //this->SARSimulationWGS(); + //this->SARSimulation(); + this->in_sar_power(); + if (boost::filesystem::exists(boost::filesystem::path(this->out_dem_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(this->out_dem_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(this->dem_rc_path), boost::filesystem::path(this->out_dem_rc_path)); + string sim_rcs_jpg_path = JoinPath(workspace_path, "dem_rcs.jpg"); + string sar_rcs_jpg_path = JoinPath(workspace_path, "sar_rcs.jpg"); + //this->createimagematchmodel(this->sar_power_path, sar_rcs_jpg_path, this->sar_sim_path, sim_rcs_jpg_path, this->workspace_path); + //if (this->ismatchmodel) { + // std::cout << "校正" << endl; + // this->correctorth_rc(this->dem_rc_path, this->matchmodel); + //} + ////插值计算行列号 + //this->ReflectTable_WGS2Range(); + //this->SARIncidentAngle_RPC(); + return 0; +} +int simProcess::InitASFSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path) +{ + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + this->in_dem_path = in_dem_path; + this->dem_path = JoinPath(workspace_path, "SAR_dem.tiff");// 获取输入DEM + this->workSpace_path = workspace_path; + this->dem_r_path = JoinPath(workspace_path, "dem_r.tiff"); + this->dem_rc_path = JoinPath(workspace_path, "dem_rc.tiff"); + string dem_rcs_path = JoinPath(workspace_path, "dem_rcs.tiff"); + this->sar_sim_wgs_path = JoinPath(workspace_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(workspace_path, "sar_sim.tiff"); + this->ori_sim_count_tiff = JoinPath(workspace_path, "RD_ori_sim_count.tiff"); + this->in_sar_path = in_sar_path; + this->sar_power_path = JoinPath(workspace_path, "in_sar_power.tiff"); + this->outSpace_path = out_dir_path; + this->out_dem_slantRange_path = out_dir_path + "\\" + "dem_slantRange.tiff";// 地形斜距 + this->out_plant_slantRange_path = out_dir_path + "\\" + "flat_slantRange.tiff";// 平地斜距 + this->out_dem_rc_path = out_dir_path + "\\" + "WGS_SAR_map.tiff";// 经纬度与行列号映射 + this->out_incidence_path = out_dir_path + "\\" + "incidentAngle.tiff";// 入射角 + this->out_localIncidenct_path = out_dir_path + "\\" + "localincidentAngle.tiff";// 局地入射角 + this->out_ori_sim_tiff = out_dir_path + "\\" + "RD_ori_sim.tif";// 局地入射角 + this->in_rpc_lon_lat_path = this->out_ori_sim_tiff; + this->out_inc_angle_rpc_path = out_dir_path + "\\" + "RD_incidentAngle.tiff";// 局地入射角 + this->out_local_inc_angle_rpc_path = out_dir_path + "\\" + "RD_localincidentAngle.tiff";// 局地入射角 + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_sar_path" << ":\t" << this->in_sar_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "dem_path" << ":\t" << this->dem_path << endl; + std::cout << "sar_power_path" << ":\t" << this->sar_power_path << endl; + std::cout << "dem_rc_path" << ":\t" << this->dem_rc_path << endl; + std::cout << "sar_sim_wgs_path" << ":\t" << this->sar_sim_wgs_path << endl; + std::cout << "sar_sim_path" << ":\t" << this->sar_sim_path << endl; + std::cout << "outSpace_path" << ":\t" << this->outSpace_path << endl; + std::cout << "out_dem_slantRange_path" << ":\t" << this->out_dem_slantRange_path << endl; + std::cout << "out_plant_slantRange_path" << ":\t" << this->out_plant_slantRange_path << endl; + std::cout << "out_dem_rc_path" << ":\t" << this->out_dem_rc_path << endl; + std::cout << "out_incidence_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_localIncidenct_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->CreateSARDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + this->SARSimulationWGS(); + ASFOrthClass asfclass; + + this->SARSimulation(); + this->in_sar_power(); + if (boost::filesystem::exists(boost::filesystem::path(this->out_dem_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(this->out_dem_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(this->dem_rc_path), boost::filesystem::path(this->out_dem_rc_path)); + string sim_rcs_jpg_path = JoinPath(workspace_path, "dem_rcs.jpg"); + string sar_rcs_jpg_path = JoinPath(workspace_path, "sar_rcs.jpg"); + //this->createImageMatchModel(this->sar_power_path, sar_rcs_jpg_path, this->sar_sim_path, sim_rcs_jpg_path, this->workSpace_path); + if (this->isMatchModel) { + std::cout << "校正" << endl; + // this->correctOrth_rc(this->dem_rc_path, this->matchmodel); + } + + // 插值计算行列号 + this->ReflectTable_WGS2Range(); + this->SARIncidentAngle_RPC(); + return 0; + return 0; +} +/// +/// 创建SAR对应的DEM +/// +/// 返回结果 +int simProcess::CreateSARDEM() +{ + std::cout << "dem2SAR_Row_col begin time:" << getCurrentTimeString() << std::endl; + { + gdalImage dem(this->in_dem_path); + double dem_mean = dem.mean(); + gdalImage sim_rc = CreategdalImage(this->dem_rc_path, dem.height, dem.width, 2, dem.gt, dem.projection); + DemBox box{ 9999,9999,-9999,-9999 }; + { + Eigen::MatrixXd sim_r; + Eigen::MatrixXd sim_c; + int line_invert = int(2000000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + int max_rows_ids = 0; + int all_count = 0; + bool state = true; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd demdata = dem.getData(max_rows_ids, 0, line_invert, dem.width, 1); + Eigen::MatrixXd sim_r = demdata.array() * 0; + Eigen::MatrixXd sim_c = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 因为不考虑斜距,所以平面置为0 + } + } + //demdata = Eigen::MatrixXd(1, 1); + landpoint = dem.getLandPoint(landpoint); + //landpoint.col(2) = landpoint.col(2).array() * 0; + + landpoint = LLA2XYZ(landpoint); + landpoint = this->pstn.PSTN(landpoint, dem_mean, 0.001, true); // time,r,c + //std::cout << "for time " << getCurrentTimeString() << std::endl; + double min_lat = 9999; + double max_lat = -9999; + double min_lon = 9999; + double max_lon = -9999; + bool has_min_max = false; + Landpoint p1{ 0,0,0 }; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + sim_r(i, j) = landpoint(i * datacols + j, 1); + sim_c(i, j) = landpoint(i * datacols + j, 2); + p1 = dem.getLandPoint(i + max_rows_ids, j, demdata(i, j)); + if (sim_r(i, j) >= -2 && sim_c(i, j) >= -2 && sim_r(i, j) <= this->pstn.height+2 && sim_c(i, j) <= this->pstn.width+2) { + min_lat = min_lat < p1.lat ? min_lat : p1.lat; + max_lat = max_lat > p1.lat ? max_lat : p1.lat; + min_lon = min_lon < p1.lon ? min_lon : p1.lon; + max_lon = max_lon > p1.lon ? max_lon : p1.lon; + has_min_max = true; + } + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + //std::cout << "lock" << endl; + if (has_min_max) { + box.min_lat = min_lat < box.min_lat ? min_lat : box.min_lat; + box.max_lat = max_lat > box.max_lat ? max_lat : box.max_lat;; + box.min_lon = min_lon < box.min_lon ? min_lon : box.min_lon;; + box.max_lon = max_lon > box.max_lon ? max_lon : box.max_lon;; + } + sim_rc.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc.saveImage(sim_c, max_rows_ids, 0, 2); + all_count = all_count + line_invert; + std::cout << "rows:\t" << all_count << "/" << dem.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + std::cout << "prepare over" << getCurrentTimeString() << std::endl; + double dist_lat = box.max_lat - box.min_lat; + double dist_lon = box.max_lon - box.min_lon; + //dist_lat = 0.2 * dist_lat; + //dist_lon = 0.2 * dist_lon; + dist_lat = 0.001; + dist_lon = 0.001; + box.min_lat = box.min_lat - dist_lat; + box.max_lat = box.max_lat + dist_lat; + box.min_lon = box.min_lon - dist_lon; + box.max_lon = box.max_lon + dist_lon; + + std::cout << "box:" << endl; + std::cout << "min_lat-max_lat:\t" << box.min_lat << "\t" << box.max_lat << endl; + std::cout << "min_lon-max_lon:\t" << box.min_lon << "\t" << box.max_lon << endl; + std::cout << "cal box of sar over" << endl; + + // 计算采样之后的影像大小 + int width = 1.2 * this->pstn.width; + int height = 1.2 * this->pstn.height; + + double heightspace = (box.max_lat - box.min_lat) / height; + double widthspace = (box.max_lon - box.min_lon) / width; + std::cout << "resample dem:\n" << getCurrentTimeString() << std::endl; + std::cout << "in_dem:\t" << this->in_dem_path << endl; + std::cout << "out_dem:\t" << this->dem_path << endl; + std::cout << "width-height:\t" << width << "-" << height << endl; + std::cout << "widthspace\t-\theight\tspace:\t" << widthspace << "\t-\t" << heightspace << endl; + + int pBandIndex[1] = { 1 }; + int pBandCount[1] = { 1 }; + + double gt[6] = { + box.min_lon,widthspace,0, //x + box.max_lat,0,-heightspace//y + }; + + //boost::filesystem::copy(dem_path, this->dem_path); + ResampleGDAL(this->in_dem_path.c_str(), this->dem_path.c_str(), gt, width, height, GRA_Bilinear); + + std::cout << "resample dem over:\n" << getCurrentTimeString() << std::endl; + std::cout << "remove sim_rc_path:\t" << this->dem_rc_path << std::endl; + } + + return 0; +} + +/// +/// 获取行号 +/// +/// +int simProcess::dem2SAR() +{ + std::cout << "the row of the sar in dem:" << getCurrentTimeString() << std::endl; + { + this->dem2SAR_row(); + } + + std::cout << "the slant range of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_clip(this->dem_path); + gdalImage dem_r(this->dem_r_path); + double dem_mean = dem_clip.mean(); + gdalImage dem_slant_range = CreategdalImage(this->out_dem_slantRange_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + gdalImage plant_slant_range = CreategdalImage(this->out_plant_slantRange_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + + + int line_invert = int(10000000 / dem_clip.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + std::cout << "the slant range of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 行号 + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 地形 + Eigen::MatrixXd demslant_range = demdata.array() * 0; // 地形斜距 + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + landpoint = LLA2XYZ(landpoint);// this->pstn.WGS842J2000(landpoint); + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + long double ti = 0; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ti = dem_r_block(i, j) / this->pstn.PRF + this->pstn.imgStartTime; + satestate = this->pstn.orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satepoint(0, 0) = satepoint(0, 0) - landpoint(i * datacols + j, 0); + satepoint(0, 1) = satepoint(0, 1) - landpoint(i * datacols + j, 1); + satepoint(0, 2) = satepoint(0, 2) - landpoint(i * datacols + j, 2); + demslant_range(i, j) = (satepoint.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + dem_slant_range.saveImage(demslant_range, max_rows_ids, 0, 1); + //sim_rc_reprocess.saveImage(sim_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + count_lines = 0; + std::cout << "the plant slant range of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 行号 + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 地形 + Eigen::MatrixXd demslant_range = demdata.array() * 0; // 地形斜距 + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = 0; // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + landpoint = LLA2XYZ(landpoint); + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + long double ti = 0; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ti = dem_r_block(i, j) / this->pstn.PRF + this->pstn.imgStartTime; + satestate = this->pstn.orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satepoint(0, 0) = satepoint(0, 0) - landpoint(i * datacols + j, 0); + satepoint(0, 1) = satepoint(0, 1) - landpoint(i * datacols + j, 1); + satepoint(0, 2) = satepoint(0, 2) - landpoint(i * datacols + j, 2); + demslant_range(i, j) = (satepoint.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + plant_slant_range.saveImage(demslant_range, max_rows_ids, 0, 1); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "the row and col of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_r(this->dem_r_path); + gdalImage plant_slant_range(this->out_plant_slantRange_path); + gdalImage dem_rc = CreategdalImage(this->dem_rc_path, dem_r.height, dem_r.width, 2, dem_r.gt, dem_r.projection); + + int line_invert = int(10000000 / dem_r.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + std::cout << "the row and col of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_r.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_r.width, 1); // 行号 + Eigen::MatrixXd slant_range = plant_slant_range.getData(max_rows_ids, 0, line_invert, dem_r.width, 1); // 地形 + Eigen::MatrixXd dem_c = getRangeColumn(slant_range, this->pstn.R0, this->pstn.fs, this->pstn.lamda);// (slant_range.array() - this->pstn.R0) / this->pstn.widthspace; + omp_set_lock(&lock); //获得互斥器 + dem_rc.saveImage(dem_r_block, max_rows_ids, 0, 1); + dem_rc.saveImage(dem_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_r.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + + return 0; +} +/// +/// 计算相关的倾斜角 -- 弧度值 +/// +/// +int simProcess::SARIncidentAngle() +{ + std::cout << "the incidence angle and local incidence :" << getCurrentTimeString() << std::endl; + { + gdalImage dem_img(this->dem_path); + gdalImage sim_r_img(this->dem_r_path); + gdalImage localincidence_angle_img = CreategdalImage(this->out_localIncidenct_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + gdalImage incidence_angle_img = CreategdalImage(this->out_incidence_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + incidence_angle_img.setNoDataValue(-10, 1); + localincidence_angle_img.setNoDataValue(-10, 1); + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(5000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + int count_lines = 0; + for (int max_rows_ids = 0; max_rows_ids < dem_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd sim_inclocal = incidence_angle_img.getData(max_rows_ids, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids, 0, line_invert + 2, line_width, 1); + sim_inclocal = sim_inclocal.array() * 0 - 10; + sim_localinclocal = sim_localinclocal.array() * 0 - 10; + localincidence_angle_img.saveImage(sim_localinclocal, max_rows_ids, 0, 1); + incidence_angle_img.saveImage(sim_inclocal, max_rows_ids, 0, 1); + } + + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + line_invert = int(200000000 / dem_img.width);// 基本大小 + for (int max_rows_ids = 1; max_rows_ids < dem_img.height; max_rows_ids = max_rows_ids + line_invert) { + start_ids = max_rows_ids - 1; + Eigen::MatrixXd demdata = dem_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_r = sim_r_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1).cast(); // + Eigen::MatrixXd sim_inclocal = incidence_angle_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + //sim_r = sim_r.array() * (1 / PRF) + imgstarttime; + int rowcount = demdata.rows(); + int colcount = demdata.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + // sataState = + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + long double r; + for (int j = 1; j < colcount - 1; j++) { + r = sim_r(i, j); + Eigen::MatrixX sataState = this->pstn.orbit.SatelliteSpacePoint(r / PRF + imgstarttime); + p0 = dem_img.getLandPoint(i + start_ids, j, demdata(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, demdata(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, demdata(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, demdata(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, demdata(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + sim_localinclocal(i, j) = getlocalIncAngle(satepoint, landpoint, slopeVector); + //p0.ati = 0; + p0 = dem_img.getLandPoint(i + start_ids, j, demdata(i, j)); // 中心 + landpoint = LLA2XYZ(p0); + sim_inclocal(i, j) = getIncAngle(satepoint, landpoint); + } + } + int rows_save = sim_inclocal.rows() - 2; + //sim_inclocal =.array(); + //sim_localinclocal = .array(); + omp_set_lock(&lock); //获得互斥器 + count_lines = count_lines + line_invert; + localincidence_angle_img.saveImage(sim_localinclocal.block(1, 0, rows_save, line_width), max_rows_ids, 0, 1); + incidence_angle_img.saveImage(sim_inclocal.block(1, 0, rows_save, line_width), max_rows_ids, 0, 1); + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "the incidence angle and local incidence over:\t" << getCurrentTimeString() << std::endl; + return 0; +} +/// +/// 模拟WGS坐标下 SAR值 +/// +/// +int simProcess::SARSimulationWGS() +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage localincidence_angle_img(this->out_localIncidenct_path); + gdalImage sim_sar_img = CreategdalImage(this->sar_sim_wgs_path, localincidence_angle_img.height, localincidence_angle_img.width, 1, localincidence_angle_img.gt, localincidence_angle_img.projection);// 注意这里保留仿真结果 + int line_invert = int(5000000 / localincidence_angle_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = localincidence_angle_img.width; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < sim_sar_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids, 0, line_invert, line_width, 1); + Eigen::MatrixXd sim_sar(line_invert, line_width); + sim_localinclocal = sim_localinclocal.array() * d2r; + // double((0.0133 * cos(localincangle) / pow(sin(localincangle + 0.1 * localincangle), 3))); + Eigen::MatrixXd cos_angle = sim_localinclocal.array().cos(); + Eigen::MatrixXd sin_angle = sim_localinclocal.array().sin(); + sim_sar = (0.0133 * cos_angle.array()) / ((sin_angle.array() + 0.1 * cos_angle.array()).pow(3)); + omp_set_lock(&lock); //获得互斥器 + count_lines = count_lines + line_invert; + sim_sar_img.saveImage(sim_sar, max_rows_ids, 0, 1); + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << sim_sar_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + + return 0; +} + +int simProcess::SARSimulation() +{ + std::cout << "computer the simulation value of sim_sar, begining:\t" << getCurrentTimeString() << endl; + gdalImage sim_sar_wgs_img(this->sar_sim_wgs_path); + gdalImage sim_rc(this->dem_rc_path); + gdalImage localIncident_img(this->out_localIncidenct_path); + gdalImage sim_sar_img = CreategdalImage(this->sar_sim_path, this->pstn.height, this->pstn.width, 1, sim_sar_wgs_img.gt, sim_sar_wgs_img.projection, false);// 注意这里保留仿真结果 + { + sim_sar_img.setNoDataValue(-9999, 1); + //double PRF = this->pstn.PRF; + //double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(30000000 / sim_sar_wgs_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = sim_sar_wgs_img.width; + Eigen::MatrixXd sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd sim_sum_h(line_invert, line_width); + Eigen::MatrixXd sim_rsc_orth(line_invert, line_width); + Eigen::MatrixXd sim_sum_sar(line_invert, line_width); + Eigen::MatrixXd demdata(line_invert, line_width); + Eigen::MatrixXd angle(line_invert, line_width); + + // 初始化 + do { + sim_sum_sar = sim_sar_img.getData(start_ids, 0, line_invert, this->pstn.width, 1).cast(); + sim_sum_sar = sim_sum_sar.array() * 0; + sim_sar_img.saveImage(sim_sum_sar, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + { + // 累加计算模拟值 + int rowcount = 0, colcount = 0; + int row_min = 0, row_max = 0; + start_ids = 0; + std::cout << "time:\tsim_arr_row_min\tsim_arr_row_max\tsim_arr_all_lines\tsim_row_min\tsim_row_max\tsim_row_min0\tsim_row_max0" << std::endl;; + do { + std::cout << "\n" << getCurrentTimeString() << "\t" << start_ids << "\t" << start_ids + line_invert << "\t" << sim_rc.height << "\t"; + sim_r = sim_rc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 行 + sim_c = sim_rc.getData(start_ids, 0, line_invert, line_width, 2).cast(); // 列 + angle = localIncident_img.getData(start_ids, 0, line_invert, line_width, 1).cast(); + sim_rsc_orth = sim_sar_wgs_img.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + // 范围 + row_min = (floor(sim_r.minCoeff())); + row_max = (ceil(sim_r.maxCoeff())); + std::cout << row_min << "\t" << row_max << "\t"; + + //std::cout << "line range:\t" << row_min << " - " << row_max << "\t computing.....\t" << getCurrentTimeString() << endl; + + if (row_max < 0 || row_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + row_min = row_min <= 0 ? 0 : row_min; + row_max = row_max >= this->pstn.height ? this->pstn.height : row_max; + std::cout << row_min << "\t" << row_max << std::endl; + //sim_sum_sar =sim_sar.getData(row_min, 0, row_max-row_min+1, this->pstn.width, 1).cast(); + //sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + if (row_min >= row_max) { + break; + } + sim_sum_sar = sim_sar_img.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 1).cast(); + rowcount = sim_r.rows(); + colcount = sim_r.cols(); + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 0; i < rowcount; i++) { + int row_ids = 0, col_ids = 0; + for (int j = 0; j < colcount; j++) { + row_ids = int(round(sim_r(i, j))); + col_ids = int(round(sim_c(i, j))); + if (row_ids >= 0 && row_ids < this->pstn.height && col_ids >= 0 && col_ids < this->pstn.width && (angle(i, j) < 90 || angle(i, j) > 270)) { + sim_sum_sar(row_ids - row_min, col_ids) += sim_rsc_orth(i, j); + } + } + } + sim_sar_img.saveImage(sim_sum_sar, row_min, 0, 1); + + start_ids = start_ids + line_invert; + } while (start_ids < sim_rc.height); + std::cout << "\ncomputer the simulation value of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + } + + { + std::cout << "Resample simulation value of sim_sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(this->sar_sim_path.c_str(), 1, GRIORA_Bilinear); + } + + return 0; +} + +int simProcess::in_sar_power() +{ + std::cout << "compute the power value of ori sar, beiging:\t" << getCurrentTimeString() << endl; + gdalImage ori_sar(this->in_sar_path); + gdalImage sim_power = CreategdalImage(this->sar_power_path, ori_sar.height, ori_sar.width, 1, ori_sar.gt, ori_sar.projection); + sim_power.setNoDataValue(-9999, 1); + { + Eigen::MatrixXd band1(1, 1); + Eigen::MatrixXd band2(1, 1); + Eigen::MatrixXd power_value(1, 1); + int start_ids = 0; + int line_invert = int(8000000 / ori_sar.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + std::cout << "rows:\t" << start_ids << "/" << ori_sar.height << "\t computing.....\t" << getCurrentTimeString() << endl; + band1 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 1).cast(); // a + band2 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 2).cast(); // b + power_value = (band1.array().pow(2) + band2.array().pow(2) + 1).log10() * 10;// 10 * Eigen::log10(Eigen::pow(0.5, Eigen::pow(2, band1.array()) + Eigen::pow(2, band2.array()))).array(); + sim_power.saveImage(power_value, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < ori_sar.height); + } + { + std::cout << "Resample the power value of ori sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(this->sar_power_path.c_str(), 1, GRIORA_Bilinear); + } + std::cout << "compute the power value of ori sar, ending:\t" << getCurrentTimeString() << endl; + { + std::cout << "=========================================\n"; + std::cout << " the power image of sar :\n"; + std::cout << this->sar_power_path.c_str() << "\n"; + std::cout << "band 1 : power value \t 10*log10(b1^2+b2^2) \n"; + std::cout << "=========================================\n"; + + } + return 0; + return 0; +} + + + + +int simProcess::Scatter2Grid(std::string lon_lat_path, std::string data_tiff, std::string grid_path, double space) { + + gdalImage lon_lat_img(lon_lat_path); + double min_lon = 400, max_lon = -400, min_lat = 300, max_lat = -300; + { + int conver_lines = 2000; + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + conver_lines) { + Eigen::MatrixXd lon = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + Eigen::MatrixXd lat = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 2); + int rows = lon.rows(); + int cols = lon.cols(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (min_lon > lon(i, j) && !isnan(lon(i, j)) && lon(i, j) > -200) { + min_lon = lon(i, j); + } + if (min_lat > lat(i, j) && !isnan(lat(i, j)) && lat(i, j) > -200) { + min_lat = lat(i, j); + } + if (max_lon < lon(i, j) && !isnan(lon(i, j)) && lon(i, j) > -200) { + max_lon = lon(i, j); + } + + if (max_lat < lat(i, j) && !isnan(lat(i, j)) && lat(i, j) > -200) { + max_lat = lat(i, j); + } + } + } + } + } + std::cout << "lon:\t" << min_lon << " , " << max_lon << endl; + std::cout << "lat:\t" << min_lat << " , " << max_lat << endl; + + double delta = space /( 110 * 1000); + int width = int((max_lon - min_lon) / delta) + 1; + int height = int((max_lat - min_lat) / delta) + 1; + Eigen::MatrixXd gt(2, 3); + gt(0, 0) = min_lon; gt(0, 1) = delta; gt(0, 2) = 0;//x + gt(1, 0) = max_lat; gt(1, 1) = 0; gt(1, 2) = -1*delta;//y + + // # + char* pszSrcWKT = NULL; + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + //oSRS.SetUTM(50, true); //北半球 东经120度 + //oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + gdalImage grid_img = CreategdalImage(grid_path, height, width, 1, gt, pszSrcWKT, true); + int conver_lines = 2000; + for (int max_rows_ids = 0; max_rows_ids < grid_img.height; max_rows_ids = max_rows_ids + conver_lines) { + Eigen::MatrixXd grid_data = grid_img.getData(max_rows_ids, 0, conver_lines, width, 1); + grid_data = grid_data.array() * 0 - 9999; + grid_img.saveImage(grid_data, max_rows_ids, 0, 1); + } + grid_img.setNoDataValue(-9999, 1); + Eigen::MatrixXd grid_data = grid_img.getData(0, 0, grid_img.height, grid_img.width, 1); + gdalImage Range_data(data_tiff); + grid_img.InitInv_gt(); + { + int conver_lines = 500; + int line_invert = 400;// 计算重叠率 + int line_offset = 60; + // 逐区域迭代计算 + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + int allCount = 0; + + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd lon_data = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + Eigen::MatrixXd lat_data = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 2); + Eigen::MatrixXd data = Range_data.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + int lon_row_count = lon_data.rows(); + for (int i = 0; i < lon_row_count; i++) { + for (int j = 0; j < lon_lat_img.width; j++) { + Landpoint p = grid_img.getRow_Col(lon_data(i, j), lat_data(i, j)); + lon_data(i, j) = p.lon; + lat_data(i, j) = p.lat; + } + } + int dem_rows_num = lon_data.rows(); + int dem_cols_num = lon_data.cols(); + + #pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < dem_rows_num - 1; i++) { + for (int j = 0; j < dem_cols_num - 1; j++) { + Point_3d p, p1, p2, p3, p4; + + p1 = { lat_data(i,j),lon_data(i,j) }; + p2 = { lat_data(i,j + 1),lon_data(i,j + 1) }; + p3 = { lat_data(i + 1, j + 1),lon_data(i + 1, j + 1) }; + p4 = { lat_data(i + 1, j),lon_data(i + 1, j) }; + + //if (angle(i, j) >= 90 && angle(i, j + 1) >= 90 && angle(i + 1, j) >= 90 && angle(i + 1, j + 1) >= 90) { + // continue; + //} + + double temp_min_r = lat_data.block(i, j, 2, 2).minCoeff(); + double temp_max_r = lat_data.block(i, j, 2, 2).maxCoeff(); + double temp_min_c = lon_data.block(i, j, 2, 2).minCoeff(); + double temp_max_c = lon_data.block(i, j, 2, 2).maxCoeff(); + if ((int(temp_min_r) != int(temp_max_r)) && (int(temp_min_c) != int(temp_max_c))) { + for (int ii = int(temp_min_r); ii <= temp_max_r + 1; ii++) { + for (int jj = int(temp_min_c); jj < temp_max_c + 1; jj++) { + if (ii < 0 || ii >= height || jj < 0 || jj >= width) { + continue; + } + p = { double(ii),double(jj),0 }; + //if (PtInRect(p, p1, p2, p3, p4)) { + p1.z = data(i, j); + p2.z = data(i, j + 1); + p3.z = data(i + 1, j + 1); + p4.z = data(i + 1, j); + + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + if (p.x < 0) { + continue; + } + double mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + grid_data(ii , jj) = p.z; + //} + } + } + } + } + } + allCount = allCount + line_invert; + std::cout << "rows:\t" << allCount << "/" << lon_lat_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + } + } + grid_img.saveImage(grid_data, 0, 0, 1); + return 0; +} + + + +/* +描述:判断点是否在四边形内,该函数也适用于多边形,将点数改成你想要的边数就行 +参数: + pCur:当前点 + pLeftTop:左上角 + pRightTop:右上角 + pRightBelow:右下 + pLeftBelow:左下 +返回值:如果在四边形内返回 true ,否则返回 false +*/ + +bool PtInRect(Point_3d pCur, Point_3d pLeftTop, Point_3d pRightTop, Point_3d pRightBelow, Point_3d pLeftBelow) +{ + int nCount = 4;//任意四边形有4个顶点 + Point_3d RectPoints[4] = { pLeftTop, pLeftBelow, pRightBelow, pRightTop }; + int nCross = 0; + double lastPointX = -999.999; + for (int i = 0; i < nCount; i++) + { + //依次取相邻的两个点 + Point_3d pBegin = RectPoints[i]; + Point_3d pEnd = RectPoints[(i + 1) % nCount]; + //相邻的两个点是平行于x轴的,当前点和x轴的平行线要么重合,要么不相交,不算 + if (pBegin.y == pEnd.y)continue; + //交点在pBegin,pEnd的延长线上,不算 + if (pCur.y < min(pBegin.y, pEnd.y) || pCur.y > max(pBegin.y, pEnd.y))continue; + //当前点和x轴的平行线与pBegin,pEnd直线的交点的x坐标 + double x = (double)(pCur.y - pBegin.y) * (double)(pEnd.x - pBegin.x) / (double)(pEnd.y - pBegin.y) + pBegin.x; + if (x > pCur.x)//只看pCur右边交点 + { + if (x != lastPointX)//防止角点算两次 + { + nCross++; + lastPointX = x; + } + } + } + // 单方向交点为奇数,点在多边形之内 + // 单方向交点为偶数,点在多边形之外 + return (nCross % 2 == 1); +} + +int simProcess::ReflectTable_WGS2Range() +{// + gdalImage sim_rc(this->dem_rc_path); + gdalImage sim_sar_img = CreategdalImage(this->out_ori_sim_tiff, this->pstn.height, this->pstn.width, 2, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + gdalImage sim_sar_count_img = CreategdalImage(this->ori_sim_count_tiff, this->pstn.height, this->pstn.width, 1, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + gdalImage localIncident_img(this->out_localIncidenct_path); + for (int max_rows_ids = 0; max_rows_ids < this->pstn.height; max_rows_ids = max_rows_ids + 1000) { + Eigen::MatrixXd sim_sar = sim_sar_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 1); + Eigen::MatrixXd sim_sarc = sim_sar_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 2); + Eigen::MatrixXd sim_sar_count = sim_sar_count_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 1); + sim_sar = sim_sar.array() * 0 - 9999; + sim_sarc= sim_sar.array() * 0 - 9999; + sim_sar_count = sim_sar_count.array() * 0; + sim_sar_img.saveImage(sim_sar, max_rows_ids, 0, 1); + sim_sar_img.saveImage(sim_sarc, max_rows_ids, 0, 2); + sim_sar_count_img.saveImage(sim_sar_count, max_rows_ids, 0, 1); + } + sim_sar_img.setNoDataValue(-9999, 1); + sim_sar_img.setNoDataValue(-9999, 2); + int conver_lines = 5000; + int line_invert = 4000;// 计算重叠率 + int line_offset = 60; + // 逐区域迭代计算 + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + int allCount = 0; + + for (int max_rows_ids = 0; max_rows_ids < sim_rc.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd angle = localIncident_img.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 1).cast(); + Eigen::MatrixXd dem_r = sim_rc.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 1); + Eigen::MatrixXd dem_c = sim_rc.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 2); + int dem_rows_num = dem_r.rows(); + int dem_cols_num = dem_r.cols(); + // 更新插值经纬度 + //Eigen::MatrixXd dem_lon = dem_r; + //Eigen::MatrixXd dem_lat = dem_c; + // 构建索引 更新经纬度并更新链 + + int temp_r, temp_c; + + /* int min_row = dem_r.minCoeff() + 1; + int max_row = dem_r.maxCoeff() + 1; + + if (max_row < 0) { + continue; + }*/ + + int min_row = dem_r.minCoeff() + 1; + int max_row = dem_r.maxCoeff() + 1; + int min_col = dem_c.minCoeff() + 1; + int max_col = dem_c.maxCoeff() + 1; + if (max_row < 0 || min_row >= this->pstn.height || max_col < 0 || min_col >= this->pstn.width) { // 增加边界判断条件 + continue; + } + + int len_rows = max_row - min_row; + min_row = min_row < 0 ? 0 : min_row; + Eigen::MatrixXd sar_r = sim_sar_img.getData(min_row, 0, len_rows, this->pstn.width, 1); + Eigen::MatrixXd sar_c = sim_sar_img.getData(min_row, 0, len_rows, this->pstn.width, 2); + len_rows = sar_r.rows(); + + + #pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < dem_rows_num - 1; i++) { + for (int j = 0; j < dem_cols_num - 1; j++) { + Point_3d p, p1, p2, p3, p4; + Landpoint lp1, lp2, lp3, lp4; + lp1 = sim_rc.getLandPoint(i + max_rows_ids, j, 0); + lp2 = sim_rc.getLandPoint(i + max_rows_ids, j + 1, 0); + lp3 = sim_rc.getLandPoint(i + 1 + max_rows_ids, j + 1, 0); + lp4 = sim_rc.getLandPoint(i + 1 + max_rows_ids, j, 0); + + p1 = { dem_r(i,j),dem_c(i,j) }; + p2 = { dem_r(i,j + 1),dem_c(i,j + 1) }; + p3 = { dem_r(i + 1,j + 1),dem_c(i + 1,j + 1) }; + p4 = { dem_r(i + 1,j),dem_c(i + 1,j) }; + + //if (angle(i, j) >= 90 && angle(i, j + 1) >= 90 && angle(i + 1, j) >= 90 && angle(i + 1, j + 1) >= 90) { + // continue; + //} + + double temp_min_r = dem_r.block(i, j, 2, 2).minCoeff(); + double temp_max_r = dem_r.block(i, j, 2, 2).maxCoeff(); + double temp_min_c = dem_c.block(i, j, 2, 2).minCoeff(); + double temp_max_c = dem_c.block(i, j, 2, 2).maxCoeff(); + if ((int(temp_min_r) != int(temp_max_r)) && (int(temp_min_c) != int(temp_max_c))) { + for (int ii = int(temp_min_r); ii <= temp_max_r + 1; ii++) { + for (int jj = int(temp_min_c); jj < temp_max_c + 1; jj++) { + if (ii < min_row || ii - min_row >= len_rows || jj < 0 || jj >= this->pstn.width) { + continue; + } + p = { double(ii),double(jj),-9999 }; + //if (PtInRect(p, p1, p2, p3, p4)) { + p1.z = lp1.lon; + p2.z = lp2.lon; + p3.z = lp3.lon; + p4.z = lp4.lon; + + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + + if (p.x < 0) { + continue; + } + double mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + sar_r(ii - min_row, jj) = p.z; + p1.z = lp1.lat; + p2.z = lp2.lat; + p3.z = lp3.lat; + p4.z = lp4.lat; + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + + if (p.x < 0) { + continue; + } + mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + sar_c(ii - min_row, jj) = p.z; + //} + } + } + + } + } + } + + omp_set_lock(&lock); //获得互斥器 + sim_sar_img.saveImage(sar_r, min_row, 0, 1); + sim_sar_img.saveImage(sar_c, min_row, 0, 2); + allCount = allCount + conver_lines; + std::cout << "rows:\t" << allCount << "/" << sim_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + + std::cout << "\t resample computing.....\t" << getCurrentTimeString() << endl; + { int conver = 5000; + int line_invert = 4000;// 计算重叠率 + ResampleGDALs(this->out_ori_sim_tiff.c_str(), 1, GRIORA_Bilinear); + ResampleGDALs(this->out_ori_sim_tiff.c_str(), 2, GRIORA_Bilinear); + } + + return 0; +} + +int simProcess::InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_paths, std::string out_inc_angle_path, std::string out_local_inc_angle_path, std::string out_inc_angle_geo_path, std::string out_local_inc_angle_geo_path) +{ + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + + this->in_rpc_lon_lat_path = in_rpc_lon_lat_paths; + this->in_dem_path = in_dem_path; + this->outSpace_path = out_dir_path; + this->workSpace_path = workspace_path; + + // 临时文件 + this->dem_path = JoinPath(this->workSpace_path, "SAR_dem.tiff"); + this->dem_rc_path = JoinPath(this->workSpace_path, "dem_rc.tiff"); + this->dem_r_path = JoinPath(this->workSpace_path, "dem_r.tiff"); + this->out_incidence_path = out_inc_angle_geo_path; + this->out_localIncidenct_path = out_local_inc_angle_geo_path; + this->rpc_wgs_path = JoinPath(this->workSpace_path, "rcp2dem_wgs.tiff"); + // 输出文件 + this->out_inc_angle_rpc_path = out_inc_angle_path; + this->out_local_inc_angle_rpc_path = out_local_inc_angle_path; + + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_rpc_lon_lat_path" << ":\t" << this->in_rpc_lon_lat_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "out_dir_path" << ":\t" << this->out_dir_path << endl; + std::cout << "out_inc_angle_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_local_inc_angle_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->createRPCDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + this->SARIncidentAngle_RPC(); + this->in_sar_power(); + return 0; + return 0; +} + +int simProcess::dem2SAR_row() +{ + + std::cout << "the row of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_clip(this->dem_path); + double dem_mean = dem_clip.mean(); + gdalImage sim_r_reprocess = CreategdalImage(this->dem_r_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + gdalImage sim_rc_reprocess = CreategdalImage(this->dem_rc_path, dem_clip.height, dem_clip.width, 2, dem_clip.gt, dem_clip.projection); + int line_invert = int(15000000 / dem_clip.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); + + Eigen::MatrixXd sim_r = demdata.array() * 0; + Eigen::MatrixXd sim_c = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + //landpoint.col(2) = landpoint.col(2).array() * 0; + landpoint = LLA2XYZ(landpoint); + landpoint = this->pstn.PSTN(landpoint, dem_mean); // time,r,c + //std::cout << "for time " << getCurrentTimeString() << std::endl; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + sim_r(i, j) = landpoint(i * datacols + j, 1); + sim_c(i, j) = landpoint(i * datacols + j, 2); + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + sim_r_reprocess.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc_reprocess.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc_reprocess.saveImage(sim_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "dem2SAR_Row_col dem_2_sarRC over " << getCurrentTimeString() << std::endl; + + std::cout << "=========================================\n"; + std::cout << "the row and col of the sar in dem:\n"; + std::cout << this->dem_r_path << "\n"; + std::cout << "band 1 : the row of the sar \n"; + std::cout << "=========================================\n"; + } + return 0; +} + +/// +/// 计算RPC的入射角 +/// +/// +int simProcess::SARIncidentAngle_RPC() { + this->calGEC_Incident_localIncident_angle(this->dem_path, this->in_rpc_lon_lat_path, this->out_inc_angle_rpc_path, this->out_local_inc_angle_rpc_path, this->pstn); + return 0; +} + +int simProcess::createRPCDEM() +{ + std::cout << "dem2SAR_Row_col begin time:" << getCurrentTimeString() << std::endl; + { + gdalImage dem(this->in_dem_path); + gdalImage lonlat(this->in_rpc_lon_lat_path); + DemBox box{ 9999,9999,-9999,-9999 }; + { + int start_ids = 0; + int line_invert = int(4000000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + for (start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) { + std::cout << "rows:\t" << start_ids << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd lon = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd lat = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 2); + double min_lat = lat.array().minCoeff(); + double max_lat = lat.array().maxCoeff(); + double min_lon = lon.array().minCoeff(); + double max_lon = lon.array().maxCoeff(); + box.min_lat = min_lat < box.min_lat ? min_lat : box.min_lat; + box.max_lat = max_lat > box.max_lat ? max_lat : box.max_lat;; + box.min_lon = min_lon < box.min_lon ? min_lon : box.min_lon;; + box.max_lon = max_lon > box.max_lon ? max_lon : box.max_lon;; + + } + } + std::cout << "prepare over" << getCurrentTimeString() << std::endl; + double dist_lat = box.max_lat - box.min_lat; + double dist_lon = box.max_lon - box.min_lon; + dist_lat = 0.1 * dist_lat; + dist_lon = 0.1 * dist_lon; + box.min_lat = box.min_lat - dist_lat; + box.max_lat = box.max_lat + dist_lat; + box.min_lon = box.min_lon - dist_lon; + box.max_lon = box.max_lon + dist_lon; + + std::cout << "box:" << endl; + std::cout << "min_lat-max_lat:\t" << box.min_lat << "\t" << box.max_lat << endl; + std::cout << "min_lon-max_lon:\t" << box.min_lon << "\t" << box.max_lon << endl; + std::cout << "cal box of sar over" << endl; + + // 计算采样之后的影像大小 + int width = 1.5 * this->pstn.width; + int height = 1.5 * this->pstn.height; + + double heightspace = (box.max_lat - box.min_lat) / height; + double widthspace = (box.max_lon - box.min_lon) / width; + std::cout << "resample dem:\n" << getCurrentTimeString() << std::endl; + std::cout << "in_dem:\t" << this->in_dem_path << endl; + std::cout << "out_dem:\t" << this->dem_path << endl; + std::cout << "width-height:\t" << width << "-" << height << endl; + std::cout << "widthspace\t-\theight\tspace:\t" << widthspace << "\t-\t" << heightspace << endl; + + int pBandIndex[1] = { 1 }; + int pBandCount[1] = { 1 }; + + double gt[6] = { + box.min_lon,widthspace,0, //x + box.max_lat,0,-heightspace//y + }; + + //boost::filesystem::copy(dem_path, this->dem_path); + ResampleGDAL(this->in_dem_path.c_str(), this->dem_path.c_str(), gt, width, height, GRA_Bilinear); + + std::cout << "resample dem over:\n" << getCurrentTimeString() << std::endl; + std::cout << "remove sim_rc_path:\t" << this->dem_rc_path << std::endl; + } + + return 0; +} + + +/// +/// 模拟SAR影像 +/// +/// dem影像 +/// rc 影像 +/// 结果:模拟sar影像 +/// 参数类 +/// 执行状态 +int simProcess::sim_SAR(std::string dem_path, std::string sim_rc_path, std::string sim_sar_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage dem_img(dem_path); + gdalImage sim_rc(sim_rc_path); + gdalImage sim_sar = CreategdalImage(sim_sar_path, dem_img.height, dem_img.width, 2, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + sim_sar.setNoDataValue(-9999, 1); + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(50000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + Eigen::MatrixX sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd dem(line_invert, line_width); + Eigen::MatrixXd sim_rsc(line_invert, line_width); + Eigen::MatrixXd sim_inclocal(line_invert, line_width); + + int rowcount = 0, colcount = 0; + //omp_lock_t lock; + //omp_init_lock(&lock); // 初始化互斥锁 + do { + std::cout << "rows:\t" << start_ids << "-" << start_ids + line_invert + 2 << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + dem = dem_img.getData(start_ids, 0, line_invert + 2, line_width, 1); + sim_r = sim_rc.getData(start_ids, 0, line_invert + 2, line_width, 1).cast(); + sim_r = sim_r.array() * (1 / PRF) + imgstarttime; + //sim_c = sim_rc.getData(start_ids, 0, line_invert + 1, line_width, 2); + sim_rsc = dem.array() * 0; + sim_inclocal = dem.array() * 0 - 9999; + rowcount = dem.rows(); + colcount = dem.cols(); + + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + Eigen::MatrixX sataState = sim_r.row(i).reshaped(line_width, 1); + sataState = this->pstn.orbit.SatelliteSpacePoint(sataState); + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle; + for (int j = 1; j < colcount - 1; j++) { + p0 = dem_img.getLandPoint(i + start_ids, j, dem(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, dem(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, dem(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, dem(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, dem(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(j,0),sataState(j,1) ,sataState(j,2) }; + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector); + sim_inclocal(i, j) = localincangle; + if (localincangle < 90) + { + localincangle = localincangle * d2r; + sim_rsc(i, j) = 100 * double((0.0133 * cos(localincangle) / pow(sin(localincangle + 0.1 * localincangle), 3))); + //sim_rsc(i, j) = sim_rsc(i, j) > 100 ? -9999 : sim_rsc(i, j); + } + } + } + //omp_set_lock(&lock); //获得互斥器 + //std::cout << sim_rsc(1, 1961) << endl; + sim_sar.saveImage(sim_rsc.block(1, 0, rowcount - 2, colcount), start_ids + 1, 0, 1); + sim_sar.saveImage(sim_inclocal.block(1, 0, rowcount - 2, colcount), start_ids + 1, 0, 2); + //omp_unset_lock(&lock); //释放互斥器 + start_ids = start_ids + line_invert - 4; + } while (start_ids < dem_img.height); + //omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "computer the simulation value of evering dem meta, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the simulation sar value Raster has the projection that is same of dem" << endl; + std::cout << sim_sar_path << endl; + std::cout << "band 1: the simulation sar value" << endl; + std::cout << "band 2: the local incident angle " << endl; + std::cout << "==========================================================" << endl; + return 0; +} + + +int simProcess::dem2aspect_slope(std::string dem_path, std::string aspect_path, std::string slope_path) +{ + std::cout << "computer aspect and slop begining:\t" << getCurrentTimeString() << endl; + + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* dem = (GDALDataset*)(GDALOpen(dem_path.c_str(), GA_ReadOnly)); + GDALDEMProcessing(aspect_path.c_str(), dem, "aspect", NULL, NULL, NULL); + GDALDEMProcessing(slope_path.c_str(), dem, "slope", NULL, NULL, NULL); + GDALClose(dem); + std::cout << "computer aspect and slop overing:\t" << getCurrentTimeString() << endl; + return 0; +} + +/// +/// 根据前面模拟结果与行列号,生成模拟仿真图,分批生成并计算目标对象 +/// +/// 仿真行列号 +/// 正射单元格结果 +/// 模拟影像路径 +/// +int simProcess::sim_sum_SAR(std::string sim_dem_path, std::string sim_rc_path, std::string sim_orth_path, std::string sim_sum_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of sim_sar, begining:\t" << getCurrentTimeString() << endl; + //gdalImage dem_img(dem_path); + gdalImage sim_rc(sim_rc_path); + gdalImage sim_rsc(sim_orth_path); + gdalImage dem(sim_dem_path); + gdalImage sim_sar = CreategdalImage(sim_sum_path, this->pstn.height, this->pstn.width, 1, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + { + sim_sar.setNoDataValue(-9999, 1); + //double PRF = this->pstn.PRF; + //double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(16000000 / sim_rc.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = sim_rc.width; + Eigen::MatrixX sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd sim_sum_h(line_invert, line_width); + Eigen::MatrixXd sim_rsc_orth(line_invert, line_width); + Eigen::MatrixXd sim_sum_sar(line_invert, line_width); + Eigen::MatrixXd sim_sum_count(line_invert, line_width); + Eigen::MatrixXd demdata(line_invert, line_width); + + // 初始化 + do { + sim_sum_sar = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 1).cast(); + sim_sum_sar = sim_sum_sar.array() * 0; + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 1); + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 2); + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 3); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + { + // 累加计算模拟值 + int rowcount = 0, colcount = 0; + int row_min = 0, row_max = 0; + start_ids = 0; + std::cout << "time:\tsim_arr_row_min\tsim_arr_row_max\tsim_arr_all_lines\tsim_row_min\tsim_row_max\tsim_row_min0\tsim_row_max0" << std::endl;; + + + do { + std::cout << "\n" << getCurrentTimeString() << "\t" << start_ids << "\t" << start_ids + line_invert << "\t" << sim_rc.height << "\t"; + sim_r = sim_rc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 行 + sim_c = sim_rc.getData(start_ids, 0, line_invert, line_width, 2).cast(); // 列 + + sim_rsc_orth = sim_rsc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + demdata = dem.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + // 范围 + row_min = (floor(sim_r.minCoeff())); + row_max = (ceil(sim_r.maxCoeff())); + std::cout << row_min << "\t" << row_max << "\t"; + + //std::cout << "line range:\t" << row_min << " - " << row_max << "\t computing.....\t" << getCurrentTimeString() << endl; + + if (row_max < 0 || row_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + row_min = row_min <= 0 ? 0 : row_min; + row_max = row_max >= this->pstn.height ? this->pstn.height : row_max; + std::cout << row_min << "\t" << row_max << std::endl; + //sim_sum_sar =sim_sar.getData(row_min, 0, row_max-row_min+1, this->pstn.width, 1).cast(); + //sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + if (row_min >= row_max) { + break; + } + sim_sum_sar = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 1).cast(); + sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + sim_sum_h = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 3).cast(); // 列 + rowcount = sim_r.rows(); + colcount = sim_r.cols(); + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 0; i < rowcount; i++) { + int row_ids = 0, col_ids = 0; + for (int j = 0; j < colcount; j++) { + row_ids = int(round(sim_r(i, j))); + col_ids = int(round(sim_c(i, j))); + if (row_ids >= 0 && row_ids < this->pstn.height && col_ids >= 0 && col_ids < this->pstn.width) { + sim_sum_sar(row_ids - row_min, col_ids) += sim_rsc_orth(i, j); + sim_sum_count(row_ids - row_min, col_ids) += 1; + sim_sum_h(row_ids - row_min, col_ids) += demdata(i, j); + } + } + } + sim_sar.saveImage(sim_sum_sar, row_min, 0, 1); + sim_sar.saveImage(sim_sum_count, row_min, 0, 2); + sim_sar.saveImage(sim_sum_h, row_min, 0, 3); + + start_ids = start_ids + line_invert; + } while (start_ids < sim_rc.height); + std::cout << "\ncomputer the simulation value of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + } + { + std::cout << "computer the height of sim_sar, begining :\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sim_sum_h(1, 1); + Eigen::MatrixXd sim_sum_count(1, 1); + + int start_ids = 0; + int line_invert = int(8000000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + sim_sum_count = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 2).cast(); // 行 + sim_sum_h = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 3).cast(); // 列 + row_count = sim_sum_h.rows(); + col_count = sim_sum_h.cols(); + std::cout << "min~max:" << endl; + std::cout << sim_sum_count.minCoeff() << "\t" << sim_sum_count.maxCoeff() << endl; + std::cout << sim_sum_h.minCoeff() << "\t" << sim_sum_h.maxCoeff() << endl; + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + if (sim_sum_count(i, j) == 0) { + sim_sum_h(i, j) = 0; + } + else { + sim_sum_h(i, j) = sim_sum_h(i, j) / sim_sum_count(i, j); + } + } + } + sim_sar.saveImage(sim_sum_h, start_ids, 0, 3); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + + std::cout << "computer the height of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + + { + std::cout << "compute the average value of sim_sar, beiging:\t" << getCurrentTimeString() << endl; + + //ResampleGDALs(sim_sum_path.c_str(), 1, GRIORA_Bilinear); + //ResampleGDALs(sim_sum_path.c_str(), 3, GRIORA_Bilinear); + std::cout << "compute the average value of sim_sar, over :\t" << getCurrentTimeString() << endl; + } + { + std::cout << "=========================================\n"; + std::cout << "sim_sar_tif infomation :\n"; + std::cout << sim_sum_path << "\n"; + std::cout << "band 1 : simulation sar value \n"; + std::cout << "band 2 : the sum of the effective value from the dem \n"; + std::cout << "band 3 : the dem altitude of the effective value from the dem \n"; + std::cout << "=========================================\n"; + + } + return 0; +} + + +/// +/// 计算 +/// +/// +/// +/// +int simProcess::ori_sar_power(std::string ori_sar_path, std::string out_sar_power_path) +{ + std::cout << "compute the power value of ori sar, beiging:\t" << getCurrentTimeString() << endl; + gdalImage ori_sar(ori_sar_path); + gdalImage sim_power = CreategdalImage(out_sar_power_path, ori_sar.height, ori_sar.width, 1, ori_sar.gt, ori_sar.projection); + sim_power.setNoDataValue(-9999, 1); + { + Eigen::MatrixXd band1(1, 1); + Eigen::MatrixXd band2(1, 1); + Eigen::MatrixXd power_value(1, 1); + int start_ids = 0; + int line_invert = int(8000000 / ori_sar.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + std::cout << "rows:\t" << start_ids << "/" << ori_sar.height << "\t computing.....\t" << getCurrentTimeString() << endl; + band1 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 1).cast(); // a + band2 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 2).cast(); // b + //power_value = band2.array() * 0-9999; + power_value = (band1.array().pow(2) + band2.array().pow(2) + 1).log10() * 10;// 10 * Eigen::log10(Eigen::pow(0.5, Eigen::pow(2, band1.array()) + Eigen::pow(2, band2.array()))).array(); + //if () { + // + //}// power_value.isNaN()) + //std::cout << power_value.minCoeff() << "\t" << power_value.maxCoeff() << "\t" << endl; + //std::cout << "band 1\t" << band1.minCoeff() << "\t" << band1.maxCoeff() << "\t" << endl; + //std::cout << "band 2\t" << band2.minCoeff() << "\t" << band2.maxCoeff() << "\t" << endl; + sim_power.saveImage(power_value, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < ori_sar.height); + } + { + std::cout << "Resample the power value of ori sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(out_sar_power_path.c_str(), 1, GRIORA_Cubic); + } + std::cout << "compute the power value of ori sar, ending:\t" << getCurrentTimeString() << endl; + { + std::cout << "=========================================\n"; + std::cout << " the power image of sar :\n"; + std::cout << out_sar_power_path << "\n"; + std::cout << "band 1 : power value \t 10*log10(b1^2+b2^2) \n"; + std::cout << "=========================================\n"; + + } + return 0; +} + +int simProcess::createImageMatchModel(std::string ori_sar_rsc_path, std::string ori_sar_rsc_jpg_path, std::string sim_sar_path, std::string sim_sar_jpg_path, std::string matchmodel_path) +{ + // 转换影像 + { + std::cout << "compute the power value of sar, begining:\t" << getCurrentTimeString() << endl; + this->matchmodel.gdal2JPG(ori_sar_rsc_path, ori_sar_rsc_jpg_path, 1); + this->matchmodel.gdal2JPG(sim_sar_path, sim_sar_jpg_path, 1); + std::cout << "compute the power value of sar, ending:\t" << getCurrentTimeString() << endl; + } + // 构建匹配模型 + { + this->matchmodel.offsetXY_matrix = this->matchmodel.ImageMatch_ori_sim(ori_sar_rsc_jpg_path, sim_sar_jpg_path); + if (this->matchmodel.offsetXY_matrix.rows() < 7) { // 无法进行精校准 + this->isMatchModel = false; + } + else { + //this->matchmodel.match_model = this->matchmodel.CreateMatchModel(this->matchmodel.offsetXY_matrix); + //this->matchmodel.outMatchModel(matchmodel_path); + } + } + return 0; +} + + +/// +/// 根据精确匹配得到的纠正模型,纠正坐标偏移 +/// +/// +/// +/// +int simProcess::correctOrth_rc(std::string sim_rc_path, ImageMatch matchmodel) +{ + gdalImage sim_rc(sim_rc_path); + { + int lineVert = (1000000 / sim_rc.width); + int start_ids = 0; + do { + Eigen::MatrixXd sim_r = sim_rc.getData(start_ids, 0, lineVert, sim_rc.width, 1); + Eigen::MatrixXd sim_c = sim_rc.getData(start_ids, 0, lineVert, sim_rc.width, 2); + // 计算偏移结果 + int rowcount = sim_r.rows(); + int colcount = sim_r.cols(); + for (int i = 0; i < rowcount; i++) { + Eigen::MatrixXd temp = matchmodel.correctMatchModel(sim_r.row(i), sim_c.col(i)); + sim_r.row(i) = temp.row(0).array(); + sim_c.row(i) = temp.row(1).array(); + } + + // 写入影像 + sim_rc.saveImage(sim_r, start_ids, 0, 1); + sim_rc.saveImage(sim_c, start_ids, 0, 2); + start_ids = start_ids + lineVert; + } while (start_ids < sim_rc.height); + } + return 0; +} + +/// +/// +/// +/// +/// +/// 输出内入射角 +/// 输出dem +/// count的tif +/// +int simProcess::correct_ati(std::string orth_rc_path, std::string dem_path, std::string out_inclocal_path, std::string out_dem_path, std::string out_count_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage dem_img(dem_path); + gdalImage orth_rc(orth_rc_path); + + //gdalImage ori_inclocal = CreategdalImage(out_inclocal_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真结果 + gdalImage ori_dem = CreategdalImage(out_dem_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真结果 + gdalImage ori_count = CreategdalImage(out_count_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真 + + + // 初始化 + { + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_dem = ori_dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + //Eigen::MatrixXd sar_inclocal = ori_inclocal.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_count = ori_count.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_dem = sar_dem.array() * 0; + //sar_inclocal = sar_inclocal.array() * 0; + sar_count = sar_count.array() * 0; + + ori_dem.saveImage(sar_dem, start_ids, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, start_ids, 0, 1); + ori_count.saveImage(sar_count, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + { + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(50000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + Eigen::MatrixX sar_r(line_invert, line_width); + Eigen::MatrixXd sar_c(line_invert, line_width); + Eigen::MatrixXd dem(line_invert, line_width); + Eigen::MatrixXd sar_dem; + Eigen::MatrixXd sar_inclocal; + Eigen::MatrixXd sar_count; + + int rowcount = 0, colcount = 0; + int r_min, r_max, c_min, c_max; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + do { + std::cout << "rows:\t" << start_ids << "-" << start_ids + line_invert + 2 << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + dem = dem_img.getData(start_ids, 0, line_invert + 2, line_width, 1); + sar_r = orth_rc.getData(start_ids, 0, line_invert + 2, line_width, 1).cast(); + sar_c = orth_rc.getData(start_ids, 0, line_invert + 2, line_width, 2).cast(); + + r_min = int(floor(sar_r.minCoeff())); + r_max = int(ceil(sar_r.maxCoeff())); + + c_min = int(floor(sar_c.minCoeff())); + c_max = int(ceil(sar_c.maxCoeff())); + + + // 计算数据结果 + rowcount = r_max - r_min + 1; + colcount = c_max - c_min + 1; + + if (r_max < 0 || r_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + r_min = r_min <= 0 ? 0 : r_min; + r_max = r_max >= this->pstn.height ? this->pstn.height : r_max; + + sar_dem = ori_dem.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); + sar_count = ori_count.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); + //sar_inclocal = ori_inclocal.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); // 列 + + rowcount = dem.rows(); + colcount = dem.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + Eigen::MatrixX sataState = sar_r.row(i).reshaped(line_width, 1).array() * (1 / PRF) + imgstarttime; + sataState = this->pstn.orbit.SatelliteSpacePoint(sataState); + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle; + int r, c; + for (int j = 1; j < colcount - 1; j++) { + p0 = dem_img.getLandPoint(i + start_ids, j, dem(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, dem(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, dem(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, dem(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, dem(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(j,0),sataState(j,1) ,sataState(j,2) }; + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector); + + if (localincangle < 90) + { + r = sar_r(i, j); + c = sar_c(i, j); + if (r >= 0 && r < this->pstn.height && c >= 0 && c < this->pstn.width) { + //sar_inclocal(r - r_min, c) += localincangle; + sar_count(r - r_min, c) += 1; + sar_dem(r - r_min, c) += dem(i, j); + } + } + } + } + //std::cout << sim_rsc(1, 1961) << endl; + ori_dem.saveImage(sar_dem, r_min, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, r_min, 0, 1); + ori_count.saveImage(sar_count, r_min, 0, 1); + start_ids = start_ids + line_invert - 4; + } while (start_ids < dem_img.height); + omp_destroy_lock(&lock); //销毁互斥器 + } + + // 平均化 + { + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_dem = ori_dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + //Eigen::MatrixXd sar_inclocal = ori_inclocal.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_count = ori_count.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_dem = sar_dem.array() / sar_count.array(); + //sar_inclocal = sar_inclocal.array() / sar_count.array(); + + ori_dem.saveImage(sar_dem, start_ids, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, start_ids, 0, 1); + + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + std::cout << "repair dem by resample, begining:\t" << getCurrentTimeString() << endl; + { + + + } + std::cout << "repair dem by resample, overing:\t" << getCurrentTimeString() << endl; + + std::cout << "correct the evering dem meta, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the dem of sar:\t" << out_dem_path << endl; + std::cout << "the local incident angle of sar:\t " << out_inclocal_path << endl; + std::cout << "==========================================================" << endl; + return 0; +} + +int simProcess::ASF(std::string in_dem_path, std::string out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN) +{ + std::cout << "computer ASF, begining:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "in parameters" << endl; + std::cout << "the dem of sar:\t" << in_dem_path << endl; + std::cout << "in sar rc path:\t" << in_dem_path << endl; + std::cout << "out parameters" << endl; + std::cout << "out latlon of sar:\t" << out_latlon_path << endl; + std::cout << "==========================================================" << endl; + + + gdalImage dem(in_dem_path); + gdalImage latlon = CreategdalImage(out_latlon_path, this->pstn.height, this->pstn.width, 2, dem.gt, dem.projection, false); + //gdalImage sar_rc(in_sar_rc_path); + // 初始化坐标 + double aveageAti = 0; + { + int line_invert = int(500000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + int count = 0; + do { + Eigen::MatrixXd sar_dem = dem.getData(start_ids, 0, line_invert, dem.width, 1); + int row_count = sar_dem.rows(); + int col_count = sar_dem.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + if (!isnan(sar_dem(i, j)) && !isinf(sar_dem(i, j))) { + aveageAti += sar_dem(i, j); + count = count + 1; + } + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + aveageAti = aveageAti / count; + } + cout << "the aveage ati of dem:\t" << aveageAti << endl; + // 初始化坐标 + Landpoint initp = dem.getLandPoint(int(dem.height / 2), int(dem.width / 2), aveageAti); + + cout << "initlandpoint lon lat ati\t" << initp.lon << "\t" << initp.lat << "\t" << initp.ati << "\t" << endl; + initp = LLA2XYZ(initp); + cout << "initlandpoint lon lat ati\t" << initp.lon << "\t" << initp.lat << "\t" << initp.ati << "\t" << endl; + + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + double alpha0 = 0; + // 迭代计算 + { + int line_invert = int(1000000 / dem.width) > 10 ? int(1000000 / dem.width) : 10; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) + { + Eigen::MatrixXd sar_dem = dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_lon = latlon.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_lat = latlon.getData(start_ids, 0, line_invert, this->pstn.width, 2); + Eigen::Vector3d initTagetPoint(initp.lon, initp.lat, initp.ati); + int row_min = start_ids; + int row_max = sar_lon.rows() + row_min; + std::cout << "rows:\t" << row_min << "-" << row_max << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + + for (int i = row_min; i < row_max; i++) { + long double satetime = i * (1 / PRF) + imgstarttime; + Eigen::MatrixXd sataspace = this->pstn.orbit.SatelliteSpacePoint(satetime); // 空间坐标 + Eigen::Vector3d SatellitePosition(sataspace(0, 0), sataspace(0, 1), sataspace(0, 2)); + Eigen::Vector3d SatelliteVelocity(sataspace(0, 3), sataspace(0, 4), sataspace(0, 5)); + Landpoint sata{ sataspace(0,0), sataspace(0, 1), sataspace(0, 2) }; + + double beta0 = 50 * d2r;// (180-getAngle(sata, sata-initp))* d2r; + + for (int j = 0; j < this->pstn.width; j++) { + double R = getRangebyColumn(j, this->pstn.R0, this->pstn.fs, this->pstn.lamda); + double ati_H = sar_dem(i - row_min, j); + if (!isnan(ati_H) && !isinf(ati_H)) { + ati_H = aveageAti; + } + Eigen::Vector3d landp = asfclass.ASF(R, SatellitePosition, SatelliteVelocity, initTagetPoint, PSTN, this->pstn.R0, ati_H, alpha0, beta0); + Landpoint landpoint{ landp(0),landp(1) ,landp(2) }; + landpoint = XYZ2LLA(landpoint); + sar_lon(i - row_min, j) = landpoint.lon; + sar_lat(i - row_min, j) = landpoint.lat; + } + } + omp_set_lock(&lock); + latlon.saveImage(sar_lon, row_min, 0, 1); + latlon.saveImage(sar_lat, row_min, 0, 2); + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "out lon and lat of sar, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the lon lat of sar:\t" << out_latlon_path << endl; + std::cout << "band 1: lon" << endl; + std::cout << "band 2: lat " << endl; + std::cout << "==========================================================" << endl; + + return 0; +} +/// +/// 计算入射角和具体入射角 +/// +/// +/// +/// +/// +/// +void simProcess::calcalIncident_localIncident_angle(std::string in_dem_path, std::string in_rc_wgs84_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN) +{ + this->calGEC_Incident_localIncident_angle(in_dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, PSTN); +} + +/// +/// 获取GEC坐标系下的入射角与距地入射角 +/// +/// +/// +/// +/// +/// +void simProcess::calGEC_Incident_localIncident_angle(std::string in_dem_path, std::string in_gec_lon_lat_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer Incident_localIncident_angle in sar, begining:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "in parameters" << endl; + std::cout << "the dem in wgs84 of sar:\t" << in_dem_path << endl; + std::cout << "in gec lon lat path:\t" << in_gec_lon_lat_path << endl; + std::cout << "out parameters" << endl; + std::cout << "out incident_angle of sar:\t" << out_incident_angle_path << endl; + std::cout << "out local incident_angle of sar:\t" << out_local_incident_angle_path << endl; + std::cout << "==========================================================" << endl; + + gdalImage dem_img(in_dem_path); + gdalImage lonlat(in_gec_lon_lat_path); + gdalImage incident_angle = CreategdalImage(out_incident_angle_path, this->pstn.height, this->pstn.width, 1, dem_img.gt, dem_img.projection, false); + gdalImage local_incident_angle = CreategdalImage(out_local_incident_angle_path, this->pstn.height, this->pstn.width, 1, dem_img.gt, dem_img.projection, false); + // 初始化 + { + dem_img.InitInv_gt(); + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_inc = incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_local_incident = local_incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_inc = sar_inc.array() * 0; + sar_local_incident = sar_local_incident.array() * 0; + + incident_angle.saveImage(sar_inc, start_ids, 0, 1); + local_incident_angle.saveImage(sar_local_incident, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + { + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + + int line_invert = 500; + int start_ids = 0; + int line_cound_sum = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + + for (start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) { + Eigen::MatrixXd lon = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd lat = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 2); + Eigen::MatrixXd dem_col = dem_img.inv_gt(0, 0) + dem_img.inv_gt(0, 1) * lon.array() + dem_img.inv_gt(0, 2) * lat.array(); + Eigen::MatrixXd dem_row = dem_img.inv_gt(1, 0) + dem_img.inv_gt(1, 1) * lon.array() + dem_img.inv_gt(1, 2) * lat.array(); + //lon = Eigen::MatrixXd::Ones(1,1); + //lat= Eigen::MatrixXd::Ones(1,1); + int min_row = floor(dem_row.array().minCoeff()); + int max_row = ceil(dem_row.array().maxCoeff()); + min_row = min_row - 1 >= 0 ? min_row - 1 : 0; + max_row = max_row + 1 < dem_img.height ? max_row + 1 : dem_img.height; + int row_len = max_row - min_row + 1; + Eigen::MatrixXd dem = dem_img.getData(min_row, 0, row_len, dem_img.width, 1); + + Eigen::MatrixXd sar_inc = incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_local_incident = local_incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + int min_col = 0; + int lon_row_count = dem_col.rows(); + int lon_col_count = dem_col.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < lon_row_count; i++) + { + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle, inc_angle; + // 同一行,卫星坐标一致 + long double satatime = (i + start_ids) * (1 / PRF) + imgstarttime; + Eigen::MatrixXd sataState = this->pstn.orbit.SatelliteSpacePoint(satatime); + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + double dem_r, dem_c; + int r0, r1; + int c0, c1; + for (int j = 0; j < lon_col_count; j++) { + // 计算行列号 + dem_r = dem_row(i, j); //y + dem_c = dem_col(i, j); // x + r0 = floor(dem_r); + r1 = ceil(dem_r); + c0 = floor(dem_c); + c1 = ceil(dem_c); + + p0 = Landpoint{ dem_c - c0,dem_r - r0,0 }; + p1 = Landpoint{ 0,0,dem(r0 - min_row, c0 - min_col) }; // p11(0,0) + p2 = Landpoint{ 0,1,dem(r0 - min_row + 1, c0 - min_col) }; // p21(0,1) + p3 = Landpoint{ 1,0,dem(r0 - min_row , c0 + 1 - min_col) }; // p12(1,0) + p4 = Landpoint{ 1,1,dem(r0 - min_row + 1, c0 + 1 - min_col) }; // p22(1,1) + p0.ati = Bilinear_interpolation(p0, p1, p2, p3, p4); + + p0 = dem_img.getLandPoint(dem_r, dem_c, p0.ati); // 中心 + p1 = dem_img.getLandPoint(r0, c0, dem(r0 - min_row, c0 - min_col)); // p11(0,0) + p2 = dem_img.getLandPoint(r1, c0, dem(r1 - min_row, c0 - min_col)); // p21(0,1) + p3 = dem_img.getLandPoint(r0, c1, dem(r0 - min_row, c1 - min_col)); // p12(1,0) + p4 = dem_img.getLandPoint(r1, c1, dem(r1 - min_row, c1 - min_col)); // p22(1,1) + + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); // 地面坡向矢量 + landpoint = LLA2XYZ(p0); + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector);// 局地入射角 + inc_angle = getIncAngle(satepoint, landpoint); // 侧视角 + + // 记录值 + sar_local_incident(i, j) = localincangle; + sar_inc(i, j) = inc_angle; + } + } + omp_set_lock(&lock); + incident_angle.saveImage(sar_inc, start_ids, 0, 1); + local_incident_angle.saveImage(sar_local_incident, start_ids, 0, 1); + line_cound_sum = line_cound_sum + line_invert; + std::cout << "rows:\t" << start_ids << "\t" << line_cound_sum << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + + std::cout << "computer Incident_localIncident_angle in sar, overing:\t" << getCurrentTimeString() << endl; +} + +/// +/// 插值GTC的影像值 +/// +/// +/// +/// +/// +void simProcess::interpolation_GTC_sar(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + + + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 2, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0 - 9999; + sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 500; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX> ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + ori(i, j) = complex{ ori_a(i, j), ori_b(i, j) }; + } + } + ori_a = Eigen::MatrixXd(1, 1); + ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows(); + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 - 1; r2 = r1 + 1; r3 = r1 + 2; // 获取行 + c1 = floor(c); + c0 = c1 - 1; c2 = c1 + 1; c3 = c1 + 2; // 获取列 + // 考虑边界情况 + if (r0<-1 || c0<-1 || c3>this->pstn.width || r3>this->pstn.height) { + continue; + } + // 边界插值计算,插值模块权重 + Eigen::MatrixX> img_block(4, 4); + if (r0 == -1 || c0 == -1) { + if (r0 == -1) { + if (c0 == -1) { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c1) *complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c2) + ori(r3 - min_r, c3); // k,-1 + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3); // k,-1 + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3); // k,-1 + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = img_block(1, 0) * complex{3, 0} - complex{3, 0} *img_block(2, 0) + img_block(3, 0);// -1,-1 + } + else if (c3 == this->pstn.width) { + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(2, 3) + img_block(3, 3);//-1,M+1 + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1,k + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1 + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1 + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1 + } + + } + + else if (c0 == -1)//r0 != -1 + { + if (r3 == this->pstn.height) { + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + else { // + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 3) = ori(r3 - min_r, c3); + } + } + + } + else if (r3 == this->pstn.height || c3 == this->pstn.width) { + if (r3 == this->pstn.height) { + if (c3 == this->pstn.width) { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);;//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);;//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);;//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(1, 3) + img_block(0, 3);//N+1,M+1 + + } + else { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3);//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3);//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3);//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + } + else if (c3 == this->pstn.width) { // r3 != this->pstn.height + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);//0,M+1 + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r0 - min_r, c3); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + + complex interpolation_value = Cubic_Convolution_interpolation(r - r1, c - c1, img_block); + // + sar_a(i, j) = interpolation_value.real(); + sar_b(i, j) = interpolation_value.imag(); + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + sar_img.saveImage(sar_b, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + } + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, over:\t" << getCurrentTimeString() << std::endl; +} + + +/// +/// 插值GTC的影像值 +/// +/// +/// +/// +/// +void simProcess::interpolation_GTC_sar_sigma(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 1, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0; + //sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + //sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 600; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + //Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX> ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + ori(i, j) = complex{ ori_a(i, j), 0 }; + } + } + ori_a = Eigen::MatrixXd(1, 1); + //ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows()-100; + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 - 1; r2 = r1 + 1; r3 = r1 + 2; // 获取行 + c1 = floor(c); + c0 = c1 - 1; c2 = c1 + 1; c3 = c1 + 2; // 获取列 + // 考虑边界情况 + if (r0<-1 || c0<-1 || c3>this->pstn.width || r3>this->pstn.height) { + continue; + } + // 边界插值计算,插值模块权重 + Eigen::MatrixX> img_block(4, 4); + if (r0 == -1 || c0 == -1) { + if (r0 == -1) { + if (c0 == -1) { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c1) * complex{3, 0} - complex{3,0} *ori(r3 - min_r, c2) + ori(r3 - min_r, c3); // k,-1 + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3); // k,-1 + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3); // k,-1 + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = img_block(1, 0) * complex{3, 0} - complex{3, 0} *img_block(2, 0) + img_block(3, 0);// -1,-1 + } + else if (c3 == this->pstn.width) { + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(2, 3) + img_block(3, 3);//-1,M+1 + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1,k + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1 + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1 + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1 + } + + } + + else if (c0 == -1)//r0 != -1 + { + if (r3 == this->pstn.height) { + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + else { // + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 3) = ori(r3 - min_r, c3); + } + } + + } + else if (r3 == this->pstn.height || c3 == this->pstn.width) { + if (r3 == this->pstn.height) { + if (c3 == this->pstn.width) { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);;//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);;//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);;//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(1, 3) + img_block(0, 3);//N+1,M+1 + + } + else { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3);//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3);//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3);//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + } + else if (c3 == this->pstn.width) { // r3 != this->pstn.height + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);//0,M+1 + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r0 - min_r, c3); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + + complex interpolation_value = Cubic_Convolution_interpolation(r - r1, c - c1, img_block); + // + //if (interpolation_value.real() < 0) { + // int a = 1; + //} + sar_a(i, j) = interpolation_value.real(); + //sar_b(i, j) = interpolation_value.imag(); + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_b, start_ids, 0, 2); + start_ids = start_ids + line_invert-100; + } while (start_ids < sar_rc.height); + } + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, over:\t" << getCurrentTimeString() << std::endl; +} + +void simProcess::interpolation_bil(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + + this->pstn.width = ori_sar.width; + this->pstn.height = ori_sar.height; + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 1, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0 - 9999; + //sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + //sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 500; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + if (start_ids == 13500) { + int sdaf = 1; + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + //Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + //ori(i, j) = complex{ ori_a(i, j), ori_b(i, j) }; + ori(i, j) = double{ ori_a(i, j)}; + } + } + ori_a = Eigen::MatrixXd(1, 1); + //ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows(); + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, c0, c1; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 + 1; // 获取行 + c1 = floor(c); + c0 = c1 + 1; // 获取列 + // 考虑边界情况 + if (r1<=0 || c1<=0 || c0>= this->pstn.width || r0>=this->pstn.height) { + continue; + } + /* if (c1 <= 0 || c0 >= this->pstn.width || (r1 - min_r) <= 0 || (r0 - min_r) <= 0 || (r1 - min_r) >= ori_a.rows() || (r0 - min_r) >= ori_a.cols()) { + continue; + }*/ + /* if ((r1 - min_r) <= 0 || (r0 - min_r) <= 0 || (r1 - min_r) >= ori_a.rows() || (r0 - min_r) >= ori_a.cols() || c1 >= ori_a.cols() || c0 >= ori_a.cols()) { + continue; + }*/ + Landpoint p0, p1, p2, p3, p4; + //std::cout << "r= " << r << " r1= " << r1 << " c= " << c << " c1= " << c1 << " min_r = " << min_r << std::endl; + p0 = Landpoint{ r - r1,c - c1,0 }; + //std::cout << "row= " << r1 - min_r << "col= " < 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + int row_count = sar_r.rows() - 100; + int col_count = sar_r.cols(); + int win_s = floor(w_size / 2); + int count = w_size * w_size; +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c, snr; + for (int j = 0; j < col_count; j++) { + double sum = 0; + double ave = 0; + double sumSquared = 0; + double variance = 0; + //((i - win_s) < 0 || (j - win_s) < 0 || (i + win_s) > sar_rc.height || (j + win_s) > sar_rc.width) + if (i == 0 || j == 0 || i == sar_rc.height || j == sar_rc.width || (i - win_s) <= 0 || (j - win_s) <= 0 || (i + win_s) >= sar_rc.height || (j + win_s) >= sar_rc.width) + { + sar_a(i, j) = sar_r(i, j); + } + else + { + r0 = i - win_s; + r1 = i + win_s; + c0 = j - win_s; + c1 = j + win_s; + // 计算窗口均值与方差 + for (int n = r0; n <= r1; n++) + { + for (int m = c0; m <= c1; m++) + { + sum += sar_r(n, m); + sumSquared += sar_r(n, m) * sar_r(n, m); + } + } + //均值 + ave = sum / count; + //方差 + variance = sumSquared / count - ave * ave; + if (variance == 0) { + sar_a(i, j) = sar_r(i, j); + } + else { + sar_a(i, j) = sar_r(i, j) + noise_var * (ave - sar_r(i, j)); + + } + } + + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + start_ids = start_ids + line_invert - 100; + } while (start_ids < sar_rc.height); + + } + +} + + + +/// +/// 根据RPC的行列号,生成RPC对应的DEM文件 +/// +/// +/// +/// +void simProcess::CreateRPC_DEM(std::string in_rpc_rc_path, std::string in_dem_path, std::string out_rpc_dem_path) +{ + gdalImage rpc_rc(in_rpc_rc_path); + gdalImage dem_img(in_dem_path); + gdalImage rpc_dem_img = CreategdalImage(out_rpc_dem_path, rpc_rc.height, rpc_rc.width, 1, rpc_rc.gt, rpc_rc.projection); + + // 初始化 + { + dem_img.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd rpc_dem = rpc_dem_img.getData(start_ids, 0, line_invert, rpc_dem_img.width, 1); + rpc_dem = rpc_dem.array() * 0 - 9999; + rpc_dem_img.saveImage(rpc_dem, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < rpc_dem_img.height); + rpc_dem_img.setNoDataValue(-9999, 1); + } + + // 插值计算结果 + { + dem_img.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << rpc_dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd rpc_dem = rpc_dem_img.getData(start_ids, 0, line_invert, rpc_dem_img.width, 1); + Eigen::MatrixXd rpc_row = rpc_dem.array() * 0 - 1; + Eigen::MatrixXd rpc_col = rpc_dem.array() * 0 - 1; + int row_count = rpc_dem.rows(); + int col_count = rpc_dem.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + Landpoint landpoint = rpc_dem_img.getLandPoint(i + start_ids, j, 0); + Landpoint land_row_col = dem_img.getRow_Col(landpoint.lon, landpoint.lat); // x,y,z + rpc_row(i, j) = land_row_col.lat; // row + rpc_col(i, j) = land_row_col.lon; // col + } + } + + double min_r = floor(rpc_row.minCoeff()) - 1; + double max_r = ceil(rpc_row.maxCoeff()) + 1; + min_r = min_r >= 0 ? min_r : 0; + int len_r = max_r - min_r; + Eigen::MatrixXd dem = dem_img.getData(min_r, 0, len_r + 2, dem_img.width, 1); + + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + Landpoint p0 = Landpoint{ rpc_row(i,j),rpc_col(i,j),0 }; + Landpoint p1 = Landpoint{ floor(p0.lon),floor(p0.lat),0 }; p1.ati = dem(int(p1.lon - min_r), int(p1.lat)); p1 = Landpoint{ 0,0,p1.ati }; + Landpoint p2 = Landpoint{ floor(p0.lon),ceil(p0.lat),0 }; p2.ati = dem(int(p2.lon - min_r), int(p2.lat)); p2 = Landpoint{ 0,1,p2.ati }; + Landpoint p3 = Landpoint{ ceil(p0.lon),floor(p0.lat),0 }; p3.ati = dem(int(p3.lon - min_r), int(p3.lat)); p3 = Landpoint{ 1,0,p3.ati }; + Landpoint p4 = Landpoint{ ceil(p0.lon),ceil(p0.lat),0 }; p4.ati = dem(int(p4.lon - min_r), int(p4.lat)); p4 = Landpoint{ 1,1,p4.ati }; + p0 = Landpoint{ p0.lon - floor(p0.lon), p0.lat - floor(p0.lat), 0 }; + p0.ati = Bilinear_interpolation(p0, p1, p2, p3, p4); + rpc_dem(i, j) = p0.ati; + } + } + rpc_dem_img.saveImage(rpc_dem, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < rpc_dem_img.height); + } + + +} + +void simProcess::CreateRPC_refrenceTable(string in_rpc_tiff_path,string in_merge_dem,string out_rpc_lon_lat_tiff_path) +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister();//注册驱动 + + const char* pszTif = in_rpc_tiff_path.c_str(); + + gdalImage rpc_img(in_rpc_tiff_path); + + GDALRPCInfo oInfo = rpc_img.getRPC(); + + //设置RPC模型中所需的DEM路径 + char** papszTransOption = NULL; + //papszTransOption = CSLSetNameValue(papszTransOption, "RPC_DEM", "E:\\DEM.img"); //设置DEM + + //使用RPC信息,DEM等构造RPC转换参数 + void* pRPCTransform = GDALCreateRPCTransformer(&oInfo, FALSE, 0, papszTransOption); + + + // 创建影像 + + gdalImage lon_lat_img = CreategdalImage(out_rpc_lon_lat_tiff_path, rpc_img.height, rpc_img.width, 2, rpc_img.gt, rpc_img.projection, false); + // 计算角点 + string temp_dem_path = in_merge_dem + ".bak"; + double merge_gt[6] = { + rpc_img.gt(0,0), rpc_img.gt(0,1), rpc_img.gt(0,2), + rpc_img.gt(0,3), rpc_img.gt(0,4), rpc_img.gt(0,5) + } ; + ResampleGDAL(in_merge_dem.c_str(), temp_dem_path.c_str(), merge_gt, rpc_img.width, rpc_img.height, GRA_Bilinear); + + gdalImage merger_dem_tiff(temp_dem_path); + double X[4] = { 0,0,rpc_img.width - 1,rpc_img.width - 1 }; + double Y[4] = { 0,rpc_img.height - 1,rpc_img.height - 1,0 }; + double Z[4] = { 0,0,0,0 }; + int sucess_num[4] = { false,false,false,false }; + GDALRPCTransform(pRPCTransform, FALSE, 4, X, Y, Z, sucess_num); + for (int i = 0; i < 4; i++) { + std::cout << X[i] << "\t" << Y[i] << "\t" << Z[i] << "\t" << sucess_num[i] << std::endl; + } + int line_invert = int(1500000 / rpc_img.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd lon = lon_lat_img.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 1); + Eigen::MatrixXd lat = lon_lat_img.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 2); + Eigen::MatrixXd dem = merger_dem_tiff.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 2); + int row_count = lon.rows(); + int col_count = lon.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + //定义图像的四个角点行列号坐标 + double dY[1] = { i + max_rows_ids }; + double dX[1] = { j }; + double dZ[1] = { dem(i,j)}; + int nSuccess[1] = { FALSE }; + GDALRPCTransform(pRPCTransform, FALSE, 1, dX, dY, dZ, nSuccess); + lon(i, j) = dX[0]; + lat(i, j) = dY[0]; + } + } + + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + std::cout << lon.array().minCoeff() << endl; + lon_lat_img.saveImage(lon, max_rows_ids, 0, 1); + lon_lat_img.saveImage(lat, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << lon_lat_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + //释放资源 + GDALDestroyRPCTransformer(pRPCTransform); + CSLDestroy(papszTransOption); +} + +/// +/// 映射表插值计算 +/// +/// 映射表 +/// 输入数据 +/// 输出数据 +void simProcess::CorrectionFromSLC2Geo(string in_lon_lat_path, string in_radar_path, string out_radar_path,int in_band_ids) +{ + gdalImage in_lon_lat(in_lon_lat_path); + gdalImage in_image(in_radar_path); + gdalImage out_radar(out_radar_path); + + cv::Mat in_mat; + cv::Mat out_mat; + + cv::eigen2cv(in_image.getData(0, 0, in_lon_lat.height, in_lon_lat.width, in_band_ids),in_mat); + + // 定义映射关系 + cv::Mat in_x,in_y; + cv::eigen2cv(in_lon_lat.getData(0, 0, in_lon_lat.height, in_lon_lat.width, 1), in_x); + cv::eigen2cv(in_lon_lat.getData(0, 0, in_lon_lat.height, in_lon_lat.width, 1), in_y); + + // 重新进行插值计算 + +} +/// +/// 根据DEM创建SAR_rc +/// +/// +/// +/// +/// + + +double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda) +{ + return (double)(2 * (R - NearRange) / LIGHTSPEED * Fs); // 计算采样率; +} + +Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda) +{ + return ((R.array() - NearRange).array() / lamda * Fs).array().cast(); +} + +double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda) +{ + return (j * lamda / 2) / Fs + NearRange; + +} + +Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda) +{ + return ((j.array() * lamda / 2) / Fs + NearRange).array().cast(); +} + +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector) { + Landpoint Rsc = satepoint - landpoint; // AB=B-A + //double R = getlength(Rsc); + //std::cout << R << endl; + double angle = getAngle(Rsc, slopeVector); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + +double getIncAngle(Landpoint& satepoint, Landpoint& landpoint) { + + Landpoint Rsc = satepoint - landpoint; // AB=B-A + Landpoint Rs = landpoint;// landpoint; + double angle = getAngle(Rsc, Rs); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////// ASF 计算 /////////////////////////////////////////////////// +////// 《星载合成孔径雷达影像正射校正方法研究》 陈尔学 ///////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////// + +/// +/// 计算 变换矩阵 卫星坐标系-> ECR +/// +/// [x,y,z,vx,vy,vz] nx6 +/// +Eigen::MatrixXd ASFOrthClass::Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc) +{ + + Eigen::Vector3d x, y, z; + + Eigen::MatrixXd M(3, 3); + + z = Rsc / Rsc.norm(); + y = Rsc.cross(Vsc) / (Rsc.norm() * Vsc.norm()); + x = y.cross(z); + + M.col(0) = x; + M.col(1) = y; + M.col(2) = z; + return M; +} +/// +/// 获取从卫星指向地面目标的单位矢量 +/// +/// 弧度值 +/// 弧度值 +/// 变换矩阵 +/// +Eigen::Vector3d ASFOrthClass::UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M) +{ + // 目标T的单位向量 ST = R * M * P + Eigen::Vector3d P(sin(alpha), -1.0 * cos(alpha) * sin(beta), -1.0 * cos(alpha) * cos(beta)); + return M * P; +} + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H) +{ + /** + 根据R和alpha 计算出beta来。 + 根据参考论文,式3 - 13,完成此方法。(注意这是近似法 + args : + R:斜距 + alpha : 雷达侧视角 + beta0 : beta初始值 + SatellitePosition : 3x1 卫星空间位置 + TargetPosition:3x1 目标对象 + */ + Eigen::MatrixXd M = this->Satellite2ECR(SatellitePosition, SatelliteVelocity); + // 地球半径 + double Rp = earth_Rp + H; + double Rs_norm = SatellitePosition.norm(); + // 初始化beta + if (beta == 0) { + double beta_cos = (Rs_norm * Rs_norm + R * R - Rp * Rp) / (2 * Rs_norm * R); + beta = acos(beta_cos); + } + + double delta_R, sin_eta, delta_beta, tan_eta; + // 迭代 + int i = 0; + do { + // 计算斜率的增加 + delta_R = R - this->FR(alpha, beta, SatellitePosition, M, R_threshold, H); + // 计算入射角 + sin_eta = Rs_norm * sin(beta) / Rp; + tan_eta = sin_eta / sqrt(1 - sin_eta * sin_eta); + // 计算增量 + delta_beta = delta_R / (R * tan_eta); + // 更新 + beta = beta + delta_beta; + // 判断循环终止条件 + i = i + 1; + if (i >= 10000) // 达到终止条件 + { + return -9999; + } + } while (abs(delta_R) > 0.01); + return beta; +} + +/// +/// 从beta,alpha获取获取目标的空间位置 +/// +/// +/// +/// +/// +/// +/// +Eigen::Vector3d ASFOrthClass::GetXYZByBetaAlpha(double alpha, double beta, Eigen::Vector3d SatellitePosition, double R, Eigen::MatrixXd M) +{ + return SatellitePosition + R * this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); +} + +/// +/// FD +/// +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity, double R, double lamda, Eigen::MatrixXd M) +{ + /** + 根据beta, alpha, 卫星空间位置, 斜距,转换矩阵 + */ + Eigen::Vector3d UnitVector = this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); + Eigen::Vector3d Rst = -1 * R * UnitVector; + double Rst_Vst = Rst.dot(SatelliteVelocity - TargetVelocity); + return -2 / (R * lamda) * Rst_Vst; +} + + +/// +/// FR +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H) +{ + /* + 根据 雷达侧视角,雷达视角,卫星位置,坐标系变换矩阵,大地高等参数,根据参考论文中公式3 - 1 == 》3 - 10的计算过程,设计此方程 + args : + alpha:雷达侧视角 卫星与地物间速度运动差导致的(即多普勒频移的结果) + beta : 雷达视角 + Satellite_position : 卫星空间位置 + M:坐标系转换矩阵 + H:大地高 + return : + R:斜距 + */ + //std::cout << beta << endl; + Eigen::Vector3d UnitVector = R_threshold * this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); + // 解方程 3 - 10 纠正错误,A公式有问题 + double a = (earth_Re + H) * (earth_Re + H); + double b = earth_Rp * earth_Rp; + long double Xs = SatellitePosition(0); + long double Ys = SatellitePosition(1); + long double Zs = SatellitePosition(2); + long double Xp = UnitVector(0); + long double Yp = UnitVector(1); + long double Zp = UnitVector(2); + //std::cout << Xp<<"\t"<< Yp<<"\t"<< Zp << endl; + long double A = (Xp * Xp + Yp * Yp) / a + (Zp * Zp) / b; + long double B = 2 * (Xs * Xp + Ys * Yp) / a + 2 * Zs * Zp / b; + long double C = (Xs * Xs + Ys * Ys) / a + Zs * Zs / b - 1; + //std::cout << A << "\t" << B << "\t" << C << endl; + C = B * B - 4 * A * C; + //std::cout << A << "\t" << B << "\t" << C << endl; + double R1 = (-B - sqrt(C)) / (2 * A); + //double R2 = (-B + sqrt(C)) / (2 * A); + //std::cout << R1 << "\t" << R2 << endl; + if (R1 > 1) { + return R1 * R_threshold; + } + else { + return -9999; + //return (-B + math.sqrt(t)) / (2 * A) # 这里通过几何分析排除这个解 + } + +} + +/// +/// ASF方法 +/// +/// +/// 卫星高度 +/// 卫星速度 +/// 初始化地面坐标 +/// +/// +/// 初始高程 +/// +/// +/// +Eigen::Vector3d ASFOrthClass::ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H, double alpha0, double beta0) +{ + // 部分参数初始化 + double alpha = alpha0; + double beta = beta0; + double delta_alpha = 0; + // 这个公式是根据《中国海洋合成孔径雷达卫星工程、产品与处理》 + // P164 5.8.4 多普勒参数计算 + double fd = PSTN.calNumericalDopplerValue(R); + Eigen::MatrixXd M = this->Satellite2ECR(SatellitePosition, SatelliteVelocity); + double FD_, delta_fd; + Eigen::Vector3d XYZ; + int i = 0;// 统计迭代次数 + while (true) { + Eigen::Vector3d TargetVelocity = Eigen::Vector3d(-1 * earth_We * TargetPosition(1), earth_We * TargetPosition(0), 0);// 计算地面速度, 粗糙计算时,默认为0 + beta = this->GetLookFromRangeYaw(R, alpha, beta, SatellitePosition, SatelliteVelocity, R_threshold, H); + FD_ = this->FD(alpha, beta, SatelliteVelocity, TargetVelocity, R, PSTN.lamda, M); + delta_fd = FD_ - fd; + delta_alpha = -1 * delta_fd * PSTN.lamda / (2 * (SatelliteVelocity - TargetVelocity).norm()); + TargetPosition = this->GetXYZByBetaAlpha(alpha, beta, SatellitePosition, R, M); + //cout << i << "\t" << delta_alpha * R << "\t" << delta_alpha<<"\t"<< (abs(delta_alpha * R) < 0.1)<<"\t"<< (abs(delta_alpha) < 0.001) << endl; + if (abs(delta_alpha * R) < 0.1 || abs(delta_alpha) < 0.0003) + { + break; + } + alpha = alpha + delta_alpha; + i = i + 1; + if (i > 10000) { + throw new exception("ASF 失败"); + } + + } + return TargetPosition; +} + diff --git a/simorthoprogram-orth_L_sar-strip/simptsn.h b/simorthoprogram-orth_L_sar-strip/simptsn.h new file mode 100644 index 0000000..24e3f8d --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/simptsn.h @@ -0,0 +1,241 @@ +#pragma once +/// +/// 仿真成像算法 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 +#include "baseTool.h" +#include +#include +#include +#include +//#include +#include +#include "SateOrbit.h" +#include "ImageMatch.h" +using namespace std; +using namespace Eigen; + +////////////// 常用函数 //////////////////////// + +double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda); +Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda); + +double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda); +Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda); +///////////// ptsn 算法 ///////////////////// + +class PSTNAlgorithm { +public: + // 初始化与析构函数 + PSTNAlgorithm(); + PSTNAlgorithm(string parameterPath); + ~PSTNAlgorithm(); + + int dem2lat_lon(std::string dem_path, std::string lon_path, std::string lat_path); + int dem2SAR_RC(std::string dem_path, std::string sim_rc_path); + + // 模拟算法函数 + Eigen::MatrixX calNumericalDopplerValue(Eigen::MatrixX R);// 数值模拟法计算多普勒频移值 + double calNumericalDopplerValue(double R);// 数值模拟法计算多普勒频移值 + Eigen::MatrixX calTheoryDopplerValue(Eigen::MatrixX R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1);//根据理论模型计算多普勒频移值 + double calTheoryDopplerValue(double R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1); + Eigen::MatrixX PSTN(Eigen::MatrixX TargetPostion, double ave_dem, double dt, bool isCol ); // 输入DEM + //Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd blh); + //Landpoint WGS842J2000(Landpoint p); +public: // WGS84 到 J2000 之间的变换参数 + Eigen::MatrixXd UTC; + double Xp = 0.204071; + double Yp = 0.318663; + double Dut1 = 0.0366742; + double Dat = 37; +public: + int height; // 影像的高 + int width; + + // 入射角 + double near_in_angle;// 近入射角 + double far_in_angle;// 远入射角 + + // SAR的成像参数 + double fs;// 距离向采样率 + double R0;//近斜距 + double LightSpeed; // 光速 + double lamda;// 波长 + double refrange;// 参考斜距 + double doppler_reference_time; //多普勒参考时间 + + double imgStartTime;// 成像起始时间 + double PRF;// 脉冲重复率 + + int doppler_paramenter_number;//多普勒系数个数 + MatrixX doppler_paras;// 多普勒系数 + + OrbitPoly orbit; // 轨道模型 + +}; + + +/// +/// 获取局地入射角,角度值 +/// +/// +/// +/// +/// +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector); + + +/// +/// 侧视入射角,角度值 +/// +/// +/// +/// +double getIncAngle(Landpoint& satepoint, Landpoint& landpoint); + + +/// +/// ASF计算方法 +/// +class ASFOrthClass { + +public: + Eigen::MatrixXd Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc); // 根据卫星坐标计算变换矩阵 M + Eigen::Vector3d UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M); + double GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H = 0); + + Eigen::Vector3d GetXYZByBetaAlpha(double alpha,double beta, Eigen::Vector3d SatellitePosition,double R, Eigen::MatrixXd M); + + double FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity,double R,double lamda, Eigen::MatrixXd M); + double FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H = 0); + + Eigen::Vector3d ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H = 0, double alpha0 = 0, double beta0 = 0); + +}; + +/// +/// 仿真处理流程 +/// +class simProcess { +public: + simProcess(); + ~simProcess(); + + int parameters(int argc, char* argv[]); + + int InitSimulationSAR(std::string paras_path,std::string workspace_path,std::string out_dir_path,std::string in_dem_path,std::string in_sar_path); // 间接定位法 + + int CreateSARDEM(); + int dem2SAR(); // 切换行号 + int SARIncidentAngle(); + int SARSimulationWGS(); + int SARSimulation(); + int in_sar_power(); + int ReflectTable_WGS2Range(); + + int InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path,std::string in_rpc_lon_lat_path,std::string out_inc_angle_path, std::string out_local_inc_angle_path, std::string out_inc_angle_geo_path, std::string out_local_inc_angle_geo_path); + int dem2SAR_row(); // 切换行号 + int SARIncidentAngle_RPC(); + int createRPCDEM(); + + // 格网离散插值 + int Scatter2Grid(std::string lon_lat_path, std::string data_tiff, std::string grid_path, double space); + + // ASF 模块计算 + int InitASFSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path); + + int ASF(std::string in_dem_path, std::string out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN); + + //int dem2simSAR(std::string dem_path, std::string out_sim_path, PSTNAlgorithm PSTN); // 根据DEM生成输出仿真图像 + int sim_SAR(std::string dem_path, std::string sim_rc_path, std::string sim_sar_path, PSTNAlgorithm PSTN); + int dem2aspect_slope(std::string dem_path, std::string aspect_path, std::string slope_path); + int sim_sum_SAR(std::string sim_dem_path,std::string sim_rc_path, std::string sim_orth_path, std::string sim_sum_path,PSTNAlgorithm pstn); + void interpolation_GTC_sar_sigma(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + + //双线性插值 + void interpolation_bil(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + //lee滤波 + void lee_process(std::string in_ori_sar_path, std::string out_orth_sar_path, int w_size, double noise_var); + // 原始影像强度图 + int ori_sar_power(std::string ori_sar_path, std::string out_sar_power_path); + + // 匹配偏移模型构建 + int createImageMatchModel(std::string ori_sar_rsc_path, std::string ori_sar_rsc_jpg_path, std::string sim_sar_path, std::string sim_sar_jpg_path, std::string matchmodel_path); + + // 纠正影像 + int correctOrth_rc(std::string sim_rc_path,ImageMatch matchmodel); + + int correct_ati(std::string orth_rc_path, std::string dem_path, std::string out_inclocal_path, std::string out_dem_path, std::string out_count_path, PSTNAlgorithm PSTN); + + void calcalIncident_localIncident_angle(std::string in_dem_path, std::string in_rc_wgs84_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN); + + void calGEC_Incident_localIncident_angle(std::string in_dem_path, std::string in_gec_lon_lat_path,std::string out_incident_angle_path, std::string out_local_incident_angle_path,PSTNAlgorithm PSTN); + + void interpolation_GTC_sar(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + // RPC + void CreateRPC_DEM(std::string in_rpc_rc_path, std::string in_dem_path, std::string out_rpc_dem_path); + + void CreateRPC_refrenceTable(string in_rpc_tiff_path, string in_merge_dem, string out_rpc_lon_lat_tiff_path); + + void CorrectionFromSLC2Geo(string in_lon_lat_path, string in_radar_path, string out_radar_path, int in_band_ids); + + +// 内部参数 +public: + ImageMatch matchmodel; + bool isMatchModel; + + std::string workSpace_path;// 工作空间路径 + std::string outSpace_path;// 输出工作空间路径 + PSTNAlgorithm pstn; // 参数组件 + ///// RPC 局地入射角 /////////////////////////////////// + std::string in_rpc_lon_lat_path; + std::string out_dir_path; + std::string workspace_path; + // 临时文件 + std::string rpc_wgs_path; + std::string ori_sim_count_tiff;// 映射角文件 + // 输出文件 + std::string out_inc_angle_rpc_path; + std::string out_local_inc_angle_rpc_path; + + // 输出文件 + std::string out_inc_angle_geo_path; + std::string out_local_inc_angle_geo_path; + + ///// 正向仿真方法 ///////// + + + + // 临时产品文件 + std::string in_dem_path; // 输入DEM + std::string dem_path; // 重采样之后DEM + std::string dem_r_path;// 行号影像 + std::string dem_rc_path; // 行列号 + std::string sar_sim_wgs_path; + std::string sar_sim_path; + std::string in_sar_path; + std::string sar_jpg_path; + std::string sar_power_path; + // 最终产品 + std::string out_dem_rc_path; // 经纬度与行列号变换文件 + + std::string out_dem_slantRange_path; // 斜距文件 + std::string out_plant_slantRange_path;// 平面斜距文件 + + //// ASF 方法 ///////////// + std::string out_lon_path;// 经度 + std::string out_lat_path;// 纬度 + std::string out_slantRange_path;// 斜距文件 + + /// 共同文件 /// + std::string out_localIncidenct_path;// 计算局地入射角 + std::string out_incidence_path; // 入射角文件 + std::string out_ori_sim_tiff;// 映射角文件' + std::string out_sim_ori_tiff; +}; + +bool PtInRect(Point_3d pCur, Point_3d pLeftTop, Point_3d pRightTop, Point_3d pRightBelow, Point_3d pLeftBelow); \ No newline at end of file diff --git a/simorthoprogram-orth_L_sar-strip/test_moudel.cpp b/simorthoprogram-orth_L_sar-strip/test_moudel.cpp new file mode 100644 index 0000000..30cfe4d --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/test_moudel.cpp @@ -0,0 +1,282 @@ +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +using namespace std; +using namespace Eigen; + +#include "test_moudel.h" + + +int test_main(int mode, string rootpath) +{ + switch (mode) + { + case 0: + { + test_mode_0(); + break; + }; + case 1: + { + test_mode_1(rootpath); + break; + } + case 7: { + test_mode_7(); + break; + } + case 8: { + std::string in_rpc_tiff = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1B_HH_L10003514912_db.tif"; + std::string out_lon_lat_path = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\RPC_ori_sim.tif"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.CreateRPC_refrenceTable(in_rpc_tiff, dem_path,out_lon_lat_path); + std::cout << "==========================================================================" << endl; + break; + } + default: + test_ASF(rootpath); + break; + } + return 0; +} + + +int test_mode_7() { + // + std::cout << "mode 7: get rpc incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 7 in_parameter_path in_dem_path in_gec_lon_lat_path work_path taget_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\orth_para.txt"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; + std::string in_gec_lon_lat_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\RPC_ori_sim.tif"; + std::string work_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary"; + std::string taget_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\inc_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\local_inc_angle.tiff"; + std::string out_incident_angle_geo_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\inc_angle_geo.tiff"; + std::string out_local_incident_angle_geo_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\local_inc_angle_geo.tiff"; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.InitRPCIncAngle(parameter_path, work_path, taget_path, dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, out_incident_angle_geo_path, out_local_incident_angle_geo_path); + std::cout << "==========================================================================" << endl; + return 0; +} + + +int test_mode_0() +{ + std::cout << "State:\tTEST MODE" << endl; + test_LLA2XYZ_XYZ2LLA(); + return 0; +} + +int test_mode_1(string rootpath) +{ + // .\baseTool\x64\Release\SIMOrthoProgram.exe 1 D:\MicroWorkspace\C-SAR\Ortho\Temporary\unpack\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff +//??????? + + std::string root_path = rootpath;// "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary2"; + std::string workspace = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary"; + std::string parameter_path =workspace+ "\\package\\orth_para.txt"; // + std::string dem_path = workspace + "\\TestDEM\\pindem.tif"; // + std::string in_sar_path = workspace + "\\unpack\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HHHV_L10004871459\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HH_L10004871459.tiff"; // + std::string work_path = workspace ; // + std::string taget_path = workspace + "\\package"; // + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the sar image:\n" << in_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + std::cout << "==========================================================================" << endl; + process.InitSimulationSAR(parameter_path, work_path, taget_path, dem_path, in_sar_path); + std::cout << "==========================================================================" << endl; + return 0; +} + + +int test_ASF(string rootpath) { + std::string root_path = rootpath;// "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary2"; + std::string parameter_path = root_path + "\\package\\orth_para.txt"; + std::string dem_path = root_path + "\\TestDEM\\mergedDEM.tif"; + std::string ori_sar_path = root_path + "\\unpack\\" + "GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HHHV_L10004871459\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HH_L10003923848.tiff"; + std::string work_path = root_path + "\\TestSim"; + std::string taget_path = root_path + "\\output"; + std::string out_GEC_dem_path = root_path + "\\output\\GEC_dem.tif"; + std::string out_GTC_rc_path = root_path + "\\output\\GTC_rc_wgs84.tif"; + std::string out_GEC_lon_lat_path = root_path + "\\output\\GEC_lon_lat.tif"; + std::string out_clip_DEM_path = root_path + "\\output\\Orth_dem.tif"; + std::cout << "==========================================================================" << endl; + std::cout << "????????????????????DEM ??Χ" << endl; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path "; + std::cout << "out_GEC_dem_path out_GTC_rc_path out_GEC_lon_lat_path out_clip_dem_path" << endl; + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the reference sar image for match simulation sar image:\n" << ori_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + ASFOrthClass ASFClass; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + // + dem_path = out_clip_DEM_path;// JoinPath(work_path, "clipDEM.tif"); + std::string out_simrc_path = JoinPath(work_path, "dem_sar_rc.tif"); //r,c + std::string sim_sar_orth_path = JoinPath(work_path, "sim_sar_orth.tif"); // orth_sim,orth_inclocal + + std::string dem_slope_path = JoinPath(work_path, "dem_slope.tif"); + std::string dem_aspect_path = JoinPath(work_path, "dem_aspect.tif"); + + std::string sim_sar_path = JoinPath(work_path, "sim_sar_sum.tif"); // sim count dem + std::string ori_sar_rsc_path = JoinPath(work_path, "ori_sar_power.tif"); // ori_power + std::string ori_sar_rsc_jpg_path = JoinPath(work_path, "ori_sar_power.jpg"); + std::string sim_sar_jpg_path = JoinPath(work_path, "sim_sar_sum.jpg"); + std::string matchmodel_path = JoinPath(work_path, "matchmodel.txt"); // matchmodel + + std::string out_dem_count_path = JoinPath(work_path, "dem_count.tif"); + + std::string out_dem_path = out_GEC_dem_path; + std::string out_inclocal_path = JoinPath(taget_path, "inclocal.tif"); + std::string out_sar_rc_path = out_GTC_rc_path; + std::string out_lon_lat_path = out_GEC_lon_lat_path; + + if (process.isMatchModel) { + process.correctOrth_rc(out_simrc_path, process.matchmodel); + } + if (boost::filesystem::exists(boost::filesystem::path(out_sar_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(out_sar_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(out_simrc_path), boost::filesystem::path(out_sar_rc_path)); + + process.correct_ati(out_sar_rc_path, dem_path, out_inclocal_path, out_dem_path, out_dem_count_path, pstn); + // ASF + + process.ASF(out_dem_path, out_lon_lat_path, ASFClass, pstn); + + return 0; +} + + +int test_mode_2() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_DEM.tiff"; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_sar_rc.tiff"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_incident_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_local_incident_angle.tiff"; + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + + process.calcalIncident_localIncident_angle(dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + + return 0; +} + +int test_mode_3() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GTC_rc_wgs84.tiff"; + std::string in_ori_sar_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\unpack\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff"; + std::string out_orth_sar_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GTC\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff"; + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); + + return 0; +} + +int test_mode_4() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string in_dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\Orth_dem.tiff"; + std::string in_rpc_rc_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\\RPC_Ortho\\RPC_sar_rc.tiff"; + std::string out_rpc_dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_DEM.tiff"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_incident_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_local_incident_angle.tiff"; + + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.CreateRPC_DEM(in_rpc_rc_path, in_dem_path, out_rpc_dem_path); + process.calcalIncident_localIncident_angle(out_rpc_dem_path, in_rpc_rc_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + return 0; +} + +int test_mode_5() +{ + std::string in_ori_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848_GTC_geo_wp.tif"; + std::string out_power_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\package\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848_GTC_geo_OrthoResult.tif"; + std::cout << "mode 5: convert ori tiff to power tiff:"; + std::cout << "SIMOrthoProgram.exe 5 in_ori_path out_power_path"; + simProcess process; + process.ori_sar_power(in_ori_path, out_power_path); + return 0; +} + +int test_mode_6() +{ + + return 0; +} + +int test_LLA2XYZ_XYZ2LLA() +{ + std::cout << "===========================================" << endl; + std::cout << "TEST LLA2XYZ and XYZ2LLA " << endl; + bool pass = false; + + Landpoint lla_p{ 30,40,500 }; + Landpoint xyz_p = LLA2XYZ(lla_p); + Landpoint lla_p2 = XYZ2LLA(xyz_p); + + std::cout << "LLA:\t" << lla_p.lon << "," << lla_p.lat << "," << lla_p.ati << endl; + std::cout << "XYZ:\t" << xyz_p.lon << "," << xyz_p.lat << "," << xyz_p.ati << endl; + std::cout<<"LLA2:\t"<< lla_p2.lon << "," << lla_p2.lat << "," << lla_p2.ati << endl; + + pass = (lla_p2.lon-lla_p.lon==0) && (lla_p2.lat- lla_p.lat==0) && (lla_p2.ati-lla_p.ati==0); + std::cout << "TEST LLA2XYZ and XYZ2LLA passed:" << pass << endl; + std::cout << "===========================================" << endl; + return pass?1:0; +} + +int test_vector_operator() +{ + // ???? + return 0; +} diff --git a/simorthoprogram-orth_L_sar-strip/test_moudel.h b/simorthoprogram-orth_L_sar-strip/test_moudel.h new file mode 100644 index 0000000..3e8638a --- /dev/null +++ b/simorthoprogram-orth_L_sar-strip/test_moudel.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +using namespace std; +using namespace Eigen; + +class test_moudel +{ + + + +}; + +int test_main(int mode, string rootpath); +int test_mode_0(); +int test_mode_1(string rootpath); +int test_ASF(string rootpath); +int test_mode_2(); +int test_mode_3(); +int test_mode_4(); +int test_mode_5(); +int test_mode_6(); +int test_mode_7(); +int test_LLA2XYZ_XYZ2LLA(); + +int test_vector_operator(); + diff --git a/simorthoprogram-orth_gf3-strip/.gitattributes b/simorthoprogram-orth_gf3-strip/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/simorthoprogram-orth_gf3-strip/.gitignore b/simorthoprogram-orth_gf3-strip/.gitignore new file mode 100644 index 0000000..85bed7a --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/.gitignore @@ -0,0 +1,56 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +*.dll + +x64/ +x64/* +.vs/ +.vs/* +/x64/* +/.vs/* +./x64/* +./.vs/* +./x64/* +/x64/* +*.ipch +*.db +*.pdb +*.tlog +*.log +*.pdb +*.db +*.tiff +*.tif +*.jpg + +Temporary*/ \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/ImageMatch.cpp b/simorthoprogram-orth_gf3-strip/ImageMatch.cpp new file mode 100644 index 0000000..476eacc --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/ImageMatch.cpp @@ -0,0 +1,510 @@ +#pragma once +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include +#include +#include +#include +#include "ImageMatch.h" +#include +#include +using namespace std; +using namespace Eigen; +using namespace cv; +/// +/// cpnvert gdal to jpg +/// +/// +/// +/// +/// +int ImageMatch::gdal2JPG(std::string gdal_path, std::string jpg_path, int band_ids) +{ + std::cout << "convert gdal to jpg , beigining : \t" << getCurrentTimeString() << endl; + gdalImage gdalimg(gdal_path); + cv::Mat img(gdalimg.height, gdalimg.width, CV_8U); + { + + int start_ids = 0; + int line_invert = int(80000000 / gdalimg.width); + Eigen::MatrixXd temp(line_invert, gdalimg.width); + double min_value = 0, temp_min = 0; + double max_value = 0, temp_max = 0; + // 线性拉伸2% + Eigen::MatrixXd hist = gdalimg.getHist(band_ids); + + int count = 0; + int sum_count = gdalimg.height * gdalimg.width; + int rows = hist.rows(); + for (int i = 0; i < rows; i++) { + + if ((count+ hist(i, 1)) / sum_count > 0.01) { + min_value = hist(i, 0); + break; + } + count = count + hist(i, 1); + } + count = 0; + for (int i = rows - 1; i >= 0; i--) { + if ((count + hist(i, 1)) / sum_count > 0.01) { + max_value = hist(i, 0); + break; + } + count = count + hist(i, 1); + } + + // 重新缩放最大值,最小值 + std::cout << "min value :\t" << min_value << "\n"; + std::cout << "max value :\t" << max_value << "\n"; + start_ids = 0; + do { + line_invert = line_invert + start_ids < gdalimg.height ? line_invert : gdalimg.height - start_ids; + + temp = gdalimg.getData(start_ids, 0, line_invert, gdalimg.width, band_ids); + temp = (temp.array() - min_value) * 250 / (max_value - min_value); + for (int i = 0; i < line_invert; i++) { + for (int j = 0; j < gdalimg.width; j++) { + if (temp(i, j) < 0) { temp(i, j) = 0; } + if (temp(i, j) > 250) { temp(i, j) = 250; } + uchar tempvalue = uchar(temp(i, j));; + img.at(i + start_ids, j) = tempvalue; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < gdalimg.height); + cv::Mat result1(gdalimg.height, gdalimg.width, CV_8U); + result1 = img; + //bilateralFilter(img, result1, 10, 80, 50); + vector compression_params; + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); //选择jpeg + compression_params.push_back(100); //在这个填入你要的图片质量 + cv::Mat out = result1; + //cv::resize(img, out, cv::Size(img.cols, img.rows), cv::INTER_AREA); + + cv::imwrite(jpg_path, out, compression_params); + + } + std::cout << "convert gdal to jpg , overing : \t" << getCurrentTimeString() << endl; + std::cout << "=========================================\n"; + std::cout << " convert gdal to jpg :\n"; + std::cout << "input gdal img file path :\t" << gdal_path << "\n"; + std::cout << "input gdal img band :\t" << band_ids << "\n"; + std::cout << "out jpg file path :\t" << jpg_path << "\n"; + std::cout << "=========================================\n"; + return 0; +} + + + +/// +/// 获取模型匹配点 +/// +/// +/// +/// +Eigen::MatrixXd ImageMatch::ImageMatch_ori_sim(std::string ori_power_path, std::string sim_sum_path, int roughSize, int PreciseSize, int scale, int searchSize, int roughStep,int preciseStep) +{ + std::cout << "match point between ori and sim , overing : \t" << getCurrentTimeString() << endl; + std::cout << "match parameters : \n"; + std::cout << "rough match templet size : \t" << roughSize << endl; + std::cout << "Precise match templet size : \t" << PreciseSize << endl; + std::cout << "Precise match wait search size : \t" << searchSize << endl; + std::cout << "Precise match scale : \t" << scale << endl; + std::cout << "Precise match step : \t" << preciseStep << endl; + std::cout << "input ori image path : \t" << ori_power_path << endl; + std::cout << "input sim image path : \t" << sim_sum_path << endl; + + //读取影像 + + + cv::Mat ori = openJPG(ori_power_path); + cv::Mat sim = openJPG(sim_sum_path); + int sim_rows = sim.rows; + int sim_cols = sim.cols; + + int BlockCount = 0; + for (int i = 0; i < sim_rows; i=i+ roughSize) { + for (int j = 0; j < sim_cols; j=j+ roughSize) { + if (i + 2 * roughSize < sim_rows && j + 2 * roughSize < sim_cols) { + BlockCount++; + } + } + } + + Eigen::MatrixXd sim_block(BlockCount,3); + BlockCount = 0; + for (int i = 0; i < sim_rows; i = i + roughSize) { + for (int j = 0; j < sim_cols; j = j + roughSize) { + if (i + 2 * roughSize < sim_rows && j + 2 * roughSize < sim_cols) { + sim_block(BlockCount, 0) = i; + sim_block(BlockCount, 1) = j; + BlockCount++; + } + } + } + + Eigen::MatrixXd Tempmatchpoints(BlockCount, 6); + Tempmatchpoints = Tempmatchpoints.array() * 0; + int count = 0; +#pragma omp parallel for num_threads(8) + for (int ii = 0; ii < BlockCount; ii++) { + int i = sim_block(ii, 0); + int j = sim_block(ii, 1); + cv::Mat templet_mat = sim(Rect(j, i, 2 * roughSize, 2 * roughSize)); + cv::Scalar mean1; + cv::Mat stddevMat; + cv::meanStdDev(templet_mat, mean1, stddevMat); + double minvalue = 0; + double maxvalue = 0; + cv::minMaxLoc(templet_mat, &minvalue, &maxvalue, NULL, NULL);//用于检测矩阵中最大值和最小值的位置 + double sig = (stddevMat.at(0, 0)) / (maxvalue - minvalue); + if (sig >1) { + //continue; + } + + // 构建搜索域 + int search_i = i - 2 * searchSize >= 0 ? i - 2 * searchSize >= 0 : 0; + int search_j = j - 2 * searchSize >= 0 ? j - 2 * searchSize >= 0 : 0; + int len_i = search_i + 4 * searchSize; + int len_j = search_j + 4 * searchSize; + len_i = search_i + len_i < ori.rows ? len_i : ori.rows - search_i - 1; + len_j = search_j + len_j < ori.cols ? len_j : ori.rows - search_j - 1; + cv::Mat serch = ori(Rect(search_j, search_i, len_j, len_i)); + // 检索 + cv::Mat result; + matchTemplate(serch, templet_mat, result, cv::TM_CCOEFF_NORMED); + Point minLoc; + Point maxLoc; + Point matchLoc; + double tempminVal = 100, tempmaxVal = 0; + cv::minMaxLoc(result, &tempminVal, &tempmaxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + double offset_j = maxLoc.x + search_j; + double offset_i = maxLoc.y + search_i; + + //cv::Scalar mean1; + //cv::Mat stddevMat; + //cv::meanStdDev(templet_mat, mean1, stddevMat); + + + Tempmatchpoints(ii, 0) = double(j); //sim_x + Tempmatchpoints(ii, 1) = double(i); //sim_y + Tempmatchpoints(ii, 2) = offset_j; // sim_x + Tempmatchpoints(ii, 3) = offset_i; // sim_y + Tempmatchpoints(ii, 4) = tempmaxVal; // maxVal + Tempmatchpoints(ii, 5) = sig; // maxVal + + std::cout << 100.0*count/ BlockCount<<"\t:\t"<< count << " / " << BlockCount<<"\t" << Tempmatchpoints(ii, 0) << "\t" << Tempmatchpoints(ii, 1) << "\t" << Tempmatchpoints(ii, 2) + << "\t" << Tempmatchpoints(ii, 3) << "\t" << Tempmatchpoints(ii, 4) << "\t" << Tempmatchpoints(ii, 5) << endl; + count++; + } + + //BlockCount = 0; + count = 0; + for (int ii = 0; ii < BlockCount; ii++) { + if (Tempmatchpoints(ii, 4) > 0.7) { + std::cout << Tempmatchpoints(ii, 0) << "\t" << Tempmatchpoints(ii, 1) << "\t" << Tempmatchpoints(ii, 2) + << "\t" << Tempmatchpoints(ii, 3) << "\t" << Tempmatchpoints(ii, 4) << "\t" << Tempmatchpoints(ii, 5) << endl; + //BlockCount++; + count++; + } + } + + + + Eigen::MatrixXd matchpoints(count, 5); + count = 0; + for (int ii = 0; ii < BlockCount; ii++) { + if (Tempmatchpoints(ii, 4) > 0.7) { + matchpoints(count, 0)=Tempmatchpoints(ii, 0); //sim_x + matchpoints(count, 1) = Tempmatchpoints(ii, 1); //sim_y + matchpoints(count, 2) = Tempmatchpoints(ii, 2);// sim_x + matchpoints(count, 3) = Tempmatchpoints(ii, 3);// sim_y + matchpoints(count, 4) = Tempmatchpoints(ii, 4); // maxVal + count++; + } + } + + + /* + // step 1: 粗匹配,分块均匀匹配 + std::cout << "rough match , begining : \t" << getCurrentTimeString() << endl; + double offset_x = 0, offset_y = 0; + cv::Mat mask = sim; + cv::Mat temp_ori = ori; + int offsetcount = 0; + Eigen::MatrixXd matchpoints; + { + int row_count = ori.rows; + int col_count = ori.cols; + int count = 0; + for (int i = roughSize; i < row_count; i = i + roughSize + 500) { // y + for (int j = roughSize; j < col_count; j = j + roughSize + 200) { //x + count = count + 1; + } + } + matchpoints= Eigen::MatrixXd::Zero(count, 5);//ori_x,ori_y,sim_x,sim_y,maxval + + double minVal = 100, maxVal = 0.7; + omp_lock_t lock; + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + omp_init_lock(&lock); // 初始化互斥锁 + count = 0; + int search_count = 0; + #pragma omp parallel for num_threads(8) + for (int i = roughSize; i < row_count; i = i + roughSize+ 500) { // y + double tempminVal = 100, tempmaxVal = 0; + cv::Mat templet_mat; + cv::Mat result; + for (int j = roughSize; j < col_count; j = j + roughSize+ 200) { //x + templet_mat = ori(Rect(j - roughSize, i - roughSize, roughSize, roughSize)); + matchTemplate(sim, templet_mat, result, cv::TM_CCOEFF_NORMED); + //normalize(result, result, 1, 0, cv::NORM_MINMAX); + // 通过函数 minMaxLoc 定位最匹配的位置; + omp_set_lock(&lock); //获得互斥器 + Point minLoc; + Point maxLoc; + Point matchLoc; + cv::minMaxLoc(result, &tempminVal, &tempmaxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + if (tempmaxVal >= maxVal) { + offset_x = maxLoc.x - (j - roughSize); + offset_y = maxLoc.y - (i - roughSize); + //maxVal = tempmaxVal; + + matchpoints(count, 0) = (j - roughSize); //ori_x + matchpoints(count, 1) = (i - roughSize); //ori_y + double temp= maxLoc.x; + matchpoints(count, 2) = temp; // sim_x + temp = maxLoc.y; + matchpoints(count, 3) = temp; // sim_y + matchpoints(count, 4) = tempmaxVal; // maxVal + count = count + 1; + + offsetcount += 1; + } + search_count = search_count + 1; + std::cout << j - roughSize << "\t" << i - roughSize << "\t" << maxLoc.x << "\t" << maxLoc.y << "\t" << tempmaxVal << "\t" << search_count << "\t" << matchpoints.rows() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + } + omp_destroy_lock(&lock); //销毁互斥器 + offset_x = offset_x*1.0 / offsetcount; + offset_y = offset_y * 1.0 / offsetcount; + std::cout << "rough match point : "<< offsetcount <<"\n" << endl; + std::cout << "offset X : \t" << offset_x << endl; + std::cout << "offset Y : \t" << offset_y << endl; + std::cout << "maxVal : \t" << maxVal << endl; + } + std::cout << "rough match out : \t" << getCurrentTimeString() << endl; + // step1.1: 粗匹配绘制结果 + + std::string rough_math_path = sim_sum_path; + boost::algorithm::replace_last(rough_math_path, ".", "_ori_in_sim."); + std::cout << "ori in sim :\t" << rough_math_path << endl; + cv::Mat ori_in_sim = sim; + cv::rectangle(ori_in_sim, cv::Point(offset_x, offset_y), Point(offset_x + ori.cols, offset_y + ori.rows), Scalar(0, 255, 0), 2, 8, 0); + + vector compression_params; + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); //选择jpeg + compression_params.push_back(100); //在这个填入你要的图片质量 + cv::Mat out = ori_in_sim; + cv::imwrite(rough_math_path, out, compression_params); + + + if (offsetcount == 0) { // 表示全局粗匹配失败,无法进行精校准,考虑直接定位法 + std::cout << "there are not effective point in rought match \t" << endl; + return Eigen::MatrixXd(0, 5); + } + + Eigen::MatrixXd matchpointstemp(offsetcount,5); + for (int i = 0; i < matchpoints.rows(); i++) { + if (matchpoints(i, 4) > 0.7) { + for (int j = 0; j < matchpoints.cols(); j++) { + matchpointstemp(i, j) = matchpoints(i, j); + } + } + } + matchpoints = matchpointstemp; + */ + + + //std::cout << "rough match , overing : \t" << getCurrentTimeString() << endl; + //// step 2: 精匹配, + //std::cout << "Precise match , begining : \t" << getCurrentTimeString() << endl; + //Eigen::MatrixXd matchpoints; + //{ + + // int row_count = ori.rows; + // int col_count = ori.cols; + + // int count = 0; + + // for (int i = PreciseSize; i < row_count; i = i + preciseStep) { // y + // for (int j = PreciseSize; j < col_count; j = j + preciseStep) { //x + // count = count + 1; + // } + // } + + // matchpoints(count, 5);//ori_x,ori_y,sim_x,sim_y,maxval + // double templeta_size = PreciseSize * scale; + // double search_size = searchSize * scale; + // count = 0; + // double ori_start_x, ori_start_y; + // double sim_start_x, sim_start_y; + // row_count = row_count - PreciseSize; + // col_count = col_count - PreciseSize; + // omp_lock_t lock; + // omp_init_lock(&lock); // 初始化互斥锁 + // // 以搜索范围为核心计算 + // #pragma omp parallel for num_threads(8) + // for (int i = searchSize + offset_y; i < row_count; i = i + preciseStep) { // y + // cv::Mat templet_mat; + // cv::Mat search_mat; + // cv::Mat resample_templet_mat; + // cv::Mat resample_search_mat; + // cv::Mat result; + // double minVal = 100, maxVal = 0; + // for (int j = searchSize + offset_x; j < col_count; j = j + preciseStep) { //x + // // 计算 起始点 + // sim_start_x = j - searchSize; + // sim_start_y = i - searchSize; + + // ori_start_x = (j - searchSize / 2) - PreciseSize / 2; + // ori_start_y = (i - searchSize / 2) - PreciseSize / 2; + // // 匹配模板,待匹配模板 + // templet_mat = ori(Rect(ori_start_x, ori_start_y, PreciseSize, PreciseSize)); + // search_mat = ori(Rect(sim_start_x, sim_start_y, searchSize, searchSize)); + + // resample_templet_mat = resampledMat(templet_mat, templeta_size); + // resample_search_mat = resampledMat(search_mat, search_size); + + // matchTemplate(sim, templet_mat, result, cv::TM_CCORR_NORMED); + // // 通过函数 minMaxLoc 定位最匹配的位置; + // cv::Point minLoc; cv::Point maxLoc; + // cv::Point matchLoc; + // cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + // if (maxVal > 0.7) { + // omp_set_lock(&lock); //获得互斥器 + // + // matchpoints(count, 0) = ori_start_x; //ori_x + // matchpoints(count, 1) = ori_start_y; //ori_y + + // matchpoints(count, 2) = sim_start_x + maxLoc.x * 1.0 / scale; // sim_x + // matchpoints(count, 3) = sim_start_y + maxLoc.y * 1.0 / scale; // sim_y + // matchpoints(count, 4) = maxVal; // maxVal + // count = count + 1; + // + // omp_unset_lock(&lock); //释放互斥器 + // } + // } + // } + // omp_destroy_lock(&lock); //销毁互斥器 + + //} + // + std::cout << "Precise match , ending : \t" << getCurrentTimeString() << endl; + std::cout << "=======================================================================" << endl; + std::cout << "match point result: \t" << getCurrentTimeString() << endl; + std::cout << "=======================================================================" << endl; + + { + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + int count = matchpoints.rows(); + for (int i = 0; i < count; i++) { + std::cout << matchpoints(i, 0) << "\t" << matchpoints(i, 1) << "\t" << matchpoints(i, 2) << "\t" << matchpoints(i, 3) << "\t" << matchpoints(i, 4) << endl; + } + + } + std::cout << "=======================================================================" << endl; + return matchpoints; +} + +Eigen::MatrixXd ImageMatch::CreateMatchModel(Eigen::MatrixXd offsetXY_matrix) +{ + // ori_x,oir_y,to_x,to_y,maxval + // 0 1 2 3 4 + Eigen::MatrixXd offset_x= offsetXY_matrix.col(2) - offsetXY_matrix.col(0); + Eigen::MatrixXd offset_y = offsetXY_matrix.col(3) - offsetXY_matrix.col(1); + // 计算最小二乘法模型 + + Eigen::MatrixXd temp(offset_x.rows(), 6); + temp.col(0) = temp.col(0).array()*0+1; //1 + temp.col(1) = offsetXY_matrix.col(3).array(); // r + temp.col(2) = offsetXY_matrix.col(2).array(); // c + temp.col(3) = offsetXY_matrix.col(3).array().pow(2);//r2 + temp.col(4) = offsetXY_matrix.col(2).array().pow(2);//c2 + temp.col(5) = offsetXY_matrix.col(2).array()* offsetXY_matrix.col(3).array();//r*c + Eigen::MatrixXd matchmodel(2, 6); + Eigen::MatrixXd tempx= temp.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(offset_x);//x c + Eigen::MatrixXd tempy = temp.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(offset_y);//y r + matchmodel.row(1) = tempx; + matchmodel.row(0) = tempy; + return matchmodel; +} + +Eigen::MatrixXd ImageMatch::correctMatchModel(Eigen::MatrixXd r, Eigen::MatrixXd c) +{ + Eigen::MatrixXd a0 = Eigen::MatrixXd::Ones(1,r.cols()); + Eigen::MatrixXd a1 = r.array(); + Eigen::MatrixXd a2 = c.array(); + Eigen::MatrixXd a3 = r.array().pow(2); + Eigen::MatrixXd a4 = c.array().pow(2); + Eigen::MatrixXd a5 = r.array() * c.array(); + + + Eigen::MatrixXd offset(2, r.cols());//r,c + offset.row(0) = r.array() + this->match_model(0, 0) * a0.array() + this->match_model(0, 1) * a1.array() + this->match_model(0, 2) * a2.array() + this->match_model(0, 3) * a3.array() + this->match_model(0, 4) * a4.array() + this->match_model(0, 5) * a5.array(); + offset.row(1) = c.array() + this->match_model(1, 0) * a0.array() + this->match_model(1, 1) * a1.array() + this->match_model(1, 2) * a2.array() + this->match_model(1, 3) * a3.array() + this->match_model(1, 4) * a4.array() + this->match_model(1, 5) * a5.array(); + + return offset; +} + +int ImageMatch::outMatchModel(std::string matchmodel_path) +{ + ofstream fout(matchmodel_path, ios::trunc); + fout << "model:" << endl; + fout << this->match_model(0, 0) << " " << this->match_model(0, 1) << " " << this->match_model(0, 2) << " " << this->match_model(0, 3) << " " << this->match_model(0, 4) << " " << this->match_model(0, 5) << endl; + fout << this->match_model(1, 0) << " " << this->match_model(1, 1) << " " << this->match_model(1, 2) << " " << this->match_model(1, 3) << " " << this->match_model(1, 4) << " " << this->match_model(1, 5) << endl; + fout << "model_points:" << endl; + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + int count = this->offsetXY_matrix.rows(); + for (int i = 0; i < count; i++) { + std::cout << this->offsetXY_matrix(i, 0) << "\t" << this->offsetXY_matrix(i, 1) << "\t" << this->offsetXY_matrix(i, 2) << "\t" << this->offsetXY_matrix(i, 3) << "\t" << this->offsetXY_matrix(i, 4) << endl; + } + fout.close(); + return 0; +} + +/// +/// 读取jpg 文件 +/// +/// +/// +cv::Mat openJPG(std::string jpg_path) +{ + cv::Mat image = cv::imread(jpg_path); + if (image.data == nullptr) //nullptr是c++11新出现的空指针常量 + { + throw new exception("图片文件不存在"); + } + return image; +} + +cv::Mat resampledMat(cv::Mat& image, int targetSize, int interpolation) +{ + cv::Mat out; + cv::resize(image, out, cv::Size(targetSize, targetSize), interpolation); + return out; +} diff --git a/simorthoprogram-orth_gf3-strip/ImageMatch.h b/simorthoprogram-orth_gf3-strip/ImageMatch.h new file mode 100644 index 0000000..0ec0a56 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/ImageMatch.h @@ -0,0 +1,39 @@ +#pragma once +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include +#include +#include +#include + +using namespace std; +using namespace Eigen; +class ImageMatch +{ +public: + int gdal2JPG(std::string gdal_path,std::string jpg_path,int band_ids); + Eigen::MatrixXd ImageMatch_ori_sim(std::string ori_power_path, std::string sim_sum_path, int roughSize=500, int Precise=300,int scale=5, int searchSize=1000,int roughStep=400 ,int preciseStep=300); + Eigen::MatrixXd CreateMatchModel(Eigen::MatrixXd offsetXY_matrix); + + Eigen::MatrixXd correctMatchModel(Eigen::MatrixXd r, Eigen::MatrixXd c); + + int outMatchModel(std::string matchmodel_path); + //参数 + Eigen::MatrixXd offsetXY_matrix; + Eigen::MatrixXd match_model; +}; + +cv::Mat openJPG(std::string jpg_path); +cv::Mat resampledMat(cv::Mat& templet, int targetSize, int interpolation = cv::INTER_AREA); diff --git a/simorthoprogram-orth_gf3-strip/OctreeNode.cpp b/simorthoprogram-orth_gf3-strip/OctreeNode.cpp new file mode 100644 index 0000000..027e74e --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/OctreeNode.cpp @@ -0,0 +1 @@ +#include "OctreeNode.h" diff --git a/simorthoprogram-orth_gf3-strip/OctreeNode.h b/simorthoprogram-orth_gf3-strip/OctreeNode.h new file mode 100644 index 0000000..4378f3f --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/OctreeNode.h @@ -0,0 +1,264 @@ +#pragma once +#include +using namespace std; +//定义八叉树节点类 +template +struct OctreeNode +{ + T data; //节点数据 + T xmin, xmax; //节点坐标,即六面体个顶点的坐标 + T ymin, ymax; + T zmin, zmax; + OctreeNode * top_left_front, * top_left_back; //该节点的个子结点 + OctreeNode * top_right_front, * top_right_back; + OctreeNode * bottom_left_front, * bottom_left_back; + OctreeNode * bottom_right_front, * bottom_right_back; + OctreeNode //节点类 + (T nodeValue = T(), + T xminValue = T(), T xmaxValue = T(), + T yminValue = T(), T ymaxValue = T(), + T zminValue = T(), T zmaxValue = T(), + OctreeNode* top_left_front_Node = NULL, + OctreeNode* top_left_back_Node = NULL, + OctreeNode* top_right_front_Node = NULL, + OctreeNode* top_right_back_Node = NULL, + OctreeNode* bottom_left_front_Node = NULL, + OctreeNode* bottom_left_back_Node = NULL, + OctreeNode* bottom_right_front_Node = NULL, + OctreeNode* bottom_right_back_Node = NULL) + :data(nodeValue), + xmin(xminValue), xmax(xmaxValue), + ymin(yminValue), ymax(ymaxValue), + zmin(zminValue), zmax(zmaxValue), + top_left_front(top_left_front_Node), + top_left_back(top_left_back_Node), + top_right_front(top_right_front_Node), + top_right_back(top_right_back_Node), + bottom_left_front(bottom_left_front_Node), + bottom_left_back(bottom_left_back_Node), + bottom_right_front(bottom_right_front_Node), + bottom_right_back(bottom_right_back_Node) {} +}; +//创建八叉树 +template +void createOctree(OctreeNode*& root, int maxdepth, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) +{ + //cout<<"处理中,请稍候……"<= 0) + { + root = new OctreeNode(); + //cout << "请输入节点值:"; + //root->data =9;//为节点赋值,可以存储节点信息,如物体可见性。由于是简单实现八叉树功能,简单赋值为9。 + cin >> root->data; //为节点赋值 + root->xmin = xmin; //为节点坐标赋值 + root->xmax = xmax; + root->ymin = ymin; + root->ymax = ymax; + root->zmin = zmin; + root->zmax = zmax; + double xm = (xmax - xmin) / 2;//计算节点个维度上的半边长 + double ym = (ymax - ymin) / 2; + double zm = (ymax - ymin) / 2; + //递归创建子树,根据每一个节点所处(是几号节点)的位置决定其子结点的坐标。 + createOctree(root->top_left_front, maxdepth, xmin, xmax - xm, ymax - ym, ymax, zmax - zm, zmax); + createOctree(root->top_left_back, maxdepth, xmin, xmax - xm, ymin, ymax - ym, zmax - zm, zmax); + createOctree(root->top_right_front, maxdepth, xmax - xm, xmax, ymax - ym, ymax, zmax - zm, zmax); + createOctree(root->top_right_back, maxdepth, xmax - xm, xmax, ymin, ymax - ym, zmax - zm, zmax); + createOctree(root->bottom_left_front, maxdepth, xmin, xmax - xm, ymax - ym, ymax, zmin, zmax - zm); + createOctree(root->bottom_left_back, maxdepth, xmin, xmax - xm, ymin, ymax - ym, zmin, zmax - zm); + createOctree(root->bottom_right_front, maxdepth, xmax - xm, xmax, ymax - ym, ymax, zmin, zmax - zm); + createOctree(root->bottom_right_back, maxdepth, xmax - xm, xmax, ymin, ymax - ym, zmin, zmax - zm); + } +} +int i = 1; +//先序遍历八叉树 +template +void preOrder(OctreeNode*& p) +{ + if (p) + { + //cout << i << ".当前节点的值为:" << p->data << "\n坐标为:"; + //cout << "xmin: " << p->xmin << " xmax: " << p->xmax; + //cout << "ymin: " << p->ymin << " ymax: " << p->ymax; + //cout << "zmin: " << p->zmin << " zmax: " << p->zmax; + i += 1; + cout << endl; + preOrder(p->top_left_front); + preOrder(p->top_left_back); + preOrder(p->top_right_front); + preOrder(p->top_right_back); + preOrder(p->bottom_left_front); + preOrder(p->bottom_left_back); + preOrder(p->bottom_right_front); + preOrder(p->bottom_right_back); + cout << endl; + } +} +//求八叉树的深度 +template +int depth(OctreeNode*& p) +{ + if (p == NULL) + return -1; + int h = depth(p->top_left_front); + return h + 1; +} +template +int num(OctreeNode*& p) +{ + if (p == NULL) + return 0; + return 1 + num(p->top_left_front) + num(p->top_left_back) + num(p->top_right_back) + num(p->top_right_front) + num(p->bottom_left_back) + num(p->bottom_left_front) + num(p->bottom_right_back) + num(p->bottom_right_front); +} +//计算单位长度,为查找点做准备 +int cal(int num) +{ + int result = 1; + if (1 == num) + result = 1; + else + { + for (int i = 1; i < num; i++) + result = 2 * result; + } + return result; +} + +template +int find(OctreeNode*& p, double x, double y, double z) +{ + //查找点 + int maxdepth = 0; + int times = 0; + static double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0; + int tmaxdepth = 0; + double txm = 1, tym = 1, tzm = 1; + + double xm = (p->xmax - p->xmin) / 2; + double ym = (p->ymax - p->ymin) / 2; + double zm = (p->ymax - p->ymin) / 2; + times++; + if (x > xmax || xymax || yzmax || z < zmin) + { + //cout << "该点不在场景中!" << endl; + return 0; + } + if (x <= p->xmin + txm && x >= p->xmax - txm && y <= p->ymin + tym && y >= p->ymax - tym && z <= p->zmin + tzm && z >= p->zmax - tzm) + { + //cout << endl << "找到该点!" << "该点位于" << endl; + //cout << "xmin: " << p->xmin << " xmax: " << p->xmax; + //cout << "ymin: " << p->ymin << " ymax: " << p->ymax; + //cout << "zmin: " << p->zmin << " zmax: " << p->zmax; + //cout << "节点内!" << endl; + //cout << "共经过" << times << "次递归!" << endl; + return 1; + } + else if (x < (p->xmax - xm) && y < (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_left_back, x, y, z); + } + else if (x < (p->xmax - xm) && y<(p->ymax - ym) && z>(p->zmax - zm)) + { + find(p->top_left_back, x, y, z); + } + else if (x > (p->xmax - xm) && y < (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_right_back, x, y, z); + } + else if (x > (p->xmax - xm) && y<(p->ymax - ym) && z>(p->zmax - zm)) + { + find(p->top_right_back, x, y, z); + } + else if (x<(p->xmax - xm) && y>(p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_left_front, x, y, z); + } + else if (x<(p->xmax - xm) && y>(p->ymax - ym) && z > (p->zmax - zm)) + { + find(p->top_left_front, x, y, z); + } + else if (x > (p->xmax - xm) && y > (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_right_front, x, y, z); + } + else if (x > (p->xmax - xm) && y > (p->ymax - ym) && z > (p->zmax - zm)) + { + find(p->top_right_front, x, y, z); + } +} +//main函数 +/* +int main() +{ + OctreeNode* rootNode = NULL; + int choiced = 0; + cout << "系统开始前请先创建八叉树" << endl; + cout << "请输入最大递归深度:" << endl; + cin >> maxdepth; + cout << "请输入外包盒坐标,顺序如下:xmin,xmax,ymin,ymax,zmin,zmax" << endl; + cin >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax; + if (maxdepth >= 0 || xmax > xmin || ymax > ymin || zmax > zmin || xmin > 0 || ymin > 0 || zmin > 0) + { + tmaxdepth = cal(maxdepth); + txm = (xmax - xmin) / tmaxdepth; + tym = (ymax - ymin) / tmaxdepth; + tzm = (zmax - zmin) / tmaxdepth; + createOctree(rootNode, maxdepth, xmin, xmax, ymin, ymax, zmin, zmax); + } + while (true) + { + system("cls"); + + cout << "请选择操作:\n"; + cout << "\t1.计算空间中区域的个数\n"; + cout << "\t2.先序遍历八叉树\n"; + cout << "\t3.查看树深度\n"; + cout << "\t4.查找节点 \n"; + cout << "\t0.退出\n"; + cin >> choiced; + + if (choiced == 0) + return 0; + if (choiced == 1) + { + system("cls"); + cout << "空间区域个数" << endl; + cout << num(rootNode); + } + + if (choiced == 2) + { + system("cls"); + cout << "先序遍历八叉树结果:/n"; + i = 1; + preOrder(rootNode); + cout << endl; + system("pause"); + } + if (choiced == 3) + { + system("cls"); + int dep = depth(rootNode); + cout << "此八叉树的深度为" << dep + 1 << endl; + system("pause"); + } + if (choiced == 4) + { + system("cls"); + cout << "请输入您希望查找的点的坐标,顺序如下:x,y,z\n"; + double x, y, z; + cin >> x >> y >> z; + times = 0; + cout << endl << "开始搜寻该点……" << endl; + find(rootNode, x, y, z); + system("pause"); + } + else + { + system("cls"); + cout << "\n\n错误选择!\n"; + system("pause"); + } + } +*/ \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp new file mode 100644 index 0000000..653016f --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp @@ -0,0 +1,49 @@ +锘// ConsoleApplication1.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + + + +#include +#include +#include +#include + +//#include + +//using namespace arma; +using namespace std; +using namespace Eigen; + +int main(int argc, char* argv[]) +{ + cout << cos(30) << endl; + cout << cos(45) << endl; + cout << cos(60) << endl; + cout << pow(1, 3) << endl; + cout << pow(2, 3) << endl; + + Eigen::MatrixXd a = Eigen::MatrixXd::Ones(6, 3); // 闅忔満鍒濆鍖栫煩闃 + Eigen::MatrixXd b = Eigen::MatrixXd::Ones(6,3).array()*2; + Eigen::Vector3d p(3, 1, 2); + double start = clock(); + Eigen::MatrixXd c = (a.array()/b.array());// .rowwise().sum(); + double endd = clock(); + double thisTime = (double)(endd - start) / CLOCKS_PER_SEC; + + cout << thisTime << endl; + cout << c.rows() << "," << c.cols() << endl; + cout << c(Eigen::all, { 0,1}) << endl; + system("PAUSE"); + return 0; +} + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj new file mode 100644 index 0000000..e8a092c --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {db6d05f9-271e-4954-98ed-591ab27bb05e} + ConsoleApplication1 + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + Parallel + + + + + + + + + + + + + + + + + + + + + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files %28x86%29\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;C:\Program Files %28x86%29\Intel\oneAPI\mkl\2022.1.0\lib\intel64;$(oneMKLOmpLibDir);$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + mkl_scalapack_ilp64.lib;mkl_cdft_core.lib;mkl_intel_ilp64.lib;mkl_sequential.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;impi.lib;mkl_intel_thread.lib;libiomp5md.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters new file mode 100644 index 0000000..18f4605 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters @@ -0,0 +1,22 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp new file mode 100644 index 0000000..490b3e3 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp @@ -0,0 +1,191 @@ +锘// PSTM_simulation_windows.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + +#include +#include +#include +#include +#include +#include +#include "ParameterInFile.h" +#include 銆銆 +#include +// +// 寮曠敤鍙橀噺鐨勭┖闂 +// +using namespace std; + + +int test(ParameterInFile parmas) { + cout << parmas.doppler_para[0] << endl; + return 0; +} + +/// +/// 妫鏌ョ幆澧冿紝涓昏妫鏌ュ唴瀛樻儏鍐 +/// +/// +/// +bool check(ParameterInFile& parmas) { + + return true; +} + +sim_block testsimblock(int a = 1) { + sim_block result(1, 2, 1, 2, 1, 1); + return result; +} + +int Fmaintest() { + sim_block temp = testsimblock(1); + point lla = point{ 110,22,33 }; + point xyz = point{ -2023567.6297546995,5559706.3694903487,2374425.2573203994 }; + point ttxyz = LLA2XYZ(lla); + point ttlla = XYZ2LLA(xyz); + VectorPoint v1 = getVector(xyz, ttxyz); + VectorPoint v2 = getVector(lla, ttlla); + cout << getModule(v1) << std::endl; + cout << getModule(v2) << std::endl; + return 0; +} + + + + +int main(int argc, char* argv[]) +{ + // try { + testPP(); + + + std::cout << "PSTM_simulation_windows.exe [mode] [pars_path] [resample_para] [--thead_num]" << endl;// 杈撳嚭甯姪鏂囨。 + std::cout << "[mode]: 璋冪敤妯″潡 0,1,2 " << endl; + std::cout << " 0:榛樿璺緞 " << endl; + std::cout << " 1:璁$畻姝e皠妯℃嫙鍥 " << endl; + std::cout << " 2:璁$畻姝e皠鏍℃鎻掑肩畻娉曚笌寮哄害鍥剧敓鎴 " << endl; + std::cout << "[para_path]:蹇呴 姝e皠妯℃嫙鍙傛暟鏂囦欢 " << endl; + std::cout << "[resample_para]:褰搈ode==2鏃讹紝蹇呴夛紱 璁$畻姝e皠鏍℃鎻掑肩畻娉曚笌寮哄害鍥剧敓鎴愬弬鏁版枃浠 " << endl; + std::cout << "[--thead_num]:鍙 绾跨▼鏁帮紝榛樿鏄8" << endl; + std::cout << "example:" << endl; + std::cout << "PSTM_simulation_windows.exe 2 C:\\sim_sar_paras.txt D:\\resample_para.txt --thead_num 8" << endl; + int mode = -1; + int thread_num = 6; + std::string pars_path = ""; //閰嶇疆鏂囦欢浠g爜 + std::string resample_para = ""; + std::string thread_str = "--thead_num"; + try { + if (argc < 3) { + std::cout << "缂哄皯鍙傛暟" << endl; + //return 0; + } + for (int i = 1; i < argc; i++) { + if (i == 1) { + mode = stoi(argv[1]); + if (mode == 0) { + pars_path = "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace4\\sim_sar_paras.txt"; + resample_para = "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace4\\resample_para.txt"; + mode = 2; + break; + } + } + if (i == 2) { + pars_path= argv[2]; + } + if (i == 3) { + if (mode == 1) { + break; + } + else { + resample_para = argv[3]; + } + } + } + + for (int i = 1; i < argc; i++) { + std::string temp = argv[i]; + + + if (temp== thread_str) { + i = i + 1; + + if (i >= argc) { break; } + else { + thread_num = stoi(argv[i]); + + } + } + } + } + catch(exception ex) { + std::cout << "鍙傛暟瑙f瀽閿欒" << endl; + // 寮濮媡est妯″紡 + + return -1; + + } + if (1) { + pars_path = "D:\\MicroWorkspace\\C-SAR\\Ortho\\Temporary\\sim_sar_paras.txt"; + resample_para = "";// "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace\\resample_para.txt"; + mode = 1; + } + + std::cout << "绾跨▼鏁帮細" << thread_num << endl; + //Fmaintest(); + + cout << mode << "\n"; + int d=round(3.13); + if (mode == 1) { + cout << "sim_sar program run....\n"; + cout << pars_path << "\n"; + ParameterInFile parmas(pars_path); + //testPTSN(parmas); + if (!check(parmas)) { + throw "涓嶇鍚堣繍琛屾潯浠"; + return 0; + } + //SimProcess(parmas, 32); + SimProcess_LVY(parmas, thread_num); + // ResamplingSim(parmas); + // 妫鏌ヨВ鏋愮粨鏋 + cout << "programover" << "\n"; + } + + else if (mode == 2) { + try { + ConvertResampleParameter converPara(resample_para); + ParameterInFile parmas(pars_path); + testPTSN(pars_path); + SimProcess_Calsim2ori(parmas, converPara, thread_num); + SimProcess_ResamplingOri2Orth(parmas, converPara, thread_num); + SimProcess_Calspow(parmas, converPara, thread_num); + } + catch(exception& ex) { + std::cout << ex.what() << std::endl; + return -1; + } + //SimProcess_CalXYZ(parmas, converPara,16); + //ConverOri2Sim(parmas, converPara); + //CalCoondinaryXYZOfSAR(parmas, converPara); + } + + + // } + //catch (exception ex) { + // 闃叉鍐呭瓨娉勯湶锛屼繚璇佸唴瀛樿兘澶熻璋冪敤 + // throw "error"; + // } + +} + + + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln new file mode 100644 index 0000000..86e7524 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln @@ -0,0 +1,41 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32602.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSTM_simulation_windows", "PSTM_simulation_windows.vcxproj", "{418EA1F3-8583-4728-ABC4-45B98FC053BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConsoleApplication1", "..\ConsoleApplication1\ConsoleApplication1.vcxproj", "{DB6D05F9-271E-4954-98ED-591AB27BB05E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x64.ActiveCfg = Debug|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x64.Build.0 = Debug|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x86.ActiveCfg = Debug|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x86.Build.0 = Debug|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x64.ActiveCfg = Release|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x64.Build.0 = Release|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x86.ActiveCfg = Release|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x86.Build.0 = Release|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x64.ActiveCfg = Debug|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x64.Build.0 = Debug|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x86.ActiveCfg = Debug|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x86.Build.0 = Debug|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x64.ActiveCfg = Release|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x64.Build.0 = Release|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x86.ActiveCfg = Release|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2C843D5-F54A-4745-908B-8387B47D60A3} + EndGlobalSection +EndGlobal diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj new file mode 100644 index 0000000..6a2d7a8 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj @@ -0,0 +1,169 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {418ea1f3-8583-4728-abc4-45b98fc053bf} + PSTMsimulationwindows + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + No + + + Application + false + v143 + true + Unicode + Parallel + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + $(ExternalIncludePath) + $(SolutionDir)bin\$(Platform)\$(Configuration) + + + false + $(ExternalIncludePath) + $(LibraryPath) + $(SolutionDir)bin\$(Platform)\$(Configuration) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + MultiThreaded + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + + + Console + true + true + true + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp new file mode 100644 index 0000000..7dfb32e --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp @@ -0,0 +1,2100 @@ +#include "ParameterInFile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +////gdal +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "common.h" + + +using namespace std; +// +// 参数文件解析 +// + +//参数文件标准格式 +// 文件值 类型 对应的代号 +// DEM文件的路径 str dem_path +// 模拟影像输出路径 str sar_sim_path +// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path +// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path +// 采样率 long double sample_f +// 近斜距 long double R0 +// 成像起始时间 long double starttime ---UTC 时间 +// 光速 long double +// 波长 long double +// 多普勒参考时间 long double TO ---UTC 时间 +// 脉冲重复频率 long double PRF +// 斜距采样间隔 long double delta_R +// 多普勒系数个数 int +// 多普勒系数1 long double +// 多普勒系数2 long double +// .... +// 卫星轨道模型是否为多项式模型 +// 卫星轨道模型多项式次数 int 4 5 +// 卫星轨道模型X值系数1 long double +// .... +// 卫星轨道模型Y值系数1 long double +// ... +// 卫星轨道模型Z值系数1 long double +// ... +// 卫星轨道模型Vx值系数1 long double +// ... +// 卫星轨道模型Vy值系数1 long double +// ... +// 卫星轨道模型Vz值系数1 long double +// ... +// +// + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +point XYZ2LLA(point& XYZ) { + long double tmpX = XYZ.x; + long double temY = XYZ.y; + long double temZ = XYZ.z; + + long double curB = 0; + long double N = 0; + long double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + long double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + long double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + point result = { 0,0,0 }; + result.x = atan2(temY, tmpX) * r2d; + result.y = curB * r2d; + result.z = temZ / sinCurB - N * (1 - eSquare); + return result; +} + + +ParameterInFile::ParameterInFile(std::string infile_path) +{ + // 解析文件 + ifstream infile(infile_path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + getline(infile, buf); this->dem_path = buf; + getline(infile, buf); this->out_sar_sim_path = buf; + getline(infile, buf); this->out_sar_sim_dem_path = buf; + getline(infile, buf); this->out_sar_sim_resampling_path = buf; + getline(infile, buf); this->out_sar_sim_resampling_rc = buf; + getline(infile, buf); this->sim_height = stoi(buf); + getline(infile, buf); this->sim_width = stoi(buf); + getline(infile, buf); this->sar_sim_match_point_path = buf; + getline(infile, buf); this->sar_sim_match_point_xyz_path = buf; + + getline(infile, buf); this->sample_f = stoi(buf); + getline(infile, buf); this->R0 = stod(buf); + getline(infile, buf); this->LightSpeed = stod(buf); + getline(infile, buf); this->lamda = stod(buf); + getline(infile, buf); this->delta_R = stod(buf); + getline(infile, buf); this->imgStartTime = stod(buf); + getline(infile, buf); this->PRF = stod(buf); + getline(infile, buf); this->delta_t = stod(buf); + getline(infile, buf); this->refrange = stod(buf); + getline(infile, buf); this->widthspace = stod(buf); + getline(infile, buf); cout << buf << endl; + + getline(infile, buf); this->doppler_paramenter_number = stoi(buf); + + // 读取多普勒系数 + this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double)); + if (this->doppler_para) { + for (int i = 0; i < this->doppler_paramenter_number; i++) { + getline(infile, buf); + this->doppler_para[i] = stod(buf); + } + } + else { + throw "内存不足"; + } + // 读取卫星轨道 + getline(infile, buf); this->polySatelliteModel = stoi(buf); + if (this->polySatelliteModel != 1) { + throw "不是多项式轨道模型"; + } + getline(infile, buf); this->polynum = stoi(buf) + 1; // 多项式项数 + getline(infile, buf); this->SatelliteModelStartTime = stod(buf); // 轨道模型起始时间 + + this->polySatellitePara = (long double*)calloc(this->polynum * 6, sizeof(long double)); + if (this->polySatellitePara) { + for (int i = 0; i < this->polynum * 6; i++) { + getline(infile, buf); + this->polySatellitePara[i] = stod(buf); + } + } + else { + throw "内存不足"; + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); +} + +ParameterInFile::ParameterInFile(const ParameterInFile& paras) +{ + //参数组 + this->dem_path = paras.dem_path; + this->out_sar_sim_path = paras.out_sar_sim_path; + this->out_sar_sim_dem_path = paras.out_sar_sim_dem_path; + this->out_sar_sim_resampling_path = paras.out_sar_sim_resampling_path; + this->out_sar_sim_resampling_rc = paras.out_sar_sim_resampling_rc; + this->sim_height = paras.sim_height; + this->sim_width = paras.sim_width; + this->sar_sim_match_point_path = paras.sar_sim_match_point_path; + this->sar_sim_match_point_xyz_path = paras.sar_sim_match_point_xyz_path; + this->sample_f = paras.sample_f; + this->R0 = paras.R0; + this->LightSpeed = paras.LightSpeed; + this->lamda = paras.lamda; + + this->delta_R = paras.delta_R; + this->imgStartTime = paras.imgStartTime; + this->PRF = paras.PRF; + this->delta_t = paras.delta_t; + this->refrange = paras.refrange; + // 多普勒 + this->widthspace = paras.widthspace; + this->doppler_paramenter_number = paras.doppler_paramenter_number; + //卫星轨道模型 + this->polySatelliteModel = paras.polySatelliteModel; + this->polynum = paras.polynum; + this->SatelliteModelStartTime = paras.SatelliteModelStartTime; + this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double)); + memcpy(this->doppler_para, paras.doppler_para, paras.doppler_paramenter_number * sizeof(long double)); + this->polySatellitePara = (long double*)calloc(paras.polynum * 6, sizeof(long double)); + memcpy(this->polySatellitePara, paras.polySatellitePara, paras.polynum * 6 * sizeof(long double)); +} + +ParameterInFile::~ParameterInFile() +{ + // 析构函数 + free(this->doppler_para); + free(this->polySatellitePara); +} + + +/// +/// 根据卫星轨道模型计算卫星 +/// +/// 卫星轨道点时间 +/// 卫星轨道模型起始时间 +/// 卫星轨道X坐标模型参数 +/// 卫星轨道Y坐标模型参数 +/// 卫星轨道Z坐标模型参数 +/// 卫星轨道Vx坐标模型参数 +/// 卫星轨道Vy坐标模型参数 +/// 卫星轨道Vz坐标模型参数 +/// 多项式项数 +/// +inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4) +{ + satelliteTime = satelliteTime - SatelliteModelStartTime; + SatelliteSpacePoint result_point = { 0,0,0,0,0,0 }; + + if (polynum <= 0)return result_point; + int ptr_indx = 0; + int yStep = polynum; + int zStep = polynum*2; + int vxStep = polynum*3; + int vyStep = polynum*4; + int vzStep = polynum*5; + //x + result_point.x += polySatellitePara[ptr_indx]; + result_point.y += polySatellitePara[ptr_indx + yStep]; + result_point.z += polySatellitePara[ptr_indx + zStep]; + result_point.vx += polySatellitePara[ptr_indx + vxStep]; + result_point.vy += polySatellitePara[ptr_indx + vyStep]; + result_point.vz += polySatellitePara[ptr_indx + vzStep]; + if (polynum == 1)return result_point; + ptr_indx++; + long double powTime = satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 2)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 3)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 4)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + ptr_indx++; + if (polynum == 5)return result_point; + for (int i = 5; i < polynum; i++) { + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx+ yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + ptr_indx++; + } + return result_point; +} + +inline SatelliteSpacePoint getSatellitePostion_orange(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4) +{ + satelliteTime = satelliteTime - SatelliteModelStartTime; + SatelliteSpacePoint result_point = { 0,0,0,0,0,0 }; + int ptr_indx = 0; + //x + for (int i = 0; i < polynum; i++) { + result_point.x += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + + //y + for (int i = 0; i < polynum; i++) { + result_point.y += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //z + for (int i = 0; i < polynum; i++) { + result_point.z += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vx + for (int i = 0; i < polynum; i++) { + result_point.vx += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vy + for (int i = 0; i < polynum; i++) { + result_point.vy += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vz + for (int i = 0; i < polynum; i++) { + result_point.vz += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + + return result_point; +} + +/// +/// 数值模拟法计算多普勒频移值 +/// 修改时间:2022.07.03 +/// +/// 斜距 +/// 光速 +/// 多普勒参考时间 +/// 多普勒参数 +/// 多普勒频移值 +inline long double calNumericalDopplerValue(long double R, long double LightSpeed, long double refrange, long double* doppler_para, int doppler_paramenter_number) +{ + //R = R * 2 / LightSpeed - T0; + long double result = 0; + result = doppler_para[0]; + R = (R - refrange) * (1000000 / LightSpeed); + for (int i = 1; i < doppler_paramenter_number; i++) { + result =result+ doppler_para[i]*pow(R,i); + } + return result; +} +/// +/// 根据理论模型计算多普勒频移值 +/// +/// 斜距 +/// 波长 +/// 地面->卫星的空间向量 +/// 地面->卫星之间的速度向量 +/// 多普勒频移值 +inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl) +{ + long double result = -2 * (R_sl.x * V_sl.x + R_sl.y * V_sl.y + R_sl.z * V_sl.z) / (lamda * R); + return result; +} + +/// +/// 根据地面点求解对应的sar影像坐标 +/// 修改2022.07.03 +/// +/// 地面点的坐标--地固坐标系 +/// 影片开始成像时间 +/// 波长 +/// 多普勒参考斜距 +/// 光速 +/// 时间间隔 +/// 近斜距 +/// 斜距间隔 +/// 卫星轨道模型时间 +/// 卫星轨道坐标模型参数 +/// 卫星轨道模型项数 +/// 多普勒模型数 +/// 影像坐标(x:行号,y:列号,z:成像时刻) +inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double refrange, long double* doppler_para, long double LightSpeed, long double prf, long double R0, long double widthspace, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum, int doppler_paramenter_number) +{ + long double ti = Starttime; + long double dt = 0.01; + long double R = 0; + long double FdThory1 = 0; + long double FdThory2 = 0; + long double FdNumber = 0; + long double FdTheory_grad = 0; + SatelliteSpacePoint spacepoint{ 0,0,0,0,0,0 }; + VectorPoint R_sl{ 0,0,0 }; + VectorPoint V_sl{ 0,0,0 }; + long double int_time = 0; + long double endfactor = 1e-4;//exp((floor(log10(1/prf))-1)* 2.302585092994046); + long double error = 0; + for (int i = 0; i < 100; i++) { + spacepoint = getSatellitePostion(ti + dt, SatelliteModelStartTime, polySatellitePara, polynum); + R_sl.x = spacepoint.x - landpoint.x; // 卫星->地面坐标 + R_sl.y = spacepoint.y - landpoint.y; // + R_sl.z = spacepoint.z - landpoint.z; + V_sl.x = spacepoint.vx; + V_sl.y = spacepoint.vy; + V_sl.z = spacepoint.vz; + R = getModule(R_sl); + FdThory1 = calTheoryDopplerValue(R, lamda, R_sl, V_sl); + spacepoint = getSatellitePostion(ti, SatelliteModelStartTime, polySatellitePara, polynum); + R_sl.x = spacepoint.x - landpoint.x; + R_sl.y = spacepoint.y - landpoint.y; + R_sl.z = spacepoint.z - landpoint.z; + V_sl.x = spacepoint.vx; + V_sl.y = spacepoint.vy; + V_sl.z = spacepoint.vz; + R = getModule(R_sl); + FdThory2 = calTheoryDopplerValue(R, lamda, R_sl, V_sl); + FdNumber = calNumericalDopplerValue(R, LightSpeed, refrange, doppler_para, doppler_paramenter_number); + FdTheory_grad = (FdThory1 - FdThory2); + error = FdNumber - FdThory2; + int_time = error * dt / FdTheory_grad; + if (abs(error) < endfactor) { + ti = ti + int_time; + break; + } + ti = ti + int_time; + } + point result{ 0,0,0 }; + result.x = (ti - Starttime) * prf; + result.y = (R - R0) / widthspace; + result.z = ti; + return result; +} + + +/// +/// 双线性插值 +/// 11 12 +/// c +/// 21 22 +/// +/// c的x,y坐标以左上角的行列号为起始点 +/// +/// +/// +/// +/// +inline point bilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22) +{ + long double r = 1 - p.x; + long double c = 1 - p.y; + + long double rc = r * c; + long double r_c_1 = r * p.y;// r* (1 - c); + long double r_1_c = p.x * c; //(1 - r) * c; + long double r_1_c_1 = p.x * p.y;// (1 - r)* (1 - c); + // 计算插值结果 + p.x = rc * p11.x + r_c_1 * p12.x + r_1_c * p21.x + r_1_c_1 * p22.x; + p.y = rc * p11.y + r_c_1 * p12.y + r_1_c * p21.y + r_1_c_1 * p22.y; + p.z = rc * p11.z + r_c_1 * p12.z + r_1_c * p21.z + r_1_c_1 * p22.z; + return p; +} + +/// +/// 三次卷积插值 +/// 11 12 13 14 +/// 21 22 23 24 +/// c +/// 31 32 33 34 +/// 41 42 43 44 +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +inline point cubicInterpolation(point& p, point& p11, point& p12, point& p13, point& p14, point& p21, point& p22, point& p23, point& p24, point& p31, point& p32, point& p33, point& p34, point& p41, point& p42, point& p43, point& p44) +{ + long double r = p.x; + long double c = p.y; + long double r1 = r, r2 = r - 1, r3 = 2 - r, r4 = 3 - r; + long double c1 = c, c2 = c - 1, c3 = 2 - c, c4 = 3 - c; + long double wr1 = 4 - 8 * r1 + 5 * r1 * r1 - r1 * r1 * r1; + long double wr2 = 1 - 2 * r2 * r2 + r2 * r2 * r2; + long double wr3 = 1 - 2 * r3 * r3 + r3 * r3 * r3; + long double wr4 = 4 - 8 * r4 + 5 * r4 * r4 - r4 * r4 * r4; + + long double wc1 = 4 - 8 * c1 + 5 * c1 * c1 - c1 * c1 * c1; + long double wc2 = 1 - 2 * c2 * c2 + c2 * c2 * c2; + long double wc3 = 1 - 2 * c3 * c3 + c3 * c3 * c3; + long double wc4 = 4 - 8 * c4 + 5 * c4 * c4 - c4 * c4 * c4; + + long double wr1_wc1 = wr1 * wc1; + long double wr2_wc1 = wr2 * wc1; + long double wr3_wc1 = wr3 * wc1; + long double wr4_wc1 = wr4 * wc1; + + long double wr1_wc2 = wr1 * wc2; + long double wr2_wc2 = wr2 * wc2; + long double wr3_wc2 = wr3 * wc2; + long double wr4_wc2 = wr4 * wc2; + + long double wr1_wc3 = wr1 * wc3; + long double wr2_wc3 = wr2 * wc3; + long double wr3_wc3 = wr3 * wc3; + long double wr4_wc3 = wr4 * wc3; + + long double wr1_wc4 = wr1 * wc4; + long double wr2_wc4 = wr2 * wc4; + long double wr3_wc4 = wr3 * wc4; + long double wr4_wc4 = wr4 * wc4; + + p.x = 0; + p.x = p.x + wr1_wc1 * p11.x + wr1_wc2 * p12.x + wr1_wc3 * p13.x + wr1_wc4 * p14.x; + p.x = p.x + wr2_wc1 * p11.x + wr2_wc2 * p12.x + wr2_wc3 * p13.x + wr2_wc4 * p14.x; + p.x = p.x + wr3_wc1 * p11.x + wr3_wc2 * p12.x + wr3_wc3 * p13.x + wr3_wc4 * p14.x; + p.x = p.x + wr4_wc1 * p11.x + wr4_wc2 * p12.x + wr4_wc3 * p13.x + wr4_wc4 * p14.x; + + p.y = 0; + p.y = p.y + wr1_wc1 * p11.y + wr1_wc2 * p12.y + wr1_wc3 * p13.y + wr1_wc4 * p14.y; + p.y = p.y + wr2_wc1 * p11.y + wr2_wc2 * p12.y + wr2_wc3 * p13.y + wr2_wc4 * p14.y; + p.y = p.y + wr3_wc1 * p11.y + wr3_wc2 * p12.y + wr3_wc3 * p13.y + wr3_wc4 * p14.y; + p.y = p.y + wr4_wc1 * p11.y + wr4_wc2 * p12.y + wr4_wc3 * p13.y + wr4_wc4 * p14.y; + + + p.z = 0; + p.z = p.z + wr1_wc1 * p11.z + wr1_wc2 * p12.z + wr1_wc3 * p13.z + wr1_wc4 * p14.z; + p.z = p.z + wr2_wc1 * p11.z + wr2_wc2 * p12.z + wr2_wc3 * p13.z + wr2_wc4 * p14.z; + p.z = p.z + wr3_wc1 * p11.z + wr3_wc2 * p12.z + wr3_wc3 * p13.z + wr3_wc4 * p14.z; + p.z = p.z + wr4_wc1 * p11.z + wr4_wc2 * p12.z + wr4_wc3 * p13.z + wr4_wc4 * p14.z; + + return p; +} + +// +// GDAL 数组操作---内置函数不进入头文件声明 +// + +float* ReadRasterArray(GDALRasterBand* demBand, int arrayWidth, int arrayHeight, GDALDataType gdal_datatype) { + + + float* result = new float[arrayWidth * arrayHeight]; // 别忘了释放内存 + if (gdal_datatype == GDALDataType::GDT_UInt16) { + unsigned short* temp = (unsigned short*)calloc(arrayHeight * arrayWidth, sizeof(unsigned short)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + short* temp = (short*)calloc(arrayHeight * arrayWidth, sizeof(short)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = (float*)calloc(arrayHeight * arrayWidth, sizeof(float)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + + return result; +} + + + +int WriteMatchPoint(string path, std::vector* matchps) { + std::cout << "输出匹配文件中:" << path; + fstream f; + //追加写入,在原来基础上加了ios::app + f.open(path, ios::out | ios::app); + for (int i = 0; i < matchps->size(); i++) { + matchPoint matchP = (*matchps)[i]; + //f << matchP.r << "," << matchP.c << "," << matchP.ti << "," << matchP.x << "," << matchP.y << "," << matchP.z << "\n"; + } + f.close(); + std::cout << "输出匹配文件over:" << path; + return 0; +} + + +sim_block::sim_block(int start_row, int end_row, int start_col, int end_col, int height, int width) +{ + this->start_row = start_row; + this->end_row = end_row; + this->start_col = start_col; + this->end_col = end_col; + this->height = height; + this->width = width; + this->size = height * width; + this->block = (short*)calloc(this->size, sizeof(short)); + this->distanceblock = (long double*)calloc(this->size, sizeof(long double)); + this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint)); + for (int i = 0; i < this->size; i++) { + this->distanceblock[i] = -1; + } +} + +/// +/// 深度拷贝 +/// +/// +sim_block::sim_block(const sim_block& sim_blocks) +{ + this->height = sim_blocks.width; + this->width = sim_blocks.height; + this->start_row = sim_blocks.start_row; + this->start_col = sim_blocks.start_col; + this->end_col = sim_blocks.end_col; + this->end_row = sim_blocks.end_row; + this->size = sim_blocks.size; + // 声明块 + this->block = (short*)calloc(this->size, sizeof(short)); + this->distanceblock = (long double*)calloc(this->size, sizeof(long double)); + this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint)); + // 移动并复制块 + memcpy(this->block, sim_blocks.block, this->size * sizeof(short)); + memcpy(this->distanceblock, sim_blocks.distanceblock, this->size * sizeof(long double)); + memcpy(this->pointblock, sim_blocks.pointblock, this->size * sizeof(matchPoint)); + +} + +sim_block::~sim_block() +{ + if (this->block) { + free(this->block); + this->block = NULL; + } + if (this->distanceblock) { + free(this->distanceblock); + this->distanceblock = NULL; + } + if (this->pointblock) { + free(this->pointblock); + this->pointblock = NULL; + } +} + +int sim_block::rowcol2blockids(int row_ids, int col_ids) +{ + if (this->start_row > row_ids && this->end_row <= row_ids && this->start_col > col_ids && this->end_col <= col_ids) { + return -1; + } + int ids = (row_ids - this->start_row) * this->width + col_ids - this->start_col; + return ids; +} + +/// +/// 根据行列号设置指定块的数值 +/// +/// 行号 +/// 列号 +/// 设置的值 +/// +int sim_block::setsimblock(int row_ids, int col_ids, short value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->block[ids] = value; + /* + try { + this->block[ids] = value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + +int sim_block::addsimblock(int row_ids, int col_ids, short value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->block[ids] += value; + /* + try { + this->block[ids] += value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + + +/// +/// 根据行列号,获取指定行列号块的数值 +/// +/// 行号 +/// 列号 +/// +short sim_block::getsimblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + short result; + result = this->block[ids]; + /* + try { + result = this->block[ids]; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return result; +} + +/// +/// 获取模拟坐标对应的点坐标 +/// +/// 行号 +/// 列号 +/// +matchPoint sim_block::getpointblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + throw "坐标错误"; + return matchPoint{ 0,0,0,0,0,0 }; + } + matchPoint result = this->pointblock[ids]; + return result; +} + +/// +/// 设置模拟块对应的点坐标 +/// +/// 行号 +/// 列号 +/// 坐标点 +/// 更新结果 +int sim_block::setpointblock(int row_ids, int col_ids, matchPoint value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { return -1; } + this->pointblock[ids] = value; + return 0; +} + +long double sim_block::getdistanceblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + long double result; + result = this->distanceblock[ids]; + /* + try { + result = this->distanceblock[ids]; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return result; +} + +int sim_block::setdistanceblock(int row_ids, int col_ids, long double value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->distanceblock[ids] = value; + /* + try { + this->distanceblock[ids] = value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + + +/// +/// 初始化dem_block +/// +/// +/// +/// +/// +/// +/// +/// +dem_block::dem_block(int all_start_row, int all_start_col, int start_row, int end_row, int start_col, int end_col, int height, int width, int sample_f) +{ + this->all_start_row = all_start_row; + this->all_start_col = all_start_col; + this->start_row = start_row; + this->end_row = end_row; + this->start_col = start_col; + this->end_col = end_col; + this->height = height; + this->width = width; + this->size = height * width; + this->pointblock = (point*)calloc(this->size, sizeof(point)); + this->sample_f = sample_f; +} + +dem_block::dem_block(const dem_block& demblocks) +{ + this->all_start_row = demblocks.all_start_row; + this->all_start_col = demblocks.all_start_col; + this->start_row = demblocks.start_row; + this->end_row = demblocks.end_row; + this->start_col = demblocks.start_col; + this->end_col = demblocks.end_col; + this->height = demblocks.height; + this->width = demblocks.width; + this->size = this->height * this->width; + this->pointblock = (point*)calloc(this->size, sizeof(point)); + this->sample_f = sample_f; + memcpy(this->pointblock, demblocks.pointblock, this->size * sizeof(point)); +} + +dem_block::~dem_block() +{ + if (this->pointblock) { + free(this->pointblock); + this->pointblock = NULL; + //delete this; + } + +} + +/// +/// 重采样dem--三次卷积插值-- 必须在地理坐标系下进行(经纬度) +/// 为了保证采样左右各舍弃了1格 +/// +/// +//dem_block dem_block::resample_dem() +//{ +// int height = this->height -2;//[1,2 ....., n-1,n] +// int width = this->width -2;//[1,2 ....., n-1,n] +// height = height * this->sample_f; //重采样之后的高度 +// width = width * this->sample_f; // 重采样之后的宽度 +// +// int start_row = (this->start_row-1) * this ->sample_f; +// int start_col = (this->start_col-1) * this->sample_f; +// int end_row = (this->end_row-1) * this->sample_f; +// int end_col = (this->end_col-1) * this->sample_f; +// dem_block resample_dem = dem_block(start_row, end_row, start_col, end_col, height, width, this->sample_f); +// +// // 执行dem重采样,采用双曲线插值 +// for (int i = sample_f; i < height; i++) { // 行 从第一行 +// int ori_i_2 = i / sample_f; +// int ori_i_1, ori_i_3, ori_i_4; +// if (ori_i_2 - 1 < 0) { continue; } +// ori_i_1 = ori_i_2 - 1; +// if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; } +// ori_i_3 = ori_i_2 + 1; +// ori_i_4 = ori_i_2 + 2; +// for (int j = sample_f; j < width; j++) { //列 从第一列 +// point p{0,0,0}; +// int ori_j_2 = j / sample_f; +// int ori_j_1, ori_j_3, ori_j_4; +// if (ori_i_2 - 1 < 0) { continue; } +// ori_j_1 = ori_j_2 - 1; +// if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; } +// ori_j_3 = ori_j_2 + 1; +// ori_j_4 = ori_j_2 + 2; +// // 获取插值需要的数据--三次重采样差值 +// p.x = (i % sample_f) * 1.0 / sample_f; p.x = p.x + 1; +// p.y = (j % sample_f) * 1.0 / sample_f; p.y = p.y + 1; +// point p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44; +// // 获取对应节点 +// p11 = this->getpointblock(ori_i_1, ori_j_1); +// p12 = this->getpointblock(ori_i_1, ori_j_2); +// p13 = this->getpointblock(ori_i_1, ori_j_3); +// p14 = this->getpointblock(ori_i_1, ori_j_4); +// p21 = this->getpointblock(ori_i_2, ori_j_1); +// p22 = this->getpointblock(ori_i_2, ori_j_2); +// p23 = this->getpointblock(ori_i_2, ori_j_3); +// p24 = this->getpointblock(ori_i_2, ori_j_4); +// p31 = this->getpointblock(ori_i_3, ori_j_1); +// p32 = this->getpointblock(ori_i_3, ori_j_2); +// p33 = this->getpointblock(ori_i_3, ori_j_3); +// p34 = this->getpointblock(ori_i_3, ori_j_4); +// p41 = this->getpointblock(ori_i_4, ori_j_1); +// p42 = this->getpointblock(ori_i_4, ori_j_2); +// p43 = this->getpointblock(ori_i_4, ori_j_3); +// p44 = this->getpointblock(ori_i_4, ori_j_4); +// p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44); +// // 计算p 对应的行列号 +// resample_dem.setpointblock(i - sample_f, j - sample_f, p); +// } +// } +// +// +// return resample_dem; +//} +/* -------需要优化的方法--------*/ +dem_block dem_block::resample_dem() { + int height = this->height - 2;//[1,2 ....., n-1,n] + int width = this->width - 2;//[1,2 ....., n-1,n] + height = height * this->sample_f; //重采样之后的高度 + width = width * this->sample_f; // 重采样之后的宽度 + + int start_row = (this->start_row - 1) * this->sample_f; + int start_col = (this->start_col - 1) * this->sample_f; + int end_row = (this->end_row - 1) * this->sample_f; + int end_col = (this->end_col - 1) * this->sample_f; + dem_block resample_dem = dem_block(all_start_row,all_start_col,start_row, end_row, start_col, end_col, height, width, this->sample_f); + long double sample_f_1 = 1.0 / sample_f; + // 执行dem重采样,采用双曲线插值 + + int ori_i_2 =0; + int ori_i_1, ori_i_3, ori_i_4; + point p{ 0,0,0 }; + point p11, p12, p13, p14; + + for (int i = sample_f; i < height; i++) { // 行 从第一行 + ori_i_2 = i * sample_f_1; + if (ori_i_2 - 1 < 0) { continue; } + ori_i_1 = ori_i_2 - 1; + if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; } + ori_i_3 = ori_i_2 + 1; + ori_i_4 = ori_i_2 + 2; + for (int j = sample_f; j < width; j++) { //列 从第一列 + p={ 0,0,0 }; + int ori_j_2 = j * sample_f_1; + int ori_j_1, ori_j_3, ori_j_4; + if (ori_i_2 - 1 < 0) { continue; } + ori_j_1 = ori_j_2 - 1; + if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; } + ori_j_3 = ori_j_2 + 1; + ori_j_4 = ori_j_2 + 2; + // 获取插值需要的数据--三次重采样差值 + p.x = (i % sample_f) * sample_f_1 + 1; + //p.x = p.x + 1; + p.y = (j % sample_f) * sample_f_1 + 1; + //p.y = p.y + 1; + + // 获取对应节点 + p11 = this->getpointblock(ori_i_2, ori_j_2); + p12 = this->getpointblock(ori_i_2, ori_j_3); + p13 = this->getpointblock(ori_i_3, ori_j_2); + p14 = this->getpointblock(ori_i_3, ori_j_3); + p = bilineadInterpolation(p, p11, p12, p13, p14); // ----- 优化 + // 计算p 对应的行列号 + resample_dem.setpointblock(i - sample_f, j - sample_f, p); + } + } + return resample_dem; +} + + +/// +/// 根据重采样结果获取对应行列号的坡面法式向量( +/// 必须提前调用UpdatePointCoodinarary()方法,保证坐标系为地固坐标系 +/// +/// 行号 +/// 列号 +/// +VectorPoint dem_block::getslopeVector(int row_ids, int col_ids) +{ + if (row_ids == 0 || col_ids == 0 || row_ids > this->height - 1 || col_ids > this->width - 1) { return VectorPoint{ 0,0,0 }; } // 无效值 + VectorPoint result{ 0,0,0 }; + // 计算向量值,注意向量值的计算初值结果 + point p1 = this->getpointblock(row_ids - 1, col_ids); + point p2 = this->getpointblock(row_ids, col_ids - 1); + point p3 = this->getpointblock(row_ids + 1, col_ids); + point p4 = this->getpointblock(row_ids, col_ids + 1); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + result = VectorFork(n24, n31); // 目标向量 + return result; +} + +int dem_block::rowcol2blockids(int row_ids, int col_ids) +{ + return row_ids * this->width + col_ids; +} + + +/// +/// 根据行列号获取对应的点 +/// +/// +/// +/// +point dem_block::getpointblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + //try { + return this->pointblock[ids]; + //} + //catch (exception e) { + //throw "error"; + //return point{ -1,-1,-1 }; + //} +} + +/// +/// 根据行列号更新值 +/// +/// +/// +/// +/// +int dem_block::setpointblock(int row_ids, int col_ids, point& value) +{ + this->pointblock[row_ids * this->width + col_ids]= value; + /* + int ids = this->rowcol2blockids(row_ids, col_ids); + try { + this->pointblock[ids] = value; + } + catch (exception ex) { + throw "error"; + return -1; + } + + */ + return 0; +} + +point dem_block::getpointblock(int ids) +{ + return this->pointblock[ids]; + /*try { + point result = this->pointblock[ids]; + return result; + } + catch (exception e) { + throw "error"; + return point{ -1,-1,-1 }; + }*/ +} + +int dem_block::setpointblock(int ids, point& value) +{ + this->pointblock[ids] = value; + /* + try { + this->pointblock[ids] = value; + } + catch (exception ex) { + throw "error"; + return -1; + } + */ + return 0; +} + +/// +/// 将点坐标由经纬度->地固坐标系 +/// +/// +/// +int dem_block::UpdatePointCoodinarary() +{ + for (int i = 0; i < this->size; i++) { + this->pointblock[i] = LLA2XYZ(this->pointblock[i]); + } + return 0; +} + + + + +ConvertResampleParameter::ConvertResampleParameter(string path) +{ + + // 解析文件 + ifstream infile(path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + getline(infile, buf); this->in_ori_dem_path = buf; + getline(infile, buf); this->ori_sim = buf; + getline(infile, buf); this->out_sar_xyz_path = buf; + getline(infile, buf); this->out_sar_xyz_incidence_path = buf; + getline(infile, buf); this->out_orth_sar_incidence_path = buf; + getline(infile, buf); this->out_orth_sar_local_incidence_path = buf; + getline(infile, buf); this->outFolder_path = buf; + getline(infile, buf); this->file_count = stoi(buf); + this->inputFile_paths = std::vector(this->file_count); + this->outFile_paths = std::vector(this->file_count); + this->outFile_pow_paths = std::vector(this->file_count); + for (int i = 0; i < this->file_count; i++) { + getline(infile, buf); this->inputFile_paths[i] = buf; + getline(infile, buf); this->outFile_paths[i] = buf; + getline(infile, buf); this->outFile_pow_paths[i] = buf; + } + + getline(infile, buf); this->ori2sim_num = stoi(buf); + + this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double)); + for (int i = 0; i < this->ori2sim_num; i++) { + getline(infile, buf); + this->ori2sim_paras[i] = stod(buf); + } + getline(infile, buf); this->sim2ori_num = stoi(buf); + this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double)); + for (int i = 0; i < this->sim2ori_num; i++) { + getline(infile, buf); + this->sim2ori_paras[i] = stod(buf); + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); + + +} + +ConvertResampleParameter::ConvertResampleParameter(const ConvertResampleParameter& para) +{ + this->in_ori_dem_path = para.in_ori_dem_path; + this->ori_sim = para.ori_sim; + this->out_sar_xyz_path = para.out_sar_xyz_path; + this->out_sar_xyz_incidence_path = para.out_sar_xyz_incidence_path; + this->out_orth_sar_incidence_path = para.out_orth_sar_incidence_path; + this->out_orth_sar_local_incidence_path = para.out_orth_sar_local_incidence_path; + this->outFolder_path = para.outFolder_path; + this->file_count = para.file_count; + this->inputFile_paths = std::vector(this->file_count); + this->outFile_paths = std::vector(this->file_count); + this->outFile_pow_paths = std::vector(this->file_count); + for (int i = 0; i < this->file_count; i++) { + this->inputFile_paths[i] = para.inputFile_paths[i]; + this->outFile_paths[i] = para.outFile_paths[i]; + this->outFile_pow_paths[i] = para.outFile_pow_paths[i]; + } + this->ori2sim_num = para.ori2sim_num; + this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double)); + memcpy(this->ori2sim_paras, para.ori2sim_paras, this->ori2sim_num * sizeof(long double)); + this->sim2ori_num = para.sim2ori_num; + this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double)); + memcpy(this->sim2ori_paras, para.sim2ori_paras, this->sim2ori_num * sizeof(long double)); +} + +ConvertResampleParameter::~ConvertResampleParameter() +{ + free(this->sim2ori_paras); + free(this->ori2sim_paras); + this->outFile_paths.clear(); + this->outFile_paths.swap(this->outFile_paths); + this->inputFile_paths.clear(); + this->inputFile_paths.swap(this->inputFile_paths); + this->outFile_pow_paths.clear(); + this->outFile_pow_paths.swap(this->outFile_pow_paths); +} + +#include "threadpool.hpp" +//int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount) + +// 插值算法 + + + +/// +/// 分块模拟求解 +/// T0 变更为 refrange, delta_R: widthspace +/// +/// +/// +/// +int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount) +{ + long double Starttime = paras.imgStartTime; + long double lamda = paras.lamda; + long double refrange = paras.refrange; + long double* doppler_para = paras.doppler_para; + long double LightSpeed = paras.LightSpeed; + long double delta_t = paras.delta_t; + long double prf = paras.PRF; + long double R0 = paras.R0; + long double widthspace = paras.widthspace; + long double SatelliteModelStartTime = paras.SatelliteModelStartTime; + long double* polySatellitePara = paras.polySatellitePara; + int sim_sar_width = paras.sim_width; + int sim_sar_height = paras.sim_height; + int polynum = paras.polynum; + int doppler_paramenter_number = paras.doppler_paramenter_number; + + + bool haspoint = true; + for (int i = 0; i < demblock.size; i++) { + point tempPoint = demblock.getpointblock(i); + tempPoint = LLA2XYZ(tempPoint); + // T0 变更为 refrange, delta_R: widthspace + point pixelpoint = PSTN(tempPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number); + if (pixelpoint.x >= -3000-paras.sample_f*5 && pixelpoint.x < paras.sim_height + paras.sample_f * 5 && pixelpoint.y >= -paras.sample_f * 5 && pixelpoint.y < paras.sim_width + paras.sample_f * 5) { + haspoint = false; + break; + } + } + + if (haspoint) { + *Pcount = -1; + return -1; + } + + // dem重采样 + demblock.sample_f = paras.sample_f; + dem_block resample = demblock.resample_dem(); // 重采样的时候经纬度, + resample.UpdatePointCoodinarary(); // 可以优化 + + //声明 + int sim_height = resample.end_row - resample.start_row; + int sim_width = resample.end_col - resample.start_col; + int sim_pixel_count = sim_width * sim_height; + + // 计算对应的行列号 + int ids = 0; + SatelliteSpacePoint satepoint_; + *Pcount = 0; + try { + // 计算间接定位法结果 + for (int i = resample.start_row; i < resample.end_row; i++) { + for (int j = resample.start_col; j < resample.end_col; j++) { + point landPoint = resample.getpointblock(i, j); + point pixelpoint = PSTN(landPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number); + point temppoint{ round(pixelpoint.x),round(pixelpoint.y),pixelpoint.z }; + if (temppoint.x < -3000 || temppoint.x >= paras.sim_height || temppoint.y < 0 || temppoint.y >= paras.sim_width) { + continue; + } + VectorPoint n = resample.getslopeVector(i, j); + satepoint_ = getSatellitePostion(pixelpoint.z, SatelliteModelStartTime, polySatellitePara, polynum); + point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标 + IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n); + if (pixelIncidence.localincidenceAngle >= 0 && pixelIncidence.localincidenceAngle <= 1) + { + matchPoint matchp{ temppoint.x, temppoint.y, pixelpoint.z,0,0,0,0,pixelIncidence.incidenceAngle,pixelIncidence.localincidenceAngle}; + result_shared[ids] = matchp; + *Pcount = *Pcount + 1; + ids = ids + 1; + } + } + } + return 0; + } + catch (exception e) { + //free(pixelpoints); + throw "计算错误"; + return -1; + } +} + +static std::mutex s_sim_dem_Mutex; //数据锁 +void taskFunc(ParameterInFile& paras, int dem_block_size, int width, short* sim_dem, int count_cure, int count_sum, + int i, int j, int block_height, int block_width, int end_row_ex, int end_col_ex, float* demarray, translateArray& gtt, translateArray& inv_gtt) +{ + //dem_block *demblock, + int Pcount = 0; + dem_block* demblock = new dem_block(i - 3, j - 3, 3, block_height - 3, 3, block_width - 3, block_height, block_width, paras.sample_f);// 构建块结构 + for (int ii = i - 3; ii < end_row_ex; ii++) { + for (int jj = j - 3; jj < end_col_ex; jj++) { + // 构建点集 + int dem_ids = ii * width + jj; + point tempPoint = Translation(ii, jj, demarray[dem_ids], gtt); + demblock->setpointblock(ii - i + 3, jj - j + 3, tempPoint); + } + } + + matchPoint* result_shared = (matchPoint*)calloc((dem_block_size + 7) * (dem_block_size + 7) * paras.sample_f * paras.sample_f, sizeof(matchPoint)); + int nRet= SimProcessBlock(*demblock, paras,result_shared, &Pcount); + + int tempstate = Pcount; + + int row_ids = 0; + int col_ids = 0; + int ids = 0; + matchPoint* pixelpoint = NULL; + { + //std::lock_guard guard(s_sim_dem_Mutex); + s_sim_dem_Mutex.lock(); + for (int ii = 0; ii < tempstate; ii++) { + pixelpoint = &result_shared[ii]; + row_ids = int(pixelpoint->r)+3000; + col_ids = int(pixelpoint->c); + ids = row_ids *paras.sim_width + col_ids; + sim_dem[ids] ++; + } + s_sim_dem_Mutex.unlock(); + } + //根据匹配结果,尝试计算插值结果 + delete demblock; + free(result_shared); + +} + + +void taskFunc_Calsim2ori(ParameterInFile& paras, ConvertResampleParameter& conveparas, + int start_row, int end_row, int start_col, int end_col, + int dem_width,int dem_height, + float* sar_local_angle, float* sar_angle, float* sar_dem_x, float* sar_dem_y, + float* demarray, translateArray& gtt, translateArray& inv_gtt) +{ + /* + // 计算向量值,注意向量值的计算初值结果 + point p1 = this->getpointblock(row_ids - 1, col_ids); + point p2 = this->getpointblock(row_ids, col_ids - 1); + point p3 = this->getpointblock(row_ids + 1, col_ids); + point p4 = this->getpointblock(row_ids, col_ids + 1); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + result = // 目标向量 + */ + double templocalincidenceAngle = 0; + double tempincidenceAngle = 0; + double templocalincidenceAngle1 = 0; + double tempincidenceAngle1 = 0; + for (int i = start_row; i <= end_row; i++) { + if (i - 1 < 0 || i + 1 >= dem_height) { + continue; + } + for (int j = start_col; j <= end_col; j++) { + if (j - 1 < 0 || j + 1 >= dem_width) { + continue; + } + int dem_ids = i * dem_width + j; + point landPoint = Translation(i, j, demarray[dem_ids], gtt); + landPoint =LLA2XYZ(landPoint); + point pixelpoint = PSTN(landPoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + long double r, c; // 结果的行列号 + sim2ori(pixelpoint.x, pixelpoint.y, r, c, conveparas.sim2ori_paras); // 计算得到的行列号 --> + + // 计算向量1 + dem_ids = (i - 1) * dem_width + j; point p1 = Translation(i - 1, j, demarray[dem_ids], gtt); p1 = LLA2XYZ(p1); + dem_ids = i * dem_width + (j - 1); point p2 = Translation(i, j - 1, demarray[dem_ids], gtt); p2 = LLA2XYZ(p2); + dem_ids = (i + 1) * dem_width + j; point p3 = Translation(i + 1, j, demarray[dem_ids], gtt); p3 = LLA2XYZ(p3); + dem_ids = i * dem_width + (j + 1); point p4 = Translation(i, j + 1, demarray[dem_ids], gtt); p4 = LLA2XYZ(p4); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + VectorPoint n = VectorFork(n24, n31); + + long double satelliteTime =r / paras.PRF + paras.imgStartTime;// pixelpoint.z;// + SatelliteSpacePoint satepoint_ = getSatellitePostion(satelliteTime, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum); + point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标 + IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n); + + dem_ids = i * dem_width + j; + sar_local_angle[dem_ids] = acos(pixelIncidence.localincidenceAngle) * r2d; + sar_angle[dem_ids] =90- acos(pixelIncidence.incidenceAngle) * r2d; + + sar_dem_x[dem_ids] = r; + sar_dem_y[dem_ids] = c; + } + } + //std::cout << "\r" << end_row << "/" << dem_height << "," << end_col << "/" << dem_width << "," << end_row*100.0 * end_col / (dem_width * dem_height) << " ------------------"; +} + +int SimProcess_LVY(ParameterInFile paras, int thread_num) +{ + std::cout << "begin time:" << getCurrentTimeString() << std::endl; + GDALAllRegister();// 注册格式的驱动 + // 打开DEM影像 + GDALDataset* demDataset = (GDALDataset*)(GDALOpen(paras.dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int width = demDataset->GetRasterXSize(); + int height = demDataset->GetRasterYSize(); + int nCount = demDataset->GetRasterCount(); + + double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + + demDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double* inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = demDataset->GetProjectionRef(); + GDALRasterBand* demBand = demDataset->GetRasterBand(1); + float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype); + int dem_pixel_count = width * height; + int psize = (paras.sim_height+3000) * paras.sim_width; + short* sim_dem = (short*)calloc(psize, sizeof(short)); + + + //// 计算每个块的尺寸 + int dem_block_size = int(ceil(sqrt(10*1024* 1024 / (paras.sample_f* paras.sample_f *sizeof(gdal_datatype))))); // 获取每块dem的尺寸 + + //构建内存储空间对象 +// try { + int a = 2; + + int i = 3; + int j = 3; + int thread_ids = 0; + bool hasfullpool = false; + int count_sum = height * width / (dem_block_size * dem_block_size); + int count_cure = 0; + + // 标志文件是否正在写出 + //bool outmatchpointing = false; + //std::vector outmatchpointthread(0); + int tempstate = 0; + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + int start_row =0; + int start_col =0; + + int end_row = 0; + int end_col = 0; + // 扩充 + int end_row_ex = 0; + int end_col_ex = 0; + + int block_height = 0; + int block_width = 0; + while (i < height - 1) { + j = 3; + while (j < width - 1) + { + count_cure++; + // 计算起始行列数 + start_row = i; + start_col = j; + + end_row = start_row + dem_block_size; + end_col = start_col + dem_block_size; + // 扩充 + end_row_ex = end_row + 3; + end_col_ex = end_col + 3; + + if (end_row_ex > height) { + end_row = height - 3; + end_row_ex = height; + } + if (end_col_ex > width) { + end_col = width - 3; + end_col_ex = width; + } + + block_height = end_row - start_row + 6; + block_width = end_col - start_col + 6; + poolPtr->append(std::bind(taskFunc, paras, dem_block_size, width, sim_dem, count_cure, count_sum, + i, j, block_height, block_width, end_row_ex, end_col_ex, demarray, gtt, inv_gtt)); + thread_ids++; + j = j + dem_block_size; + } + i = i + dem_block_size; + } + + std::cout << "SimProcess doing"<waiteFinish(); + // 输出文件 + std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl; + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + const char* out_sar_sim = paras.out_sar_sim_path.c_str(); + + GDALDataset* poDstDS = poDriver->Create(out_sar_sim, paras.sim_width, paras.sim_height + 3000, 1, GDT_Int16, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, paras.sim_width, paras.sim_height + 3000, sim_dem, paras.sim_width, paras.sim_height + 3000, GDT_Int16, 0, 0); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + free(sim_dem); + GDALClose(demDataset); + delete demarray; + std::cout << "输出成果文件-over" << std::endl; + + std::cout << "end time:" << getCurrentTimeString() << std::endl; + return 0; +} + +int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num) +{ + std::cout << "begin time:" << getCurrentTimeString() << std::endl; + GDALAllRegister();// 注册格式的驱动 + // 打开DEM影像 + GDALDataset* demDataset = (GDALDataset*)(GDALOpen(conveparas.in_ori_dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int width = demDataset->GetRasterXSize(); + int height = demDataset->GetRasterYSize(); + int nCount = demDataset->GetRasterCount(); + double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + demDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = demDataset->GetProjectionRef(); + GDALRasterBand* demBand = demDataset->GetRasterBand(1); + float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype); + int dem_pixel_count = width * height; + int psize = width * height; + float* sar_local_angle = (float*)calloc(psize, sizeof(float)); + float* sar_angle = (float*)calloc(psize, sizeof(float)); + float* sar_dem_x = (float*)calloc(psize, sizeof(float)); + float* sar_dem_y = (float*)calloc(psize, sizeof(float)); + + for (int i = 0; i < psize; i++) { + sar_dem_x[i] = -100000; + sar_dem_y[i] = -100000; + sar_local_angle[i] = -9999; + sar_angle[i] = -9999; + } + + int blocksize =1000 ; // 获取每块dem的尺寸 + int tempstate = 0; + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + for (int start_row = 1; start_row = height-2 )? height-2 : (start_row + blocksize); + + for(int start_col =1; start_col < width -2;) + { + int end_col = (start_col + blocksize >= width-2) ? width-2 : (start_col + blocksize); + + poolPtr->append(std::bind(taskFunc_Calsim2ori, paras, conveparas, + start_row, end_row, start_col, end_col,width, height, + sar_local_angle,sar_angle, sar_dem_x,sar_dem_y, + demarray, gtt, inv_gtt)); + start_col = end_col; + } + start_row = end_row; + } + + std::cout << "doing...." << std::endl; + poolPtr->waiteFinish(); + // 输出文件; + + std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl; + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + const char* out_sar_sim = paras.out_sar_sim_path.c_str(); + + poolPtr->stop(); + GDALClose(demDataset); + + delete demarray, demBand, subthreadPool; + + out_sar_sim = conveparas.ori_sim.c_str(); + GDALDataset* poDstDS = poDriver->Create(out_sar_sim, width, height, 2, GDT_Float32, NULL); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_x, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-100000); + poDstDS->GetRasterBand(2)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_y, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(2)->SetNoDataValue(-100000); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + poDstDS = poDriver->Create(conveparas.out_orth_sar_local_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_local_angle, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + poDstDS = poDriver->Create(conveparas.out_orth_sar_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_angle, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + std::cout << "输出成果文件-over" << std::endl; + + std::cout << "end time:" << getCurrentTimeString() << std::endl; + free(sar_dem_x); + free(sar_dem_y); + free(sar_local_angle); + free(sar_angle); + free(gt); + free(inv_gt); + return 0; +} + +/* +11 12 13 14 +21 22 23 24 +31 32 33 34 +41 42 43 44 +*/ +//分块重采样 +int orth_ReSampling(int start_row,int end_row,int start_col,int end_col, + int width,int height,int ori_width,int ori_height , + float* ori_array, float* result_arr, float* ori_r_array, float* ori_c_array) { + for (int i = start_row; i < end_row; i++) { + for (int j = start_col; j < end_col; j++) { + int ori_ids = i * width + j; + int p_ids = 0; + point p{ ori_r_array[ori_ids] ,ori_c_array[ori_ids],0 }; + point p22 { floor(ori_r_array[ori_ids]),floor(ori_c_array[ori_ids]),0 }; + if (p22.x < 0 || p22.y < 0 || p22.x >= ori_height - 1 || p22.y >= ori_width - 1) { + continue; + } + else if (p22.x < 1 || p22.y < 1 || p22.x >= ori_height - 2 || p22.y >= ori_width - 2) { + //双线性 + point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids]; + point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids]; + point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids]; + p.x = p.x - p22.x; + p.y = p.y - p22.y; + p=bilineadInterpolation(p, p22, p23, p32, p33); + result_arr[ori_ids] = p.z; + } + else { // p22.x >= 1 && p22.y >= 1 && p22.x < ori_height - 2&& p22.y < ori_width - 2 + // 三次 + point p11{ p22.x - 1,p22.y - 1,0 }; p_ids = p11.x * ori_width + p11.y; p11.z = ori_array[p_ids]; + point p12{ p22.x - 1,p22.y ,0 }; p_ids = p12.x * ori_width + p12.y; p12.z = ori_array[p_ids]; + point p13{ p22.x - 1,p22.y + 1,0 }; p_ids = p13.x * ori_width + p13.y; p13.z = ori_array[p_ids]; + point p14{ p22.x - 1,p22.y + 2,0 }; p_ids = p14.x * ori_width + p14.y; p14.z = ori_array[p_ids]; + + point p21{ p22.x ,p22.y - 1,0 }; p_ids = p21.x * ori_width + p21.y; p21.z = ori_array[p_ids]; + point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids]; + point p24{ p22.x ,p22.y + 2,0 }; p_ids = p24.x * ori_width + p24.y; p24.z = ori_array[p_ids]; + + point p31{ p22.x + 1,p22.y - 1,0 }; p_ids = p31.x * ori_width + p31.y; p31.z = ori_array[p_ids]; + point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids]; + point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids]; + point p34{ p22.x + 1,p22.y + 2,0 }; p_ids = p34.x * ori_width + p34.y; p34.z = ori_array[p_ids]; + + point p41{ p22.x + 2,p22.y - 1,0 }; p_ids = p41.x * ori_width + p41.y; p41.z = ori_array[p_ids]; + point p42{ p22.x + 2,p22.y ,0 }; p_ids = p42.x * ori_width + p42.y; p42.z = ori_array[p_ids]; + point p43{ p22.x + 2,p22.y + 1,0 }; p_ids = p43.x * ori_width + p43.y; p43.z = ori_array[p_ids]; + point p44{ p22.x + 2,p22.y + 2,0 }; p_ids = p44.x * ori_width + p44.y; p44.z = ori_array[p_ids]; + p.x = p.x - p11.x; + p.y = p.y - p11.y; + p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44); + result_arr[ori_ids] = p.z; + } + } + } + + //std::cout << "\r" << end_row << "/" << height << "," << end_col << "/" << width << ","<GetRasterXSize(); + int height = sim2oriDataset->GetRasterYSize(); + int nCount = sim2oriDataset->GetRasterCount(); + double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + sim2oriDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = sim2oriDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = sim2oriDataset->GetProjectionRef(); + GDALRasterBand* ori_r_Band = sim2oriDataset->GetRasterBand(1); + float* ori_r_array = ReadRasterArray(ori_r_Band, width, height, gdal_datatype); + GDALRasterBand* ori_c_Band = sim2oriDataset->GetRasterBand(2); + float* ori_c_array = ReadRasterArray(ori_c_Band, width, height, gdal_datatype); + // 读取行列号 + delete ori_r_Band, ori_c_Band; + + + for (int t = 0; t < conveparas.file_count; t++) { + // 读 + // 创建 + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + string in_file_path = conveparas.inputFile_paths[t]; + string out_file_path = conveparas.outFile_paths[t]; + + GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly)); + int orth_width = inDataset->GetRasterXSize(); + int orth_height = inDataset->GetRasterYSize(); + int orth_num = inDataset->GetRasterCount(); + // 写 + + GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, orth_num, GDT_Float32, NULL); + outDstDS->SetGeoTransform(gt); + outDstDS->SetProjection(Projection); + + + float* result_arr = (float*)calloc(width * height, sizeof(float)); + int psize = width * height; + int blocksize = 1000; + for (int b = 1; b <= orth_num; b++) { + for (int i = 0; i < psize; i++) { + result_arr[i] = -9999; + } + GDALRasterBand* ori_Band = inDataset->GetRasterBand(b); + float* ori_arr= ReadRasterArray(ori_Band, orth_width, orth_height, gdal_datatype); + + // 线程池 + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + + // 三次样条重采样 + for (int start_row = 0; start_row < height; start_row = start_row + blocksize) { + int end_row = start_row + blocksize >= height ? height : start_row + blocksize; + for (int start_col = 0; start_col < width; start_col = start_col + blocksize) { + int end_col = start_col + blocksize >= width ? width : start_col + blocksize; + // 分块计算结果 + poolPtr->append(std::bind(orth_ReSampling,start_row,end_row,start_col,end_col,width,height, orth_width, orth_height, + ori_arr, result_arr, ori_r_array, ori_c_array)); + } + } + + std::cout << "resampling...." << std::endl; + poolPtr->waiteFinish(); + // 输出文件 + std::cout<GetRasterBand(b)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0); + outDstDS->GetRasterBand(b)->SetNoDataValue(-9999); + poolPtr->stop(); + delete ori_arr, ori_Band, subthreadPool; + } + free(result_arr); + GDALFlushCache(outDstDS); + GDALClose(outDstDS); + GDALClose(inDataset); + + } + free(gt); + free(inv_gt); + delete ori_r_array, ori_c_array;// , sim2oriDataset; + //GDALClose(sim2oriDataset); + return 0; +} + +/// +/// 生成影像的强度图 +/// +/// +/// +/// +/// +int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num) +{ + for (int t = 0; t < conveparas.file_count; t++) { + // 读 + // 创建 + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + string in_file_path = conveparas.outFile_paths[t]; + string out_file_path = conveparas.outFile_pow_paths[t]; + + GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly)); + int width = inDataset->GetRasterXSize(); + int height = inDataset->GetRasterYSize(); + int num = inDataset->GetRasterCount(); + double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + inDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + const char* Projection = inDataset->GetProjectionRef(); + + GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, 1, GDT_Float32, NULL); + outDstDS->SetGeoTransform(gt); + outDstDS->SetProjection(Projection); + GDALDataType gdal_datatype = inDataset->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* ori_Band = inDataset->GetRasterBand(1); + float* ori_a_array = ReadRasterArray(ori_Band, width, height, gdal_datatype); + ori_Band = inDataset->GetRasterBand(2); + float* ori_b_array = ReadRasterArray(ori_Band, width, height, gdal_datatype); + + + + float* result_arr = (float*)calloc(width * height, sizeof(float)); + int psize = width * height; + int blocksize = 1000; + for (int i = 0; i < psize; i++) { + result_arr[i] = -9999; + } + + // 线程池 + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + + // 三次样条重采样 + for (int start_row = 0; start_row < height; start_row = start_row + blocksize) { + int end_row = start_row + blocksize >= height ? height : start_row + blocksize; + for (int start_col = 0; start_col < width; start_col = start_col + blocksize) { + int end_col = start_col + blocksize >= width ? width : start_col + blocksize; + // 分块计算结果 + poolPtr->append(std::bind(orth_pow, start_row, end_row, start_col, end_col, width, height, + result_arr, ori_a_array, ori_b_array)); + } + } + + std::cout << "pow resampling ..." << std::endl; + poolPtr->waiteFinish(); + // 输出文件 + std::cout << t << " , " << 1 << ",输出成果文件:" << getCurrentTimeString() << std::endl; + outDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0); + outDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poolPtr->stop(); + delete ori_a_array, ori_b_array, ori_Band, subthreadPool; + free(gt); + free(inv_gt); + free(result_arr); + //GDALFlushCache(outDstDS); + //GDALClose(outDstDS); + //GDALClose(inDataset); + //delete poDriver; + + } + + //GDALClose(sim2oriDataset); + return 0; +} + +int ResamplingSim(ParameterInFile paras) +{ + GDALAllRegister(); + // 打开DEM影像 + GDALDataset* simDataset = (GDALDataset*)(GDALOpen(paras.out_sar_sim_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int ori_sim_width = simDataset->GetRasterXSize(); + int ori_sim_height = simDataset->GetRasterYSize(); + int width = paras.sim_width; + int height = paras.sim_height; + float width_scales = width * 1.0 / ori_sim_width; + float height_scales = height * 1.0 / ori_sim_height; + + GDALClose(simDataset); + ResampleGDAL(paras.out_sar_sim_path.c_str(), paras.out_sar_sim_resampling_path.c_str(), width_scales, height_scales, GDALResampleAlg::GRA_CubicSpline); + return 0; +} + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX = 1.0, float fResY = 1.0, GDALResampleAlg eResample = GRA_Bilinear) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if (pDSrc == NULL) + { + return -1; + } + + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = GDALDataType::GDT_Float32;// pDSrc->GetRasterBand(1)->GetRasterDataType(); + + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + + double dGeoTrans[6] = { 0 }; + int nNewWidth = width, nNewHeight = height; + pDSrc->GetGeoTransform(dGeoTrans); + + + bool bNoGeoRef = false; + long double dOldGeoTrans0 = dGeoTrans[0]; + //如果没有投影,人为设置一个 + if (strlen(pszSrcWKT) <= 0) + { + //OGRSpatialReference oSRS; + //oSRS.SetUTM(50,true); //北半球 东经120度 + //oSRS.SetWellKnownGeogCS("WGS84"); + //oSRS.exportToWkt(&pszSrcWKT); + //pDSrc->SetProjection(pszSrcWKT); + + + ////////////////////////////////////////////////////////////////////////// + dGeoTrans[0] = 1.0; + pDSrc->SetGeoTransform(dGeoTrans); + ////////////////////////////////////////////////////////////////////////// + + + bNoGeoRef = true; + } + + + //adfGeoTransform[0] /* top left x */ + //adfGeoTransform[1] /* w-e pixel resolution */ + //adfGeoTransform[2] /* rotation, 0 if image is "north up" */ + //adfGeoTransform[3] /* top left y */ + //adfGeoTransform[4] /* rotation, 0 if image is "north up" */ + //adfGeoTransform[5] /* n-s pixel resolution */ + + + dGeoTrans[1] = dGeoTrans[1] / fResX; + dGeoTrans[5] = dGeoTrans[5] / fResY; + nNewWidth = static_cast(nNewWidth * fResX + 0.5); + nNewHeight = static_cast(nNewHeight * fResY + 0.5); + + + //创建结果数据集 + GDALDataset* pDDst = pDriver->Create(pszOutFile, nNewWidth, nNewHeight, nBandCount, dataType, NULL); + if (pDDst == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(dGeoTrans); + + + void* hTransformArg = NULL; + hTransformArg = GDALCreateGenImgProjTransformer2((GDALDatasetH)pDSrc, (GDALDatasetH)pDDst, NULL); //GDALCreateGenImgProjTransformer((GDALDatasetH) pDSrc,pszSrcWKT,(GDALDatasetH) pDDst,pszSrcWKT,FALSE,0.0,1); + + + if (hTransformArg == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return -3; + } + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + + psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + + + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = hTransformArg; + + + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) + { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) + { + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return -3; + } + + + oWo.ChunkAndWarpImage(0, 0, nNewWidth, nNewHeight); + + + GDALDestroyGenImgProjTransformer(hTransformArg); + GDALDestroyWarpOptions(psWo); + if (bNoGeoRef) + { + dGeoTrans[0] = dOldGeoTrans0; + pDDst->SetGeoTransform(dGeoTrans); + //pDDst->SetProjection(""); + } + GDALFlushCache(pDDst); + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return 0; +} + +/// +/// 根据地面坐标获取计算结果 +/// +/// +/// +/// +/// +point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas) +{ + long double Starttime = paras.imgStartTime; + long double lamda = paras.lamda; + long double refrange = paras.refrange; + long double* doppler_para = paras.doppler_para; + long double LightSpeed = paras.LightSpeed; + long double delta_t = paras.delta_t; + long double R0 = paras.R0; + long double delta_R = paras.delta_R; + long double SatelliteModelStartTime = paras.SatelliteModelStartTime; + long double* polySatellitePara = paras.polySatellitePara; + int sim_sar_width = paras.sim_width; + int sim_sar_height = paras.sim_height; + int polynum = paras.polynum; + int doppler_paramenter_number = paras.doppler_paramenter_number; + + point pixelpoint = PSTN(landp, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + long double r, c; + sim2ori(pixelpoint.x, pixelpoint.y, r, c, convparas.sim2ori_paras); + return point{ r,c,0 }; +} + +// 根据坐标变换求解行列号 +int calSARPosition(ParameterInFile paras, ConvertResampleParameter converPara) { + // + + return 0; + +} + + +/// +/// 测试代码 +/// + +int testPP() { + + point landpoint; + landpoint.x = -1945072.5; + landpoint.y = 5344083.0; + landpoint.z = 2878316.0; + point targetpoint; + targetpoint.x = 31; + targetpoint.y = 118; + targetpoint.z = 33; + + landpoint = LLA2XYZ(targetpoint); + std::cout << "PTSN\nX:" << landpoint.x<< "\nY:" << landpoint.y << "\nZ:" << landpoint.z << "\n"; // <0.1 + return 0; +} + +int testPTSN(ParameterInFile paras) { + point landpoint; + landpoint.x = -1945072.5; + landpoint.y = 5344083.0; + landpoint.z = 2878316.0; + point targetpoint; + targetpoint.x = 31; + targetpoint.y = 118; + targetpoint.z = 1592144812.73686337471008300781; + + landpoint=LLA2XYZ(targetpoint); + point pixelpoint = PSTN(landpoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + std::cout << "PTSN\nX:" << targetpoint.x - pixelpoint.x << "\nY:" << targetpoint.y - pixelpoint.y << "\nZ:" << targetpoint.z - pixelpoint.z << "\n"; // <0.1 + + SatelliteSpacePoint sateP = getSatellitePostion(1592144812.7368634, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum); + SatelliteSpacePoint sateT{ -3044863.2137617283, 5669112.1303918585, 3066571.1073331647, -26.15659591374557, 3600.8531673370803, -6658.59211430739 }; + std::cout << "Sate\nX:" << sateP.x - sateT.x << "\nY:" << sateP.y - sateT.y << "\nZ:" << sateP.z - sateT.z << "\nVx" << sateP.vx - sateT.vx << "\nVy:" << sateP.vy - sateT.vy << "\nVz:" << sateP.vz - sateT.vz << "\n"; + return 0; +} diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h new file mode 100644 index 0000000..7a11165 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h @@ -0,0 +1,576 @@ +#pragma once +#include +#include +#include +#include +#include +#include "gdalwarper.h" + +#define PI_180 180/3.141592653589793238462643383279; +#define T180_PI 3.141592653589793238462643383279/180; + +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI + +const long double PI=3.141592653589793238462643383279; +const long double epsilon = 0.000000000000001; +const long double pi = 3.14159265358979323846; +const long double d2r = pi / 180; +const long double r2d = 180 / pi; + +const long double a = 6378137.0; //椭球长半轴 +const long double f_inverse = 298.257223563; //扁率倒数 +const long double b = a - a / f_inverse; +const long double e = sqrt(a * a - b * b) / a; +const long double eSquare = e*e; + + + +int testPP(); + +using namespace std; +/// +/// 内敛函数 +/// + +struct point // 点 SAR影像的像素坐标; +{ + long double x; // 纬度 lat pixel_row + long double y; // 经度 lon pixel_col + long double z; // 高程 ati pixel_time +}; + +struct VectorPoint { + long double x; + long double y; + long double z; +}; +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +inline point LLA2XYZ(point& LLA) { + long double L = LLA.x * d2r; + long double B = LLA.y * d2r; + long double H = LLA.z; + + long double sinB = sin(B); + long double cosB = cos(B); + + //long double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + long double N = a / sqrt(1 - eSquare * sinB * sinB); + point result = { 0,0,0 }; + result.x = (N + H) * cosB * cos(L); + result.y = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.z = (N * (1 - eSquare) + H) * sinB; + return result; +} + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +point XYZ2LLA(point& XYZ); + +/// +/// 计算两个点之间的XY平面欧式距离的平方 +/// +/// +/// +/// +inline long double caldistanceXY(point& p1, point& p2) { + //return pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2); + return (p1.x - p2.x)* (p1.x - p2.x) + (p1.y - p2.y)* (p1.y - p2.y); +} + +/// +/// 使用两个点,生成向量 p1-->p2 +/// +/// p1 +/// p2 +/// 向量 +inline VectorPoint getVector(point& p1, point& p2) { + VectorPoint result = { 0,0,0 }; + result.x = p2.x - p1.x; + result.y = p2.y - p1.y; + result.z = p2.z - p1.z; + return result; +} + +/// +/// 获取向量的模 +/// +/// 向量 +/// 向量模 +inline long double getModule(VectorPoint& vector1) { + //return sqrt(pow(vector1.x, 2) + pow(vector1.y, 2) + pow(vector1.z, 2)); + return sqrt(vector1.x* vector1.x + vector1.y* vector1.y + vector1.z* vector1.z); +} + +inline long double getModuleV1V2(VectorPoint& v1, VectorPoint& v2) +{ + return sqrt((v1.x * v1.x + v1.y * v1.y + v1.z * v1.z) * (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z)); +} + +/// +/// 向量夹角的角度( 角度) +/// +/// 向量 +/// 向量夹角的角度 +inline long double getVectorAngle(VectorPoint& vector1,VectorPoint& vector2) { + //return Radians2Degrees( acos((vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModule(vector1) * getModule(vector2)))); + return Radians2Degrees(acos((vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModuleV1V2(vector1, vector2)))); + +} + + +/// +/// 向量的夹角值 +/// +/// 向量 +/// 向量夹角的角度 +inline long double getVectorAngleValue(VectorPoint& vector1, VectorPoint& vector2) { + //return (vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModule(vector1) * getModule(vector2)); + return (vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModuleV1V2(vector1, vector2)); +} +/// +/// 向量点乘 +/// +/// 向量1 +/// 向量2 +/// 点乘值 +inline long double Vectordot(VectorPoint& V1, VectorPoint& v2) { + return V1.x * v2.x + V1.y * v2.y + V1.z * v2.z; +} + +/// +/// 向量点乘 +/// +/// 向量1 +/// 系数值 +/// 向量与数之间的插值 +inline VectorPoint VectordotNumber(VectorPoint& V1, long double lamda) { + V1.x = V1.x * lamda; + V1.y = V1.y * lamda; + V1.z = V1.z * lamda; + return V1; +} + +/// +/// 向量叉乘 +/// 旋转方向:v1->v2 +/// +/// v1 +/// v2 +/// 叉乘的结果向量 +inline VectorPoint VectorFork(VectorPoint &v1, VectorPoint& v2) { + VectorPoint result{ 0,0,0 }; + result.x = v1.y * v2.z - v1.z * v2.y; + result.y =v1.z*v2.x -v1.x * v2.z; + result.z = v1.x * v2.y - v1.y * v2.x; + return result; +} + + +// +// 参数文件解析 +// + +//参数文件标准格式 +// 文件值 类型 对应的代号 +// DEM文件的路径 str dem_path +// 模拟影像输出路径 str sar_sim_path +// 模拟影像的宽 int +// 模拟影像的高 int +// 模拟影像的匹配坐标文件输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path +// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path +// 采样率 long double sample_f +// 近斜距 long double R0 +// 成像起始时间 long double starttime ---UTC 时间 +// 光速 long double +// 波长 long double +// 多普勒参考时间 long double TO ---UTC 时间 +// 脉冲重复频率 long double PRF +// 斜距采样间隔 long double delta_R +// 多普勒系数个数 int +// 多普勒系数1 long double +// 多普勒系数2 long double +// .... +// 卫星轨道模型是否为多项式模型 int 1 是。0 不是 +// 卫星轨道模型多项式次数 int 4 5 +// 卫星轨道模型起始时间 long double +// 卫星轨道模型X值系数1 long double +// .... +// 卫星轨道模型Y值系数1 long double +// ... +// 卫星轨道模型Z值系数1 long double +// ... +// 卫星轨道模型Vx值系数1 long double +// ... +// 卫星轨道模型Vy值系数1 long double +// ... +// 卫星轨道模型Vz值系数1 long double +// ... +// +// + +class ParameterInFile +{ +public: + ParameterInFile(std::string infile_path); + ParameterInFile(const ParameterInFile& paras); + ~ParameterInFile(); +public: + //参数组 + std::string dem_path; //dem 路径 + std::string out_sar_sim_path; // 输出模拟sar + std::string out_sar_sim_dem_path; // 输出模拟sar + std::string out_sar_sim_resampling_path; // 输出模拟sar + std::string out_sar_sim_resampling_rc; + int sim_height; // 模拟影像的高 + int sim_width; + long double widthspace;// 距离向分辨率 + std::string sar_sim_match_point_path; //输出模拟影像的地点x + std::string sar_sim_match_point_xyz_path; //输出模拟影像的地点x + int sample_f; //采样率 + long double R0; //近斜距 + long double LightSpeed;//光速 + long double lamda;//波长 + long double refrange;// 参考斜距 + + long double delta_R; // 斜距间隔 + long double imgStartTime; //成像起始时间 + long double PRF;// 脉冲重复率 + long double delta_t;// 时间间隔 + // 多普勒 + int doppler_paramenter_number;// 多普勒系数个数 + long double* doppler_para;//多普勒系数 + //卫星轨道模型 + int polySatelliteModel;// 是否为卫星多轨道模型 + int polynum;// 多项数 + long double SatelliteModelStartTime; + long double* polySatellitePara; +}; + +// 根据轨道模型计算卫星空间位置 +struct SatelliteSpacePoint { + long double x=0; + long double y=0; + long double z=0; + long double vx=0; + long double vy=0; + long double vz=0; + +}; + + +/// +/// 根据卫星轨道模型计算卫星 +/// +/// 卫星轨道点时间 +/// 卫星轨道模型起始时间 +/// 卫星轨道坐标模型参数 +/// 多项式项数 +/// +inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime,long double SatelliteModelStartTime,long double* polySatellitePara,int polynum); + +/// +/// 数值模拟法计算多普勒频移值 +/// +/// 斜距 +/// 光速 +/// 多普勒参考时间 +/// 多普勒参数 +/// 多普勒频移值 +inline long double calNumericalDopplerValue(long double R,long double LightSpeed,long double T0, long double* doppler_para,int doppler_paramenter_number); + +/// +/// 根据理论模型计算多普勒频移值 +/// +/// 斜距 +/// 波长 +/// 地面->卫星的空间向量 +/// 地面->卫星之间的速度向量 +/// 多普勒频移值 +inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl); + +/// +/// 根据地面点求解对应的sar影像坐标 +/// +/// 地面点的坐标--地固坐标系 +/// 影片开始成像时间 +/// 波长 +/// 多普勒参考时间 +/// 光速 +/// 时间间隔 +/// 近斜距 +/// 斜距间隔 +/// 卫星轨道模型时间 +/// 卫星轨道坐标模型参数 +/// 卫星轨道模型项数 +/// 多普勒模型数 +/// 影像坐标(x:行号,y:列号,z:成像时刻) +inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double T0, long double* doppler_para, long double LightSpeed, long double delta_t, long double R0, long double delta_R, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4, int doppler_paramenter_number = 5); + + + +struct translateArray { + long double a0, a1, a2; + long double b0, b1, b2; +}; +/// +/// 转换影像 +/// +/// +/// +/// +/// +/// +inline point Translation(long double row_ids,long double col_ids,long double value,translateArray& gt) { + + point result{ 0,0,0 }; + result.x = gt.a0 + gt.a1 * col_ids + gt.a2 * row_ids; + result.y = gt.b0 + gt.b1 * col_ids + gt.b2 * row_ids; + result.z = value; + return result; +} + +inline int Translation(long double& x, long double& y, long double& r, long double& c, translateArray& gt) { + + c = gt.a0 + gt.a1 * x + gt.a2 * y; + r = gt.b0 + gt.b1 * x + gt.b2 * y; + return 0; +} + +/// +/// dem块 +/// +class dem_block { + +public: + dem_block(int all_start_row,int all_start_col,int start_row, int end_row, int start_col, int end_col, int height, int width,int sample_f); + dem_block(const dem_block& demblocks); + ~dem_block(); + dem_block resample_dem(); + //dem_block resample_dem_cudic(); + int rowcol2blockids(int row_ids, int col_ids); + point getpointblock(int row_ids, int col_ids); + int setpointblock(int row_ids, int col_ids, point& value); + point getpointblock(int ids); + int setpointblock(int ids, point& value); + int UpdatePointCoodinarary(); + VectorPoint getslopeVector(int row_ids, int col_ids); +public: + int all_start_row; + int all_start_col; + int start_row; // 目标区域的起始行号 + int end_row; // + int start_col; // 目标区域的起始列号 + int end_col; + int height; + int width; + int size; + int sample_f; + point* pointblock; // 原始块 +}; + + + +inline point bilineadInterpolation(point& p,point& p11,point& p12,point& p21,point& p22); + +inline point cubicInterpolation(point& p, point& p11, point& p12,point& p13,point& p14, point& p21, point& p22,point& p23,point& p24,point& p31,point& p32,point& p33,point& p34,point& p41,point& p42,point& p43,point& p44); + +/// +/// 双线性插值方法 +/// +/// +/// +/// +/// +/// +/// +inline point SARbilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22) { + + + + +} +/// +/// 入射角 -- 弧度制 +/// +struct IncidenceAngle +{ + long double incidenceAngle; // 雷达入射角 + long double localincidenceAngle; // 局地入射角 +}; + +struct matchPoint { + long double r, c, ti; + long double land_x, land_y, land_z; + long double distance; + long double incidenceAngle, localincidenceAngle; +}; +/// +/// 模拟sar 的矩阵块,累加模块默认使用short 类型(累加上限: +/// +class sim_block { +public: + sim_block(int start_row,int end_row,int start_col,int end_col,int height,int width); + sim_block(const sim_block& sim_blocks); + ~sim_block(); + + int rowcol2blockids(int row_ids, int col_ids); + short getsimblock(int row_ids, int col_ids); + int setsimblock(int row_ids,int col_ids, short value); + int addsimblock(int row_ids, int col_ids,short value); + matchPoint getpointblock(int row_ids,int col_ids); + int setpointblock(int row_ids, int col_ids, matchPoint value); + // + long double getdistanceblock(int row_ids, int col_ids); + int setdistanceblock(int row_ids, int col_ids, long double value); + +public: + int start_row; + int end_row; + int start_col; + int end_col; + int height; + int width; + int size; + short* block; + long double* distanceblock; + matchPoint* pointblock; +}; + + +/// +/// 根据卫星坐标,地面坐标,地面法向量,求解对应的雷达入射角和局地入射角 +/// +/// 卫星空间坐标 +/// 地面坐标 +/// 地面坡度 +/// 入射角文件 +inline IncidenceAngle calIncidence(point satellitepoint,point landpoint,VectorPoint slopvector) { + + IncidenceAngle result; + VectorPoint R_ls = getVector(landpoint, satellitepoint); + result.localincidenceAngle = getVectorAngleValue(R_ls, slopvector); + VectorPoint R_s{ satellitepoint.x,satellitepoint.y,satellitepoint.z }; + result.incidenceAngle = getVectorAngleValue(R_s, R_ls); + return result; +} + + +int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount); + +int ResamplingSim(ParameterInFile paras); +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX, float fResY, GDALResampleAlg eResample); + +/// +/// 模拟sar的处理算法模块。 +/// 为了控制内存的取用 +/// 线程数:8 --以进程类的方式进行管理--使用队列的方法 +/// 线程内存:dem_block_size*sample_f*sample_f< 1 G +/// +/// 参数文件项 +/// 线程数默认为8 +/// 执行情况 +int SimProcess(ParameterInFile paras, int thread_num); +int SimProcess_LVY(ParameterInFile paras, int thread_num); +int WriteMatchPoint(string path, std::vector* matchps); +// 测试函数接口 + +int testPTSN(ParameterInFile paras); + + +/// +/// +/// 考虑影像的插值方案 +/// +/// + +class ConvertResampleParameter { +public: + ConvertResampleParameter(string path); + ConvertResampleParameter(const ConvertResampleParameter& para); + ~ConvertResampleParameter(); +public: + string in_ori_dem_path; + string ori_sim; + string out_sar_xyz_path; + string out_sar_xyz_incidence_path; + string out_orth_sar_incidence_path; + string out_orth_sar_local_incidence_path; + string outFolder_path; + int file_count; + std::vector inputFile_paths; + std::vector outFile_paths; + std::vector outFile_pow_paths; + int ori2sim_num; + long double* ori2sim_paras; + int sim2ori_num; + long double* sim2ori_paras; +}; + +inline int ori2sim(long double ori_x,long double ori_y,long double& sim_x,long double& sim_y,long double* conver_paras) { + long double xy = ori_x * ori_y; + long double x2 = ori_x * ori_x; + long double y2 = ori_y * ori_y; + + sim_x = conver_paras[0] + ori_x * conver_paras[1] + ori_y * conver_paras[2] + x2 * conver_paras[3] + y2 * conver_paras[4] + xy * conver_paras[5]; + sim_y = conver_paras[6] + ori_x * conver_paras[7] + ori_y * conver_paras[8] + x2 * conver_paras[9] + y2 * conver_paras[10] + xy * conver_paras[11]; + return 1; +} + +/// +/// 将模拟的行列号转换为目标行列号 +/// +/// 模拟的行号 +/// 模拟的列号 +/// 待计算的目标行号 +/// 待计算的目标列号 +/// 变换矩阵 +/// 默认:0 表示计算结束 +inline int sim2ori(long double sim_r,long double sim_c,long double& ori_r,long double& ori_c, long double* conver_paras) { + long double xy = sim_r * sim_c; + long double x2 = sim_r * sim_r; + long double y2 = sim_c * sim_c; + ori_r = conver_paras[0] + sim_r * conver_paras[1] + sim_c * conver_paras[2] + x2 * conver_paras[3] + y2 * conver_paras[4] + xy * conver_paras[5]; + ori_c = conver_paras[6] + sim_r * conver_paras[7] + sim_c * conver_paras[8] + x2 * conver_paras[9] + y2 * conver_paras[10] + xy * conver_paras[11]; + return 0; +} + +// 查询精确坐标 + +point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas); + +int SimProcessBlock_CalXYZ(dem_block demblock, ParameterInFile paras, ConvertResampleParameter converParas, matchPoint* result_shared, int* Pcount); +int SimProcess_CalXYZ(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); + + +/* + 正射模块思路 + dem->sim->ori(r,c) <-重采样-> ori + step1: 计算dem 对应的 ori 坐标,并保存-> ori_sim.tif (r,c,incidence,localincidence) + step2: 根据结果插值计算对应的a,b + +*/ +int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); // 正射模块 + + +/* +重采样: +step1:读取目标栅格,并根据目标栅格创建对象 +step2: +*/ +int SimProcess_ResamplingOri2Orth(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); + +/* +生成强度图 +*/ +int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); // 正射模块 \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp new file mode 100644 index 0000000..70e8eee --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp @@ -0,0 +1,30 @@ +锘#include "common.h" + +#include +#include +#include + +/** + * @brief GetCurrentTime 鑾峰彇褰撳墠鏃堕棿 + * @return + */ +std::string getCurrentTimeString() { + + std::time_t t = std::time(NULL); + char mbstr[100]; + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", + std::localtime(&t)); + std::string strTime = mbstr; + return strTime; +} + +std::string getCurrentShortTimeString() { + + std::time_t t = std::time(NULL); + char mbstr[100]; + std::strftime(mbstr, sizeof(mbstr), "%H:%M:%S", + std::localtime(&t)); + std::string strTime = mbstr; + return strTime; +} + diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h new file mode 100644 index 0000000..75fee08 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h @@ -0,0 +1,14 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include + +/** + * @brief GetCurrentTime 获取当前时间 + * @return + */ +std::string getCurrentTimeString(); +std::string getCurrentShortTimeString(); + +#endif \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props new file mode 100644 index 0000000..9535a71 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props @@ -0,0 +1,17 @@ + + + + + + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\bin\intel64;$(VC_ExecutablePath_x64);$(CommonExecutablePath) + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\include;C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\include;$(oneMKLIncludeDir);$(IncludePath) + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\lib\intel64;C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files (x86)\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;$(LibraryPath) + <_PropertySheetDisplayName>mkl_debug_x64 + + + + mkl_intel_ilp64.lib;mkl_intel_thread.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;libiomp5md.lib;impi.lib;mkl_sequential.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props new file mode 100644 index 0000000..d675cec --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props @@ -0,0 +1,16 @@ + + + + + + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\bin\intel64;$(VC_ExecutablePath_x64);$(CommonExecutablePath) + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\include;C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\include;$(oneMKLIncludeDir);$(IncludePath) + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\lib\intel64;C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files (x86)\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;$(LibraryPath) + + + + mkl_intel_ilp64.lib;mkl_intel_thread.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;libiomp5md.lib;impi.lib;mkl_sequential.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp new file mode 100644 index 0000000..18a154f --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp @@ -0,0 +1,11 @@ +锘#include "taskprocess.h" + +TaskProcess::TaskProcess() +{ + +} + +TaskProcess::~TaskProcess() +{ + +} diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h new file mode 100644 index 0000000..0688930 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h @@ -0,0 +1,15 @@ +锘#ifndef TASKPROCESS_H +#define TASKPROCESS_H + +class TaskProcess +{ +public: + TaskProcess(); + ~TaskProcess(); +private: + + +}; + + +#endif \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp new file mode 100644 index 0000000..2e4fae9 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp @@ -0,0 +1,182 @@ +锘#include "threadpool.hpp" + +#include +#include +//#include + +#include + +static const int MAX_THREADS = 10000; //鏈澶х嚎绋嬫暟鐩 +/** + * @brief ThreadPool + * @param number[in]绾跨▼鏁 *榛樿寮涓涓嚎绋 + * @param + * emptyQuit[in]绌虹嚎绋嬮鍑猴紝榛樿false銆傚鏋滀负true锛岄渶瑕佸厛娣诲姞浠诲姟锛屽啀start锛岀劧鍚巜aite瀹屾垚 + */ +ThreadPool::ThreadPool(int number, bool emptyQuit) + : m_StopFlag(false), m_EmptyQuit(emptyQuit), m_JoinFlag(false), m_QuitNum(0), m_EmptyQuitWaite(false) { + std::cout << "绾跨▼姹犱腑绾跨▼鏁帮細" << number << std::endl; + if (number <= 0 || number > MAX_THREADS) throw std::exception(); + m_ThreadNum = number; +} + +ThreadPool::~ThreadPool() { + // std::cout << "~ThreadPool()" << std::endl; + stop(); +} +/** + * @brief stop 鍋滄 + */ +void ThreadPool::stop() { + //淇濊瘉澶氱嚎绋嬫儏鍐典笅鍙皟鐢ㄤ竴娆topThreadGroup + std::call_once(m_CallStopSlag, [this] { stopThreadGroup(); }); +} +/** + * @brief stopThreadGroup 鍋滄绾跨▼缁 + */ +void ThreadPool::stopThreadGroup() { + m_StopFlag = true; + Sleep(500); + m_Condition.notify_all(); + waiteFinish(); //绛夊緟绾跨▼閫鍑 + std::thread* thread = NULL; + for (int i = 0; i < m_WorkThreads.size(); i++) + { + thread = m_WorkThreads[i]; + if (thread != NULL) + { + thread->join(); + delete thread; + thread = NULL; + } + m_WorkThreads[i] = NULL; + } + m_WorkThreads.clear(); +} +/** + * @brief startThread 鍚姩绾跨▼ + */ +void ThreadPool::startThread() { + for (int i = 0; i < m_ThreadNum; i++) { + std::thread* thread = new std::thread(ThreadPool::worker, this); + m_WorkThreads.push_back(thread); + } +} +/** + * @brief waiteThreadFinish 绛夊緟绾跨▼缁撴潫 + */ +void ThreadPool::waiteThreadFinish() { + if (m_JoinFlag) return; + if (m_EmptyQuit) + { + m_EmptyQuitWaite = true; + do + { + if (m_ThreadNum == m_QuitNum) + break; + Sleep(400); + + } while (true); + m_StopFlag = true; + m_Condition.notify_all(); + + } + /* for (int i = 0; i < work_threads.size(); i++) { + if (work_threads[i]) { work_threads[i]->join(); } + }*/ + m_JoinFlag = true; +} +/** + * @brief start 鍚姩 + */ +void ThreadPool::start() { + std::call_once(m_CallStartSlag, [this] { startThread(); }); +} +/** + * @brief waiteFinish 绛夊緟鎵鏈変换鍔$粨鏉,璁剧疆涓轰换鍔′负绌洪鍑烘椂璋冪敤 + */ +void ThreadPool::waiteFinish() { + std::call_once(m_CallWaiteFinisFlag, [this] { waiteThreadFinish(); }); +} +/** +* @brief 浠诲姟鏁 +*/ +int ThreadPool::taskNum() +{ + return m_TasksQueue.size(); +} +/** + * @brief append 寰璇锋眰闃熷垪锛渢ask_queue锛炰腑娣诲姞浠诲姟 + * @param task + * @return + */ +bool ThreadPool::append(Task task) { + /*鎿嶄綔宸ヤ綔闃熷垪鏃朵竴瀹氳鍔犻攣锛屽洜涓轰粬琚墍鏈夌嚎绋嬪叡浜*/ + m_DataMutex.lock(); + m_TasksQueue.push(task); + m_DataMutex.unlock(); + + m_Condition.notify_one(); //绾跨▼姹犳坊鍔犺繘鍘讳簡浠诲姟锛岃嚜鐒惰閫氱煡绛夊緟鐨勭嚎绋 + return true; +} +/** + * @brief worker 绾跨▼鍥炶皟鍑芥暟 + * @param arg + * @return + */ +void* ThreadPool::worker(void* arg) { + ThreadPool* pool = (ThreadPool*)arg; + pool->run(); + return pool; +} +/** + * @brief notEmpty 鏄惁绌 + * @return + */ +bool ThreadPool::notEmpty() { + bool empty = m_TasksQueue.empty(); + if (empty) { + // std::ostringstream oss; + // oss << std::this_thread::get_id(); + // printf("queue empty thread id %s waite...!\n", oss.str().c_str()); + } + return !empty; +} +/** + * @brief run 宸ヤ綔绾跨▼闇瑕佽繍琛岀殑鍑芥暟,涓嶆柇鐨勪粠浠诲姟闃熷垪涓彇鍑哄苟鎵ц + */ +void ThreadPool::run() { + bool flag = false; + int remainder = 0; + while (!m_StopFlag) { + flag = false; + { + std::unique_lock lk(this->m_QueueMutex); + /*銆unique_lock() 鍑轰綔鐢ㄥ煙浼氳嚜鍔ㄨВ閿併*/ + m_Condition.wait(lk, [this] { return m_StopFlag || notEmpty(); }); + } + + if (m_StopFlag) break; + Task task; + m_DataMutex.lock(); + //濡傛灉浠诲姟闃熷垪涓嶄负绌猴紝灏卞仠涓嬫潵绛夊緟鍞ら啋 + if (!this->m_TasksQueue.empty()) { + task = m_TasksQueue.front(); + m_TasksQueue.pop(); + remainder = m_TasksQueue.size(); + flag = true; + } + m_DataMutex.unlock(); + if (flag) task(); + //濡傛灉闃熷垪涓虹┖骞朵笖瀹屾垚閫鍑猴紝宸茬粡寮濮嬬瓑寰呴鍑哄氨閫鍑 + if (m_TasksQueue.empty() && m_EmptyQuit && m_EmptyQuitWaite) + { + break; + } + + } + m_QuitNum += 1; + std::ostringstream oss; + oss << std::this_thread::get_id(); + printf("thread %s end\n", oss.str().c_str()); +} diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp new file mode 100644 index 0000000..1a50eba --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp @@ -0,0 +1,102 @@ +锘#ifndef THREADPOOL_HPP +#define THREADPOOL_HPP + +#include +#include +#include +#include +#include //unique_ptr +#include +#include +#include +#include + +typedef std::function Task; + +class ThreadPool { +public: + /** + * @brief ThreadPool + * @param number[in]绾跨▼鏁 *榛樿寮涓涓嚎绋 + * @param + * emptyQuit[in]绌虹嚎绋嬮鍑猴紝榛樿false銆傚鏋滀负true锛岄渶瑕佸厛娣诲姞浠诲姟锛屽啀start锛岀劧鍚巜aite瀹屾垚 + */ + ThreadPool(int number = 1, bool emptyQuit = false); + ~ThreadPool(); + + /** + * @brief append 寰璇锋眰闃熷垪锛渢ask_queue锛炰腑娣诲姞浠诲姟 + * @param task + * @return + */ + bool append(Task task); + /** + * @brief start 鍚姩 + */ + void start(); + /** + * @brief stop 鍋滄 + */ + void stop(); + /** + * @brief waiteFinish 绛夊緟鎵鏈変换鍔$粨鏉,璁剧疆涓轰换鍔′负绌洪鍑烘椂璋冪敤 + */ + void waiteFinish(); + /** + * @brief 浠诲姟鏁 + */ + int taskNum(); +private: + /** + * @brief worker 绾跨▼鍥炶皟鍑芥暟 + * @param arg + * @return + */ + static void *worker(void *arg); + /** + * @brief run 宸ヤ綔绾跨▼闇瑕佽繍琛岀殑鍑芥暟,涓嶆柇鐨勪粠浠诲姟闃熷垪涓彇鍑哄苟鎵ц + */ + void run(); + /** + * @brief stopThreadGroup 鍋滄绾跨▼缁 + */ + void stopThreadGroup(); + /** + * @brief startThread 鍚姩绾跨▼ + */ + void startThread(); + /** + * @brief waiteThreadFinish 绛夊緟绾跨▼缁撴潫 + */ + void waiteThreadFinish(); + /** + * @brief notEmpty 鏄惁绌 + * @return + */ + bool notEmpty(); + +private: + std::vector m_WorkThreads; /*宸ヤ綔绾跨▼*/ + std::queue m_TasksQueue; /*浠诲姟闃熷垪*/ + + std::mutex m_QueueMutex; + std::condition_variable m_Condition; /*蹇呴』涓巙nique_lock閰嶅悎浣跨敤*/ + + std::recursive_mutex m_DataMutex; //鏁版嵁閿 + + std::atomic_bool m_StopFlag; //鏄惁鍋滄鏍囧織 + std::once_flag m_CallStopSlag; + std::once_flag m_CallStartSlag; + std::once_flag m_CallWaiteFinisFlag; + int m_ThreadNum; //绾跨▼鏁 + + std::atomic_bool m_EmptyQuit; //鏃犱换鍔¢鍑烘ā寮,鏀规ā寮忓厛娣诲姞浠诲姟锛屽啀鍚姩 + std::atomic_bool m_JoinFlag; //绾跨▼鏄惁Join + + std::atomic_bool m_EmptyQuitWaite;//寮濮嬮鍑虹瓑寰 + std::atomic_int m_QuitNum;//閫鍑虹殑绾跨▼璁℃暟 + +}; +typedef std::shared_ptr ThreadPoolPtr; + +#endif // THREADPOOL_HPP diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp new file mode 100644 index 0000000..54b39f6 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp @@ -0,0 +1,20 @@ +锘// testengiewithmkl.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + +#include + +int main() +{ + std::cout << "Hello World!\n"; +} + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj new file mode 100644 index 0000000..e99f8f9 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c26dab80-43be-4542-a2a3-7b5acb6e35e6} + testengiewithmkl + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters new file mode 100644 index 0000000..eab1303 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters @@ -0,0 +1,22 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/README.md b/simorthoprogram-orth_gf3-strip/README.md new file mode 100644 index 0000000..f7f7324 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/README.md @@ -0,0 +1 @@ +# SIMOrthoProgram \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/RPC_Correct.cpp b/simorthoprogram-orth_gf3-strip/RPC_Correct.cpp new file mode 100644 index 0000000..039a578 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/RPC_Correct.cpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" + +#include "RPC_Correct.h" + +using namespace std; +using namespace Eigen; + + + diff --git a/simorthoprogram-orth_gf3-strip/RPC_Correct.h b/simorthoprogram-orth_gf3-strip/RPC_Correct.h new file mode 100644 index 0000000..c500e94 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/RPC_Correct.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" +//#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +using namespace std; +using namespace Eigen; + + +// 专门用于解析RPC + + + + +class RPC_Correct +{ +}; + diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.aps b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.aps new file mode 100644 index 0000000..56cedc1 Binary files /dev/null and b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.aps differ diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.cpp b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.cpp new file mode 100644 index 0000000..e38b677 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.cpp @@ -0,0 +1,440 @@ +// SIMOrthoProgram.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 +// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + + + +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +#include "test_moudel.h" +#include +using namespace std; +using namespace Eigen; + +//mode 1 +void PreProcess(int argc, char* argv[]) +{ + // .\baseTool\x64\Release\SIMOrthoProgram.exe 1 D:\MicroWorkspace\C-SAR\Ortho\Temporary\unpack\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff + //输入参数 + std::cout << "==========================================================================" << endl; + std::cout << "预处理计算结果,可以计算出DEM 范围 " << endl; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path "; + std::string parameter_path = argv[2]; // 参数文件 + std::string dem_path = argv[3]; // dem 文件 + std::string in_sar_path = argv[4]; // 输入SAR文件 + std::string work_path = argv[5]; // 目标空间文件 + std::string taget_path = argv[6]; // 输出坐标映射文件 + //std::string parameter_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\package\\orth_para.txt"; // 参数文件 + //std::string dem_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; // dem 文件 + //std::string in_sar_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\unpack\\HJ2E_KSC_STRIP_003375_E100.3_N26.8_20230522_SLC_HHHV_L10000057058\\HJ2E_KSC_STRIP_003375_E100.3_N26.8_20230522_SLC_HHHV_L10000057058\\HJ2E_KSC_STRIP_003375_E100.3_N26.8_20230522_SLC_HH_L10000057058.tiff"; // 输入SAR文件 + + //std::string work_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary"; // 目标空间文件 + //std::string taget_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\package"; // 输出坐标映射文件 + + //std::string parameter_path = "D:\\micro\\WorkSpace\\Ortho1\\Temporary\\package\\orth_para.txt"; // 参数文件 + //std::string dem_path = "D:\\micro\\WorkSpace\\Ortho1\\Temporary\\TestDEM\\mergedDEM.tif"; // dem 文件 + //std::string in_sar_path = "D:\\micro\\WorkSpace\\Ortho1\\Temporary\\unpack\\GF3_SAY_QPSI_011444_E118.9_N31.4_20181012_L1A_AHV_L10003515422\\GF3_SAY_QPSI_011444_E118.9_N31.4_20181012_L1A_HH_L10003515422.tiff"; // 输入SAR文件 + //std::string work_path = "D:\\micro\\WorkSpace\\Ortho1\\Temporary"; // 目标空间文件 + //std::string taget_path = "D:\\micro\\WorkSpace\\Ortho1\\Temporary\\package"; // 输出坐标映射文件 + //std::string Incident_path = argv[7];// 输出入射角文件 + + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the sar image:\n" << in_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + std::cout << "==========================================================================" << endl; + process.InitSimulationSAR(parameter_path, work_path, taget_path, dem_path, in_sar_path); + std::cout << "==========================================================================" << endl; +} + +//mode 2 +void calIncident_localIncident_angle(int argc, char* argv[]) { + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_rc_wgs84_path = argv[4]; + std::string out_incident_angle_path = argv[5]; + std::string out_local_incident_angle_path = argv[6]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.pstn = pstn; + process.calcalIncident_localIncident_angle(dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + +} + +// mode 3 +void calInterpolation_cubic_Wgs84_rc_sar(int argc, char* argv[]) { + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\package\\orth_para.txt"; argv[2]; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\dem_rc.tiff"; argv[3]; + std::string in_ori_sar_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\unpack\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_AHV_L10003514912\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_VV_L10003514912.tiff"; argv[4]; + std::string out_orth_sar_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\package\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_VV_L10003514912_GTC_rpc_geo.tif"; argv[5]; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + +// mode 4 处理 RPC的入射角 +void getRPC_Incident_localIncident_angle(int argc, char* argv[]) { + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string in_dem_path = argv[3]; + std::string in_rpc_rc_path = argv[4]; + std::string out_rpc_dem_path = argv[5]; + std::string out_incident_angle_path = argv[6]; + std::string out_local_incident_angle_path = argv[7]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + + process.CreateRPC_DEM(in_rpc_rc_path, in_dem_path, out_rpc_dem_path); + process.calcalIncident_localIncident_angle(out_rpc_dem_path, in_rpc_rc_path, out_incident_angle_path, out_local_incident_angle_path, pstn); +} + +//mode 5 +void cal_ori_2_power_tiff(int argc, char* argv[]) { + std::cout << "mode 5: convert ori tiff to power tiff:"; + std::cout << "SIMOrthoProgram.exe 5 in_ori_path out_power_path"; + std::string in_ori_path = argv[2]; + std::string out_power_path = argv[3]; + simProcess process; + process.ori_sar_power(in_ori_path, out_power_path); + +} + +// mode 6 +void cal_GEC_Incident_localIncident_angle(int argc, char* argv[]) { + std::cout << "mode 6: get gec incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 6 in_parameter_path in_dem_path in_gec_lon_lat_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_gec_lon_lat_path = argv[4]; + std::string out_incident_angle_path = argv[5]; + std::string out_local_incident_angle_path = argv[6]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.calGEC_Incident_localIncident_angle(dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, pstn); +} + +// mode 7 +void RPC_inangle(int argc, char* argv[]) { + std::cout << "mode 7: get rpc incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 7 in_parameter_path in_dem_path in_gec_lon_lat_path work_path taget_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_gec_lon_lat_path = argv[4]; + std::string work_path = argv[5]; + std::string taget_path = argv[6]; + std::string out_incident_angle_path = argv[7]; + std::string out_local_incident_angle_path = argv[8]; + std::string out_incident_angle_geo_path = argv[9]; + std::string out_local_incident_angle_geo_path = argv[10]; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.InitRPCIncAngle(parameter_path, work_path, taget_path, dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, out_incident_angle_geo_path, out_local_incident_angle_geo_path); + std::cout << "==========================================================================" << endl; +} + +// mode 9 +void calInterpolation_cubic_Wgs84_rc_sar_sigma(int argc, char* argv[]) { + + std::cout << "mode 9: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 9 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\package\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\package\\RD_sim_ori.tif"; + std::string in_ori_sar_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\in_sar_power.tiff"; + std::string out_orth_sar_path = "D:\\micro\\WorkSpace\\Ortho\\Temporary\\in_sar_power_GTC.tiff"; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar_sigma(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + +// mode 11 +void interpolation_bil_GTC_sar_sigma(int argc, char* argv[]) { + + std::cout << "mode 11: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 11 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\micro\\WorkSpace\\SoilSalinity\\Temporary\\preprocessing\\GF3B_SYC_QPSI_008316_E116.1_N43.3_20230622_L1A_AHV_L10000202892-ortho\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\micro\\WorkSpace\\SoilSalinity\\Temporary\\preprocessing\\sim_ori_cut.tif"; + std::string in_ori_sar_path = "D:\\micro\\WorkSpace\\SoilSalinity\\Temporary\\processing\\salinity.tif"; + std::string out_orth_sar_path = "D:\\micro\\WorkSpace\\SoilSalinity\\Temporary\\processing\\salinity_geo.tif"; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_bil(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + + +// mode 12 +void lee_process_sar(int argc, char* argv[]) { + + std::cout << "mode 12: lee process:\n "; + std::cout << "SIMOrthoProgram.exe 12 in_sar_path out_sar_path win_size noise_var\n"; + std::string in_sar_path = "D:\\micro\\WorkSpace\\BackScattering\\Temporary\\preprocessing\\GF3_SAY_QPSI_011444_E118.9_N31.4_20181012_L1A_HH_L10003515422_DB.tif"; + std::string out_sar_path = "D:\\micro\\WorkSpace\\BackScattering\\Temporary\\preprocessed_lee.tif"; + int win_size = 5; + double noise_var = 0.25; + in_sar_path = argv[2]; + out_sar_path = argv[3]; + win_size = stoi(argv[4]); + noise_var = stod(argv[5]); + + simProcess process; + std::cout << "==========================================================================\n" << endl; + //std::cout << in_sar_path << endl; + //std::cout << out_sar_path << endl; + //std::cout << win_size << endl; + //std::cout << noise_var << endl; + process.lee_process(in_sar_path, out_sar_path, win_size, noise_var); +} + +void createRPC_lon_lat(int argc, char* argv[]) { + std::cout << "mode 8"; + std::cout << "SIMOrthoProgram.exe 8 in_rpc_tiff out_lon_lat_path"; + std::string in_rpc_tiff = argv[2]; + std::string in_dem_tiff = argv[3]; + std::string out_lon_lat_path = argv[4]; + + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.CreateRPC_refrenceTable(in_rpc_tiff, in_dem_tiff,out_lon_lat_path); + std::cout << "==========================================================================" << endl; +} + +void Scatter2Grid_lon_lat(int argc, char* argv[]) { + std::cout << "mode 10"; + std::cout << "SIMOrthoProgram.exe 10 lon_lat_path data_tiff grid_path space"; + std::string lon_lat_path = "F:\\orthtest\\ori_sim_preprocessed.tif"; + std::string data_tiff = "F:\\orthtest\\SoilMoistureProduct_geo.tif"; + std::string grid_path = "F:\\orthtest\\SoilMoistureProduct_geo_test.tif"; + double space = 5; + + lon_lat_path = argv[2]; + data_tiff = argv[3]; + grid_path = argv[4]; + space = stod(argv[5]); + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.Scatter2Grid(lon_lat_path, data_tiff, grid_path, space); + std::cout << "==========================================================================" << endl; +} + + +string GetExePath() +{ + char szFilePath[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA(NULL, szFilePath, MAX_PATH); + /* + strrchr:函数功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置), + 并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。 + 使用这个地址返回从最后一个字符c到str末尾的字符串。 + */ + (strrchr(szFilePath, '\\'))[0] = 0; // 删除文件名,只获得路径字串// + string path = szFilePath; + return path; +} + +/// +/// 初始化 +/// +void initProjEnv() { + PJ_CONTEXT* C; + C = proj_context_create(); + std::cout << "========================== init PROJ ================================================" << endl; + string exepath = GetExePath(); + char buffer[10240]; + int i; + for (i = 0; i < exepath.length(); i++) { + buffer[i] = exepath[i]; + } + buffer[i] = '\0'; + + const char* proj_share_path = buffer; + proj_context_set_search_paths(C, 1, &proj_share_path); + char* buf = nullptr; + size_t sz = 0; + + if (_dupenv_s(&buf, &sz, "PROJ_LIB") == 0 && buf != nullptr) + { + printf("PROJ_LIB = %s\n", buf); + std::string newEnv = "PROJ_LIB=" + std::string(buffer); + _putenv(newEnv.c_str()); + } + else { + std::string newEnv = "PROJ_LIB=" + std::string(buffer); + _putenv(newEnv.c_str()); + } + + if (_dupenv_s(&buf, &sz, "PROJ_LIB") == 0 && buf != nullptr) + { + std::cout << "after PROJ_LIB = " << buf << endl; + } + free(buf); + std::cout << "========================================================================================" << endl; +} + + +int main(int argc, char* argv[]) +{ + initProjEnv(); + //WGS84_J2000(); + cout << "test\t" << acos(-1) << endl; + cout << getAngle(Landpoint{ -3421843,5089485,3630606 }, Landpoint{ -2609414,4763328,3332879 }) << endl;; + Landpoint p2 = { -3421843,5089485,3630606 }; Landpoint p1 = { -2609414,4763328,3332879 }; + cout << getIncAngle(p2, p1) << endl;; + std::cout << "program start:\t" << getCurrentTimeString() << endl;; + int mode = 11; + GDALAllRegister(); + if (argc == 0) { // 测试参数 + // 算法说明 + std::cout << "========================== description ================================================" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + std::cout << "mode 1: Preprocess\n "; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path out_GEC_dem_path out_GTC_rc_path out_GEC_lon_lat_path out_clip_dem_path" << endl; + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + + std::cout << "mode 5: interpolation(cubic convolution) orth sar value by gec_lon_lat and dem and ori_sar image and sar model:"; + std::cout << "SIMOrthoProgram.exe 5 in_parameter_path in_gec_lon_lat_path in_dem_path in_sar_path out_orth_sar_path"; + + std::cout << "mode 6: get gec incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 6 in_parameter_path in_dem_path in_gec_lon_lat_path out_incident_angle_path out_local_incident_angle_path"; + if (mode == 10) { + Scatter2Grid_lon_lat(argc, argv); + } + else { + test_main(mode, "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary"); + } + //calInterpolation_cubic_Wgs84_rc_sar(argc, argv); + } + else if (argc > 1) { // 预处理模块 + + std::cout << "=============================description V2.0 =============================================" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + mode = stoi(argv[1]); + if (mode == 0) { + test_main(mode, argv[2]); + } + else if (mode == 1) { + PreProcess(argc, argv); // + } + else if (mode == 2) { // RPC 计算模块 + calIncident_localIncident_angle(argc, argv); + } + else if (mode == 3) { + calInterpolation_cubic_Wgs84_rc_sar(argc, argv); + } + else if (mode == 4) { + getRPC_Incident_localIncident_angle(argc, argv); + } + else if (mode == 5) { + cal_ori_2_power_tiff(argc, argv); + } + else if (mode == 6) { + cal_GEC_Incident_localIncident_angle(argc, argv); + } + else if (mode == 7) { + RPC_inangle(argc, argv); + } + else if (mode == 8) { + createRPC_lon_lat(argc, argv); + } + else if (mode == 9) { + calInterpolation_cubic_Wgs84_rc_sar_sigma(argc, argv); + } + else if (mode == 10) { + Scatter2Grid_lon_lat(argc, argv); + } + else if (mode == 11) { + interpolation_bil_GTC_sar_sigma(argc, argv); + } + else if (mode == 12){ + lee_process_sar(argc, argv); + } + } + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + std::cout << "program over:\t" << getCurrentTimeString() << endl; + + +} + +// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 +// 调试程序: F5 或调试 >“开始调试”菜单 + +// 入门使用技巧: +// 1. 使用解决方案资源管理器窗口添加/管理文件 +// 2. 使用团队资源管理器窗口连接到源代码管理 +// 3. 使用输出窗口查看生成输出和其他消息 +// 4. 使用错误列表窗口查看错误 +// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 +// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.rc b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.rc new file mode 100644 index 0000000..f8ef045 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// 涓枃(绠浣擄紝涓浗) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// + +#endif // 涓枃(绠浣擄紝涓浗) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.sln b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.sln new file mode 100644 index 0000000..469c9dd --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.sln @@ -0,0 +1,31 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32602.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SIMOrthoProgram", "SIMOrthoProgram.vcxproj", "{7722B0A9-572B-4E32-AFBE-4DC88898F8EE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x64.ActiveCfg = Debug|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x64.Build.0 = Debug|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x86.ActiveCfg = Debug|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x86.Build.0 = Debug|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x64.ActiveCfg = Release|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x64.Build.0 = Release|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x86.ActiveCfg = Release|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CE6D0980-E92A-4188-91CE-EEE5749F908C} + EndGlobalSection +EndGlobal diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj new file mode 100644 index 0000000..0a21447 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj @@ -0,0 +1,200 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7722b0a9-572b-4e32-afbe-4dc88898f8ee} + SIMOrthoProgram + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + false + v142 + Unicode + Sequential + + + Application + false + v142 + true + Unicode + Parallel + false + + + + + + + + + + + + + + + + + + + + + C:\ProgramData\Miniconda3\envs\orth\Library\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64;$(oneMKLOmpLibDir);$(LibraryPath) + true + false + C:\ProgramData\Miniconda3\envs\orth\Library\include;$(ExternalIncludePath) + + + true + true + true + $(IncludePath) + $(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(LibraryPath) + $(VC_ReferencesPath_x64); + $(WindowsSDK_MetadataPath); + true + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _CONSOLE;%(PreprocessorDefinitions) + true + true + Default + stdc11 + MultiThreaded + + + Console + true + %(AdditionalDependencies) + + + + + Level3 + + + false + true + _CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + Default + Default + MaxSpeed + Neither + false + false + true + /bigobj %(AdditionalOptions) + + + Console + true + true + true + + + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj.filters b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj.filters new file mode 100644 index 0000000..a443456 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj.filters @@ -0,0 +1,88 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + + + 璧勬簮鏂囦欢 + + + + + 璧勬簮鏂囦欢 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj.user b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SIMOrthoProgram.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/SateOrbit.cpp b/simorthoprogram-orth_gf3-strip/SateOrbit.cpp new file mode 100644 index 0000000..f34405d --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SateOrbit.cpp @@ -0,0 +1,86 @@ +#include "SateOrbit.h" +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +#include +#include +#include +#include +//#include + +using namespace std; +using namespace Eigen; + + + +OrbitPoly::OrbitPoly() +{ +} + +OrbitPoly::OrbitPoly(int polynum, Eigen::MatrixX polySatellitePara, double SatelliteModelStartTime) +{ + if (polySatellitePara.rows() != polynum||polySatellitePara.cols()!=6) { + throw exception("?????????????????"); + } + this->polySatellitePara = polySatellitePara; + this->SatelliteModelStartTime = SatelliteModelStartTime; + this->polynum = polynum; +} + +OrbitPoly::~OrbitPoly() +{ +} + +Eigen::MatrixX OrbitPoly::SatelliteSpacePoint(Eigen::MatrixX satellitetime) +{ + Eigen::MatrixX result= SatelliteSpacePoints(satellitetime, this->SatelliteModelStartTime, this->polySatellitePara, this->polynum); + return result; +} + +Eigen::MatrixX OrbitPoly::SatelliteSpacePoint(long double satellitetime) { + + if (this->polySatellitePara.rows() != polynum || this->polySatellitePara.cols() != 6) { + throw exception("the size of satellitetime has error!! row: p1,p2,p3,p4 col: x,y,z,vx,vy,vz "); + } + // ????????? + double satellitetime2 =double( satellitetime - this->SatelliteModelStartTime); + Eigen::MatrixX satetime(1, polynum); + for (int i = 0; i < polynum; i++) { + satetime(0, i) = pow(satellitetime2, i); + } + + // ???? + Eigen::MatrixX satellitePoints(1, 6); + satellitePoints = satetime * polySatellitePara; + return satellitePoints; +} + +/// +/// ???????????????????? +/// +/// ??????? +/// ?????????? +/// ??????[x1,y1,z1,vx1,vy1,vz1; x2,y2,z2,vx2,vy2,vz2; ..... ] +/// ?????????? +/// ???????? +Eigen::MatrixX SatelliteSpacePoints(Eigen::MatrixX& satellitetime, double SatelliteModelStartTime, Eigen::MatrixX& polySatellitePara, int polynum) +{ + if (satellitetime.cols() != 1) { + throw exception("the size of satellitetime has error!!"); + } + if (polySatellitePara.rows() != polynum || polySatellitePara.cols() != 6) { + throw exception("the size of satellitetime has error!! row: p1,p2,p3,p4 col: x,y,z,vx,vy,vz "); + } + // ????????? + int satellitetime_num = satellitetime.rows(); + satellitetime = satellitetime.array() - SatelliteModelStartTime; + Eigen::MatrixX satelliteTime(satellitetime_num, polynum); + for (int i = 0; i < polynum; i++) { + satelliteTime.col(i) = satellitetime.array().pow(i); + } + + // ???? + Eigen::MatrixX satellitePoints(satellitetime_num, 6); + satellitePoints = satelliteTime * polySatellitePara; + return satellitePoints; +} diff --git a/simorthoprogram-orth_gf3-strip/SateOrbit.h b/simorthoprogram-orth_gf3-strip/SateOrbit.h new file mode 100644 index 0000000..b1e6daf --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/SateOrbit.h @@ -0,0 +1,53 @@ +#pragma once +/// +/// 计算卫星轨道 +/// + +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 +#include "baseTool.h" + +#include +#include +#include +#include +//#include +//#include + + +using namespace std; +using namespace Eigen; +//using namespace arma; + + +/// +/// 多项式轨道模型 +/// +class OrbitPoly { +public: + //OrbitPoly(std::string orbitModelPath); + OrbitPoly(); + OrbitPoly(int polynum, Eigen::MatrixX polySatellitePara, double SatelliteModelStartTime); + ~OrbitPoly(); + + Eigen::MatrixX SatelliteSpacePoint(Eigen::MatrixX satellitetime); + Eigen::MatrixX SatelliteSpacePoint(long double satellitetime); +public: + int polynum; + Eigen::MatrixX polySatellitePara; + double SatelliteModelStartTime; +}; + + + +/// +/// 获取指定时刻的卫星轨道坐标 +/// +/// 卫星时刻 +/// 模型起算时间 +/// 模型参数[x1,y1,z1,vx1,vy1,vz1; x2,y2,z2,vx2,vy2,vz2; ..... ] +/// 模型参数数量 +/// 卫星坐标 +Eigen::MatrixX SatelliteSpacePoints(Eigen::MatrixX &satellitetime, double SatelliteModelStartTime, Eigen::MatrixX& polySatellitePara, int polynum = 4); diff --git a/simorthoprogram-orth_gf3-strip/WGS84_J2000.cpp b/simorthoprogram-orth_gf3-strip/WGS84_J2000.cpp new file mode 100644 index 0000000..e868836 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/WGS84_J2000.cpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include"WGS84_J2000.h" diff --git a/simorthoprogram-orth_gf3-strip/WGS84_J2000.h b/simorthoprogram-orth_gf3-strip/WGS84_J2000.h new file mode 100644 index 0000000..ae3e496 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/WGS84_J2000.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include diff --git a/simorthoprogram-orth_gf3-strip/baseTool.cpp b/simorthoprogram-orth_gf3-strip/baseTool.cpp new file mode 100644 index 0000000..c1c65eb --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/baseTool.cpp @@ -0,0 +1,1401 @@ +#pragma once +/// +/// 锟斤拷锟斤拷锟洁、锟斤拷锟斤拷锟斤拷锟斤拷 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + + +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include < io.h > +#include < stdio.h > +#include < stdlib.h > +#include +#include +#include +//#include +#include //#include "ogrsf_frmts.h" +#include +#include +#include +#include +#include + +#include "baseTool.h" +using namespace std; +using namespace Eigen; +using namespace cv; + + + +/** + * @brief GetCurrentTime 锟斤拷取锟斤拷前时锟斤拷 + * @return + */ +std::string getCurrentTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + std::string strTime = mbstr; + return strTime; +} + +std::string getCurrentShortTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + std::string strTime = mbstr; + return strTime; +} + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon + p2.lon,p1.lat + p2.lat,p1.ati + p2.ati }; +} + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon - p2.lon,p1.lat - p2.lat,p1.ati - p2.ati }; +} + +bool operator ==(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat == p2.lat && p1.lon == p2.lon && p1.ati == p2.ati; +} + + + +Landpoint operator *(const Landpoint& p, double scale) +{ + return Landpoint{ + p.lon * scale, + p.lat * scale, + p.ati * scale + }; +} + +double getAngle(const Landpoint& a, const Landpoint& b) +{ + double c = dot(a, b) / (getlength(a) * getlength(b)); + if (a.lon * b.lat - a.lat * b.lon >= 0) { + return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } + else { + return 360 - acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } +} + +double dot(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat * p2.lat + p1.lon * p2.lon + p1.ati * p2.ati; +} + +double getlength(const Landpoint& p1) { + + return sqrt(dot(p1, p1)); +} + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b) { + return Landpoint{ + a.lat * b.ati - a.ati * b.lat,//x + a.ati * b.lon - a.lon * b.ati,//y + a.lon * b.lat - a.lat * b.lon//z + }; +} + +/// +/// 锟斤拷锟斤拷乇锟斤拷露锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟姐都锟斤拷WGS84锟斤拷锟斤拷系锟斤拷锟斤拷p1为锟斤拷锟姐, +/// 锟斤拷 N +/// W p1 +/// p4 p0 p2 E +/// p3 S +/// n21=n2xn1 +/// n=(n21+n32+n43+n41)*0.25; +/// +/// 目锟斤拷锟?1锟?7 +/// 锟斤拷围锟斤拷1 +/// 锟斤拷围锟斤拷2 +/// 锟斤拷围锟斤拷3 +/// 锟斤拷围锟斤拷4 +/// 锟斤拷锟斤拷锟角讹拷 +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4) { + + Landpoint n0 = LLA2XYZ(p0), + n1 = LLA2XYZ(p1), + n2 = LLA2XYZ(p2), + n3 = LLA2XYZ(p3), + n4 = LLA2XYZ(p4); + Landpoint n01 = n1 - n0, n02 = n2 - n0, n03 = n3 - n0, n04 = n4 - n0; + // 锟斤拷n01为锟斤拷锟斤拷锟斤拷锟斤拷 + Landpoint np01 = p1-p0, np02 = p2-p0, np03 = p3-p0, np04 = p4-p0; + double a2 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np02.lon,np02.lat,0 });// 01->02 锟斤拷时锟斤拷 + double a3 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np03.lon,np03.lat,0 });// 01->03 锟斤拷时锟斤拷 + double a4 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np04.lon,np04.lat,0 });// 01->04 锟斤拷时锟斤拷 + //std::cout << a2 << "\t" << a3 << "\t" << a4 << endl; + a2 = 360 - a2; + a3 = 360 - a3; + a4 = 360 - a4; + Landpoint N, W, S, E; + N = n01; + if (a2 >= a3 && a2 >= a4) { + W = n02; + if (a3 >= a4) { + S = n03; + E = n04; + } + else { + S = n04; + E = n03; + } + } + else if (a3 >= a2 && a3 >= a4) { + W = n03; + if (a2 >= a4) { + S = n02; + E = n04; + } + else { + S = n04; + E = n02; + } + } + else if (a4 >= a2 && a4 >= a3) + { + W = n04; + if (a2 >= a3) { + S = n02; + E = n03; + } + else { + S = n03; + E = n02; + } + } + return (crossProduct(N, W) + crossProduct(W, S) + crossProduct(S, E) + crossProduct(E, N)) * 0.25; +} + +/// +/// 锟斤拷锟捷讹拷锟斤拷锟斤拷锟斤拷小 +/// p11 p12 p13 p14 +/// p21 p22 p23 p24 +/// p(2+u,2+v) +/// p31 p32 p33 p34 +/// p41 p42 p43 p44 +/// +/// 锟斤拷元锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟斤拷锟?1锟?7 +/// 锟斤拷元锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟斤拷锟?1锟?7 +/// 4x4 锟斤拷值锟斤拷锟斤拷 +/// +complex Cubic_Convolution_interpolation(double u, double v, Eigen::MatrixX> img) +{ + if (img.rows() != 4 || img.cols() != 4) { + throw exception("the size of img's block is not right"); + } + // 锟斤拷锟斤拷锟斤拷模锟斤拷 + Eigen::MatrixX> wrc(1, 4);// 使锟斤拷 complex 锟斤拷锟斤拷锟斤拷要原锟斤拷锟斤拷为锟剿伙拷取值 + Eigen::MatrixX> wcr(4, 1);// + for (int i = 0; i < 4; i++) { + wrc(0, i) = Cubic_kernel_weight(u+1-i); // u+1,u,u-1,u-2 + wcr(i, 0) = Cubic_kernel_weight(v + 1 - i); + } + + Eigen::MatrixX> interValue = wrc * img * wcr; + return interValue(0, 0); +} + +complex Cubic_kernel_weight(double s) +{ + s = abs(s); + if (s <= 1) { + return complex(1.5 * s * s * s - 2.5 * s * s + 1,0); + } + else if (s <= 2) { + return complex(-0.5 * s * s * s + 2.5 * s * s - 4 * s + 2,0); + } + else { + return complex(0,0); + } +} + +/// +/// p11 p12 -- x +/// p0(u,v) +/// p21 p22 +/// | +/// y +/// p11(0,0) +/// p21(0,1) +/// P12(1,0) +/// p22(1,1) +/// +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22) +{ + + return p11.ati * (1 - p0.lon) * (1 - p0.lat) + + p12.ati * p0.lon * (1 - p0.lat) + + p21.ati * (1 - p0.lon) * p0.lat + + p22.ati * p0.lon * p0.lat; +} + + + + + +/// +/// 锟斤拷锟斤拷纬锟斤拷转锟斤拷为锟截固诧拷锟斤拷锟斤拷锟斤拷系 +/// +/// 锟斤拷纬锟饺碉拷--degree +/// 投影锟斤拷锟斤拷系锟斤拷 +Landpoint LLA2XYZ(const Landpoint& LLA) { + double L = LLA.lon * d2r; + double B = LLA.lat * d2r; + double H = LLA.ati; + + double sinB = sin(B); + double cosB = cos(B); + + //double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + double N = a / sqrt(1 - eSquare * sinB * sinB); + Landpoint result = { 0,0,0 }; + result.lon = (N + H) * cosB * cos(L); + result.lat = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.ati = (N * (1 - 1/f_inverse)* (1 - 1 / f_inverse) + H) * sinB; + return result; +} + +/// +/// 锟斤拷锟斤拷n,3) lon,lat,ati +/// +/// +/// +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint) +{ + landpoint.col(0) = landpoint.col(0).array() * d2r; // lon + landpoint.col(1) = landpoint.col(1).array() * d2r; // lat + + Eigen::MatrixXd sinB = (landpoint.col(1).array().sin());//lat + Eigen::MatrixXd cosB = (landpoint.col(1).array().cos());//lat + + Eigen::MatrixXd N = a / ((1 - sinB.array().pow(2) * eSquare).array().sqrt()); + Eigen::MatrixXd result(landpoint.rows(), 3); + + result.col(0) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::cos(landpoint.col(0).array()).array(); //x + result.col(1) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::sin(landpoint.col(0).array()).array(); //y + + result.col(2) = (N.array() * (1 - 1/f_inverse)* (1 - 1 / f_inverse) + landpoint.col(2).array()) * sinB.array(); //z + + return result; +} + + +/// +/// 锟斤拷锟截固诧拷锟斤拷锟斤拷锟斤拷系转锟斤拷为锟斤拷纬锟斤拷 +/// +/// 锟教诧拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷纬锟斤拷--degree +Landpoint XYZ2LLA(const Landpoint& XYZ) { + double tmpX = XYZ.lon;// 锟斤拷锟斤拷 x + double temY = XYZ.lat;// 纬锟斤拷 y + double temZ = XYZ.ati; + + double curB = 0; + double N = 0; + double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + Landpoint result = { 0,0,0 }; + result.lon = atan2(temY, tmpX) * r2d; + result.lat = curB * r2d; + result.ati = temZ / sinCurB - N * (1 - eSquare); + return result; +} + +/// +/// 锟斤拷锟斤拷图锟斤拷锟饺∮帮拷锟?1锟?7 +/// +/// +gdalImage::gdalImage(string raster_path) +{ + omp_lock_t lock; + omp_init_lock(&lock); // 锟斤拷始锟斤拷锟斤拷锟斤拷锟斤拷 + omp_set_lock(&lock); //锟斤拷没锟斤拷锟斤拷锟?1锟?7 + this->img_path = raster_path; + + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + // 锟斤拷DEM影锟斤拷 + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(raster_path.c_str(), 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]; + + this->projection = rasterDataset->GetProjectionRef(); + // 锟斤拷锟斤拷锟斤拷锟斤拷 + //double* inv_gt = new double[6];; + //GDALInvGeoTransform(gt, inv_gt); // 锟斤拷锟斤拷锟斤拷锟斤拷 + // 锟斤拷锟斤拷投影 + GDALFlushCache((GDALDatasetH)rasterDataset); + GDALClose((GDALDatasetH)rasterDataset); + rasterDataset = NULL;// 指锟斤拷锟矫匡拷 + this->InitInv_gt(); + delete[] gt; + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 +} + +gdalImage::~gdalImage() +{ +} + +void gdalImage::setHeight(int height) +{ + this->height = height; +} + +void gdalImage::setWidth(int width) +{ + this->width = width; +} + +void gdalImage::setTranslationMatrix(Eigen::MatrixXd gt) +{ + this->gt = gt; +} + +void gdalImage::setData(Eigen::MatrixXd data) +{ + this->data = data; +} + +Eigen::MatrixXd gdalImage::getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids = 1) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_ReadOnly));//锟斤拷只锟斤拷锟斤拷式锟斤拷取锟斤拷锟斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + MatrixXd datamatrix(rows_count, cols_count); + + + if (gdal_datatype == GDALDataType::GDT_UInt16) { + + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 + //GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return datamatrix; + +} + +/// +/// 写锟斤拷遥锟斤拷影锟斤拷 +/// +/// +/// +/// +/// +void gdalImage::saveImage(Eigen::MatrixXd data, int start_row = 0, int start_col = 0, int band_ids = 1) +{ + 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) { + string tip = "file path: " + this->img_path; + throw exception(tip.c_str()); + } + GDALAllRegister(); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = nullptr; + if (boost::filesystem::exists(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.c_str(), this->width, this->height, this->band_num, GDT_Float32, NULL); // 锟斤拷锟斤拷锟斤拷 + poDstDS->SetProjection(this->projection.c_str()); + + + 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(); + + float* databuffer = new float[datarows * datacols];// (float*)malloc(datarows * datacols * sizeof(float)); + + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + float temp = float(data(i, j)); + databuffer[i * datacols + j] = temp; + } + } + //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_Float32, 0, 0); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(-9999); + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + //GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 +} + +void gdalImage::saveImage() +{ + this->saveImage(this->data, this->start_row, this->start_col, this->data_band_ids); +} + +void gdalImage::setNoDataValue(double nodatavalue = -9999, int band_ids = 1) +{ + + + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + //GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.c_str(), GA_Update)); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(nodatavalue); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); +} + +int gdalImage::InitInv_gt() +{ + //1 lon lat = x + //1 lon lat = y + Eigen::MatrixXd temp(2, 3); + this->inv_gt = temp; + double a = this->gt(0, 0); + double b = this->gt(0, 1); + double c = this->gt(0, 2); + double d = this->gt(1, 0); + double e = this->gt(1, 1); + double f = this->gt(1, 2); + double g = 1; + double det_gt = b * f - c * e; + if (det_gt == 0) { + return 0; + } + this->inv_gt(0, 0) = (c * d - a * f) / det_gt; //2 + this->inv_gt(0, 1) = f / det_gt; // lon + this->inv_gt(0, 2) = -c / det_gt; // lat + this->inv_gt(1, 0) = (a*e-b*d) / det_gt; //1 + this->inv_gt(1, 1) = -e / det_gt; // lon + this->inv_gt(1, 2) = b / det_gt; // lat + return 1; +} + +Landpoint gdalImage::getRow_Col(double lon, double lat) +{ + Landpoint p{ 0,0,0 }; + p.lon = this->inv_gt(0, 0) + lon * this->inv_gt(0, 1) + lat * this->inv_gt(0, 2); //x + p.lat = this->inv_gt(1, 0) + lon * this->inv_gt(1, 1) + lat * this->inv_gt(1, 2); //y + return p; +} + +Landpoint gdalImage::getLandPoint(double row, double col, double ati = 0) +{ + Landpoint p{ 0,0,0 }; + p.lon = this->gt(0, 0) + col * this->gt(0, 1) + row * this->gt(0, 2); //x + p.lat = this->gt(1, 0) + col * this->gt(1, 1) + row * this->gt(1, 2); //y + p.ati = ati; + return p; +} + +double gdalImage::mean(int bandids ) +{ + double mean_value = 0; + double count = this->height* this->width; + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + mean_value = mean_value+ sar_a.sum() / count; + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return mean_value; +} + +double gdalImage::max(int bandids) +{ + double max_value = 0; + bool state_max = true; + int line_invert = 100; + int start_ids = 0; + double temp_max = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_max) { + state_max = false; + max_value = sar_a.maxCoeff(); + } + else { + temp_max= sar_a.maxCoeff(); + if (max_value < temp_max) { + max_value = temp_max; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return max_value; +} + +double gdalImage::min(int bandids) +{ + double min_value = 0; + bool state_min = true; + int line_invert = 100; + int start_ids = 0; + double temp_min = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_min) { + state_min = false; + min_value = sar_a.minCoeff(); + } + else { + temp_min = sar_a.minCoeff(); + if (min_value < temp_min) { + min_value = temp_min; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return min_value; +} + +GDALRPCInfo gdalImage::getRPC() +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister();//注锟斤拷锟斤拷锟斤拷 + //锟斤拷锟斤拷锟斤拷 + GDALDataset* pDS = (GDALDataset*)GDALOpen(this->img_path.c_str(), GA_ReadOnly); + //锟斤拷元锟斤拷锟斤拷锟叫伙拷取RPC锟斤拷息 + char** papszRPC = pDS->GetMetadata("RPC"); + + //锟斤拷锟斤拷取锟斤拷RPC锟斤拷息锟斤拷锟斤拷山峁癸拷锟?1锟?7 + GDALRPCInfo oInfo; + GDALExtractRPCInfo(papszRPC, &oInfo); + + GDALClose((GDALDatasetH)pDS); + + return oInfo; +} + +Eigen::MatrixXd gdalImage::getLandPoint(Eigen::MatrixXd points) +{ + if (points.cols() != 3) { + throw new exception("the size of points is equit 3!!!"); + } + + Eigen::MatrixXd result(points.rows(), 3); + result.col(2) = points.col(2);// 锟竭筹拷 + points.col(2) = points.col(2).array() * 0 + 1; + points.col(0).swap(points.col(2));// 锟斤拷锟斤拷 + Eigen::MatrixXd gts(3, 2); + gts.col(0) = this->gt.row(0); + gts.col(1) = this->gt.row(1); + //cout << this->gt(0, 0) << "\t" << this->gt(0, 1) << "\t" << this->gt(0, 2) << endl;; + //cout << gts(0, 0) << "\t" << gts(1,0) << "\t" << gts(2, 0) << endl;; + //cout << this->gt(1, 0) << "\t" << this->gt(1, 1) << "\t" << this->gt(1, 2) << endl;; + //cout<< gts(0, 1) << "\t" << gts(1, 1) << "\t" << gts(2,1) << endl;; + //cout << points(3, 0) << "\t" << points(3, 1) << "\t" << points(3, 2) << endl;; + + + result.block(0, 0, points.rows(), 2) = points * gts; + return result; +} + +Eigen::MatrixXd gdalImage::getHist(int bandids) +{ + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + // 锟斤拷DEM影锟斤拷 + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_ReadOnly));//锟斤拷只锟斤拷锟斤拷式锟斤拷取锟斤拷锟斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* xBand = rasterDataset->GetRasterBand(bandids); + + //锟斤拷取图锟斤拷直锟斤拷图 + + double dfMin = this->min(bandids); + double dfMax = this->max(bandids); + int count = int((dfMax - dfMin) / 0.01); + count = count > 255 ? count : 255; + GUIntBig* panHistogram =new GUIntBig[count]; + xBand->GetHistogram(dfMin, dfMax, count, panHistogram, TRUE, FALSE, NULL, NULL); + Eigen::MatrixXd result(count, 2); + double delta = (dfMax - dfMin) / count; + for (int i = 0; i < count; i++) { + result(i, 0) = dfMin + i * delta; + result(i, 1) = double(panHistogram[i]); + } + delete[] panHistogram; + GDALClose((GDALDatasetH)rasterDataset); + return result; +} + + +gdalImage CreategdalImage(string img_path, int height, int width, int band_num, Eigen::MatrixXd gt, std::string projection, bool need_gt) { + + if (boost::filesystem::exists(img_path.c_str())) { + boost::filesystem::remove(img_path.c_str()); + } + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = poDriver->Create(img_path.c_str(), width, height, band_num, GDT_Float32, NULL); // 锟斤拷锟斤拷锟斤拷 + if (need_gt) { + poDstDS->SetProjection(projection.c_str()); + + // 锟斤拷锟斤拷转锟斤拷锟斤拷锟斤拷 + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + for (int i = 1; i <= band_num; i++) { + poDstDS->GetRasterBand(i)->SetNoDataValue(-9999); + } + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + + +/// +/// 锟矫硷拷DEM +/// +/// +/// +/// +/// +void clipGdalImage(string in_path, string out_path, DemBox box, double pixelinterval) { + + + + +} + + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if (pDSrc == NULL) + { + return -1; + } + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + //锟斤拷锟矫伙拷锟酵队帮拷锟斤拷锟轿?拷锟斤拷锟揭伙拷锟?1锟?7 + if (strlen(pszSrcWKT) <= 0) + { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + //oSRS.SetUTM(50, true); //锟斤拷锟斤拷锟斤拷 锟斤拷锟斤拷120锟斤拷 + //oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + } + std::cout << "GDALCreateGenImgProjTransformer " << endl; + void* hTransformArg; + hTransformArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, NULL, pszSrcWKT, FALSE, 0.0, 1); + std::cout << "no proj " << endl; + //(没锟斤拷投影锟斤拷影锟斤拷锟斤拷锟斤拷锟斤拷卟锟酵?拷锟?1锟?7) + if (hTransformArg == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + std::cout << "has proj " << endl; + double dGeoTrans[6] = { 0 }; + int nNewWidth = 0, nNewHeight = 0; + if (GDALSuggestedWarpOutput((GDALDatasetH)pDSrc, GDALGenImgProjTransform, hTransformArg, dGeoTrans, &nNewWidth, &nNewHeight) != CE_None) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + + //GDALDestroyGenImgProjTransformer(hTransformArg); + + //锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷菁锟?1锟?7 + GDALDataset* pDDst = pDriver->Create(pszOutFile, new_width, new_height, nBandCount, dataType, NULL); + if (pDDst == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(gt); + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + //psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + std::cout << "GDALCreateGenImgProjTransformer" << endl; + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, (GDALDatasetH)pDDst, pszSrcWKT, FALSE, 0.0, 1);; + + std::cout << "GDALCreateGenImgProjTransformer has created" << endl; + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) + { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + return -3; + } + std::cout << "ChunkAndWarpImage:"<< new_width<<","<< new_height << endl; + oWo.ChunkAndWarpMulti(0, 0, new_width, new_height); + GDALFlushCache(pDDst); + std::cout << "ChunkAndWarpImage over" << endl; + //GDALDestroyGenImgProjTransformer(psWo->pTransformerArg); + //GDALDestroyWarpOptions(psWo); + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return 0; +} + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_Update); + if (pDSrc == NULL) + { + return -1; + } + + GDALDataType gdal_datatype = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* demBand = pDSrc->GetRasterBand(band_ids); + + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int start_col = 0, start_row = 0, rows_count = 0, cols_count; + + int row_delta = int(120000000 / width); + + GDALRasterIOExtraArg psExtraArg; + INIT_RASTERIO_EXTRA_ARG(psExtraArg); + psExtraArg.eResampleAlg = eResample; + + do { + + rows_count = start_row + row_delta < height ? row_delta : height - start_row; + cols_count = width; + + if (gdal_datatype == GDALDataType::GDT_UInt16) { + + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + start_row = start_row + rows_count; + } while (start_row < height); + GDALClose((GDALDatasetH)pDSrc); + + + return 0; +} + + +string Convert(float Num) +{ + ostringstream oss; + oss << Num; + string str(oss.str()); + return str; +} + + + +std::string JoinPath(const std::string& path, const std::string& filename) +{ + int dir_size = path.size(); + + int last_sprt_index = path.find_last_of('\\'); + int last_is_sprt = (last_sprt_index == dir_size - 1); + + if (last_is_sprt) + { + return path + filename; + } + else + { + return path + "\\" + filename; + } +} + + + + +/// +////////////////////////////////////////////////////////////////////// WGS84 to J2000 ///////////////////////////////////////////////////////////////////////////////////////// +/// +/* +Eigen::Matrix WGS84_J2000::IAU2000ModelParams = Eigen::Matrix(); + +WGS84_J2000::WGS84_J2000() +{ + WGS84_J2000::IAU2000ModelParams << 0.0, 0.0, 0.0, 0.0, 1.0, -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0, + 0.0, 0.0, 2.0, -2.0, 2.0, -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0, + 0.0, 0.0, 2.0, 0.0, 2.0, -2276413.0, -234.0, 2796.0, 978459.0, -485.0, 1374.0, + 0.0, 0.0, 0.0, 0.0, 2.0, 2074554.0, 207.0, -698.0, -897492.0, 470.0, -291.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 1475877.0, -3633.0, 11817.0, 73871.0, -184.0, -1924.0, + 0.0, 1.0, 2.0, -2.0, 2.0, -516821.0, 1226.0, -524.0, 224386.0, -677.0, -174.0, + 1.0, 0.0, 0.0, 0.0, 0.0, 711159.0, 73.0, -872.0, -6750.0, 0.0, 358.0, + 0.0, 0.0, 2.0, 0.0, 1.0, -387298.0, -367.0, 380.0, 200728.0, 18.0, 318.0, + 1.0, 0.0, 2.0, 0.0, 2.0, -301461.0, -36.0, 816.0, 129025.0, -63.0, 367.0, + 0.0, -1.0, 2.0, -2.0, 2.0, 215829.0, -494.0, 111.0, -95929.0, 299.0, 132.0, + 0.0, 0.0, 2.0, -2.0, 1.0, 128227.0, 137.0, 181.0, -68982.0, -9.0, 39.0, + -1.0, 0.0, 2.0, 0.0, 2.0, 123457.0, 11.0, 19.0, -53311.0, 32.0, -4.0, + -1.0, 0.0, 0.0, 2.0, 0.0, 156994.0, 10.0, -168.0, -1235.0, 0.0, 82.0, + 1.0, 0.0, 0.0, 0.0, 1.0, 63110.0, 63.0, 27.0, -33228.0, 0.0, -9.0, + -1.0, 0.0, 0.0, 0.0, 1.0, -57976.0, -63.0, -189.0, 31429.0, 0.0, -75.0, + -1.0, 0.0, 2.0, 2.0, 2.0, -59641.0, -11.0, 149.0, 25543.0, -11.0, 66.0, + 1.0, 0.0, 2.0, 0.0, 1.0, -51613.0, -42.0, 129.0, 26366.0, 0.0, 78.0, + -2.0, 0.0, 2.0, 0.0, 1.0, 45893.0, 50.0, 31.0, -24236.0, -10.0, 20.0, + 0.0, 0.0, 0.0, 2.0, 0.0, 63384.0, 11.0, -150.0, -1220.0, 0.0, 29.0, + 0.0, 0.0, 2.0, 2.0, 2.0, -38571.0, -1.0, 158.0, 16452.0, -11.0, 68.0, + 0.0, -2.0, 2.0, -2.0, 2.0, 32481.0, 0.0, 0.0, -13870.0, 0.0, 0.0, + -2.0, 0.0, 0.0, 2.0, 0.0, -47722.0, 0.0, -18.0, 477.0, 0.0, -25.0, + 2.0, 0.0, 2.0, 0.0, 2.0, -31046.0, -1.0, 131.0, 13238.0, -11.0, 59.0, + 1.0, 0.0, 2.0, -2.0, 2.0, 28593.0, 0.0, -1.0, -12338.0, 10.0, -3.0, + -1.0, 0.0, 2.0, 0.0, 1.0, 20441.0, 21.0, 10.0, -10758.0, 0.0, -3.0, + 2.0, 0.0, 0.0, 0.0, 0.0, 29243.0, 0.0, -74.0, -609.0, 0.0, 13.0, + 0.0, 0.0, 2.0, 0.0, 0.0, 25887.0, 0.0, -66.0, -550.0, 0.0, 11.0, + 0.0, 1.0, 0.0, 0.0, 1.0, -14053.0, -25.0, 79.0, 8551.0, -2.0, -45.0, + -1.0, 0.0, 0.0, 2.0, 1.0, 15164.0, 10.0, 11.0, -8001.0, 0.0, -1.0, + 0.0, 2.0, 2.0, -2.0, 2.0, -15794.0, 72.0, -16.0, 6850.0, -42.0, -5.0, + 0.0, 0.0, -2.0, 2.0, 0.0, 21783.0, 0.0, 13.0, -167.0, 0.0, 13.0, + 1.0, 0.0, 0.0, -2.0, 1.0, -12873.0, -10.0, -37.0, 6953.0, 0.0, -14.0, + 0.0, -1.0, 0.0, 0.0, 1.0, -12654.0, 11.0, 63.0, 6415.0, 0.0, 26.0, + -1.0, 0.0, 2.0, 2.0, 1.0, -10204.0, 0.0, 25.0, 5222.0, 0.0, 15.0, + 0.0, 2.0, 0.0, 0.0, 0.0, 16707.0, -85.0, -10.0, 168.0, -1.0, 10.0, + 1.0, 0.0, 2.0, 2.0, 2.0, -7691.0, 0.0, 44.0, 3268.0, 0.0, 19.0, + -2.0, 0.0, 2.0, 0.0, 0.0, -11024.0, 0.0, -14.0, 104.0, 0.0, 2.0, + 0.0, 1.0, 2.0, 0.0, 2.0, 7566.0, -21.0, -11.0, -3250.0, 0.0, -5.0, + 0.0, 0.0, 2.0, 2.0, 1.0, -6637.0, -11.0, 25.0, 3353.0, 0.0, 14.0, + 0.0, -1.0, 2.0, 0.0, 2.0, -7141.0, 21.0, 8.0, 3070.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 2.0, 1.0, -6302.0, -11.0, 2.0, 3272.0, 0.0, 4.0, + 1.0, 0.0, 2.0, -2.0, 1.0, 5800.0, 10.0, 2.0, -3045.0, 0.0, -1.0, + 2.0, 0.0, 2.0, -2.0, 2.0, 6443.0, 0.0, -7.0, -2768.0, 0.0, -4.0, + -2.0, 0.0, 0.0, 2.0, 1.0, -5774.0, -11.0, -15.0, 3041.0, 0.0, -5.0, + 2.0, 0.0, 2.0, 0.0, 1.0, -5350.0, 0.0, 21.0, 2695.0, 0.0, 12.0, + 0.0, -1.0, 2.0, -2.0, 1.0, -4752.0, -11.0, -3.0, 2719.0, 0.0, -3.0, + 0.0, 0.0, 0.0, -2.0, 1.0, -4940.0, -11.0, -21.0, 2720.0, 0.0, -9.0, + -1.0, -1.0, 0.0, 2.0, 0.0, 7350.0, 0.0, -8.0, -51.0, 0.0, 4.0, + 2.0, 0.0, 0.0, -2.0, 1.0, 4065.0, 0.0, 6.0, -2206.0, 0.0, 1.0, + 1.0, 0.0, 0.0, 2.0, 0.0, 6579.0, 0.0, -24.0, -199.0, 0.0, 2.0, + 0.0, 1.0, 2.0, -2.0, 1.0, 3579.0, 0.0, 5.0, -1900.0, 0.0, 1.0, + 1.0, -1.0, 0.0, 0.0, 0.0, 4725.0, 0.0, -6.0, -41.0, 0.0, 3.0, + -2.0, 0.0, 2.0, 0.0, 2.0, -3075.0, 0.0, -2.0, 1313.0, 0.0, -1.0, + 3.0, 0.0, 2.0, 0.0, 2.0, -2904.0, 0.0, 15.0, 1233.0, 0.0, 7.0, + 0.0, -1.0, 0.0, 2.0, 0.0, 4348.0, 0.0, -10.0, -81.0, 0.0, 2.0, + 1.0, -1.0, 2.0, 0.0, 2.0, -2878.0, 0.0, 8.0, 1232.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 1.0, 0.0, -4230.0, 0.0, 5.0, -20.0, 0.0, -2.0, + -1.0, -1.0, 2.0, 2.0, 2.0, -2819.0, 0.0, 7.0, 1207.0, 0.0, 3.0, + -1.0, 0.0, 2.0, 0.0, 0.0, -4056.0, 0.0, 5.0, 40.0, 0.0, -2.0, + 0.0, -1.0, 2.0, 2.0, 2.0, -2647.0, 0.0, 11.0, 1129.0, 0.0, 5.0, + -2.0, 0.0, 0.0, 0.0, 1.0, -2294.0, 0.0, -10.0, 1266.0, 0.0, -4.0, + 1.0, 1.0, 2.0, 0.0, 2.0, 2481.0, 0.0, -7.0, -1062.0, 0.0, -3.0, + 2.0, 0.0, 0.0, 0.0, 1.0, 2179.0, 0.0, -2.0, -1129.0, 0.0, -2.0, + -1.0, 1.0, 0.0, 1.0, 0.0, 3276.0, 0.0, 1.0, -9.0, 0.0, 0.0, + 1.0, 1.0, 0.0, 0.0, 0.0, -3389.0, 0.0, 5.0, 35.0, 0.0, -2.0, + 1.0, 0.0, 2.0, 0.0, 0.0, 3339.0, 0.0, -13.0, -107.0, 0.0, 1.0, + -1.0, 0.0, 2.0, -2.0, 1.0, -1987.0, 0.0, -6.0, 1073.0, 0.0, -2.0, + 1.0, 0.0, 0.0, 0.0, 2.0, -1981.0, 0.0, 0.0, 854.0, 0.0, 0.0, + -1.0, 0.0, 0.0, 1.0, 0.0, 4026.0, 0.0, -353.0, -553.0, 0.0, -139.0, + 0.0, 0.0, 2.0, 1.0, 2.0, 1660.0, 0.0, -5.0, -710.0, 0.0, -2.0, + -1.0, 0.0, 2.0, 4.0, 2.0, -1521.0, 0.0, 9.0, 647.0, 0.0, 4.0, + -1.0, 1.0, 0.0, 1.0, 1.0, 1314.0, 0.0, 0.0, -700.0, 0.0, 0.0, + 0.0, -2.0, 2.0, -2.0, 1.0, -1283.0, 0.0, 0.0, 672.0, 0.0, 0.0, + 1.0, 0.0, 2.0, 2.0, 1.0, -1331.0, 0.0, 8.0, 663.0, 0.0, 4.0, + -2.0, 0.0, 2.0, 2.0, 2.0, 1383.0, 0.0, -2.0, -594.0, 0.0, -2.0, + -1.0, 0.0, 0.0, 0.0, 2.0, 1405.0, 0.0, 4.0, -610.0, 0.0, 2.0, + 1.0, 1.0, 2.0, -2.0, 2.0, 1290.0, 0.0, 0.0, -556.0, 0.0, 0.0; +} +WGS84_J2000::~WGS84_J2000() +{ + +} +/// +/// step1 WGS 84 转锟斤拷锟斤拷协锟斤拷锟斤拷锟斤拷锟斤拷锟较碉拷锟?1锟?7 +/// 锟斤拷鼐锟轿筹拷雀叱锟紹LH锟斤拷毓锟斤拷锟斤拷锟较碉拷锟阶?拷锟?1锟?7 BLH-- > XG +/// ECEF, Earth Centered Earth Fixed; 锟截癸拷锟斤拷锟斤拷系 锟轿匡拷平锟芥:平锟斤拷锟斤拷妫?拷锟斤拷锟斤拷锟斤拷模锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷CIO锟斤拷锟斤拷锟竭达拷直锟斤拷平锟芥。 +/// x锟斤拷为锟轿匡拷平锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟狡斤拷娼伙拷撸锟絲锟斤拷为锟斤拷锟斤拷指锟斤拷CIO锟姐。 +/// +/// B L H锟街憋拷为锟斤拷锟轿筹拷取锟斤拷锟截撅拷锟饺和达拷馗叱锟?1锟?7 锟斤拷锟斤拷锟斤拷锟轿狽 * 3锟斤拷锟斤拷 +/// XYZ 为锟截癸拷锟斤拷锟斤拷系锟斤拷 x y z锟斤拷锟斤拷锟斤拷锟斤拷锟轿狽 * 3锟斤拷锟斤拷 +Eigen::MatrixXd WGS84_J2000::WGS84TECEF(Eigen::MatrixXd LBH_deg_m) +{ + return LLA2XYZ(LBH_deg_m); +} +/// +/// step 2 协锟斤拷锟斤拷锟斤拷锟斤拷锟较?1锟?7 转锟斤拷为瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷锟斤拷要锟芥及锟斤拷询 锟斤拷锟斤拷时锟教碉拷 xp,yp , 锟斤拷锟皆诧拷询EOP锟侥硷拷锟斤拷茫锟斤拷锟斤拷氐锟街凤拷锟斤拷锟絟ttp://celestrak.com/spacedata/ +/// earthFixedXYZ=ordinateSingleRotate('x',yp)*ordinateSingleRotate('y',xp)*earthFixedXYZ; +/// +/// axis 锟斤拷示围锟斤拷锟斤拷转锟斤拷锟斤拷锟斤拷锟斤拷 '1' 锟斤拷示围锟斤拷 x锟斤拷锟斤拷时锟斤拷锟斤拷转;'2' 锟斤拷示围锟斤拷 y锟斤拷锟斤拷时锟斤拷锟斤拷转;'3'锟斤拷示围锟斤拷 z锟斤拷锟斤拷时锟斤拷锟斤拷转 +/// angle_deg 锟斤拷示锟斤拷转锟侥角讹拷 默锟斤拷 degree +/// +Eigen::MatrixXd WGS84_J2000::ordinateSingleRotate(int axis, double angle_deg) +{ + angle_deg = angle_deg * d2r; + Eigen::MatrixXd R = Eigen::MatrixXd::Ones(3, 3); + switch (axis) + { + case 1: // x + R << 1, 0.0, 0.0, + 0.0, cos(angle_deg), sin(angle_deg), + 0.0, -1 * sin(angle_deg), cos(angle_deg); + break; + case 2:// y + R << cos(angle_deg), 0.0, -1 * sin(angle_deg), + 0.0, 1, 0.0, + sin(angle_deg), 0.0, cos(angle_deg); + break; + case 3:// z + R << cos(angle_deg), sin(angle_deg), 0.0, + -1 * sin(angle_deg), cos(angle_deg), 0.0, + 0.0, 0.0, 1; + break; + default: + throw exception("Error Axis"); + exit(-1); + } + return R; +} + +/// +/// step 3 瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷为 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷utc时锟斤拷转锟斤拷为锟斤拷锟斤拷锟斤拷锟轿猴拷锟斤拷时 +/// xyz= ordinateSingleRotate('z',-gst_deg)*earthFixedXYZ; +/// UNTITLED 锟斤拷锟姐当锟截猴拷锟斤拷时,锟斤拷锟斤拷值锟斤拷时锟斤拷为锟斤拷位 +/// %dAT 锟斤拷锟斤拷锟斤拷 +/// % TAI锟斤拷锟斤拷原锟斤拷时锟斤拷 锟斤拷时锟斤拷锟斤拷准 TAI = UTC + dAT;% 锟斤拷锟斤拷原锟斤拷时锟斤拷 +/// % TT 锟斤拷锟斤拷时 TT = TAI + 32.184 锟斤拷2014锟斤拷锟绞憋拷锟?1锟?7; +/// % TDT 锟斤拷锟斤拷锟斤拷学时锟斤拷 +/// % ET 锟斤拷锟斤拷时锟斤拷 +/// % 锟斤拷锟斤拷时 = 锟斤拷锟斤拷锟斤拷学时锟斤拷 = 锟斤拷锟斤拷时锟斤拷 +/// %锟斤拷锟斤拷时=锟斤拷锟斤拷锟斤拷学时锟斤拷=锟斤拷锟斤拷时锟斤拷 +/// +/// 锟斤拷式为y m d 锟斤拷锟斤拷d锟斤拷锟斤拷值为小锟斤拷锟斤拷锟斤拷h m s 锟斤拷锟斤拷sec/3600+min/60+h)/24转锟斤拷锟斤拷小锟斤拷锟斤拷锟斤拷锟桔加碉拷day 锟斤拷 +/// dUT1 为ut1-utc 锟侥差,锟斤拷值锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷1锟诫,锟斤拷iers锟缴伙拷锟斤拷锟街?1锟?7 0 +/// 锟斤拷锟斤拷锟斤拷 37 +/// 锟斤拷锟斤拷原锟斤拷时锟斤拷 锟斤拷时锟斤拷锟斤拷准 TAI=UTC+dAT; %锟斤拷锟斤拷原锟斤拷时锟斤拷 +/// 锟斤拷锟斤拷时 TT = TAI+32.184 锟斤拷2014锟斤拷锟绞憋拷锟?1锟?7; +/// +int WGS84_J2000::utc2gst(Eigen::MatrixXd UTC, double dUT1, double dAT, double& gst_deg, double& JDTDB) +{ + + //function[gst_deg, JDTDB] = utc2gst(UTC, dUT1, dAT) + //% TDT 锟斤拷锟斤拷锟斤拷学时锟斤拷 + // % ET 锟斤拷锟斤拷时锟斤拷 + // % 锟斤拷锟斤拷时 = 锟斤拷锟斤拷锟斤拷学时锟斤拷 = 锟斤拷锟斤拷时锟斤拷 + double J2000 = 2451545; + + double JDutc = YMD2JD(UTC(0,0), UTC(0,1), UTC(0,2)); + double JDUT1 = JDutc + dUT1 / 86400;// % UT1 为锟斤拷锟斤拷时锟斤拷锟斤拷锟斤拷时锟斤拷锟斤拷锟斤拷转锟侥诧拷锟斤拷锟饺o拷锟斤拷锟斤拷锟経TC时锟斤拷锟斤拷dUT1锟侥诧拷锟絛UT1锟节革拷锟斤拷锟斤拷锟斤拷锟斤拷时锟脚猴拷锟叫伙拷锟斤拷0.1锟斤拷木锟斤拷雀锟斤拷锟絀ERS锟斤拷锟斤拷锟斤拷锟斤拷锟襟,伙拷锟斤拷1e - 5锟侥撅拷锟饺革拷锟斤拷锟斤拷 + double dT = 32.184 + dAT - dUT1; + double JDTT = JDUT1 + dT / 86400; + + + //% JDTT = YMD2JD(UTC(1), UTC(2), UTC(3)) + dUT1 / 86400; + //% 锟斤拷锟饺硷拷锟斤拷TDB, TDB锟斤拷锟斤拷锟侥讹拷锟斤拷学时锟斤拷锟斤拷太锟斤拷锟斤拷锟斤拷锟斤拷锟角碉拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟叫碉拷时锟斤拷叨锟?1锟?7 + double T = (JDTT - J2000) / 36525; + double temp = 0.001657 * sin(628.3076 * T + 6.2401) + + 0.000022 * sin(575.3385 * T + 4.2970) + + 0.000014 * sin(1256.6152 * T + 6.1969) + + 0.000005 * sin(606.9777 * T + 4.0212) + + 0.000005 * sin(52.9691 * T + 0.4444) + + 0.000002 * sin(21.3299 * T + 5.5431) + + 0.00001 * T * sin(628.3076 * T + 4.2490); + JDTDB = JDTT + temp / 86400; + + //% 锟斤拷锟斤拷锟斤拷锟経T2, UT2锟斤拷锟斤拷UT1锟侥伙拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟皆硷拷锟节变化锟斤拷玫锟斤拷锟斤拷锟斤拷锟绞憋拷锟?1锟?7 + // %% 锟斤拷锟斤拷UT1锟斤拷锟斤拷Tb, Tb为锟皆憋拷锟斤拷锟斤拷锟斤拷为锟斤拷位锟斤拷锟斤拷锟斤拷元B2000.0锟斤拷锟斤拷ff + // % B2000 = 2451544.033; + //% Tb = (YMD2JD(UT1(1), UT1(2), UT1(3)) - B2000) / 365.2422; + //% dTs = 0.022 * sin(2 * pi * Tb) - 0.012 * cos(2 * pi * Tb) - 0.006 * sin(4 * pi * Tb) + 0.007 * cos(4 * pi * Tb); + //% dTs = dTs / 86400; + //% UT2 = UT1 + [0 0 dTs]; + + //% 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷时GMST; 锟斤拷位为锟斤拷 + T = (JDTDB - J2000) / 36525; + double T2 = T * T; + double T3 = T2 * T; + double T4 = T3 * T; + double T5 = T4 * T; + double Du = JDUT1 - J2000; + double thita = 0.7790572732640 + 1.00273781191135448 * Du;//% 锟斤拷J2000锟斤拷锟斤拷锟阶?拷锟斤拷锟饺︼拷锟斤拷锟?1锟?7 + double GMST_deg = (-0.0000000368 * T5 - 0.000029956 * T4 - 0.00000044 * T3 + 1.3915817 * T2 + 4612.156534 * T + 0.014506) / 3600 + (thita - floor(thita)) * 360; + double epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg; + WGS84_J2000::nutationInLongitudeCaculate(JDTDB, epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg); + //[epthilongA_deg, dertaPthi_deg] = nutationInLongitudeCaculate(JDTDB); + + //% 锟斤拷锟斤拷嗑?拷露锟斤拷锟斤拷锟斤拷锟斤拷锟絜clipticObliquitygama锟斤拷锟斤拷位为锟斤拷锟斤拷 + //% 锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷锟?1锟?7 太锟斤拷平锟斤拷锟斤拷锟?1锟?7 锟斤拷锟斤拷纬锟饺凤拷锟斤拷 锟斤拷锟斤拷平锟角撅拷(锟斤拷锟斤拷平锟狡撅拷 - 太锟斤拷平锟狡撅拷锟斤拷 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟狡撅拷 锟斤拷位为锟斤拷锟斤拷 + double F_deg = (0.00000417 * T4 - 0.001037 * T3 - 12.7512 * T2 + 1739527262.8478 * T + 335779.526232) / 3600; + F_deg = fmod(F_deg, 360); + double D_deg = (-0.00003169 * T4 + 0.006593 * T3 - 6.3706 * T2 + 1602961601.2090 * T + 1072260.70369) / 3600; + D_deg = fmod(D_deg, 360); + double Omiga_deg = (-0.00005939 * T4 + 0.007702 * T3 + 7.4722 * T2 - 6962890.5431 * T + 450160.398036) / 3600; + Omiga_deg = fmod(Omiga_deg, 360); + + double epthilongGama_deg = dertaPthi_deg * cosd(epthilongA_deg) + + (0.00264096 * sind(Omiga_deg ) + + 0.00006352 * sind(2 * Omiga_deg ) + + 0.00001175 * sind(2 * F_deg - 2 * D_deg + 3 * Omiga_deg) + + 0.00001121 * sind(2 * F_deg - 2 * D_deg + Omiga_deg) + - 0.00000455 * sind(2 * F_deg - 2 * D_deg + 2 * Omiga_deg) + + 0.00000202 * sind(2 * F_deg + 3 * Omiga_deg) + + 0.00000198 * sind(2 * F_deg + Omiga_deg) + - 0.00000172 * sind(3 * Omiga_deg) + - 0.00000087 * T * sind(Omiga_deg)) / 3600; + gst_deg = epthilongGama_deg + GMST_deg; + return 0; +} + + +/// +/// step 4 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷瞬时平锟斤拷锟斤拷 锟斤拷锟斤拷系 +/// 锟斤拷锟斤拷平锟狡赤交锟角o拷锟狡撅拷锟铰讹拷锟斤拷锟酵斤拷锟斤拷锟铰讹拷锟斤拷瞬时锟狡赤交锟角★拷 +/// +/// 锟斤拷锟斤拷锟斤拷 +/// 锟斤拷示锟斤拷锟斤拷木锟斤拷锟揭?拷锟?1锟?7 锟斤拷值为锟斤拷normal锟斤拷 锟酵★拷high锟斤拷 锟斤拷锟斤拷锟斤拷'N'锟酵★拷H'锟斤拷示一锟姐精锟饺和高撅拷锟斤拷 锟斤拷默锟斤拷为锟竭撅拷锟饺硷拷锟斤拷 +/// 平锟狡赤交锟斤拷 +/// 锟狡撅拷锟铰讹拷 +/// 锟酵斤拷锟斤拷锟铰讹拷 +/// 瞬时锟狡赤交锟斤拷 +/// +int WGS84_J2000::nutationInLongitudeCaculate(double JD, double& epthilongA_deg, double& dertaPthi_deg, double& dertaEpthilong_deg, double& epthilong_deg) +{ + double T = (JD - 2451545) / 36525; + double T2 = T * T; + double T3 = T2 * T; + double T4 = T3 * T; + double T5 = T4 * T; + //% 锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷锟絣unarMeanAnomaly_deg(l_deg) 太锟斤拷平锟斤拷锟斤拷锟絊olarMeanAnomaly_deg(solarl_deg) + // % 锟斤拷锟斤拷纬锟饺凤拷锟斤拷lunarLatitudeAngle_deg(F_deg) 锟斤拷锟斤拷平锟角撅拷diffLunarSolarElestialLongitude_deg(D_deg锟斤拷锟斤拷平锟狡撅拷 - 太锟斤拷平锟狡撅拷锟斤拷 + // % 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟狡撅拷SolarAscendingNodeElestialLongitude_deg(Omiga_deg) + double l_deg = (-0.00024470 * T4 + 0.051635 * T3 + 31.8792 * T2 + 1717915923.2178 * T + 485868.249036) / 3600; + l_deg = fmod(l_deg, 360); + double solarl_deg = (-0.00001149 * T4 + 0.000136 * T3 - 0.5532 * T2 + 129596581.0481 * T + 1287104.79305) / 3600; + solarl_deg = fmod(solarl_deg, 360); + double F_deg = (0.00000417 * T4 - 0.001037 * T3 - 12.7512 * T2 + 1739527262.8478 * T + 335779.526232) / 3600; + F_deg = fmod(F_deg, 360); + double D_deg = (-0.00003169 * T4 + 0.006593 * T3 - 6.3706 * T2 + 1602961601.2090 * T + 1072260.70369) / 3600; + D_deg = fmod(D_deg, 360); + double Omiga_deg = (-0.00005939 * T4 + 0.007702 * T3 + 7.4722 * T2 - 6962890.5431 * T + 450160.398036) / 3600; + Omiga_deg = fmod(Omiga_deg, 360); + Eigen::MatrixXd basicAngle_deg = Eigen::Matrix{ l_deg,solarl_deg,F_deg,D_deg,Omiga_deg }; + + epthilongA_deg = (-0.0000000434 * T5 - 0.000000576 * T4 + 0.00200340 * T3 - 0.0001831 * T2 - 46.836769 * T + 84381.406) / 3600; + epthilongA_deg = epthilongA_deg - floor(epthilongA_deg / 360) * 360; + //% IAU2000模锟斤拷锟斤拷77锟斤拷 + Eigen::MatrixXd elestialLonNutation = WGS84_J2000::IAU2000ModelParams; + + dertaPthi_deg = -3.75e-08; + dertaEpthilong_deg = 0.388e-3 / 3600; + for (int i = 0; i < 77; i++) { + double sumAngle_deg = 0; + for (int j = 0; j < 5; j++) { + sumAngle_deg = sumAngle_deg + elestialLonNutation(i, j) * basicAngle_deg(j); + } + sumAngle_deg = sumAngle_deg - floor(sumAngle_deg / 360) * 360; + dertaPthi_deg = dertaPthi_deg + ((elestialLonNutation(i, 5) + elestialLonNutation(i, 6) * T) * sind(sumAngle_deg ) + elestialLonNutation(i, 7) * cosd(sumAngle_deg)) * 1e-7 / 3600; + dertaEpthilong_deg = dertaEpthilong_deg + ((elestialLonNutation(i, 8) + elestialLonNutation(i, 9) * T) * cosd(sumAngle_deg) + elestialLonNutation(i, 10) * sind(sumAngle_deg)) * 1e-7 / 3600; + } + epthilong_deg = epthilongA_deg + dertaEpthilong_deg; + return 0; +} + +/// +/// zA锟斤拷thitaA锟斤拷zetaA为锟斤拷锟斤拷锟斤拷锟?1锟?7, 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 +/// +/// +/// +/// +/// +/// +int WGS84_J2000::precessionAngle(double JDTDB, double& zetaA, double& thitaA, double& zA) +{ + double T = (JDTDB - 2451545) / 36525; + double T2 = T * T; + double T3 = T2 * T; + //% + //% zetaA = (2306.218 * T + 0.30188 * T2 + 0.017998 * T3) / 3600; + //% zA = (2306.218 * T + 1.09468 * T2 + 0.018203) / 3600; + //% thitaA = (2004.3109 * T - 0.42665 * T2 - 0.041833 * T3) / 3600; + double T4 = T3 * T; + double T5 = T4 * T; + zetaA = (-0.0000003173 * T5 - 0.000005971 * T4 + 0.01801828 * T3 + 0.2988499 * T2 + 2306.083227 * T + 2.650545) / 3600; + thitaA = (-0.0000001274 * T5 - 0.000007089 * T4 - 0.04182264 * T3 - 0.4294934 * T2 + 2004.191903 * T) / 3600; + zA = (-0.0000002904 * T5 - 0.000028596 * T4 + 0.01826837 * T3 + 1.0927348 * T2 + 2306.077181 * T - 2.650545) / 3600; + return 0; +} + +/// +/// 同时 YMD2JD锟斤拷锟斤拷为 锟斤拷锟斤拷锟斤拷转锟斤拷为锟斤拷锟斤拷锟秸o拷 +/// +/// +/// +/// +/// +double WGS84_J2000::YMD2JD(double y, double m, double d) +{ + int B = 0; + if (y > 1582 || (y == 1582 && m > 10) || (y == 1582 && m == 10 && d >= 15)) { + B = 2 - floor(y / 100) + floor(y / 400); + } + return floor(365.25 * (y + 4712)) + floor(30.6 * (m + 1)) + d - 63.5 + B; +} + +/// +/// WGS84 转 J2000 +/// +/// WGS84 锟斤拷纬锟斤拷 +/// 1x3 Y,m,d +/// EARTH ORIENTATION PARAMETER Xp +/// EARTH ORIENTATION PARAMETER Yp +/// Solar Weather Data dut1 +/// Solar Weather Data dat +/// +Eigen::MatrixXd WGS84_J2000::WGS842J2000(Eigen::MatrixXd BLH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat) +{ + //step 1 step1 WGS 84 转锟斤拷锟斤拷协锟斤拷锟斤拷锟斤拷锟斤拷锟较碉拷锟?1锟?7 + Eigen::MatrixXd earthFixedXYZ = WGS84_J2000::WGS84TECEF(BLH_deg_m).transpose(); + //step 2 协锟斤拷锟斤拷锟斤拷锟斤拷锟较?1锟?7 转锟斤拷为瞬时锟斤拷锟斤拷锟斤拷锟斤拷 + // 锟斤拷锟斤拷要锟芥及锟斤拷询 锟斤拷锟斤拷时锟教碉拷 xp,yp , 锟斤拷锟皆诧拷询EOP锟侥硷拷锟斤拷茫锟斤拷锟斤拷氐锟街凤拷锟斤拷锟絟ttp://celestrak.com/spacedata/ + earthFixedXYZ = ordinateSingleRotate(1, yp) * ordinateSingleRotate(2, xp) * earthFixedXYZ; + //step 3 瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷为 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 + // 锟矫诧拷锟斤拷锟斤拷要锟芥及锟斤拷锟斤拷锟斤拷锟斤拷锟轿猴拷锟斤拷时锟角的硷拷锟姐,锟斤拷锟节革拷锟斤拷锟斤拷锟轿猴拷锟斤拷时锟斤拷 锟斤拷锟姐方锟斤拷 锟杰多,锟斤拷锟斤拷锟斤拷锟?1锟?7 一锟斤拷锟斤拷为锟斤拷确锟侥硷拷锟姐方锟斤拷锟斤拷锟斤拷锟斤拷dut1 锟斤拷dat锟斤拷锟斤拷锟斤拷EOP锟侥硷拷锟斤拷锟叫★拷EOP锟侥硷拷锟斤拷锟截碉拷址锟斤拷锟斤拷 http://celestrak.org/spacedata/ + double gst_deg, JDTDB; + WGS84_J2000::utc2gst(UTC, dut1, dat, gst_deg, JDTDB); + Eigen::MatrixXd xyz = ordinateSingleRotate(3, -1 * gst_deg) * earthFixedXYZ; + //step 4 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷瞬时平锟斤拷锟斤拷 锟斤拷锟斤拷系 + double epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg; + WGS84_J2000::nutationInLongitudeCaculate(JDTDB, epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg); + xyz = ordinateSingleRotate(1, -epthilongA_deg) * ordinateSingleRotate(3, dertaPthi_deg) * ordinateSingleRotate(1, dertaEpthilong_deg + epthilongA_deg) * xyz; + //step5 瞬时平锟斤拷锟斤拷锟斤拷锟斤拷系转锟斤拷为协锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系锟斤拷J2000锟斤拷 + double zetaA, thitaA, zA; + WGS84_J2000::precessionAngle(JDTDB, zetaA, thitaA, zA); + xyz = ordinateSingleRotate(3, zetaA) * ordinateSingleRotate(2, -thitaA) * ordinateSingleRotate(3, zA) * xyz; + return xyz.transpose(); + //return Eigen::MatrixXd(); +} + +Landpoint WGS84_J2000::WGS842J2000(Landpoint p, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat) +{ + Eigen::MatrixXd blh = Eigen::MatrixXd(1, 3); + blh << p.lon, p.lat, p.ati; + blh = WGS84_J2000::WGS842J2000(blh, UTC, xp, yp, dut1, dat); + return Landpoint{ blh(0,0),blh(0,1) ,blh(0,0) }; + //return Landpoint(); +} +*/ + +//计算方位角添加的方法 +BLH xyz2blh(double X, double Y, double Z) +{ + double f, e2, B = 0.0, N = 0.0, H = 0.0, R0, R1, deltaH, deltaB; + f = (1.0 / 298.257223563), e2 = f * (2 - f); + BLH res = { 0 }; + R0 = sqrt(pow(X, 2) + pow(Y, 2)); + R1 = sqrt(pow(X, 2) + pow(Y, 2) + pow(Z, 2)); + //经度直接求解 + res.L = atan2(Y, X); + //迭代求大地维度和大地高 + N = a; + H = R1 - a; + B = atan2(Z * (N + H), R0 * (N * (1 - e2) + H)); + do + { + deltaH = N;//判断收敛所用 + deltaB = B; + N = a / sqrt(1 - e2 * pow(sin(B), 2)); + H = R0 / cos(B) - N; + B = atan2(Z * (N + H), R0 * (N * (1 - e2) + H)); + } while (fabs(deltaH - H) > 1.0e-3 && fabs(deltaB - B) > 1.0e-9); + res.B = B; + res.H = H; + return res; +} + +ENU xyz2enu(double Xr, double Yr, double Zr, double Xs, double Ys, double Zs) +{ + ENU enu = { 0 }; + BLH ref = xyz2blh(Xr, Yr, Zr); + double sinL = sin(ref.L); + double cosL = cos(ref.L); + double sinB = sin(ref.B); + double cosB = cos(ref.B); + double dx = Xs - Xr; + double dy = Ys - Yr; + double dz = Zs - Zr; + enu.E = -sinL * dx + cosL * dy; + enu.N = -sinB * cosL * dx - sinB * sinL * dy + cosB * dz; + enu.U = cosB * cosL * dx + cosB * sinL * dy + sinB * dz; + return enu; +} + +RAH Satrah(double Xr, double Yr, double Zr, double Xs, double Ys, double Zs) +{ + RAH rah = { 0 }; + ENU enu = xyz2enu(Xr, Yr, Zr, Xs, Ys, Zs); + rah.H = atan2(enu.U, sqrt(enu.E * enu.E + enu.N * enu.N)); + rah.A = atan2(enu.E, enu.N); + if (rah.A < 0) + rah.A += 2 * M_PI; + if (rah.A > 2 * M_PI) + rah.A -= 2 * M_PI; + rah.R = sqrt(enu.E * enu.E + enu.N * enu.N + enu.U * enu.U); + return rah; +} + +void creatTxt(const std::string& txtPath, const std::string& data) +{ + std::ofstream file(txtPath + "/Azimuth.txt"); + if (file.is_open()) + { + file << data; + file.close(); + std::cout << "create txt,write in Azimuth" << std::endl; + } + else + { + std::cout << "create txt failed!" << std::endl; + } +} + + + diff --git a/simorthoprogram-orth_gf3-strip/baseTool.h b/simorthoprogram-orth_gf3-strip/baseTool.h new file mode 100644 index 0000000..2a46d4b --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/baseTool.h @@ -0,0 +1,433 @@ +#pragma once +/// +/// 基本类、基本函数 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; +using namespace Eigen; + +#define PI_180 180/3.141592653589793238462643383279 +#define T180_PI 3.141592653589793238462643383279/180 +#define LIGHTSPEED 299792458 + + +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI + + + + + + + + +const double PI = 3.141592653589793238462643383279; +const double epsilon = 0.000000000000001; +const double pi = 3.14159265358979323846; +const double d2r = pi / 180; +const double r2d = 180 / pi; + +const double a = 6378137.0; //椭球长半轴 +const double ae = 6378137.0; //椭球长半轴 +const double ee= 0.0818191910428;// 第一偏心率 +const double f_inverse = 298.257223563; //扁率倒数 +const double b = a - a / f_inverse; +const double eSquare = (a * a - b * b) / (a * a); +const double e = sqrt(eSquare); +const double earth_Re = 6378136.49; +const double earth_Rp = (1 - 1 / f_inverse) * earth_Re; +const double earth_We = 0.000072292115; +///////////////////////////////////// 运行时间打印 ////////////////////////////////////////////////////////// + + +std::string getCurrentTimeString(); +std::string getCurrentShortTimeString(); + + +/////////////////////////////// 基本图像类 ////////////////////////////////////////////////////////// + +/// +/// 三维向量,坐标表达 +/// +struct Landpoint // 点 SAR影像的像素坐标; +{ + /// + /// 经度x + /// + double lon; // 经度x lon pixel_col + /// + /// 纬度y + /// + double lat; // 纬度y lat pixel_row + /// + /// 高度z + /// + double ati; // 高程z ati pixel_time +}; +struct Point_3d { + double x; + double y; + double z; +}; + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2); + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2); + +bool operator ==(const Landpoint& p1, const Landpoint& p2); + +Landpoint operator *(const Landpoint& p, double scale); + +/// +/// 向量A,B的夹角,角度 +/// +/// +/// +/// 角度制 0-360度,逆时针 +double getAngle(const Landpoint& a, const Landpoint& b); + +/// +/// 点乘 +/// +/// +/// +/// +double dot(const Landpoint& p1, const Landpoint& p2); + +double getlength(const Landpoint& p1); + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b); + + + +struct DemBox { + double min_lat; //纬度 + double min_lon;//经度 + double max_lat;//纬度 + double max_lon;//经度 +}; + + +/// +/// gdalImage图像操作类 +/// +class gdalImage +{ + +public: // 方法 + gdalImage(string raster_path); + ~gdalImage(); + void setHeight(int); + void setWidth(int); + void setTranslationMatrix(Eigen::MatrixXd gt); + void setData(Eigen::MatrixXd); + Eigen::MatrixXd getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + void saveImage(Eigen::MatrixXd,int start_row,int start_col, int band_ids); + void saveImage(); + void setNoDataValue(double nodatavalue,int band_ids); + int InitInv_gt(); + Landpoint getRow_Col(double lon, double lat); + Landpoint getLandPoint(double i, double j, double ati); + double mean(int bandids=1); + double max(int bandids=1); + double min(int bandids=1); + GDALRPCInfo getRPC(); + Eigen::MatrixXd getLandPoint(Eigen::MatrixXd points); + + Eigen::MatrixXd getHist(int bandids); +public: + string img_path; // 图像文件 + int height; // 高 + int width; // 宽 + int band_num;// 波段数 + int start_row;// + int start_col;// + int data_band_ids; + Eigen::MatrixXd gt; // 变换矩阵 + Eigen::MatrixXd inv_gt; // 逆变换矩阵 + Eigen::MatrixXd data; + string projection; +}; + +gdalImage CreategdalImage(string img_path, int height, int width, int band_num, Eigen::MatrixXd gt, std::string projection, bool need_gt=true); + +void clipGdalImage(string in_path, string out_path, DemBox box, double pixelinterval); + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample); + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample=GRIORA_Bilinear); + + + +/////////////////////////////// 基本图像类 结束 ////////////////////////////////////////////////////////// + +string Convert(float Num); +std::string JoinPath(const std::string& path, const std::string& filename); + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + + +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +Landpoint LLA2XYZ(const Landpoint& LLA); +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint); + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +Landpoint XYZ2LLA(const Landpoint& XYZ); + + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + +/// +/// 计算地表坡度向量 +/// +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 向量角度 +//Landpoint getSlopeVector(Landpoint& p0, Landpoint& p1, Landpoint& p2, Landpoint& p3, Landpoint& p4, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4); + +////////////////////////////// 插值 //////////////////////////////////////////// + +complex Cubic_Convolution_interpolation(double u,double v,Eigen::MatrixX> img); + +complex Cubic_kernel_weight(double s); + +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22); + + + +inline float cross2d(Point_3d a, Point_3d b) { return a.x * b.y - a.y * b.x; } + +inline Point_3d operator-(Point_3d a, Point_3d b) { + return Point_3d{ a.x - b.x, a.y - b.y, a.z - b.z }; +}; + +inline Point_3d operator+(Point_3d a, Point_3d b) { + return Point_3d{ a.x + b.x, a.y +b.y, a.z + b.z }; +}; + +inline double operator/(Point_3d a, Point_3d b) { + return sqrt(pow(a.x,2)+ pow(a.y, 2))/sqrt(pow(b.x, 2)+ pow(b.y, 2)); +}; +inline bool onSegment(Point_3d Pi, Point_3d Pj, Point_3d Q) +{ + if ((Q.x - Pi.x) * (Pj.y - Pi.y) == (Pj.x - Pi.x) * (Q.y - Pi.y) //叉乘 + //保证Q点坐标在pi,pj之间 + && min(Pi.x, Pj.x) <= Q.x && Q.x <= max(Pi.x, Pj.x) + && min(Pi.y, Pj.y) <= Q.y && Q.y <= max(Pi.y, Pj.y)) + return true; + else + return false; +} + +inline Point_3d invBilinear(Point_3d p, Point_3d a, Point_3d b, Point_3d c, Point_3d d) +{ + Point_3d res ; + + Point_3d e = b - a; + Point_3d f = d - a; + Point_3d g = a - b + c - d; + Point_3d h = p - a; + + double k2 = cross2d(g, f); + double k1 = cross2d(e, f) + cross2d(h, g); + double k0 = cross2d(h, e); + double u, v; + // if edges are parallel, this is a linear equation + if (abs(k2) < 0.001) + { + v = -k0 / k1; + u = (h.x - f.x *v) / (e.x + g.x *v); + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + // otherwise, it's a quadratic + else + { + float w = k1 * k1 - 4.0 * k0 * k2; + if (w < 0.0){ + // 可能在边界上 + if (onSegment(a, b, p)) { + Point_3d tt = b - a; + Point_3d ttpa = p - a; + double scater=ttpa / tt; + if(scater<0||scater>1){ return { -9999,-9999,-9999 }; } + p.z = a.z + scater * tt.z; + return p; + } + else if (onSegment(b, c, p)) { + Point_3d tt = c-b; + Point_3d ttpa = p - b; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = b.z + scater * tt.z; + return p; + } + else if (onSegment(c, d, p)) { + Point_3d tt = d-c; + Point_3d ttpa = p - c; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = c.z + scater * tt.z; + return p; + } + else if (onSegment(d, a, p)) { + Point_3d tt = a-d; + Point_3d ttpa = p - d; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = d.z + scater * tt.z; + return p; + } + + return { -9999,-9999,-9999 }; + } + else { + w = sqrt(w); + + float ik2 = 0.5 / k2; + float v = (-k1 - w) * ik2; + float u = (h.x - f.x * v) / (e.x + g.x * v); + + if (u < 0.0 || u>1.0 || v < 0.0 || v>1.0) + { + v = (-k1 + w) * ik2; + u = (h.x - f.x * v) / (e.x + g.x * v); + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; +} + + + +// +// WGS84 到J2000 坐标系的变换 +// 参考网址:https://blog.csdn.net/hit5067/article/details/116894616 +// 资料网址:http://celestrak.org/spacedata/ +// 参数文件: +// a. Earth Orientation Parameter 文件: http://celestrak.org/spacedata/EOP-Last5Years.csv +// b. Space Weather Data 文件: http://celestrak.org/spacedata/SW-Last5Years.csv +// 备注:上述文件是自2017年-五年内 +/** +在wgs84 坐标系转到J2000 坐标系 主要 涉及到坐标的相互转换。一般给定的WGS坐标为 给定时刻的 t ,BLH +转换步骤: +step 1: WGS 84 转换到协议地球坐标系 +step 2: 协议地球坐标系 转换为瞬时地球坐标系 +step 3: 瞬时地球坐标系 转换为 瞬时真天球坐标系 +step 4: 瞬时真天球坐标系 转到瞬时平天球 坐标系 +step 5: 瞬时平天球坐标系转换为协议天球坐标系(J2000) +**/ + + +inline double sind(double degree) { + return sin(degree * d2r); +} + +inline double cosd(double d) { + return cos(d * d2r); +} + +/* +class WGS84_J2000 +{ +public: + WGS84_J2000(); + ~WGS84_J2000(); + +public: + // step1 WGS 84 转换到协议地球坐标系。 + static Eigen::MatrixXd WGS84TECEF(Eigen::MatrixXd WGS84_Lon_lat_ait); + //step 2 协议地球坐标系 转换为瞬时地球坐标系 + static Eigen::MatrixXd ordinateSingleRotate(int axis, double angle_deg); + // step 3 瞬时地球坐标系 转换为 瞬时真天球坐标系 + // xyz= ordinateSingleRotate('z',-gst_deg)*earthFixedXYZ; + static int utc2gst(Eigen::MatrixXd UTC, double dUT1, double dAT, double& gst_deg, double& JDTDB); + // step 4 瞬时真天球坐标系 转到瞬时平天球 坐标系 + static int nutationInLongitudeCaculate(double JD, double& epthilongA_deg, double& dertaPthi_deg, double& dertaEpthilong_deg, double& epthilong_deg); + // step5 瞬时平天球坐标系转换为协议天球坐标系(J2000)函数中 JDTDB 为给定时刻 的地球动力学时对应的儒略日,其计算方法由步骤三中的函数给出。 + // xyz=ordinateSingleRotate('Z',zetaA)*ordinateSingleRotate('y',-thitaA)*ordinateSingleRotate('z',zA)*xyz; + static int precessionAngle(double JDTDB, double& zetaA, double& thitaA, double& zA); + // YMD2JD 同时 YMD2JD函数为 年月日转换为儒略日,具体说明 见公元纪年法(儒略历-格里高历)转儒略日_${王小贱}的博客-CSDN博客_年积日计算公式 + static double YMD2JD(double y, double m, double d); + static Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd BLH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); + static Landpoint WGS842J2000(Landpoint LBH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); +public: + static std::string EOP_File_Path; + static std::string Space_Weather_Data; + // IAU2000模型有77项11列 + static Eigen::Matrix IAU2000ModelParams; +}; + +*/ + + +/* +计算卫星高度角、方位角(XYZ转ENU,ENU转RAH) https://blog.csdn.net/why1472587/article/details/128178417 +*/ +//经纬度(BLH) +typedef struct BLH { + double B; + double L; + double H; +}; +//站心坐标系也称NEU坐标系或东北高坐标系 +typedef struct ENU { + double E; + double N; + double U; +}; + +//r为卫星向径,A为卫星方位角,h为卫星的高度角。 +typedef struct RAH { + double R; + double A; + double H; +}; + +//xyz转blh: +BLH xyz2blh(double X, double Y, double Z); + +//xyz转enu Xr 已知测站坐标 +ENU xyz2enu(double Xr, double Yr, double Zr, double Xs, double Ys, double Zs); + +//求卫星方位角、高度角 +RAH Satrah(double Xr, double Yr, double Zr, double Xs, double Ys, double Zs); + +//将值写入到txt中 +void creatTxt(const std::string& txtPath, const std::string& data); \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/interpolation.cpp b/simorthoprogram-orth_gf3-strip/interpolation.cpp new file mode 100644 index 0000000..4e1ce26 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/interpolation.cpp @@ -0,0 +1 @@ +#include "interpolation.h" diff --git a/simorthoprogram-orth_gf3-strip/interpolation.h b/simorthoprogram-orth_gf3-strip/interpolation.h new file mode 100644 index 0000000..70c1ae4 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/interpolation.h @@ -0,0 +1,10 @@ +#pragma once +/** +专门用于插值计算的类库 + +*/ +#include +#include +#include +#include +#include diff --git a/simorthoprogram-orth_gf3-strip/linterp.h b/simorthoprogram-orth_gf3-strip/linterp.h new file mode 100644 index 0000000..5e1cb67 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/linterp.h @@ -0,0 +1,423 @@ + +// +// Copyright (c) 2012 Ronaldo Carpio +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. The authors make no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +// + +/* +This is a C++ header-only library for N-dimensional linear interpolation on a rectangular grid. Implements two methods: +* Multilinear: Interpolate using the N-dimensional hypercube containing the point. Interpolation step is O(2^N) +* Simplicial: Interpolate using the N-dimensional simplex containing the point. Interpolation step is O(N log N), but less accurate. +Requires boost/multi_array library. + +For a description of the algorithms, see: +* Weiser & Zarantonello (1988), "A Note on Piecewise Linear and Multilinear Table Interpolation in Many Dimensions", _Mathematics of Computation_ 50 (181), p. 189-196 +* Davies (1996), "Multidimensional Triangulation and Interpolation for Reinforcement Learning", _Proceedings of Neural Information Processing Systems 1996_ +*/ + +#ifndef _linterp_h +#define _linterp_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using std::vector; +using std::array; +typedef unsigned int uint; +typedef vector iVec; +typedef vector dVec; + + +// TODO: +// - specify behavior past grid boundaries. +// 1) clamp +// 2) return a pre-determined value (e.g. NaN) + +// compile-time params: +// 1) number of dimensions +// 2) scalar type T +// 3) copy data or not (default: false). The grids will always be copied +// 4) ref count class (default: none) +// 5) continuous or not + +// run-time constructor params: +// 1) f +// 2) grids +// 3) behavior outside grid: default=clamp +// 4) value to return outside grid, defaut=nan + +struct EmptyClass {}; + +template +class NDInterpolator { +public: + typedef T value_type; + typedef ArrayRefCountT array_ref_count_type; + typedef GridRefCountT grid_ref_count_type; + + static const int m_N = N; + static const bool m_bCopyData = CopyData; + static const bool m_bContinuous = Continuous; + + typedef boost::numeric::ublas::array_adaptor grid_type; + typedef boost::const_multi_array_ref array_type; + typedef std::unique_ptr array_type_ptr; + + array_type_ptr m_pF; + ArrayRefCountT m_ref_F; // reference count for m_pF + vector m_F_copy; // if CopyData == true, this holds the copy of F + + vector m_grid_list; + vector m_grid_ref_list; // reference counts for grids + vector > m_grid_copy_list; // if CopyData == true, this holds the copies of the grids + + // constructors assume that [f_begin, f_end) is a contiguous array in C-order + // non ref-counted constructor. + template + NDInterpolator(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) { + init(grids_begin, grids_len_begin, f_begin, f_end); + } + + // ref-counted constructor + template + NDInterpolator(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT grid_refs_begin) { + init_refcount(grids_begin, grids_len_begin, f_begin, f_end, refF, grid_refs_begin); + } + + template + void init(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) { + set_grids(grids_begin, grids_len_begin, m_bCopyData); + set_f_array(f_begin, f_end, m_bCopyData); + } + template + void init_refcount(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT grid_refs_begin) { + set_grids(grids_begin, grids_len_begin, m_bCopyData); + set_grids_refcount(grid_refs_begin, grid_refs_begin + N); + set_f_array(f_begin, f_end, m_bCopyData); + set_f_refcount(refF); + } + + template + void set_grids(IterT1 grids_begin, IterT2 grids_len_begin, bool bCopy) { + m_grid_list.clear(); + m_grid_ref_list.clear(); + m_grid_copy_list.clear(); + for (int i=0; i(grids_begin[i], grids_begin[i] + grids_len_begin[i]) ); // make our own copy of the grid + T *begin = &(m_grid_copy_list[i][0]); + m_grid_list.push_back(grid_type(gridLength, begin)); // use our copy + } + } + } + template + void set_grids_refcount(RefCountIterT refs_begin, RefCountIterT refs_end) { + assert(refs_end - refs_begin == N); + m_grid_ref_list.assign(refs_begin, refs_begin + N); + } + + // assumes that [f_begin, f_end) is a contiguous array in C-order + template + void set_f_array(IterT f_begin, IterT f_end, bool bCopy) { + unsigned int nGridPoints = 1; + array sizes; + for (unsigned int i=0; i(f_begin, f_end); + m_pF.reset(new array_type(&m_F_copy[0], sizes)); + } + } + void set_f_refcount(ArrayRefCountT &refF) { + m_ref_F = refF; + } + + // -1 is before the first grid point + // N-1 (where grid.size() == N) is after the last grid point + int find_cell(int dim, T x) const { + grid_type const &grid(m_grid_list[dim]); + if (x < *(grid.begin())) return -1; + else if (x >= *(grid.end()-1)) return grid.size()-1; + else { + auto i_upper = std::upper_bound(grid.begin(), grid.end(), x); + return i_upper - grid.begin() - 1; + } + } + + // return the value of f at the given cell and vertex + T get_f_val(array const &cell_index, array const &v_index) const { + array f_index; + + if (m_bContinuous) { + for (int i=0; i= m_grid_list[i].size()-1) { + f_index[i] = m_grid_list[i].size()-1; + } else { + f_index[i] = cell_index[i] + v_index[i]; + } + } + } else { + for (int i=0; i= m_grid_list[i].size()-1) { + f_index[i] = (2*m_grid_list[i].size())-1; + } else { + f_index[i] = 1 + (2*cell_index[i]) + v_index[i]; + } + } + } + return (*m_pF)(f_index); + } + + T get_f_val(array const &cell_index, int v) const { + array v_index; + for (int dim=0; dim> (N-dim-1)) & 1; // test if the i-th bit is set + } + return get_f_val(cell_index, v_index); + } +}; + +template +class InterpSimplex : public NDInterpolator { +public: + typedef NDInterpolator super; + + template + InterpSimplex(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) + : super(grids_begin, grids_len_begin, f_begin, f_end) + {} + template + InterpSimplex(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT ref_begins) + : super(grids_begin, grids_len_begin, f_begin, f_end, refF, ref_begins) + {} + + template + T interp(IterT x_begin) const { + array result; + array< array, N > coord_iter; + for (int i=0; i + void interp_vec(int n, IterT1 coord_iter_begin, IterT1 coord_iter_end, IterT2 i_result) const { + assert(N == coord_iter_end - coord_iter_begin); + + array cell_index, v_index; + array,N> xipair; + int c; + T y, v0, v1; + //mexPrintf("%d\n", n); + for (int i=0; ifind_cell(dim, coord_iter_begin[dim][i]); + //mexPrintf("%d\n", c); + if (c == -1) { // before first grid point + y = 1.0; + } else if (c == grid.size()-1) { // after last grid point + y = 0.0; + } else { + //mexPrintf("%f %f\n", grid[c], grid[c+1]); + y = (coord_iter_begin[dim][i] - grid[c]) / (grid[c + 1] - grid[c]); + if (y < 0.0) y=0.0; + else if (y > 1.0) y=1.0; + } + xipair[dim].first = y; + xipair[dim].second = dim; + cell_index[dim] = c; + } + // sort xi's and get the permutation + std::sort(xipair.begin(), xipair.end(), [](std::pair const &a, std::pair const &b) { + return (a.first < b.first); + }); + // walk the vertices of the simplex determined by the permutation + for (int j=0; jget_f_val(cell_index, v_index); + y = v0; + for (int j=0; jget_f_val(cell_index, v_index); + y += (1.0 - xipair[j].first) * (v1-v0); // interpolate + v0 = v1; + } + *i_result++ = y; + } + } +}; + +template +class InterpMultilinear : public NDInterpolator { +public: + typedef NDInterpolator super; + + template + InterpMultilinear(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) + : super(grids_begin, grids_len_begin, f_begin, f_end) + {} + template + InterpMultilinear(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT ref_begins) + : super(grids_begin, grids_len_begin, f_begin, f_end, refF, ref_begins) + {} + + template + static T linterp_nd_unitcube(IterT1 f_begin, IterT1 f_end, IterT2 xi_begin, IterT2 xi_end) { + int n = xi_end - xi_begin; + int f_len = f_end - f_begin; + assert(1 << n == f_len); + T sub_lower, sub_upper; + if (n == 1) { + sub_lower = f_begin[0]; + sub_upper = f_begin[1]; + } else { + sub_lower = linterp_nd_unitcube(f_begin, f_begin + (f_len/2), xi_begin + 1, xi_end); + sub_upper = linterp_nd_unitcube(f_begin + (f_len/2), f_end, xi_begin + 1, xi_end); + } + T result = sub_lower + (*xi_begin)*(sub_upper - sub_lower); + return result; + } + + template + T interp(IterT x_begin) const { + array result; + array< array, N > coord_iter; + for (int i=0; i + void interp_vec(int n, IterT1 coord_iter_begin, IterT1 coord_iter_end, IterT2 i_result) const { + assert(N == coord_iter_end - coord_iter_begin); + array index; + int c; + T y, xi; + vector f(1 << N); + array x; + + for (int i=0; ifind_cell(dim, coord_iter_begin[dim][i]); + if (c == -1) { // before first grid point + y = 1.0; + } else if (c == grid.size()-1) { // after last grid point + y = 0.0; + } else { + y = (coord_iter_begin[dim][i] - grid[c]) / (grid[c + 1] - grid[c]); + if (y < 0.0) y=0.0; + else if (y > 1.0) y=1.0; + } + index[dim] = c; + x[dim] = y; + } + // copy f values at vertices + for (int v=0; v < (1 << N); v++) { // loop over each vertex of hypercube + f[v] = this->get_f_val(index, v); + } + *i_result++ = linterp_nd_unitcube(f.begin(), f.end(), x.begin(), x.end()); + } + } +}; + +typedef InterpSimplex<1,double> NDInterpolator_1_S; +typedef InterpSimplex<2,double> NDInterpolator_2_S; +typedef InterpSimplex<3,double> NDInterpolator_3_S; +typedef InterpSimplex<4,double> NDInterpolator_4_S; +typedef InterpSimplex<5,double> NDInterpolator_5_S; +typedef InterpMultilinear<1,double> NDInterpolator_1_ML; +typedef InterpMultilinear<2,double> NDInterpolator_2_ML; +typedef InterpMultilinear<3,double> NDInterpolator_3_ML; +typedef InterpMultilinear<4,double> NDInterpolator_4_ML; +typedef InterpMultilinear<5,double> NDInterpolator_5_ML; + +// C interface +extern "C" { + void linterp_simplex_1(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); + void linterp_simplex_2(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); + void linterp_simplex_3(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); +} + +void inline linterp_simplex_1(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=1; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + +void inline linterp_simplex_2(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=2; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + +void inline linterp_simplex_3(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=3; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + + + + +#endif //_linterp_h \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/resource.h b/simorthoprogram-orth_gf3-strip/resource.h new file mode 100644 index 0000000..c8940a4 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 供 SIMOrthoProgram.rc 使用 +// +#define IDR_PROJ1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/simorthoprogram-orth_gf3-strip/simptsn.cpp b/simorthoprogram-orth_gf3-strip/simptsn.cpp new file mode 100644 index 0000000..af9fa78 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/simptsn.cpp @@ -0,0 +1,3739 @@ +#pragma once +/// +/// 仿真成像算法 +/// + +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Eigen; + + + +PSTNAlgorithm::PSTNAlgorithm() +{ +} + +PSTNAlgorithm::PSTNAlgorithm(string infile_path) +{ + std::cout << "=========================================================================" << endl; + std::cout << "read parameters :\t" << infile_path << endl; + std::cout << "parameters files :\t" << infile_path << endl; + std::cout << "params file Format:" << endl; + std::cout << "height --- image height" << endl; + std::cout << "width --- image width" << endl; + std::cout << "R0 --- image nearRange" << endl; + std::cout << "near_in_angle " << endl; + std::cout << "far incident angle " << endl; + std::cout << "LightSpeed " << endl; + std::cout << "lamda" << endl; + std::cout << "imgStartTime" << endl; + std::cout << "PRF" << endl; + std::cout << "refrange" << endl; + std::cout << "fs" << endl; + //std::cout << "doppler_reference_time" << endl; + std::cout << "doppler_paramenter_number " << endl; + std::cout << "doppler_paramenter 1 " << endl; + std::cout << "doppler_paramenter 2" << endl; + std::cout << "doppler_paramenter 3 " << endl; + std::cout << "doppler_paramenter 4 " << endl; + std::cout << "doppler_paramenter 5 " << endl; + std::cout << "ispolySatelliteModel" << endl; + std::cout << "sate polynum " << endl; + std::cout << "SatelliteModelStartTime" << endl; + std::cout << "orbit params list " << endl; + std::cout << "============================================================================" << endl; + + // 解析文件 + ifstream infile(infile_path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + + // 参数域 + getline(infile, buf); this->height = stoi(buf); + getline(infile, buf); this->width = stoi(buf); std::cout << "height,width\t" << this->height << "," << this->width << endl; + getline(infile, buf); this->R0 = stod(buf); std::cout <<""<< "R0\t" << this->R0 << endl; //近斜距 + getline(infile, buf); this->near_in_angle = stod(buf); std::cout << "near_in_angle\t" << this->near_in_angle << endl; //近入射角 + getline(infile, buf); this->far_in_angle = stod(buf); std::cout << "far_in_angle\t" << this->far_in_angle << endl; //远入射角 + + getline(infile, buf); this->LightSpeed = stod(buf); std::cout << "LightSpeed\t" << this->LightSpeed << endl; + getline(infile, buf); this->lamda = stod(buf); std::cout << "lamda\t" << this->lamda << endl; + getline(infile, buf); this->imgStartTime = stod(buf); std::cout << "imgStartTime\t" << this->imgStartTime << endl; + getline(infile, buf); this->PRF = stod(buf); std::cout << "PRF\t" << this->PRF << endl; + getline(infile, buf); this->refrange = stod(buf); std::cout << "refrange\t" << this->refrange << endl; + getline(infile, buf); this->fs = stod(buf); std::cout << "fs\t" << this->fs << endl; + //getline(infile, buf); this->doppler_reference_time = stod(buf); std::cout << "doppler_reference_time\t" << this->doppler_reference_time << endl; + getline(infile, buf); this->doppler_paramenter_number = stoi(buf); std::cout << "doppler_paramenter_number\t" << this->doppler_paramenter_number << endl; + + // 读取多普勒系数 + this->doppler_paras = Eigen::MatrixX(this->doppler_paramenter_number, 1); + if (this->doppler_paramenter_number > 0) { + for (int i = 0; i < this->doppler_paramenter_number; i++) { + getline(infile, buf); + this->doppler_paras(i, 0) = stod(buf); + } + std::cout << "doppler_paramenter:\n" << this->doppler_paras << endl; + } + else { + throw "内存不足"; + } + // 读取卫星轨道 + getline(infile, buf); std::cout << "ispolySatelliteModel\t" << buf << endl; + if (stoi(buf) != 1) { + throw "不是多项式轨道模型"; + } + getline(infile, buf); int polynum = stoi(buf) + 1; // 多项式项数 + getline(infile, buf); double SatelliteModelStartTime = stod(buf); // 轨道模型起始时间 + + Eigen::MatrixX polySatellitePara(polynum, 6); + if (polynum >= 4) { + for (int i = 0; i < 6; i++) { + for (int j = 0; j < polynum; j++) { + getline(infile, buf); + polySatellitePara(j, i) = stod(buf); + std::cout << "orbit params " << i << " , " << j << buf << endl; + } + } + } + else { + throw "内存不足"; + } + OrbitPoly orbit(polynum, polySatellitePara, SatelliteModelStartTime); + this->orbit = orbit; + std::cout << "sate polynum\t" << polynum << endl; + std::cout << "sate polySatellitePara\n" << polySatellitePara << endl; + std::cout << "sate SatelliteModelStartTime\t" << SatelliteModelStartTime << endl; + + if (!infile.eof()) // 获取变换的函数 + { + double yy, mm, dd; + getline(infile, buf); + if (buf != "" || buf.length() > 3) { + yy = stod(buf); + getline(infile, buf); mm = stod(buf); + getline(infile, buf); dd = stod(buf); + this->UTC = Eigen::Matrix{ yy,mm,dd }; + std::cout << "UTC\t" << this->UTC << endl; + std::cout << "\nWGS84 to J2000 Params:\t" << endl; + getline(infile, buf); this->Xp = stod(buf); std::cout << "Xp\t" << this->Xp << endl; + getline(infile, buf); this->Yp = stod(buf); std::cout << "Yp\t" << this->Yp << endl; + getline(infile, buf); this->Dut1 = stod(buf); std::cout << "dut1\t" << this->Dut1 << endl; + getline(infile, buf); this->Dat = stod(buf); std::cout << "dat\t" << this->Dat << endl; + } + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); + std::cout << "============================================================================" << endl; +} + +PSTNAlgorithm::~PSTNAlgorithm() +{ +} + +/// +/// 将dem坐标转换为经纬文件 +/// +/// dem +/// 经度 +/// 纬度 +/// +int PSTNAlgorithm::dem2lat_lon(std::string dem_path, std::string lon_path, std::string lat_path) +{ + gdalImage dem_img(dem_path); + //gdalImage lon_img = CreategdalImage(lon_path, dem_img.height, dem_img.width); + //gdalImage lat_img = CreategdalImage(lat_path, dem_img.height, dem_img.width); + + + return 0; +} + +int PSTNAlgorithm::dem2SAR_RC(std::string dem_path, std::string sim_rc_path) +{ + return 0; +} + + +Eigen::MatrixX PSTNAlgorithm::calNumericalDopplerValue(Eigen::MatrixX R) +{ + Eigen::MatrixX t = (R.array() - this->refrange) * (1000000 / LIGHTSPEED); + Eigen::MatrixX tlist(t.rows(), this->doppler_paramenter_number);// nx5 + tlist.col(0) = Eigen::MatrixX::Ones(t.rows(), 1).col(0); + for (int i = 1; i < this->doppler_paramenter_number; i++) + { + tlist.col(i) = t.array().pow(i); + } + //return tlist.array()*this + return tlist * this->doppler_paras; //nx5,5x1 + //return Eigen::MatrixX(1, 1); +} + + +double PSTNAlgorithm::calNumericalDopplerValue(double R) +{ + double t = (R - this->refrange) * (1e6 / LIGHTSPEED); // GF3 + /*double t = R / LIGHTSPEED - 0.004401;*/ + double temp = this->doppler_paras(0) + this->doppler_paras(1) * t + this->doppler_paras(2) * t * t + this->doppler_paras(3) * t * t * t + this->doppler_paras(4) * t * t * t * t; + return temp; +} + + +Eigen::MatrixX PSTNAlgorithm::PSTN(Eigen::MatrixX landpoints, double ave_dem = 0, double dt = 0.001, bool isCol = false) +{ + //Eigen::MatrixX a(1, 1); + //a(0, 0) = 1554386455.999999; + //Eigen::MatrixX satestatetest = this->orbit.SatelliteSpacePoint(a); + //std::cout << satestatetest << endl; + + int point_num = landpoints.rows(); + Eigen::MatrixX SARPoint = Eigen::MatrixX::Ones(point_num, 3); + double L_T = 0; + double S_T = 0; + double R_T = 0; + double cos_theta = 0; + + Eigen::MatrixX landpoint = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + Eigen::MatrixX satevector = Eigen::MatrixX::Ones(1, 3);// 卫星速度 + Eigen::MatrixX sate_land = Eigen::MatrixX::Ones(1, 3); // 卫星-地面矢量 + double ti = this->orbit.SatelliteModelStartTime; + double R1 = 0;// 斜距 + double R2 = 0;// 斜距 + double FdTheory1 = 0; + double FdTheory2 = 0; + double FdNumberical = 0; + double inc_t = 0; + double delta_angle = (this->far_in_angle - this->near_in_angle) / this->width; + //std::cout << landpoint(0, 0) << "\t" << landpoint(0, 1) << "\t" << landpoint(0, 2) << endl; + dt = dt / this->PRF; + Landpoint satePoints = { 0, 0, 0 }; + Landpoint landPoint = { 0, 0, 0 }; + // 开始迭代 + for (int j = 0; j < point_num; j++) { + landpoint = landpoints.row(j); + for (int i = 0; i < 50; i++) { + satestate = this->orbit.SatelliteSpacePoint(ti + dt); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satevector = satestate(Eigen::all, { 3,4,5 }); + sate_land = satepoint - landpoint; + //std::cout << sate_land << endl; + R1 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0];; + FdTheory1 = this->calTheoryDopplerValue(R1, sate_land, satevector); + + satestate = this->orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satevector = satestate(Eigen::all, { 3,4,5 }); + sate_land = satepoint - landpoint; + R2 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + FdNumberical = this->calNumericalDopplerValue(R2); + FdTheory2 = this->calTheoryDopplerValue(R2, sate_land, satevector); + + inc_t = dt * (FdTheory2 - FdNumberical) / (FdTheory1 - FdTheory2); + if (abs(FdTheory1 - FdTheory2) < 1e-9) { + break; + } + ti = ti - inc_t; + if (abs(inc_t) <= dt) { + break; + } + } + SARPoint(j, 0) = ti; + SARPoint(j, 1) = (ti - this->imgStartTime) * this->PRF; + + // 尝试使用入射角切分列号 + satestate = this->orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + sate_land = satepoint - landpoint; + R1 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0];; + //SARPoint(j, 2) = getIncAngle(satePoints, landPoint); + //SARPoint(j, 2) = (R1 - this->R0 - (this->refrange - this->R0) / 3) / this->widthspace; + SARPoint(j, 2) = getRangeColumn(R1, this->R0, this->fs, this->lamda);// (R1 - this->R0) / this->widthspace; // + } + //std::cout <<"SARPoints(200, 0):\t" << SARPoint(200, 0) << "\t" << SARPoint(200, 1) << "\t" << SARPoint(200, 2) << "\t" << endl; + return SARPoint; +} + +/* +Eigen::MatrixXd PSTNAlgorithm::WGS842J2000(Eigen::MatrixXd blh) +{ + return WGS84_J2000::WGS842J2000(blh, this->UTC, this->Xp, this->Yp, this->Dut1, this->Dat); + //return Eigen::MatrixXd(); +} + +Landpoint PSTNAlgorithm::WGS842J2000(Landpoint p) +{ + Eigen::MatrixXd blh = Eigen::MatrixXd(1, 3); + blh<WGS842J2000(blh); + return Landpoint{ blh(0,0),blh(0,1) ,blh(0,0) }; +} +*/ + +/// +/// 计算理论多普勒距离 +/// +/// 斜距 +/// nx3 +/// nx3 +/// +Eigen::MatrixX PSTNAlgorithm::calTheoryDopplerValue(Eigen::MatrixX R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1) +{ + return (R_s1.array() * V_s1.array()).rowwise().sum().array() * (-2) / (R.array() * this->lamda); + //return Eigen::MatrixX(1, 1); +} + +double PSTNAlgorithm::calTheoryDopplerValue(double R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1) { + return ((R_s1.array() * V_s1.array()).rowwise().sum().array() * (-2) / (R * this->lamda))[0]; +} + + +simProcess::simProcess() +{ + +} +simProcess::~simProcess() +{ +} +/// +/// 参数解析 +/// +/// +/// +/// +int simProcess::parameters(int argc, char* argv[]) +{ + for (int i = 0; i < argc; i++) { + std::cout << argv[i] << endl; + } + return 0; +} +/// +/// 间接定位法,初始化参数 +/// +/// 参数文件路径 +/// 工作空间路径 +/// 输出空间路径 +/// 输入DEM文件路径 +/// 输入SAR影像文件路径 +/// 初始化姐u共 +int simProcess::InitSimulationSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_sar_path) +{ + + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + this->in_dem_path = in_dem_path; + this->dem_path = JoinPath(workspace_path, "SAR_dem.tiff");// 获取输入DEM + this->workSpace_path = workspace_path; + this->dem_r_path = JoinPath(workspace_path, "dem_r.tiff"); + + string dem_rcs_path = JoinPath(workspace_path, "dem_rcs.tiff"); + this->sar_sim_wgs_path = JoinPath(workspace_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(workspace_path, "sar_sim.tiff"); + this->ori_sim_count_tiff = JoinPath(workspace_path, "RD_ori_sim_count.tiff"); + this->in_sar_path = in_sar_path; + this->sar_power_path = JoinPath(workspace_path, "in_sar_power.tiff"); + this->outSpace_path = out_dir_path; + this->out_dem_slantRange_path = out_dir_path + "\\" + "dem_slantRange.tiff";// 地形斜距 + this->out_plant_slantRange_path = out_dir_path + "\\" + "flat_slantRange.tiff";// 平地斜距 + this->out_dem_rc_path = out_dir_path + "\\" + "WGS_SAR_map.tiff";// 经纬度与行列号映射 + + + this->out_incidence_path = out_dir_path + "\\" + "incidentAngle.tiff";// 入射角 + this->out_localIncidenct_path = out_dir_path + "\\" + "localincidentAngle.tiff";// 局地入射角 + this->out_ori_sim_tiff = out_dir_path + "\\" + "RD_ori_sim.tif";// 坐标变换 + this->out_sim_ori_tiff = out_dir_path + "\\" + "RD_sim_ori.tif";// 坐标变换 + this->dem_rc_path = this->out_sim_ori_tiff;// JoinPath(out_dir_path, "RD_sim_ori.tif"); + this->sar_sim_wgs_path = JoinPath(out_dir_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(out_dir_path, "sar_sim.tiff"); + + + this->in_rpc_lon_lat_path = this->out_ori_sim_tiff; + this->out_inc_angle_rpc_path = out_dir_path + "\\" + "RD_incidentAngle.tiff";// 局地入射角 + this->out_local_inc_angle_rpc_path = out_dir_path + "\\" + "RD_localincidentAngle.tiff";// 局地入射角 + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_sar_path" << ":\t" << this->in_sar_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "dem_path" << ":\t" << this->dem_path << endl; + std::cout << "sar_power_path" << ":\t" << this->sar_power_path << endl; + std::cout << "dem_r_path" << ":\t" << this->dem_r_path << endl; + std::cout << "dem_rc_path" << ":\t" << this->dem_rc_path << endl; + std::cout << "sar_sim_wgs_path" << ":\t" << this->sar_sim_wgs_path << endl; + std::cout << "sar_sim_path" << ":\t" << this->sar_sim_path << endl; + std::cout << "outSpace_path" << ":\t" << this->outSpace_path << endl; + std::cout << "out_dem_slantRange_path" << ":\t" << this->out_dem_slantRange_path << endl; + std::cout << "out_plant_slantRange_path" << ":\t" << this->out_plant_slantRange_path << endl; + std::cout << "out_dem_rc_path" << ":\t" << this->out_dem_rc_path << endl; + std::cout << "out_incidence_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_localIncidenct_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->CreateSARDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + + this->getAzimuth(); //添加生成方位角方法 + + /*this->SARSimulationWGS(); + this->SARSimulation(); + this->in_sar_power();*/ + if (boost::filesystem::exists(boost::filesystem::path(this->out_dem_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(this->out_dem_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(this->dem_rc_path), boost::filesystem::path(this->out_dem_rc_path)); + string sim_rcs_jpg_path = JoinPath(workspace_path, "dem_rcs.jpg"); + string sar_rcs_jpg_path = JoinPath(workspace_path, "sar_rcs.jpg"); + //this->createimagematchmodel(this->sar_power_path, sar_rcs_jpg_path, this->sar_sim_path, sim_rcs_jpg_path, this->workspace_path); + //if (this->ismatchmodel) { + // std::cout << "校正" << endl; + // this->correctorth_rc(this->dem_rc_path, this->matchmodel); + //} + ////插值计算行列号 + //this->ReflectTable_WGS2Range(); + //this->SARIncidentAngle_RPC(); + return 0; +} +int simProcess::InitASFSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path) +{ + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + this->in_dem_path = in_dem_path; + this->dem_path = JoinPath(workspace_path, "SAR_dem.tiff");// 获取输入DEM + this->workSpace_path = workspace_path; + this->dem_r_path = JoinPath(workspace_path, "dem_r.tiff"); + this->dem_rc_path = JoinPath(workspace_path, "dem_rc.tiff"); + string dem_rcs_path = JoinPath(workspace_path, "dem_rcs.tiff"); + this->sar_sim_wgs_path = JoinPath(workspace_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(workspace_path, "sar_sim.tiff"); + this->ori_sim_count_tiff = JoinPath(workspace_path, "RD_ori_sim_count.tiff"); + this->in_sar_path = in_sar_path; + this->sar_power_path = JoinPath(workspace_path, "in_sar_power.tiff"); + this->outSpace_path = out_dir_path; + this->out_dem_slantRange_path = out_dir_path + "\\" + "dem_slantRange.tiff";// 地形斜距 + this->out_plant_slantRange_path = out_dir_path + "\\" + "flat_slantRange.tiff";// 平地斜距 + this->out_dem_rc_path = out_dir_path + "\\" + "WGS_SAR_map.tiff";// 经纬度与行列号映射 + this->out_incidence_path = out_dir_path + "\\" + "incidentAngle.tiff";// 入射角 + this->out_localIncidenct_path = out_dir_path + "\\" + "localincidentAngle.tiff";// 局地入射角 + this->out_ori_sim_tiff = out_dir_path + "\\" + "RD_ori_sim.tif";// 局地入射角 + this->in_rpc_lon_lat_path = this->out_ori_sim_tiff; + this->out_inc_angle_rpc_path = out_dir_path + "\\" + "RD_incidentAngle.tiff";// 局地入射角 + this->out_local_inc_angle_rpc_path = out_dir_path + "\\" + "RD_localincidentAngle.tiff";// 局地入射角 + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_sar_path" << ":\t" << this->in_sar_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "dem_path" << ":\t" << this->dem_path << endl; + std::cout << "sar_power_path" << ":\t" << this->sar_power_path << endl; + std::cout << "dem_rc_path" << ":\t" << this->dem_rc_path << endl; + std::cout << "sar_sim_wgs_path" << ":\t" << this->sar_sim_wgs_path << endl; + std::cout << "sar_sim_path" << ":\t" << this->sar_sim_path << endl; + std::cout << "outSpace_path" << ":\t" << this->outSpace_path << endl; + std::cout << "out_dem_slantRange_path" << ":\t" << this->out_dem_slantRange_path << endl; + std::cout << "out_plant_slantRange_path" << ":\t" << this->out_plant_slantRange_path << endl; + std::cout << "out_dem_rc_path" << ":\t" << this->out_dem_rc_path << endl; + std::cout << "out_incidence_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_localIncidenct_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->CreateSARDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + this->SARSimulationWGS(); + ASFOrthClass asfclass; + + this->SARSimulation(); + this->in_sar_power(); + if (boost::filesystem::exists(boost::filesystem::path(this->out_dem_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(this->out_dem_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(this->dem_rc_path), boost::filesystem::path(this->out_dem_rc_path)); + string sim_rcs_jpg_path = JoinPath(workspace_path, "dem_rcs.jpg"); + string sar_rcs_jpg_path = JoinPath(workspace_path, "sar_rcs.jpg"); + //this->createImageMatchModel(this->sar_power_path, sar_rcs_jpg_path, this->sar_sim_path, sim_rcs_jpg_path, this->workSpace_path); + if (this->isMatchModel) { + std::cout << "校正" << endl; + // this->correctOrth_rc(this->dem_rc_path, this->matchmodel); + } + + // 插值计算行列号 + this->ReflectTable_WGS2Range(); + this->SARIncidentAngle_RPC(); + return 0; + return 0; +} +/// +/// 创建SAR对应的DEM +/// +/// 返回结果 +int simProcess::CreateSARDEM() +{ + std::cout << "dem2SAR_Row_col begin time:" << getCurrentTimeString() << std::endl; + { + gdalImage dem(this->in_dem_path); + double dem_mean = dem.mean(); + gdalImage sim_rc = CreategdalImage(this->dem_rc_path, dem.height, dem.width, 2, dem.gt, dem.projection); + DemBox box{ 9999,9999,-9999,-9999 }; + { + Eigen::MatrixXd sim_r; + Eigen::MatrixXd sim_c; + int line_invert = int(2000000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + int max_rows_ids = 0; + int all_count = 0; + bool state = true; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd demdata = dem.getData(max_rows_ids, 0, line_invert, dem.width, 1); + Eigen::MatrixXd sim_r = demdata.array() * 0; + Eigen::MatrixXd sim_c = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 因为不考虑斜距,所以平面置为0 + } + } + //demdata = Eigen::MatrixXd(1, 1); + landpoint = dem.getLandPoint(landpoint); + //landpoint.col(2) = landpoint.col(2).array() * 0; + + landpoint = LLA2XYZ(landpoint); + landpoint = this->pstn.PSTN(landpoint, dem_mean, 0.001, true); // time,r,c + //std::cout << "for time " << getCurrentTimeString() << std::endl; + double min_lat = 9999; + double max_lat = -9999; + double min_lon = 9999; + double max_lon = -9999; + bool has_min_max = false; + Landpoint p1{ 0,0,0 }; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + sim_r(i, j) = landpoint(i * datacols + j, 1); + sim_c(i, j) = landpoint(i * datacols + j, 2); + p1 = dem.getLandPoint(i + max_rows_ids, j, demdata(i, j)); + if (sim_r(i, j) >= 0 && sim_c(i, j) >= 0 && sim_r(i, j) <= this->pstn.height && sim_c(i, j) <= this->pstn.width) { + min_lat = min_lat < p1.lat ? min_lat : p1.lat; + max_lat = max_lat > p1.lat ? max_lat : p1.lat; + min_lon = min_lon < p1.lon ? min_lon : p1.lon; + max_lon = max_lon > p1.lon ? max_lon : p1.lon; + has_min_max = true; + } + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + //std::cout << "lock" << endl; + if (has_min_max) { + box.min_lat = min_lat < box.min_lat ? min_lat : box.min_lat; + box.max_lat = max_lat > box.max_lat ? max_lat : box.max_lat;; + box.min_lon = min_lon < box.min_lon ? min_lon : box.min_lon;; + box.max_lon = max_lon > box.max_lon ? max_lon : box.max_lon;; + } + sim_rc.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc.saveImage(sim_c, max_rows_ids, 0, 2); + all_count = all_count + line_invert; + std::cout << "rows:\t" << all_count << "/" << dem.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + std::cout << "prepare over" << getCurrentTimeString() << std::endl; + double dist_lat = box.max_lat - box.min_lat; + double dist_lon = box.max_lon - box.min_lon; + //dist_lat = 0.2 * dist_lat; + //dist_lon = 0.2 * dist_lon; + dist_lat = 0.001; + dist_lon = 0.001; + box.min_lat = box.min_lat - dist_lat; + box.max_lat = box.max_lat + dist_lat; + box.min_lon = box.min_lon - dist_lon; + box.max_lon = box.max_lon + dist_lon; + + std::cout << "box:" << endl; + std::cout << "min_lat-max_lat:\t" << box.min_lat << "\t" << box.max_lat << endl; + std::cout << "min_lon-max_lon:\t" << box.min_lon << "\t" << box.max_lon << endl; + std::cout << "cal box of sar over" << endl; + + // 计算采样之后的影像大小 + int width = 1.2 * this->pstn.width; + int height = 1.2 * this->pstn.height; + + double heightspace = (box.max_lat - box.min_lat) / height; + double widthspace = (box.max_lon - box.min_lon) / width; + std::cout << "resample dem:\n" << getCurrentTimeString() << std::endl; + std::cout << "in_dem:\t" << this->in_dem_path << endl; + std::cout << "out_dem:\t" << this->dem_path << endl; + std::cout << "width-height:\t" << width << "-" << height << endl; + std::cout << "widthspace\t-\theight\tspace:\t" << widthspace << "\t-\t" << heightspace << endl; + + int pBandIndex[1] = { 1 }; + int pBandCount[1] = { 1 }; + + double gt[6] = { + box.min_lon,widthspace,0, //x + box.max_lat,0,-heightspace//y + }; + + //boost::filesystem::copy(dem_path, this->dem_path); + ResampleGDAL(this->in_dem_path.c_str(), this->dem_path.c_str(), gt, width, height, GRA_Bilinear); + + std::cout << "resample dem over:\n" << getCurrentTimeString() << std::endl; + std::cout << "remove sim_rc_path:\t" << this->dem_rc_path << std::endl; + } + + return 0; +} + +/// +/// 获取行号 +/// +/// +int simProcess::dem2SAR() +{ + std::cout << "the row of the sar in dem:" << getCurrentTimeString() << std::endl; + { + this->dem2SAR_row(); + } + + std::cout << "the slant range of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_clip(this->dem_path); + gdalImage dem_r(this->dem_r_path); + double dem_mean = dem_clip.mean(); + gdalImage dem_slant_range = CreategdalImage(this->out_dem_slantRange_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + gdalImage plant_slant_range = CreategdalImage(this->out_plant_slantRange_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + + + int line_invert = int(10000000 / dem_clip.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + std::cout << "the slant range of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 行号 + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 地形 + Eigen::MatrixXd demslant_range = demdata.array() * 0; // 地形斜距 + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + landpoint = LLA2XYZ(landpoint);// this->pstn.WGS842J2000(landpoint); + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + long double ti = 0; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ti = dem_r_block(i, j) / this->pstn.PRF + this->pstn.imgStartTime; + satestate = this->pstn.orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satepoint(0, 0) = satepoint(0, 0) - landpoint(i * datacols + j, 0); + satepoint(0, 1) = satepoint(0, 1) - landpoint(i * datacols + j, 1); + satepoint(0, 2) = satepoint(0, 2) - landpoint(i * datacols + j, 2); + demslant_range(i, j) = (satepoint.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + dem_slant_range.saveImage(demslant_range, max_rows_ids, 0, 1); + //sim_rc_reprocess.saveImage(sim_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + count_lines = 0; + std::cout << "the plant slant range of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 行号 + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 地形 + Eigen::MatrixXd demslant_range = demdata.array() * 0; // 地形斜距 + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = 0; // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + landpoint = LLA2XYZ(landpoint); + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + long double ti = 0; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ti = dem_r_block(i, j) / this->pstn.PRF + this->pstn.imgStartTime; + satestate = this->pstn.orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satepoint(0, 0) = satepoint(0, 0) - landpoint(i * datacols + j, 0); + satepoint(0, 1) = satepoint(0, 1) - landpoint(i * datacols + j, 1); + satepoint(0, 2) = satepoint(0, 2) - landpoint(i * datacols + j, 2); + demslant_range(i, j) = (satepoint.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + plant_slant_range.saveImage(demslant_range, max_rows_ids, 0, 1); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "the row and col of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_r(this->dem_r_path); + gdalImage plant_slant_range(this->out_plant_slantRange_path); + gdalImage dem_rc = CreategdalImage(this->dem_rc_path, dem_r.height, dem_r.width, 2, dem_r.gt, dem_r.projection); + + int line_invert = int(10000000 / dem_r.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + std::cout << "the row and col of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_r.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_r.width, 1); // 行号 + Eigen::MatrixXd slant_range = plant_slant_range.getData(max_rows_ids, 0, line_invert, dem_r.width, 1); // 地形 + Eigen::MatrixXd dem_c = getRangeColumn(slant_range, this->pstn.R0, this->pstn.fs, this->pstn.lamda);// (slant_range.array() - this->pstn.R0) / this->pstn.widthspace; + omp_set_lock(&lock); //获得互斥器 + dem_rc.saveImage(dem_r_block, max_rows_ids, 0, 1); + dem_rc.saveImage(dem_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_r.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + + return 0; +} +/// +/// 计算相关的倾斜角 -- 弧度值 +/// +/// +int simProcess::SARIncidentAngle() +{ + std::cout << "the incidence angle and local incidence :" << getCurrentTimeString() << std::endl; + { + gdalImage dem_img(this->dem_path); + gdalImage sim_r_img(this->dem_r_path); + gdalImage localincidence_angle_img = CreategdalImage(this->out_localIncidenct_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + gdalImage incidence_angle_img = CreategdalImage(this->out_incidence_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + incidence_angle_img.setNoDataValue(-10, 1); + localincidence_angle_img.setNoDataValue(-10, 1); + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(5000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + int count_lines = 0; + for (int max_rows_ids = 0; max_rows_ids < dem_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd sim_inclocal = incidence_angle_img.getData(max_rows_ids, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids, 0, line_invert + 2, line_width, 1); + sim_inclocal = sim_inclocal.array() * 0 - 10; + sim_localinclocal = sim_localinclocal.array() * 0 - 10; + localincidence_angle_img.saveImage(sim_localinclocal, max_rows_ids, 0, 1); + incidence_angle_img.saveImage(sim_inclocal, max_rows_ids, 0, 1); + } + + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + line_invert = int(200000000 / dem_img.width);// 基本大小 + for (int max_rows_ids = 1; max_rows_ids < dem_img.height; max_rows_ids = max_rows_ids + line_invert) { + start_ids = max_rows_ids - 1; + Eigen::MatrixXd demdata = dem_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_r = sim_r_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1).cast(); // + Eigen::MatrixXd sim_inclocal = incidence_angle_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + //sim_r = sim_r.array() * (1 / PRF) + imgstarttime; + int rowcount = demdata.rows(); + int colcount = demdata.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + // sataState = + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + long double r; + for (int j = 1; j < colcount - 1; j++) { + r = sim_r(i, j); + Eigen::MatrixX sataState = this->pstn.orbit.SatelliteSpacePoint(r / PRF + imgstarttime); + p0 = dem_img.getLandPoint(i + start_ids, j, demdata(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, demdata(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, demdata(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, demdata(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, demdata(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + sim_localinclocal(i, j) = getlocalIncAngle(satepoint, landpoint, slopeVector); + //p0.ati = 0; + p0 = dem_img.getLandPoint(i + start_ids, j, demdata(i, j)); // 中心 + landpoint = LLA2XYZ(p0); + sim_inclocal(i, j) = getIncAngle(satepoint, landpoint); + } + } + int rows_save = sim_inclocal.rows() - 2; + //sim_inclocal =.array(); + //sim_localinclocal = .array(); + omp_set_lock(&lock); //获得互斥器 + count_lines = count_lines + line_invert; + localincidence_angle_img.saveImage(sim_localinclocal.block(1, 0, rows_save, line_width), max_rows_ids, 0, 1); + incidence_angle_img.saveImage(sim_inclocal.block(1, 0, rows_save, line_width), max_rows_ids, 0, 1); + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "the incidence angle and local incidence over:\t" << getCurrentTimeString() << std::endl; + return 0; +} +/// +/// 模拟WGS坐标下 SAR值 +/// +/// +int simProcess::SARSimulationWGS() +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage localincidence_angle_img(this->out_localIncidenct_path); + gdalImage sim_sar_img = CreategdalImage(this->sar_sim_wgs_path, localincidence_angle_img.height, localincidence_angle_img.width, 1, localincidence_angle_img.gt, localincidence_angle_img.projection);// 注意这里保留仿真结果 + int line_invert = int(5000000 / localincidence_angle_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = localincidence_angle_img.width; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < sim_sar_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids, 0, line_invert, line_width, 1); + Eigen::MatrixXd sim_sar(line_invert, line_width); + sim_localinclocal = sim_localinclocal.array() * d2r; + // double((0.0133 * cos(localincangle) / pow(sin(localincangle + 0.1 * localincangle), 3))); + Eigen::MatrixXd cos_angle = sim_localinclocal.array().cos(); + Eigen::MatrixXd sin_angle = sim_localinclocal.array().sin(); + sim_sar = (0.0133 * cos_angle.array()) / ((sin_angle.array() + 0.1 * cos_angle.array()).pow(3)); + omp_set_lock(&lock); //获得互斥器 + count_lines = count_lines + line_invert; + sim_sar_img.saveImage(sim_sar, max_rows_ids, 0, 1); + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << sim_sar_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + + return 0; +} + +int simProcess::SARSimulation() +{ + std::cout << "computer the simulation value of sim_sar, begining:\t" << getCurrentTimeString() << endl; + gdalImage sim_sar_wgs_img(this->sar_sim_wgs_path); + gdalImage sim_rc(this->dem_rc_path); + gdalImage localIncident_img(this->out_localIncidenct_path); + gdalImage sim_sar_img = CreategdalImage(this->sar_sim_path, this->pstn.height, this->pstn.width, 1, sim_sar_wgs_img.gt, sim_sar_wgs_img.projection, false);// 注意这里保留仿真结果 + { + sim_sar_img.setNoDataValue(-9999, 1); + //double PRF = this->pstn.PRF; + //double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(30000000 / sim_sar_wgs_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = sim_sar_wgs_img.width; + Eigen::MatrixXd sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd sim_sum_h(line_invert, line_width); + Eigen::MatrixXd sim_rsc_orth(line_invert, line_width); + Eigen::MatrixXd sim_sum_sar(line_invert, line_width); + Eigen::MatrixXd demdata(line_invert, line_width); + Eigen::MatrixXd angle(line_invert, line_width); + + // 初始化 + do { + sim_sum_sar = sim_sar_img.getData(start_ids, 0, line_invert, this->pstn.width, 1).cast(); + sim_sum_sar = sim_sum_sar.array() * 0; + sim_sar_img.saveImage(sim_sum_sar, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + { + // 累加计算模拟值 + int rowcount = 0, colcount = 0; + int row_min = 0, row_max = 0; + start_ids = 0; + std::cout << "time:\tsim_arr_row_min\tsim_arr_row_max\tsim_arr_all_lines\tsim_row_min\tsim_row_max\tsim_row_min0\tsim_row_max0" << std::endl;; + do { + std::cout << "\n" << getCurrentTimeString() << "\t" << start_ids << "\t" << start_ids + line_invert << "\t" << sim_rc.height << "\t"; + sim_r = sim_rc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 行 + sim_c = sim_rc.getData(start_ids, 0, line_invert, line_width, 2).cast(); // 列 + angle = localIncident_img.getData(start_ids, 0, line_invert, line_width, 1).cast(); + sim_rsc_orth = sim_sar_wgs_img.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + // 范围 + row_min = (floor(sim_r.minCoeff())); + row_max = (ceil(sim_r.maxCoeff())); + std::cout << row_min << "\t" << row_max << "\t"; + + //std::cout << "line range:\t" << row_min << " - " << row_max << "\t computing.....\t" << getCurrentTimeString() << endl; + + if (row_max < 0 || row_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + row_min = row_min <= 0 ? 0 : row_min; + row_max = row_max >= this->pstn.height ? this->pstn.height : row_max; + std::cout << row_min << "\t" << row_max << std::endl; + //sim_sum_sar =sim_sar.getData(row_min, 0, row_max-row_min+1, this->pstn.width, 1).cast(); + //sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + if (row_min >= row_max) { + break; + } + sim_sum_sar = sim_sar_img.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 1).cast(); + rowcount = sim_r.rows(); + colcount = sim_r.cols(); + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 0; i < rowcount; i++) { + int row_ids = 0, col_ids = 0; + for (int j = 0; j < colcount; j++) { + row_ids = int(round(sim_r(i, j))); + col_ids = int(round(sim_c(i, j))); + if (row_ids >= 0 && row_ids < this->pstn.height && col_ids >= 0 && col_ids < this->pstn.width && (angle(i, j) < 90 || angle(i, j) > 270)) { + sim_sum_sar(row_ids - row_min, col_ids) += sim_rsc_orth(i, j); + } + } + } + sim_sar_img.saveImage(sim_sum_sar, row_min, 0, 1); + + start_ids = start_ids + line_invert; + } while (start_ids < sim_rc.height); + std::cout << "\ncomputer the simulation value of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + } + + { + std::cout << "Resample simulation value of sim_sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(this->sar_sim_path.c_str(), 1, GRIORA_Bilinear); + } + + return 0; +} + +int simProcess::in_sar_power() +{ + std::cout << "compute the power value of ori sar, beiging:\t" << getCurrentTimeString() << endl; + gdalImage ori_sar(this->in_sar_path); + gdalImage sim_power = CreategdalImage(this->sar_power_path, ori_sar.height, ori_sar.width, 1, ori_sar.gt, ori_sar.projection); + sim_power.setNoDataValue(-9999, 1); + { + Eigen::MatrixXd band1(1, 1); + Eigen::MatrixXd band2(1, 1); + Eigen::MatrixXd power_value(1, 1); + int start_ids = 0; + int line_invert = int(8000000 / ori_sar.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + std::cout << "rows:\t" << start_ids << "/" << ori_sar.height << "\t computing.....\t" << getCurrentTimeString() << endl; + band1 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 1).cast(); // a + band2 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 2).cast(); // b + power_value = (band1.array().pow(2) + band2.array().pow(2) + 1).log10() * 10;// 10 * Eigen::log10(Eigen::pow(0.5, Eigen::pow(2, band1.array()) + Eigen::pow(2, band2.array()))).array(); + sim_power.saveImage(power_value, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < ori_sar.height); + } + { + std::cout << "Resample the power value of ori sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(this->sar_power_path.c_str(), 1, GRIORA_Bilinear); + } + std::cout << "compute the power value of ori sar, ending:\t" << getCurrentTimeString() << endl; + { + std::cout << "=========================================\n"; + std::cout << " the power image of sar :\n"; + std::cout << this->sar_power_path.c_str() << "\n"; + std::cout << "band 1 : power value \t 10*log10(b1^2+b2^2) \n"; + std::cout << "=========================================\n"; + + } + return 0; + return 0; +} + + + + +int simProcess::Scatter2Grid(std::string lon_lat_path, std::string data_tiff, std::string grid_path, double space) { + + gdalImage lon_lat_img(lon_lat_path); + double min_lon = 400, max_lon = -400, min_lat = 300, max_lat = -300; + { + int conver_lines = 2000; + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + conver_lines) { + Eigen::MatrixXd lon = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + Eigen::MatrixXd lat = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 2); + int rows = lon.rows(); + int cols = lon.cols(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (min_lon > lon(i, j) && !isnan(lon(i, j)) && lon(i, j) > -200) { + min_lon = lon(i, j); + } + if (min_lat > lat(i, j) && !isnan(lat(i, j)) && lat(i, j) > -200) { + min_lat = lat(i, j); + } + if (max_lon < lon(i, j) && !isnan(lon(i, j)) && lon(i, j) > -200) { + max_lon = lon(i, j); + } + + if (max_lat < lat(i, j) && !isnan(lat(i, j)) && lat(i, j) > -200) { + max_lat = lat(i, j); + } + } + } + } + } + std::cout << "lon:\t" << min_lon << " , " << max_lon << endl; + std::cout << "lat:\t" << min_lat << " , " << max_lat << endl; + + double delta = space /( 110 * 1000); + int width = int((max_lon - min_lon) / delta) + 1; + int height = int((max_lat - min_lat) / delta) + 1; + Eigen::MatrixXd gt(2, 3); + gt(0, 0) = min_lon; gt(0, 1) = delta; gt(0, 2) = 0;//x + gt(1, 0) = max_lat; gt(1, 1) = 0; gt(1, 2) = -1*delta;//y + + // # + char* pszSrcWKT = NULL; + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + //oSRS.SetUTM(50, true); //北半球 东经120度 + //oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + gdalImage grid_img = CreategdalImage(grid_path, height, width, 1, gt, pszSrcWKT, true); + int conver_lines = 2000; + for (int max_rows_ids = 0; max_rows_ids < grid_img.height; max_rows_ids = max_rows_ids + conver_lines) { + Eigen::MatrixXd grid_data = grid_img.getData(max_rows_ids, 0, conver_lines, width, 1); + grid_data = grid_data.array() * 0 - 9999; + grid_img.saveImage(grid_data, max_rows_ids, 0, 1); + } + grid_img.setNoDataValue(-9999, 1); + Eigen::MatrixXd grid_data = grid_img.getData(0, 0, grid_img.height, grid_img.width, 1); + gdalImage Range_data(data_tiff); + grid_img.InitInv_gt(); + { + int conver_lines = 500; + int line_invert = 400;// 计算重叠率 + int line_offset = 60; + // 逐区域迭代计算 + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + int allCount = 0; + + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd lon_data = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + Eigen::MatrixXd lat_data = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 2); + Eigen::MatrixXd data = Range_data.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + int lon_row_count = lon_data.rows(); + for (int i = 0; i < lon_row_count; i++) { + for (int j = 0; j < lon_lat_img.width; j++) { + Landpoint p = grid_img.getRow_Col(lon_data(i, j), lat_data(i, j)); + lon_data(i, j) = p.lon; + lat_data(i, j) = p.lat; + } + } + int dem_rows_num = lon_data.rows(); + int dem_cols_num = lon_data.cols(); + + #pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < dem_rows_num - 1; i++) { + for (int j = 0; j < dem_cols_num - 1; j++) { + Point_3d p, p1, p2, p3, p4; + + p1 = { lat_data(i,j),lon_data(i,j) }; + p2 = { lat_data(i,j + 1),lon_data(i,j + 1) }; + p3 = { lat_data(i + 1, j + 1),lon_data(i + 1, j + 1) }; + p4 = { lat_data(i + 1, j),lon_data(i + 1, j) }; + + //if (angle(i, j) >= 90 && angle(i, j + 1) >= 90 && angle(i + 1, j) >= 90 && angle(i + 1, j + 1) >= 90) { + // continue; + //} + + double temp_min_r = lat_data.block(i, j, 2, 2).minCoeff(); + double temp_max_r = lat_data.block(i, j, 2, 2).maxCoeff(); + double temp_min_c = lon_data.block(i, j, 2, 2).minCoeff(); + double temp_max_c = lon_data.block(i, j, 2, 2).maxCoeff(); + if ((int(temp_min_r) != int(temp_max_r)) && (int(temp_min_c) != int(temp_max_c))) { + for (int ii = int(temp_min_r); ii <= temp_max_r + 1; ii++) { + for (int jj = int(temp_min_c); jj < temp_max_c + 1; jj++) { + if (ii < 0 || ii >= height || jj < 0 || jj >= width) { + continue; + } + p = { double(ii),double(jj),0 }; + //if (PtInRect(p, p1, p2, p3, p4)) { + p1.z = data(i, j); + p2.z = data(i, j + 1); + p3.z = data(i + 1, j + 1); + p4.z = data(i + 1, j); + + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + if (p.x < 0) { + continue; + } + double mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + grid_data(ii , jj) = p.z; + //} + } + } + } + } + } + allCount = allCount + line_invert; + std::cout << "rows:\t" << allCount << "/" << lon_lat_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + } + } + grid_img.saveImage(grid_data, 0, 0, 1); + return 0; +} + + + +/* +描述:判断点是否在四边形内,该函数也适用于多边形,将点数改成你想要的边数就行 +参数: + pCur:当前点 + pLeftTop:左上角 + pRightTop:右上角 + pRightBelow:右下 + pLeftBelow:左下 +返回值:如果在四边形内返回 true ,否则返回 false +*/ + +bool PtInRect(Point_3d pCur, Point_3d pLeftTop, Point_3d pRightTop, Point_3d pRightBelow, Point_3d pLeftBelow) +{ + int nCount = 4;//任意四边形有4个顶点 + Point_3d RectPoints[4] = { pLeftTop, pLeftBelow, pRightBelow, pRightTop }; + int nCross = 0; + double lastPointX = -999.999; + for (int i = 0; i < nCount; i++) + { + //依次取相邻的两个点 + Point_3d pBegin = RectPoints[i]; + Point_3d pEnd = RectPoints[(i + 1) % nCount]; + //相邻的两个点是平行于x轴的,当前点和x轴的平行线要么重合,要么不相交,不算 + if (pBegin.y == pEnd.y)continue; + //交点在pBegin,pEnd的延长线上,不算 + if (pCur.y < min(pBegin.y, pEnd.y) || pCur.y > max(pBegin.y, pEnd.y))continue; + //当前点和x轴的平行线与pBegin,pEnd直线的交点的x坐标 + double x = (double)(pCur.y - pBegin.y) * (double)(pEnd.x - pBegin.x) / (double)(pEnd.y - pBegin.y) + pBegin.x; + if (x > pCur.x)//只看pCur右边交点 + { + if (x != lastPointX)//防止角点算两次 + { + nCross++; + lastPointX = x; + } + } + } + // 单方向交点为奇数,点在多边形之内 + // 单方向交点为偶数,点在多边形之外 + return (nCross % 2 == 1); +} + +int simProcess::ReflectTable_WGS2Range() +{// + gdalImage sim_rc(this->dem_rc_path); + gdalImage sim_sar_img = CreategdalImage(this->out_ori_sim_tiff, this->pstn.height, this->pstn.width, 2, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + gdalImage sim_sar_count_img = CreategdalImage(this->ori_sim_count_tiff, this->pstn.height, this->pstn.width, 1, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + gdalImage localIncident_img(this->out_localIncidenct_path); + for (int max_rows_ids = 0; max_rows_ids < this->pstn.height; max_rows_ids = max_rows_ids + 1000) { + Eigen::MatrixXd sim_sar = sim_sar_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 1); + Eigen::MatrixXd sim_sarc = sim_sar_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 2); + Eigen::MatrixXd sim_sar_count = sim_sar_count_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 1); + sim_sar = sim_sar.array() * 0 - 9999; + sim_sarc= sim_sar.array() * 0 - 9999; + sim_sar_count = sim_sar_count.array() * 0; + sim_sar_img.saveImage(sim_sar, max_rows_ids, 0, 1); + sim_sar_img.saveImage(sim_sarc, max_rows_ids, 0, 2); + sim_sar_count_img.saveImage(sim_sar_count, max_rows_ids, 0, 1); + } + sim_sar_img.setNoDataValue(-9999, 1); + sim_sar_img.setNoDataValue(-9999, 2); + int conver_lines = 5000; + int line_invert = 4000;// 计算重叠率 + int line_offset = 60; + // 逐区域迭代计算 + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + int allCount = 0; + + for (int max_rows_ids = 0; max_rows_ids < sim_rc.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd angle = localIncident_img.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 1).cast(); + Eigen::MatrixXd dem_r = sim_rc.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 1); + Eigen::MatrixXd dem_c = sim_rc.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 2); + int dem_rows_num = dem_r.rows(); + int dem_cols_num = dem_r.cols(); + // 更新插值经纬度 + //Eigen::MatrixXd dem_lon = dem_r; + //Eigen::MatrixXd dem_lat = dem_c; + // 构建索引 更新经纬度并更新链 + + int temp_r, temp_c; + + /* int min_row = dem_r.minCoeff() + 1; + int max_row = dem_r.maxCoeff() + 1; + + if (max_row < 0) { + continue; + }*/ + + int min_row = dem_r.minCoeff() + 1; + int max_row = dem_r.maxCoeff() + 1; + int min_col = dem_c.minCoeff() + 1; + int max_col = dem_c.maxCoeff() + 1; + if (max_row < 0 || min_row >= this->pstn.height || max_col < 0 || min_col >= this->pstn.width) { // 增加边界判断条件 + continue; + } + + int len_rows = max_row - min_row; + min_row = min_row < 0 ? 0 : min_row; + Eigen::MatrixXd sar_r = sim_sar_img.getData(min_row, 0, len_rows, this->pstn.width, 1); + Eigen::MatrixXd sar_c = sim_sar_img.getData(min_row, 0, len_rows, this->pstn.width, 2); + len_rows = sar_r.rows(); + + + #pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < dem_rows_num - 1; i++) { + for (int j = 0; j < dem_cols_num - 1; j++) { + Point_3d p, p1, p2, p3, p4; + Landpoint lp1, lp2, lp3, lp4; + lp1 = sim_rc.getLandPoint(i + max_rows_ids, j, 0); + lp2 = sim_rc.getLandPoint(i + max_rows_ids, j + 1, 0); + lp3 = sim_rc.getLandPoint(i + 1 + max_rows_ids, j + 1, 0); + lp4 = sim_rc.getLandPoint(i + 1 + max_rows_ids, j, 0); + + p1 = { dem_r(i,j),dem_c(i,j) }; + p2 = { dem_r(i,j + 1),dem_c(i,j + 1) }; + p3 = { dem_r(i + 1,j + 1),dem_c(i + 1,j + 1) }; + p4 = { dem_r(i + 1,j),dem_c(i + 1,j) }; + + //if (angle(i, j) >= 90 && angle(i, j + 1) >= 90 && angle(i + 1, j) >= 90 && angle(i + 1, j + 1) >= 90) { + // continue; + //} + + double temp_min_r = dem_r.block(i, j, 2, 2).minCoeff(); + double temp_max_r = dem_r.block(i, j, 2, 2).maxCoeff(); + double temp_min_c = dem_c.block(i, j, 2, 2).minCoeff(); + double temp_max_c = dem_c.block(i, j, 2, 2).maxCoeff(); + if ((int(temp_min_r) != int(temp_max_r)) && (int(temp_min_c) != int(temp_max_c))) { + for (int ii = int(temp_min_r); ii <= temp_max_r + 1; ii++) { + for (int jj = int(temp_min_c); jj < temp_max_c + 1; jj++) { + if (ii < min_row || ii - min_row >= len_rows || jj < 0 || jj >= this->pstn.width) { + continue; + } + p = { double(ii),double(jj),-9999 }; + //if (PtInRect(p, p1, p2, p3, p4)) { + p1.z = lp1.lon; + p2.z = lp2.lon; + p3.z = lp3.lon; + p4.z = lp4.lon; + + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + + if (p.x < 0) { + continue; + } + double mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + sar_r(ii - min_row, jj) = p.z; + p1.z = lp1.lat; + p2.z = lp2.lat; + p3.z = lp3.lat; + p4.z = lp4.lat; + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + + if (p.x < 0) { + continue; + } + mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + sar_c(ii - min_row, jj) = p.z; + //} + } + } + + } + } + } + + omp_set_lock(&lock); //获得互斥器 + sim_sar_img.saveImage(sar_r, min_row, 0, 1); + sim_sar_img.saveImage(sar_c, min_row, 0, 2); + allCount = allCount + conver_lines; + std::cout << "rows:\t" << allCount << "/" << sim_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + + std::cout << "\t resample computing.....\t" << getCurrentTimeString() << endl; + { int conver = 5000; + int line_invert = 4000;// 计算重叠率 + ResampleGDALs(this->out_ori_sim_tiff.c_str(), 1, GRIORA_Bilinear); + ResampleGDALs(this->out_ori_sim_tiff.c_str(), 2, GRIORA_Bilinear); + } + + return 0; +} + +int simProcess::InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_paths, std::string out_inc_angle_path, std::string out_local_inc_angle_path, std::string out_inc_angle_geo_path, std::string out_local_inc_angle_geo_path) +{ + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + + this->in_rpc_lon_lat_path = in_rpc_lon_lat_paths; + this->in_dem_path = in_dem_path; + this->outSpace_path = out_dir_path; + this->workSpace_path = workspace_path; + + // 临时文件 + this->dem_path = JoinPath(this->workSpace_path, "SAR_dem.tiff"); + this->dem_rc_path = JoinPath(this->workSpace_path, "dem_rc.tiff"); + this->dem_r_path = JoinPath(this->workSpace_path, "dem_r.tiff"); + this->out_incidence_path = out_inc_angle_geo_path; + this->out_localIncidenct_path = out_local_inc_angle_geo_path; + this->rpc_wgs_path = JoinPath(this->workSpace_path, "rcp2dem_wgs.tiff"); + // 输出文件 + this->out_inc_angle_rpc_path = out_inc_angle_path; + this->out_local_inc_angle_rpc_path = out_local_inc_angle_path; + + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_rpc_lon_lat_path" << ":\t" << this->in_rpc_lon_lat_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "out_dir_path" << ":\t" << this->out_dir_path << endl; + std::cout << "out_inc_angle_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_local_inc_angle_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->createRPCDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + this->SARIncidentAngle_RPC(); + this->in_sar_power(); + return 0; + return 0; +} + +int simProcess::dem2SAR_row() +{ + + std::cout << "the row of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_clip(this->dem_path); + double dem_mean = dem_clip.mean(); + gdalImage sim_r_reprocess = CreategdalImage(this->dem_r_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + gdalImage sim_rc_reprocess = CreategdalImage(this->dem_rc_path, dem_clip.height, dem_clip.width, 2, dem_clip.gt, dem_clip.projection); + int line_invert = int(15000000 / dem_clip.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); + + Eigen::MatrixXd sim_r = demdata.array() * 0; + Eigen::MatrixXd sim_c = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + //landpoint.col(2) = landpoint.col(2).array() * 0; + landpoint = LLA2XYZ(landpoint); + landpoint = this->pstn.PSTN(landpoint, dem_mean); // time,r,c + //std::cout << "for time " << getCurrentTimeString() << std::endl; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + sim_r(i, j) = landpoint(i * datacols + j, 1); + sim_c(i, j) = landpoint(i * datacols + j, 2); + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + sim_r_reprocess.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc_reprocess.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc_reprocess.saveImage(sim_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "dem2SAR_Row_col dem_2_sarRC over " << getCurrentTimeString() << std::endl; + + std::cout << "=========================================\n"; + std::cout << "the row and col of the sar in dem:\n"; + std::cout << this->dem_r_path << "\n"; + std::cout << "band 1 : the row of the sar \n"; + std::cout << "=========================================\n"; + } + return 0; +} + +/// +/// 计算RPC的入射角 +/// +/// +int simProcess::SARIncidentAngle_RPC() { + this->calGEC_Incident_localIncident_angle(this->dem_path, this->in_rpc_lon_lat_path, this->out_inc_angle_rpc_path, this->out_local_inc_angle_rpc_path, this->pstn); + return 0; +} + +int simProcess::createRPCDEM() +{ + std::cout << "dem2SAR_Row_col begin time:" << getCurrentTimeString() << std::endl; + { + gdalImage dem(this->in_dem_path); + gdalImage lonlat(this->in_rpc_lon_lat_path); + DemBox box{ 9999,9999,-9999,-9999 }; + { + int start_ids = 0; + int line_invert = int(4000000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + for (start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) { + std::cout << "rows:\t" << start_ids << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd lon = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd lat = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 2); + double min_lat = lat.array().minCoeff(); + double max_lat = lat.array().maxCoeff(); + double min_lon = lon.array().minCoeff(); + double max_lon = lon.array().maxCoeff(); + box.min_lat = min_lat < box.min_lat ? min_lat : box.min_lat; + box.max_lat = max_lat > box.max_lat ? max_lat : box.max_lat;; + box.min_lon = min_lon < box.min_lon ? min_lon : box.min_lon;; + box.max_lon = max_lon > box.max_lon ? max_lon : box.max_lon;; + + } + } + std::cout << "prepare over" << getCurrentTimeString() << std::endl; + double dist_lat = box.max_lat - box.min_lat; + double dist_lon = box.max_lon - box.min_lon; + dist_lat = 0.1 * dist_lat; + dist_lon = 0.1 * dist_lon; + box.min_lat = box.min_lat - dist_lat; + box.max_lat = box.max_lat + dist_lat; + box.min_lon = box.min_lon - dist_lon; + box.max_lon = box.max_lon + dist_lon; + + std::cout << "box:" << endl; + std::cout << "min_lat-max_lat:\t" << box.min_lat << "\t" << box.max_lat << endl; + std::cout << "min_lon-max_lon:\t" << box.min_lon << "\t" << box.max_lon << endl; + std::cout << "cal box of sar over" << endl; + + // 计算采样之后的影像大小 + int width = 1.5 * this->pstn.width; + int height = 1.5 * this->pstn.height; + + double heightspace = (box.max_lat - box.min_lat) / height; + double widthspace = (box.max_lon - box.min_lon) / width; + std::cout << "resample dem:\n" << getCurrentTimeString() << std::endl; + std::cout << "in_dem:\t" << this->in_dem_path << endl; + std::cout << "out_dem:\t" << this->dem_path << endl; + std::cout << "width-height:\t" << width << "-" << height << endl; + std::cout << "widthspace\t-\theight\tspace:\t" << widthspace << "\t-\t" << heightspace << endl; + + int pBandIndex[1] = { 1 }; + int pBandCount[1] = { 1 }; + + double gt[6] = { + box.min_lon,widthspace,0, //x + box.max_lat,0,-heightspace//y + }; + + //boost::filesystem::copy(dem_path, this->dem_path); + ResampleGDAL(this->in_dem_path.c_str(), this->dem_path.c_str(), gt, width, height, GRA_Bilinear); + + std::cout << "resample dem over:\n" << getCurrentTimeString() << std::endl; + std::cout << "remove sim_rc_path:\t" << this->dem_rc_path << std::endl; + } + + return 0; +} + + +/// +/// 模拟SAR影像 +/// +/// dem影像 +/// rc 影像 +/// 结果:模拟sar影像 +/// 参数类 +/// 执行状态 +int simProcess::sim_SAR(std::string dem_path, std::string sim_rc_path, std::string sim_sar_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage dem_img(dem_path); + gdalImage sim_rc(sim_rc_path); + gdalImage sim_sar = CreategdalImage(sim_sar_path, dem_img.height, dem_img.width, 2, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + sim_sar.setNoDataValue(-9999, 1); + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(50000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + Eigen::MatrixX sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd dem(line_invert, line_width); + Eigen::MatrixXd sim_rsc(line_invert, line_width); + Eigen::MatrixXd sim_inclocal(line_invert, line_width); + + int rowcount = 0, colcount = 0; + //omp_lock_t lock; + //omp_init_lock(&lock); // 初始化互斥锁 + do { + std::cout << "rows:\t" << start_ids << "-" << start_ids + line_invert + 2 << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + dem = dem_img.getData(start_ids, 0, line_invert + 2, line_width, 1); + sim_r = sim_rc.getData(start_ids, 0, line_invert + 2, line_width, 1).cast(); + sim_r = sim_r.array() * (1 / PRF) + imgstarttime; + //sim_c = sim_rc.getData(start_ids, 0, line_invert + 1, line_width, 2); + sim_rsc = dem.array() * 0; + sim_inclocal = dem.array() * 0 - 9999; + rowcount = dem.rows(); + colcount = dem.cols(); + + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + Eigen::MatrixX sataState = sim_r.row(i).reshaped(line_width, 1); + sataState = this->pstn.orbit.SatelliteSpacePoint(sataState); + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle; + for (int j = 1; j < colcount - 1; j++) { + p0 = dem_img.getLandPoint(i + start_ids, j, dem(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, dem(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, dem(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, dem(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, dem(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(j,0),sataState(j,1) ,sataState(j,2) }; + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector); + sim_inclocal(i, j) = localincangle; + if (localincangle < 90) + { + localincangle = localincangle * d2r; + sim_rsc(i, j) = 100 * double((0.0133 * cos(localincangle) / pow(sin(localincangle + 0.1 * localincangle), 3))); + //sim_rsc(i, j) = sim_rsc(i, j) > 100 ? -9999 : sim_rsc(i, j); + } + } + } + //omp_set_lock(&lock); //获得互斥器 + //std::cout << sim_rsc(1, 1961) << endl; + sim_sar.saveImage(sim_rsc.block(1, 0, rowcount - 2, colcount), start_ids + 1, 0, 1); + sim_sar.saveImage(sim_inclocal.block(1, 0, rowcount - 2, colcount), start_ids + 1, 0, 2); + //omp_unset_lock(&lock); //释放互斥器 + start_ids = start_ids + line_invert - 4; + } while (start_ids < dem_img.height); + //omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "computer the simulation value of evering dem meta, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the simulation sar value Raster has the projection that is same of dem" << endl; + std::cout << sim_sar_path << endl; + std::cout << "band 1: the simulation sar value" << endl; + std::cout << "band 2: the local incident angle " << endl; + std::cout << "==========================================================" << endl; + return 0; +} + + +int simProcess::dem2aspect_slope(std::string dem_path, std::string aspect_path, std::string slope_path) +{ + std::cout << "computer aspect and slop begining:\t" << getCurrentTimeString() << endl; + + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* dem = (GDALDataset*)(GDALOpen(dem_path.c_str(), GA_ReadOnly)); + GDALDEMProcessing(aspect_path.c_str(), dem, "aspect", NULL, NULL, NULL); + GDALDEMProcessing(slope_path.c_str(), dem, "slope", NULL, NULL, NULL); + GDALClose(dem); + std::cout << "computer aspect and slop overing:\t" << getCurrentTimeString() << endl; + return 0; +} + +/// +/// 根据前面模拟结果与行列号,生成模拟仿真图,分批生成并计算目标对象 +/// +/// 仿真行列号 +/// 正射单元格结果 +/// 模拟影像路径 +/// +int simProcess::sim_sum_SAR(std::string sim_dem_path, std::string sim_rc_path, std::string sim_orth_path, std::string sim_sum_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of sim_sar, begining:\t" << getCurrentTimeString() << endl; + //gdalImage dem_img(dem_path); + gdalImage sim_rc(sim_rc_path); + gdalImage sim_rsc(sim_orth_path); + gdalImage dem(sim_dem_path); + gdalImage sim_sar = CreategdalImage(sim_sum_path, this->pstn.height, this->pstn.width, 1, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + { + sim_sar.setNoDataValue(-9999, 1); + //double PRF = this->pstn.PRF; + //double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(16000000 / sim_rc.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = sim_rc.width; + Eigen::MatrixX sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd sim_sum_h(line_invert, line_width); + Eigen::MatrixXd sim_rsc_orth(line_invert, line_width); + Eigen::MatrixXd sim_sum_sar(line_invert, line_width); + Eigen::MatrixXd sim_sum_count(line_invert, line_width); + Eigen::MatrixXd demdata(line_invert, line_width); + + // 初始化 + do { + sim_sum_sar = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 1).cast(); + sim_sum_sar = sim_sum_sar.array() * 0; + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 1); + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 2); + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 3); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + { + // 累加计算模拟值 + int rowcount = 0, colcount = 0; + int row_min = 0, row_max = 0; + start_ids = 0; + std::cout << "time:\tsim_arr_row_min\tsim_arr_row_max\tsim_arr_all_lines\tsim_row_min\tsim_row_max\tsim_row_min0\tsim_row_max0" << std::endl;; + + + do { + std::cout << "\n" << getCurrentTimeString() << "\t" << start_ids << "\t" << start_ids + line_invert << "\t" << sim_rc.height << "\t"; + sim_r = sim_rc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 行 + sim_c = sim_rc.getData(start_ids, 0, line_invert, line_width, 2).cast(); // 列 + + sim_rsc_orth = sim_rsc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + demdata = dem.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + // 范围 + row_min = (floor(sim_r.minCoeff())); + row_max = (ceil(sim_r.maxCoeff())); + std::cout << row_min << "\t" << row_max << "\t"; + + //std::cout << "line range:\t" << row_min << " - " << row_max << "\t computing.....\t" << getCurrentTimeString() << endl; + + if (row_max < 0 || row_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + row_min = row_min <= 0 ? 0 : row_min; + row_max = row_max >= this->pstn.height ? this->pstn.height : row_max; + std::cout << row_min << "\t" << row_max << std::endl; + //sim_sum_sar =sim_sar.getData(row_min, 0, row_max-row_min+1, this->pstn.width, 1).cast(); + //sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + if (row_min >= row_max) { + break; + } + sim_sum_sar = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 1).cast(); + sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + sim_sum_h = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 3).cast(); // 列 + rowcount = sim_r.rows(); + colcount = sim_r.cols(); + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 0; i < rowcount; i++) { + int row_ids = 0, col_ids = 0; + for (int j = 0; j < colcount; j++) { + row_ids = int(round(sim_r(i, j))); + col_ids = int(round(sim_c(i, j))); + if (row_ids >= 0 && row_ids < this->pstn.height && col_ids >= 0 && col_ids < this->pstn.width) { + sim_sum_sar(row_ids - row_min, col_ids) += sim_rsc_orth(i, j); + sim_sum_count(row_ids - row_min, col_ids) += 1; + sim_sum_h(row_ids - row_min, col_ids) += demdata(i, j); + } + } + } + sim_sar.saveImage(sim_sum_sar, row_min, 0, 1); + sim_sar.saveImage(sim_sum_count, row_min, 0, 2); + sim_sar.saveImage(sim_sum_h, row_min, 0, 3); + + start_ids = start_ids + line_invert; + } while (start_ids < sim_rc.height); + std::cout << "\ncomputer the simulation value of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + } + { + std::cout << "computer the height of sim_sar, begining :\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sim_sum_h(1, 1); + Eigen::MatrixXd sim_sum_count(1, 1); + + int start_ids = 0; + int line_invert = int(8000000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + sim_sum_count = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 2).cast(); // 行 + sim_sum_h = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 3).cast(); // 列 + row_count = sim_sum_h.rows(); + col_count = sim_sum_h.cols(); + std::cout << "min~max:" << endl; + std::cout << sim_sum_count.minCoeff() << "\t" << sim_sum_count.maxCoeff() << endl; + std::cout << sim_sum_h.minCoeff() << "\t" << sim_sum_h.maxCoeff() << endl; + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + if (sim_sum_count(i, j) == 0) { + sim_sum_h(i, j) = 0; + } + else { + sim_sum_h(i, j) = sim_sum_h(i, j) / sim_sum_count(i, j); + } + } + } + sim_sar.saveImage(sim_sum_h, start_ids, 0, 3); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + + std::cout << "computer the height of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + + { + std::cout << "compute the average value of sim_sar, beiging:\t" << getCurrentTimeString() << endl; + + //ResampleGDALs(sim_sum_path.c_str(), 1, GRIORA_Bilinear); + //ResampleGDALs(sim_sum_path.c_str(), 3, GRIORA_Bilinear); + std::cout << "compute the average value of sim_sar, over :\t" << getCurrentTimeString() << endl; + } + { + std::cout << "=========================================\n"; + std::cout << "sim_sar_tif infomation :\n"; + std::cout << sim_sum_path << "\n"; + std::cout << "band 1 : simulation sar value \n"; + std::cout << "band 2 : the sum of the effective value from the dem \n"; + std::cout << "band 3 : the dem altitude of the effective value from the dem \n"; + std::cout << "=========================================\n"; + + } + return 0; +} + + +/// +/// 计算 +/// +/// +/// +/// +int simProcess::ori_sar_power(std::string ori_sar_path, std::string out_sar_power_path) +{ + std::cout << "compute the power value of ori sar, beiging:\t" << getCurrentTimeString() << endl; + gdalImage ori_sar(ori_sar_path); + gdalImage sim_power = CreategdalImage(out_sar_power_path, ori_sar.height, ori_sar.width, 1, ori_sar.gt, ori_sar.projection); + sim_power.setNoDataValue(-9999, 1); + { + Eigen::MatrixXd band1(1, 1); + Eigen::MatrixXd band2(1, 1); + Eigen::MatrixXd power_value(1, 1); + int start_ids = 0; + int line_invert = int(8000000 / ori_sar.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + std::cout << "rows:\t" << start_ids << "/" << ori_sar.height << "\t computing.....\t" << getCurrentTimeString() << endl; + band1 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 1).cast(); // a + band2 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 2).cast(); // b + //power_value = band2.array() * 0-9999; + power_value = (band1.array().pow(2) + band2.array().pow(2) + 1).log10() * 10;// 10 * Eigen::log10(Eigen::pow(0.5, Eigen::pow(2, band1.array()) + Eigen::pow(2, band2.array()))).array(); + //if () { + // + //}// power_value.isNaN()) + //std::cout << power_value.minCoeff() << "\t" << power_value.maxCoeff() << "\t" << endl; + //std::cout << "band 1\t" << band1.minCoeff() << "\t" << band1.maxCoeff() << "\t" << endl; + //std::cout << "band 2\t" << band2.minCoeff() << "\t" << band2.maxCoeff() << "\t" << endl; + sim_power.saveImage(power_value, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < ori_sar.height); + } + { + std::cout << "Resample the power value of ori sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(out_sar_power_path.c_str(), 1, GRIORA_Cubic); + } + std::cout << "compute the power value of ori sar, ending:\t" << getCurrentTimeString() << endl; + { + std::cout << "=========================================\n"; + std::cout << " the power image of sar :\n"; + std::cout << out_sar_power_path << "\n"; + std::cout << "band 1 : power value \t 10*log10(b1^2+b2^2) \n"; + std::cout << "=========================================\n"; + + } + return 0; +} + +int simProcess::createImageMatchModel(std::string ori_sar_rsc_path, std::string ori_sar_rsc_jpg_path, std::string sim_sar_path, std::string sim_sar_jpg_path, std::string matchmodel_path) +{ + // 转换影像 + { + std::cout << "compute the power value of sar, begining:\t" << getCurrentTimeString() << endl; + this->matchmodel.gdal2JPG(ori_sar_rsc_path, ori_sar_rsc_jpg_path, 1); + this->matchmodel.gdal2JPG(sim_sar_path, sim_sar_jpg_path, 1); + std::cout << "compute the power value of sar, ending:\t" << getCurrentTimeString() << endl; + } + // 构建匹配模型 + { + this->matchmodel.offsetXY_matrix = this->matchmodel.ImageMatch_ori_sim(ori_sar_rsc_jpg_path, sim_sar_jpg_path); + if (this->matchmodel.offsetXY_matrix.rows() < 7) { // 无法进行精校准 + this->isMatchModel = false; + } + else { + //this->matchmodel.match_model = this->matchmodel.CreateMatchModel(this->matchmodel.offsetXY_matrix); + //this->matchmodel.outMatchModel(matchmodel_path); + } + } + return 0; +} + + +/// +/// 根据精确匹配得到的纠正模型,纠正坐标偏移 +/// +/// +/// +/// +int simProcess::correctOrth_rc(std::string sim_rc_path, ImageMatch matchmodel) +{ + gdalImage sim_rc(sim_rc_path); + { + int lineVert = (1000000 / sim_rc.width); + int start_ids = 0; + do { + Eigen::MatrixXd sim_r = sim_rc.getData(start_ids, 0, lineVert, sim_rc.width, 1); + Eigen::MatrixXd sim_c = sim_rc.getData(start_ids, 0, lineVert, sim_rc.width, 2); + // 计算偏移结果 + int rowcount = sim_r.rows(); + int colcount = sim_r.cols(); + for (int i = 0; i < rowcount; i++) { + Eigen::MatrixXd temp = matchmodel.correctMatchModel(sim_r.row(i), sim_c.col(i)); + sim_r.row(i) = temp.row(0).array(); + sim_c.row(i) = temp.row(1).array(); + } + + // 写入影像 + sim_rc.saveImage(sim_r, start_ids, 0, 1); + sim_rc.saveImage(sim_c, start_ids, 0, 2); + start_ids = start_ids + lineVert; + } while (start_ids < sim_rc.height); + } + return 0; +} + +/// +/// +/// +/// +/// +/// 输出内入射角 +/// 输出dem +/// count的tif +/// +int simProcess::correct_ati(std::string orth_rc_path, std::string dem_path, std::string out_inclocal_path, std::string out_dem_path, std::string out_count_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage dem_img(dem_path); + gdalImage orth_rc(orth_rc_path); + + //gdalImage ori_inclocal = CreategdalImage(out_inclocal_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真结果 + gdalImage ori_dem = CreategdalImage(out_dem_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真结果 + gdalImage ori_count = CreategdalImage(out_count_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真 + + + // 初始化 + { + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_dem = ori_dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + //Eigen::MatrixXd sar_inclocal = ori_inclocal.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_count = ori_count.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_dem = sar_dem.array() * 0; + //sar_inclocal = sar_inclocal.array() * 0; + sar_count = sar_count.array() * 0; + + ori_dem.saveImage(sar_dem, start_ids, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, start_ids, 0, 1); + ori_count.saveImage(sar_count, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + { + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(50000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + Eigen::MatrixX sar_r(line_invert, line_width); + Eigen::MatrixXd sar_c(line_invert, line_width); + Eigen::MatrixXd dem(line_invert, line_width); + Eigen::MatrixXd sar_dem; + Eigen::MatrixXd sar_inclocal; + Eigen::MatrixXd sar_count; + + int rowcount = 0, colcount = 0; + int r_min, r_max, c_min, c_max; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + do { + std::cout << "rows:\t" << start_ids << "-" << start_ids + line_invert + 2 << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + dem = dem_img.getData(start_ids, 0, line_invert + 2, line_width, 1); + sar_r = orth_rc.getData(start_ids, 0, line_invert + 2, line_width, 1).cast(); + sar_c = orth_rc.getData(start_ids, 0, line_invert + 2, line_width, 2).cast(); + + r_min = int(floor(sar_r.minCoeff())); + r_max = int(ceil(sar_r.maxCoeff())); + + c_min = int(floor(sar_c.minCoeff())); + c_max = int(ceil(sar_c.maxCoeff())); + + + // 计算数据结果 + rowcount = r_max - r_min + 1; + colcount = c_max - c_min + 1; + + if (r_max < 0 || r_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + r_min = r_min <= 0 ? 0 : r_min; + r_max = r_max >= this->pstn.height ? this->pstn.height : r_max; + + sar_dem = ori_dem.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); + sar_count = ori_count.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); + //sar_inclocal = ori_inclocal.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); // 列 + + rowcount = dem.rows(); + colcount = dem.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + Eigen::MatrixX sataState = sar_r.row(i).reshaped(line_width, 1).array() * (1 / PRF) + imgstarttime; + sataState = this->pstn.orbit.SatelliteSpacePoint(sataState); + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle; + int r, c; + for (int j = 1; j < colcount - 1; j++) { + p0 = dem_img.getLandPoint(i + start_ids, j, dem(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, dem(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, dem(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, dem(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, dem(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(j,0),sataState(j,1) ,sataState(j,2) }; + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector); + + if (localincangle < 90) + { + r = sar_r(i, j); + c = sar_c(i, j); + if (r >= 0 && r < this->pstn.height && c >= 0 && c < this->pstn.width) { + //sar_inclocal(r - r_min, c) += localincangle; + sar_count(r - r_min, c) += 1; + sar_dem(r - r_min, c) += dem(i, j); + } + } + } + } + //std::cout << sim_rsc(1, 1961) << endl; + ori_dem.saveImage(sar_dem, r_min, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, r_min, 0, 1); + ori_count.saveImage(sar_count, r_min, 0, 1); + start_ids = start_ids + line_invert - 4; + } while (start_ids < dem_img.height); + omp_destroy_lock(&lock); //销毁互斥器 + } + + // 平均化 + { + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_dem = ori_dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + //Eigen::MatrixXd sar_inclocal = ori_inclocal.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_count = ori_count.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_dem = sar_dem.array() / sar_count.array(); + //sar_inclocal = sar_inclocal.array() / sar_count.array(); + + ori_dem.saveImage(sar_dem, start_ids, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, start_ids, 0, 1); + + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + std::cout << "repair dem by resample, begining:\t" << getCurrentTimeString() << endl; + { + + + } + std::cout << "repair dem by resample, overing:\t" << getCurrentTimeString() << endl; + + std::cout << "correct the evering dem meta, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the dem of sar:\t" << out_dem_path << endl; + std::cout << "the local incident angle of sar:\t " << out_inclocal_path << endl; + std::cout << "==========================================================" << endl; + return 0; +} + +int simProcess::ASF(std::string in_dem_path, std::string out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN) +{ + std::cout << "computer ASF, begining:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "in parameters" << endl; + std::cout << "the dem of sar:\t" << in_dem_path << endl; + std::cout << "in sar rc path:\t" << in_dem_path << endl; + std::cout << "out parameters" << endl; + std::cout << "out latlon of sar:\t" << out_latlon_path << endl; + std::cout << "==========================================================" << endl; + + + gdalImage dem(in_dem_path); + gdalImage latlon = CreategdalImage(out_latlon_path, this->pstn.height, this->pstn.width, 2, dem.gt, dem.projection, false); + //gdalImage sar_rc(in_sar_rc_path); + // 初始化坐标 + double aveageAti = 0; + { + int line_invert = int(500000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + int count = 0; + do { + Eigen::MatrixXd sar_dem = dem.getData(start_ids, 0, line_invert, dem.width, 1); + int row_count = sar_dem.rows(); + int col_count = sar_dem.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + if (!isnan(sar_dem(i, j)) && !isinf(sar_dem(i, j))) { + aveageAti += sar_dem(i, j); + count = count + 1; + } + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + aveageAti = aveageAti / count; + } + cout << "the aveage ati of dem:\t" << aveageAti << endl; + // 初始化坐标 + Landpoint initp = dem.getLandPoint(int(dem.height / 2), int(dem.width / 2), aveageAti); + + cout << "initlandpoint lon lat ati\t" << initp.lon << "\t" << initp.lat << "\t" << initp.ati << "\t" << endl; + initp = LLA2XYZ(initp); + cout << "initlandpoint lon lat ati\t" << initp.lon << "\t" << initp.lat << "\t" << initp.ati << "\t" << endl; + + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + double alpha0 = 0; + // 迭代计算 + { + int line_invert = int(1000000 / dem.width) > 10 ? int(1000000 / dem.width) : 10; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) + { + Eigen::MatrixXd sar_dem = dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_lon = latlon.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_lat = latlon.getData(start_ids, 0, line_invert, this->pstn.width, 2); + Eigen::Vector3d initTagetPoint(initp.lon, initp.lat, initp.ati); + int row_min = start_ids; + int row_max = sar_lon.rows() + row_min; + std::cout << "rows:\t" << row_min << "-" << row_max << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + + for (int i = row_min; i < row_max; i++) { + long double satetime = i * (1 / PRF) + imgstarttime; + Eigen::MatrixXd sataspace = this->pstn.orbit.SatelliteSpacePoint(satetime); // 空间坐标 + Eigen::Vector3d SatellitePosition(sataspace(0, 0), sataspace(0, 1), sataspace(0, 2)); + Eigen::Vector3d SatelliteVelocity(sataspace(0, 3), sataspace(0, 4), sataspace(0, 5)); + Landpoint sata{ sataspace(0,0), sataspace(0, 1), sataspace(0, 2) }; + + double beta0 = 50 * d2r;// (180-getAngle(sata, sata-initp))* d2r; + + for (int j = 0; j < this->pstn.width; j++) { + double R = getRangebyColumn(j, this->pstn.R0, this->pstn.fs, this->pstn.lamda); + double ati_H = sar_dem(i - row_min, j); + if (!isnan(ati_H) && !isinf(ati_H)) { + ati_H = aveageAti; + } + Eigen::Vector3d landp = asfclass.ASF(R, SatellitePosition, SatelliteVelocity, initTagetPoint, PSTN, this->pstn.R0, ati_H, alpha0, beta0); + Landpoint landpoint{ landp(0),landp(1) ,landp(2) }; + landpoint = XYZ2LLA(landpoint); + sar_lon(i - row_min, j) = landpoint.lon; + sar_lat(i - row_min, j) = landpoint.lat; + } + } + omp_set_lock(&lock); + latlon.saveImage(sar_lon, row_min, 0, 1); + latlon.saveImage(sar_lat, row_min, 0, 2); + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "out lon and lat of sar, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the lon lat of sar:\t" << out_latlon_path << endl; + std::cout << "band 1: lon" << endl; + std::cout << "band 2: lat " << endl; + std::cout << "==========================================================" << endl; + + return 0; +} +/// +/// 计算入射角和具体入射角 +/// +/// +/// +/// +/// +/// +void simProcess::calcalIncident_localIncident_angle(std::string in_dem_path, std::string in_rc_wgs84_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN) +{ + this->calGEC_Incident_localIncident_angle(in_dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, PSTN); +} + +/// +/// 获取GEC坐标系下的入射角与距地入射角 +/// +/// +/// +/// +/// +/// +void simProcess::calGEC_Incident_localIncident_angle(std::string in_dem_path, std::string in_gec_lon_lat_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer Incident_localIncident_angle in sar, begining:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "in parameters" << endl; + std::cout << "the dem in wgs84 of sar:\t" << in_dem_path << endl; + std::cout << "in gec lon lat path:\t" << in_gec_lon_lat_path << endl; + std::cout << "out parameters" << endl; + std::cout << "out incident_angle of sar:\t" << out_incident_angle_path << endl; + std::cout << "out local incident_angle of sar:\t" << out_local_incident_angle_path << endl; + std::cout << "==========================================================" << endl; + + gdalImage dem_img(in_dem_path); + gdalImage lonlat(in_gec_lon_lat_path); + gdalImage incident_angle = CreategdalImage(out_incident_angle_path, this->pstn.height, this->pstn.width, 1, dem_img.gt, dem_img.projection, false); + gdalImage local_incident_angle = CreategdalImage(out_local_incident_angle_path, this->pstn.height, this->pstn.width, 1, dem_img.gt, dem_img.projection, false); + // 初始化 + { + dem_img.InitInv_gt(); + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_inc = incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_local_incident = local_incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_inc = sar_inc.array() * 0; + sar_local_incident = sar_local_incident.array() * 0; + + incident_angle.saveImage(sar_inc, start_ids, 0, 1); + local_incident_angle.saveImage(sar_local_incident, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + { + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + + int line_invert = 500; + int start_ids = 0; + int line_cound_sum = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + + for (start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) { + Eigen::MatrixXd lon = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd lat = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 2); + Eigen::MatrixXd dem_col = dem_img.inv_gt(0, 0) + dem_img.inv_gt(0, 1) * lon.array() + dem_img.inv_gt(0, 2) * lat.array(); + Eigen::MatrixXd dem_row = dem_img.inv_gt(1, 0) + dem_img.inv_gt(1, 1) * lon.array() + dem_img.inv_gt(1, 2) * lat.array(); + //lon = Eigen::MatrixXd::Ones(1,1); + //lat= Eigen::MatrixXd::Ones(1,1); + int min_row = floor(dem_row.array().minCoeff()); + int max_row = ceil(dem_row.array().maxCoeff()); + min_row = min_row - 1 >= 0 ? min_row - 1 : 0; + max_row = max_row + 1 < dem_img.height ? max_row + 1 : dem_img.height; + int row_len = max_row - min_row + 1; + Eigen::MatrixXd dem = dem_img.getData(min_row, 0, row_len, dem_img.width, 1); + + Eigen::MatrixXd sar_inc = incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_local_incident = local_incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + int min_col = 0; + int lon_row_count = dem_col.rows(); + int lon_col_count = dem_col.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < lon_row_count; i++) + { + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle, inc_angle; + // 同一行,卫星坐标一致 + long double satatime = (i + start_ids) * (1 / PRF) + imgstarttime; + Eigen::MatrixXd sataState = this->pstn.orbit.SatelliteSpacePoint(satatime); + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + double dem_r, dem_c; + int r0, r1; + int c0, c1; + for (int j = 0; j < lon_col_count; j++) { + // 计算行列号 + dem_r = dem_row(i, j); //y + dem_c = dem_col(i, j); // x + r0 = floor(dem_r); + r1 = ceil(dem_r); + c0 = floor(dem_c); + c1 = ceil(dem_c); + + p0 = Landpoint{ dem_c - c0,dem_r - r0,0 }; + p1 = Landpoint{ 0,0,dem(r0 - min_row, c0 - min_col) }; // p11(0,0) + p2 = Landpoint{ 0,1,dem(r0 - min_row + 1, c0 - min_col) }; // p21(0,1) + p3 = Landpoint{ 1,0,dem(r0 - min_row , c0 + 1 - min_col) }; // p12(1,0) + p4 = Landpoint{ 1,1,dem(r0 - min_row + 1, c0 + 1 - min_col) }; // p22(1,1) + p0.ati = Bilinear_interpolation(p0, p1, p2, p3, p4); + + p0 = dem_img.getLandPoint(dem_r, dem_c, p0.ati); // 中心 + p1 = dem_img.getLandPoint(r0, c0, dem(r0 - min_row, c0 - min_col)); // p11(0,0) + p2 = dem_img.getLandPoint(r1, c0, dem(r1 - min_row, c0 - min_col)); // p21(0,1) + p3 = dem_img.getLandPoint(r0, c1, dem(r0 - min_row, c1 - min_col)); // p12(1,0) + p4 = dem_img.getLandPoint(r1, c1, dem(r1 - min_row, c1 - min_col)); // p22(1,1) + + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); // 地面坡向矢量 + landpoint = LLA2XYZ(p0); + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector);// 局地入射角 + inc_angle = getIncAngle(satepoint, landpoint); // 侧视角 + + // 记录值 + sar_local_incident(i, j) = localincangle; + sar_inc(i, j) = inc_angle; + } + } + omp_set_lock(&lock); + incident_angle.saveImage(sar_inc, start_ids, 0, 1); + local_incident_angle.saveImage(sar_local_incident, start_ids, 0, 1); + line_cound_sum = line_cound_sum + line_invert; + std::cout << "rows:\t" << start_ids << "\t" << line_cound_sum << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + + std::cout << "computer Incident_localIncident_angle in sar, overing:\t" << getCurrentTimeString() << endl; +} + +/// +/// 插值GTC的影像值 +/// +/// +/// +/// +/// +void simProcess::interpolation_GTC_sar(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + + + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 2, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0 - 9999; + sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 500; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX> ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + ori(i, j) = complex{ ori_a(i, j), ori_b(i, j) }; + } + } + ori_a = Eigen::MatrixXd(1, 1); + ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows(); + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 - 1; r2 = r1 + 1; r3 = r1 + 2; // 获取行 + c1 = floor(c); + c0 = c1 - 1; c2 = c1 + 1; c3 = c1 + 2; // 获取列 + // 考虑边界情况 + if (r0<-1 || c0<-1 || c3>this->pstn.width || r3>this->pstn.height) { + continue; + } + // 边界插值计算,插值模块权重 + Eigen::MatrixX> img_block(4, 4); + if (r0 == -1 || c0 == -1) { + if (r0 == -1) { + if (c0 == -1) { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c1) *complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c2) + ori(r3 - min_r, c3); // k,-1 + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3); // k,-1 + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3); // k,-1 + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = img_block(1, 0) * complex{3, 0} - complex{3, 0} *img_block(2, 0) + img_block(3, 0);// -1,-1 + } + else if (c3 == this->pstn.width) { + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(2, 3) + img_block(3, 3);//-1,M+1 + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1,k + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1 + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1 + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1 + } + + } + + else if (c0 == -1)//r0 != -1 + { + if (r3 == this->pstn.height) { + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + else { // + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 3) = ori(r3 - min_r, c3); + } + } + + } + else if (r3 == this->pstn.height || c3 == this->pstn.width) { + if (r3 == this->pstn.height) { + if (c3 == this->pstn.width) { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);;//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);;//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);;//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(1, 3) + img_block(0, 3);//N+1,M+1 + + } + else { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3);//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3);//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3);//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + } + else if (c3 == this->pstn.width) { // r3 != this->pstn.height + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);//0,M+1 + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r0 - min_r, c3); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + + complex interpolation_value = Cubic_Convolution_interpolation(r - r1, c - c1, img_block); + // + sar_a(i, j) = interpolation_value.real(); + sar_b(i, j) = interpolation_value.imag(); + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + sar_img.saveImage(sar_b, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + } + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, over:\t" << getCurrentTimeString() << std::endl; +} + + +/// +/// 插值GTC的影像值 +/// +/// +/// +/// +/// +void simProcess::interpolation_GTC_sar_sigma(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 1, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0; + //sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + //sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 600; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + //Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX> ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + ori(i, j) = complex{ ori_a(i, j), 0 }; + } + } + ori_a = Eigen::MatrixXd(1, 1); + //ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows()-100; + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 - 1; r2 = r1 + 1; r3 = r1 + 2; // 获取行 + c1 = floor(c); + c0 = c1 - 1; c2 = c1 + 1; c3 = c1 + 2; // 获取列 + // 考虑边界情况 + if (r0<-1 || c0<-1 || c3>this->pstn.width || r3>this->pstn.height) { + continue; + } + // 边界插值计算,插值模块权重 + Eigen::MatrixX> img_block(4, 4); + if (r0 == -1 || c0 == -1) { + if (r0 == -1) { + if (c0 == -1) { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c1) * complex{3, 0} - complex{3,0} *ori(r3 - min_r, c2) + ori(r3 - min_r, c3); // k,-1 + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3); // k,-1 + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3); // k,-1 + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = img_block(1, 0) * complex{3, 0} - complex{3, 0} *img_block(2, 0) + img_block(3, 0);// -1,-1 + } + else if (c3 == this->pstn.width) { + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(2, 3) + img_block(3, 3);//-1,M+1 + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1,k + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1 + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1 + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1 + } + + } + + else if (c0 == -1)//r0 != -1 + { + if (r3 == this->pstn.height) { + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + else { // + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 3) = ori(r3 - min_r, c3); + } + } + + } + else if (r3 == this->pstn.height || c3 == this->pstn.width) { + if (r3 == this->pstn.height) { + if (c3 == this->pstn.width) { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);;//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);;//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);;//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(1, 3) + img_block(0, 3);//N+1,M+1 + + } + else { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3);//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3);//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3);//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + } + else if (c3 == this->pstn.width) { // r3 != this->pstn.height + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);//0,M+1 + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r0 - min_r, c3); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + + complex interpolation_value = Cubic_Convolution_interpolation(r - r1, c - c1, img_block); + // + //if (interpolation_value.real() < 0) { + // int a = 1; + //} + sar_a(i, j) = interpolation_value.real(); + //sar_b(i, j) = interpolation_value.imag(); + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_b, start_ids, 0, 2); + start_ids = start_ids + line_invert-100; + } while (start_ids < sar_rc.height); + } + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, over:\t" << getCurrentTimeString() << std::endl; +} + +void simProcess::interpolation_bil(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + + this->pstn.width = ori_sar.width; + this->pstn.height = ori_sar.height; + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 1, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0 - 9999; + //sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + //sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 500; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + if (start_ids == 13500) { + int sdaf = 1; + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + //Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + //ori(i, j) = complex{ ori_a(i, j), ori_b(i, j) }; + ori(i, j) = double{ ori_a(i, j)}; + } + } + ori_a = Eigen::MatrixXd(1, 1); + //ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows(); + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, c0, c1; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 + 1; // 获取行 + c1 = floor(c); + c0 = c1 + 1; // 获取列 + // 考虑边界情况 + if (r1<=0 || c1<=0 || c0>= this->pstn.width || r0>=this->pstn.height) { + continue; + } + /* if (c1 <= 0 || c0 >= this->pstn.width || (r1 - min_r) <= 0 || (r0 - min_r) <= 0 || (r1 - min_r) >= ori_a.rows() || (r0 - min_r) >= ori_a.cols()) { + continue; + }*/ + /* if ((r1 - min_r) <= 0 || (r0 - min_r) <= 0 || (r1 - min_r) >= ori_a.rows() || (r0 - min_r) >= ori_a.cols() || c1 >= ori_a.cols() || c0 >= ori_a.cols()) { + continue; + }*/ + Landpoint p0, p1, p2, p3, p4; + //std::cout << "r= " << r << " r1= " << r1 << " c= " << c << " c1= " << c1 << " min_r = " << min_r << std::endl; + p0 = Landpoint{ r - r1,c - c1,0 }; + //std::cout << "row= " << r1 - min_r << "col= " < 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + int row_count = sar_r.rows() - 100; + int col_count = sar_r.cols(); + int win_s = floor(w_size / 2); + int count = w_size * w_size; +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c, snr; + for (int j = 0; j < col_count; j++) { + double sum = 0; + double ave = 0; + double sumSquared = 0; + double variance = 0; + //((i - win_s) < 0 || (j - win_s) < 0 || (i + win_s) > sar_rc.height || (j + win_s) > sar_rc.width) + if (i == 0 || j == 0 || i == sar_rc.height || j == sar_rc.width || (i - win_s) <= 0 || (j - win_s) <= 0 || (i + win_s) >= sar_rc.height || (j + win_s) >= sar_rc.width) + { + sar_a(i, j) = sar_r(i, j); + } + else + { + r0 = i - win_s; + r1 = i + win_s; + c0 = j - win_s; + c1 = j + win_s; + // 计算窗口均值与方差 + for (int n = r0; n <= r1; n++) + { + for (int m = c0; m <= c1; m++) + { + sum += sar_r(n, m); + sumSquared += sar_r(n, m) * sar_r(n, m); + } + } + //均值 + ave = sum / count; + //方差 + variance = sumSquared / count - ave * ave; + if (variance == 0) { + sar_a(i, j) = sar_r(i, j); + } + else { + sar_a(i, j) = sar_r(i, j) + noise_var * (ave - sar_r(i, j)); + + } + } + + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + start_ids = start_ids + line_invert - 100; + } while (start_ids < sar_rc.height); + + } + +} + +//计算方位角 +double simProcess::getAzimuth() +{ + std::cout << "the getAzimuth :" << getCurrentTimeString() << std::endl; + { + gdalImage dem_img(this->dem_path); + gdalImage sim_r_img(this->dem_r_path); + //gdalImage localincidence_angle_img = CreategdalImage(this->out_localIncidenct_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + //gdalImage incidence_angle_img = CreategdalImage(this->out_incidence_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + /*incidence_angle_img.setNoDataValue(-10, 1); + localincidence_angle_img.setNoDataValue(-10, 1);*/ + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(5000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + int count_lines = 0; + + //选取其中一个点进行计算方位角,直接把原来循环的第一个写死拿来做计算好了 + Eigen::MatrixXd demdata = dem_img.getData(1, 1, line_invert + 2, line_width, 1);//好像是把图像分成条带 + Eigen::MatrixXd sim_r = sim_r_img.getData(1, 1, line_invert + 2, line_width, 1).cast(); // + //注意Landpoint结构体的定义 为BLH???LLA2XYZ好像又通过方法转为xyz了 + Landpoint p0, landpoint, satepoint, satepointxyz; + p0 = dem_img.getLandPoint(1, 1, demdata(0, 0)); // 中心 + p0 = LLA2XYZ(p0); + long double r; + r = sim_r(1, 1); + Eigen::MatrixX sataState = this->pstn.orbit.SatelliteSpacePoint(r / PRF + imgstarttime); + //获取得到的satepoint是什么坐标系?wgs84? + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + satepoint = LLA2XYZ(satepoint); + //根据上面获取得到的地面点和卫星的位置计算方位角。。。 + RAH resultrah = Satrah(p0.lon, p0.lat, p0.ati, satepoint.lon, satepoint.lat, satepoint.ati); + std::cout << "RAH A:" << resultrah.A * 180 / PI << endl; + //把计算得到的方位角写入到文件中? + creatTxt(this->workSpace_path, to_string(resultrah.A * 180 / PI)); + return resultrah.A; + } + std::cout << "the getAzimuth over:\t" << getCurrentTimeString() << std::endl; + return 0.0; +} + +/// +/// 根据RPC的行列号,生成RPC对应的DEM文件 +/// +/// +/// +/// +void simProcess::CreateRPC_DEM(std::string in_rpc_rc_path, std::string in_dem_path, std::string out_rpc_dem_path) +{ + gdalImage rpc_rc(in_rpc_rc_path); + gdalImage dem_img(in_dem_path); + gdalImage rpc_dem_img = CreategdalImage(out_rpc_dem_path, rpc_rc.height, rpc_rc.width, 1, rpc_rc.gt, rpc_rc.projection); + + // 初始化 + { + dem_img.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd rpc_dem = rpc_dem_img.getData(start_ids, 0, line_invert, rpc_dem_img.width, 1); + rpc_dem = rpc_dem.array() * 0 - 9999; + rpc_dem_img.saveImage(rpc_dem, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < rpc_dem_img.height); + rpc_dem_img.setNoDataValue(-9999, 1); + } + + // 插值计算结果 + { + dem_img.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << rpc_dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd rpc_dem = rpc_dem_img.getData(start_ids, 0, line_invert, rpc_dem_img.width, 1); + Eigen::MatrixXd rpc_row = rpc_dem.array() * 0 - 1; + Eigen::MatrixXd rpc_col = rpc_dem.array() * 0 - 1; + int row_count = rpc_dem.rows(); + int col_count = rpc_dem.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + Landpoint landpoint = rpc_dem_img.getLandPoint(i + start_ids, j, 0); + Landpoint land_row_col = dem_img.getRow_Col(landpoint.lon, landpoint.lat); // x,y,z + rpc_row(i, j) = land_row_col.lat; // row + rpc_col(i, j) = land_row_col.lon; // col + } + } + + double min_r = floor(rpc_row.minCoeff()) - 1; + double max_r = ceil(rpc_row.maxCoeff()) + 1; + min_r = min_r >= 0 ? min_r : 0; + int len_r = max_r - min_r; + Eigen::MatrixXd dem = dem_img.getData(min_r, 0, len_r + 2, dem_img.width, 1); + + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + Landpoint p0 = Landpoint{ rpc_row(i,j),rpc_col(i,j),0 }; + Landpoint p1 = Landpoint{ floor(p0.lon),floor(p0.lat),0 }; p1.ati = dem(int(p1.lon - min_r), int(p1.lat)); p1 = Landpoint{ 0,0,p1.ati }; + Landpoint p2 = Landpoint{ floor(p0.lon),ceil(p0.lat),0 }; p2.ati = dem(int(p2.lon - min_r), int(p2.lat)); p2 = Landpoint{ 0,1,p2.ati }; + Landpoint p3 = Landpoint{ ceil(p0.lon),floor(p0.lat),0 }; p3.ati = dem(int(p3.lon - min_r), int(p3.lat)); p3 = Landpoint{ 1,0,p3.ati }; + Landpoint p4 = Landpoint{ ceil(p0.lon),ceil(p0.lat),0 }; p4.ati = dem(int(p4.lon - min_r), int(p4.lat)); p4 = Landpoint{ 1,1,p4.ati }; + p0 = Landpoint{ p0.lon - floor(p0.lon), p0.lat - floor(p0.lat), 0 }; + p0.ati = Bilinear_interpolation(p0, p1, p2, p3, p4); + rpc_dem(i, j) = p0.ati; + } + } + rpc_dem_img.saveImage(rpc_dem, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < rpc_dem_img.height); + } + + +} + +void simProcess::CreateRPC_refrenceTable(string in_rpc_tiff_path,string in_merge_dem,string out_rpc_lon_lat_tiff_path) +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister();//注册驱动 + + const char* pszTif = in_rpc_tiff_path.c_str(); + + gdalImage rpc_img(in_rpc_tiff_path); + + GDALRPCInfo oInfo = rpc_img.getRPC(); + + //设置RPC模型中所需的DEM路径 + char** papszTransOption = NULL; + //papszTransOption = CSLSetNameValue(papszTransOption, "RPC_DEM", "E:\\DEM.img"); //设置DEM + + //使用RPC信息,DEM等构造RPC转换参数 + void* pRPCTransform = GDALCreateRPCTransformer(&oInfo, FALSE, 0, papszTransOption); + + + // 创建影像 + + gdalImage lon_lat_img = CreategdalImage(out_rpc_lon_lat_tiff_path, rpc_img.height, rpc_img.width, 2, rpc_img.gt, rpc_img.projection, false); + // 计算角点 + string temp_dem_path = in_merge_dem + ".bak"; + double merge_gt[6] = { + rpc_img.gt(0,0), rpc_img.gt(0,1), rpc_img.gt(0,2), + rpc_img.gt(0,3), rpc_img.gt(0,4), rpc_img.gt(0,5) + } ; + ResampleGDAL(in_merge_dem.c_str(), temp_dem_path.c_str(), merge_gt, rpc_img.width, rpc_img.height, GRA_Bilinear); + + gdalImage merger_dem_tiff(temp_dem_path); + double X[4] = { 0,0,rpc_img.width - 1,rpc_img.width - 1 }; + double Y[4] = { 0,rpc_img.height - 1,rpc_img.height - 1,0 }; + double Z[4] = { 0,0,0,0 }; + int sucess_num[4] = { false,false,false,false }; + GDALRPCTransform(pRPCTransform, FALSE, 4, X, Y, Z, sucess_num); + for (int i = 0; i < 4; i++) { + std::cout << X[i] << "\t" << Y[i] << "\t" << Z[i] << "\t" << sucess_num[i] << std::endl; + } + int line_invert = int(1500000 / rpc_img.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd lon = lon_lat_img.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 1); + Eigen::MatrixXd lat = lon_lat_img.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 2); + Eigen::MatrixXd dem = merger_dem_tiff.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 2); + int row_count = lon.rows(); + int col_count = lon.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + //定义图像的四个角点行列号坐标 + double dY[1] = { i + max_rows_ids }; + double dX[1] = { j }; + double dZ[1] = { dem(i,j)}; + int nSuccess[1] = { FALSE }; + GDALRPCTransform(pRPCTransform, FALSE, 1, dX, dY, dZ, nSuccess); + lon(i, j) = dX[0]; + lat(i, j) = dY[0]; + } + } + + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + std::cout << lon.array().minCoeff() << endl; + lon_lat_img.saveImage(lon, max_rows_ids, 0, 1); + lon_lat_img.saveImage(lat, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << lon_lat_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + //释放资源 + GDALDestroyRPCTransformer(pRPCTransform); + CSLDestroy(papszTransOption); +} + +/// +/// 映射表插值计算 +/// +/// 映射表 +/// 输入数据 +/// 输出数据 +void simProcess::CorrectionFromSLC2Geo(string in_lon_lat_path, string in_radar_path, string out_radar_path,int in_band_ids) +{ + gdalImage in_lon_lat(in_lon_lat_path); + gdalImage in_image(in_radar_path); + gdalImage out_radar(out_radar_path); + + cv::Mat in_mat; + cv::Mat out_mat; + + cv::eigen2cv(in_image.getData(0, 0, in_lon_lat.height, in_lon_lat.width, in_band_ids),in_mat); + + // 定义映射关系 + cv::Mat in_x,in_y; + cv::eigen2cv(in_lon_lat.getData(0, 0, in_lon_lat.height, in_lon_lat.width, 1), in_x); + cv::eigen2cv(in_lon_lat.getData(0, 0, in_lon_lat.height, in_lon_lat.width, 1), in_y); + + // 重新进行插值计算 + +} +/// +/// 根据DEM创建SAR_rc +/// +/// +/// +/// +/// + + +double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda) +{ + double result = (double)(2 * (R - NearRange) / LIGHTSPEED * Fs); // 计算采样率 + return result; +} + +Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda) +{ + return ((R.array() - NearRange).array() / lamda * Fs).array().cast(); +} + +double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda) +{ + return (j * lamda / 2) / Fs + NearRange; + +} + +Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda) +{ + return ((j.array() * lamda / 2) / Fs + NearRange).array().cast(); +} + +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector) { + Landpoint Rsc = satepoint - landpoint; // AB=B-A + //double R = getlength(Rsc); + //std::cout << R << endl; + double angle = getAngle(Rsc, slopeVector); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + +double getIncAngle(Landpoint& satepoint, Landpoint& landpoint) { + + Landpoint Rsc = satepoint - landpoint; // AB=B-A + Landpoint Rs = landpoint;// landpoint; + double angle = getAngle(Rsc, Rs); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////// ASF 计算 /////////////////////////////////////////////////// +////// 《星载合成孔径雷达影像正射校正方法研究》 陈尔学 ///////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////// + +/// +/// 计算 变换矩阵 卫星坐标系-> ECR +/// +/// [x,y,z,vx,vy,vz] nx6 +/// +Eigen::MatrixXd ASFOrthClass::Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc) +{ + + Eigen::Vector3d x, y, z; + + Eigen::MatrixXd M(3, 3); + + z = Rsc / Rsc.norm(); + y = Rsc.cross(Vsc) / (Rsc.norm() * Vsc.norm()); + x = y.cross(z); + + M.col(0) = x; + M.col(1) = y; + M.col(2) = z; + return M; +} +/// +/// 获取从卫星指向地面目标的单位矢量 +/// +/// 弧度值 +/// 弧度值 +/// 变换矩阵 +/// +Eigen::Vector3d ASFOrthClass::UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M) +{ + // 目标T的单位向量 ST = R * M * P + Eigen::Vector3d P(sin(alpha), -1.0 * cos(alpha) * sin(beta), -1.0 * cos(alpha) * cos(beta)); + return M * P; +} + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H) +{ + /** + 根据R和alpha 计算出beta来。 + 根据参考论文,式3 - 13,完成此方法。(注意这是近似法 + args : + R:斜距 + alpha : 雷达侧视角 + beta0 : beta初始值 + SatellitePosition : 3x1 卫星空间位置 + TargetPosition:3x1 目标对象 + */ + Eigen::MatrixXd M = this->Satellite2ECR(SatellitePosition, SatelliteVelocity); + // 地球半径 + double Rp = earth_Rp + H; + double Rs_norm = SatellitePosition.norm(); + // 初始化beta + if (beta == 0) { + double beta_cos = (Rs_norm * Rs_norm + R * R - Rp * Rp) / (2 * Rs_norm * R); + beta = acos(beta_cos); + } + + double delta_R, sin_eta, delta_beta, tan_eta; + // 迭代 + int i = 0; + do { + // 计算斜率的增加 + delta_R = R - this->FR(alpha, beta, SatellitePosition, M, R_threshold, H); + // 计算入射角 + sin_eta = Rs_norm * sin(beta) / Rp; + tan_eta = sin_eta / sqrt(1 - sin_eta * sin_eta); + // 计算增量 + delta_beta = delta_R / (R * tan_eta); + // 更新 + beta = beta + delta_beta; + // 判断循环终止条件 + i = i + 1; + if (i >= 10000) // 达到终止条件 + { + return -9999; + } + } while (abs(delta_R) > 0.01); + return beta; +} + +/// +/// 从beta,alpha获取获取目标的空间位置 +/// +/// +/// +/// +/// +/// +/// +Eigen::Vector3d ASFOrthClass::GetXYZByBetaAlpha(double alpha, double beta, Eigen::Vector3d SatellitePosition, double R, Eigen::MatrixXd M) +{ + return SatellitePosition + R * this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); +} + +/// +/// FD +/// +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity, double R, double lamda, Eigen::MatrixXd M) +{ + /** + 根据beta, alpha, 卫星空间位置, 斜距,转换矩阵 + */ + Eigen::Vector3d UnitVector = this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); + Eigen::Vector3d Rst = -1 * R * UnitVector; + double Rst_Vst = Rst.dot(SatelliteVelocity - TargetVelocity); + return -2 / (R * lamda) * Rst_Vst; +} + + +/// +/// FR +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H) +{ + /* + 根据 雷达侧视角,雷达视角,卫星位置,坐标系变换矩阵,大地高等参数,根据参考论文中公式3 - 1 == 》3 - 10的计算过程,设计此方程 + args : + alpha:雷达侧视角 卫星与地物间速度运动差导致的(即多普勒频移的结果) + beta : 雷达视角 + Satellite_position : 卫星空间位置 + M:坐标系转换矩阵 + H:大地高 + return : + R:斜距 + */ + //std::cout << beta << endl; + Eigen::Vector3d UnitVector = R_threshold * this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); + // 解方程 3 - 10 纠正错误,A公式有问题 + double a = (earth_Re + H) * (earth_Re + H); + double b = earth_Rp * earth_Rp; + long double Xs = SatellitePosition(0); + long double Ys = SatellitePosition(1); + long double Zs = SatellitePosition(2); + long double Xp = UnitVector(0); + long double Yp = UnitVector(1); + long double Zp = UnitVector(2); + //std::cout << Xp<<"\t"<< Yp<<"\t"<< Zp << endl; + long double A = (Xp * Xp + Yp * Yp) / a + (Zp * Zp) / b; + long double B = 2 * (Xs * Xp + Ys * Yp) / a + 2 * Zs * Zp / b; + long double C = (Xs * Xs + Ys * Ys) / a + Zs * Zs / b - 1; + //std::cout << A << "\t" << B << "\t" << C << endl; + C = B * B - 4 * A * C; + //std::cout << A << "\t" << B << "\t" << C << endl; + double R1 = (-B - sqrt(C)) / (2 * A); + //double R2 = (-B + sqrt(C)) / (2 * A); + //std::cout << R1 << "\t" << R2 << endl; + if (R1 > 1) { + return R1 * R_threshold; + } + else { + return -9999; + //return (-B + math.sqrt(t)) / (2 * A) # 这里通过几何分析排除这个解 + } + +} + +/// +/// ASF方法 +/// +/// +/// 卫星高度 +/// 卫星速度 +/// 初始化地面坐标 +/// +/// +/// 初始高程 +/// +/// +/// +Eigen::Vector3d ASFOrthClass::ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H, double alpha0, double beta0) +{ + // 部分参数初始化 + double alpha = alpha0; + double beta = beta0; + double delta_alpha = 0; + // 这个公式是根据《中国海洋合成孔径雷达卫星工程、产品与处理》 + // P164 5.8.4 多普勒参数计算 + double fd = PSTN.calNumericalDopplerValue(R); + Eigen::MatrixXd M = this->Satellite2ECR(SatellitePosition, SatelliteVelocity); + double FD_, delta_fd; + Eigen::Vector3d XYZ; + int i = 0;// 统计迭代次数 + while (true) { + Eigen::Vector3d TargetVelocity = Eigen::Vector3d(-1 * earth_We * TargetPosition(1), earth_We * TargetPosition(0), 0);// 计算地面速度, 粗糙计算时,默认为0 + beta = this->GetLookFromRangeYaw(R, alpha, beta, SatellitePosition, SatelliteVelocity, R_threshold, H); + FD_ = this->FD(alpha, beta, SatelliteVelocity, TargetVelocity, R, PSTN.lamda, M); + delta_fd = FD_ - fd; + delta_alpha = -1 * delta_fd * PSTN.lamda / (2 * (SatelliteVelocity - TargetVelocity).norm()); + TargetPosition = this->GetXYZByBetaAlpha(alpha, beta, SatellitePosition, R, M); + //cout << i << "\t" << delta_alpha * R << "\t" << delta_alpha<<"\t"<< (abs(delta_alpha * R) < 0.1)<<"\t"<< (abs(delta_alpha) < 0.001) << endl; + if (abs(delta_alpha * R) < 0.1 || abs(delta_alpha) < 0.0003) + { + break; + } + alpha = alpha + delta_alpha; + i = i + 1; + if (i > 10000) { + throw new exception("ASF 失败"); + } + + } + return TargetPosition; +} + diff --git a/simorthoprogram-orth_gf3-strip/simptsn.h b/simorthoprogram-orth_gf3-strip/simptsn.h new file mode 100644 index 0000000..84b85b1 --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/simptsn.h @@ -0,0 +1,243 @@ +#pragma once +/// +/// 仿真成像算法 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 +#include "baseTool.h" +#include +#include +#include +#include +//#include +#include +#include "SateOrbit.h" +#include "ImageMatch.h" +using namespace std; +using namespace Eigen; + +////////////// 常用函数 //////////////////////// + +double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda); +Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda); + +double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda); +Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda); +///////////// ptsn 算法 ///////////////////// + +class PSTNAlgorithm { +public: + // 初始化与析构函数 + PSTNAlgorithm(); + PSTNAlgorithm(string parameterPath); + ~PSTNAlgorithm(); + + int dem2lat_lon(std::string dem_path, std::string lon_path, std::string lat_path); + int dem2SAR_RC(std::string dem_path, std::string sim_rc_path); + + // 模拟算法函数 + Eigen::MatrixX calNumericalDopplerValue(Eigen::MatrixX R);// 数值模拟法计算多普勒频移值 + double calNumericalDopplerValue(double R);// 数值模拟法计算多普勒频移值 + Eigen::MatrixX calTheoryDopplerValue(Eigen::MatrixX R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1);//根据理论模型计算多普勒频移值 + double calTheoryDopplerValue(double R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1); + Eigen::MatrixX PSTN(Eigen::MatrixX TargetPostion, double ave_dem, double dt, bool isCol ); // 输入DEM + //Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd blh); + //Landpoint WGS842J2000(Landpoint p); +public: // WGS84 到 J2000 之间的变换参数 + Eigen::MatrixXd UTC; + double Xp = 0.204071; + double Yp = 0.318663; + double Dut1 = 0.0366742; + double Dat = 37; +public: + int height; // 影像的高 + int width; + + // 入射角 + double near_in_angle;// 近入射角 + double far_in_angle;// 远入射角 + + // SAR的成像参数 + double fs;// 距离向采样率 + double R0;//近斜距 + double LightSpeed; // 光速 + double lamda;// 波长 + double refrange;// 参考斜距 + double doppler_reference_time; //多普勒参考时间 + + double imgStartTime;// 成像起始时间 + double PRF;// 脉冲重复率 + + int doppler_paramenter_number;//多普勒系数个数 + MatrixX doppler_paras;// 多普勒系数 + + OrbitPoly orbit; // 轨道模型 + +}; + + +/// +/// 获取局地入射角,角度值 +/// +/// +/// +/// +/// +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector); + + +/// +/// 侧视入射角,角度值 +/// +/// +/// +/// +double getIncAngle(Landpoint& satepoint, Landpoint& landpoint); + + +/// +/// ASF计算方法 +/// +class ASFOrthClass { + +public: + Eigen::MatrixXd Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc); // 根据卫星坐标计算变换矩阵 M + Eigen::Vector3d UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M); + double GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H = 0); + + Eigen::Vector3d GetXYZByBetaAlpha(double alpha,double beta, Eigen::Vector3d SatellitePosition,double R, Eigen::MatrixXd M); + + double FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity,double R,double lamda, Eigen::MatrixXd M); + double FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H = 0); + + Eigen::Vector3d ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H = 0, double alpha0 = 0, double beta0 = 0); + +}; + +/// +/// 仿真处理流程 +/// +class simProcess { +public: + simProcess(); + ~simProcess(); + + int parameters(int argc, char* argv[]); + + int InitSimulationSAR(std::string paras_path,std::string workspace_path,std::string out_dir_path,std::string in_dem_path,std::string in_sar_path); // 间接定位法 + + int CreateSARDEM(); + int dem2SAR(); // 切换行号 + int SARIncidentAngle(); + int SARSimulationWGS(); + int SARSimulation(); + int in_sar_power(); + int ReflectTable_WGS2Range(); + + int InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path,std::string in_rpc_lon_lat_path,std::string out_inc_angle_path, std::string out_local_inc_angle_path, std::string out_inc_angle_geo_path, std::string out_local_inc_angle_geo_path); + int dem2SAR_row(); // 切换行号 + int SARIncidentAngle_RPC(); + int createRPCDEM(); + + // 格网离散插值 + int Scatter2Grid(std::string lon_lat_path, std::string data_tiff, std::string grid_path, double space); + + // ASF 模块计算 + int InitASFSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path); + + int ASF(std::string in_dem_path, std::string out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN); + + //int dem2simSAR(std::string dem_path, std::string out_sim_path, PSTNAlgorithm PSTN); // 根据DEM生成输出仿真图像 + int sim_SAR(std::string dem_path, std::string sim_rc_path, std::string sim_sar_path, PSTNAlgorithm PSTN); + int dem2aspect_slope(std::string dem_path, std::string aspect_path, std::string slope_path); + int sim_sum_SAR(std::string sim_dem_path,std::string sim_rc_path, std::string sim_orth_path, std::string sim_sum_path,PSTNAlgorithm pstn); + void interpolation_GTC_sar_sigma(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + + //双线性插值 + void interpolation_bil(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + //lee滤波 + void lee_process(std::string in_ori_sar_path, std::string out_orth_sar_path, int w_size, double noise_var); + // 原始影像强度图 + int ori_sar_power(std::string ori_sar_path, std::string out_sar_power_path); + + // 匹配偏移模型构建 + int createImageMatchModel(std::string ori_sar_rsc_path, std::string ori_sar_rsc_jpg_path, std::string sim_sar_path, std::string sim_sar_jpg_path, std::string matchmodel_path); + + // 纠正影像 + int correctOrth_rc(std::string sim_rc_path,ImageMatch matchmodel); + + int correct_ati(std::string orth_rc_path, std::string dem_path, std::string out_inclocal_path, std::string out_dem_path, std::string out_count_path, PSTNAlgorithm PSTN); + + void calcalIncident_localIncident_angle(std::string in_dem_path, std::string in_rc_wgs84_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN); + + void calGEC_Incident_localIncident_angle(std::string in_dem_path, std::string in_gec_lon_lat_path,std::string out_incident_angle_path, std::string out_local_incident_angle_path,PSTNAlgorithm PSTN); + + void interpolation_GTC_sar(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + // RPC + void CreateRPC_DEM(std::string in_rpc_rc_path, std::string in_dem_path, std::string out_rpc_dem_path); + + void CreateRPC_refrenceTable(string in_rpc_tiff_path, string in_merge_dem, string out_rpc_lon_lat_tiff_path); + + void CorrectionFromSLC2Geo(string in_lon_lat_path, string in_radar_path, string out_radar_path, int in_band_ids); + + //TODO:计算方位角 + double getAzimuth(); + +// 内部参数 +public: + ImageMatch matchmodel; + bool isMatchModel; + + std::string workSpace_path;// 工作空间路径 + std::string outSpace_path;// 输出工作空间路径 + PSTNAlgorithm pstn; // 参数组件 + ///// RPC 局地入射角 /////////////////////////////////// + std::string in_rpc_lon_lat_path; + std::string out_dir_path; + std::string workspace_path; + // 临时文件 + std::string rpc_wgs_path; + std::string ori_sim_count_tiff;// 映射角文件 + // 输出文件 + std::string out_inc_angle_rpc_path; + std::string out_local_inc_angle_rpc_path; + + // 输出文件 + std::string out_inc_angle_geo_path; + std::string out_local_inc_angle_geo_path; + + ///// 正向仿真方法 ///////// + + + + // 临时产品文件 + std::string in_dem_path; // 输入DEM + std::string dem_path; // 重采样之后DEM + std::string dem_r_path;// 行号影像 + std::string dem_rc_path; // 行列号 + std::string sar_sim_wgs_path; + std::string sar_sim_path; + std::string in_sar_path; + std::string sar_jpg_path; + std::string sar_power_path; + // 最终产品 + std::string out_dem_rc_path; // 经纬度与行列号变换文件 + + std::string out_dem_slantRange_path; // 斜距文件 + std::string out_plant_slantRange_path;// 平面斜距文件 + + //// ASF 方法 ///////////// + std::string out_lon_path;// 经度 + std::string out_lat_path;// 纬度 + std::string out_slantRange_path;// 斜距文件 + + /// 共同文件 /// + std::string out_localIncidenct_path;// 计算局地入射角 + std::string out_incidence_path; // 入射角文件 + std::string out_ori_sim_tiff;// 映射角文件' + std::string out_sim_ori_tiff; +}; + +bool PtInRect(Point_3d pCur, Point_3d pLeftTop, Point_3d pRightTop, Point_3d pRightBelow, Point_3d pLeftBelow); \ No newline at end of file diff --git a/simorthoprogram-orth_gf3-strip/test_moudel.cpp b/simorthoprogram-orth_gf3-strip/test_moudel.cpp new file mode 100644 index 0000000..30cfe4d --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/test_moudel.cpp @@ -0,0 +1,282 @@ +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +using namespace std; +using namespace Eigen; + +#include "test_moudel.h" + + +int test_main(int mode, string rootpath) +{ + switch (mode) + { + case 0: + { + test_mode_0(); + break; + }; + case 1: + { + test_mode_1(rootpath); + break; + } + case 7: { + test_mode_7(); + break; + } + case 8: { + std::string in_rpc_tiff = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1B_HH_L10003514912_db.tif"; + std::string out_lon_lat_path = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\RPC_ori_sim.tif"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.CreateRPC_refrenceTable(in_rpc_tiff, dem_path,out_lon_lat_path); + std::cout << "==========================================================================" << endl; + break; + } + default: + test_ASF(rootpath); + break; + } + return 0; +} + + +int test_mode_7() { + // + std::cout << "mode 7: get rpc incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 7 in_parameter_path in_dem_path in_gec_lon_lat_path work_path taget_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\orth_para.txt"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; + std::string in_gec_lon_lat_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\RPC_ori_sim.tif"; + std::string work_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary"; + std::string taget_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\inc_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\local_inc_angle.tiff"; + std::string out_incident_angle_geo_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\inc_angle_geo.tiff"; + std::string out_local_incident_angle_geo_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\local_inc_angle_geo.tiff"; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.InitRPCIncAngle(parameter_path, work_path, taget_path, dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, out_incident_angle_geo_path, out_local_incident_angle_geo_path); + std::cout << "==========================================================================" << endl; + return 0; +} + + +int test_mode_0() +{ + std::cout << "State:\tTEST MODE" << endl; + test_LLA2XYZ_XYZ2LLA(); + return 0; +} + +int test_mode_1(string rootpath) +{ + // .\baseTool\x64\Release\SIMOrthoProgram.exe 1 D:\MicroWorkspace\C-SAR\Ortho\Temporary\unpack\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff +//??????? + + std::string root_path = rootpath;// "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary2"; + std::string workspace = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary"; + std::string parameter_path =workspace+ "\\package\\orth_para.txt"; // + std::string dem_path = workspace + "\\TestDEM\\pindem.tif"; // + std::string in_sar_path = workspace + "\\unpack\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HHHV_L10004871459\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HH_L10004871459.tiff"; // + std::string work_path = workspace ; // + std::string taget_path = workspace + "\\package"; // + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the sar image:\n" << in_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + std::cout << "==========================================================================" << endl; + process.InitSimulationSAR(parameter_path, work_path, taget_path, dem_path, in_sar_path); + std::cout << "==========================================================================" << endl; + return 0; +} + + +int test_ASF(string rootpath) { + std::string root_path = rootpath;// "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary2"; + std::string parameter_path = root_path + "\\package\\orth_para.txt"; + std::string dem_path = root_path + "\\TestDEM\\mergedDEM.tif"; + std::string ori_sar_path = root_path + "\\unpack\\" + "GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HHHV_L10004871459\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HH_L10003923848.tiff"; + std::string work_path = root_path + "\\TestSim"; + std::string taget_path = root_path + "\\output"; + std::string out_GEC_dem_path = root_path + "\\output\\GEC_dem.tif"; + std::string out_GTC_rc_path = root_path + "\\output\\GTC_rc_wgs84.tif"; + std::string out_GEC_lon_lat_path = root_path + "\\output\\GEC_lon_lat.tif"; + std::string out_clip_DEM_path = root_path + "\\output\\Orth_dem.tif"; + std::cout << "==========================================================================" << endl; + std::cout << "????????????????????DEM ??Χ" << endl; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path "; + std::cout << "out_GEC_dem_path out_GTC_rc_path out_GEC_lon_lat_path out_clip_dem_path" << endl; + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the reference sar image for match simulation sar image:\n" << ori_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + ASFOrthClass ASFClass; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + // + dem_path = out_clip_DEM_path;// JoinPath(work_path, "clipDEM.tif"); + std::string out_simrc_path = JoinPath(work_path, "dem_sar_rc.tif"); //r,c + std::string sim_sar_orth_path = JoinPath(work_path, "sim_sar_orth.tif"); // orth_sim,orth_inclocal + + std::string dem_slope_path = JoinPath(work_path, "dem_slope.tif"); + std::string dem_aspect_path = JoinPath(work_path, "dem_aspect.tif"); + + std::string sim_sar_path = JoinPath(work_path, "sim_sar_sum.tif"); // sim count dem + std::string ori_sar_rsc_path = JoinPath(work_path, "ori_sar_power.tif"); // ori_power + std::string ori_sar_rsc_jpg_path = JoinPath(work_path, "ori_sar_power.jpg"); + std::string sim_sar_jpg_path = JoinPath(work_path, "sim_sar_sum.jpg"); + std::string matchmodel_path = JoinPath(work_path, "matchmodel.txt"); // matchmodel + + std::string out_dem_count_path = JoinPath(work_path, "dem_count.tif"); + + std::string out_dem_path = out_GEC_dem_path; + std::string out_inclocal_path = JoinPath(taget_path, "inclocal.tif"); + std::string out_sar_rc_path = out_GTC_rc_path; + std::string out_lon_lat_path = out_GEC_lon_lat_path; + + if (process.isMatchModel) { + process.correctOrth_rc(out_simrc_path, process.matchmodel); + } + if (boost::filesystem::exists(boost::filesystem::path(out_sar_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(out_sar_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(out_simrc_path), boost::filesystem::path(out_sar_rc_path)); + + process.correct_ati(out_sar_rc_path, dem_path, out_inclocal_path, out_dem_path, out_dem_count_path, pstn); + // ASF + + process.ASF(out_dem_path, out_lon_lat_path, ASFClass, pstn); + + return 0; +} + + +int test_mode_2() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_DEM.tiff"; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_sar_rc.tiff"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_incident_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_local_incident_angle.tiff"; + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + + process.calcalIncident_localIncident_angle(dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + + return 0; +} + +int test_mode_3() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GTC_rc_wgs84.tiff"; + std::string in_ori_sar_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\unpack\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff"; + std::string out_orth_sar_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GTC\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff"; + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); + + return 0; +} + +int test_mode_4() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string in_dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\Orth_dem.tiff"; + std::string in_rpc_rc_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\\RPC_Ortho\\RPC_sar_rc.tiff"; + std::string out_rpc_dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_DEM.tiff"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_incident_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_local_incident_angle.tiff"; + + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.CreateRPC_DEM(in_rpc_rc_path, in_dem_path, out_rpc_dem_path); + process.calcalIncident_localIncident_angle(out_rpc_dem_path, in_rpc_rc_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + return 0; +} + +int test_mode_5() +{ + std::string in_ori_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848_GTC_geo_wp.tif"; + std::string out_power_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\package\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848_GTC_geo_OrthoResult.tif"; + std::cout << "mode 5: convert ori tiff to power tiff:"; + std::cout << "SIMOrthoProgram.exe 5 in_ori_path out_power_path"; + simProcess process; + process.ori_sar_power(in_ori_path, out_power_path); + return 0; +} + +int test_mode_6() +{ + + return 0; +} + +int test_LLA2XYZ_XYZ2LLA() +{ + std::cout << "===========================================" << endl; + std::cout << "TEST LLA2XYZ and XYZ2LLA " << endl; + bool pass = false; + + Landpoint lla_p{ 30,40,500 }; + Landpoint xyz_p = LLA2XYZ(lla_p); + Landpoint lla_p2 = XYZ2LLA(xyz_p); + + std::cout << "LLA:\t" << lla_p.lon << "," << lla_p.lat << "," << lla_p.ati << endl; + std::cout << "XYZ:\t" << xyz_p.lon << "," << xyz_p.lat << "," << xyz_p.ati << endl; + std::cout<<"LLA2:\t"<< lla_p2.lon << "," << lla_p2.lat << "," << lla_p2.ati << endl; + + pass = (lla_p2.lon-lla_p.lon==0) && (lla_p2.lat- lla_p.lat==0) && (lla_p2.ati-lla_p.ati==0); + std::cout << "TEST LLA2XYZ and XYZ2LLA passed:" << pass << endl; + std::cout << "===========================================" << endl; + return pass?1:0; +} + +int test_vector_operator() +{ + // ???? + return 0; +} diff --git a/simorthoprogram-orth_gf3-strip/test_moudel.h b/simorthoprogram-orth_gf3-strip/test_moudel.h new file mode 100644 index 0000000..3e8638a --- /dev/null +++ b/simorthoprogram-orth_gf3-strip/test_moudel.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +using namespace std; +using namespace Eigen; + +class test_moudel +{ + + + +}; + +int test_main(int mode, string rootpath); +int test_mode_0(); +int test_mode_1(string rootpath); +int test_ASF(string rootpath); +int test_mode_2(); +int test_mode_3(); +int test_mode_4(); +int test_mode_5(); +int test_mode_6(); +int test_mode_7(); +int test_LLA2XYZ_XYZ2LLA(); + +int test_vector_operator(); + diff --git a/simorthoprogram-orth_s_sar-strip/.gitattributes b/simorthoprogram-orth_s_sar-strip/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/simorthoprogram-orth_s_sar-strip/.gitignore b/simorthoprogram-orth_s_sar-strip/.gitignore new file mode 100644 index 0000000..85bed7a --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/.gitignore @@ -0,0 +1,56 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +*.dll + +x64/ +x64/* +.vs/ +.vs/* +/x64/* +/.vs/* +./x64/* +./.vs/* +./x64/* +/x64/* +*.ipch +*.db +*.pdb +*.tlog +*.log +*.pdb +*.db +*.tiff +*.tif +*.jpg + +Temporary*/ \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/ImageMatch.cpp b/simorthoprogram-orth_s_sar-strip/ImageMatch.cpp new file mode 100644 index 0000000..476eacc --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/ImageMatch.cpp @@ -0,0 +1,510 @@ +#pragma once +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include +#include +#include +#include +#include "ImageMatch.h" +#include +#include +using namespace std; +using namespace Eigen; +using namespace cv; +/// +/// cpnvert gdal to jpg +/// +/// +/// +/// +/// +int ImageMatch::gdal2JPG(std::string gdal_path, std::string jpg_path, int band_ids) +{ + std::cout << "convert gdal to jpg , beigining : \t" << getCurrentTimeString() << endl; + gdalImage gdalimg(gdal_path); + cv::Mat img(gdalimg.height, gdalimg.width, CV_8U); + { + + int start_ids = 0; + int line_invert = int(80000000 / gdalimg.width); + Eigen::MatrixXd temp(line_invert, gdalimg.width); + double min_value = 0, temp_min = 0; + double max_value = 0, temp_max = 0; + // 线性拉伸2% + Eigen::MatrixXd hist = gdalimg.getHist(band_ids); + + int count = 0; + int sum_count = gdalimg.height * gdalimg.width; + int rows = hist.rows(); + for (int i = 0; i < rows; i++) { + + if ((count+ hist(i, 1)) / sum_count > 0.01) { + min_value = hist(i, 0); + break; + } + count = count + hist(i, 1); + } + count = 0; + for (int i = rows - 1; i >= 0; i--) { + if ((count + hist(i, 1)) / sum_count > 0.01) { + max_value = hist(i, 0); + break; + } + count = count + hist(i, 1); + } + + // 重新缩放最大值,最小值 + std::cout << "min value :\t" << min_value << "\n"; + std::cout << "max value :\t" << max_value << "\n"; + start_ids = 0; + do { + line_invert = line_invert + start_ids < gdalimg.height ? line_invert : gdalimg.height - start_ids; + + temp = gdalimg.getData(start_ids, 0, line_invert, gdalimg.width, band_ids); + temp = (temp.array() - min_value) * 250 / (max_value - min_value); + for (int i = 0; i < line_invert; i++) { + for (int j = 0; j < gdalimg.width; j++) { + if (temp(i, j) < 0) { temp(i, j) = 0; } + if (temp(i, j) > 250) { temp(i, j) = 250; } + uchar tempvalue = uchar(temp(i, j));; + img.at(i + start_ids, j) = tempvalue; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < gdalimg.height); + cv::Mat result1(gdalimg.height, gdalimg.width, CV_8U); + result1 = img; + //bilateralFilter(img, result1, 10, 80, 50); + vector compression_params; + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); //选择jpeg + compression_params.push_back(100); //在这个填入你要的图片质量 + cv::Mat out = result1; + //cv::resize(img, out, cv::Size(img.cols, img.rows), cv::INTER_AREA); + + cv::imwrite(jpg_path, out, compression_params); + + } + std::cout << "convert gdal to jpg , overing : \t" << getCurrentTimeString() << endl; + std::cout << "=========================================\n"; + std::cout << " convert gdal to jpg :\n"; + std::cout << "input gdal img file path :\t" << gdal_path << "\n"; + std::cout << "input gdal img band :\t" << band_ids << "\n"; + std::cout << "out jpg file path :\t" << jpg_path << "\n"; + std::cout << "=========================================\n"; + return 0; +} + + + +/// +/// 获取模型匹配点 +/// +/// +/// +/// +Eigen::MatrixXd ImageMatch::ImageMatch_ori_sim(std::string ori_power_path, std::string sim_sum_path, int roughSize, int PreciseSize, int scale, int searchSize, int roughStep,int preciseStep) +{ + std::cout << "match point between ori and sim , overing : \t" << getCurrentTimeString() << endl; + std::cout << "match parameters : \n"; + std::cout << "rough match templet size : \t" << roughSize << endl; + std::cout << "Precise match templet size : \t" << PreciseSize << endl; + std::cout << "Precise match wait search size : \t" << searchSize << endl; + std::cout << "Precise match scale : \t" << scale << endl; + std::cout << "Precise match step : \t" << preciseStep << endl; + std::cout << "input ori image path : \t" << ori_power_path << endl; + std::cout << "input sim image path : \t" << sim_sum_path << endl; + + //读取影像 + + + cv::Mat ori = openJPG(ori_power_path); + cv::Mat sim = openJPG(sim_sum_path); + int sim_rows = sim.rows; + int sim_cols = sim.cols; + + int BlockCount = 0; + for (int i = 0; i < sim_rows; i=i+ roughSize) { + for (int j = 0; j < sim_cols; j=j+ roughSize) { + if (i + 2 * roughSize < sim_rows && j + 2 * roughSize < sim_cols) { + BlockCount++; + } + } + } + + Eigen::MatrixXd sim_block(BlockCount,3); + BlockCount = 0; + for (int i = 0; i < sim_rows; i = i + roughSize) { + for (int j = 0; j < sim_cols; j = j + roughSize) { + if (i + 2 * roughSize < sim_rows && j + 2 * roughSize < sim_cols) { + sim_block(BlockCount, 0) = i; + sim_block(BlockCount, 1) = j; + BlockCount++; + } + } + } + + Eigen::MatrixXd Tempmatchpoints(BlockCount, 6); + Tempmatchpoints = Tempmatchpoints.array() * 0; + int count = 0; +#pragma omp parallel for num_threads(8) + for (int ii = 0; ii < BlockCount; ii++) { + int i = sim_block(ii, 0); + int j = sim_block(ii, 1); + cv::Mat templet_mat = sim(Rect(j, i, 2 * roughSize, 2 * roughSize)); + cv::Scalar mean1; + cv::Mat stddevMat; + cv::meanStdDev(templet_mat, mean1, stddevMat); + double minvalue = 0; + double maxvalue = 0; + cv::minMaxLoc(templet_mat, &minvalue, &maxvalue, NULL, NULL);//用于检测矩阵中最大值和最小值的位置 + double sig = (stddevMat.at(0, 0)) / (maxvalue - minvalue); + if (sig >1) { + //continue; + } + + // 构建搜索域 + int search_i = i - 2 * searchSize >= 0 ? i - 2 * searchSize >= 0 : 0; + int search_j = j - 2 * searchSize >= 0 ? j - 2 * searchSize >= 0 : 0; + int len_i = search_i + 4 * searchSize; + int len_j = search_j + 4 * searchSize; + len_i = search_i + len_i < ori.rows ? len_i : ori.rows - search_i - 1; + len_j = search_j + len_j < ori.cols ? len_j : ori.rows - search_j - 1; + cv::Mat serch = ori(Rect(search_j, search_i, len_j, len_i)); + // 检索 + cv::Mat result; + matchTemplate(serch, templet_mat, result, cv::TM_CCOEFF_NORMED); + Point minLoc; + Point maxLoc; + Point matchLoc; + double tempminVal = 100, tempmaxVal = 0; + cv::minMaxLoc(result, &tempminVal, &tempmaxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + double offset_j = maxLoc.x + search_j; + double offset_i = maxLoc.y + search_i; + + //cv::Scalar mean1; + //cv::Mat stddevMat; + //cv::meanStdDev(templet_mat, mean1, stddevMat); + + + Tempmatchpoints(ii, 0) = double(j); //sim_x + Tempmatchpoints(ii, 1) = double(i); //sim_y + Tempmatchpoints(ii, 2) = offset_j; // sim_x + Tempmatchpoints(ii, 3) = offset_i; // sim_y + Tempmatchpoints(ii, 4) = tempmaxVal; // maxVal + Tempmatchpoints(ii, 5) = sig; // maxVal + + std::cout << 100.0*count/ BlockCount<<"\t:\t"<< count << " / " << BlockCount<<"\t" << Tempmatchpoints(ii, 0) << "\t" << Tempmatchpoints(ii, 1) << "\t" << Tempmatchpoints(ii, 2) + << "\t" << Tempmatchpoints(ii, 3) << "\t" << Tempmatchpoints(ii, 4) << "\t" << Tempmatchpoints(ii, 5) << endl; + count++; + } + + //BlockCount = 0; + count = 0; + for (int ii = 0; ii < BlockCount; ii++) { + if (Tempmatchpoints(ii, 4) > 0.7) { + std::cout << Tempmatchpoints(ii, 0) << "\t" << Tempmatchpoints(ii, 1) << "\t" << Tempmatchpoints(ii, 2) + << "\t" << Tempmatchpoints(ii, 3) << "\t" << Tempmatchpoints(ii, 4) << "\t" << Tempmatchpoints(ii, 5) << endl; + //BlockCount++; + count++; + } + } + + + + Eigen::MatrixXd matchpoints(count, 5); + count = 0; + for (int ii = 0; ii < BlockCount; ii++) { + if (Tempmatchpoints(ii, 4) > 0.7) { + matchpoints(count, 0)=Tempmatchpoints(ii, 0); //sim_x + matchpoints(count, 1) = Tempmatchpoints(ii, 1); //sim_y + matchpoints(count, 2) = Tempmatchpoints(ii, 2);// sim_x + matchpoints(count, 3) = Tempmatchpoints(ii, 3);// sim_y + matchpoints(count, 4) = Tempmatchpoints(ii, 4); // maxVal + count++; + } + } + + + /* + // step 1: 粗匹配,分块均匀匹配 + std::cout << "rough match , begining : \t" << getCurrentTimeString() << endl; + double offset_x = 0, offset_y = 0; + cv::Mat mask = sim; + cv::Mat temp_ori = ori; + int offsetcount = 0; + Eigen::MatrixXd matchpoints; + { + int row_count = ori.rows; + int col_count = ori.cols; + int count = 0; + for (int i = roughSize; i < row_count; i = i + roughSize + 500) { // y + for (int j = roughSize; j < col_count; j = j + roughSize + 200) { //x + count = count + 1; + } + } + matchpoints= Eigen::MatrixXd::Zero(count, 5);//ori_x,ori_y,sim_x,sim_y,maxval + + double minVal = 100, maxVal = 0.7; + omp_lock_t lock; + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + omp_init_lock(&lock); // 初始化互斥锁 + count = 0; + int search_count = 0; + #pragma omp parallel for num_threads(8) + for (int i = roughSize; i < row_count; i = i + roughSize+ 500) { // y + double tempminVal = 100, tempmaxVal = 0; + cv::Mat templet_mat; + cv::Mat result; + for (int j = roughSize; j < col_count; j = j + roughSize+ 200) { //x + templet_mat = ori(Rect(j - roughSize, i - roughSize, roughSize, roughSize)); + matchTemplate(sim, templet_mat, result, cv::TM_CCOEFF_NORMED); + //normalize(result, result, 1, 0, cv::NORM_MINMAX); + // 通过函数 minMaxLoc 定位最匹配的位置; + omp_set_lock(&lock); //获得互斥器 + Point minLoc; + Point maxLoc; + Point matchLoc; + cv::minMaxLoc(result, &tempminVal, &tempmaxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + if (tempmaxVal >= maxVal) { + offset_x = maxLoc.x - (j - roughSize); + offset_y = maxLoc.y - (i - roughSize); + //maxVal = tempmaxVal; + + matchpoints(count, 0) = (j - roughSize); //ori_x + matchpoints(count, 1) = (i - roughSize); //ori_y + double temp= maxLoc.x; + matchpoints(count, 2) = temp; // sim_x + temp = maxLoc.y; + matchpoints(count, 3) = temp; // sim_y + matchpoints(count, 4) = tempmaxVal; // maxVal + count = count + 1; + + offsetcount += 1; + } + search_count = search_count + 1; + std::cout << j - roughSize << "\t" << i - roughSize << "\t" << maxLoc.x << "\t" << maxLoc.y << "\t" << tempmaxVal << "\t" << search_count << "\t" << matchpoints.rows() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + } + omp_destroy_lock(&lock); //销毁互斥器 + offset_x = offset_x*1.0 / offsetcount; + offset_y = offset_y * 1.0 / offsetcount; + std::cout << "rough match point : "<< offsetcount <<"\n" << endl; + std::cout << "offset X : \t" << offset_x << endl; + std::cout << "offset Y : \t" << offset_y << endl; + std::cout << "maxVal : \t" << maxVal << endl; + } + std::cout << "rough match out : \t" << getCurrentTimeString() << endl; + // step1.1: 粗匹配绘制结果 + + std::string rough_math_path = sim_sum_path; + boost::algorithm::replace_last(rough_math_path, ".", "_ori_in_sim."); + std::cout << "ori in sim :\t" << rough_math_path << endl; + cv::Mat ori_in_sim = sim; + cv::rectangle(ori_in_sim, cv::Point(offset_x, offset_y), Point(offset_x + ori.cols, offset_y + ori.rows), Scalar(0, 255, 0), 2, 8, 0); + + vector compression_params; + compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); //选择jpeg + compression_params.push_back(100); //在这个填入你要的图片质量 + cv::Mat out = ori_in_sim; + cv::imwrite(rough_math_path, out, compression_params); + + + if (offsetcount == 0) { // 表示全局粗匹配失败,无法进行精校准,考虑直接定位法 + std::cout << "there are not effective point in rought match \t" << endl; + return Eigen::MatrixXd(0, 5); + } + + Eigen::MatrixXd matchpointstemp(offsetcount,5); + for (int i = 0; i < matchpoints.rows(); i++) { + if (matchpoints(i, 4) > 0.7) { + for (int j = 0; j < matchpoints.cols(); j++) { + matchpointstemp(i, j) = matchpoints(i, j); + } + } + } + matchpoints = matchpointstemp; + */ + + + //std::cout << "rough match , overing : \t" << getCurrentTimeString() << endl; + //// step 2: 精匹配, + //std::cout << "Precise match , begining : \t" << getCurrentTimeString() << endl; + //Eigen::MatrixXd matchpoints; + //{ + + // int row_count = ori.rows; + // int col_count = ori.cols; + + // int count = 0; + + // for (int i = PreciseSize; i < row_count; i = i + preciseStep) { // y + // for (int j = PreciseSize; j < col_count; j = j + preciseStep) { //x + // count = count + 1; + // } + // } + + // matchpoints(count, 5);//ori_x,ori_y,sim_x,sim_y,maxval + // double templeta_size = PreciseSize * scale; + // double search_size = searchSize * scale; + // count = 0; + // double ori_start_x, ori_start_y; + // double sim_start_x, sim_start_y; + // row_count = row_count - PreciseSize; + // col_count = col_count - PreciseSize; + // omp_lock_t lock; + // omp_init_lock(&lock); // 初始化互斥锁 + // // 以搜索范围为核心计算 + // #pragma omp parallel for num_threads(8) + // for (int i = searchSize + offset_y; i < row_count; i = i + preciseStep) { // y + // cv::Mat templet_mat; + // cv::Mat search_mat; + // cv::Mat resample_templet_mat; + // cv::Mat resample_search_mat; + // cv::Mat result; + // double minVal = 100, maxVal = 0; + // for (int j = searchSize + offset_x; j < col_count; j = j + preciseStep) { //x + // // 计算 起始点 + // sim_start_x = j - searchSize; + // sim_start_y = i - searchSize; + + // ori_start_x = (j - searchSize / 2) - PreciseSize / 2; + // ori_start_y = (i - searchSize / 2) - PreciseSize / 2; + // // 匹配模板,待匹配模板 + // templet_mat = ori(Rect(ori_start_x, ori_start_y, PreciseSize, PreciseSize)); + // search_mat = ori(Rect(sim_start_x, sim_start_y, searchSize, searchSize)); + + // resample_templet_mat = resampledMat(templet_mat, templeta_size); + // resample_search_mat = resampledMat(search_mat, search_size); + + // matchTemplate(sim, templet_mat, result, cv::TM_CCORR_NORMED); + // // 通过函数 minMaxLoc 定位最匹配的位置; + // cv::Point minLoc; cv::Point maxLoc; + // cv::Point matchLoc; + // cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);//用于检测矩阵中最大值和最小值的位置 + // if (maxVal > 0.7) { + // omp_set_lock(&lock); //获得互斥器 + // + // matchpoints(count, 0) = ori_start_x; //ori_x + // matchpoints(count, 1) = ori_start_y; //ori_y + + // matchpoints(count, 2) = sim_start_x + maxLoc.x * 1.0 / scale; // sim_x + // matchpoints(count, 3) = sim_start_y + maxLoc.y * 1.0 / scale; // sim_y + // matchpoints(count, 4) = maxVal; // maxVal + // count = count + 1; + // + // omp_unset_lock(&lock); //释放互斥器 + // } + // } + // } + // omp_destroy_lock(&lock); //销毁互斥器 + + //} + // + std::cout << "Precise match , ending : \t" << getCurrentTimeString() << endl; + std::cout << "=======================================================================" << endl; + std::cout << "match point result: \t" << getCurrentTimeString() << endl; + std::cout << "=======================================================================" << endl; + + { + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + int count = matchpoints.rows(); + for (int i = 0; i < count; i++) { + std::cout << matchpoints(i, 0) << "\t" << matchpoints(i, 1) << "\t" << matchpoints(i, 2) << "\t" << matchpoints(i, 3) << "\t" << matchpoints(i, 4) << endl; + } + + } + std::cout << "=======================================================================" << endl; + return matchpoints; +} + +Eigen::MatrixXd ImageMatch::CreateMatchModel(Eigen::MatrixXd offsetXY_matrix) +{ + // ori_x,oir_y,to_x,to_y,maxval + // 0 1 2 3 4 + Eigen::MatrixXd offset_x= offsetXY_matrix.col(2) - offsetXY_matrix.col(0); + Eigen::MatrixXd offset_y = offsetXY_matrix.col(3) - offsetXY_matrix.col(1); + // 计算最小二乘法模型 + + Eigen::MatrixXd temp(offset_x.rows(), 6); + temp.col(0) = temp.col(0).array()*0+1; //1 + temp.col(1) = offsetXY_matrix.col(3).array(); // r + temp.col(2) = offsetXY_matrix.col(2).array(); // c + temp.col(3) = offsetXY_matrix.col(3).array().pow(2);//r2 + temp.col(4) = offsetXY_matrix.col(2).array().pow(2);//c2 + temp.col(5) = offsetXY_matrix.col(2).array()* offsetXY_matrix.col(3).array();//r*c + Eigen::MatrixXd matchmodel(2, 6); + Eigen::MatrixXd tempx= temp.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(offset_x);//x c + Eigen::MatrixXd tempy = temp.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(offset_y);//y r + matchmodel.row(1) = tempx; + matchmodel.row(0) = tempy; + return matchmodel; +} + +Eigen::MatrixXd ImageMatch::correctMatchModel(Eigen::MatrixXd r, Eigen::MatrixXd c) +{ + Eigen::MatrixXd a0 = Eigen::MatrixXd::Ones(1,r.cols()); + Eigen::MatrixXd a1 = r.array(); + Eigen::MatrixXd a2 = c.array(); + Eigen::MatrixXd a3 = r.array().pow(2); + Eigen::MatrixXd a4 = c.array().pow(2); + Eigen::MatrixXd a5 = r.array() * c.array(); + + + Eigen::MatrixXd offset(2, r.cols());//r,c + offset.row(0) = r.array() + this->match_model(0, 0) * a0.array() + this->match_model(0, 1) * a1.array() + this->match_model(0, 2) * a2.array() + this->match_model(0, 3) * a3.array() + this->match_model(0, 4) * a4.array() + this->match_model(0, 5) * a5.array(); + offset.row(1) = c.array() + this->match_model(1, 0) * a0.array() + this->match_model(1, 1) * a1.array() + this->match_model(1, 2) * a2.array() + this->match_model(1, 3) * a3.array() + this->match_model(1, 4) * a4.array() + this->match_model(1, 5) * a5.array(); + + return offset; +} + +int ImageMatch::outMatchModel(std::string matchmodel_path) +{ + ofstream fout(matchmodel_path, ios::trunc); + fout << "model:" << endl; + fout << this->match_model(0, 0) << " " << this->match_model(0, 1) << " " << this->match_model(0, 2) << " " << this->match_model(0, 3) << " " << this->match_model(0, 4) << " " << this->match_model(0, 5) << endl; + fout << this->match_model(1, 0) << " " << this->match_model(1, 1) << " " << this->match_model(1, 2) << " " << this->match_model(1, 3) << " " << this->match_model(1, 4) << " " << this->match_model(1, 5) << endl; + fout << "model_points:" << endl; + std::cout << "ori_x\tori_y\tsim_x\tsim_y\tmaxval \t" << endl; + int count = this->offsetXY_matrix.rows(); + for (int i = 0; i < count; i++) { + std::cout << this->offsetXY_matrix(i, 0) << "\t" << this->offsetXY_matrix(i, 1) << "\t" << this->offsetXY_matrix(i, 2) << "\t" << this->offsetXY_matrix(i, 3) << "\t" << this->offsetXY_matrix(i, 4) << endl; + } + fout.close(); + return 0; +} + +/// +/// 读取jpg 文件 +/// +/// +/// +cv::Mat openJPG(std::string jpg_path) +{ + cv::Mat image = cv::imread(jpg_path); + if (image.data == nullptr) //nullptr是c++11新出现的空指针常量 + { + throw new exception("图片文件不存在"); + } + return image; +} + +cv::Mat resampledMat(cv::Mat& image, int targetSize, int interpolation) +{ + cv::Mat out; + cv::resize(image, out, cv::Size(targetSize, targetSize), interpolation); + return out; +} diff --git a/simorthoprogram-orth_s_sar-strip/ImageMatch.h b/simorthoprogram-orth_s_sar-strip/ImageMatch.h new file mode 100644 index 0000000..0ec0a56 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/ImageMatch.h @@ -0,0 +1,39 @@ +#pragma once +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include +#include +#include +#include + +using namespace std; +using namespace Eigen; +class ImageMatch +{ +public: + int gdal2JPG(std::string gdal_path,std::string jpg_path,int band_ids); + Eigen::MatrixXd ImageMatch_ori_sim(std::string ori_power_path, std::string sim_sum_path, int roughSize=500, int Precise=300,int scale=5, int searchSize=1000,int roughStep=400 ,int preciseStep=300); + Eigen::MatrixXd CreateMatchModel(Eigen::MatrixXd offsetXY_matrix); + + Eigen::MatrixXd correctMatchModel(Eigen::MatrixXd r, Eigen::MatrixXd c); + + int outMatchModel(std::string matchmodel_path); + //参数 + Eigen::MatrixXd offsetXY_matrix; + Eigen::MatrixXd match_model; +}; + +cv::Mat openJPG(std::string jpg_path); +cv::Mat resampledMat(cv::Mat& templet, int targetSize, int interpolation = cv::INTER_AREA); diff --git a/simorthoprogram-orth_s_sar-strip/OctreeNode.cpp b/simorthoprogram-orth_s_sar-strip/OctreeNode.cpp new file mode 100644 index 0000000..027e74e --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/OctreeNode.cpp @@ -0,0 +1 @@ +#include "OctreeNode.h" diff --git a/simorthoprogram-orth_s_sar-strip/OctreeNode.h b/simorthoprogram-orth_s_sar-strip/OctreeNode.h new file mode 100644 index 0000000..4378f3f --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/OctreeNode.h @@ -0,0 +1,264 @@ +#pragma once +#include +using namespace std; +//定义八叉树节点类 +template +struct OctreeNode +{ + T data; //节点数据 + T xmin, xmax; //节点坐标,即六面体个顶点的坐标 + T ymin, ymax; + T zmin, zmax; + OctreeNode * top_left_front, * top_left_back; //该节点的个子结点 + OctreeNode * top_right_front, * top_right_back; + OctreeNode * bottom_left_front, * bottom_left_back; + OctreeNode * bottom_right_front, * bottom_right_back; + OctreeNode //节点类 + (T nodeValue = T(), + T xminValue = T(), T xmaxValue = T(), + T yminValue = T(), T ymaxValue = T(), + T zminValue = T(), T zmaxValue = T(), + OctreeNode* top_left_front_Node = NULL, + OctreeNode* top_left_back_Node = NULL, + OctreeNode* top_right_front_Node = NULL, + OctreeNode* top_right_back_Node = NULL, + OctreeNode* bottom_left_front_Node = NULL, + OctreeNode* bottom_left_back_Node = NULL, + OctreeNode* bottom_right_front_Node = NULL, + OctreeNode* bottom_right_back_Node = NULL) + :data(nodeValue), + xmin(xminValue), xmax(xmaxValue), + ymin(yminValue), ymax(ymaxValue), + zmin(zminValue), zmax(zmaxValue), + top_left_front(top_left_front_Node), + top_left_back(top_left_back_Node), + top_right_front(top_right_front_Node), + top_right_back(top_right_back_Node), + bottom_left_front(bottom_left_front_Node), + bottom_left_back(bottom_left_back_Node), + bottom_right_front(bottom_right_front_Node), + bottom_right_back(bottom_right_back_Node) {} +}; +//创建八叉树 +template +void createOctree(OctreeNode*& root, int maxdepth, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) +{ + //cout<<"处理中,请稍候……"<= 0) + { + root = new OctreeNode(); + //cout << "请输入节点值:"; + //root->data =9;//为节点赋值,可以存储节点信息,如物体可见性。由于是简单实现八叉树功能,简单赋值为9。 + cin >> root->data; //为节点赋值 + root->xmin = xmin; //为节点坐标赋值 + root->xmax = xmax; + root->ymin = ymin; + root->ymax = ymax; + root->zmin = zmin; + root->zmax = zmax; + double xm = (xmax - xmin) / 2;//计算节点个维度上的半边长 + double ym = (ymax - ymin) / 2; + double zm = (ymax - ymin) / 2; + //递归创建子树,根据每一个节点所处(是几号节点)的位置决定其子结点的坐标。 + createOctree(root->top_left_front, maxdepth, xmin, xmax - xm, ymax - ym, ymax, zmax - zm, zmax); + createOctree(root->top_left_back, maxdepth, xmin, xmax - xm, ymin, ymax - ym, zmax - zm, zmax); + createOctree(root->top_right_front, maxdepth, xmax - xm, xmax, ymax - ym, ymax, zmax - zm, zmax); + createOctree(root->top_right_back, maxdepth, xmax - xm, xmax, ymin, ymax - ym, zmax - zm, zmax); + createOctree(root->bottom_left_front, maxdepth, xmin, xmax - xm, ymax - ym, ymax, zmin, zmax - zm); + createOctree(root->bottom_left_back, maxdepth, xmin, xmax - xm, ymin, ymax - ym, zmin, zmax - zm); + createOctree(root->bottom_right_front, maxdepth, xmax - xm, xmax, ymax - ym, ymax, zmin, zmax - zm); + createOctree(root->bottom_right_back, maxdepth, xmax - xm, xmax, ymin, ymax - ym, zmin, zmax - zm); + } +} +int i = 1; +//先序遍历八叉树 +template +void preOrder(OctreeNode*& p) +{ + if (p) + { + //cout << i << ".当前节点的值为:" << p->data << "\n坐标为:"; + //cout << "xmin: " << p->xmin << " xmax: " << p->xmax; + //cout << "ymin: " << p->ymin << " ymax: " << p->ymax; + //cout << "zmin: " << p->zmin << " zmax: " << p->zmax; + i += 1; + cout << endl; + preOrder(p->top_left_front); + preOrder(p->top_left_back); + preOrder(p->top_right_front); + preOrder(p->top_right_back); + preOrder(p->bottom_left_front); + preOrder(p->bottom_left_back); + preOrder(p->bottom_right_front); + preOrder(p->bottom_right_back); + cout << endl; + } +} +//求八叉树的深度 +template +int depth(OctreeNode*& p) +{ + if (p == NULL) + return -1; + int h = depth(p->top_left_front); + return h + 1; +} +template +int num(OctreeNode*& p) +{ + if (p == NULL) + return 0; + return 1 + num(p->top_left_front) + num(p->top_left_back) + num(p->top_right_back) + num(p->top_right_front) + num(p->bottom_left_back) + num(p->bottom_left_front) + num(p->bottom_right_back) + num(p->bottom_right_front); +} +//计算单位长度,为查找点做准备 +int cal(int num) +{ + int result = 1; + if (1 == num) + result = 1; + else + { + for (int i = 1; i < num; i++) + result = 2 * result; + } + return result; +} + +template +int find(OctreeNode*& p, double x, double y, double z) +{ + //查找点 + int maxdepth = 0; + int times = 0; + static double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0; + int tmaxdepth = 0; + double txm = 1, tym = 1, tzm = 1; + + double xm = (p->xmax - p->xmin) / 2; + double ym = (p->ymax - p->ymin) / 2; + double zm = (p->ymax - p->ymin) / 2; + times++; + if (x > xmax || xymax || yzmax || z < zmin) + { + //cout << "该点不在场景中!" << endl; + return 0; + } + if (x <= p->xmin + txm && x >= p->xmax - txm && y <= p->ymin + tym && y >= p->ymax - tym && z <= p->zmin + tzm && z >= p->zmax - tzm) + { + //cout << endl << "找到该点!" << "该点位于" << endl; + //cout << "xmin: " << p->xmin << " xmax: " << p->xmax; + //cout << "ymin: " << p->ymin << " ymax: " << p->ymax; + //cout << "zmin: " << p->zmin << " zmax: " << p->zmax; + //cout << "节点内!" << endl; + //cout << "共经过" << times << "次递归!" << endl; + return 1; + } + else if (x < (p->xmax - xm) && y < (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_left_back, x, y, z); + } + else if (x < (p->xmax - xm) && y<(p->ymax - ym) && z>(p->zmax - zm)) + { + find(p->top_left_back, x, y, z); + } + else if (x > (p->xmax - xm) && y < (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_right_back, x, y, z); + } + else if (x > (p->xmax - xm) && y<(p->ymax - ym) && z>(p->zmax - zm)) + { + find(p->top_right_back, x, y, z); + } + else if (x<(p->xmax - xm) && y>(p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_left_front, x, y, z); + } + else if (x<(p->xmax - xm) && y>(p->ymax - ym) && z > (p->zmax - zm)) + { + find(p->top_left_front, x, y, z); + } + else if (x > (p->xmax - xm) && y > (p->ymax - ym) && z < (p->zmax - zm)) + { + find(p->bottom_right_front, x, y, z); + } + else if (x > (p->xmax - xm) && y > (p->ymax - ym) && z > (p->zmax - zm)) + { + find(p->top_right_front, x, y, z); + } +} +//main函数 +/* +int main() +{ + OctreeNode* rootNode = NULL; + int choiced = 0; + cout << "系统开始前请先创建八叉树" << endl; + cout << "请输入最大递归深度:" << endl; + cin >> maxdepth; + cout << "请输入外包盒坐标,顺序如下:xmin,xmax,ymin,ymax,zmin,zmax" << endl; + cin >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax; + if (maxdepth >= 0 || xmax > xmin || ymax > ymin || zmax > zmin || xmin > 0 || ymin > 0 || zmin > 0) + { + tmaxdepth = cal(maxdepth); + txm = (xmax - xmin) / tmaxdepth; + tym = (ymax - ymin) / tmaxdepth; + tzm = (zmax - zmin) / tmaxdepth; + createOctree(rootNode, maxdepth, xmin, xmax, ymin, ymax, zmin, zmax); + } + while (true) + { + system("cls"); + + cout << "请选择操作:\n"; + cout << "\t1.计算空间中区域的个数\n"; + cout << "\t2.先序遍历八叉树\n"; + cout << "\t3.查看树深度\n"; + cout << "\t4.查找节点 \n"; + cout << "\t0.退出\n"; + cin >> choiced; + + if (choiced == 0) + return 0; + if (choiced == 1) + { + system("cls"); + cout << "空间区域个数" << endl; + cout << num(rootNode); + } + + if (choiced == 2) + { + system("cls"); + cout << "先序遍历八叉树结果:/n"; + i = 1; + preOrder(rootNode); + cout << endl; + system("pause"); + } + if (choiced == 3) + { + system("cls"); + int dep = depth(rootNode); + cout << "此八叉树的深度为" << dep + 1 << endl; + system("pause"); + } + if (choiced == 4) + { + system("cls"); + cout << "请输入您希望查找的点的坐标,顺序如下:x,y,z\n"; + double x, y, z; + cin >> x >> y >> z; + times = 0; + cout << endl << "开始搜寻该点……" << endl; + find(rootNode, x, y, z); + system("pause"); + } + else + { + system("cls"); + cout << "\n\n错误选择!\n"; + system("pause"); + } + } +*/ \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp new file mode 100644 index 0000000..653016f --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.cpp @@ -0,0 +1,49 @@ +锘// ConsoleApplication1.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + + + +#include +#include +#include +#include + +//#include + +//using namespace arma; +using namespace std; +using namespace Eigen; + +int main(int argc, char* argv[]) +{ + cout << cos(30) << endl; + cout << cos(45) << endl; + cout << cos(60) << endl; + cout << pow(1, 3) << endl; + cout << pow(2, 3) << endl; + + Eigen::MatrixXd a = Eigen::MatrixXd::Ones(6, 3); // 闅忔満鍒濆鍖栫煩闃 + Eigen::MatrixXd b = Eigen::MatrixXd::Ones(6,3).array()*2; + Eigen::Vector3d p(3, 1, 2); + double start = clock(); + Eigen::MatrixXd c = (a.array()/b.array());// .rowwise().sum(); + double endd = clock(); + double thisTime = (double)(endd - start) / CLOCKS_PER_SEC; + + cout << thisTime << endl; + cout << c.rows() << "," << c.cols() << endl; + cout << c(Eigen::all, { 0,1}) << endl; + system("PAUSE"); + return 0; +} + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj new file mode 100644 index 0000000..e8a092c --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {db6d05f9-271e-4954-98ed-591ab27bb05e} + ConsoleApplication1 + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + Parallel + + + + + + + + + + + + + + + + + + + + + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files %28x86%29\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;C:\Program Files %28x86%29\Intel\oneAPI\mkl\2022.1.0\lib\intel64;$(oneMKLOmpLibDir);$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + mkl_scalapack_ilp64.lib;mkl_cdft_core.lib;mkl_intel_ilp64.lib;mkl_sequential.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;impi.lib;mkl_intel_thread.lib;libiomp5md.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters new file mode 100644 index 0000000..18f4605 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.filters @@ -0,0 +1,22 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/ConsoleApplication1/ConsoleApplication1.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp new file mode 100644 index 0000000..490b3e3 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.cpp @@ -0,0 +1,191 @@ +锘// PSTM_simulation_windows.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + +#include +#include +#include +#include +#include +#include +#include "ParameterInFile.h" +#include 銆銆 +#include +// +// 寮曠敤鍙橀噺鐨勭┖闂 +// +using namespace std; + + +int test(ParameterInFile parmas) { + cout << parmas.doppler_para[0] << endl; + return 0; +} + +/// +/// 妫鏌ョ幆澧冿紝涓昏妫鏌ュ唴瀛樻儏鍐 +/// +/// +/// +bool check(ParameterInFile& parmas) { + + return true; +} + +sim_block testsimblock(int a = 1) { + sim_block result(1, 2, 1, 2, 1, 1); + return result; +} + +int Fmaintest() { + sim_block temp = testsimblock(1); + point lla = point{ 110,22,33 }; + point xyz = point{ -2023567.6297546995,5559706.3694903487,2374425.2573203994 }; + point ttxyz = LLA2XYZ(lla); + point ttlla = XYZ2LLA(xyz); + VectorPoint v1 = getVector(xyz, ttxyz); + VectorPoint v2 = getVector(lla, ttlla); + cout << getModule(v1) << std::endl; + cout << getModule(v2) << std::endl; + return 0; +} + + + + +int main(int argc, char* argv[]) +{ + // try { + testPP(); + + + std::cout << "PSTM_simulation_windows.exe [mode] [pars_path] [resample_para] [--thead_num]" << endl;// 杈撳嚭甯姪鏂囨。 + std::cout << "[mode]: 璋冪敤妯″潡 0,1,2 " << endl; + std::cout << " 0:榛樿璺緞 " << endl; + std::cout << " 1:璁$畻姝e皠妯℃嫙鍥 " << endl; + std::cout << " 2:璁$畻姝e皠鏍℃鎻掑肩畻娉曚笌寮哄害鍥剧敓鎴 " << endl; + std::cout << "[para_path]:蹇呴 姝e皠妯℃嫙鍙傛暟鏂囦欢 " << endl; + std::cout << "[resample_para]:褰搈ode==2鏃讹紝蹇呴夛紱 璁$畻姝e皠鏍℃鎻掑肩畻娉曚笌寮哄害鍥剧敓鎴愬弬鏁版枃浠 " << endl; + std::cout << "[--thead_num]:鍙 绾跨▼鏁帮紝榛樿鏄8" << endl; + std::cout << "example:" << endl; + std::cout << "PSTM_simulation_windows.exe 2 C:\\sim_sar_paras.txt D:\\resample_para.txt --thead_num 8" << endl; + int mode = -1; + int thread_num = 6; + std::string pars_path = ""; //閰嶇疆鏂囦欢浠g爜 + std::string resample_para = ""; + std::string thread_str = "--thead_num"; + try { + if (argc < 3) { + std::cout << "缂哄皯鍙傛暟" << endl; + //return 0; + } + for (int i = 1; i < argc; i++) { + if (i == 1) { + mode = stoi(argv[1]); + if (mode == 0) { + pars_path = "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace4\\sim_sar_paras.txt"; + resample_para = "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace4\\resample_para.txt"; + mode = 2; + break; + } + } + if (i == 2) { + pars_path= argv[2]; + } + if (i == 3) { + if (mode == 1) { + break; + } + else { + resample_para = argv[3]; + } + } + } + + for (int i = 1; i < argc; i++) { + std::string temp = argv[i]; + + + if (temp== thread_str) { + i = i + 1; + + if (i >= argc) { break; } + else { + thread_num = stoi(argv[i]); + + } + } + } + } + catch(exception ex) { + std::cout << "鍙傛暟瑙f瀽閿欒" << endl; + // 寮濮媡est妯″紡 + + return -1; + + } + if (1) { + pars_path = "D:\\MicroWorkspace\\C-SAR\\Ortho\\Temporary\\sim_sar_paras.txt"; + resample_para = "";// "D:\\otherSoftware\\Ortho\\Ortho\\ortho_indirect\\datafolder\\testworkspace\\resample_para.txt"; + mode = 1; + } + + std::cout << "绾跨▼鏁帮細" << thread_num << endl; + //Fmaintest(); + + cout << mode << "\n"; + int d=round(3.13); + if (mode == 1) { + cout << "sim_sar program run....\n"; + cout << pars_path << "\n"; + ParameterInFile parmas(pars_path); + //testPTSN(parmas); + if (!check(parmas)) { + throw "涓嶇鍚堣繍琛屾潯浠"; + return 0; + } + //SimProcess(parmas, 32); + SimProcess_LVY(parmas, thread_num); + // ResamplingSim(parmas); + // 妫鏌ヨВ鏋愮粨鏋 + cout << "programover" << "\n"; + } + + else if (mode == 2) { + try { + ConvertResampleParameter converPara(resample_para); + ParameterInFile parmas(pars_path); + testPTSN(pars_path); + SimProcess_Calsim2ori(parmas, converPara, thread_num); + SimProcess_ResamplingOri2Orth(parmas, converPara, thread_num); + SimProcess_Calspow(parmas, converPara, thread_num); + } + catch(exception& ex) { + std::cout << ex.what() << std::endl; + return -1; + } + //SimProcess_CalXYZ(parmas, converPara,16); + //ConverOri2Sim(parmas, converPara); + //CalCoondinaryXYZOfSAR(parmas, converPara); + } + + + // } + //catch (exception ex) { + // 闃叉鍐呭瓨娉勯湶锛屼繚璇佸唴瀛樿兘澶熻璋冪敤 + // throw "error"; + // } + +} + + + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln new file mode 100644 index 0000000..86e7524 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.sln @@ -0,0 +1,41 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32602.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSTM_simulation_windows", "PSTM_simulation_windows.vcxproj", "{418EA1F3-8583-4728-ABC4-45B98FC053BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConsoleApplication1", "..\ConsoleApplication1\ConsoleApplication1.vcxproj", "{DB6D05F9-271E-4954-98ED-591AB27BB05E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x64.ActiveCfg = Debug|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x64.Build.0 = Debug|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x86.ActiveCfg = Debug|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Debug|x86.Build.0 = Debug|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x64.ActiveCfg = Release|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x64.Build.0 = Release|x64 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x86.ActiveCfg = Release|Win32 + {418EA1F3-8583-4728-ABC4-45B98FC053BF}.Release|x86.Build.0 = Release|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x64.ActiveCfg = Debug|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x64.Build.0 = Debug|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x86.ActiveCfg = Debug|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Debug|x86.Build.0 = Debug|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x64.ActiveCfg = Release|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x64.Build.0 = Release|x64 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x86.ActiveCfg = Release|Win32 + {DB6D05F9-271E-4954-98ED-591AB27BB05E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2C843D5-F54A-4745-908B-8387B47D60A3} + EndGlobalSection +EndGlobal diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj new file mode 100644 index 0000000..6a2d7a8 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/PSTM_simulation_windows.vcxproj @@ -0,0 +1,169 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {418ea1f3-8583-4728-abc4-45b98fc053bf} + PSTMsimulationwindows + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + No + + + Application + false + v143 + true + Unicode + Parallel + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + $(ExternalIncludePath) + $(SolutionDir)bin\$(Platform)\$(Configuration) + + + false + $(ExternalIncludePath) + $(LibraryPath) + $(SolutionDir)bin\$(Platform)\$(Configuration) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + MultiThreaded + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + + + Console + true + true + true + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp new file mode 100644 index 0000000..7dfb32e --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.cpp @@ -0,0 +1,2100 @@ +#include "ParameterInFile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +////gdal +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "common.h" + + +using namespace std; +// +// 参数文件解析 +// + +//参数文件标准格式 +// 文件值 类型 对应的代号 +// DEM文件的路径 str dem_path +// 模拟影像输出路径 str sar_sim_path +// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path +// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path +// 采样率 long double sample_f +// 近斜距 long double R0 +// 成像起始时间 long double starttime ---UTC 时间 +// 光速 long double +// 波长 long double +// 多普勒参考时间 long double TO ---UTC 时间 +// 脉冲重复频率 long double PRF +// 斜距采样间隔 long double delta_R +// 多普勒系数个数 int +// 多普勒系数1 long double +// 多普勒系数2 long double +// .... +// 卫星轨道模型是否为多项式模型 +// 卫星轨道模型多项式次数 int 4 5 +// 卫星轨道模型X值系数1 long double +// .... +// 卫星轨道模型Y值系数1 long double +// ... +// 卫星轨道模型Z值系数1 long double +// ... +// 卫星轨道模型Vx值系数1 long double +// ... +// 卫星轨道模型Vy值系数1 long double +// ... +// 卫星轨道模型Vz值系数1 long double +// ... +// +// + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +point XYZ2LLA(point& XYZ) { + long double tmpX = XYZ.x; + long double temY = XYZ.y; + long double temZ = XYZ.z; + + long double curB = 0; + long double N = 0; + long double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + long double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + long double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + point result = { 0,0,0 }; + result.x = atan2(temY, tmpX) * r2d; + result.y = curB * r2d; + result.z = temZ / sinCurB - N * (1 - eSquare); + return result; +} + + +ParameterInFile::ParameterInFile(std::string infile_path) +{ + // 解析文件 + ifstream infile(infile_path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + getline(infile, buf); this->dem_path = buf; + getline(infile, buf); this->out_sar_sim_path = buf; + getline(infile, buf); this->out_sar_sim_dem_path = buf; + getline(infile, buf); this->out_sar_sim_resampling_path = buf; + getline(infile, buf); this->out_sar_sim_resampling_rc = buf; + getline(infile, buf); this->sim_height = stoi(buf); + getline(infile, buf); this->sim_width = stoi(buf); + getline(infile, buf); this->sar_sim_match_point_path = buf; + getline(infile, buf); this->sar_sim_match_point_xyz_path = buf; + + getline(infile, buf); this->sample_f = stoi(buf); + getline(infile, buf); this->R0 = stod(buf); + getline(infile, buf); this->LightSpeed = stod(buf); + getline(infile, buf); this->lamda = stod(buf); + getline(infile, buf); this->delta_R = stod(buf); + getline(infile, buf); this->imgStartTime = stod(buf); + getline(infile, buf); this->PRF = stod(buf); + getline(infile, buf); this->delta_t = stod(buf); + getline(infile, buf); this->refrange = stod(buf); + getline(infile, buf); this->widthspace = stod(buf); + getline(infile, buf); cout << buf << endl; + + getline(infile, buf); this->doppler_paramenter_number = stoi(buf); + + // 读取多普勒系数 + this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double)); + if (this->doppler_para) { + for (int i = 0; i < this->doppler_paramenter_number; i++) { + getline(infile, buf); + this->doppler_para[i] = stod(buf); + } + } + else { + throw "内存不足"; + } + // 读取卫星轨道 + getline(infile, buf); this->polySatelliteModel = stoi(buf); + if (this->polySatelliteModel != 1) { + throw "不是多项式轨道模型"; + } + getline(infile, buf); this->polynum = stoi(buf) + 1; // 多项式项数 + getline(infile, buf); this->SatelliteModelStartTime = stod(buf); // 轨道模型起始时间 + + this->polySatellitePara = (long double*)calloc(this->polynum * 6, sizeof(long double)); + if (this->polySatellitePara) { + for (int i = 0; i < this->polynum * 6; i++) { + getline(infile, buf); + this->polySatellitePara[i] = stod(buf); + } + } + else { + throw "内存不足"; + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); +} + +ParameterInFile::ParameterInFile(const ParameterInFile& paras) +{ + //参数组 + this->dem_path = paras.dem_path; + this->out_sar_sim_path = paras.out_sar_sim_path; + this->out_sar_sim_dem_path = paras.out_sar_sim_dem_path; + this->out_sar_sim_resampling_path = paras.out_sar_sim_resampling_path; + this->out_sar_sim_resampling_rc = paras.out_sar_sim_resampling_rc; + this->sim_height = paras.sim_height; + this->sim_width = paras.sim_width; + this->sar_sim_match_point_path = paras.sar_sim_match_point_path; + this->sar_sim_match_point_xyz_path = paras.sar_sim_match_point_xyz_path; + this->sample_f = paras.sample_f; + this->R0 = paras.R0; + this->LightSpeed = paras.LightSpeed; + this->lamda = paras.lamda; + + this->delta_R = paras.delta_R; + this->imgStartTime = paras.imgStartTime; + this->PRF = paras.PRF; + this->delta_t = paras.delta_t; + this->refrange = paras.refrange; + // 多普勒 + this->widthspace = paras.widthspace; + this->doppler_paramenter_number = paras.doppler_paramenter_number; + //卫星轨道模型 + this->polySatelliteModel = paras.polySatelliteModel; + this->polynum = paras.polynum; + this->SatelliteModelStartTime = paras.SatelliteModelStartTime; + this->doppler_para = (long double*)calloc(this->doppler_paramenter_number, sizeof(long double)); + memcpy(this->doppler_para, paras.doppler_para, paras.doppler_paramenter_number * sizeof(long double)); + this->polySatellitePara = (long double*)calloc(paras.polynum * 6, sizeof(long double)); + memcpy(this->polySatellitePara, paras.polySatellitePara, paras.polynum * 6 * sizeof(long double)); +} + +ParameterInFile::~ParameterInFile() +{ + // 析构函数 + free(this->doppler_para); + free(this->polySatellitePara); +} + + +/// +/// 根据卫星轨道模型计算卫星 +/// +/// 卫星轨道点时间 +/// 卫星轨道模型起始时间 +/// 卫星轨道X坐标模型参数 +/// 卫星轨道Y坐标模型参数 +/// 卫星轨道Z坐标模型参数 +/// 卫星轨道Vx坐标模型参数 +/// 卫星轨道Vy坐标模型参数 +/// 卫星轨道Vz坐标模型参数 +/// 多项式项数 +/// +inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4) +{ + satelliteTime = satelliteTime - SatelliteModelStartTime; + SatelliteSpacePoint result_point = { 0,0,0,0,0,0 }; + + if (polynum <= 0)return result_point; + int ptr_indx = 0; + int yStep = polynum; + int zStep = polynum*2; + int vxStep = polynum*3; + int vyStep = polynum*4; + int vzStep = polynum*5; + //x + result_point.x += polySatellitePara[ptr_indx]; + result_point.y += polySatellitePara[ptr_indx + yStep]; + result_point.z += polySatellitePara[ptr_indx + zStep]; + result_point.vx += polySatellitePara[ptr_indx + vxStep]; + result_point.vy += polySatellitePara[ptr_indx + vyStep]; + result_point.vz += polySatellitePara[ptr_indx + vzStep]; + if (polynum == 1)return result_point; + ptr_indx++; + long double powTime = satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 2)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 3)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + if (polynum == 4)return result_point; + ptr_indx++; + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx + yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + ptr_indx++; + if (polynum == 5)return result_point; + for (int i = 5; i < polynum; i++) { + powTime *= satelliteTime; + result_point.x += powTime * polySatellitePara[ptr_indx]; + result_point.y += powTime * polySatellitePara[ptr_indx+ yStep]; + result_point.z += powTime * polySatellitePara[ptr_indx + zStep]; + result_point.vx += powTime * polySatellitePara[ptr_indx + vxStep]; + result_point.vy += powTime * polySatellitePara[ptr_indx + vyStep]; + result_point.vz += powTime * polySatellitePara[ptr_indx + vzStep]; + ptr_indx++; + } + return result_point; +} + +inline SatelliteSpacePoint getSatellitePostion_orange(long double satelliteTime, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4) +{ + satelliteTime = satelliteTime - SatelliteModelStartTime; + SatelliteSpacePoint result_point = { 0,0,0,0,0,0 }; + int ptr_indx = 0; + //x + for (int i = 0; i < polynum; i++) { + result_point.x += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + + //y + for (int i = 0; i < polynum; i++) { + result_point.y += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //z + for (int i = 0; i < polynum; i++) { + result_point.z += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vx + for (int i = 0; i < polynum; i++) { + result_point.vx += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vy + for (int i = 0; i < polynum; i++) { + result_point.vy += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + //vz + for (int i = 0; i < polynum; i++) { + result_point.vz += pow(satelliteTime, i) * polySatellitePara[ptr_indx]; + ptr_indx++; + } + + return result_point; +} + +/// +/// 数值模拟法计算多普勒频移值 +/// 修改时间:2022.07.03 +/// +/// 斜距 +/// 光速 +/// 多普勒参考时间 +/// 多普勒参数 +/// 多普勒频移值 +inline long double calNumericalDopplerValue(long double R, long double LightSpeed, long double refrange, long double* doppler_para, int doppler_paramenter_number) +{ + //R = R * 2 / LightSpeed - T0; + long double result = 0; + result = doppler_para[0]; + R = (R - refrange) * (1000000 / LightSpeed); + for (int i = 1; i < doppler_paramenter_number; i++) { + result =result+ doppler_para[i]*pow(R,i); + } + return result; +} +/// +/// 根据理论模型计算多普勒频移值 +/// +/// 斜距 +/// 波长 +/// 地面->卫星的空间向量 +/// 地面->卫星之间的速度向量 +/// 多普勒频移值 +inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl) +{ + long double result = -2 * (R_sl.x * V_sl.x + R_sl.y * V_sl.y + R_sl.z * V_sl.z) / (lamda * R); + return result; +} + +/// +/// 根据地面点求解对应的sar影像坐标 +/// 修改2022.07.03 +/// +/// 地面点的坐标--地固坐标系 +/// 影片开始成像时间 +/// 波长 +/// 多普勒参考斜距 +/// 光速 +/// 时间间隔 +/// 近斜距 +/// 斜距间隔 +/// 卫星轨道模型时间 +/// 卫星轨道坐标模型参数 +/// 卫星轨道模型项数 +/// 多普勒模型数 +/// 影像坐标(x:行号,y:列号,z:成像时刻) +inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double refrange, long double* doppler_para, long double LightSpeed, long double prf, long double R0, long double widthspace, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum, int doppler_paramenter_number) +{ + long double ti = Starttime; + long double dt = 0.01; + long double R = 0; + long double FdThory1 = 0; + long double FdThory2 = 0; + long double FdNumber = 0; + long double FdTheory_grad = 0; + SatelliteSpacePoint spacepoint{ 0,0,0,0,0,0 }; + VectorPoint R_sl{ 0,0,0 }; + VectorPoint V_sl{ 0,0,0 }; + long double int_time = 0; + long double endfactor = 1e-4;//exp((floor(log10(1/prf))-1)* 2.302585092994046); + long double error = 0; + for (int i = 0; i < 100; i++) { + spacepoint = getSatellitePostion(ti + dt, SatelliteModelStartTime, polySatellitePara, polynum); + R_sl.x = spacepoint.x - landpoint.x; // 卫星->地面坐标 + R_sl.y = spacepoint.y - landpoint.y; // + R_sl.z = spacepoint.z - landpoint.z; + V_sl.x = spacepoint.vx; + V_sl.y = spacepoint.vy; + V_sl.z = spacepoint.vz; + R = getModule(R_sl); + FdThory1 = calTheoryDopplerValue(R, lamda, R_sl, V_sl); + spacepoint = getSatellitePostion(ti, SatelliteModelStartTime, polySatellitePara, polynum); + R_sl.x = spacepoint.x - landpoint.x; + R_sl.y = spacepoint.y - landpoint.y; + R_sl.z = spacepoint.z - landpoint.z; + V_sl.x = spacepoint.vx; + V_sl.y = spacepoint.vy; + V_sl.z = spacepoint.vz; + R = getModule(R_sl); + FdThory2 = calTheoryDopplerValue(R, lamda, R_sl, V_sl); + FdNumber = calNumericalDopplerValue(R, LightSpeed, refrange, doppler_para, doppler_paramenter_number); + FdTheory_grad = (FdThory1 - FdThory2); + error = FdNumber - FdThory2; + int_time = error * dt / FdTheory_grad; + if (abs(error) < endfactor) { + ti = ti + int_time; + break; + } + ti = ti + int_time; + } + point result{ 0,0,0 }; + result.x = (ti - Starttime) * prf; + result.y = (R - R0) / widthspace; + result.z = ti; + return result; +} + + +/// +/// 双线性插值 +/// 11 12 +/// c +/// 21 22 +/// +/// c的x,y坐标以左上角的行列号为起始点 +/// +/// +/// +/// +/// +inline point bilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22) +{ + long double r = 1 - p.x; + long double c = 1 - p.y; + + long double rc = r * c; + long double r_c_1 = r * p.y;// r* (1 - c); + long double r_1_c = p.x * c; //(1 - r) * c; + long double r_1_c_1 = p.x * p.y;// (1 - r)* (1 - c); + // 计算插值结果 + p.x = rc * p11.x + r_c_1 * p12.x + r_1_c * p21.x + r_1_c_1 * p22.x; + p.y = rc * p11.y + r_c_1 * p12.y + r_1_c * p21.y + r_1_c_1 * p22.y; + p.z = rc * p11.z + r_c_1 * p12.z + r_1_c * p21.z + r_1_c_1 * p22.z; + return p; +} + +/// +/// 三次卷积插值 +/// 11 12 13 14 +/// 21 22 23 24 +/// c +/// 31 32 33 34 +/// 41 42 43 44 +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +inline point cubicInterpolation(point& p, point& p11, point& p12, point& p13, point& p14, point& p21, point& p22, point& p23, point& p24, point& p31, point& p32, point& p33, point& p34, point& p41, point& p42, point& p43, point& p44) +{ + long double r = p.x; + long double c = p.y; + long double r1 = r, r2 = r - 1, r3 = 2 - r, r4 = 3 - r; + long double c1 = c, c2 = c - 1, c3 = 2 - c, c4 = 3 - c; + long double wr1 = 4 - 8 * r1 + 5 * r1 * r1 - r1 * r1 * r1; + long double wr2 = 1 - 2 * r2 * r2 + r2 * r2 * r2; + long double wr3 = 1 - 2 * r3 * r3 + r3 * r3 * r3; + long double wr4 = 4 - 8 * r4 + 5 * r4 * r4 - r4 * r4 * r4; + + long double wc1 = 4 - 8 * c1 + 5 * c1 * c1 - c1 * c1 * c1; + long double wc2 = 1 - 2 * c2 * c2 + c2 * c2 * c2; + long double wc3 = 1 - 2 * c3 * c3 + c3 * c3 * c3; + long double wc4 = 4 - 8 * c4 + 5 * c4 * c4 - c4 * c4 * c4; + + long double wr1_wc1 = wr1 * wc1; + long double wr2_wc1 = wr2 * wc1; + long double wr3_wc1 = wr3 * wc1; + long double wr4_wc1 = wr4 * wc1; + + long double wr1_wc2 = wr1 * wc2; + long double wr2_wc2 = wr2 * wc2; + long double wr3_wc2 = wr3 * wc2; + long double wr4_wc2 = wr4 * wc2; + + long double wr1_wc3 = wr1 * wc3; + long double wr2_wc3 = wr2 * wc3; + long double wr3_wc3 = wr3 * wc3; + long double wr4_wc3 = wr4 * wc3; + + long double wr1_wc4 = wr1 * wc4; + long double wr2_wc4 = wr2 * wc4; + long double wr3_wc4 = wr3 * wc4; + long double wr4_wc4 = wr4 * wc4; + + p.x = 0; + p.x = p.x + wr1_wc1 * p11.x + wr1_wc2 * p12.x + wr1_wc3 * p13.x + wr1_wc4 * p14.x; + p.x = p.x + wr2_wc1 * p11.x + wr2_wc2 * p12.x + wr2_wc3 * p13.x + wr2_wc4 * p14.x; + p.x = p.x + wr3_wc1 * p11.x + wr3_wc2 * p12.x + wr3_wc3 * p13.x + wr3_wc4 * p14.x; + p.x = p.x + wr4_wc1 * p11.x + wr4_wc2 * p12.x + wr4_wc3 * p13.x + wr4_wc4 * p14.x; + + p.y = 0; + p.y = p.y + wr1_wc1 * p11.y + wr1_wc2 * p12.y + wr1_wc3 * p13.y + wr1_wc4 * p14.y; + p.y = p.y + wr2_wc1 * p11.y + wr2_wc2 * p12.y + wr2_wc3 * p13.y + wr2_wc4 * p14.y; + p.y = p.y + wr3_wc1 * p11.y + wr3_wc2 * p12.y + wr3_wc3 * p13.y + wr3_wc4 * p14.y; + p.y = p.y + wr4_wc1 * p11.y + wr4_wc2 * p12.y + wr4_wc3 * p13.y + wr4_wc4 * p14.y; + + + p.z = 0; + p.z = p.z + wr1_wc1 * p11.z + wr1_wc2 * p12.z + wr1_wc3 * p13.z + wr1_wc4 * p14.z; + p.z = p.z + wr2_wc1 * p11.z + wr2_wc2 * p12.z + wr2_wc3 * p13.z + wr2_wc4 * p14.z; + p.z = p.z + wr3_wc1 * p11.z + wr3_wc2 * p12.z + wr3_wc3 * p13.z + wr3_wc4 * p14.z; + p.z = p.z + wr4_wc1 * p11.z + wr4_wc2 * p12.z + wr4_wc3 * p13.z + wr4_wc4 * p14.z; + + return p; +} + +// +// GDAL 数组操作---内置函数不进入头文件声明 +// + +float* ReadRasterArray(GDALRasterBand* demBand, int arrayWidth, int arrayHeight, GDALDataType gdal_datatype) { + + + float* result = new float[arrayWidth * arrayHeight]; // 别忘了释放内存 + if (gdal_datatype == GDALDataType::GDT_UInt16) { + unsigned short* temp = (unsigned short*)calloc(arrayHeight * arrayWidth, sizeof(unsigned short)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + short* temp = (short*)calloc(arrayHeight * arrayWidth, sizeof(short)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = (float*)calloc(arrayHeight * arrayWidth, sizeof(float)); + demBand->RasterIO(GF_Read, 0, 0, arrayWidth, arrayHeight, temp, arrayWidth, arrayHeight, gdal_datatype, 0, 0); + for (int i = 0; i < arrayHeight * arrayWidth; i++) { + result[i] = temp[i] * 1.0; + } + free(temp); + } + + return result; +} + + + +int WriteMatchPoint(string path, std::vector* matchps) { + std::cout << "输出匹配文件中:" << path; + fstream f; + //追加写入,在原来基础上加了ios::app + f.open(path, ios::out | ios::app); + for (int i = 0; i < matchps->size(); i++) { + matchPoint matchP = (*matchps)[i]; + //f << matchP.r << "," << matchP.c << "," << matchP.ti << "," << matchP.x << "," << matchP.y << "," << matchP.z << "\n"; + } + f.close(); + std::cout << "输出匹配文件over:" << path; + return 0; +} + + +sim_block::sim_block(int start_row, int end_row, int start_col, int end_col, int height, int width) +{ + this->start_row = start_row; + this->end_row = end_row; + this->start_col = start_col; + this->end_col = end_col; + this->height = height; + this->width = width; + this->size = height * width; + this->block = (short*)calloc(this->size, sizeof(short)); + this->distanceblock = (long double*)calloc(this->size, sizeof(long double)); + this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint)); + for (int i = 0; i < this->size; i++) { + this->distanceblock[i] = -1; + } +} + +/// +/// 深度拷贝 +/// +/// +sim_block::sim_block(const sim_block& sim_blocks) +{ + this->height = sim_blocks.width; + this->width = sim_blocks.height; + this->start_row = sim_blocks.start_row; + this->start_col = sim_blocks.start_col; + this->end_col = sim_blocks.end_col; + this->end_row = sim_blocks.end_row; + this->size = sim_blocks.size; + // 声明块 + this->block = (short*)calloc(this->size, sizeof(short)); + this->distanceblock = (long double*)calloc(this->size, sizeof(long double)); + this->pointblock = (matchPoint*)calloc(this->size, sizeof(matchPoint)); + // 移动并复制块 + memcpy(this->block, sim_blocks.block, this->size * sizeof(short)); + memcpy(this->distanceblock, sim_blocks.distanceblock, this->size * sizeof(long double)); + memcpy(this->pointblock, sim_blocks.pointblock, this->size * sizeof(matchPoint)); + +} + +sim_block::~sim_block() +{ + if (this->block) { + free(this->block); + this->block = NULL; + } + if (this->distanceblock) { + free(this->distanceblock); + this->distanceblock = NULL; + } + if (this->pointblock) { + free(this->pointblock); + this->pointblock = NULL; + } +} + +int sim_block::rowcol2blockids(int row_ids, int col_ids) +{ + if (this->start_row > row_ids && this->end_row <= row_ids && this->start_col > col_ids && this->end_col <= col_ids) { + return -1; + } + int ids = (row_ids - this->start_row) * this->width + col_ids - this->start_col; + return ids; +} + +/// +/// 根据行列号设置指定块的数值 +/// +/// 行号 +/// 列号 +/// 设置的值 +/// +int sim_block::setsimblock(int row_ids, int col_ids, short value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->block[ids] = value; + /* + try { + this->block[ids] = value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + +int sim_block::addsimblock(int row_ids, int col_ids, short value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->block[ids] += value; + /* + try { + this->block[ids] += value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + + +/// +/// 根据行列号,获取指定行列号块的数值 +/// +/// 行号 +/// 列号 +/// +short sim_block::getsimblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + short result; + result = this->block[ids]; + /* + try { + result = this->block[ids]; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return result; +} + +/// +/// 获取模拟坐标对应的点坐标 +/// +/// 行号 +/// 列号 +/// +matchPoint sim_block::getpointblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + throw "坐标错误"; + return matchPoint{ 0,0,0,0,0,0 }; + } + matchPoint result = this->pointblock[ids]; + return result; +} + +/// +/// 设置模拟块对应的点坐标 +/// +/// 行号 +/// 列号 +/// 坐标点 +/// 更新结果 +int sim_block::setpointblock(int row_ids, int col_ids, matchPoint value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { return -1; } + this->pointblock[ids] = value; + return 0; +} + +long double sim_block::getdistanceblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + long double result; + result = this->distanceblock[ids]; + /* + try { + result = this->distanceblock[ids]; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return result; +} + +int sim_block::setdistanceblock(int row_ids, int col_ids, long double value) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + if (ids < 0) { + return -1; + } + this->distanceblock[ids] = value; + /* + try { + this->distanceblock[ids] = value; + } + catch (exception e) { + throw "Error"; + return -1; + } + */ + return 0; +} + + +/// +/// 初始化dem_block +/// +/// +/// +/// +/// +/// +/// +/// +dem_block::dem_block(int all_start_row, int all_start_col, int start_row, int end_row, int start_col, int end_col, int height, int width, int sample_f) +{ + this->all_start_row = all_start_row; + this->all_start_col = all_start_col; + this->start_row = start_row; + this->end_row = end_row; + this->start_col = start_col; + this->end_col = end_col; + this->height = height; + this->width = width; + this->size = height * width; + this->pointblock = (point*)calloc(this->size, sizeof(point)); + this->sample_f = sample_f; +} + +dem_block::dem_block(const dem_block& demblocks) +{ + this->all_start_row = demblocks.all_start_row; + this->all_start_col = demblocks.all_start_col; + this->start_row = demblocks.start_row; + this->end_row = demblocks.end_row; + this->start_col = demblocks.start_col; + this->end_col = demblocks.end_col; + this->height = demblocks.height; + this->width = demblocks.width; + this->size = this->height * this->width; + this->pointblock = (point*)calloc(this->size, sizeof(point)); + this->sample_f = sample_f; + memcpy(this->pointblock, demblocks.pointblock, this->size * sizeof(point)); +} + +dem_block::~dem_block() +{ + if (this->pointblock) { + free(this->pointblock); + this->pointblock = NULL; + //delete this; + } + +} + +/// +/// 重采样dem--三次卷积插值-- 必须在地理坐标系下进行(经纬度) +/// 为了保证采样左右各舍弃了1格 +/// +/// +//dem_block dem_block::resample_dem() +//{ +// int height = this->height -2;//[1,2 ....., n-1,n] +// int width = this->width -2;//[1,2 ....., n-1,n] +// height = height * this->sample_f; //重采样之后的高度 +// width = width * this->sample_f; // 重采样之后的宽度 +// +// int start_row = (this->start_row-1) * this ->sample_f; +// int start_col = (this->start_col-1) * this->sample_f; +// int end_row = (this->end_row-1) * this->sample_f; +// int end_col = (this->end_col-1) * this->sample_f; +// dem_block resample_dem = dem_block(start_row, end_row, start_col, end_col, height, width, this->sample_f); +// +// // 执行dem重采样,采用双曲线插值 +// for (int i = sample_f; i < height; i++) { // 行 从第一行 +// int ori_i_2 = i / sample_f; +// int ori_i_1, ori_i_3, ori_i_4; +// if (ori_i_2 - 1 < 0) { continue; } +// ori_i_1 = ori_i_2 - 1; +// if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; } +// ori_i_3 = ori_i_2 + 1; +// ori_i_4 = ori_i_2 + 2; +// for (int j = sample_f; j < width; j++) { //列 从第一列 +// point p{0,0,0}; +// int ori_j_2 = j / sample_f; +// int ori_j_1, ori_j_3, ori_j_4; +// if (ori_i_2 - 1 < 0) { continue; } +// ori_j_1 = ori_j_2 - 1; +// if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; } +// ori_j_3 = ori_j_2 + 1; +// ori_j_4 = ori_j_2 + 2; +// // 获取插值需要的数据--三次重采样差值 +// p.x = (i % sample_f) * 1.0 / sample_f; p.x = p.x + 1; +// p.y = (j % sample_f) * 1.0 / sample_f; p.y = p.y + 1; +// point p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44; +// // 获取对应节点 +// p11 = this->getpointblock(ori_i_1, ori_j_1); +// p12 = this->getpointblock(ori_i_1, ori_j_2); +// p13 = this->getpointblock(ori_i_1, ori_j_3); +// p14 = this->getpointblock(ori_i_1, ori_j_4); +// p21 = this->getpointblock(ori_i_2, ori_j_1); +// p22 = this->getpointblock(ori_i_2, ori_j_2); +// p23 = this->getpointblock(ori_i_2, ori_j_3); +// p24 = this->getpointblock(ori_i_2, ori_j_4); +// p31 = this->getpointblock(ori_i_3, ori_j_1); +// p32 = this->getpointblock(ori_i_3, ori_j_2); +// p33 = this->getpointblock(ori_i_3, ori_j_3); +// p34 = this->getpointblock(ori_i_3, ori_j_4); +// p41 = this->getpointblock(ori_i_4, ori_j_1); +// p42 = this->getpointblock(ori_i_4, ori_j_2); +// p43 = this->getpointblock(ori_i_4, ori_j_3); +// p44 = this->getpointblock(ori_i_4, ori_j_4); +// p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44); +// // 计算p 对应的行列号 +// resample_dem.setpointblock(i - sample_f, j - sample_f, p); +// } +// } +// +// +// return resample_dem; +//} +/* -------需要优化的方法--------*/ +dem_block dem_block::resample_dem() { + int height = this->height - 2;//[1,2 ....., n-1,n] + int width = this->width - 2;//[1,2 ....., n-1,n] + height = height * this->sample_f; //重采样之后的高度 + width = width * this->sample_f; // 重采样之后的宽度 + + int start_row = (this->start_row - 1) * this->sample_f; + int start_col = (this->start_col - 1) * this->sample_f; + int end_row = (this->end_row - 1) * this->sample_f; + int end_col = (this->end_col - 1) * this->sample_f; + dem_block resample_dem = dem_block(all_start_row,all_start_col,start_row, end_row, start_col, end_col, height, width, this->sample_f); + long double sample_f_1 = 1.0 / sample_f; + // 执行dem重采样,采用双曲线插值 + + int ori_i_2 =0; + int ori_i_1, ori_i_3, ori_i_4; + point p{ 0,0,0 }; + point p11, p12, p13, p14; + + for (int i = sample_f; i < height; i++) { // 行 从第一行 + ori_i_2 = i * sample_f_1; + if (ori_i_2 - 1 < 0) { continue; } + ori_i_1 = ori_i_2 - 1; + if (ori_i_2 + 1 > this->height || ori_i_2 + 2 > this->height) { break; } + ori_i_3 = ori_i_2 + 1; + ori_i_4 = ori_i_2 + 2; + for (int j = sample_f; j < width; j++) { //列 从第一列 + p={ 0,0,0 }; + int ori_j_2 = j * sample_f_1; + int ori_j_1, ori_j_3, ori_j_4; + if (ori_i_2 - 1 < 0) { continue; } + ori_j_1 = ori_j_2 - 1; + if (ori_j_2 + 1 > this->height || ori_j_2 + 2 > this->height) { break; } + ori_j_3 = ori_j_2 + 1; + ori_j_4 = ori_j_2 + 2; + // 获取插值需要的数据--三次重采样差值 + p.x = (i % sample_f) * sample_f_1 + 1; + //p.x = p.x + 1; + p.y = (j % sample_f) * sample_f_1 + 1; + //p.y = p.y + 1; + + // 获取对应节点 + p11 = this->getpointblock(ori_i_2, ori_j_2); + p12 = this->getpointblock(ori_i_2, ori_j_3); + p13 = this->getpointblock(ori_i_3, ori_j_2); + p14 = this->getpointblock(ori_i_3, ori_j_3); + p = bilineadInterpolation(p, p11, p12, p13, p14); // ----- 优化 + // 计算p 对应的行列号 + resample_dem.setpointblock(i - sample_f, j - sample_f, p); + } + } + return resample_dem; +} + + +/// +/// 根据重采样结果获取对应行列号的坡面法式向量( +/// 必须提前调用UpdatePointCoodinarary()方法,保证坐标系为地固坐标系 +/// +/// 行号 +/// 列号 +/// +VectorPoint dem_block::getslopeVector(int row_ids, int col_ids) +{ + if (row_ids == 0 || col_ids == 0 || row_ids > this->height - 1 || col_ids > this->width - 1) { return VectorPoint{ 0,0,0 }; } // 无效值 + VectorPoint result{ 0,0,0 }; + // 计算向量值,注意向量值的计算初值结果 + point p1 = this->getpointblock(row_ids - 1, col_ids); + point p2 = this->getpointblock(row_ids, col_ids - 1); + point p3 = this->getpointblock(row_ids + 1, col_ids); + point p4 = this->getpointblock(row_ids, col_ids + 1); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + result = VectorFork(n24, n31); // 目标向量 + return result; +} + +int dem_block::rowcol2blockids(int row_ids, int col_ids) +{ + return row_ids * this->width + col_ids; +} + + +/// +/// 根据行列号获取对应的点 +/// +/// +/// +/// +point dem_block::getpointblock(int row_ids, int col_ids) +{ + int ids = this->rowcol2blockids(row_ids, col_ids); + //try { + return this->pointblock[ids]; + //} + //catch (exception e) { + //throw "error"; + //return point{ -1,-1,-1 }; + //} +} + +/// +/// 根据行列号更新值 +/// +/// +/// +/// +/// +int dem_block::setpointblock(int row_ids, int col_ids, point& value) +{ + this->pointblock[row_ids * this->width + col_ids]= value; + /* + int ids = this->rowcol2blockids(row_ids, col_ids); + try { + this->pointblock[ids] = value; + } + catch (exception ex) { + throw "error"; + return -1; + } + + */ + return 0; +} + +point dem_block::getpointblock(int ids) +{ + return this->pointblock[ids]; + /*try { + point result = this->pointblock[ids]; + return result; + } + catch (exception e) { + throw "error"; + return point{ -1,-1,-1 }; + }*/ +} + +int dem_block::setpointblock(int ids, point& value) +{ + this->pointblock[ids] = value; + /* + try { + this->pointblock[ids] = value; + } + catch (exception ex) { + throw "error"; + return -1; + } + */ + return 0; +} + +/// +/// 将点坐标由经纬度->地固坐标系 +/// +/// +/// +int dem_block::UpdatePointCoodinarary() +{ + for (int i = 0; i < this->size; i++) { + this->pointblock[i] = LLA2XYZ(this->pointblock[i]); + } + return 0; +} + + + + +ConvertResampleParameter::ConvertResampleParameter(string path) +{ + + // 解析文件 + ifstream infile(path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + getline(infile, buf); this->in_ori_dem_path = buf; + getline(infile, buf); this->ori_sim = buf; + getline(infile, buf); this->out_sar_xyz_path = buf; + getline(infile, buf); this->out_sar_xyz_incidence_path = buf; + getline(infile, buf); this->out_orth_sar_incidence_path = buf; + getline(infile, buf); this->out_orth_sar_local_incidence_path = buf; + getline(infile, buf); this->outFolder_path = buf; + getline(infile, buf); this->file_count = stoi(buf); + this->inputFile_paths = std::vector(this->file_count); + this->outFile_paths = std::vector(this->file_count); + this->outFile_pow_paths = std::vector(this->file_count); + for (int i = 0; i < this->file_count; i++) { + getline(infile, buf); this->inputFile_paths[i] = buf; + getline(infile, buf); this->outFile_paths[i] = buf; + getline(infile, buf); this->outFile_pow_paths[i] = buf; + } + + getline(infile, buf); this->ori2sim_num = stoi(buf); + + this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double)); + for (int i = 0; i < this->ori2sim_num; i++) { + getline(infile, buf); + this->ori2sim_paras[i] = stod(buf); + } + getline(infile, buf); this->sim2ori_num = stoi(buf); + this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double)); + for (int i = 0; i < this->sim2ori_num; i++) { + getline(infile, buf); + this->sim2ori_paras[i] = stod(buf); + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); + + +} + +ConvertResampleParameter::ConvertResampleParameter(const ConvertResampleParameter& para) +{ + this->in_ori_dem_path = para.in_ori_dem_path; + this->ori_sim = para.ori_sim; + this->out_sar_xyz_path = para.out_sar_xyz_path; + this->out_sar_xyz_incidence_path = para.out_sar_xyz_incidence_path; + this->out_orth_sar_incidence_path = para.out_orth_sar_incidence_path; + this->out_orth_sar_local_incidence_path = para.out_orth_sar_local_incidence_path; + this->outFolder_path = para.outFolder_path; + this->file_count = para.file_count; + this->inputFile_paths = std::vector(this->file_count); + this->outFile_paths = std::vector(this->file_count); + this->outFile_pow_paths = std::vector(this->file_count); + for (int i = 0; i < this->file_count; i++) { + this->inputFile_paths[i] = para.inputFile_paths[i]; + this->outFile_paths[i] = para.outFile_paths[i]; + this->outFile_pow_paths[i] = para.outFile_pow_paths[i]; + } + this->ori2sim_num = para.ori2sim_num; + this->ori2sim_paras = (long double*)calloc(this->ori2sim_num, sizeof(long double)); + memcpy(this->ori2sim_paras, para.ori2sim_paras, this->ori2sim_num * sizeof(long double)); + this->sim2ori_num = para.sim2ori_num; + this->sim2ori_paras = (long double*)calloc(this->sim2ori_num, sizeof(long double)); + memcpy(this->sim2ori_paras, para.sim2ori_paras, this->sim2ori_num * sizeof(long double)); +} + +ConvertResampleParameter::~ConvertResampleParameter() +{ + free(this->sim2ori_paras); + free(this->ori2sim_paras); + this->outFile_paths.clear(); + this->outFile_paths.swap(this->outFile_paths); + this->inputFile_paths.clear(); + this->inputFile_paths.swap(this->inputFile_paths); + this->outFile_pow_paths.clear(); + this->outFile_pow_paths.swap(this->outFile_pow_paths); +} + +#include "threadpool.hpp" +//int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount) + +// 插值算法 + + + +/// +/// 分块模拟求解 +/// T0 变更为 refrange, delta_R: widthspace +/// +/// +/// +/// +int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount) +{ + long double Starttime = paras.imgStartTime; + long double lamda = paras.lamda; + long double refrange = paras.refrange; + long double* doppler_para = paras.doppler_para; + long double LightSpeed = paras.LightSpeed; + long double delta_t = paras.delta_t; + long double prf = paras.PRF; + long double R0 = paras.R0; + long double widthspace = paras.widthspace; + long double SatelliteModelStartTime = paras.SatelliteModelStartTime; + long double* polySatellitePara = paras.polySatellitePara; + int sim_sar_width = paras.sim_width; + int sim_sar_height = paras.sim_height; + int polynum = paras.polynum; + int doppler_paramenter_number = paras.doppler_paramenter_number; + + + bool haspoint = true; + for (int i = 0; i < demblock.size; i++) { + point tempPoint = demblock.getpointblock(i); + tempPoint = LLA2XYZ(tempPoint); + // T0 变更为 refrange, delta_R: widthspace + point pixelpoint = PSTN(tempPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number); + if (pixelpoint.x >= -3000-paras.sample_f*5 && pixelpoint.x < paras.sim_height + paras.sample_f * 5 && pixelpoint.y >= -paras.sample_f * 5 && pixelpoint.y < paras.sim_width + paras.sample_f * 5) { + haspoint = false; + break; + } + } + + if (haspoint) { + *Pcount = -1; + return -1; + } + + // dem重采样 + demblock.sample_f = paras.sample_f; + dem_block resample = demblock.resample_dem(); // 重采样的时候经纬度, + resample.UpdatePointCoodinarary(); // 可以优化 + + //声明 + int sim_height = resample.end_row - resample.start_row; + int sim_width = resample.end_col - resample.start_col; + int sim_pixel_count = sim_width * sim_height; + + // 计算对应的行列号 + int ids = 0; + SatelliteSpacePoint satepoint_; + *Pcount = 0; + try { + // 计算间接定位法结果 + for (int i = resample.start_row; i < resample.end_row; i++) { + for (int j = resample.start_col; j < resample.end_col; j++) { + point landPoint = resample.getpointblock(i, j); + point pixelpoint = PSTN(landPoint, Starttime, lamda, refrange, doppler_para, LightSpeed, prf, R0, widthspace, SatelliteModelStartTime, polySatellitePara, polynum, doppler_paramenter_number); + point temppoint{ round(pixelpoint.x),round(pixelpoint.y),pixelpoint.z }; + if (temppoint.x < -3000 || temppoint.x >= paras.sim_height || temppoint.y < 0 || temppoint.y >= paras.sim_width) { + continue; + } + VectorPoint n = resample.getslopeVector(i, j); + satepoint_ = getSatellitePostion(pixelpoint.z, SatelliteModelStartTime, polySatellitePara, polynum); + point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标 + IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n); + if (pixelIncidence.localincidenceAngle >= 0 && pixelIncidence.localincidenceAngle <= 1) + { + matchPoint matchp{ temppoint.x, temppoint.y, pixelpoint.z,0,0,0,0,pixelIncidence.incidenceAngle,pixelIncidence.localincidenceAngle}; + result_shared[ids] = matchp; + *Pcount = *Pcount + 1; + ids = ids + 1; + } + } + } + return 0; + } + catch (exception e) { + //free(pixelpoints); + throw "计算错误"; + return -1; + } +} + +static std::mutex s_sim_dem_Mutex; //数据锁 +void taskFunc(ParameterInFile& paras, int dem_block_size, int width, short* sim_dem, int count_cure, int count_sum, + int i, int j, int block_height, int block_width, int end_row_ex, int end_col_ex, float* demarray, translateArray& gtt, translateArray& inv_gtt) +{ + //dem_block *demblock, + int Pcount = 0; + dem_block* demblock = new dem_block(i - 3, j - 3, 3, block_height - 3, 3, block_width - 3, block_height, block_width, paras.sample_f);// 构建块结构 + for (int ii = i - 3; ii < end_row_ex; ii++) { + for (int jj = j - 3; jj < end_col_ex; jj++) { + // 构建点集 + int dem_ids = ii * width + jj; + point tempPoint = Translation(ii, jj, demarray[dem_ids], gtt); + demblock->setpointblock(ii - i + 3, jj - j + 3, tempPoint); + } + } + + matchPoint* result_shared = (matchPoint*)calloc((dem_block_size + 7) * (dem_block_size + 7) * paras.sample_f * paras.sample_f, sizeof(matchPoint)); + int nRet= SimProcessBlock(*demblock, paras,result_shared, &Pcount); + + int tempstate = Pcount; + + int row_ids = 0; + int col_ids = 0; + int ids = 0; + matchPoint* pixelpoint = NULL; + { + //std::lock_guard guard(s_sim_dem_Mutex); + s_sim_dem_Mutex.lock(); + for (int ii = 0; ii < tempstate; ii++) { + pixelpoint = &result_shared[ii]; + row_ids = int(pixelpoint->r)+3000; + col_ids = int(pixelpoint->c); + ids = row_ids *paras.sim_width + col_ids; + sim_dem[ids] ++; + } + s_sim_dem_Mutex.unlock(); + } + //根据匹配结果,尝试计算插值结果 + delete demblock; + free(result_shared); + +} + + +void taskFunc_Calsim2ori(ParameterInFile& paras, ConvertResampleParameter& conveparas, + int start_row, int end_row, int start_col, int end_col, + int dem_width,int dem_height, + float* sar_local_angle, float* sar_angle, float* sar_dem_x, float* sar_dem_y, + float* demarray, translateArray& gtt, translateArray& inv_gtt) +{ + /* + // 计算向量值,注意向量值的计算初值结果 + point p1 = this->getpointblock(row_ids - 1, col_ids); + point p2 = this->getpointblock(row_ids, col_ids - 1); + point p3 = this->getpointblock(row_ids + 1, col_ids); + point p4 = this->getpointblock(row_ids, col_ids + 1); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + result = // 目标向量 + */ + double templocalincidenceAngle = 0; + double tempincidenceAngle = 0; + double templocalincidenceAngle1 = 0; + double tempincidenceAngle1 = 0; + for (int i = start_row; i <= end_row; i++) { + if (i - 1 < 0 || i + 1 >= dem_height) { + continue; + } + for (int j = start_col; j <= end_col; j++) { + if (j - 1 < 0 || j + 1 >= dem_width) { + continue; + } + int dem_ids = i * dem_width + j; + point landPoint = Translation(i, j, demarray[dem_ids], gtt); + landPoint =LLA2XYZ(landPoint); + point pixelpoint = PSTN(landPoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + long double r, c; // 结果的行列号 + sim2ori(pixelpoint.x, pixelpoint.y, r, c, conveparas.sim2ori_paras); // 计算得到的行列号 --> + + // 计算向量1 + dem_ids = (i - 1) * dem_width + j; point p1 = Translation(i - 1, j, demarray[dem_ids], gtt); p1 = LLA2XYZ(p1); + dem_ids = i * dem_width + (j - 1); point p2 = Translation(i, j - 1, demarray[dem_ids], gtt); p2 = LLA2XYZ(p2); + dem_ids = (i + 1) * dem_width + j; point p3 = Translation(i + 1, j, demarray[dem_ids], gtt); p3 = LLA2XYZ(p3); + dem_ids = i * dem_width + (j + 1); point p4 = Translation(i, j + 1, demarray[dem_ids], gtt); p4 = LLA2XYZ(p4); + VectorPoint n24 = getVector(p2, p4); + VectorPoint n31 = getVector(p3, p1); + VectorPoint n = VectorFork(n24, n31); + + long double satelliteTime =r / paras.PRF + paras.imgStartTime;// pixelpoint.z;// + SatelliteSpacePoint satepoint_ = getSatellitePostion(satelliteTime, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum); + point satepoint{ satepoint_.x,satepoint_.y,satepoint_.z };//卫星坐标 + IncidenceAngle pixelIncidence = calIncidence(satepoint, landPoint, n); + + dem_ids = i * dem_width + j; + sar_local_angle[dem_ids] = acos(pixelIncidence.localincidenceAngle) * r2d; + sar_angle[dem_ids] =90- acos(pixelIncidence.incidenceAngle) * r2d; + + sar_dem_x[dem_ids] = r; + sar_dem_y[dem_ids] = c; + } + } + //std::cout << "\r" << end_row << "/" << dem_height << "," << end_col << "/" << dem_width << "," << end_row*100.0 * end_col / (dem_width * dem_height) << " ------------------"; +} + +int SimProcess_LVY(ParameterInFile paras, int thread_num) +{ + std::cout << "begin time:" << getCurrentTimeString() << std::endl; + GDALAllRegister();// 注册格式的驱动 + // 打开DEM影像 + GDALDataset* demDataset = (GDALDataset*)(GDALOpen(paras.dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int width = demDataset->GetRasterXSize(); + int height = demDataset->GetRasterYSize(); + int nCount = demDataset->GetRasterCount(); + + double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + + demDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double* inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = demDataset->GetProjectionRef(); + GDALRasterBand* demBand = demDataset->GetRasterBand(1); + float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype); + int dem_pixel_count = width * height; + int psize = (paras.sim_height+3000) * paras.sim_width; + short* sim_dem = (short*)calloc(psize, sizeof(short)); + + + //// 计算每个块的尺寸 + int dem_block_size = int(ceil(sqrt(10*1024* 1024 / (paras.sample_f* paras.sample_f *sizeof(gdal_datatype))))); // 获取每块dem的尺寸 + + //构建内存储空间对象 +// try { + int a = 2; + + int i = 3; + int j = 3; + int thread_ids = 0; + bool hasfullpool = false; + int count_sum = height * width / (dem_block_size * dem_block_size); + int count_cure = 0; + + // 标志文件是否正在写出 + //bool outmatchpointing = false; + //std::vector outmatchpointthread(0); + int tempstate = 0; + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + int start_row =0; + int start_col =0; + + int end_row = 0; + int end_col = 0; + // 扩充 + int end_row_ex = 0; + int end_col_ex = 0; + + int block_height = 0; + int block_width = 0; + while (i < height - 1) { + j = 3; + while (j < width - 1) + { + count_cure++; + // 计算起始行列数 + start_row = i; + start_col = j; + + end_row = start_row + dem_block_size; + end_col = start_col + dem_block_size; + // 扩充 + end_row_ex = end_row + 3; + end_col_ex = end_col + 3; + + if (end_row_ex > height) { + end_row = height - 3; + end_row_ex = height; + } + if (end_col_ex > width) { + end_col = width - 3; + end_col_ex = width; + } + + block_height = end_row - start_row + 6; + block_width = end_col - start_col + 6; + poolPtr->append(std::bind(taskFunc, paras, dem_block_size, width, sim_dem, count_cure, count_sum, + i, j, block_height, block_width, end_row_ex, end_col_ex, demarray, gtt, inv_gtt)); + thread_ids++; + j = j + dem_block_size; + } + i = i + dem_block_size; + } + + std::cout << "SimProcess doing"<waiteFinish(); + // 输出文件 + std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl; + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + const char* out_sar_sim = paras.out_sar_sim_path.c_str(); + + GDALDataset* poDstDS = poDriver->Create(out_sar_sim, paras.sim_width, paras.sim_height + 3000, 1, GDT_Int16, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, paras.sim_width, paras.sim_height + 3000, sim_dem, paras.sim_width, paras.sim_height + 3000, GDT_Int16, 0, 0); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + free(sim_dem); + GDALClose(demDataset); + delete demarray; + std::cout << "输出成果文件-over" << std::endl; + + std::cout << "end time:" << getCurrentTimeString() << std::endl; + return 0; +} + +int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num) +{ + std::cout << "begin time:" << getCurrentTimeString() << std::endl; + GDALAllRegister();// 注册格式的驱动 + // 打开DEM影像 + GDALDataset* demDataset = (GDALDataset*)(GDALOpen(conveparas.in_ori_dem_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int width = demDataset->GetRasterXSize(); + int height = demDataset->GetRasterYSize(); + int nCount = demDataset->GetRasterCount(); + double* gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + demDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = demDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = demDataset->GetProjectionRef(); + GDALRasterBand* demBand = demDataset->GetRasterBand(1); + float* demarray = ReadRasterArray(demBand, width, height, gdal_datatype); + int dem_pixel_count = width * height; + int psize = width * height; + float* sar_local_angle = (float*)calloc(psize, sizeof(float)); + float* sar_angle = (float*)calloc(psize, sizeof(float)); + float* sar_dem_x = (float*)calloc(psize, sizeof(float)); + float* sar_dem_y = (float*)calloc(psize, sizeof(float)); + + for (int i = 0; i < psize; i++) { + sar_dem_x[i] = -100000; + sar_dem_y[i] = -100000; + sar_local_angle[i] = -9999; + sar_angle[i] = -9999; + } + + int blocksize =1000 ; // 获取每块dem的尺寸 + int tempstate = 0; + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + for (int start_row = 1; start_row = height-2 )? height-2 : (start_row + blocksize); + + for(int start_col =1; start_col < width -2;) + { + int end_col = (start_col + blocksize >= width-2) ? width-2 : (start_col + blocksize); + + poolPtr->append(std::bind(taskFunc_Calsim2ori, paras, conveparas, + start_row, end_row, start_col, end_col,width, height, + sar_local_angle,sar_angle, sar_dem_x,sar_dem_y, + demarray, gtt, inv_gtt)); + start_col = end_col; + } + start_row = end_row; + } + + std::cout << "doing...." << std::endl; + poolPtr->waiteFinish(); + // 输出文件; + + std::cout << "输出成果文件:" << getCurrentTimeString() << std::endl; + + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + const char* out_sar_sim = paras.out_sar_sim_path.c_str(); + + poolPtr->stop(); + GDALClose(demDataset); + + delete demarray, demBand, subthreadPool; + + out_sar_sim = conveparas.ori_sim.c_str(); + GDALDataset* poDstDS = poDriver->Create(out_sar_sim, width, height, 2, GDT_Float32, NULL); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_x, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-100000); + poDstDS->GetRasterBand(2)->RasterIO(GF_Write, 0, 0, width, height, sar_dem_y, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(2)->SetNoDataValue(-100000); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + poDstDS = poDriver->Create(conveparas.out_orth_sar_local_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_local_angle, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + poDstDS = poDriver->Create(conveparas.out_orth_sar_incidence_path.c_str(), width, height, 1, GDT_Float32, NULL); + poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, sar_angle, width, height, GDT_Float32, 0, 0); + poDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poDstDS->SetGeoTransform(gt); + poDstDS->SetProjection(Projection); + GDALFlushCache(poDstDS); + GDALClose(poDstDS); + + std::cout << "输出成果文件-over" << std::endl; + + std::cout << "end time:" << getCurrentTimeString() << std::endl; + free(sar_dem_x); + free(sar_dem_y); + free(sar_local_angle); + free(sar_angle); + free(gt); + free(inv_gt); + return 0; +} + +/* +11 12 13 14 +21 22 23 24 +31 32 33 34 +41 42 43 44 +*/ +//分块重采样 +int orth_ReSampling(int start_row,int end_row,int start_col,int end_col, + int width,int height,int ori_width,int ori_height , + float* ori_array, float* result_arr, float* ori_r_array, float* ori_c_array) { + for (int i = start_row; i < end_row; i++) { + for (int j = start_col; j < end_col; j++) { + int ori_ids = i * width + j; + int p_ids = 0; + point p{ ori_r_array[ori_ids] ,ori_c_array[ori_ids],0 }; + point p22 { floor(ori_r_array[ori_ids]),floor(ori_c_array[ori_ids]),0 }; + if (p22.x < 0 || p22.y < 0 || p22.x >= ori_height - 1 || p22.y >= ori_width - 1) { + continue; + } + else if (p22.x < 1 || p22.y < 1 || p22.x >= ori_height - 2 || p22.y >= ori_width - 2) { + //双线性 + point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids]; + point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids]; + point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids]; + p.x = p.x - p22.x; + p.y = p.y - p22.y; + p=bilineadInterpolation(p, p22, p23, p32, p33); + result_arr[ori_ids] = p.z; + } + else { // p22.x >= 1 && p22.y >= 1 && p22.x < ori_height - 2&& p22.y < ori_width - 2 + // 三次 + point p11{ p22.x - 1,p22.y - 1,0 }; p_ids = p11.x * ori_width + p11.y; p11.z = ori_array[p_ids]; + point p12{ p22.x - 1,p22.y ,0 }; p_ids = p12.x * ori_width + p12.y; p12.z = ori_array[p_ids]; + point p13{ p22.x - 1,p22.y + 1,0 }; p_ids = p13.x * ori_width + p13.y; p13.z = ori_array[p_ids]; + point p14{ p22.x - 1,p22.y + 2,0 }; p_ids = p14.x * ori_width + p14.y; p14.z = ori_array[p_ids]; + + point p21{ p22.x ,p22.y - 1,0 }; p_ids = p21.x * ori_width + p21.y; p21.z = ori_array[p_ids]; + point p23{ p22.x ,p22.y + 1,0 }; p_ids = p23.x * ori_width + p23.y; p23.z = ori_array[p_ids]; + point p24{ p22.x ,p22.y + 2,0 }; p_ids = p24.x * ori_width + p24.y; p24.z = ori_array[p_ids]; + + point p31{ p22.x + 1,p22.y - 1,0 }; p_ids = p31.x * ori_width + p31.y; p31.z = ori_array[p_ids]; + point p32{ p22.x + 1,p22.y ,0 }; p_ids = p32.x * ori_width + p32.y; p32.z = ori_array[p_ids]; + point p33{ p22.x + 1,p22.y + 1,0 }; p_ids = p33.x * ori_width + p33.y; p33.z = ori_array[p_ids]; + point p34{ p22.x + 1,p22.y + 2,0 }; p_ids = p34.x * ori_width + p34.y; p34.z = ori_array[p_ids]; + + point p41{ p22.x + 2,p22.y - 1,0 }; p_ids = p41.x * ori_width + p41.y; p41.z = ori_array[p_ids]; + point p42{ p22.x + 2,p22.y ,0 }; p_ids = p42.x * ori_width + p42.y; p42.z = ori_array[p_ids]; + point p43{ p22.x + 2,p22.y + 1,0 }; p_ids = p43.x * ori_width + p43.y; p43.z = ori_array[p_ids]; + point p44{ p22.x + 2,p22.y + 2,0 }; p_ids = p44.x * ori_width + p44.y; p44.z = ori_array[p_ids]; + p.x = p.x - p11.x; + p.y = p.y - p11.y; + p = cubicInterpolation(p, p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44); + result_arr[ori_ids] = p.z; + } + } + } + + //std::cout << "\r" << end_row << "/" << height << "," << end_col << "/" << width << ","<GetRasterXSize(); + int height = sim2oriDataset->GetRasterYSize(); + int nCount = sim2oriDataset->GetRasterCount(); + double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + sim2oriDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + GDALDataType gdal_datatype = sim2oriDataset->GetRasterBand(1)->GetRasterDataType(); + const char* Projection = sim2oriDataset->GetProjectionRef(); + GDALRasterBand* ori_r_Band = sim2oriDataset->GetRasterBand(1); + float* ori_r_array = ReadRasterArray(ori_r_Band, width, height, gdal_datatype); + GDALRasterBand* ori_c_Band = sim2oriDataset->GetRasterBand(2); + float* ori_c_array = ReadRasterArray(ori_c_Band, width, height, gdal_datatype); + // 读取行列号 + delete ori_r_Band, ori_c_Band; + + + for (int t = 0; t < conveparas.file_count; t++) { + // 读 + // 创建 + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + string in_file_path = conveparas.inputFile_paths[t]; + string out_file_path = conveparas.outFile_paths[t]; + + GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly)); + int orth_width = inDataset->GetRasterXSize(); + int orth_height = inDataset->GetRasterYSize(); + int orth_num = inDataset->GetRasterCount(); + // 写 + + GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, orth_num, GDT_Float32, NULL); + outDstDS->SetGeoTransform(gt); + outDstDS->SetProjection(Projection); + + + float* result_arr = (float*)calloc(width * height, sizeof(float)); + int psize = width * height; + int blocksize = 1000; + for (int b = 1; b <= orth_num; b++) { + for (int i = 0; i < psize; i++) { + result_arr[i] = -9999; + } + GDALRasterBand* ori_Band = inDataset->GetRasterBand(b); + float* ori_arr= ReadRasterArray(ori_Band, orth_width, orth_height, gdal_datatype); + + // 线程池 + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + + // 三次样条重采样 + for (int start_row = 0; start_row < height; start_row = start_row + blocksize) { + int end_row = start_row + blocksize >= height ? height : start_row + blocksize; + for (int start_col = 0; start_col < width; start_col = start_col + blocksize) { + int end_col = start_col + blocksize >= width ? width : start_col + blocksize; + // 分块计算结果 + poolPtr->append(std::bind(orth_ReSampling,start_row,end_row,start_col,end_col,width,height, orth_width, orth_height, + ori_arr, result_arr, ori_r_array, ori_c_array)); + } + } + + std::cout << "resampling...." << std::endl; + poolPtr->waiteFinish(); + // 输出文件 + std::cout<GetRasterBand(b)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0); + outDstDS->GetRasterBand(b)->SetNoDataValue(-9999); + poolPtr->stop(); + delete ori_arr, ori_Band, subthreadPool; + } + free(result_arr); + GDALFlushCache(outDstDS); + GDALClose(outDstDS); + GDALClose(inDataset); + + } + free(gt); + free(inv_gt); + delete ori_r_array, ori_c_array;// , sim2oriDataset; + //GDALClose(sim2oriDataset); + return 0; +} + +/// +/// 生成影像的强度图 +/// +/// +/// +/// +/// +int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num) +{ + for (int t = 0; t < conveparas.file_count; t++) { + // 读 + // 创建 + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + string in_file_path = conveparas.outFile_paths[t]; + string out_file_path = conveparas.outFile_pow_paths[t]; + + GDALDataset* inDataset = (GDALDataset*)(GDALOpen(in_file_path.c_str(), GA_ReadOnly)); + int width = inDataset->GetRasterXSize(); + int height = inDataset->GetRasterYSize(); + int num = inDataset->GetRasterCount(); + double*gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + inDataset->GetGeoTransform(gt); // 获得仿射矩阵 + translateArray gtt{ gt[0],gt[1],gt[2],gt[3],gt[4],gt[5] }; + double*inv_gt = (double*)calloc(6, sizeof(double)); // 仿射矩阵 + GDALInvGeoTransform(gt, inv_gt); // 逆矩阵 + translateArray inv_gtt{ inv_gt[0],inv_gt[1],inv_gt[2],inv_gt[3],inv_gt[4],inv_gt[5] }; + const char* Projection = inDataset->GetProjectionRef(); + + GDALDataset* outDstDS = poDriver->Create(out_file_path.c_str(), width, height, 1, GDT_Float32, NULL); + outDstDS->SetGeoTransform(gt); + outDstDS->SetProjection(Projection); + GDALDataType gdal_datatype = inDataset->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* ori_Band = inDataset->GetRasterBand(1); + float* ori_a_array = ReadRasterArray(ori_Band, width, height, gdal_datatype); + ori_Band = inDataset->GetRasterBand(2); + float* ori_b_array = ReadRasterArray(ori_Band, width, height, gdal_datatype); + + + + float* result_arr = (float*)calloc(width * height, sizeof(float)); + int psize = width * height; + int blocksize = 1000; + for (int i = 0; i < psize; i++) { + result_arr[i] = -9999; + } + + // 线程池 + ThreadPool* subthreadPool = new ThreadPool(thread_num, true); + ThreadPoolPtr poolPtr(subthreadPool); + poolPtr->start(); + + + // 三次样条重采样 + for (int start_row = 0; start_row < height; start_row = start_row + blocksize) { + int end_row = start_row + blocksize >= height ? height : start_row + blocksize; + for (int start_col = 0; start_col < width; start_col = start_col + blocksize) { + int end_col = start_col + blocksize >= width ? width : start_col + blocksize; + // 分块计算结果 + poolPtr->append(std::bind(orth_pow, start_row, end_row, start_col, end_col, width, height, + result_arr, ori_a_array, ori_b_array)); + } + } + + std::cout << "pow resampling ..." << std::endl; + poolPtr->waiteFinish(); + // 输出文件 + std::cout << t << " , " << 1 << ",输出成果文件:" << getCurrentTimeString() << std::endl; + outDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, width, height, result_arr, width, height, GDT_Float32, 0, 0); + outDstDS->GetRasterBand(1)->SetNoDataValue(-9999); + poolPtr->stop(); + delete ori_a_array, ori_b_array, ori_Band, subthreadPool; + free(gt); + free(inv_gt); + free(result_arr); + //GDALFlushCache(outDstDS); + //GDALClose(outDstDS); + //GDALClose(inDataset); + //delete poDriver; + + } + + //GDALClose(sim2oriDataset); + return 0; +} + +int ResamplingSim(ParameterInFile paras) +{ + GDALAllRegister(); + // 打开DEM影像 + GDALDataset* simDataset = (GDALDataset*)(GDALOpen(paras.out_sar_sim_path.c_str(), GA_ReadOnly));//以只读方式读取地形影像 + int ori_sim_width = simDataset->GetRasterXSize(); + int ori_sim_height = simDataset->GetRasterYSize(); + int width = paras.sim_width; + int height = paras.sim_height; + float width_scales = width * 1.0 / ori_sim_width; + float height_scales = height * 1.0 / ori_sim_height; + + GDALClose(simDataset); + ResampleGDAL(paras.out_sar_sim_path.c_str(), paras.out_sar_sim_resampling_path.c_str(), width_scales, height_scales, GDALResampleAlg::GRA_CubicSpline); + return 0; +} + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX = 1.0, float fResY = 1.0, GDALResampleAlg eResample = GRA_Bilinear) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if (pDSrc == NULL) + { + return -1; + } + + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = GDALDataType::GDT_Float32;// pDSrc->GetRasterBand(1)->GetRasterDataType(); + + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + + double dGeoTrans[6] = { 0 }; + int nNewWidth = width, nNewHeight = height; + pDSrc->GetGeoTransform(dGeoTrans); + + + bool bNoGeoRef = false; + long double dOldGeoTrans0 = dGeoTrans[0]; + //如果没有投影,人为设置一个 + if (strlen(pszSrcWKT) <= 0) + { + //OGRSpatialReference oSRS; + //oSRS.SetUTM(50,true); //北半球 东经120度 + //oSRS.SetWellKnownGeogCS("WGS84"); + //oSRS.exportToWkt(&pszSrcWKT); + //pDSrc->SetProjection(pszSrcWKT); + + + ////////////////////////////////////////////////////////////////////////// + dGeoTrans[0] = 1.0; + pDSrc->SetGeoTransform(dGeoTrans); + ////////////////////////////////////////////////////////////////////////// + + + bNoGeoRef = true; + } + + + //adfGeoTransform[0] /* top left x */ + //adfGeoTransform[1] /* w-e pixel resolution */ + //adfGeoTransform[2] /* rotation, 0 if image is "north up" */ + //adfGeoTransform[3] /* top left y */ + //adfGeoTransform[4] /* rotation, 0 if image is "north up" */ + //adfGeoTransform[5] /* n-s pixel resolution */ + + + dGeoTrans[1] = dGeoTrans[1] / fResX; + dGeoTrans[5] = dGeoTrans[5] / fResY; + nNewWidth = static_cast(nNewWidth * fResX + 0.5); + nNewHeight = static_cast(nNewHeight * fResY + 0.5); + + + //创建结果数据集 + GDALDataset* pDDst = pDriver->Create(pszOutFile, nNewWidth, nNewHeight, nBandCount, dataType, NULL); + if (pDDst == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(dGeoTrans); + + + void* hTransformArg = NULL; + hTransformArg = GDALCreateGenImgProjTransformer2((GDALDatasetH)pDSrc, (GDALDatasetH)pDDst, NULL); //GDALCreateGenImgProjTransformer((GDALDatasetH) pDSrc,pszSrcWKT,(GDALDatasetH) pDDst,pszSrcWKT,FALSE,0.0,1); + + + if (hTransformArg == NULL) + { + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return -3; + } + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + + psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + + + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = hTransformArg; + + + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) + { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) + { + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return -3; + } + + + oWo.ChunkAndWarpImage(0, 0, nNewWidth, nNewHeight); + + + GDALDestroyGenImgProjTransformer(hTransformArg); + GDALDestroyWarpOptions(psWo); + if (bNoGeoRef) + { + dGeoTrans[0] = dOldGeoTrans0; + pDDst->SetGeoTransform(dGeoTrans); + //pDDst->SetProjection(""); + } + GDALFlushCache(pDDst); + GDALClose((GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)pDDst); + return 0; +} + +/// +/// 根据地面坐标获取计算结果 +/// +/// +/// +/// +/// +point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas) +{ + long double Starttime = paras.imgStartTime; + long double lamda = paras.lamda; + long double refrange = paras.refrange; + long double* doppler_para = paras.doppler_para; + long double LightSpeed = paras.LightSpeed; + long double delta_t = paras.delta_t; + long double R0 = paras.R0; + long double delta_R = paras.delta_R; + long double SatelliteModelStartTime = paras.SatelliteModelStartTime; + long double* polySatellitePara = paras.polySatellitePara; + int sim_sar_width = paras.sim_width; + int sim_sar_height = paras.sim_height; + int polynum = paras.polynum; + int doppler_paramenter_number = paras.doppler_paramenter_number; + + point pixelpoint = PSTN(landp, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + long double r, c; + sim2ori(pixelpoint.x, pixelpoint.y, r, c, convparas.sim2ori_paras); + return point{ r,c,0 }; +} + +// 根据坐标变换求解行列号 +int calSARPosition(ParameterInFile paras, ConvertResampleParameter converPara) { + // + + return 0; + +} + + +/// +/// 测试代码 +/// + +int testPP() { + + point landpoint; + landpoint.x = -1945072.5; + landpoint.y = 5344083.0; + landpoint.z = 2878316.0; + point targetpoint; + targetpoint.x = 31; + targetpoint.y = 118; + targetpoint.z = 33; + + landpoint = LLA2XYZ(targetpoint); + std::cout << "PTSN\nX:" << landpoint.x<< "\nY:" << landpoint.y << "\nZ:" << landpoint.z << "\n"; // <0.1 + return 0; +} + +int testPTSN(ParameterInFile paras) { + point landpoint; + landpoint.x = -1945072.5; + landpoint.y = 5344083.0; + landpoint.z = 2878316.0; + point targetpoint; + targetpoint.x = 31; + targetpoint.y = 118; + targetpoint.z = 1592144812.73686337471008300781; + + landpoint=LLA2XYZ(targetpoint); + point pixelpoint = PSTN(landpoint, paras.imgStartTime, paras.lamda, paras.refrange, paras.doppler_para, paras.LightSpeed, paras.PRF, paras.R0, paras.delta_R, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum, paras.doppler_paramenter_number); + std::cout << "PTSN\nX:" << targetpoint.x - pixelpoint.x << "\nY:" << targetpoint.y - pixelpoint.y << "\nZ:" << targetpoint.z - pixelpoint.z << "\n"; // <0.1 + + SatelliteSpacePoint sateP = getSatellitePostion(1592144812.7368634, paras.SatelliteModelStartTime, paras.polySatellitePara, paras.polynum); + SatelliteSpacePoint sateT{ -3044863.2137617283, 5669112.1303918585, 3066571.1073331647, -26.15659591374557, 3600.8531673370803, -6658.59211430739 }; + std::cout << "Sate\nX:" << sateP.x - sateT.x << "\nY:" << sateP.y - sateT.y << "\nZ:" << sateP.z - sateT.z << "\nVx" << sateP.vx - sateT.vx << "\nVy:" << sateP.vy - sateT.vy << "\nVz:" << sateP.vz - sateT.vz << "\n"; + return 0; +} diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h new file mode 100644 index 0000000..7a11165 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/ParameterInFile.h @@ -0,0 +1,576 @@ +#pragma once +#include +#include +#include +#include +#include +#include "gdalwarper.h" + +#define PI_180 180/3.141592653589793238462643383279; +#define T180_PI 3.141592653589793238462643383279/180; + +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI + +const long double PI=3.141592653589793238462643383279; +const long double epsilon = 0.000000000000001; +const long double pi = 3.14159265358979323846; +const long double d2r = pi / 180; +const long double r2d = 180 / pi; + +const long double a = 6378137.0; //椭球长半轴 +const long double f_inverse = 298.257223563; //扁率倒数 +const long double b = a - a / f_inverse; +const long double e = sqrt(a * a - b * b) / a; +const long double eSquare = e*e; + + + +int testPP(); + +using namespace std; +/// +/// 内敛函数 +/// + +struct point // 点 SAR影像的像素坐标; +{ + long double x; // 纬度 lat pixel_row + long double y; // 经度 lon pixel_col + long double z; // 高程 ati pixel_time +}; + +struct VectorPoint { + long double x; + long double y; + long double z; +}; +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +inline point LLA2XYZ(point& LLA) { + long double L = LLA.x * d2r; + long double B = LLA.y * d2r; + long double H = LLA.z; + + long double sinB = sin(B); + long double cosB = cos(B); + + //long double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + long double N = a / sqrt(1 - eSquare * sinB * sinB); + point result = { 0,0,0 }; + result.x = (N + H) * cosB * cos(L); + result.y = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.z = (N * (1 - eSquare) + H) * sinB; + return result; +} + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +point XYZ2LLA(point& XYZ); + +/// +/// 计算两个点之间的XY平面欧式距离的平方 +/// +/// +/// +/// +inline long double caldistanceXY(point& p1, point& p2) { + //return pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2); + return (p1.x - p2.x)* (p1.x - p2.x) + (p1.y - p2.y)* (p1.y - p2.y); +} + +/// +/// 使用两个点,生成向量 p1-->p2 +/// +/// p1 +/// p2 +/// 向量 +inline VectorPoint getVector(point& p1, point& p2) { + VectorPoint result = { 0,0,0 }; + result.x = p2.x - p1.x; + result.y = p2.y - p1.y; + result.z = p2.z - p1.z; + return result; +} + +/// +/// 获取向量的模 +/// +/// 向量 +/// 向量模 +inline long double getModule(VectorPoint& vector1) { + //return sqrt(pow(vector1.x, 2) + pow(vector1.y, 2) + pow(vector1.z, 2)); + return sqrt(vector1.x* vector1.x + vector1.y* vector1.y + vector1.z* vector1.z); +} + +inline long double getModuleV1V2(VectorPoint& v1, VectorPoint& v2) +{ + return sqrt((v1.x * v1.x + v1.y * v1.y + v1.z * v1.z) * (v2.x * v2.x + v2.y * v2.y + v2.z * v2.z)); +} + +/// +/// 向量夹角的角度( 角度) +/// +/// 向量 +/// 向量夹角的角度 +inline long double getVectorAngle(VectorPoint& vector1,VectorPoint& vector2) { + //return Radians2Degrees( acos((vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModule(vector1) * getModule(vector2)))); + return Radians2Degrees(acos((vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModuleV1V2(vector1, vector2)))); + +} + + +/// +/// 向量的夹角值 +/// +/// 向量 +/// 向量夹角的角度 +inline long double getVectorAngleValue(VectorPoint& vector1, VectorPoint& vector2) { + //return (vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModule(vector1) * getModule(vector2)); + return (vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z) / (getModuleV1V2(vector1, vector2)); +} +/// +/// 向量点乘 +/// +/// 向量1 +/// 向量2 +/// 点乘值 +inline long double Vectordot(VectorPoint& V1, VectorPoint& v2) { + return V1.x * v2.x + V1.y * v2.y + V1.z * v2.z; +} + +/// +/// 向量点乘 +/// +/// 向量1 +/// 系数值 +/// 向量与数之间的插值 +inline VectorPoint VectordotNumber(VectorPoint& V1, long double lamda) { + V1.x = V1.x * lamda; + V1.y = V1.y * lamda; + V1.z = V1.z * lamda; + return V1; +} + +/// +/// 向量叉乘 +/// 旋转方向:v1->v2 +/// +/// v1 +/// v2 +/// 叉乘的结果向量 +inline VectorPoint VectorFork(VectorPoint &v1, VectorPoint& v2) { + VectorPoint result{ 0,0,0 }; + result.x = v1.y * v2.z - v1.z * v2.y; + result.y =v1.z*v2.x -v1.x * v2.z; + result.z = v1.x * v2.y - v1.y * v2.x; + return result; +} + + +// +// 参数文件解析 +// + +//参数文件标准格式 +// 文件值 类型 对应的代号 +// DEM文件的路径 str dem_path +// 模拟影像输出路径 str sar_sim_path +// 模拟影像的宽 int +// 模拟影像的高 int +// 模拟影像的匹配坐标文件输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标X输出路径 str sar_sim_match_point_x_path +// 模拟影像的匹配坐标Y输出路径 str sar_sim_match_point_y_path +// 模拟影像的匹配坐标Z输出路径 str sar_sim_match_point_z_path +// 采样率 long double sample_f +// 近斜距 long double R0 +// 成像起始时间 long double starttime ---UTC 时间 +// 光速 long double +// 波长 long double +// 多普勒参考时间 long double TO ---UTC 时间 +// 脉冲重复频率 long double PRF +// 斜距采样间隔 long double delta_R +// 多普勒系数个数 int +// 多普勒系数1 long double +// 多普勒系数2 long double +// .... +// 卫星轨道模型是否为多项式模型 int 1 是。0 不是 +// 卫星轨道模型多项式次数 int 4 5 +// 卫星轨道模型起始时间 long double +// 卫星轨道模型X值系数1 long double +// .... +// 卫星轨道模型Y值系数1 long double +// ... +// 卫星轨道模型Z值系数1 long double +// ... +// 卫星轨道模型Vx值系数1 long double +// ... +// 卫星轨道模型Vy值系数1 long double +// ... +// 卫星轨道模型Vz值系数1 long double +// ... +// +// + +class ParameterInFile +{ +public: + ParameterInFile(std::string infile_path); + ParameterInFile(const ParameterInFile& paras); + ~ParameterInFile(); +public: + //参数组 + std::string dem_path; //dem 路径 + std::string out_sar_sim_path; // 输出模拟sar + std::string out_sar_sim_dem_path; // 输出模拟sar + std::string out_sar_sim_resampling_path; // 输出模拟sar + std::string out_sar_sim_resampling_rc; + int sim_height; // 模拟影像的高 + int sim_width; + long double widthspace;// 距离向分辨率 + std::string sar_sim_match_point_path; //输出模拟影像的地点x + std::string sar_sim_match_point_xyz_path; //输出模拟影像的地点x + int sample_f; //采样率 + long double R0; //近斜距 + long double LightSpeed;//光速 + long double lamda;//波长 + long double refrange;// 参考斜距 + + long double delta_R; // 斜距间隔 + long double imgStartTime; //成像起始时间 + long double PRF;// 脉冲重复率 + long double delta_t;// 时间间隔 + // 多普勒 + int doppler_paramenter_number;// 多普勒系数个数 + long double* doppler_para;//多普勒系数 + //卫星轨道模型 + int polySatelliteModel;// 是否为卫星多轨道模型 + int polynum;// 多项数 + long double SatelliteModelStartTime; + long double* polySatellitePara; +}; + +// 根据轨道模型计算卫星空间位置 +struct SatelliteSpacePoint { + long double x=0; + long double y=0; + long double z=0; + long double vx=0; + long double vy=0; + long double vz=0; + +}; + + +/// +/// 根据卫星轨道模型计算卫星 +/// +/// 卫星轨道点时间 +/// 卫星轨道模型起始时间 +/// 卫星轨道坐标模型参数 +/// 多项式项数 +/// +inline SatelliteSpacePoint getSatellitePostion(long double satelliteTime,long double SatelliteModelStartTime,long double* polySatellitePara,int polynum); + +/// +/// 数值模拟法计算多普勒频移值 +/// +/// 斜距 +/// 光速 +/// 多普勒参考时间 +/// 多普勒参数 +/// 多普勒频移值 +inline long double calNumericalDopplerValue(long double R,long double LightSpeed,long double T0, long double* doppler_para,int doppler_paramenter_number); + +/// +/// 根据理论模型计算多普勒频移值 +/// +/// 斜距 +/// 波长 +/// 地面->卫星的空间向量 +/// 地面->卫星之间的速度向量 +/// 多普勒频移值 +inline long double calTheoryDopplerValue(long double R, long double lamda, VectorPoint R_sl, VectorPoint V_sl); + +/// +/// 根据地面点求解对应的sar影像坐标 +/// +/// 地面点的坐标--地固坐标系 +/// 影片开始成像时间 +/// 波长 +/// 多普勒参考时间 +/// 光速 +/// 时间间隔 +/// 近斜距 +/// 斜距间隔 +/// 卫星轨道模型时间 +/// 卫星轨道坐标模型参数 +/// 卫星轨道模型项数 +/// 多普勒模型数 +/// 影像坐标(x:行号,y:列号,z:成像时刻) +inline point PSTN(point& landpoint, long double Starttime, long double lamda, long double T0, long double* doppler_para, long double LightSpeed, long double delta_t, long double R0, long double delta_R, long double SatelliteModelStartTime, long double* polySatellitePara, int polynum = 4, int doppler_paramenter_number = 5); + + + +struct translateArray { + long double a0, a1, a2; + long double b0, b1, b2; +}; +/// +/// 转换影像 +/// +/// +/// +/// +/// +/// +inline point Translation(long double row_ids,long double col_ids,long double value,translateArray& gt) { + + point result{ 0,0,0 }; + result.x = gt.a0 + gt.a1 * col_ids + gt.a2 * row_ids; + result.y = gt.b0 + gt.b1 * col_ids + gt.b2 * row_ids; + result.z = value; + return result; +} + +inline int Translation(long double& x, long double& y, long double& r, long double& c, translateArray& gt) { + + c = gt.a0 + gt.a1 * x + gt.a2 * y; + r = gt.b0 + gt.b1 * x + gt.b2 * y; + return 0; +} + +/// +/// dem块 +/// +class dem_block { + +public: + dem_block(int all_start_row,int all_start_col,int start_row, int end_row, int start_col, int end_col, int height, int width,int sample_f); + dem_block(const dem_block& demblocks); + ~dem_block(); + dem_block resample_dem(); + //dem_block resample_dem_cudic(); + int rowcol2blockids(int row_ids, int col_ids); + point getpointblock(int row_ids, int col_ids); + int setpointblock(int row_ids, int col_ids, point& value); + point getpointblock(int ids); + int setpointblock(int ids, point& value); + int UpdatePointCoodinarary(); + VectorPoint getslopeVector(int row_ids, int col_ids); +public: + int all_start_row; + int all_start_col; + int start_row; // 目标区域的起始行号 + int end_row; // + int start_col; // 目标区域的起始列号 + int end_col; + int height; + int width; + int size; + int sample_f; + point* pointblock; // 原始块 +}; + + + +inline point bilineadInterpolation(point& p,point& p11,point& p12,point& p21,point& p22); + +inline point cubicInterpolation(point& p, point& p11, point& p12,point& p13,point& p14, point& p21, point& p22,point& p23,point& p24,point& p31,point& p32,point& p33,point& p34,point& p41,point& p42,point& p43,point& p44); + +/// +/// 双线性插值方法 +/// +/// +/// +/// +/// +/// +/// +inline point SARbilineadInterpolation(point& p, point& p11, point& p12, point& p21, point& p22) { + + + + +} +/// +/// 入射角 -- 弧度制 +/// +struct IncidenceAngle +{ + long double incidenceAngle; // 雷达入射角 + long double localincidenceAngle; // 局地入射角 +}; + +struct matchPoint { + long double r, c, ti; + long double land_x, land_y, land_z; + long double distance; + long double incidenceAngle, localincidenceAngle; +}; +/// +/// 模拟sar 的矩阵块,累加模块默认使用short 类型(累加上限: +/// +class sim_block { +public: + sim_block(int start_row,int end_row,int start_col,int end_col,int height,int width); + sim_block(const sim_block& sim_blocks); + ~sim_block(); + + int rowcol2blockids(int row_ids, int col_ids); + short getsimblock(int row_ids, int col_ids); + int setsimblock(int row_ids,int col_ids, short value); + int addsimblock(int row_ids, int col_ids,short value); + matchPoint getpointblock(int row_ids,int col_ids); + int setpointblock(int row_ids, int col_ids, matchPoint value); + // + long double getdistanceblock(int row_ids, int col_ids); + int setdistanceblock(int row_ids, int col_ids, long double value); + +public: + int start_row; + int end_row; + int start_col; + int end_col; + int height; + int width; + int size; + short* block; + long double* distanceblock; + matchPoint* pointblock; +}; + + +/// +/// 根据卫星坐标,地面坐标,地面法向量,求解对应的雷达入射角和局地入射角 +/// +/// 卫星空间坐标 +/// 地面坐标 +/// 地面坡度 +/// 入射角文件 +inline IncidenceAngle calIncidence(point satellitepoint,point landpoint,VectorPoint slopvector) { + + IncidenceAngle result; + VectorPoint R_ls = getVector(landpoint, satellitepoint); + result.localincidenceAngle = getVectorAngleValue(R_ls, slopvector); + VectorPoint R_s{ satellitepoint.x,satellitepoint.y,satellitepoint.z }; + result.incidenceAngle = getVectorAngleValue(R_s, R_ls); + return result; +} + + +int SimProcessBlock(dem_block demblock, ParameterInFile paras, matchPoint* result_shared, int* Pcount); + +int ResamplingSim(ParameterInFile paras); +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, float fResX, float fResY, GDALResampleAlg eResample); + +/// +/// 模拟sar的处理算法模块。 +/// 为了控制内存的取用 +/// 线程数:8 --以进程类的方式进行管理--使用队列的方法 +/// 线程内存:dem_block_size*sample_f*sample_f< 1 G +/// +/// 参数文件项 +/// 线程数默认为8 +/// 执行情况 +int SimProcess(ParameterInFile paras, int thread_num); +int SimProcess_LVY(ParameterInFile paras, int thread_num); +int WriteMatchPoint(string path, std::vector* matchps); +// 测试函数接口 + +int testPTSN(ParameterInFile paras); + + +/// +/// +/// 考虑影像的插值方案 +/// +/// + +class ConvertResampleParameter { +public: + ConvertResampleParameter(string path); + ConvertResampleParameter(const ConvertResampleParameter& para); + ~ConvertResampleParameter(); +public: + string in_ori_dem_path; + string ori_sim; + string out_sar_xyz_path; + string out_sar_xyz_incidence_path; + string out_orth_sar_incidence_path; + string out_orth_sar_local_incidence_path; + string outFolder_path; + int file_count; + std::vector inputFile_paths; + std::vector outFile_paths; + std::vector outFile_pow_paths; + int ori2sim_num; + long double* ori2sim_paras; + int sim2ori_num; + long double* sim2ori_paras; +}; + +inline int ori2sim(long double ori_x,long double ori_y,long double& sim_x,long double& sim_y,long double* conver_paras) { + long double xy = ori_x * ori_y; + long double x2 = ori_x * ori_x; + long double y2 = ori_y * ori_y; + + sim_x = conver_paras[0] + ori_x * conver_paras[1] + ori_y * conver_paras[2] + x2 * conver_paras[3] + y2 * conver_paras[4] + xy * conver_paras[5]; + sim_y = conver_paras[6] + ori_x * conver_paras[7] + ori_y * conver_paras[8] + x2 * conver_paras[9] + y2 * conver_paras[10] + xy * conver_paras[11]; + return 1; +} + +/// +/// 将模拟的行列号转换为目标行列号 +/// +/// 模拟的行号 +/// 模拟的列号 +/// 待计算的目标行号 +/// 待计算的目标列号 +/// 变换矩阵 +/// 默认:0 表示计算结束 +inline int sim2ori(long double sim_r,long double sim_c,long double& ori_r,long double& ori_c, long double* conver_paras) { + long double xy = sim_r * sim_c; + long double x2 = sim_r * sim_r; + long double y2 = sim_c * sim_c; + ori_r = conver_paras[0] + sim_r * conver_paras[1] + sim_c * conver_paras[2] + x2 * conver_paras[3] + y2 * conver_paras[4] + xy * conver_paras[5]; + ori_c = conver_paras[6] + sim_r * conver_paras[7] + sim_c * conver_paras[8] + x2 * conver_paras[9] + y2 * conver_paras[10] + xy * conver_paras[11]; + return 0; +} + +// 查询精确坐标 + +point GetOriRC(point& landp, ParameterInFile& paras, ConvertResampleParameter& convparas); + +int SimProcessBlock_CalXYZ(dem_block demblock, ParameterInFile paras, ConvertResampleParameter converParas, matchPoint* result_shared, int* Pcount); +int SimProcess_CalXYZ(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); + + +/* + 正射模块思路 + dem->sim->ori(r,c) <-重采样-> ori + step1: 计算dem 对应的 ori 坐标,并保存-> ori_sim.tif (r,c,incidence,localincidence) + step2: 根据结果插值计算对应的a,b + +*/ +int SimProcess_Calsim2ori(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); // 正射模块 + + +/* +重采样: +step1:读取目标栅格,并根据目标栅格创建对象 +step2: +*/ +int SimProcess_ResamplingOri2Orth(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); + +/* +生成强度图 +*/ +int SimProcess_Calspow(ParameterInFile paras, ConvertResampleParameter conveparas, int thread_num); // 正射模块 \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp new file mode 100644 index 0000000..70e8eee --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.cpp @@ -0,0 +1,30 @@ +锘#include "common.h" + +#include +#include +#include + +/** + * @brief GetCurrentTime 鑾峰彇褰撳墠鏃堕棿 + * @return + */ +std::string getCurrentTimeString() { + + std::time_t t = std::time(NULL); + char mbstr[100]; + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", + std::localtime(&t)); + std::string strTime = mbstr; + return strTime; +} + +std::string getCurrentShortTimeString() { + + std::time_t t = std::time(NULL); + char mbstr[100]; + std::strftime(mbstr, sizeof(mbstr), "%H:%M:%S", + std::localtime(&t)); + std::string strTime = mbstr; + return strTime; +} + diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h new file mode 100644 index 0000000..75fee08 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/common.h @@ -0,0 +1,14 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include + +/** + * @brief GetCurrentTime 获取当前时间 + * @return + */ +std::string getCurrentTimeString(); +std::string getCurrentShortTimeString(); + +#endif \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props new file mode 100644 index 0000000..9535a71 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_debug_x64.props @@ -0,0 +1,17 @@ + + + + + + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\bin\intel64;$(VC_ExecutablePath_x64);$(CommonExecutablePath) + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\include;C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\include;$(oneMKLIncludeDir);$(IncludePath) + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\lib\intel64;C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files (x86)\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;$(LibraryPath) + <_PropertySheetDisplayName>mkl_debug_x64 + + + + mkl_intel_ilp64.lib;mkl_intel_thread.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;libiomp5md.lib;impi.lib;mkl_sequential.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props new file mode 100644 index 0000000..d675cec --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/mkl_release_x64.props @@ -0,0 +1,16 @@ + + + + + + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\bin\intel64;$(VC_ExecutablePath_x64);$(CommonExecutablePath) + C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\include;C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\include;$(oneMKLIncludeDir);$(IncludePath) + C:\Program Files (x86)\Intel\oneAPI\mkl\2022.1.0\lib\intel64;C:\Program Files (x86)\Intel\oneAPI\mpi\2021.6.0\lib\release;C:\Program Files (x86)\Intel\oneAPI\compiler\2022.1.0\windows\compiler\lib\intel64_win;$(LibraryPath) + + + + mkl_intel_ilp64.lib;mkl_intel_thread.lib;mkl_core.lib;mkl_blacs_intelmpi_ilp64.lib;libiomp5md.lib;impi.lib;mkl_sequential.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp new file mode 100644 index 0000000..18a154f --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.cpp @@ -0,0 +1,11 @@ +锘#include "taskprocess.h" + +TaskProcess::TaskProcess() +{ + +} + +TaskProcess::~TaskProcess() +{ + +} diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h new file mode 100644 index 0000000..0688930 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/taskprocess.h @@ -0,0 +1,15 @@ +锘#ifndef TASKPROCESS_H +#define TASKPROCESS_H + +class TaskProcess +{ +public: + TaskProcess(); + ~TaskProcess(); +private: + + +}; + + +#endif \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp new file mode 100644 index 0000000..2e4fae9 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.cpp @@ -0,0 +1,182 @@ +锘#include "threadpool.hpp" + +#include +#include +//#include + +#include + +static const int MAX_THREADS = 10000; //鏈澶х嚎绋嬫暟鐩 +/** + * @brief ThreadPool + * @param number[in]绾跨▼鏁 *榛樿寮涓涓嚎绋 + * @param + * emptyQuit[in]绌虹嚎绋嬮鍑猴紝榛樿false銆傚鏋滀负true锛岄渶瑕佸厛娣诲姞浠诲姟锛屽啀start锛岀劧鍚巜aite瀹屾垚 + */ +ThreadPool::ThreadPool(int number, bool emptyQuit) + : m_StopFlag(false), m_EmptyQuit(emptyQuit), m_JoinFlag(false), m_QuitNum(0), m_EmptyQuitWaite(false) { + std::cout << "绾跨▼姹犱腑绾跨▼鏁帮細" << number << std::endl; + if (number <= 0 || number > MAX_THREADS) throw std::exception(); + m_ThreadNum = number; +} + +ThreadPool::~ThreadPool() { + // std::cout << "~ThreadPool()" << std::endl; + stop(); +} +/** + * @brief stop 鍋滄 + */ +void ThreadPool::stop() { + //淇濊瘉澶氱嚎绋嬫儏鍐典笅鍙皟鐢ㄤ竴娆topThreadGroup + std::call_once(m_CallStopSlag, [this] { stopThreadGroup(); }); +} +/** + * @brief stopThreadGroup 鍋滄绾跨▼缁 + */ +void ThreadPool::stopThreadGroup() { + m_StopFlag = true; + Sleep(500); + m_Condition.notify_all(); + waiteFinish(); //绛夊緟绾跨▼閫鍑 + std::thread* thread = NULL; + for (int i = 0; i < m_WorkThreads.size(); i++) + { + thread = m_WorkThreads[i]; + if (thread != NULL) + { + thread->join(); + delete thread; + thread = NULL; + } + m_WorkThreads[i] = NULL; + } + m_WorkThreads.clear(); +} +/** + * @brief startThread 鍚姩绾跨▼ + */ +void ThreadPool::startThread() { + for (int i = 0; i < m_ThreadNum; i++) { + std::thread* thread = new std::thread(ThreadPool::worker, this); + m_WorkThreads.push_back(thread); + } +} +/** + * @brief waiteThreadFinish 绛夊緟绾跨▼缁撴潫 + */ +void ThreadPool::waiteThreadFinish() { + if (m_JoinFlag) return; + if (m_EmptyQuit) + { + m_EmptyQuitWaite = true; + do + { + if (m_ThreadNum == m_QuitNum) + break; + Sleep(400); + + } while (true); + m_StopFlag = true; + m_Condition.notify_all(); + + } + /* for (int i = 0; i < work_threads.size(); i++) { + if (work_threads[i]) { work_threads[i]->join(); } + }*/ + m_JoinFlag = true; +} +/** + * @brief start 鍚姩 + */ +void ThreadPool::start() { + std::call_once(m_CallStartSlag, [this] { startThread(); }); +} +/** + * @brief waiteFinish 绛夊緟鎵鏈変换鍔$粨鏉,璁剧疆涓轰换鍔′负绌洪鍑烘椂璋冪敤 + */ +void ThreadPool::waiteFinish() { + std::call_once(m_CallWaiteFinisFlag, [this] { waiteThreadFinish(); }); +} +/** +* @brief 浠诲姟鏁 +*/ +int ThreadPool::taskNum() +{ + return m_TasksQueue.size(); +} +/** + * @brief append 寰璇锋眰闃熷垪锛渢ask_queue锛炰腑娣诲姞浠诲姟 + * @param task + * @return + */ +bool ThreadPool::append(Task task) { + /*鎿嶄綔宸ヤ綔闃熷垪鏃朵竴瀹氳鍔犻攣锛屽洜涓轰粬琚墍鏈夌嚎绋嬪叡浜*/ + m_DataMutex.lock(); + m_TasksQueue.push(task); + m_DataMutex.unlock(); + + m_Condition.notify_one(); //绾跨▼姹犳坊鍔犺繘鍘讳簡浠诲姟锛岃嚜鐒惰閫氱煡绛夊緟鐨勭嚎绋 + return true; +} +/** + * @brief worker 绾跨▼鍥炶皟鍑芥暟 + * @param arg + * @return + */ +void* ThreadPool::worker(void* arg) { + ThreadPool* pool = (ThreadPool*)arg; + pool->run(); + return pool; +} +/** + * @brief notEmpty 鏄惁绌 + * @return + */ +bool ThreadPool::notEmpty() { + bool empty = m_TasksQueue.empty(); + if (empty) { + // std::ostringstream oss; + // oss << std::this_thread::get_id(); + // printf("queue empty thread id %s waite...!\n", oss.str().c_str()); + } + return !empty; +} +/** + * @brief run 宸ヤ綔绾跨▼闇瑕佽繍琛岀殑鍑芥暟,涓嶆柇鐨勪粠浠诲姟闃熷垪涓彇鍑哄苟鎵ц + */ +void ThreadPool::run() { + bool flag = false; + int remainder = 0; + while (!m_StopFlag) { + flag = false; + { + std::unique_lock lk(this->m_QueueMutex); + /*銆unique_lock() 鍑轰綔鐢ㄥ煙浼氳嚜鍔ㄨВ閿併*/ + m_Condition.wait(lk, [this] { return m_StopFlag || notEmpty(); }); + } + + if (m_StopFlag) break; + Task task; + m_DataMutex.lock(); + //濡傛灉浠诲姟闃熷垪涓嶄负绌猴紝灏卞仠涓嬫潵绛夊緟鍞ら啋 + if (!this->m_TasksQueue.empty()) { + task = m_TasksQueue.front(); + m_TasksQueue.pop(); + remainder = m_TasksQueue.size(); + flag = true; + } + m_DataMutex.unlock(); + if (flag) task(); + //濡傛灉闃熷垪涓虹┖骞朵笖瀹屾垚閫鍑猴紝宸茬粡寮濮嬬瓑寰呴鍑哄氨閫鍑 + if (m_TasksQueue.empty() && m_EmptyQuit && m_EmptyQuitWaite) + { + break; + } + + } + m_QuitNum += 1; + std::ostringstream oss; + oss << std::this_thread::get_id(); + printf("thread %s end\n", oss.str().c_str()); +} diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp new file mode 100644 index 0000000..1a50eba --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/PSTM_simulation_windows/threadpool.hpp @@ -0,0 +1,102 @@ +锘#ifndef THREADPOOL_HPP +#define THREADPOOL_HPP + +#include +#include +#include +#include +#include //unique_ptr +#include +#include +#include +#include + +typedef std::function Task; + +class ThreadPool { +public: + /** + * @brief ThreadPool + * @param number[in]绾跨▼鏁 *榛樿寮涓涓嚎绋 + * @param + * emptyQuit[in]绌虹嚎绋嬮鍑猴紝榛樿false銆傚鏋滀负true锛岄渶瑕佸厛娣诲姞浠诲姟锛屽啀start锛岀劧鍚巜aite瀹屾垚 + */ + ThreadPool(int number = 1, bool emptyQuit = false); + ~ThreadPool(); + + /** + * @brief append 寰璇锋眰闃熷垪锛渢ask_queue锛炰腑娣诲姞浠诲姟 + * @param task + * @return + */ + bool append(Task task); + /** + * @brief start 鍚姩 + */ + void start(); + /** + * @brief stop 鍋滄 + */ + void stop(); + /** + * @brief waiteFinish 绛夊緟鎵鏈変换鍔$粨鏉,璁剧疆涓轰换鍔′负绌洪鍑烘椂璋冪敤 + */ + void waiteFinish(); + /** + * @brief 浠诲姟鏁 + */ + int taskNum(); +private: + /** + * @brief worker 绾跨▼鍥炶皟鍑芥暟 + * @param arg + * @return + */ + static void *worker(void *arg); + /** + * @brief run 宸ヤ綔绾跨▼闇瑕佽繍琛岀殑鍑芥暟,涓嶆柇鐨勪粠浠诲姟闃熷垪涓彇鍑哄苟鎵ц + */ + void run(); + /** + * @brief stopThreadGroup 鍋滄绾跨▼缁 + */ + void stopThreadGroup(); + /** + * @brief startThread 鍚姩绾跨▼ + */ + void startThread(); + /** + * @brief waiteThreadFinish 绛夊緟绾跨▼缁撴潫 + */ + void waiteThreadFinish(); + /** + * @brief notEmpty 鏄惁绌 + * @return + */ + bool notEmpty(); + +private: + std::vector m_WorkThreads; /*宸ヤ綔绾跨▼*/ + std::queue m_TasksQueue; /*浠诲姟闃熷垪*/ + + std::mutex m_QueueMutex; + std::condition_variable m_Condition; /*蹇呴』涓巙nique_lock閰嶅悎浣跨敤*/ + + std::recursive_mutex m_DataMutex; //鏁版嵁閿 + + std::atomic_bool m_StopFlag; //鏄惁鍋滄鏍囧織 + std::once_flag m_CallStopSlag; + std::once_flag m_CallStartSlag; + std::once_flag m_CallWaiteFinisFlag; + int m_ThreadNum; //绾跨▼鏁 + + std::atomic_bool m_EmptyQuit; //鏃犱换鍔¢鍑烘ā寮,鏀规ā寮忓厛娣诲姞浠诲姟锛屽啀鍚姩 + std::atomic_bool m_JoinFlag; //绾跨▼鏄惁Join + + std::atomic_bool m_EmptyQuitWaite;//寮濮嬮鍑虹瓑寰 + std::atomic_int m_QuitNum;//閫鍑虹殑绾跨▼璁℃暟 + +}; +typedef std::shared_ptr ThreadPoolPtr; + +#endif // THREADPOOL_HPP diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp new file mode 100644 index 0000000..54b39f6 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.cpp @@ -0,0 +1,20 @@ +锘// testengiewithmkl.cpp : 姝ゆ枃浠跺寘鍚 "main" 鍑芥暟銆傜▼搴忔墽琛屽皢鍦ㄦ澶勫紑濮嬪苟缁撴潫銆 +// + +#include + +int main() +{ + std::cout << "Hello World!\n"; +} + +// 杩愯绋嬪簭: Ctrl + F5 鎴栬皟璇 >鈥滃紑濮嬫墽琛(涓嶈皟璇)鈥濊彍鍗 +// 璋冭瘯绋嬪簭: F5 鎴栬皟璇 >鈥滃紑濮嬭皟璇曗濊彍鍗 + +// 鍏ラ棬浣跨敤鎶宸: +// 1. 浣跨敤瑙e喅鏂规璧勬簮绠$悊鍣ㄧ獥鍙f坊鍔/绠$悊鏂囦欢 +// 2. 浣跨敤鍥㈤槦璧勬簮绠$悊鍣ㄧ獥鍙h繛鎺ュ埌婧愪唬鐮佺鐞 +// 3. 浣跨敤杈撳嚭绐楀彛鏌ョ湅鐢熸垚杈撳嚭鍜屽叾浠栨秷鎭 +// 4. 浣跨敤閿欒鍒楄〃绐楀彛鏌ョ湅閿欒 +// 5. 杞埌鈥滈」鐩>鈥滄坊鍔犳柊椤光濅互鍒涘缓鏂扮殑浠g爜鏂囦欢锛屾垨杞埌鈥滈」鐩>鈥滄坊鍔犵幇鏈夐」鈥濅互灏嗙幇鏈変唬鐮佹枃浠舵坊鍔犲埌椤圭洰 +// 6. 灏嗘潵锛岃嫢瑕佸啀娆℃墦寮姝ら」鐩紝璇疯浆鍒扳滄枃浠垛>鈥滄墦寮鈥>鈥滈」鐩濆苟閫夋嫨 .sln 鏂囦欢 diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj new file mode 100644 index 0000000..e99f8f9 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c26dab80-43be-4542-a2a3-7b5acb6e35e6} + testengiewithmkl + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters new file mode 100644 index 0000000..eab1303 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.filters @@ -0,0 +1,22 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/PSTM_simulation_windows2021-11-30/testengiewithmkl/testengiewithmkl.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/README.md b/simorthoprogram-orth_s_sar-strip/README.md new file mode 100644 index 0000000..f7f7324 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/README.md @@ -0,0 +1 @@ +# SIMOrthoProgram \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/RPC_Correct.cpp b/simorthoprogram-orth_s_sar-strip/RPC_Correct.cpp new file mode 100644 index 0000000..039a578 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/RPC_Correct.cpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" + +#include "RPC_Correct.h" + +using namespace std; +using namespace Eigen; + + + diff --git a/simorthoprogram-orth_s_sar-strip/RPC_Correct.h b/simorthoprogram-orth_s_sar-strip/RPC_Correct.h new file mode 100644 index 0000000..c500e94 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/RPC_Correct.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" +//#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +using namespace std; +using namespace Eigen; + + +// 专门用于解析RPC + + + + +class RPC_Correct +{ +}; + diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.aps b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.aps new file mode 100644 index 0000000..56cedc1 Binary files /dev/null and b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.aps differ diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.cpp b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.cpp new file mode 100644 index 0000000..c8be2e2 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.cpp @@ -0,0 +1,434 @@ +// SIMOrthoProgram.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 +// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + + + +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +#include "test_moudel.h" +#include +using namespace std; +using namespace Eigen; + +//mode 1 +void PreProcess(int argc, char* argv[]) +{ + // .\baseTool\x64\Release\SIMOrthoProgram.exe 1 D:\MicroWorkspace\C-SAR\Ortho\Temporary\unpack\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff + //输入参数 + std::cout << "==========================================================================" << endl; + std::cout << "预处理计算结果,可以计算出DEM 范围 " << endl; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path "; + std::string parameter_path = argv[2]; // 参数文件 + std::string dem_path = argv[3]; // dem 文件 + std::string in_sar_path = argv[4]; // 输入SAR文件 + std::string work_path = argv[5]; // 目标空间文件 + std::string taget_path = argv[6]; // 输出坐标映射文件 + + //std::string parameter_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package\\orth_para.txt"; // 参数文件 + //std::string dem_path = "D:\\micro\\LWork\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; // dem 文件 + //std::string in_sar_path = "D:\\micro\\LWork\\Ortho\\Temporary\\unpack\\LT1B_MONO_MYC_STRIP4_005860_E130.9_N47.7_20230327_SLC_AHV_L1A_0000086966\\LT1B_MONO_MYC_STRIP4_005860_E130.9_N47.7_20230327_SLC_HH_L1A_0000086966.tiff"; // 输入SAR文件 + //std::string work_path = "D:\\micro\\LWork\\Ortho\\Temporary"; // 目标空间文件 + //std::string taget_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package"; // 输出坐标映射文件 + //std::string Incident_path = argv[7];// 输出入射角文件 + + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the sar image:\n" << in_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + std::cout << "==========================================================================" << endl; + process.InitSimulationSAR(parameter_path, work_path, taget_path, dem_path, in_sar_path); + std::cout << "==========================================================================" << endl; +} + +//mode 2 +void calIncident_localIncident_angle(int argc, char* argv[]) { + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_rc_wgs84_path = argv[4]; + std::string out_incident_angle_path = argv[5]; + std::string out_local_incident_angle_path = argv[6]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.pstn = pstn; + process.calcalIncident_localIncident_angle(dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + +} + +// mode 3 +void calInterpolation_cubic_Wgs84_rc_sar(int argc, char* argv[]) { + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\package\\orth_para.txt"; argv[2]; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\dem_rc.tiff"; argv[3]; + std::string in_ori_sar_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\unpack\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_AHV_L10003514912\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_VV_L10003514912.tiff"; argv[4]; + std::string out_orth_sar_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary\\package\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1A_VV_L10003514912_GTC_rpc_geo.tif"; argv[5]; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + +// mode 4 处理 RPC的入射角 +void getRPC_Incident_localIncident_angle(int argc, char* argv[]) { + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string in_dem_path = argv[3]; + std::string in_rpc_rc_path = argv[4]; + std::string out_rpc_dem_path = argv[5]; + std::string out_incident_angle_path = argv[6]; + std::string out_local_incident_angle_path = argv[7]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + + process.CreateRPC_DEM(in_rpc_rc_path, in_dem_path, out_rpc_dem_path); + process.calcalIncident_localIncident_angle(out_rpc_dem_path, in_rpc_rc_path, out_incident_angle_path, out_local_incident_angle_path, pstn); +} + +//mode 5 +void cal_ori_2_power_tiff(int argc, char* argv[]) { + std::cout << "mode 5: convert ori tiff to power tiff:"; + std::cout << "SIMOrthoProgram.exe 5 in_ori_path out_power_path"; + std::string in_ori_path = argv[2]; + std::string out_power_path = argv[3]; + simProcess process; + process.ori_sar_power(in_ori_path, out_power_path); + +} + +// mode 6 +void cal_GEC_Incident_localIncident_angle(int argc, char* argv[]) { + std::cout << "mode 6: get gec incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 6 in_parameter_path in_dem_path in_gec_lon_lat_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_gec_lon_lat_path = argv[4]; + std::string out_incident_angle_path = argv[5]; + std::string out_local_incident_angle_path = argv[6]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.calGEC_Incident_localIncident_angle(dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, pstn); +} + +// mode 7 +void RPC_inangle(int argc, char* argv[]) { + std::cout << "mode 7: get rpc incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 7 in_parameter_path in_dem_path in_gec_lon_lat_path work_path taget_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = argv[2]; + std::string dem_path = argv[3]; + std::string in_gec_lon_lat_path = argv[4]; + std::string work_path = argv[5]; + std::string taget_path = argv[6]; + std::string out_incident_angle_path = argv[7]; + std::string out_local_incident_angle_path = argv[8]; + std::string out_incident_angle_geo_path = argv[9]; + std::string out_local_incident_angle_geo_path = argv[10]; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.InitRPCIncAngle(parameter_path, work_path, taget_path, dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, out_incident_angle_geo_path, out_local_incident_angle_geo_path); + std::cout << "==========================================================================" << endl; +} + +// mode 9 +void calInterpolation_cubic_Wgs84_rc_sar_sigma(int argc, char* argv[]) { + + std::cout << "mode 9: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 9 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\micro\\LWork\\Ortho\\Temporary\\package\\RD_sim_ori.tif"; + std::string in_ori_sar_path = "D:\\micro\\LWork\\Ortho\\Temporary\\in_sar_power.tiff"; + std::string out_orth_sar_path = "D:\\micro\\LWork\\Ortho\\Temporary\\in_sar_power_GTC.tiff"; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar_sigma(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + +// mode 11 +void interpolation_bil_GTC_sar_sigma(int argc, char* argv[]) { + + std::cout << "mode 11: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 11 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::string parameter_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\preprocessing\\GF3B_MYC_QPSI_008114_E121.6_N40.9_20230608_L1A_AHV_L10000196489-ortho\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\preprocessing\\GF3B_MYC_QPSI_008114_E121.6_N40.9_20230608_L1A_AHV_L10000196489-ortho\\sim_ori-ortho.tif"; + std::string in_ori_sar_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\SurfaceRoughnessProduct_temp.tif"; + std::string out_orth_sar_path = "D:\\micro\\WorkSpace\\SurfaceRoughness\\Temporary\\SurfaceRoughnessProduct_geo1.tif"; + parameter_path = argv[2]; + in_rc_wgs84_path = argv[3]; + in_ori_sar_path = argv[4]; + out_orth_sar_path = argv[5]; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + process.pstn = pstn; + std::cout << "==========================================================================" << endl; + process.interpolation_bil(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); +} + + +// mode 12 +void lee_process_sar(int argc, char* argv[]) { + + std::cout << "mode 12: lee process:\n "; + std::cout << "SIMOrthoProgram.exe 12 in_sar_path out_sar_path win_size noise_var\n"; + std::string in_sar_path = "D:\\micro\\WorkSpace\\BackScattering\\Temporary\\preprocessing\\GF3_SAY_QPSI_011444_E118.9_N31.4_20181012_L1A_HH_L10003515422_DB.tif"; + std::string out_sar_path = "D:\\micro\\WorkSpace\\BackScattering\\Temporary\\preprocessed_lee.tif"; + int win_size = 5; + double noise_var = 0.25; + in_sar_path = argv[2]; + out_sar_path = argv[3]; + win_size = stoi(argv[4]); + noise_var = stod(argv[5]); + + simProcess process; + std::cout << "==========================================================================\n" << endl; + //std::cout << in_sar_path << endl; + //std::cout << out_sar_path << endl; + //std::cout << win_size << endl; + //std::cout << noise_var << endl; + process.lee_process(in_sar_path, out_sar_path, win_size, noise_var); +} + +void createRPC_lon_lat(int argc, char* argv[]) { + std::cout << "mode 8"; + std::cout << "SIMOrthoProgram.exe 8 in_rpc_tiff out_lon_lat_path"; + std::string in_rpc_tiff = argv[2]; + std::string in_dem_tiff = argv[3]; + std::string out_lon_lat_path = argv[4]; + + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.CreateRPC_refrenceTable(in_rpc_tiff, in_dem_tiff,out_lon_lat_path); + std::cout << "==========================================================================" << endl; +} + +void Scatter2Grid_lon_lat(int argc, char* argv[]) { + std::cout << "mode 10"; + std::cout << "SIMOrthoProgram.exe 10 lon_lat_path data_tiff grid_path space"; + std::string lon_lat_path = "F:\\orthtest\\ori_sim_preprocessed.tif"; + std::string data_tiff = "F:\\orthtest\\SoilMoistureProduct_geo.tif"; + std::string grid_path = "F:\\orthtest\\SoilMoistureProduct_geo_test.tif"; + double space = 5; + + lon_lat_path = argv[2]; + data_tiff = argv[3]; + grid_path = argv[4]; + space = stod(argv[5]); + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.Scatter2Grid(lon_lat_path, data_tiff, grid_path, space); + std::cout << "==========================================================================" << endl; +} + + +string GetExePath() +{ + char szFilePath[MAX_PATH + 1] = { 0 }; + GetModuleFileNameA(NULL, szFilePath, MAX_PATH); + /* + strrchr:函数功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置), + 并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。 + 使用这个地址返回从最后一个字符c到str末尾的字符串。 + */ + (strrchr(szFilePath, '\\'))[0] = 0; // 删除文件名,只获得路径字串// + string path = szFilePath; + return path; +} + +/// +/// 初始化 +/// +void initProjEnv() { + PJ_CONTEXT* C; + C = proj_context_create(); + std::cout << "========================== init PROJ ================================================" << endl; + string exepath = GetExePath(); + char buffer[10240]; + int i; + for (i = 0; i < exepath.length(); i++) { + buffer[i] = exepath[i]; + } + buffer[i] = '\0'; + + const char* proj_share_path = buffer; + proj_context_set_search_paths(C, 1, &proj_share_path); + char* buf = nullptr; + size_t sz = 0; + + if (_dupenv_s(&buf, &sz, "PROJ_LIB") == 0 && buf != nullptr) + { + printf("PROJ_LIB = %s\n", buf); + std::string newEnv = "PROJ_LIB=" + std::string(buffer); + _putenv(newEnv.c_str()); + } + else { + std::string newEnv = "PROJ_LIB=" + std::string(buffer); + _putenv(newEnv.c_str()); + } + + if (_dupenv_s(&buf, &sz, "PROJ_LIB") == 0 && buf != nullptr) + { + std::cout << "after PROJ_LIB = " << buf << endl; + } + free(buf); + std::cout << "========================================================================================" << endl; +} + + +int main(int argc, char* argv[]) +{ + initProjEnv(); + //WGS84_J2000(); + cout << "test\t" << acos(-1) << endl; + cout << getAngle(Landpoint{ -3421843,5089485,3630606 }, Landpoint{ -2609414,4763328,3332879 }) << endl;; + Landpoint p2 = { -3421843,5089485,3630606 }; Landpoint p1 = { -2609414,4763328,3332879 }; + cout << getIncAngle(p2, p1) << endl;; + std::cout << "program start:\t" << getCurrentTimeString() << endl;; + int mode = 9; + GDALAllRegister(); + if (argc == 0) { // 测试参数 + // 算法说明 + std::cout << "========================== description ================================================" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + std::cout << "mode 1: Preprocess\n "; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path out_GEC_dem_path out_GTC_rc_path out_GEC_lon_lat_path out_clip_dem_path" << endl; + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + + std::cout << "mode 5: interpolation(cubic convolution) orth sar value by gec_lon_lat and dem and ori_sar image and sar model:"; + std::cout << "SIMOrthoProgram.exe 5 in_parameter_path in_gec_lon_lat_path in_dem_path in_sar_path out_orth_sar_path"; + + std::cout << "mode 6: get gec incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 6 in_parameter_path in_dem_path in_gec_lon_lat_path out_incident_angle_path out_local_incident_angle_path"; + if (mode == 10) { + Scatter2Grid_lon_lat(argc, argv); + } + else { + test_main(mode, "D:\\MicroSAR\\C-SAR\\Ortho\\Ortho\\Temporary"); + } + //calInterpolation_cubic_Wgs84_rc_sar(argc, argv); + } + else if (argc > 1) { // 预处理模块 + + std::cout << "=============================description V2.0 =============================================" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + std::cout << "algorithm moudel:.exe [modeparamert] {otherParaments}" << endl; + mode = stoi(argv[1]); + if (mode == 0) { + test_main(mode, argv[2]); + } + else if (mode == 1) { + PreProcess(argc, argv); // + } + else if (mode == 2) { // RPC 计算模块 + calIncident_localIncident_angle(argc, argv); + } + else if (mode == 3) { + calInterpolation_cubic_Wgs84_rc_sar(argc, argv); + } + else if (mode == 4) { + getRPC_Incident_localIncident_angle(argc, argv); + } + else if (mode == 5) { + cal_ori_2_power_tiff(argc, argv); + } + else if (mode == 6) { + cal_GEC_Incident_localIncident_angle(argc, argv); + } + else if (mode == 7) { + RPC_inangle(argc, argv); + } + else if (mode == 8) { + createRPC_lon_lat(argc, argv); + } + else if (mode == 9) { + calInterpolation_cubic_Wgs84_rc_sar_sigma(argc, argv); + } + else if (mode == 10) { + Scatter2Grid_lon_lat(argc, argv); + } + else if (mode == 11) { + interpolation_bil_GTC_sar_sigma(argc, argv); + } + else if (mode == 12){ + lee_process_sar(argc, argv); + } + } + GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + std::cout << "program over:\t" << getCurrentTimeString() << endl; + + +} + +// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 +// 调试程序: F5 或调试 >“开始调试”菜单 + +// 入门使用技巧: +// 1. 使用解决方案资源管理器窗口添加/管理文件 +// 2. 使用团队资源管理器窗口连接到源代码管理 +// 3. 使用输出窗口查看生成输出和其他消息 +// 4. 使用错误列表窗口查看错误 +// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 +// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.rc b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.rc new file mode 100644 index 0000000..f8ef045 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.rc @@ -0,0 +1,64 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// 涓枃(绠浣擄紝涓浗) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// + +#endif // 涓枃(绠浣擄紝涓浗) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.sln b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.sln new file mode 100644 index 0000000..469c9dd --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.sln @@ -0,0 +1,31 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32602.215 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SIMOrthoProgram", "SIMOrthoProgram.vcxproj", "{7722B0A9-572B-4E32-AFBE-4DC88898F8EE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x64.ActiveCfg = Debug|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x64.Build.0 = Debug|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x86.ActiveCfg = Debug|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Debug|x86.Build.0 = Debug|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x64.ActiveCfg = Release|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x64.Build.0 = Release|x64 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x86.ActiveCfg = Release|Win32 + {7722B0A9-572B-4E32-AFBE-4DC88898F8EE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CE6D0980-E92A-4188-91CE-EEE5749F908C} + EndGlobalSection +EndGlobal diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj new file mode 100644 index 0000000..0d2e720 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj @@ -0,0 +1,201 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7722b0a9-572b-4e32-afbe-4dc88898f8ee} + SIMOrthoProgram + 10.0 + SIMOrthoProgram-S-SAR + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + false + v142 + Unicode + Sequential + + + Application + false + v142 + true + Unicode + Parallel + false + + + + + + + + + + + + + + + + + + + + + C:\ProgramData\Miniconda3\envs\orth\Library\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64;$(oneMKLOmpLibDir);$(LibraryPath) + true + false + C:\ProgramData\Miniconda3\envs\orth\Library\include;$(ExternalIncludePath) + + + true + true + true + $(IncludePath) + $(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(LibraryPath) + $(VC_ReferencesPath_x64); + $(WindowsSDK_MetadataPath); + true + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _CONSOLE;%(PreprocessorDefinitions) + true + true + Default + stdc11 + MultiThreaded + + + Console + true + %(AdditionalDependencies) + + + + + Level3 + + + false + true + _CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + Default + Default + MaxSpeed + Neither + false + false + true + /bigobj %(AdditionalOptions) + + + Console + true + true + true + + + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj.filters b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj.filters new file mode 100644 index 0000000..a443456 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj.filters @@ -0,0 +1,88 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + + + + + 璧勬簮鏂囦欢 + + + + + 璧勬簮鏂囦欢 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj.user b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SIMOrthoProgram.vcxproj.user @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/SateOrbit.cpp b/simorthoprogram-orth_s_sar-strip/SateOrbit.cpp new file mode 100644 index 0000000..f34405d --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SateOrbit.cpp @@ -0,0 +1,86 @@ +#include "SateOrbit.h" +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +#include +#include +#include +#include +//#include + +using namespace std; +using namespace Eigen; + + + +OrbitPoly::OrbitPoly() +{ +} + +OrbitPoly::OrbitPoly(int polynum, Eigen::MatrixX polySatellitePara, double SatelliteModelStartTime) +{ + if (polySatellitePara.rows() != polynum||polySatellitePara.cols()!=6) { + throw exception("?????????????????"); + } + this->polySatellitePara = polySatellitePara; + this->SatelliteModelStartTime = SatelliteModelStartTime; + this->polynum = polynum; +} + +OrbitPoly::~OrbitPoly() +{ +} + +Eigen::MatrixX OrbitPoly::SatelliteSpacePoint(Eigen::MatrixX satellitetime) +{ + Eigen::MatrixX result= SatelliteSpacePoints(satellitetime, this->SatelliteModelStartTime, this->polySatellitePara, this->polynum); + return result; +} + +Eigen::MatrixX OrbitPoly::SatelliteSpacePoint(long double satellitetime) { + + if (this->polySatellitePara.rows() != polynum || this->polySatellitePara.cols() != 6) { + throw exception("the size of satellitetime has error!! row: p1,p2,p3,p4 col: x,y,z,vx,vy,vz "); + } + // ????????? + double satellitetime2 =double( satellitetime - this->SatelliteModelStartTime); + Eigen::MatrixX satetime(1, polynum); + for (int i = 0; i < polynum; i++) { + satetime(0, i) = pow(satellitetime2, i); + } + + // ???? + Eigen::MatrixX satellitePoints(1, 6); + satellitePoints = satetime * polySatellitePara; + return satellitePoints; +} + +/// +/// ???????????????????? +/// +/// ??????? +/// ?????????? +/// ??????[x1,y1,z1,vx1,vy1,vz1; x2,y2,z2,vx2,vy2,vz2; ..... ] +/// ?????????? +/// ???????? +Eigen::MatrixX SatelliteSpacePoints(Eigen::MatrixX& satellitetime, double SatelliteModelStartTime, Eigen::MatrixX& polySatellitePara, int polynum) +{ + if (satellitetime.cols() != 1) { + throw exception("the size of satellitetime has error!!"); + } + if (polySatellitePara.rows() != polynum || polySatellitePara.cols() != 6) { + throw exception("the size of satellitetime has error!! row: p1,p2,p3,p4 col: x,y,z,vx,vy,vz "); + } + // ????????? + int satellitetime_num = satellitetime.rows(); + satellitetime = satellitetime.array() - SatelliteModelStartTime; + Eigen::MatrixX satelliteTime(satellitetime_num, polynum); + for (int i = 0; i < polynum; i++) { + satelliteTime.col(i) = satellitetime.array().pow(i); + } + + // ???? + Eigen::MatrixX satellitePoints(satellitetime_num, 6); + satellitePoints = satelliteTime * polySatellitePara; + return satellitePoints; +} diff --git a/simorthoprogram-orth_s_sar-strip/SateOrbit.h b/simorthoprogram-orth_s_sar-strip/SateOrbit.h new file mode 100644 index 0000000..b1e6daf --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/SateOrbit.h @@ -0,0 +1,53 @@ +#pragma once +/// +/// 计算卫星轨道 +/// + +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 +#include "baseTool.h" + +#include +#include +#include +#include +//#include +//#include + + +using namespace std; +using namespace Eigen; +//using namespace arma; + + +/// +/// 多项式轨道模型 +/// +class OrbitPoly { +public: + //OrbitPoly(std::string orbitModelPath); + OrbitPoly(); + OrbitPoly(int polynum, Eigen::MatrixX polySatellitePara, double SatelliteModelStartTime); + ~OrbitPoly(); + + Eigen::MatrixX SatelliteSpacePoint(Eigen::MatrixX satellitetime); + Eigen::MatrixX SatelliteSpacePoint(long double satellitetime); +public: + int polynum; + Eigen::MatrixX polySatellitePara; + double SatelliteModelStartTime; +}; + + + +/// +/// 获取指定时刻的卫星轨道坐标 +/// +/// 卫星时刻 +/// 模型起算时间 +/// 模型参数[x1,y1,z1,vx1,vy1,vz1; x2,y2,z2,vx2,vy2,vz2; ..... ] +/// 模型参数数量 +/// 卫星坐标 +Eigen::MatrixX SatelliteSpacePoints(Eigen::MatrixX &satellitetime, double SatelliteModelStartTime, Eigen::MatrixX& polySatellitePara, int polynum = 4); diff --git a/simorthoprogram-orth_s_sar-strip/WGS84_J2000.cpp b/simorthoprogram-orth_s_sar-strip/WGS84_J2000.cpp new file mode 100644 index 0000000..e868836 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/WGS84_J2000.cpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include"WGS84_J2000.h" diff --git a/simorthoprogram-orth_s_sar-strip/WGS84_J2000.h b/simorthoprogram-orth_s_sar-strip/WGS84_J2000.h new file mode 100644 index 0000000..ae3e496 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/WGS84_J2000.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include diff --git a/simorthoprogram-orth_s_sar-strip/baseTool.cpp b/simorthoprogram-orth_s_sar-strip/baseTool.cpp new file mode 100644 index 0000000..6b89b76 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/baseTool.cpp @@ -0,0 +1,1328 @@ +#pragma once +/// +/// 锟斤拷锟斤拷锟洁、锟斤拷锟斤拷锟斤拷锟斤拷 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + + +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include < io.h > +#include < stdio.h > +#include < stdlib.h > +#include +#include +#include +//#include +#include //#include "ogrsf_frmts.h" +#include +#include +#include +#include +#include + +#include "baseTool.h" +using namespace std; +using namespace Eigen; +using namespace cv; + + + +/** + * @brief GetCurrentTime 锟斤拷取锟斤拷前时锟斤拷 + * @return + */ +std::string getCurrentTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + std::string strTime = mbstr; + return strTime; +} + +std::string getCurrentShortTimeString() { + struct tm ConversionTime; + std::time_t t = std::time(NULL); + char mbstr[100]; + _localtime64_s(&ConversionTime, &t); + std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %H:%M:%S", &ConversionTime); + std::string strTime = mbstr; + return strTime; +} + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon + p2.lon,p1.lat + p2.lat,p1.ati + p2.ati }; +} + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2) +{ + return Landpoint{ p1.lon - p2.lon,p1.lat - p2.lat,p1.ati - p2.ati }; +} + +bool operator ==(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat == p2.lat && p1.lon == p2.lon && p1.ati == p2.ati; +} + + + +Landpoint operator *(const Landpoint& p, double scale) +{ + return Landpoint{ + p.lon * scale, + p.lat * scale, + p.ati * scale + }; +} + +double getAngle(const Landpoint& a, const Landpoint& b) +{ + double c = dot(a, b) / (getlength(a) * getlength(b)); + if (a.lon * b.lat - a.lat * b.lon >= 0) { + return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } + else { + return 360 - acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; + } +} + +double dot(const Landpoint& p1, const Landpoint& p2) +{ + return p1.lat * p2.lat + p1.lon * p2.lon + p1.ati * p2.ati; +} + +double getlength(const Landpoint& p1) { + + return sqrt(dot(p1, p1)); +} + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b) { + return Landpoint{ + a.lat * b.ati - a.ati * b.lat,//x + a.ati * b.lon - a.lon * b.ati,//y + a.lon * b.lat - a.lat * b.lon//z + }; +} + +/// +/// 锟斤拷锟斤拷乇锟斤拷露锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟姐都锟斤拷WGS84锟斤拷锟斤拷系锟斤拷锟斤拷p1为锟斤拷锟姐, +/// 锟斤拷 N +/// W p1 +/// p4 p0 p2 E +/// p3 S +/// n21=n2xn1 +/// n=(n21+n32+n43+n41)*0.25; +/// +/// 目锟斤拷锟?1锟?7 +/// 锟斤拷围锟斤拷1 +/// 锟斤拷围锟斤拷2 +/// 锟斤拷围锟斤拷3 +/// 锟斤拷围锟斤拷4 +/// 锟斤拷锟斤拷锟角讹拷 +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4) { + + Landpoint n0 = LLA2XYZ(p0), + n1 = LLA2XYZ(p1), + n2 = LLA2XYZ(p2), + n3 = LLA2XYZ(p3), + n4 = LLA2XYZ(p4); + Landpoint n01 = n1 - n0, n02 = n2 - n0, n03 = n3 - n0, n04 = n4 - n0; + // 锟斤拷n01为锟斤拷锟斤拷锟斤拷锟斤拷 + Landpoint np01 = p1-p0, np02 = p2-p0, np03 = p3-p0, np04 = p4-p0; + double a2 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np02.lon,np02.lat,0 });// 01->02 锟斤拷时锟斤拷 + double a3 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np03.lon,np03.lat,0 });// 01->03 锟斤拷时锟斤拷 + double a4 = getAngle(Landpoint{ np01.lon,np01.lat,0 }, Landpoint{ np04.lon,np04.lat,0 });// 01->04 锟斤拷时锟斤拷 + //std::cout << a2 << "\t" << a3 << "\t" << a4 << endl; + a2 = 360 - a2; + a3 = 360 - a3; + a4 = 360 - a4; + Landpoint N, W, S, E; + N = n01; + if (a2 >= a3 && a2 >= a4) { + W = n02; + if (a3 >= a4) { + S = n03; + E = n04; + } + else { + S = n04; + E = n03; + } + } + else if (a3 >= a2 && a3 >= a4) { + W = n03; + if (a2 >= a4) { + S = n02; + E = n04; + } + else { + S = n04; + E = n02; + } + } + else if (a4 >= a2 && a4 >= a3) + { + W = n04; + if (a2 >= a3) { + S = n02; + E = n03; + } + else { + S = n03; + E = n02; + } + } + return (crossProduct(N, W) + crossProduct(W, S) + crossProduct(S, E) + crossProduct(E, N)) * 0.25; +} + +/// +/// 锟斤拷锟捷讹拷锟斤拷锟斤拷锟斤拷小 +/// p11 p12 p13 p14 +/// p21 p22 p23 p24 +/// p(2+u,2+v) +/// p31 p32 p33 p34 +/// p41 p42 p43 p44 +/// +/// 锟斤拷元锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟斤拷锟?1锟?7 +/// 锟斤拷元锟斤拷锟斤拷锟斤拷锟叫★拷锟斤拷锟斤拷锟?1锟?7 +/// 4x4 锟斤拷值锟斤拷锟斤拷 +/// +complex Cubic_Convolution_interpolation(double u, double v, Eigen::MatrixX> img) +{ + if (img.rows() != 4 || img.cols() != 4) { + throw exception("the size of img's block is not right"); + } + // 锟斤拷锟斤拷锟斤拷模锟斤拷 + Eigen::MatrixX> wrc(1, 4);// 使锟斤拷 complex 锟斤拷锟斤拷锟斤拷要原锟斤拷锟斤拷为锟剿伙拷取值 + Eigen::MatrixX> wcr(4, 1);// + for (int i = 0; i < 4; i++) { + wrc(0, i) = Cubic_kernel_weight(u+1-i); // u+1,u,u-1,u-2 + wcr(i, 0) = Cubic_kernel_weight(v + 1 - i); + } + + Eigen::MatrixX> interValue = wrc * img * wcr; + return interValue(0, 0); +} + +complex Cubic_kernel_weight(double s) +{ + s = abs(s); + if (s <= 1) { + return complex(1.5 * s * s * s - 2.5 * s * s + 1,0); + } + else if (s <= 2) { + return complex(-0.5 * s * s * s + 2.5 * s * s - 4 * s + 2,0); + } + else { + return complex(0,0); + } +} + +/// +/// p11 p12 -- x +/// p0(u,v) +/// p21 p22 +/// | +/// y +/// p11(0,0) +/// p21(0,1) +/// P12(1,0) +/// p22(1,1) +/// +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// x,y,z +/// +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22) +{ + + return p11.ati * (1 - p0.lon) * (1 - p0.lat) + + p12.ati * p0.lon * (1 - p0.lat) + + p21.ati * (1 - p0.lon) * p0.lat + + p22.ati * p0.lon * p0.lat; +} + + + + + +/// +/// 锟斤拷锟斤拷纬锟斤拷转锟斤拷为锟截固诧拷锟斤拷锟斤拷锟斤拷系 +/// +/// 锟斤拷纬锟饺碉拷--degree +/// 投影锟斤拷锟斤拷系锟斤拷 +Landpoint LLA2XYZ(const Landpoint& LLA) { + double L = LLA.lon * d2r; + double B = LLA.lat * d2r; + double H = LLA.ati; + + double sinB = sin(B); + double cosB = cos(B); + + //double N = a / sqrt(1 - e * e * sin(B) * sin(B)); + double N = a / sqrt(1 - eSquare * sinB * sinB); + Landpoint result = { 0,0,0 }; + result.lon = (N + H) * cosB * cos(L); + result.lat = (N + H) * cosB * sin(L); + //result.z = (N * (1 - e * e) + H) * sin(B); + result.ati = (N * (1 - 1/f_inverse)* (1 - 1 / f_inverse) + H) * sinB; + return result; +} + +/// +/// 锟斤拷锟斤拷n,3) lon,lat,ati +/// +/// +/// +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint) +{ + landpoint.col(0) = landpoint.col(0).array() * d2r; // lon + landpoint.col(1) = landpoint.col(1).array() * d2r; // lat + + Eigen::MatrixXd sinB = (landpoint.col(1).array().sin());//lat + Eigen::MatrixXd cosB = (landpoint.col(1).array().cos());//lat + + Eigen::MatrixXd N = a / ((1 - sinB.array().pow(2) * eSquare).array().sqrt()); + Eigen::MatrixXd result(landpoint.rows(), 3); + + result.col(0) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::cos(landpoint.col(0).array()).array(); //x + result.col(1) = (N.array() + landpoint.col(2).array()) * cosB.array() * Eigen::sin(landpoint.col(0).array()).array(); //y + + result.col(2) = (N.array() * (1 - 1/f_inverse)* (1 - 1 / f_inverse) + landpoint.col(2).array()) * sinB.array(); //z + + return result; +} + + +/// +/// 锟斤拷锟截固诧拷锟斤拷锟斤拷锟斤拷系转锟斤拷为锟斤拷纬锟斤拷 +/// +/// 锟教诧拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷纬锟斤拷--degree +Landpoint XYZ2LLA(const Landpoint& XYZ) { + double tmpX = XYZ.lon;// 锟斤拷锟斤拷 x + double temY = XYZ.lat;// 纬锟斤拷 y + double temZ = XYZ.ati; + + double curB = 0; + double N = 0; + double sqrtTempXY = sqrt(tmpX * tmpX + temY * temY); + double calB = atan2(temZ, sqrtTempXY); + int counter = 0; + double sinCurB = 0; + while (abs(curB - calB) * r2d > epsilon && counter < 25) + { + curB = calB; + sinCurB = sin(curB); + N = a / sqrt(1 - eSquare * sinCurB * sinCurB); + calB = atan2(temZ + N * eSquare * sinCurB, sqrtTempXY); + counter++; + } + + Landpoint result = { 0,0,0 }; + result.lon = atan2(temY, tmpX) * r2d; + result.lat = curB * r2d; + result.ati = temZ / sinCurB - N * (1 - eSquare); + return result; +} + +/// +/// 锟斤拷锟斤拷图锟斤拷锟饺∮帮拷锟?1锟?7 +/// +/// +gdalImage::gdalImage(string raster_path) +{ + omp_lock_t lock; + omp_init_lock(&lock); // 锟斤拷始锟斤拷锟斤拷锟斤拷锟斤拷 + omp_set_lock(&lock); //锟斤拷没锟斤拷锟斤拷锟?1锟?7 + this->img_path = raster_path; + + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + // 锟斤拷DEM影锟斤拷 + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(raster_path.c_str(), 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]; + + this->projection = rasterDataset->GetProjectionRef(); + // 锟斤拷锟斤拷锟斤拷锟斤拷 + //double* inv_gt = new double[6];; + //GDALInvGeoTransform(gt, inv_gt); // 锟斤拷锟斤拷锟斤拷锟斤拷 + // 锟斤拷锟斤拷投影 + GDALFlushCache((GDALDatasetH)rasterDataset); + GDALClose((GDALDatasetH)rasterDataset); + rasterDataset = NULL;// 指锟斤拷锟矫匡拷 + this->InitInv_gt(); + delete[] gt; + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 +} + +gdalImage::~gdalImage() +{ +} + +void gdalImage::setHeight(int height) +{ + this->height = height; +} + +void gdalImage::setWidth(int width) +{ + this->width = width; +} + +void gdalImage::setTranslationMatrix(Eigen::MatrixXd gt) +{ + this->gt = gt; +} + +void gdalImage::setData(Eigen::MatrixXd data) +{ + this->data = data; +} + +Eigen::MatrixXd gdalImage::getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids = 1) +{ + omp_lock_t lock; + omp_init_lock(&lock); + omp_set_lock(&lock); + GDALAllRegister(); + + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_ReadOnly));//锟斤拷只锟斤拷锟斤拷式锟斤拷取锟斤拷锟斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* demBand = rasterDataset->GetRasterBand(band_ids); + + rows_count = start_row + rows_count <= this->height ? rows_count : this->height - start_row; + cols_count = start_col + cols_count <= this->width ? cols_count : this->width - start_col; + + MatrixXd datamatrix(rows_count, cols_count); + + + if (gdal_datatype == GDALDataType::GDT_UInt16) { + + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + + for (int i = 0; i < rows_count; i++) { + for (int j = 0; j < cols_count; j++) { + datamatrix(i, j) = temp[i * cols_count + j]; + } + } + delete[] temp; + } + GDALClose((GDALDatasetH)rasterDataset); + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 + //GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return datamatrix; + +} + +/// +/// 写锟斤拷遥锟斤拷影锟斤拷 +/// +/// +/// +/// +/// +void gdalImage::saveImage(Eigen::MatrixXd data, int start_row = 0, int start_col = 0, int band_ids = 1) +{ + 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) { + string tip = "file path: " + this->img_path; + throw exception(tip.c_str()); + } + GDALAllRegister(); + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = nullptr; + if (boost::filesystem::exists(this->img_path)) { + poDstDS = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_Update)); + } + else { + poDstDS = poDriver->Create(this->img_path.c_str(), this->width, this->height, this->band_num, GDT_Float32, NULL); // 锟斤拷锟斤拷锟斤拷 + poDstDS->SetProjection(this->projection.c_str()); + + + 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(); + + float* databuffer = new float[datarows * datacols];// (float*)malloc(datarows * datacols * sizeof(float)); + + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + float temp = float(data(i, j)); + databuffer[i * datacols + j] = temp; + } + } + //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_Float32, 0, 0); + + GDALFlushCache(poDstDS); + GDALClose((GDALDatasetH)poDstDS); + //GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + delete[] databuffer; + omp_unset_lock(&lock); //锟酵放伙拷锟斤拷锟斤拷 + omp_destroy_lock(&lock); //锟斤拷锟劫伙拷锟斤拷锟斤拷 +} + +void gdalImage::saveImage() +{ + this->saveImage(this->data, this->start_row, this->start_col, this->data_band_ids); +} + +void gdalImage::setNoDataValue(double nodatavalue = -9999, int band_ids = 1) +{ + + + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + //GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = (GDALDataset*)(GDALOpen(img_path.c_str(), GA_Update)); + poDstDS->GetRasterBand(band_ids)->SetNoDataValue(nodatavalue); + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); +} + +int gdalImage::InitInv_gt() +{ + //1 lon lat = x + //1 lon lat = y + Eigen::MatrixXd temp(2, 3); + this->inv_gt = temp; + double a = this->gt(0, 0); + double b = this->gt(0, 1); + double c = this->gt(0, 2); + double d = this->gt(1, 0); + double e = this->gt(1, 1); + double f = this->gt(1, 2); + double g = 1; + double det_gt = b * f - c * e; + if (det_gt == 0) { + return 0; + } + this->inv_gt(0, 0) = (c * d - a * f) / det_gt; //2 + this->inv_gt(0, 1) = f / det_gt; // lon + this->inv_gt(0, 2) = -c / det_gt; // lat + this->inv_gt(1, 0) = (a*e-b*d) / det_gt; //1 + this->inv_gt(1, 1) = -e / det_gt; // lon + this->inv_gt(1, 2) = b / det_gt; // lat + return 1; +} + +Landpoint gdalImage::getRow_Col(double lon, double lat) +{ + Landpoint p{ 0,0,0 }; + p.lon = this->inv_gt(0, 0) + lon * this->inv_gt(0, 1) + lat * this->inv_gt(0, 2); //x + p.lat = this->inv_gt(1, 0) + lon * this->inv_gt(1, 1) + lat * this->inv_gt(1, 2); //y + return p; +} + +Landpoint gdalImage::getLandPoint(double row, double col, double ati = 0) +{ + Landpoint p{ 0,0,0 }; + p.lon = this->gt(0, 0) + col * this->gt(0, 1) + row * this->gt(0, 2); //x + p.lat = this->gt(1, 0) + col * this->gt(1, 1) + row * this->gt(1, 2); //y + p.ati = ati; + return p; +} + +double gdalImage::mean(int bandids ) +{ + double mean_value = 0; + double count = this->height* this->width; + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + mean_value = mean_value+ sar_a.sum() / count; + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return mean_value; +} + +double gdalImage::max(int bandids) +{ + double max_value = 0; + bool state_max = true; + int line_invert = 100; + int start_ids = 0; + double temp_max = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_max) { + state_max = false; + max_value = sar_a.maxCoeff(); + } + else { + temp_max= sar_a.maxCoeff(); + if (max_value < temp_max) { + max_value = temp_max; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return max_value; +} + +double gdalImage::min(int bandids) +{ + double min_value = 0; + bool state_min = true; + int line_invert = 100; + int start_ids = 0; + double temp_min = 0; + do { + Eigen::MatrixXd sar_a = this->getData(start_ids, 0, line_invert, this->width, bandids); + if (state_min) { + state_min = false; + min_value = sar_a.minCoeff(); + } + else { + temp_min = sar_a.minCoeff(); + if (min_value < temp_min) { + min_value = temp_min; + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->height); + return min_value; +} + +GDALRPCInfo gdalImage::getRPC() +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister();//注锟斤拷锟斤拷锟斤拷 + //锟斤拷锟斤拷锟斤拷 + GDALDataset* pDS = (GDALDataset*)GDALOpen(this->img_path.c_str(), GA_ReadOnly); + //锟斤拷元锟斤拷锟斤拷锟叫伙拷取RPC锟斤拷息 + char** papszRPC = pDS->GetMetadata("RPC"); + + //锟斤拷锟斤拷取锟斤拷RPC锟斤拷息锟斤拷锟斤拷山峁癸拷锟?1锟?7 + GDALRPCInfo oInfo; + GDALExtractRPCInfo(papszRPC, &oInfo); + + GDALClose((GDALDatasetH)pDS); + + return oInfo; +} + +Eigen::MatrixXd gdalImage::getLandPoint(Eigen::MatrixXd points) +{ + if (points.cols() != 3) { + throw new exception("the size of points is equit 3!!!"); + } + + Eigen::MatrixXd result(points.rows(), 3); + result.col(2) = points.col(2);// 锟竭筹拷 + points.col(2) = points.col(2).array() * 0 + 1; + points.col(0).swap(points.col(2));// 锟斤拷锟斤拷 + Eigen::MatrixXd gts(3, 2); + gts.col(0) = this->gt.row(0); + gts.col(1) = this->gt.row(1); + //cout << this->gt(0, 0) << "\t" << this->gt(0, 1) << "\t" << this->gt(0, 2) << endl;; + //cout << gts(0, 0) << "\t" << gts(1,0) << "\t" << gts(2, 0) << endl;; + //cout << this->gt(1, 0) << "\t" << this->gt(1, 1) << "\t" << this->gt(1, 2) << endl;; + //cout<< gts(0, 1) << "\t" << gts(1, 1) << "\t" << gts(2,1) << endl;; + //cout << points(3, 0) << "\t" << points(3, 1) << "\t" << points(3, 2) << endl;; + + + result.block(0, 0, points.rows(), 2) = points * gts; + return result; +} + +Eigen::MatrixXd gdalImage::getHist(int bandids) +{ + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + // 锟斤拷DEM影锟斤拷 + GDALDataset* rasterDataset = (GDALDataset*)(GDALOpen(this->img_path.c_str(), GA_ReadOnly));//锟斤拷只锟斤拷锟斤拷式锟斤拷取锟斤拷锟斤拷影锟斤拷 + + GDALDataType gdal_datatype = rasterDataset->GetRasterBand(1)->GetRasterDataType(); + GDALRasterBand* xBand = rasterDataset->GetRasterBand(bandids); + + //锟斤拷取图锟斤拷直锟斤拷图 + + double dfMin = this->min(bandids); + double dfMax = this->max(bandids); + int count = int((dfMax - dfMin) / 0.01); + count = count > 255 ? count : 255; + GUIntBig* panHistogram =new GUIntBig[count]; + xBand->GetHistogram(dfMin, dfMax, count, panHistogram, TRUE, FALSE, NULL, NULL); + Eigen::MatrixXd result(count, 2); + double delta = (dfMax - dfMin) / count; + for (int i = 0; i < count; i++) { + result(i, 0) = dfMin + i * delta; + result(i, 1) = double(panHistogram[i]); + } + delete[] panHistogram; + GDALClose((GDALDatasetH)rasterDataset); + return result; +} + + +gdalImage CreategdalImage(string img_path, int height, int width, int band_num, Eigen::MatrixXd gt, std::string projection, bool need_gt) { + + if (boost::filesystem::exists(img_path.c_str())) { + boost::filesystem::remove(img_path.c_str()); + } + GDALAllRegister();// 注锟斤拷锟绞斤拷锟斤拷锟斤拷锟?1锟?7 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* poDstDS = poDriver->Create(img_path.c_str(), width, height, band_num, GDT_Float32, NULL); // 锟斤拷锟斤拷锟斤拷 + if (need_gt) { + poDstDS->SetProjection(projection.c_str()); + + // 锟斤拷锟斤拷转锟斤拷锟斤拷锟斤拷 + double gt_ptr[6] = { 0 }; + for (int i = 0; i < gt.rows(); i++) { + for (int j = 0; j < gt.cols(); j++) { + gt_ptr[i * 3 + j] = gt(i, j); + } + } + poDstDS->SetGeoTransform(gt_ptr); + } + for (int i = 1; i <= band_num; i++) { + poDstDS->GetRasterBand(i)->SetNoDataValue(-9999); + } + GDALFlushCache((GDALDatasetH)poDstDS); + GDALClose((GDALDatasetH)poDstDS); + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + gdalImage result_img(img_path); + return result_img; +} + + +/// +/// 锟矫硷拷DEM +/// +/// +/// +/// +/// +void clipGdalImage(string in_path, string out_path, DemBox box, double pixelinterval) { + + + + +} + + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly); + if (pDSrc == NULL) + { + return -1; + } + + GDALDriver* pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + if (pDriver == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int nBandCount = pDSrc->GetRasterCount(); + GDALDataType dataType = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + char* pszSrcWKT = NULL; + pszSrcWKT = const_cast(pDSrc->GetProjectionRef()); + + //锟斤拷锟矫伙拷锟酵队帮拷锟斤拷锟轿?拷锟斤拷锟揭伙拷锟?1锟?7 + if (strlen(pszSrcWKT) <= 0) + { + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + //oSRS.SetUTM(50, true); //锟斤拷锟斤拷锟斤拷 锟斤拷锟斤拷120锟斤拷 + //oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + } + std::cout << "GDALCreateGenImgProjTransformer " << endl; + void* hTransformArg; + hTransformArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, NULL, pszSrcWKT, FALSE, 0.0, 1); + std::cout << "no proj " << endl; + //(没锟斤拷投影锟斤拷影锟斤拷锟斤拷锟斤拷锟斤拷卟锟酵?拷锟?1锟?7) + if (hTransformArg == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + std::cout << "has proj " << endl; + double dGeoTrans[6] = { 0 }; + int nNewWidth = 0, nNewHeight = 0; + if (GDALSuggestedWarpOutput((GDALDatasetH)pDSrc, GDALGenImgProjTransform, hTransformArg, dGeoTrans, &nNewWidth, &nNewHeight) != CE_None) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -3; + } + + //GDALDestroyGenImgProjTransformer(hTransformArg); + + //锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷菁锟?1锟?7 + GDALDataset* pDDst = pDriver->Create(pszOutFile, new_width, new_height, nBandCount, dataType, NULL); + if (pDDst == NULL) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + return -2; + } + + pDDst->SetProjection(pszSrcWKT); + pDDst->SetGeoTransform(gt); + + GDALWarpOptions* psWo = GDALCreateWarpOptions(); + + //psWo->papszWarpOptions = CSLDuplicate(NULL); + psWo->eWorkingDataType = dataType; + psWo->eResampleAlg = eResample; + + psWo->hSrcDS = (GDALDatasetH)pDSrc; + psWo->hDstDS = (GDALDatasetH)pDDst; + std::cout << "GDALCreateGenImgProjTransformer" << endl; + psWo->pfnTransformer = GDALGenImgProjTransform; + psWo->pTransformerArg = GDALCreateGenImgProjTransformer((GDALDatasetH)pDSrc, pszSrcWKT, (GDALDatasetH)pDDst, pszSrcWKT, FALSE, 0.0, 1);; + + std::cout << "GDALCreateGenImgProjTransformer has created" << endl; + psWo->nBandCount = nBandCount; + psWo->panSrcBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + psWo->panDstBands = (int*)CPLMalloc(nBandCount * sizeof(int)); + for (int i = 0; i < nBandCount; i++) + { + psWo->panSrcBands[i] = i + 1; + psWo->panDstBands[i] = i + 1; + } + + GDALWarpOperation oWo; + if (oWo.Initialize(psWo) != CE_None) + { + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + return -3; + } + std::cout << "ChunkAndWarpImage:"<< new_width<<","<< new_height << endl; + oWo.ChunkAndWarpMulti(0, 0, new_width, new_height); + GDALFlushCache(pDDst); + std::cout << "ChunkAndWarpImage over" << endl; + //GDALDestroyGenImgProjTransformer(psWo->pTransformerArg); + //GDALDestroyWarpOptions(psWo); + GDALClose((GDALDatasetH)(GDALDatasetH)pDSrc); + GDALClose((GDALDatasetH)(GDALDatasetH)pDDst); + ////GDALDestroy(); // or, DllMain at DLL_PROCESS_DETACH + return 0; +} + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample) +{ + GDALAllRegister(); + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + GDALDataset* pDSrc = (GDALDataset*)GDALOpen(pszSrcFile, GA_Update); + if (pDSrc == NULL) + { + return -1; + } + + GDALDataType gdal_datatype = pDSrc->GetRasterBand(1)->GetRasterDataType(); + + GDALRasterBand* demBand = pDSrc->GetRasterBand(band_ids); + + int width = pDSrc->GetRasterXSize(); + int height = pDSrc->GetRasterYSize(); + int start_col = 0, start_row = 0, rows_count = 0, cols_count; + + int row_delta = int(120000000 / width); + + GDALRasterIOExtraArg psExtraArg; + INIT_RASTERIO_EXTRA_ARG(psExtraArg); + psExtraArg.eResampleAlg = eResample; + + do { + + rows_count = start_row + row_delta < height ? row_delta : height - start_row; + cols_count = width; + + if (gdal_datatype == GDALDataType::GDT_UInt16) { + + unsigned short* temp = new unsigned short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + + } + else if (gdal_datatype == GDALDataType::GDT_Int16) { + + short* temp = new short[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + else if (gdal_datatype == GDALDataType::GDT_Float32) { + float* temp = new float[rows_count * cols_count]; + demBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0); + demBand->RasterIO(GF_Write, start_col, start_row, cols_count, rows_count, temp, cols_count, rows_count, gdal_datatype, 0, 0, &psExtraArg); + delete[] temp; + } + start_row = start_row + rows_count; + } while (start_row < height); + GDALClose((GDALDatasetH)pDSrc); + + + return 0; +} + + +string Convert(float Num) +{ + ostringstream oss; + oss << Num; + string str(oss.str()); + return str; +} + + + +std::string JoinPath(const std::string& path, const std::string& filename) +{ + int dir_size = path.size(); + + int last_sprt_index = path.find_last_of('\\'); + int last_is_sprt = (last_sprt_index == dir_size - 1); + + if (last_is_sprt) + { + return path + filename; + } + else + { + return path + "\\" + filename; + } +} + + + + +/// +////////////////////////////////////////////////////////////////////// WGS84 to J2000 ///////////////////////////////////////////////////////////////////////////////////////// +/// +/* +Eigen::Matrix WGS84_J2000::IAU2000ModelParams = Eigen::Matrix(); + +WGS84_J2000::WGS84_J2000() +{ + WGS84_J2000::IAU2000ModelParams << 0.0, 0.0, 0.0, 0.0, 1.0, -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0, + 0.0, 0.0, 2.0, -2.0, 2.0, -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0, + 0.0, 0.0, 2.0, 0.0, 2.0, -2276413.0, -234.0, 2796.0, 978459.0, -485.0, 1374.0, + 0.0, 0.0, 0.0, 0.0, 2.0, 2074554.0, 207.0, -698.0, -897492.0, 470.0, -291.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 1475877.0, -3633.0, 11817.0, 73871.0, -184.0, -1924.0, + 0.0, 1.0, 2.0, -2.0, 2.0, -516821.0, 1226.0, -524.0, 224386.0, -677.0, -174.0, + 1.0, 0.0, 0.0, 0.0, 0.0, 711159.0, 73.0, -872.0, -6750.0, 0.0, 358.0, + 0.0, 0.0, 2.0, 0.0, 1.0, -387298.0, -367.0, 380.0, 200728.0, 18.0, 318.0, + 1.0, 0.0, 2.0, 0.0, 2.0, -301461.0, -36.0, 816.0, 129025.0, -63.0, 367.0, + 0.0, -1.0, 2.0, -2.0, 2.0, 215829.0, -494.0, 111.0, -95929.0, 299.0, 132.0, + 0.0, 0.0, 2.0, -2.0, 1.0, 128227.0, 137.0, 181.0, -68982.0, -9.0, 39.0, + -1.0, 0.0, 2.0, 0.0, 2.0, 123457.0, 11.0, 19.0, -53311.0, 32.0, -4.0, + -1.0, 0.0, 0.0, 2.0, 0.0, 156994.0, 10.0, -168.0, -1235.0, 0.0, 82.0, + 1.0, 0.0, 0.0, 0.0, 1.0, 63110.0, 63.0, 27.0, -33228.0, 0.0, -9.0, + -1.0, 0.0, 0.0, 0.0, 1.0, -57976.0, -63.0, -189.0, 31429.0, 0.0, -75.0, + -1.0, 0.0, 2.0, 2.0, 2.0, -59641.0, -11.0, 149.0, 25543.0, -11.0, 66.0, + 1.0, 0.0, 2.0, 0.0, 1.0, -51613.0, -42.0, 129.0, 26366.0, 0.0, 78.0, + -2.0, 0.0, 2.0, 0.0, 1.0, 45893.0, 50.0, 31.0, -24236.0, -10.0, 20.0, + 0.0, 0.0, 0.0, 2.0, 0.0, 63384.0, 11.0, -150.0, -1220.0, 0.0, 29.0, + 0.0, 0.0, 2.0, 2.0, 2.0, -38571.0, -1.0, 158.0, 16452.0, -11.0, 68.0, + 0.0, -2.0, 2.0, -2.0, 2.0, 32481.0, 0.0, 0.0, -13870.0, 0.0, 0.0, + -2.0, 0.0, 0.0, 2.0, 0.0, -47722.0, 0.0, -18.0, 477.0, 0.0, -25.0, + 2.0, 0.0, 2.0, 0.0, 2.0, -31046.0, -1.0, 131.0, 13238.0, -11.0, 59.0, + 1.0, 0.0, 2.0, -2.0, 2.0, 28593.0, 0.0, -1.0, -12338.0, 10.0, -3.0, + -1.0, 0.0, 2.0, 0.0, 1.0, 20441.0, 21.0, 10.0, -10758.0, 0.0, -3.0, + 2.0, 0.0, 0.0, 0.0, 0.0, 29243.0, 0.0, -74.0, -609.0, 0.0, 13.0, + 0.0, 0.0, 2.0, 0.0, 0.0, 25887.0, 0.0, -66.0, -550.0, 0.0, 11.0, + 0.0, 1.0, 0.0, 0.0, 1.0, -14053.0, -25.0, 79.0, 8551.0, -2.0, -45.0, + -1.0, 0.0, 0.0, 2.0, 1.0, 15164.0, 10.0, 11.0, -8001.0, 0.0, -1.0, + 0.0, 2.0, 2.0, -2.0, 2.0, -15794.0, 72.0, -16.0, 6850.0, -42.0, -5.0, + 0.0, 0.0, -2.0, 2.0, 0.0, 21783.0, 0.0, 13.0, -167.0, 0.0, 13.0, + 1.0, 0.0, 0.0, -2.0, 1.0, -12873.0, -10.0, -37.0, 6953.0, 0.0, -14.0, + 0.0, -1.0, 0.0, 0.0, 1.0, -12654.0, 11.0, 63.0, 6415.0, 0.0, 26.0, + -1.0, 0.0, 2.0, 2.0, 1.0, -10204.0, 0.0, 25.0, 5222.0, 0.0, 15.0, + 0.0, 2.0, 0.0, 0.0, 0.0, 16707.0, -85.0, -10.0, 168.0, -1.0, 10.0, + 1.0, 0.0, 2.0, 2.0, 2.0, -7691.0, 0.0, 44.0, 3268.0, 0.0, 19.0, + -2.0, 0.0, 2.0, 0.0, 0.0, -11024.0, 0.0, -14.0, 104.0, 0.0, 2.0, + 0.0, 1.0, 2.0, 0.0, 2.0, 7566.0, -21.0, -11.0, -3250.0, 0.0, -5.0, + 0.0, 0.0, 2.0, 2.0, 1.0, -6637.0, -11.0, 25.0, 3353.0, 0.0, 14.0, + 0.0, -1.0, 2.0, 0.0, 2.0, -7141.0, 21.0, 8.0, 3070.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 2.0, 1.0, -6302.0, -11.0, 2.0, 3272.0, 0.0, 4.0, + 1.0, 0.0, 2.0, -2.0, 1.0, 5800.0, 10.0, 2.0, -3045.0, 0.0, -1.0, + 2.0, 0.0, 2.0, -2.0, 2.0, 6443.0, 0.0, -7.0, -2768.0, 0.0, -4.0, + -2.0, 0.0, 0.0, 2.0, 1.0, -5774.0, -11.0, -15.0, 3041.0, 0.0, -5.0, + 2.0, 0.0, 2.0, 0.0, 1.0, -5350.0, 0.0, 21.0, 2695.0, 0.0, 12.0, + 0.0, -1.0, 2.0, -2.0, 1.0, -4752.0, -11.0, -3.0, 2719.0, 0.0, -3.0, + 0.0, 0.0, 0.0, -2.0, 1.0, -4940.0, -11.0, -21.0, 2720.0, 0.0, -9.0, + -1.0, -1.0, 0.0, 2.0, 0.0, 7350.0, 0.0, -8.0, -51.0, 0.0, 4.0, + 2.0, 0.0, 0.0, -2.0, 1.0, 4065.0, 0.0, 6.0, -2206.0, 0.0, 1.0, + 1.0, 0.0, 0.0, 2.0, 0.0, 6579.0, 0.0, -24.0, -199.0, 0.0, 2.0, + 0.0, 1.0, 2.0, -2.0, 1.0, 3579.0, 0.0, 5.0, -1900.0, 0.0, 1.0, + 1.0, -1.0, 0.0, 0.0, 0.0, 4725.0, 0.0, -6.0, -41.0, 0.0, 3.0, + -2.0, 0.0, 2.0, 0.0, 2.0, -3075.0, 0.0, -2.0, 1313.0, 0.0, -1.0, + 3.0, 0.0, 2.0, 0.0, 2.0, -2904.0, 0.0, 15.0, 1233.0, 0.0, 7.0, + 0.0, -1.0, 0.0, 2.0, 0.0, 4348.0, 0.0, -10.0, -81.0, 0.0, 2.0, + 1.0, -1.0, 2.0, 0.0, 2.0, -2878.0, 0.0, 8.0, 1232.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 1.0, 0.0, -4230.0, 0.0, 5.0, -20.0, 0.0, -2.0, + -1.0, -1.0, 2.0, 2.0, 2.0, -2819.0, 0.0, 7.0, 1207.0, 0.0, 3.0, + -1.0, 0.0, 2.0, 0.0, 0.0, -4056.0, 0.0, 5.0, 40.0, 0.0, -2.0, + 0.0, -1.0, 2.0, 2.0, 2.0, -2647.0, 0.0, 11.0, 1129.0, 0.0, 5.0, + -2.0, 0.0, 0.0, 0.0, 1.0, -2294.0, 0.0, -10.0, 1266.0, 0.0, -4.0, + 1.0, 1.0, 2.0, 0.0, 2.0, 2481.0, 0.0, -7.0, -1062.0, 0.0, -3.0, + 2.0, 0.0, 0.0, 0.0, 1.0, 2179.0, 0.0, -2.0, -1129.0, 0.0, -2.0, + -1.0, 1.0, 0.0, 1.0, 0.0, 3276.0, 0.0, 1.0, -9.0, 0.0, 0.0, + 1.0, 1.0, 0.0, 0.0, 0.0, -3389.0, 0.0, 5.0, 35.0, 0.0, -2.0, + 1.0, 0.0, 2.0, 0.0, 0.0, 3339.0, 0.0, -13.0, -107.0, 0.0, 1.0, + -1.0, 0.0, 2.0, -2.0, 1.0, -1987.0, 0.0, -6.0, 1073.0, 0.0, -2.0, + 1.0, 0.0, 0.0, 0.0, 2.0, -1981.0, 0.0, 0.0, 854.0, 0.0, 0.0, + -1.0, 0.0, 0.0, 1.0, 0.0, 4026.0, 0.0, -353.0, -553.0, 0.0, -139.0, + 0.0, 0.0, 2.0, 1.0, 2.0, 1660.0, 0.0, -5.0, -710.0, 0.0, -2.0, + -1.0, 0.0, 2.0, 4.0, 2.0, -1521.0, 0.0, 9.0, 647.0, 0.0, 4.0, + -1.0, 1.0, 0.0, 1.0, 1.0, 1314.0, 0.0, 0.0, -700.0, 0.0, 0.0, + 0.0, -2.0, 2.0, -2.0, 1.0, -1283.0, 0.0, 0.0, 672.0, 0.0, 0.0, + 1.0, 0.0, 2.0, 2.0, 1.0, -1331.0, 0.0, 8.0, 663.0, 0.0, 4.0, + -2.0, 0.0, 2.0, 2.0, 2.0, 1383.0, 0.0, -2.0, -594.0, 0.0, -2.0, + -1.0, 0.0, 0.0, 0.0, 2.0, 1405.0, 0.0, 4.0, -610.0, 0.0, 2.0, + 1.0, 1.0, 2.0, -2.0, 2.0, 1290.0, 0.0, 0.0, -556.0, 0.0, 0.0; +} +WGS84_J2000::~WGS84_J2000() +{ + +} +/// +/// step1 WGS 84 转锟斤拷锟斤拷协锟斤拷锟斤拷锟斤拷锟斤拷锟较碉拷锟?1锟?7 +/// 锟斤拷鼐锟轿筹拷雀叱锟紹LH锟斤拷毓锟斤拷锟斤拷锟较碉拷锟阶?拷锟?1锟?7 BLH-- > XG +/// ECEF, Earth Centered Earth Fixed; 锟截癸拷锟斤拷锟斤拷系 锟轿匡拷平锟芥:平锟斤拷锟斤拷妫?拷锟斤拷锟斤拷锟斤拷模锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷CIO锟斤拷锟斤拷锟竭达拷直锟斤拷平锟芥。 +/// x锟斤拷为锟轿匡拷平锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟狡斤拷娼伙拷撸锟絲锟斤拷为锟斤拷锟斤拷指锟斤拷CIO锟姐。 +/// +/// B L H锟街憋拷为锟斤拷锟轿筹拷取锟斤拷锟截撅拷锟饺和达拷馗叱锟?1锟?7 锟斤拷锟斤拷锟斤拷锟轿狽 * 3锟斤拷锟斤拷 +/// XYZ 为锟截癸拷锟斤拷锟斤拷系锟斤拷 x y z锟斤拷锟斤拷锟斤拷锟斤拷锟轿狽 * 3锟斤拷锟斤拷 +Eigen::MatrixXd WGS84_J2000::WGS84TECEF(Eigen::MatrixXd LBH_deg_m) +{ + return LLA2XYZ(LBH_deg_m); +} +/// +/// step 2 协锟斤拷锟斤拷锟斤拷锟斤拷锟较?1锟?7 转锟斤拷为瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷锟斤拷要锟芥及锟斤拷询 锟斤拷锟斤拷时锟教碉拷 xp,yp , 锟斤拷锟皆诧拷询EOP锟侥硷拷锟斤拷茫锟斤拷锟斤拷氐锟街凤拷锟斤拷锟絟ttp://celestrak.com/spacedata/ +/// earthFixedXYZ=ordinateSingleRotate('x',yp)*ordinateSingleRotate('y',xp)*earthFixedXYZ; +/// +/// axis 锟斤拷示围锟斤拷锟斤拷转锟斤拷锟斤拷锟斤拷锟斤拷 '1' 锟斤拷示围锟斤拷 x锟斤拷锟斤拷时锟斤拷锟斤拷转;'2' 锟斤拷示围锟斤拷 y锟斤拷锟斤拷时锟斤拷锟斤拷转;'3'锟斤拷示围锟斤拷 z锟斤拷锟斤拷时锟斤拷锟斤拷转 +/// angle_deg 锟斤拷示锟斤拷转锟侥角讹拷 默锟斤拷 degree +/// +Eigen::MatrixXd WGS84_J2000::ordinateSingleRotate(int axis, double angle_deg) +{ + angle_deg = angle_deg * d2r; + Eigen::MatrixXd R = Eigen::MatrixXd::Ones(3, 3); + switch (axis) + { + case 1: // x + R << 1, 0.0, 0.0, + 0.0, cos(angle_deg), sin(angle_deg), + 0.0, -1 * sin(angle_deg), cos(angle_deg); + break; + case 2:// y + R << cos(angle_deg), 0.0, -1 * sin(angle_deg), + 0.0, 1, 0.0, + sin(angle_deg), 0.0, cos(angle_deg); + break; + case 3:// z + R << cos(angle_deg), sin(angle_deg), 0.0, + -1 * sin(angle_deg), cos(angle_deg), 0.0, + 0.0, 0.0, 1; + break; + default: + throw exception("Error Axis"); + exit(-1); + } + return R; +} + +/// +/// step 3 瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷为 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 +/// 锟斤拷utc时锟斤拷转锟斤拷为锟斤拷锟斤拷锟斤拷锟轿猴拷锟斤拷时 +/// xyz= ordinateSingleRotate('z',-gst_deg)*earthFixedXYZ; +/// UNTITLED 锟斤拷锟姐当锟截猴拷锟斤拷时,锟斤拷锟斤拷值锟斤拷时锟斤拷为锟斤拷位 +/// %dAT 锟斤拷锟斤拷锟斤拷 +/// % TAI锟斤拷锟斤拷原锟斤拷时锟斤拷 锟斤拷时锟斤拷锟斤拷准 TAI = UTC + dAT;% 锟斤拷锟斤拷原锟斤拷时锟斤拷 +/// % TT 锟斤拷锟斤拷时 TT = TAI + 32.184 锟斤拷2014锟斤拷锟绞憋拷锟?1锟?7; +/// % TDT 锟斤拷锟斤拷锟斤拷学时锟斤拷 +/// % ET 锟斤拷锟斤拷时锟斤拷 +/// % 锟斤拷锟斤拷时 = 锟斤拷锟斤拷锟斤拷学时锟斤拷 = 锟斤拷锟斤拷时锟斤拷 +/// %锟斤拷锟斤拷时=锟斤拷锟斤拷锟斤拷学时锟斤拷=锟斤拷锟斤拷时锟斤拷 +/// +/// 锟斤拷式为y m d 锟斤拷锟斤拷d锟斤拷锟斤拷值为小锟斤拷锟斤拷锟斤拷h m s 锟斤拷锟斤拷sec/3600+min/60+h)/24转锟斤拷锟斤拷小锟斤拷锟斤拷锟斤拷锟桔加碉拷day 锟斤拷 +/// dUT1 为ut1-utc 锟侥差,锟斤拷值锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷1锟诫,锟斤拷iers锟缴伙拷锟斤拷锟街?1锟?7 0 +/// 锟斤拷锟斤拷锟斤拷 37 +/// 锟斤拷锟斤拷原锟斤拷时锟斤拷 锟斤拷时锟斤拷锟斤拷准 TAI=UTC+dAT; %锟斤拷锟斤拷原锟斤拷时锟斤拷 +/// 锟斤拷锟斤拷时 TT = TAI+32.184 锟斤拷2014锟斤拷锟绞憋拷锟?1锟?7; +/// +int WGS84_J2000::utc2gst(Eigen::MatrixXd UTC, double dUT1, double dAT, double& gst_deg, double& JDTDB) +{ + + //function[gst_deg, JDTDB] = utc2gst(UTC, dUT1, dAT) + //% TDT 锟斤拷锟斤拷锟斤拷学时锟斤拷 + // % ET 锟斤拷锟斤拷时锟斤拷 + // % 锟斤拷锟斤拷时 = 锟斤拷锟斤拷锟斤拷学时锟斤拷 = 锟斤拷锟斤拷时锟斤拷 + double J2000 = 2451545; + + double JDutc = YMD2JD(UTC(0,0), UTC(0,1), UTC(0,2)); + double JDUT1 = JDutc + dUT1 / 86400;// % UT1 为锟斤拷锟斤拷时锟斤拷锟斤拷锟斤拷时锟斤拷锟斤拷锟斤拷转锟侥诧拷锟斤拷锟饺o拷锟斤拷锟斤拷锟経TC时锟斤拷锟斤拷dUT1锟侥诧拷锟絛UT1锟节革拷锟斤拷锟斤拷锟斤拷锟斤拷时锟脚猴拷锟叫伙拷锟斤拷0.1锟斤拷木锟斤拷雀锟斤拷锟絀ERS锟斤拷锟斤拷锟斤拷锟斤拷锟襟,伙拷锟斤拷1e - 5锟侥撅拷锟饺革拷锟斤拷锟斤拷 + double dT = 32.184 + dAT - dUT1; + double JDTT = JDUT1 + dT / 86400; + + + //% JDTT = YMD2JD(UTC(1), UTC(2), UTC(3)) + dUT1 / 86400; + //% 锟斤拷锟饺硷拷锟斤拷TDB, TDB锟斤拷锟斤拷锟侥讹拷锟斤拷学时锟斤拷锟斤拷太锟斤拷锟斤拷锟斤拷锟斤拷锟角碉拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟叫碉拷时锟斤拷叨锟?1锟?7 + double T = (JDTT - J2000) / 36525; + double temp = 0.001657 * sin(628.3076 * T + 6.2401) + + 0.000022 * sin(575.3385 * T + 4.2970) + + 0.000014 * sin(1256.6152 * T + 6.1969) + + 0.000005 * sin(606.9777 * T + 4.0212) + + 0.000005 * sin(52.9691 * T + 0.4444) + + 0.000002 * sin(21.3299 * T + 5.5431) + + 0.00001 * T * sin(628.3076 * T + 4.2490); + JDTDB = JDTT + temp / 86400; + + //% 锟斤拷锟斤拷锟斤拷锟経T2, UT2锟斤拷锟斤拷UT1锟侥伙拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟皆硷拷锟节变化锟斤拷玫锟斤拷锟斤拷锟斤拷锟绞憋拷锟?1锟?7 + // %% 锟斤拷锟斤拷UT1锟斤拷锟斤拷Tb, Tb为锟皆憋拷锟斤拷锟斤拷锟斤拷为锟斤拷位锟斤拷锟斤拷锟斤拷元B2000.0锟斤拷锟斤拷ff + // % B2000 = 2451544.033; + //% Tb = (YMD2JD(UT1(1), UT1(2), UT1(3)) - B2000) / 365.2422; + //% dTs = 0.022 * sin(2 * pi * Tb) - 0.012 * cos(2 * pi * Tb) - 0.006 * sin(4 * pi * Tb) + 0.007 * cos(4 * pi * Tb); + //% dTs = dTs / 86400; + //% UT2 = UT1 + [0 0 dTs]; + + //% 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷时GMST; 锟斤拷位为锟斤拷 + T = (JDTDB - J2000) / 36525; + double T2 = T * T; + double T3 = T2 * T; + double T4 = T3 * T; + double T5 = T4 * T; + double Du = JDUT1 - J2000; + double thita = 0.7790572732640 + 1.00273781191135448 * Du;//% 锟斤拷J2000锟斤拷锟斤拷锟阶?拷锟斤拷锟饺︼拷锟斤拷锟?1锟?7 + double GMST_deg = (-0.0000000368 * T5 - 0.000029956 * T4 - 0.00000044 * T3 + 1.3915817 * T2 + 4612.156534 * T + 0.014506) / 3600 + (thita - floor(thita)) * 360; + double epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg; + WGS84_J2000::nutationInLongitudeCaculate(JDTDB, epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg); + //[epthilongA_deg, dertaPthi_deg] = nutationInLongitudeCaculate(JDTDB); + + //% 锟斤拷锟斤拷嗑?拷露锟斤拷锟斤拷锟斤拷锟斤拷锟絜clipticObliquitygama锟斤拷锟斤拷位为锟斤拷锟斤拷 + //% 锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷锟?1锟?7 太锟斤拷平锟斤拷锟斤拷锟?1锟?7 锟斤拷锟斤拷纬锟饺凤拷锟斤拷 锟斤拷锟斤拷平锟角撅拷(锟斤拷锟斤拷平锟狡撅拷 - 太锟斤拷平锟狡撅拷锟斤拷 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟狡撅拷 锟斤拷位为锟斤拷锟斤拷 + double F_deg = (0.00000417 * T4 - 0.001037 * T3 - 12.7512 * T2 + 1739527262.8478 * T + 335779.526232) / 3600; + F_deg = fmod(F_deg, 360); + double D_deg = (-0.00003169 * T4 + 0.006593 * T3 - 6.3706 * T2 + 1602961601.2090 * T + 1072260.70369) / 3600; + D_deg = fmod(D_deg, 360); + double Omiga_deg = (-0.00005939 * T4 + 0.007702 * T3 + 7.4722 * T2 - 6962890.5431 * T + 450160.398036) / 3600; + Omiga_deg = fmod(Omiga_deg, 360); + + double epthilongGama_deg = dertaPthi_deg * cosd(epthilongA_deg) + + (0.00264096 * sind(Omiga_deg ) + + 0.00006352 * sind(2 * Omiga_deg ) + + 0.00001175 * sind(2 * F_deg - 2 * D_deg + 3 * Omiga_deg) + + 0.00001121 * sind(2 * F_deg - 2 * D_deg + Omiga_deg) + - 0.00000455 * sind(2 * F_deg - 2 * D_deg + 2 * Omiga_deg) + + 0.00000202 * sind(2 * F_deg + 3 * Omiga_deg) + + 0.00000198 * sind(2 * F_deg + Omiga_deg) + - 0.00000172 * sind(3 * Omiga_deg) + - 0.00000087 * T * sind(Omiga_deg)) / 3600; + gst_deg = epthilongGama_deg + GMST_deg; + return 0; +} + + +/// +/// step 4 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷瞬时平锟斤拷锟斤拷 锟斤拷锟斤拷系 +/// 锟斤拷锟斤拷平锟狡赤交锟角o拷锟狡撅拷锟铰讹拷锟斤拷锟酵斤拷锟斤拷锟铰讹拷锟斤拷瞬时锟狡赤交锟角★拷 +/// +/// 锟斤拷锟斤拷锟斤拷 +/// 锟斤拷示锟斤拷锟斤拷木锟斤拷锟揭?拷锟?1锟?7 锟斤拷值为锟斤拷normal锟斤拷 锟酵★拷high锟斤拷 锟斤拷锟斤拷锟斤拷'N'锟酵★拷H'锟斤拷示一锟姐精锟饺和高撅拷锟斤拷 锟斤拷默锟斤拷为锟竭撅拷锟饺硷拷锟斤拷 +/// 平锟狡赤交锟斤拷 +/// 锟狡撅拷锟铰讹拷 +/// 锟酵斤拷锟斤拷锟铰讹拷 +/// 瞬时锟狡赤交锟斤拷 +/// +int WGS84_J2000::nutationInLongitudeCaculate(double JD, double& epthilongA_deg, double& dertaPthi_deg, double& dertaEpthilong_deg, double& epthilong_deg) +{ + double T = (JD - 2451545) / 36525; + double T2 = T * T; + double T3 = T2 * T; + double T4 = T3 * T; + double T5 = T4 * T; + //% 锟斤拷锟斤拷锟斤拷锟斤拷平锟斤拷锟斤拷锟絣unarMeanAnomaly_deg(l_deg) 太锟斤拷平锟斤拷锟斤拷锟絊olarMeanAnomaly_deg(solarl_deg) + // % 锟斤拷锟斤拷纬锟饺凤拷锟斤拷lunarLatitudeAngle_deg(F_deg) 锟斤拷锟斤拷平锟角撅拷diffLunarSolarElestialLongitude_deg(D_deg锟斤拷锟斤拷平锟狡撅拷 - 太锟斤拷平锟狡撅拷锟斤拷 + // % 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷平锟狡撅拷SolarAscendingNodeElestialLongitude_deg(Omiga_deg) + double l_deg = (-0.00024470 * T4 + 0.051635 * T3 + 31.8792 * T2 + 1717915923.2178 * T + 485868.249036) / 3600; + l_deg = fmod(l_deg, 360); + double solarl_deg = (-0.00001149 * T4 + 0.000136 * T3 - 0.5532 * T2 + 129596581.0481 * T + 1287104.79305) / 3600; + solarl_deg = fmod(solarl_deg, 360); + double F_deg = (0.00000417 * T4 - 0.001037 * T3 - 12.7512 * T2 + 1739527262.8478 * T + 335779.526232) / 3600; + F_deg = fmod(F_deg, 360); + double D_deg = (-0.00003169 * T4 + 0.006593 * T3 - 6.3706 * T2 + 1602961601.2090 * T + 1072260.70369) / 3600; + D_deg = fmod(D_deg, 360); + double Omiga_deg = (-0.00005939 * T4 + 0.007702 * T3 + 7.4722 * T2 - 6962890.5431 * T + 450160.398036) / 3600; + Omiga_deg = fmod(Omiga_deg, 360); + Eigen::MatrixXd basicAngle_deg = Eigen::Matrix{ l_deg,solarl_deg,F_deg,D_deg,Omiga_deg }; + + epthilongA_deg = (-0.0000000434 * T5 - 0.000000576 * T4 + 0.00200340 * T3 - 0.0001831 * T2 - 46.836769 * T + 84381.406) / 3600; + epthilongA_deg = epthilongA_deg - floor(epthilongA_deg / 360) * 360; + //% IAU2000模锟斤拷锟斤拷77锟斤拷 + Eigen::MatrixXd elestialLonNutation = WGS84_J2000::IAU2000ModelParams; + + dertaPthi_deg = -3.75e-08; + dertaEpthilong_deg = 0.388e-3 / 3600; + for (int i = 0; i < 77; i++) { + double sumAngle_deg = 0; + for (int j = 0; j < 5; j++) { + sumAngle_deg = sumAngle_deg + elestialLonNutation(i, j) * basicAngle_deg(j); + } + sumAngle_deg = sumAngle_deg - floor(sumAngle_deg / 360) * 360; + dertaPthi_deg = dertaPthi_deg + ((elestialLonNutation(i, 5) + elestialLonNutation(i, 6) * T) * sind(sumAngle_deg ) + elestialLonNutation(i, 7) * cosd(sumAngle_deg)) * 1e-7 / 3600; + dertaEpthilong_deg = dertaEpthilong_deg + ((elestialLonNutation(i, 8) + elestialLonNutation(i, 9) * T) * cosd(sumAngle_deg) + elestialLonNutation(i, 10) * sind(sumAngle_deg)) * 1e-7 / 3600; + } + epthilong_deg = epthilongA_deg + dertaEpthilong_deg; + return 0; +} + +/// +/// zA锟斤拷thitaA锟斤拷zetaA为锟斤拷锟斤拷锟斤拷锟?1锟?7, 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 +/// +/// +/// +/// +/// +/// +int WGS84_J2000::precessionAngle(double JDTDB, double& zetaA, double& thitaA, double& zA) +{ + double T = (JDTDB - 2451545) / 36525; + double T2 = T * T; + double T3 = T2 * T; + //% + //% zetaA = (2306.218 * T + 0.30188 * T2 + 0.017998 * T3) / 3600; + //% zA = (2306.218 * T + 1.09468 * T2 + 0.018203) / 3600; + //% thitaA = (2004.3109 * T - 0.42665 * T2 - 0.041833 * T3) / 3600; + double T4 = T3 * T; + double T5 = T4 * T; + zetaA = (-0.0000003173 * T5 - 0.000005971 * T4 + 0.01801828 * T3 + 0.2988499 * T2 + 2306.083227 * T + 2.650545) / 3600; + thitaA = (-0.0000001274 * T5 - 0.000007089 * T4 - 0.04182264 * T3 - 0.4294934 * T2 + 2004.191903 * T) / 3600; + zA = (-0.0000002904 * T5 - 0.000028596 * T4 + 0.01826837 * T3 + 1.0927348 * T2 + 2306.077181 * T - 2.650545) / 3600; + return 0; +} + +/// +/// 同时 YMD2JD锟斤拷锟斤拷为 锟斤拷锟斤拷锟斤拷转锟斤拷为锟斤拷锟斤拷锟秸o拷 +/// +/// +/// +/// +/// +double WGS84_J2000::YMD2JD(double y, double m, double d) +{ + int B = 0; + if (y > 1582 || (y == 1582 && m > 10) || (y == 1582 && m == 10 && d >= 15)) { + B = 2 - floor(y / 100) + floor(y / 400); + } + return floor(365.25 * (y + 4712)) + floor(30.6 * (m + 1)) + d - 63.5 + B; +} + +/// +/// WGS84 转 J2000 +/// +/// WGS84 锟斤拷纬锟斤拷 +/// 1x3 Y,m,d +/// EARTH ORIENTATION PARAMETER Xp +/// EARTH ORIENTATION PARAMETER Yp +/// Solar Weather Data dut1 +/// Solar Weather Data dat +/// +Eigen::MatrixXd WGS84_J2000::WGS842J2000(Eigen::MatrixXd BLH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat) +{ + //step 1 step1 WGS 84 转锟斤拷锟斤拷协锟斤拷锟斤拷锟斤拷锟斤拷锟较碉拷锟?1锟?7 + Eigen::MatrixXd earthFixedXYZ = WGS84_J2000::WGS84TECEF(BLH_deg_m).transpose(); + //step 2 协锟斤拷锟斤拷锟斤拷锟斤拷锟较?1锟?7 转锟斤拷为瞬时锟斤拷锟斤拷锟斤拷锟斤拷 + // 锟斤拷锟斤拷要锟芥及锟斤拷询 锟斤拷锟斤拷时锟教碉拷 xp,yp , 锟斤拷锟皆诧拷询EOP锟侥硷拷锟斤拷茫锟斤拷锟斤拷氐锟街凤拷锟斤拷锟絟ttp://celestrak.com/spacedata/ + earthFixedXYZ = ordinateSingleRotate(1, yp) * ordinateSingleRotate(2, xp) * earthFixedXYZ; + //step 3 瞬时锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷为 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 + // 锟矫诧拷锟斤拷锟斤拷要锟芥及锟斤拷锟斤拷锟斤拷锟斤拷锟轿猴拷锟斤拷时锟角的硷拷锟姐,锟斤拷锟节革拷锟斤拷锟斤拷锟轿猴拷锟斤拷时锟斤拷 锟斤拷锟姐方锟斤拷 锟杰多,锟斤拷锟斤拷锟斤拷锟?1锟?7 一锟斤拷锟斤拷为锟斤拷确锟侥硷拷锟姐方锟斤拷锟斤拷锟斤拷锟斤拷dut1 锟斤拷dat锟斤拷锟斤拷锟斤拷EOP锟侥硷拷锟斤拷锟叫★拷EOP锟侥硷拷锟斤拷锟截碉拷址锟斤拷锟斤拷 http://celestrak.org/spacedata/ + double gst_deg, JDTDB; + WGS84_J2000::utc2gst(UTC, dut1, dat, gst_deg, JDTDB); + Eigen::MatrixXd xyz = ordinateSingleRotate(3, -1 * gst_deg) * earthFixedXYZ; + //step 4 瞬时锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系 转锟斤拷瞬时平锟斤拷锟斤拷 锟斤拷锟斤拷系 + double epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg; + WGS84_J2000::nutationInLongitudeCaculate(JDTDB, epthilongA_deg, dertaPthi_deg, dertaEpthilong_deg, epthilong_deg); + xyz = ordinateSingleRotate(1, -epthilongA_deg) * ordinateSingleRotate(3, dertaPthi_deg) * ordinateSingleRotate(1, dertaEpthilong_deg + epthilongA_deg) * xyz; + //step5 瞬时平锟斤拷锟斤拷锟斤拷锟斤拷系转锟斤拷为协锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷系锟斤拷J2000锟斤拷 + double zetaA, thitaA, zA; + WGS84_J2000::precessionAngle(JDTDB, zetaA, thitaA, zA); + xyz = ordinateSingleRotate(3, zetaA) * ordinateSingleRotate(2, -thitaA) * ordinateSingleRotate(3, zA) * xyz; + return xyz.transpose(); + //return Eigen::MatrixXd(); +} + +Landpoint WGS84_J2000::WGS842J2000(Landpoint p, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat) +{ + Eigen::MatrixXd blh = Eigen::MatrixXd(1, 3); + blh << p.lon, p.lat, p.ati; + blh = WGS84_J2000::WGS842J2000(blh, UTC, xp, yp, dut1, dat); + return Landpoint{ blh(0,0),blh(0,1) ,blh(0,0) }; + //return Landpoint(); +} +*/ + + + diff --git a/simorthoprogram-orth_s_sar-strip/baseTool.h b/simorthoprogram-orth_s_sar-strip/baseTool.h new file mode 100644 index 0000000..64e53cf --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/baseTool.h @@ -0,0 +1,397 @@ +#pragma once +/// +/// 基本类、基本函数 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; +using namespace Eigen; + +#define PI_180 180/3.141592653589793238462643383279 +#define T180_PI 3.141592653589793238462643383279/180 +#define LIGHTSPEED 299792458 + + +#define Radians2Degrees(Radians) Radians*PI_180 +#define Degrees2Radians(Degrees) Degrees*T180_PI + + + + + + + + +const double PI = 3.141592653589793238462643383279; +const double epsilon = 0.000000000000001; +const double pi = 3.14159265358979323846; +const double d2r = pi / 180; +const double r2d = 180 / pi; + +const double a = 6378137.0; //椭球长半轴 +const double ae = 6378137.0; //椭球长半轴 +const double ee= 0.0818191910428;// 第一偏心率 +const double f_inverse = 298.257223563; //扁率倒数 +const double b = a - a / f_inverse; +const double eSquare = (a * a - b * b) / (a * a); +const double e = sqrt(eSquare); +const double earth_Re = 6378136.49; +const double earth_Rp = (1 - 1 / f_inverse) * earth_Re; +const double earth_We = 0.000072292115; +///////////////////////////////////// 运行时间打印 ////////////////////////////////////////////////////////// + + +std::string getCurrentTimeString(); +std::string getCurrentShortTimeString(); + + +/////////////////////////////// 基本图像类 ////////////////////////////////////////////////////////// + +/// +/// 三维向量,坐标表达 +/// +struct Landpoint // 点 SAR影像的像素坐标; +{ + /// + /// 经度x + /// + double lon; // 经度x lon pixel_col + /// + /// 纬度y + /// + double lat; // 纬度y lat pixel_row + /// + /// 高度z + /// + double ati; // 高程z ati pixel_time +}; +struct Point_3d { + double x; + double y; + double z; +}; + +Landpoint operator +(const Landpoint& p1, const Landpoint& p2); + +Landpoint operator -(const Landpoint& p1, const Landpoint& p2); + +bool operator ==(const Landpoint& p1, const Landpoint& p2); + +Landpoint operator *(const Landpoint& p, double scale); + +/// +/// 向量A,B的夹角,角度 +/// +/// +/// +/// 角度制 0-360度,逆时针 +double getAngle(const Landpoint& a, const Landpoint& b); + +/// +/// 点乘 +/// +/// +/// +/// +double dot(const Landpoint& p1, const Landpoint& p2); + +double getlength(const Landpoint& p1); + +Landpoint crossProduct(const Landpoint& a, const Landpoint& b); + + + +struct DemBox { + double min_lat; //纬度 + double min_lon;//经度 + double max_lat;//纬度 + double max_lon;//经度 +}; + + +/// +/// gdalImage图像操作类 +/// +class gdalImage +{ + +public: // 方法 + gdalImage(string raster_path); + ~gdalImage(); + void setHeight(int); + void setWidth(int); + void setTranslationMatrix(Eigen::MatrixXd gt); + void setData(Eigen::MatrixXd); + Eigen::MatrixXd getData(int start_row, int start_col, int rows_count, int cols_count, int band_ids); + void saveImage(Eigen::MatrixXd,int start_row,int start_col, int band_ids); + void saveImage(); + void setNoDataValue(double nodatavalue,int band_ids); + int InitInv_gt(); + Landpoint getRow_Col(double lon, double lat); + Landpoint getLandPoint(double i, double j, double ati); + double mean(int bandids=1); + double max(int bandids=1); + double min(int bandids=1); + GDALRPCInfo getRPC(); + Eigen::MatrixXd getLandPoint(Eigen::MatrixXd points); + + Eigen::MatrixXd getHist(int bandids); +public: + string img_path; // 图像文件 + int height; // 高 + int width; // 宽 + int band_num;// 波段数 + int start_row;// + int start_col;// + int data_band_ids; + Eigen::MatrixXd gt; // 变换矩阵 + Eigen::MatrixXd inv_gt; // 逆变换矩阵 + Eigen::MatrixXd data; + string projection; +}; + +gdalImage CreategdalImage(string img_path, int height, int width, int band_num, Eigen::MatrixXd gt, std::string projection, bool need_gt=true); + +void clipGdalImage(string in_path, string out_path, DemBox box, double pixelinterval); + +int ResampleGDAL(const char* pszSrcFile, const char* pszOutFile, double* gt, int new_width, int new_height, GDALResampleAlg eResample); + +int ResampleGDALs(const char* pszSrcFile, int band_ids, GDALRIOResampleAlg eResample=GRIORA_Bilinear); + + + +/////////////////////////////// 基本图像类 结束 ////////////////////////////////////////////////////////// + +string Convert(float Num); +std::string JoinPath(const std::string& path, const std::string& filename); + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + + +/// +/// 将经纬度转换为地固参心坐标系 +/// +/// 经纬度点--degree +/// 投影坐标系点 +Landpoint LLA2XYZ(const Landpoint& LLA); +Eigen::MatrixXd LLA2XYZ(Eigen::MatrixXd landpoint); + +/// +/// 将地固参心坐标系转换为经纬度 +/// +/// 固参心坐标系 +/// 经纬度--degree +Landpoint XYZ2LLA(const Landpoint& XYZ); + + +////////////////////////////// 坐标部分基本方法 ////////////////////////////////////////// + +/// +/// 计算地表坡度向量 +/// +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 固参心坐标系 +/// 向量角度 +//Landpoint getSlopeVector(Landpoint& p0, Landpoint& p1, Landpoint& p2, Landpoint& p3, Landpoint& p4, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); +Landpoint getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4); + +////////////////////////////// 插值 //////////////////////////////////////////// + +complex Cubic_Convolution_interpolation(double u,double v,Eigen::MatrixX> img); + +complex Cubic_kernel_weight(double s); + +double Bilinear_interpolation(Landpoint p0, Landpoint p11, Landpoint p21, Landpoint p12, Landpoint p22); + + + +inline float cross2d(Point_3d a, Point_3d b) { return a.x * b.y - a.y * b.x; } + +inline Point_3d operator-(Point_3d a, Point_3d b) { + return Point_3d{ a.x - b.x, a.y - b.y, a.z - b.z }; +}; + +inline Point_3d operator+(Point_3d a, Point_3d b) { + return Point_3d{ a.x + b.x, a.y +b.y, a.z + b.z }; +}; + +inline double operator/(Point_3d a, Point_3d b) { + return sqrt(pow(a.x,2)+ pow(a.y, 2))/sqrt(pow(b.x, 2)+ pow(b.y, 2)); +}; +inline bool onSegment(Point_3d Pi, Point_3d Pj, Point_3d Q) +{ + if ((Q.x - Pi.x) * (Pj.y - Pi.y) == (Pj.x - Pi.x) * (Q.y - Pi.y) //叉乘 + //保证Q点坐标在pi,pj之间 + && min(Pi.x, Pj.x) <= Q.x && Q.x <= max(Pi.x, Pj.x) + && min(Pi.y, Pj.y) <= Q.y && Q.y <= max(Pi.y, Pj.y)) + return true; + else + return false; +} + +inline Point_3d invBilinear(Point_3d p, Point_3d a, Point_3d b, Point_3d c, Point_3d d) +{ + Point_3d res ; + + Point_3d e = b - a; + Point_3d f = d - a; + Point_3d g = a - b + c - d; + Point_3d h = p - a; + + double k2 = cross2d(g, f); + double k1 = cross2d(e, f) + cross2d(h, g); + double k0 = cross2d(h, e); + double u, v; + // if edges are parallel, this is a linear equation + if (abs(k2) < 0.001) + { + v = -k0 / k1; + u = (h.x - f.x *v) / (e.x + g.x *v); + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + // otherwise, it's a quadratic + else + { + float w = k1 * k1 - 4.0 * k0 * k2; + if (w < 0.0){ + // 可能在边界上 + if (onSegment(a, b, p)) { + Point_3d tt = b - a; + Point_3d ttpa = p - a; + double scater=ttpa / tt; + if(scater<0||scater>1){ return { -9999,-9999,-9999 }; } + p.z = a.z + scater * tt.z; + return p; + } + else if (onSegment(b, c, p)) { + Point_3d tt = c-b; + Point_3d ttpa = p - b; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = b.z + scater * tt.z; + return p; + } + else if (onSegment(c, d, p)) { + Point_3d tt = d-c; + Point_3d ttpa = p - c; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = c.z + scater * tt.z; + return p; + } + else if (onSegment(d, a, p)) { + Point_3d tt = a-d; + Point_3d ttpa = p - d; + double scater = ttpa / tt; + if (scater < 0 || scater>1) { return { -9999,-9999,-9999 }; } + p.z = d.z + scater * tt.z; + return p; + } + + return { -9999,-9999,-9999 }; + } + else { + w = sqrt(w); + + float ik2 = 0.5 / k2; + float v = (-k1 - w) * ik2; + float u = (h.x - f.x * v) / (e.x + g.x * v); + + if (u < 0.0 || u>1.0 || v < 0.0 || v>1.0) + { + v = (-k1 + w) * ik2; + u = (h.x - f.x * v) / (e.x + g.x * v); + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; + } + } + p.z = a.z + (b.z - a.z) * u + (d.z - a.z) * v + (a.z - b.z + c.z - d.z) * u * v; + return p; +} + + + +// +// WGS84 到J2000 坐标系的变换 +// 参考网址:https://blog.csdn.net/hit5067/article/details/116894616 +// 资料网址:http://celestrak.org/spacedata/ +// 参数文件: +// a. Earth Orientation Parameter 文件: http://celestrak.org/spacedata/EOP-Last5Years.csv +// b. Space Weather Data 文件: http://celestrak.org/spacedata/SW-Last5Years.csv +// 备注:上述文件是自2017年-五年内 +/** +在wgs84 坐标系转到J2000 坐标系 主要 涉及到坐标的相互转换。一般给定的WGS坐标为 给定时刻的 t ,BLH +转换步骤: +step 1: WGS 84 转换到协议地球坐标系 +step 2: 协议地球坐标系 转换为瞬时地球坐标系 +step 3: 瞬时地球坐标系 转换为 瞬时真天球坐标系 +step 4: 瞬时真天球坐标系 转到瞬时平天球 坐标系 +step 5: 瞬时平天球坐标系转换为协议天球坐标系(J2000) +**/ + + +inline double sind(double degree) { + return sin(degree * d2r); +} + +inline double cosd(double d) { + return cos(d * d2r); +} + +/* +class WGS84_J2000 +{ +public: + WGS84_J2000(); + ~WGS84_J2000(); + +public: + // step1 WGS 84 转换到协议地球坐标系。 + static Eigen::MatrixXd WGS84TECEF(Eigen::MatrixXd WGS84_Lon_lat_ait); + //step 2 协议地球坐标系 转换为瞬时地球坐标系 + static Eigen::MatrixXd ordinateSingleRotate(int axis, double angle_deg); + // step 3 瞬时地球坐标系 转换为 瞬时真天球坐标系 + // xyz= ordinateSingleRotate('z',-gst_deg)*earthFixedXYZ; + static int utc2gst(Eigen::MatrixXd UTC, double dUT1, double dAT, double& gst_deg, double& JDTDB); + // step 4 瞬时真天球坐标系 转到瞬时平天球 坐标系 + static int nutationInLongitudeCaculate(double JD, double& epthilongA_deg, double& dertaPthi_deg, double& dertaEpthilong_deg, double& epthilong_deg); + // step5 瞬时平天球坐标系转换为协议天球坐标系(J2000)函数中 JDTDB 为给定时刻 的地球动力学时对应的儒略日,其计算方法由步骤三中的函数给出。 + // xyz=ordinateSingleRotate('Z',zetaA)*ordinateSingleRotate('y',-thitaA)*ordinateSingleRotate('z',zA)*xyz; + static int precessionAngle(double JDTDB, double& zetaA, double& thitaA, double& zA); + // YMD2JD 同时 YMD2JD函数为 年月日转换为儒略日,具体说明 见公元纪年法(儒略历-格里高历)转儒略日_${王小贱}的博客-CSDN博客_年积日计算公式 + static double YMD2JD(double y, double m, double d); + static Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd BLH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); + static Landpoint WGS842J2000(Landpoint LBH_deg_m, Eigen::MatrixXd UTC, double xp, double yp, double dut1, double dat); +public: + static std::string EOP_File_Path; + static std::string Space_Weather_Data; + // IAU2000模型有77项11列 + static Eigen::Matrix IAU2000ModelParams; +}; + +*/ \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/interpolation.cpp b/simorthoprogram-orth_s_sar-strip/interpolation.cpp new file mode 100644 index 0000000..4e1ce26 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/interpolation.cpp @@ -0,0 +1 @@ +#include "interpolation.h" diff --git a/simorthoprogram-orth_s_sar-strip/interpolation.h b/simorthoprogram-orth_s_sar-strip/interpolation.h new file mode 100644 index 0000000..70c1ae4 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/interpolation.h @@ -0,0 +1,10 @@ +#pragma once +/** +专门用于插值计算的类库 + +*/ +#include +#include +#include +#include +#include diff --git a/simorthoprogram-orth_s_sar-strip/linterp.h b/simorthoprogram-orth_s_sar-strip/linterp.h new file mode 100644 index 0000000..5e1cb67 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/linterp.h @@ -0,0 +1,423 @@ + +// +// Copyright (c) 2012 Ronaldo Carpio +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. The authors make no representations +// about the suitability of this software for any purpose. +// It is provided "as is" without express or implied warranty. +// + +/* +This is a C++ header-only library for N-dimensional linear interpolation on a rectangular grid. Implements two methods: +* Multilinear: Interpolate using the N-dimensional hypercube containing the point. Interpolation step is O(2^N) +* Simplicial: Interpolate using the N-dimensional simplex containing the point. Interpolation step is O(N log N), but less accurate. +Requires boost/multi_array library. + +For a description of the algorithms, see: +* Weiser & Zarantonello (1988), "A Note on Piecewise Linear and Multilinear Table Interpolation in Many Dimensions", _Mathematics of Computation_ 50 (181), p. 189-196 +* Davies (1996), "Multidimensional Triangulation and Interpolation for Reinforcement Learning", _Proceedings of Neural Information Processing Systems 1996_ +*/ + +#ifndef _linterp_h +#define _linterp_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using std::vector; +using std::array; +typedef unsigned int uint; +typedef vector iVec; +typedef vector dVec; + + +// TODO: +// - specify behavior past grid boundaries. +// 1) clamp +// 2) return a pre-determined value (e.g. NaN) + +// compile-time params: +// 1) number of dimensions +// 2) scalar type T +// 3) copy data or not (default: false). The grids will always be copied +// 4) ref count class (default: none) +// 5) continuous or not + +// run-time constructor params: +// 1) f +// 2) grids +// 3) behavior outside grid: default=clamp +// 4) value to return outside grid, defaut=nan + +struct EmptyClass {}; + +template +class NDInterpolator { +public: + typedef T value_type; + typedef ArrayRefCountT array_ref_count_type; + typedef GridRefCountT grid_ref_count_type; + + static const int m_N = N; + static const bool m_bCopyData = CopyData; + static const bool m_bContinuous = Continuous; + + typedef boost::numeric::ublas::array_adaptor grid_type; + typedef boost::const_multi_array_ref array_type; + typedef std::unique_ptr array_type_ptr; + + array_type_ptr m_pF; + ArrayRefCountT m_ref_F; // reference count for m_pF + vector m_F_copy; // if CopyData == true, this holds the copy of F + + vector m_grid_list; + vector m_grid_ref_list; // reference counts for grids + vector > m_grid_copy_list; // if CopyData == true, this holds the copies of the grids + + // constructors assume that [f_begin, f_end) is a contiguous array in C-order + // non ref-counted constructor. + template + NDInterpolator(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) { + init(grids_begin, grids_len_begin, f_begin, f_end); + } + + // ref-counted constructor + template + NDInterpolator(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT grid_refs_begin) { + init_refcount(grids_begin, grids_len_begin, f_begin, f_end, refF, grid_refs_begin); + } + + template + void init(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) { + set_grids(grids_begin, grids_len_begin, m_bCopyData); + set_f_array(f_begin, f_end, m_bCopyData); + } + template + void init_refcount(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT grid_refs_begin) { + set_grids(grids_begin, grids_len_begin, m_bCopyData); + set_grids_refcount(grid_refs_begin, grid_refs_begin + N); + set_f_array(f_begin, f_end, m_bCopyData); + set_f_refcount(refF); + } + + template + void set_grids(IterT1 grids_begin, IterT2 grids_len_begin, bool bCopy) { + m_grid_list.clear(); + m_grid_ref_list.clear(); + m_grid_copy_list.clear(); + for (int i=0; i(grids_begin[i], grids_begin[i] + grids_len_begin[i]) ); // make our own copy of the grid + T *begin = &(m_grid_copy_list[i][0]); + m_grid_list.push_back(grid_type(gridLength, begin)); // use our copy + } + } + } + template + void set_grids_refcount(RefCountIterT refs_begin, RefCountIterT refs_end) { + assert(refs_end - refs_begin == N); + m_grid_ref_list.assign(refs_begin, refs_begin + N); + } + + // assumes that [f_begin, f_end) is a contiguous array in C-order + template + void set_f_array(IterT f_begin, IterT f_end, bool bCopy) { + unsigned int nGridPoints = 1; + array sizes; + for (unsigned int i=0; i(f_begin, f_end); + m_pF.reset(new array_type(&m_F_copy[0], sizes)); + } + } + void set_f_refcount(ArrayRefCountT &refF) { + m_ref_F = refF; + } + + // -1 is before the first grid point + // N-1 (where grid.size() == N) is after the last grid point + int find_cell(int dim, T x) const { + grid_type const &grid(m_grid_list[dim]); + if (x < *(grid.begin())) return -1; + else if (x >= *(grid.end()-1)) return grid.size()-1; + else { + auto i_upper = std::upper_bound(grid.begin(), grid.end(), x); + return i_upper - grid.begin() - 1; + } + } + + // return the value of f at the given cell and vertex + T get_f_val(array const &cell_index, array const &v_index) const { + array f_index; + + if (m_bContinuous) { + for (int i=0; i= m_grid_list[i].size()-1) { + f_index[i] = m_grid_list[i].size()-1; + } else { + f_index[i] = cell_index[i] + v_index[i]; + } + } + } else { + for (int i=0; i= m_grid_list[i].size()-1) { + f_index[i] = (2*m_grid_list[i].size())-1; + } else { + f_index[i] = 1 + (2*cell_index[i]) + v_index[i]; + } + } + } + return (*m_pF)(f_index); + } + + T get_f_val(array const &cell_index, int v) const { + array v_index; + for (int dim=0; dim> (N-dim-1)) & 1; // test if the i-th bit is set + } + return get_f_val(cell_index, v_index); + } +}; + +template +class InterpSimplex : public NDInterpolator { +public: + typedef NDInterpolator super; + + template + InterpSimplex(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) + : super(grids_begin, grids_len_begin, f_begin, f_end) + {} + template + InterpSimplex(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT ref_begins) + : super(grids_begin, grids_len_begin, f_begin, f_end, refF, ref_begins) + {} + + template + T interp(IterT x_begin) const { + array result; + array< array, N > coord_iter; + for (int i=0; i + void interp_vec(int n, IterT1 coord_iter_begin, IterT1 coord_iter_end, IterT2 i_result) const { + assert(N == coord_iter_end - coord_iter_begin); + + array cell_index, v_index; + array,N> xipair; + int c; + T y, v0, v1; + //mexPrintf("%d\n", n); + for (int i=0; ifind_cell(dim, coord_iter_begin[dim][i]); + //mexPrintf("%d\n", c); + if (c == -1) { // before first grid point + y = 1.0; + } else if (c == grid.size()-1) { // after last grid point + y = 0.0; + } else { + //mexPrintf("%f %f\n", grid[c], grid[c+1]); + y = (coord_iter_begin[dim][i] - grid[c]) / (grid[c + 1] - grid[c]); + if (y < 0.0) y=0.0; + else if (y > 1.0) y=1.0; + } + xipair[dim].first = y; + xipair[dim].second = dim; + cell_index[dim] = c; + } + // sort xi's and get the permutation + std::sort(xipair.begin(), xipair.end(), [](std::pair const &a, std::pair const &b) { + return (a.first < b.first); + }); + // walk the vertices of the simplex determined by the permutation + for (int j=0; jget_f_val(cell_index, v_index); + y = v0; + for (int j=0; jget_f_val(cell_index, v_index); + y += (1.0 - xipair[j].first) * (v1-v0); // interpolate + v0 = v1; + } + *i_result++ = y; + } + } +}; + +template +class InterpMultilinear : public NDInterpolator { +public: + typedef NDInterpolator super; + + template + InterpMultilinear(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end) + : super(grids_begin, grids_len_begin, f_begin, f_end) + {} + template + InterpMultilinear(IterT1 grids_begin, IterT2 grids_len_begin, IterT3 f_begin, IterT3 f_end, ArrayRefCountT &refF, RefCountIterT ref_begins) + : super(grids_begin, grids_len_begin, f_begin, f_end, refF, ref_begins) + {} + + template + static T linterp_nd_unitcube(IterT1 f_begin, IterT1 f_end, IterT2 xi_begin, IterT2 xi_end) { + int n = xi_end - xi_begin; + int f_len = f_end - f_begin; + assert(1 << n == f_len); + T sub_lower, sub_upper; + if (n == 1) { + sub_lower = f_begin[0]; + sub_upper = f_begin[1]; + } else { + sub_lower = linterp_nd_unitcube(f_begin, f_begin + (f_len/2), xi_begin + 1, xi_end); + sub_upper = linterp_nd_unitcube(f_begin + (f_len/2), f_end, xi_begin + 1, xi_end); + } + T result = sub_lower + (*xi_begin)*(sub_upper - sub_lower); + return result; + } + + template + T interp(IterT x_begin) const { + array result; + array< array, N > coord_iter; + for (int i=0; i + void interp_vec(int n, IterT1 coord_iter_begin, IterT1 coord_iter_end, IterT2 i_result) const { + assert(N == coord_iter_end - coord_iter_begin); + array index; + int c; + T y, xi; + vector f(1 << N); + array x; + + for (int i=0; ifind_cell(dim, coord_iter_begin[dim][i]); + if (c == -1) { // before first grid point + y = 1.0; + } else if (c == grid.size()-1) { // after last grid point + y = 0.0; + } else { + y = (coord_iter_begin[dim][i] - grid[c]) / (grid[c + 1] - grid[c]); + if (y < 0.0) y=0.0; + else if (y > 1.0) y=1.0; + } + index[dim] = c; + x[dim] = y; + } + // copy f values at vertices + for (int v=0; v < (1 << N); v++) { // loop over each vertex of hypercube + f[v] = this->get_f_val(index, v); + } + *i_result++ = linterp_nd_unitcube(f.begin(), f.end(), x.begin(), x.end()); + } + } +}; + +typedef InterpSimplex<1,double> NDInterpolator_1_S; +typedef InterpSimplex<2,double> NDInterpolator_2_S; +typedef InterpSimplex<3,double> NDInterpolator_3_S; +typedef InterpSimplex<4,double> NDInterpolator_4_S; +typedef InterpSimplex<5,double> NDInterpolator_5_S; +typedef InterpMultilinear<1,double> NDInterpolator_1_ML; +typedef InterpMultilinear<2,double> NDInterpolator_2_ML; +typedef InterpMultilinear<3,double> NDInterpolator_3_ML; +typedef InterpMultilinear<4,double> NDInterpolator_4_ML; +typedef InterpMultilinear<5,double> NDInterpolator_5_ML; + +// C interface +extern "C" { + void linterp_simplex_1(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); + void linterp_simplex_2(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); + void linterp_simplex_3(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult); +} + +void inline linterp_simplex_1(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=1; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + +void inline linterp_simplex_2(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=2; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + +void inline linterp_simplex_3(double **grids_begin, int *grid_len_begin, double *pF, int xi_len, double **xi_begin, double *pResult) { + const int N=3; + size_t total_size = 1; + for (int i=0; i interp_obj(grids_begin, grid_len_begin, pF, pF + total_size); + interp_obj.interp_vec(xi_len, xi_begin, xi_begin + N, pResult); +} + + + + +#endif //_linterp_h \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/resource.h b/simorthoprogram-orth_s_sar-strip/resource.h new file mode 100644 index 0000000..c8940a4 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 供 SIMOrthoProgram.rc 使用 +// +#define IDR_PROJ1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/simorthoprogram-orth_s_sar-strip/simptsn.cpp b/simorthoprogram-orth_s_sar-strip/simptsn.cpp new file mode 100644 index 0000000..f721877 --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/simptsn.cpp @@ -0,0 +1,3696 @@ +#pragma once +/// +/// 仿真成像算法 +/// + +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 + +#include +#include +#include +#include +#include +#include +#include "baseTool.h" +#include "simptsn.h" +#include "SateOrbit.h" +#include "ImageMatch.h" +#include +#include +#include "gdal_priv.h" +#include "gdal_alg.h" +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Eigen; + + + +PSTNAlgorithm::PSTNAlgorithm() +{ +} + +PSTNAlgorithm::PSTNAlgorithm(string infile_path) +{ + std::cout << "=========================================================================" << endl; + std::cout << "read parameters :\t" << infile_path << endl; + std::cout << "parameters files :\t" << infile_path << endl; + std::cout << "params file Format:" << endl; + std::cout << "height --- image height" << endl; + std::cout << "width --- image width" << endl; + std::cout << "R0 --- image nearRange" << endl; + std::cout << "near_in_angle " << endl; + std::cout << "far incident angle " << endl; + std::cout << "LightSpeed " << endl; + std::cout << "lamda" << endl; + std::cout << "imgStartTime" << endl; + std::cout << "PRF" << endl; + std::cout << "refrange" << endl; + std::cout << "fs" << endl; + std::cout << "doppler_reference_time" << endl; + std::cout << "doppler_paramenter_number " << endl; + std::cout << "doppler_paramenter 1 " << endl; + std::cout << "doppler_paramenter 2" << endl; + std::cout << "doppler_paramenter 3 " << endl; + std::cout << "doppler_paramenter 4 " << endl; + std::cout << "doppler_paramenter 5 " << endl; + std::cout << "ispolySatelliteModel" << endl; + std::cout << "sate polynum " << endl; + std::cout << "SatelliteModelStartTime" << endl; + std::cout << "orbit params list " << endl; + std::cout << "============================================================================" << endl; + + // 解析文件 + ifstream infile(infile_path, ios::in); + if (!infile.is_open()) { + throw "参数文件未打开"; + } + try { + int line_ids = 0; + string buf; + + // 参数域 + getline(infile, buf); this->height = stoi(buf); + getline(infile, buf); this->width = stoi(buf); std::cout << "height,width\t" << this->height << "," << this->width << endl; + getline(infile, buf); this->R0 = stod(buf); std::cout <<""<< "R0\t" << this->R0 << endl; //近斜距 + getline(infile, buf); this->near_in_angle = stod(buf); std::cout << "near_in_angle\t" << this->near_in_angle << endl; //近入射角 + getline(infile, buf); this->far_in_angle = stod(buf); std::cout << "far_in_angle\t" << this->far_in_angle << endl; //远入射角 + + getline(infile, buf); this->LightSpeed = stod(buf); std::cout << "LightSpeed\t" << this->LightSpeed << endl; + getline(infile, buf); this->lamda = stod(buf); std::cout << "lamda\t" << this->lamda << endl; + getline(infile, buf); this->imgStartTime = stod(buf); std::cout << "imgStartTime\t" << this->imgStartTime << endl; + getline(infile, buf); this->PRF = stod(buf); std::cout << "PRF\t" << this->PRF << endl; + getline(infile, buf); this->refrange = stod(buf); std::cout << "refrange\t" << this->refrange << endl; + getline(infile, buf); this->fs = stod(buf); std::cout << "fs\t" << this->fs << endl; + getline(infile, buf); this->doppler_reference_time = stod(buf); std::cout << "doppler_reference_time\t" << this->doppler_reference_time << endl; + getline(infile, buf); this->doppler_paramenter_number = stoi(buf); std::cout << "doppler_paramenter_number\t" << this->doppler_paramenter_number << endl; + + // 读取多普勒系数 + this->doppler_paras = Eigen::MatrixX(this->doppler_paramenter_number, 1); + if (this->doppler_paramenter_number > 0) { + for (int i = 0; i < this->doppler_paramenter_number; i++) { + getline(infile, buf); + this->doppler_paras(i, 0) = stod(buf); + } + std::cout << "doppler_paramenter:\n" << this->doppler_paras << endl; + } + else { + throw "内存不足"; + } + // 读取卫星轨道 + getline(infile, buf); std::cout << "ispolySatelliteModel\t" << buf << endl; + if (stoi(buf) != 1) { + throw "不是多项式轨道模型"; + } + getline(infile, buf); int polynum = stoi(buf) + 1; // 多项式项数 + getline(infile, buf); double SatelliteModelStartTime = stod(buf); // 轨道模型起始时间 + + Eigen::MatrixX polySatellitePara(polynum, 6); + if (polynum >= 4) { + for (int i = 0; i < 6; i++) { + for (int j = 0; j < polynum; j++) { + getline(infile, buf); + polySatellitePara(j, i) = stod(buf); + std::cout << "orbit params " << i << " , " << j << buf << endl; + } + } + } + else { + throw "内存不足"; + } + OrbitPoly orbit(polynum, polySatellitePara, SatelliteModelStartTime); + this->orbit = orbit; + std::cout << "sate polynum\t" << polynum << endl; + std::cout << "sate polySatellitePara\n" << polySatellitePara << endl; + std::cout << "sate SatelliteModelStartTime\t" << SatelliteModelStartTime << endl; + + if (!infile.eof()) // 获取变换的函数 + { + double yy, mm, dd; + getline(infile, buf); + if (buf != "" || buf.length() > 3) { + yy = stod(buf); + getline(infile, buf); mm = stod(buf); + getline(infile, buf); dd = stod(buf); + this->UTC = Eigen::Matrix{ yy,mm,dd }; + std::cout << "UTC\t" << this->UTC << endl; + std::cout << "\nWGS84 to J2000 Params:\t" << endl; + getline(infile, buf); this->Xp = stod(buf); std::cout << "Xp\t" << this->Xp << endl; + getline(infile, buf); this->Yp = stod(buf); std::cout << "Yp\t" << this->Yp << endl; + getline(infile, buf); this->Dut1 = stod(buf); std::cout << "dut1\t" << this->Dut1 << endl; + getline(infile, buf); this->Dat = stod(buf); std::cout << "dat\t" << this->Dat << endl; + } + } + } + catch (exception e) { + infile.close(); + throw "文件读取错误"; + } + infile.close(); + std::cout << "============================================================================" << endl; +} + +PSTNAlgorithm::~PSTNAlgorithm() +{ +} + +/// +/// 将dem坐标转换为经纬文件 +/// +/// dem +/// 经度 +/// 纬度 +/// +int PSTNAlgorithm::dem2lat_lon(std::string dem_path, std::string lon_path, std::string lat_path) +{ + gdalImage dem_img(dem_path); + //gdalImage lon_img = CreategdalImage(lon_path, dem_img.height, dem_img.width); + //gdalImage lat_img = CreategdalImage(lat_path, dem_img.height, dem_img.width); + + + return 0; +} + +int PSTNAlgorithm::dem2SAR_RC(std::string dem_path, std::string sim_rc_path) +{ + return 0; +} + + +Eigen::MatrixX PSTNAlgorithm::calNumericalDopplerValue(Eigen::MatrixX R) +{ + Eigen::MatrixX t = (R.array() - this->refrange) * (1000000 / LIGHTSPEED); + Eigen::MatrixX tlist(t.rows(), this->doppler_paramenter_number);// nx5 + tlist.col(0) = Eigen::MatrixX::Ones(t.rows(), 1).col(0); + for (int i = 1; i < this->doppler_paramenter_number; i++) + { + tlist.col(i) = t.array().pow(i); + } + //return tlist.array()*this + return tlist * this->doppler_paras; //nx5,5x1 + //return Eigen::MatrixX(1, 1); +} + + +double PSTNAlgorithm::calNumericalDopplerValue(double R) +{ + //double t = (R - this->refrange) * (1e6 / LIGHTSPEED); GF3 + double t = R / LIGHTSPEED - this->doppler_reference_time; //S_SAR公式 + double temp = this->doppler_paras(0) + this->doppler_paras(1) * t + this->doppler_paras(2) * t * t + this->doppler_paras(3) * t * t * t + this->doppler_paras(4) * t * t * t * t; // GF3 HJ + //double temp = this->doppler_paras(0) + this->doppler_paras(1) * t + this->doppler_paras(2) * t * t + this->doppler_paras(3) * t * t * t; // LT + return temp; +} + + +Eigen::MatrixX PSTNAlgorithm::PSTN(Eigen::MatrixX landpoints, double ave_dem = 0, double dt = 0.001, bool isCol = false) +{ + //Eigen::MatrixX a(1, 1); + //a(0, 0) = 1554386455.999999; + //Eigen::MatrixX satestatetest = this->orbit.SatelliteSpacePoint(a); + //std::cout << satestatetest << endl; + + int point_num = landpoints.rows(); + Eigen::MatrixX SARPoint = Eigen::MatrixX::Ones(point_num, 3); + double L_T = 0; + double S_T = 0; + double R_T = 0; + double cos_theta = 0; + + Eigen::MatrixX landpoint = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + Eigen::MatrixX satevector = Eigen::MatrixX::Ones(1, 3);// 卫星速度 + Eigen::MatrixX sate_land = Eigen::MatrixX::Ones(1, 3); // 卫星-地面矢量 + double ti = this->orbit.SatelliteModelStartTime; + double R1 = 0;// 斜距 + double R2 = 0;// 斜距 + double FdTheory1 = 0; + double FdTheory2 = 0; + double FdNumberical = 0; + double inc_t = 0; + //double delta_angle = (this->far_in_angle - this->near_in_angle) / this->width; + //std::cout << landpoint(0, 0) << "\t" << landpoint(0, 1) << "\t" << landpoint(0, 2) << endl; + dt = dt / this->PRF; + Landpoint satePoints = { 0, 0, 0 }; + Landpoint landPoint = { 0, 0, 0 }; + // 开始迭代 + for (int j = 0; j < point_num; j++) { + landpoint = landpoints.row(j); + for (int i = 0; i < 50; i++) { + satestate = this->orbit.SatelliteSpacePoint(ti + dt); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satevector = satestate(Eigen::all, { 3,4,5 }); + sate_land = satepoint - landpoint; + //std::cout << sate_land << endl; + R1 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0];; + FdTheory1 = this->calTheoryDopplerValue(R1, sate_land, satevector); + + satestate = this->orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satevector = satestate(Eigen::all, { 3,4,5 }); + sate_land = satepoint - landpoint; + R2 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + FdNumberical = this->calNumericalDopplerValue(R2); + FdTheory2 = this->calTheoryDopplerValue(R2, sate_land, satevector); + + inc_t = dt * (FdTheory2 - FdNumberical) / (FdTheory1 - FdTheory2); + if (abs(FdTheory1 - FdTheory2) < 1e-9) { + break; + } + ti = ti - inc_t; + if (abs(inc_t) <= dt) { + break; + } + } + SARPoint(j, 0) = ti; + SARPoint(j, 1) = (ti - this->imgStartTime) * this->PRF; + + // 尝试使用入射角切分列号 + satestate = this->orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + sate_land = satepoint - landpoint; + R1 = (sate_land.array().pow(2).array().rowwise().sum().array().sqrt())[0];; + //SARPoint(j, 2) = getIncAngle(satePoints, landPoint); + //SARPoint(j, 2) = (R1 - this->R0 - (this->refrange - this->R0) / 3) / this->widthspace; + + SARPoint(j, 2) = getRangeColumn(R1, this->R0, this->fs, this->lamda);// (R1 - this->R0) / this->widthspace; // + } + //std::cout <<"SARPoints(200, 0):\t" << SARPoint(200, 0) << "\t" << SARPoint(200, 1) << "\t" << SARPoint(200, 2) << "\t" << endl; + return SARPoint; +} + +/* +Eigen::MatrixXd PSTNAlgorithm::WGS842J2000(Eigen::MatrixXd blh) +{ + return WGS84_J2000::WGS842J2000(blh, this->UTC, this->Xp, this->Yp, this->Dut1, this->Dat); + //return Eigen::MatrixXd(); +} + +Landpoint PSTNAlgorithm::WGS842J2000(Landpoint p) +{ + Eigen::MatrixXd blh = Eigen::MatrixXd(1, 3); + blh<WGS842J2000(blh); + return Landpoint{ blh(0,0),blh(0,1) ,blh(0,0) }; +} +*/ + +/// +/// 计算理论多普勒距离 +/// +/// 斜距 +/// nx3 +/// nx3 +/// +Eigen::MatrixX PSTNAlgorithm::calTheoryDopplerValue(Eigen::MatrixX R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1) +{ + return (R_s1.array() * V_s1.array()).rowwise().sum().array() * (-2) / (R.array() * this->lamda); + //return Eigen::MatrixX(1, 1); +} + +double PSTNAlgorithm::calTheoryDopplerValue(double R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1) { + return ((R_s1.array() * V_s1.array()).rowwise().sum().array() * (-2) / (R * this->lamda))[0]; +} + + +simProcess::simProcess() +{ + +} +simProcess::~simProcess() +{ +} +/// +/// 参数解析 +/// +/// +/// +/// +int simProcess::parameters(int argc, char* argv[]) +{ + for (int i = 0; i < argc; i++) { + std::cout << argv[i] << endl; + } + return 0; +} +/// +/// 间接定位法,初始化参数 +/// +/// 参数文件路径 +/// 工作空间路径 +/// 输出空间路径 +/// 输入DEM文件路径 +/// 输入SAR影像文件路径 +/// 初始化姐u共 +int simProcess::InitSimulationSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_sar_path) +{ + + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + this->in_dem_path = in_dem_path; + this->dem_path = JoinPath(workspace_path, "SAR_dem.tiff");// 获取输入DEM + this->workSpace_path = workspace_path; + this->dem_r_path = JoinPath(workspace_path, "dem_r.tiff"); + + string dem_rcs_path = JoinPath(workspace_path, "dem_rcs.tiff"); + this->sar_sim_wgs_path = JoinPath(workspace_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(workspace_path, "sar_sim.tiff"); + this->ori_sim_count_tiff = JoinPath(workspace_path, "RD_ori_sim_count.tiff"); + this->in_sar_path = in_sar_path; + this->sar_power_path = JoinPath(workspace_path, "in_sar_power.tiff"); + this->outSpace_path = out_dir_path; + this->out_dem_slantRange_path = out_dir_path + "\\" + "dem_slantRange.tiff";// 地形斜距 + this->out_plant_slantRange_path = out_dir_path + "\\" + "flat_slantRange.tiff";// 平地斜距 + this->out_dem_rc_path = out_dir_path + "\\" + "WGS_SAR_map.tiff";// 经纬度与行列号映射 + + + this->out_incidence_path = out_dir_path + "\\" + "incidentAngle.tiff";// 入射角 + this->out_localIncidenct_path = out_dir_path + "\\" + "localincidentAngle.tiff";// 局地入射角 + this->out_ori_sim_tiff = out_dir_path + "\\" + "RD_ori_sim.tif";// 坐标变换 + this->out_sim_ori_tiff = out_dir_path + "\\" + "RD_sim_ori.tif";// 坐标变换 + this->dem_rc_path = this->out_sim_ori_tiff;// JoinPath(out_dir_path, "RD_sim_ori.tif"); + this->sar_sim_wgs_path = JoinPath(out_dir_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(out_dir_path, "sar_sim.tiff"); + + + this->in_rpc_lon_lat_path = this->out_ori_sim_tiff; + this->out_inc_angle_rpc_path = out_dir_path + "\\" + "RD_incidentAngle.tiff";// 局地入射角 + this->out_local_inc_angle_rpc_path = out_dir_path + "\\" + "RD_localincidentAngle.tiff";// 局地入射角 + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_sar_path" << ":\t" << this->in_sar_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "dem_path" << ":\t" << this->dem_path << endl; + std::cout << "sar_power_path" << ":\t" << this->sar_power_path << endl; + std::cout << "dem_r_path" << ":\t" << this->dem_r_path << endl; + std::cout << "dem_rc_path" << ":\t" << this->dem_rc_path << endl; + std::cout << "sar_sim_wgs_path" << ":\t" << this->sar_sim_wgs_path << endl; + std::cout << "sar_sim_path" << ":\t" << this->sar_sim_path << endl; + std::cout << "outSpace_path" << ":\t" << this->outSpace_path << endl; + std::cout << "out_dem_slantRange_path" << ":\t" << this->out_dem_slantRange_path << endl; + std::cout << "out_plant_slantRange_path" << ":\t" << this->out_plant_slantRange_path << endl; + std::cout << "out_dem_rc_path" << ":\t" << this->out_dem_rc_path << endl; + std::cout << "out_incidence_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_localIncidenct_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->CreateSARDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + //this->SARSimulationWGS(); + //this->SARSimulation(); + //this->in_sar_power(); + if (boost::filesystem::exists(boost::filesystem::path(this->out_dem_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(this->out_dem_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(this->dem_rc_path), boost::filesystem::path(this->out_dem_rc_path)); + string sim_rcs_jpg_path = JoinPath(workspace_path, "dem_rcs.jpg"); + string sar_rcs_jpg_path = JoinPath(workspace_path, "sar_rcs.jpg"); + //this->createimagematchmodel(this->sar_power_path, sar_rcs_jpg_path, this->sar_sim_path, sim_rcs_jpg_path, this->workspace_path); + //if (this->ismatchmodel) { + // std::cout << "校正" << endl; + // this->correctorth_rc(this->dem_rc_path, this->matchmodel); + //} + ////插值计算行列号 + //this->ReflectTable_WGS2Range(); + //this->SARIncidentAngle_RPC(); + return 0; +} +int simProcess::InitASFSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path) +{ + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + this->in_dem_path = in_dem_path; + this->dem_path = JoinPath(workspace_path, "SAR_dem.tiff");// 获取输入DEM + this->workSpace_path = workspace_path; + this->dem_r_path = JoinPath(workspace_path, "dem_r.tiff"); + this->dem_rc_path = JoinPath(workspace_path, "dem_rc.tiff"); + string dem_rcs_path = JoinPath(workspace_path, "dem_rcs.tiff"); + this->sar_sim_wgs_path = JoinPath(workspace_path, "sar_sim_wgs.tiff"); + this->sar_sim_path = JoinPath(workspace_path, "sar_sim.tiff"); + this->ori_sim_count_tiff = JoinPath(workspace_path, "RD_ori_sim_count.tiff"); + this->in_sar_path = in_sar_path; + this->sar_power_path = JoinPath(workspace_path, "in_sar_power.tiff"); + this->outSpace_path = out_dir_path; + this->out_dem_slantRange_path = out_dir_path + "\\" + "dem_slantRange.tiff";// 地形斜距 + this->out_plant_slantRange_path = out_dir_path + "\\" + "flat_slantRange.tiff";// 平地斜距 + this->out_dem_rc_path = out_dir_path + "\\" + "WGS_SAR_map.tiff";// 经纬度与行列号映射 + this->out_incidence_path = out_dir_path + "\\" + "incidentAngle.tiff";// 入射角 + this->out_localIncidenct_path = out_dir_path + "\\" + "localincidentAngle.tiff";// 局地入射角 + this->out_ori_sim_tiff = out_dir_path + "\\" + "RD_ori_sim.tif";// 局地入射角 + this->in_rpc_lon_lat_path = this->out_ori_sim_tiff; + this->out_inc_angle_rpc_path = out_dir_path + "\\" + "RD_incidentAngle.tiff";// 局地入射角 + this->out_local_inc_angle_rpc_path = out_dir_path + "\\" + "RD_localincidentAngle.tiff";// 局地入射角 + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_sar_path" << ":\t" << this->in_sar_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "dem_path" << ":\t" << this->dem_path << endl; + std::cout << "sar_power_path" << ":\t" << this->sar_power_path << endl; + std::cout << "dem_rc_path" << ":\t" << this->dem_rc_path << endl; + std::cout << "sar_sim_wgs_path" << ":\t" << this->sar_sim_wgs_path << endl; + std::cout << "sar_sim_path" << ":\t" << this->sar_sim_path << endl; + std::cout << "outSpace_path" << ":\t" << this->outSpace_path << endl; + std::cout << "out_dem_slantRange_path" << ":\t" << this->out_dem_slantRange_path << endl; + std::cout << "out_plant_slantRange_path" << ":\t" << this->out_plant_slantRange_path << endl; + std::cout << "out_dem_rc_path" << ":\t" << this->out_dem_rc_path << endl; + std::cout << "out_incidence_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_localIncidenct_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->CreateSARDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + this->SARSimulationWGS(); + ASFOrthClass asfclass; + + this->SARSimulation(); + this->in_sar_power(); + if (boost::filesystem::exists(boost::filesystem::path(this->out_dem_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(this->out_dem_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(this->dem_rc_path), boost::filesystem::path(this->out_dem_rc_path)); + string sim_rcs_jpg_path = JoinPath(workspace_path, "dem_rcs.jpg"); + string sar_rcs_jpg_path = JoinPath(workspace_path, "sar_rcs.jpg"); + //this->createImageMatchModel(this->sar_power_path, sar_rcs_jpg_path, this->sar_sim_path, sim_rcs_jpg_path, this->workSpace_path); + if (this->isMatchModel) { + std::cout << "校正" << endl; + // this->correctOrth_rc(this->dem_rc_path, this->matchmodel); + } + + // 插值计算行列号 + this->ReflectTable_WGS2Range(); + this->SARIncidentAngle_RPC(); + return 0; + return 0; +} +/// +/// 创建SAR对应的DEM +/// +/// 返回结果 +int simProcess::CreateSARDEM() +{ + std::cout << "dem2SAR_Row_col begin time:" << getCurrentTimeString() << std::endl; + { + gdalImage dem(this->in_dem_path); + double dem_mean = dem.mean(); + gdalImage sim_rc = CreategdalImage(this->dem_rc_path, dem.height, dem.width, 2, dem.gt, dem.projection); + DemBox box{ 9999,9999,-9999,-9999 }; + { + Eigen::MatrixXd sim_r; + Eigen::MatrixXd sim_c; + int line_invert = int(2000000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + int max_rows_ids = 0; + int all_count = 0; + bool state = true; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd demdata = dem.getData(max_rows_ids, 0, line_invert, dem.width, 1); + Eigen::MatrixXd sim_r = demdata.array() * 0; + Eigen::MatrixXd sim_c = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 因为不考虑斜距,所以平面置为0 + } + } + //demdata = Eigen::MatrixXd(1, 1); + landpoint = dem.getLandPoint(landpoint); + //landpoint.col(2) = landpoint.col(2).array() * 0; + + landpoint = LLA2XYZ(landpoint); + landpoint = this->pstn.PSTN(landpoint, dem_mean, 0.001, true); // time,r,c + //std::cout << "for time " << getCurrentTimeString() << std::endl; + double min_lat = 9999; + double max_lat = -9999; + double min_lon = 9999; + double max_lon = -9999; + bool has_min_max = false; + Landpoint p1{ 0,0,0 }; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + sim_r(i, j) = landpoint(i * datacols + j, 1); + sim_c(i, j) = landpoint(i * datacols + j, 2); + p1 = dem.getLandPoint(i + max_rows_ids, j, demdata(i, j)); + if (sim_r(i, j) >= 0 && sim_c(i, j) >= 0 && sim_r(i, j) <= this->pstn.height && sim_c(i, j) <= this->pstn.width) { + min_lat = min_lat < p1.lat ? min_lat : p1.lat; + max_lat = max_lat > p1.lat ? max_lat : p1.lat; + min_lon = min_lon < p1.lon ? min_lon : p1.lon; + max_lon = max_lon > p1.lon ? max_lon : p1.lon; + has_min_max = true; + } + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + //std::cout << "lock" << endl; + if (has_min_max) { + box.min_lat = min_lat < box.min_lat ? min_lat : box.min_lat; + box.max_lat = max_lat > box.max_lat ? max_lat : box.max_lat;; + box.min_lon = min_lon < box.min_lon ? min_lon : box.min_lon;; + box.max_lon = max_lon > box.max_lon ? max_lon : box.max_lon;; + } + sim_rc.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc.saveImage(sim_c, max_rows_ids, 0, 2); + all_count = all_count + line_invert; + std::cout << "rows:\t" << all_count << "/" << dem.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + std::cout << "prepare over" << getCurrentTimeString() << std::endl; + double dist_lat = box.max_lat - box.min_lat; + double dist_lon = box.max_lon - box.min_lon; + /* dist_lat = 0.2 * dist_lat; + dist_lon = 0.2 * dist_lon;*/ + dist_lat = 0.001; + dist_lon = 0.001; + box.min_lat = box.min_lat - dist_lat; + box.max_lat = box.max_lat + dist_lat; + box.min_lon = box.min_lon - dist_lon; + box.max_lon = box.max_lon + dist_lon; + + std::cout << "box:" << endl; + std::cout << "min_lat-max_lat:\t" << box.min_lat << "\t" << box.max_lat << endl; + std::cout << "min_lon-max_lon:\t" << box.min_lon << "\t" << box.max_lon << endl; + std::cout << "cal box of sar over" << endl; + + // 计算采样之后的影像大小 + int width = 1.2 * this->pstn.width; + int height = 1.2 * this->pstn.height; + + double heightspace = (box.max_lat - box.min_lat) / height; + double widthspace = (box.max_lon - box.min_lon) / width; + std::cout << "resample dem:\n" << getCurrentTimeString() << std::endl; + std::cout << "in_dem:\t" << this->in_dem_path << endl; + std::cout << "out_dem:\t" << this->dem_path << endl; + std::cout << "width-height:\t" << width << "-" << height << endl; + std::cout << "widthspace\t-\theight\tspace:\t" << widthspace << "\t-\t" << heightspace << endl; + + int pBandIndex[1] = { 1 }; + int pBandCount[1] = { 1 }; + + double gt[6] = { + box.min_lon,widthspace,0, //x + box.max_lat,0,-heightspace//y + }; + + //boost::filesystem::copy(dem_path, this->dem_path); + ResampleGDAL(this->in_dem_path.c_str(), this->dem_path.c_str(), gt, width, height, GRA_Bilinear); + + std::cout << "resample dem over:\n" << getCurrentTimeString() << std::endl; + std::cout << "remove sim_rc_path:\t" << this->dem_rc_path << std::endl; + } + + return 0; +} + +/// +/// 获取行号 +/// +/// +int simProcess::dem2SAR() +{ + std::cout << "the row of the sar in dem:" << getCurrentTimeString() << std::endl; + { + this->dem2SAR_row(); + } + + std::cout << "the slant range of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_clip(this->dem_path); + gdalImage dem_r(this->dem_r_path); + double dem_mean = dem_clip.mean(); + gdalImage dem_slant_range = CreategdalImage(this->out_dem_slantRange_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + gdalImage plant_slant_range = CreategdalImage(this->out_plant_slantRange_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + + + int line_invert = int(10000000 / dem_clip.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + std::cout << "the slant range of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 行号 + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 地形 + Eigen::MatrixXd demslant_range = demdata.array() * 0; // 地形斜距 + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + landpoint = LLA2XYZ(landpoint);// this->pstn.WGS842J2000(landpoint); + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + long double ti = 0; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ti = dem_r_block(i, j) / this->pstn.PRF + this->pstn.imgStartTime; + satestate = this->pstn.orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satepoint(0, 0) = satepoint(0, 0) - landpoint(i * datacols + j, 0); + satepoint(0, 1) = satepoint(0, 1) - landpoint(i * datacols + j, 1); + satepoint(0, 2) = satepoint(0, 2) - landpoint(i * datacols + j, 2); + demslant_range(i, j) = (satepoint.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + dem_slant_range.saveImage(demslant_range, max_rows_ids, 0, 1); + //sim_rc_reprocess.saveImage(sim_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + count_lines = 0; + std::cout << "the plant slant range of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 行号 + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); // 地形 + Eigen::MatrixXd demslant_range = demdata.array() * 0; // 地形斜距 + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = 0; // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + landpoint = LLA2XYZ(landpoint); + Eigen::MatrixX satestate = Eigen::MatrixX::Ones(1, 6);// 卫星状态 + Eigen::MatrixX satepoint = Eigen::MatrixX::Ones(1, 3);// 卫星坐标 + long double ti = 0; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + ti = dem_r_block(i, j) / this->pstn.PRF + this->pstn.imgStartTime; + satestate = this->pstn.orbit.SatelliteSpacePoint(ti); + satepoint = satestate(Eigen::all, { 0,1,2 }); + satepoint(0, 0) = satepoint(0, 0) - landpoint(i * datacols + j, 0); + satepoint(0, 1) = satepoint(0, 1) - landpoint(i * datacols + j, 1); + satepoint(0, 2) = satepoint(0, 2) - landpoint(i * datacols + j, 2); + demslant_range(i, j) = (satepoint.array().pow(2).array().rowwise().sum().array().sqrt())[0]; + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + plant_slant_range.saveImage(demslant_range, max_rows_ids, 0, 1); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "the row and col of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_r(this->dem_r_path); + gdalImage plant_slant_range(this->out_plant_slantRange_path); + gdalImage dem_rc = CreategdalImage(this->dem_rc_path, dem_r.height, dem_r.width, 2, dem_r.gt, dem_r.projection); + + int line_invert = int(10000000 / dem_r.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + std::cout << "the row and col of the sar:" << getCurrentTimeString() << std::endl; +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_r.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd dem_r_block = dem_r.getData(max_rows_ids, 0, line_invert, dem_r.width, 1); // 行号 + Eigen::MatrixXd slant_range = plant_slant_range.getData(max_rows_ids, 0, line_invert, dem_r.width, 1); // 地形 + Eigen::MatrixXd dem_c = getRangeColumn(slant_range, this->pstn.R0, this->pstn.fs, this->pstn.lamda);// (slant_range.array() - this->pstn.R0) / this->pstn.widthspace; + omp_set_lock(&lock); //获得互斥器 + dem_rc.saveImage(dem_r_block, max_rows_ids, 0, 1); + dem_rc.saveImage(dem_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_r.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + + return 0; +} +/// +/// 计算相关的倾斜角 -- 弧度值 +/// +/// +int simProcess::SARIncidentAngle() +{ + std::cout << "the incidence angle and local incidence :" << getCurrentTimeString() << std::endl; + { + gdalImage dem_img(this->dem_path); + gdalImage sim_r_img(this->dem_r_path); + gdalImage localincidence_angle_img = CreategdalImage(this->out_localIncidenct_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + gdalImage incidence_angle_img = CreategdalImage(this->out_incidence_path, dem_img.height, dem_img.width, 1, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + incidence_angle_img.setNoDataValue(-10, 1); + localincidence_angle_img.setNoDataValue(-10, 1); + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(5000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + int count_lines = 0; + for (int max_rows_ids = 0; max_rows_ids < dem_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd sim_inclocal = incidence_angle_img.getData(max_rows_ids, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids, 0, line_invert + 2, line_width, 1); + sim_inclocal = sim_inclocal.array() * 0 - 10; + sim_localinclocal = sim_localinclocal.array() * 0 - 10; + localincidence_angle_img.saveImage(sim_localinclocal, max_rows_ids, 0, 1); + incidence_angle_img.saveImage(sim_inclocal, max_rows_ids, 0, 1); + } + + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + line_invert = int(200000000 / dem_img.width);// 基本大小 + for (int max_rows_ids = 1; max_rows_ids < dem_img.height; max_rows_ids = max_rows_ids + line_invert) { + start_ids = max_rows_ids - 1; + Eigen::MatrixXd demdata = dem_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_r = sim_r_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1).cast(); // + Eigen::MatrixXd sim_inclocal = incidence_angle_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids - 1, 0, line_invert + 2, line_width, 1); + //sim_r = sim_r.array() * (1 / PRF) + imgstarttime; + int rowcount = demdata.rows(); + int colcount = demdata.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + // sataState = + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + long double r; + for (int j = 1; j < colcount - 1; j++) { + r = sim_r(i, j); + Eigen::MatrixX sataState = this->pstn.orbit.SatelliteSpacePoint(r / PRF + imgstarttime); + p0 = dem_img.getLandPoint(i + start_ids, j, demdata(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, demdata(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, demdata(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, demdata(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, demdata(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + sim_localinclocal(i, j) = getlocalIncAngle(satepoint, landpoint, slopeVector); + //p0.ati = 0; + p0 = dem_img.getLandPoint(i + start_ids, j, demdata(i, j)); // 中心 + landpoint = LLA2XYZ(p0); + sim_inclocal(i, j) = getIncAngle(satepoint, landpoint); + } + } + int rows_save = sim_inclocal.rows() - 2; + //sim_inclocal =.array(); + //sim_localinclocal = .array(); + omp_set_lock(&lock); //获得互斥器 + count_lines = count_lines + line_invert; + localincidence_angle_img.saveImage(sim_localinclocal.block(1, 0, rows_save, line_width), max_rows_ids, 0, 1); + incidence_angle_img.saveImage(sim_inclocal.block(1, 0, rows_save, line_width), max_rows_ids, 0, 1); + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "the incidence angle and local incidence over:\t" << getCurrentTimeString() << std::endl; + return 0; +} +/// +/// 模拟WGS坐标下 SAR值 +/// +/// +int simProcess::SARSimulationWGS() +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage localincidence_angle_img(this->out_localIncidenct_path); + gdalImage sim_sar_img = CreategdalImage(this->sar_sim_wgs_path, localincidence_angle_img.height, localincidence_angle_img.width, 1, localincidence_angle_img.gt, localincidence_angle_img.projection);// 注意这里保留仿真结果 + int line_invert = int(5000000 / localincidence_angle_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = localincidence_angle_img.width; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < sim_sar_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd sim_localinclocal = localincidence_angle_img.getData(max_rows_ids, 0, line_invert, line_width, 1); + Eigen::MatrixXd sim_sar(line_invert, line_width); + sim_localinclocal = sim_localinclocal.array() * d2r; + // double((0.0133 * cos(localincangle) / pow(sin(localincangle + 0.1 * localincangle), 3))); + Eigen::MatrixXd cos_angle = sim_localinclocal.array().cos(); + Eigen::MatrixXd sin_angle = sim_localinclocal.array().sin(); + sim_sar = (0.0133 * cos_angle.array()) / ((sin_angle.array() + 0.1 * cos_angle.array()).pow(3)); + omp_set_lock(&lock); //获得互斥器 + count_lines = count_lines + line_invert; + sim_sar_img.saveImage(sim_sar, max_rows_ids, 0, 1); + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << sim_sar_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + + return 0; +} + +int simProcess::SARSimulation() +{ + std::cout << "computer the simulation value of sim_sar, begining:\t" << getCurrentTimeString() << endl; + gdalImage sim_sar_wgs_img(this->sar_sim_wgs_path); + gdalImage sim_rc(this->dem_rc_path); + gdalImage localIncident_img(this->out_localIncidenct_path); + gdalImage sim_sar_img = CreategdalImage(this->sar_sim_path, this->pstn.height, this->pstn.width, 1, sim_sar_wgs_img.gt, sim_sar_wgs_img.projection, false);// 注意这里保留仿真结果 + { + sim_sar_img.setNoDataValue(-9999, 1); + //double PRF = this->pstn.PRF; + //double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(30000000 / sim_sar_wgs_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = sim_sar_wgs_img.width; + Eigen::MatrixXd sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd sim_sum_h(line_invert, line_width); + Eigen::MatrixXd sim_rsc_orth(line_invert, line_width); + Eigen::MatrixXd sim_sum_sar(line_invert, line_width); + Eigen::MatrixXd demdata(line_invert, line_width); + Eigen::MatrixXd angle(line_invert, line_width); + + // 初始化 + do { + sim_sum_sar = sim_sar_img.getData(start_ids, 0, line_invert, this->pstn.width, 1).cast(); + sim_sum_sar = sim_sum_sar.array() * 0; + sim_sar_img.saveImage(sim_sum_sar, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + { + // 累加计算模拟值 + int rowcount = 0, colcount = 0; + int row_min = 0, row_max = 0; + start_ids = 0; + std::cout << "time:\tsim_arr_row_min\tsim_arr_row_max\tsim_arr_all_lines\tsim_row_min\tsim_row_max\tsim_row_min0\tsim_row_max0" << std::endl;; + do { + std::cout << "\n" << getCurrentTimeString() << "\t" << start_ids << "\t" << start_ids + line_invert << "\t" << sim_rc.height << "\t"; + sim_r = sim_rc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 行 + sim_c = sim_rc.getData(start_ids, 0, line_invert, line_width, 2).cast(); // 列 + angle = localIncident_img.getData(start_ids, 0, line_invert, line_width, 1).cast(); + sim_rsc_orth = sim_sar_wgs_img.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + // 范围 + row_min = (floor(sim_r.minCoeff())); + row_max = (ceil(sim_r.maxCoeff())); + std::cout << row_min << "\t" << row_max << "\t"; + + //std::cout << "line range:\t" << row_min << " - " << row_max << "\t computing.....\t" << getCurrentTimeString() << endl; + + if (row_max < 0 || row_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + row_min = row_min <= 0 ? 0 : row_min; + row_max = row_max >= this->pstn.height ? this->pstn.height : row_max; + std::cout << row_min << "\t" << row_max << std::endl; + //sim_sum_sar =sim_sar.getData(row_min, 0, row_max-row_min+1, this->pstn.width, 1).cast(); + //sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + if (row_min >= row_max) { + break; + } + sim_sum_sar = sim_sar_img.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 1).cast(); + rowcount = sim_r.rows(); + colcount = sim_r.cols(); + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 0; i < rowcount; i++) { + int row_ids = 0, col_ids = 0; + for (int j = 0; j < colcount; j++) { + row_ids = int(round(sim_r(i, j))); + col_ids = int(round(sim_c(i, j))); + if (row_ids >= 0 && row_ids < this->pstn.height && col_ids >= 0 && col_ids < this->pstn.width && (angle(i, j) < 90 || angle(i, j) > 270)) { + sim_sum_sar(row_ids - row_min, col_ids) += sim_rsc_orth(i, j); + } + } + } + sim_sar_img.saveImage(sim_sum_sar, row_min, 0, 1); + + start_ids = start_ids + line_invert; + } while (start_ids < sim_rc.height); + std::cout << "\ncomputer the simulation value of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + } + + { + std::cout << "Resample simulation value of sim_sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(this->sar_sim_path.c_str(), 1, GRIORA_Bilinear); + } + + return 0; +} + +int simProcess::in_sar_power() +{ + std::cout << "compute the power value of ori sar, beiging:\t" << getCurrentTimeString() << endl; + gdalImage ori_sar(this->in_sar_path); + gdalImage sim_power = CreategdalImage(this->sar_power_path, ori_sar.height, ori_sar.width, 1, ori_sar.gt, ori_sar.projection); + sim_power.setNoDataValue(-9999, 1); + { + Eigen::MatrixXd band1(1, 1); + Eigen::MatrixXd band2(1, 1); + Eigen::MatrixXd power_value(1, 1); + int start_ids = 0; + int line_invert = int(8000000 / ori_sar.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + std::cout << "rows:\t" << start_ids << "/" << ori_sar.height << "\t computing.....\t" << getCurrentTimeString() << endl; + band1 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 1).cast(); // a + band2 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 2).cast(); // b + power_value = (band1.array().pow(2) + band2.array().pow(2) + 1).log10() * 10;// 10 * Eigen::log10(Eigen::pow(0.5, Eigen::pow(2, band1.array()) + Eigen::pow(2, band2.array()))).array(); + sim_power.saveImage(power_value, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < ori_sar.height); + } + { + std::cout << "Resample the power value of ori sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(this->sar_power_path.c_str(), 1, GRIORA_Bilinear); + } + std::cout << "compute the power value of ori sar, ending:\t" << getCurrentTimeString() << endl; + { + std::cout << "=========================================\n"; + std::cout << " the power image of sar :\n"; + std::cout << this->sar_power_path.c_str() << "\n"; + std::cout << "band 1 : power value \t 10*log10(b1^2+b2^2) \n"; + std::cout << "=========================================\n"; + + } + return 0; + return 0; +} + + + + +int simProcess::Scatter2Grid(std::string lon_lat_path, std::string data_tiff, std::string grid_path, double space) { + + gdalImage lon_lat_img(lon_lat_path); + double min_lon = 400, max_lon = -400, min_lat = 300, max_lat = -300; + { + int conver_lines = 2000; + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + conver_lines) { + Eigen::MatrixXd lon = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + Eigen::MatrixXd lat = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 2); + int rows = lon.rows(); + int cols = lon.cols(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (min_lon > lon(i, j) && !isnan(lon(i, j)) && lon(i, j) > -200) { + min_lon = lon(i, j); + } + if (min_lat > lat(i, j) && !isnan(lat(i, j)) && lat(i, j) > -200) { + min_lat = lat(i, j); + } + if (max_lon < lon(i, j) && !isnan(lon(i, j)) && lon(i, j) > -200) { + max_lon = lon(i, j); + } + + if (max_lat < lat(i, j) && !isnan(lat(i, j)) && lat(i, j) > -200) { + max_lat = lat(i, j); + } + } + } + } + } + std::cout << "lon:\t" << min_lon << " , " << max_lon << endl; + std::cout << "lat:\t" << min_lat << " , " << max_lat << endl; + + double delta = space /( 110 * 1000); + int width = int((max_lon - min_lon) / delta) + 1; + int height = int((max_lat - min_lat) / delta) + 1; + Eigen::MatrixXd gt(2, 3); + gt(0, 0) = min_lon; gt(0, 1) = delta; gt(0, 2) = 0;//x + gt(1, 0) = max_lat; gt(1, 1) = 0; gt(1, 2) = -1*delta;//y + + // # + char* pszSrcWKT = NULL; + OGRSpatialReference oSRS; + oSRS.importFromEPSG(4326); + //oSRS.SetUTM(50, true); //北半球 东经120度 + //oSRS.SetWellKnownGeogCS("WGS84"); + oSRS.exportToWkt(&pszSrcWKT); + gdalImage grid_img = CreategdalImage(grid_path, height, width, 1, gt, pszSrcWKT, true); + int conver_lines = 2000; + for (int max_rows_ids = 0; max_rows_ids < grid_img.height; max_rows_ids = max_rows_ids + conver_lines) { + Eigen::MatrixXd grid_data = grid_img.getData(max_rows_ids, 0, conver_lines, width, 1); + grid_data = grid_data.array() * 0 - 9999; + grid_img.saveImage(grid_data, max_rows_ids, 0, 1); + } + grid_img.setNoDataValue(-9999, 1); + Eigen::MatrixXd grid_data = grid_img.getData(0, 0, grid_img.height, grid_img.width, 1); + gdalImage Range_data(data_tiff); + grid_img.InitInv_gt(); + { + int conver_lines = 500; + int line_invert = 400;// 计算重叠率 + int line_offset = 60; + // 逐区域迭代计算 + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + int allCount = 0; + + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd lon_data = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + Eigen::MatrixXd lat_data = lon_lat_img.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 2); + Eigen::MatrixXd data = Range_data.getData(max_rows_ids, 0, conver_lines, lon_lat_img.width, 1); + int lon_row_count = lon_data.rows(); + for (int i = 0; i < lon_row_count; i++) { + for (int j = 0; j < lon_lat_img.width; j++) { + Landpoint p = grid_img.getRow_Col(lon_data(i, j), lat_data(i, j)); + lon_data(i, j) = p.lon; + lat_data(i, j) = p.lat; + } + } + int dem_rows_num = lon_data.rows(); + int dem_cols_num = lon_data.cols(); + + #pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < dem_rows_num - 1; i++) { + for (int j = 0; j < dem_cols_num - 1; j++) { + Point_3d p, p1, p2, p3, p4; + + p1 = { lat_data(i,j),lon_data(i,j) }; + p2 = { lat_data(i,j + 1),lon_data(i,j + 1) }; + p3 = { lat_data(i + 1, j + 1),lon_data(i + 1, j + 1) }; + p4 = { lat_data(i + 1, j),lon_data(i + 1, j) }; + + //if (angle(i, j) >= 90 && angle(i, j + 1) >= 90 && angle(i + 1, j) >= 90 && angle(i + 1, j + 1) >= 90) { + // continue; + //} + + double temp_min_r = lat_data.block(i, j, 2, 2).minCoeff(); + double temp_max_r = lat_data.block(i, j, 2, 2).maxCoeff(); + double temp_min_c = lon_data.block(i, j, 2, 2).minCoeff(); + double temp_max_c = lon_data.block(i, j, 2, 2).maxCoeff(); + if ((int(temp_min_r) != int(temp_max_r)) && (int(temp_min_c) != int(temp_max_c))) { + for (int ii = int(temp_min_r); ii <= temp_max_r + 1; ii++) { + for (int jj = int(temp_min_c); jj < temp_max_c + 1; jj++) { + if (ii < 0 || ii >= height || jj < 0 || jj >= width) { + continue; + } + p = { double(ii),double(jj),0 }; + //if (PtInRect(p, p1, p2, p3, p4)) { + p1.z = data(i, j); + p2.z = data(i, j + 1); + p3.z = data(i + 1, j + 1); + p4.z = data(i + 1, j); + + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + if (p.x < 0) { + continue; + } + double mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + grid_data(ii , jj) = p.z; + //} + } + } + } + } + } + allCount = allCount + line_invert; + std::cout << "rows:\t" << allCount << "/" << lon_lat_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + } + } + grid_img.saveImage(grid_data, 0, 0, 1); + return 0; +} + + + +/* +描述:判断点是否在四边形内,该函数也适用于多边形,将点数改成你想要的边数就行 +参数: + pCur:当前点 + pLeftTop:左上角 + pRightTop:右上角 + pRightBelow:右下 + pLeftBelow:左下 +返回值:如果在四边形内返回 true ,否则返回 false +*/ + +bool PtInRect(Point_3d pCur, Point_3d pLeftTop, Point_3d pRightTop, Point_3d pRightBelow, Point_3d pLeftBelow) +{ + int nCount = 4;//任意四边形有4个顶点 + Point_3d RectPoints[4] = { pLeftTop, pLeftBelow, pRightBelow, pRightTop }; + int nCross = 0; + double lastPointX = -999.999; + for (int i = 0; i < nCount; i++) + { + //依次取相邻的两个点 + Point_3d pBegin = RectPoints[i]; + Point_3d pEnd = RectPoints[(i + 1) % nCount]; + //相邻的两个点是平行于x轴的,当前点和x轴的平行线要么重合,要么不相交,不算 + if (pBegin.y == pEnd.y)continue; + //交点在pBegin,pEnd的延长线上,不算 + if (pCur.y < min(pBegin.y, pEnd.y) || pCur.y > max(pBegin.y, pEnd.y))continue; + //当前点和x轴的平行线与pBegin,pEnd直线的交点的x坐标 + double x = (double)(pCur.y - pBegin.y) * (double)(pEnd.x - pBegin.x) / (double)(pEnd.y - pBegin.y) + pBegin.x; + if (x > pCur.x)//只看pCur右边交点 + { + if (x != lastPointX)//防止角点算两次 + { + nCross++; + lastPointX = x; + } + } + } + // 单方向交点为奇数,点在多边形之内 + // 单方向交点为偶数,点在多边形之外 + return (nCross % 2 == 1); +} + +int simProcess::ReflectTable_WGS2Range() +{// + gdalImage sim_rc(this->dem_rc_path); + gdalImage sim_sar_img = CreategdalImage(this->out_ori_sim_tiff, this->pstn.height, this->pstn.width, 2, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + gdalImage sim_sar_count_img = CreategdalImage(this->ori_sim_count_tiff, this->pstn.height, this->pstn.width, 1, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + gdalImage localIncident_img(this->out_localIncidenct_path); + for (int max_rows_ids = 0; max_rows_ids < this->pstn.height; max_rows_ids = max_rows_ids + 1000) { + Eigen::MatrixXd sim_sar = sim_sar_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 1); + Eigen::MatrixXd sim_sarc = sim_sar_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 2); + Eigen::MatrixXd sim_sar_count = sim_sar_count_img.getData(max_rows_ids, 0, 1000, this->pstn.width, 1); + sim_sar = sim_sar.array() * 0 - 9999; + sim_sarc= sim_sar.array() * 0 - 9999; + sim_sar_count = sim_sar_count.array() * 0; + sim_sar_img.saveImage(sim_sar, max_rows_ids, 0, 1); + sim_sar_img.saveImage(sim_sarc, max_rows_ids, 0, 2); + sim_sar_count_img.saveImage(sim_sar_count, max_rows_ids, 0, 1); + } + sim_sar_img.setNoDataValue(-9999, 1); + sim_sar_img.setNoDataValue(-9999, 2); + int conver_lines = 5000; + int line_invert = 4000;// 计算重叠率 + int line_offset = 60; + // 逐区域迭代计算 + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + int allCount = 0; + + for (int max_rows_ids = 0; max_rows_ids < sim_rc.height; max_rows_ids = max_rows_ids + line_invert) { + Eigen::MatrixXd angle = localIncident_img.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 1).cast(); + Eigen::MatrixXd dem_r = sim_rc.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 1); + Eigen::MatrixXd dem_c = sim_rc.getData(max_rows_ids, 0, conver_lines, sim_rc.width, 2); + int dem_rows_num = dem_r.rows(); + int dem_cols_num = dem_r.cols(); + // 更新插值经纬度 + //Eigen::MatrixXd dem_lon = dem_r; + //Eigen::MatrixXd dem_lat = dem_c; + // 构建索引 更新经纬度并更新链 + + int temp_r, temp_c; + + /* int min_row = dem_r.minCoeff() + 1; + int max_row = dem_r.maxCoeff() + 1; + + if (max_row < 0) { + continue; + }*/ + + int min_row = dem_r.minCoeff() + 1; + int max_row = dem_r.maxCoeff() + 1; + int min_col = dem_c.minCoeff() + 1; + int max_col = dem_c.maxCoeff() + 1; + if (max_row < 0 || min_row >= this->pstn.height || max_col < 0 || min_col >= this->pstn.width) { // 增加边界判断条件 + continue; + } + + int len_rows = max_row - min_row; + min_row = min_row < 0 ? 0 : min_row; + Eigen::MatrixXd sar_r = sim_sar_img.getData(min_row, 0, len_rows, this->pstn.width, 1); + Eigen::MatrixXd sar_c = sim_sar_img.getData(min_row, 0, len_rows, this->pstn.width, 2); + len_rows = sar_r.rows(); + + + #pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < dem_rows_num - 1; i++) { + for (int j = 0; j < dem_cols_num - 1; j++) { + Point_3d p, p1, p2, p3, p4; + Landpoint lp1, lp2, lp3, lp4; + lp1 = sim_rc.getLandPoint(i + max_rows_ids, j, 0); + lp2 = sim_rc.getLandPoint(i + max_rows_ids, j + 1, 0); + lp3 = sim_rc.getLandPoint(i + 1 + max_rows_ids, j + 1, 0); + lp4 = sim_rc.getLandPoint(i + 1 + max_rows_ids, j, 0); + + p1 = { dem_r(i,j),dem_c(i,j) }; + p2 = { dem_r(i,j + 1),dem_c(i,j + 1) }; + p3 = { dem_r(i + 1,j + 1),dem_c(i + 1,j + 1) }; + p4 = { dem_r(i + 1,j),dem_c(i + 1,j) }; + + //if (angle(i, j) >= 90 && angle(i, j + 1) >= 90 && angle(i + 1, j) >= 90 && angle(i + 1, j + 1) >= 90) { + // continue; + //} + + double temp_min_r = dem_r.block(i, j, 2, 2).minCoeff(); + double temp_max_r = dem_r.block(i, j, 2, 2).maxCoeff(); + double temp_min_c = dem_c.block(i, j, 2, 2).minCoeff(); + double temp_max_c = dem_c.block(i, j, 2, 2).maxCoeff(); + if ((int(temp_min_r) != int(temp_max_r)) && (int(temp_min_c) != int(temp_max_c))) { + for (int ii = int(temp_min_r); ii <= temp_max_r + 1; ii++) { + for (int jj = int(temp_min_c); jj < temp_max_c + 1; jj++) { + if (ii < min_row || ii - min_row >= len_rows || jj < 0 || jj >= this->pstn.width) { + continue; + } + p = { double(ii),double(jj),-9999 }; + //if (PtInRect(p, p1, p2, p3, p4)) { + p1.z = lp1.lon; + p2.z = lp2.lon; + p3.z = lp3.lon; + p4.z = lp4.lon; + + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + + if (p.x < 0) { + continue; + } + double mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + sar_r(ii - min_row, jj) = p.z; + p1.z = lp1.lat; + p2.z = lp2.lat; + p3.z = lp3.lat; + p4.z = lp4.lat; + p = invBilinear(p, p1, p2, p3, p4); + if (isnan(p.z)) { + continue; + } + + if (p.x < 0) { + continue; + } + mean = (p1.z + p2.z + p3.z + p4.z) / 4; + if (p.z > p1.z && p.z > p2.z && p.z > p3.z && p.z > p4.z) { + p.z = mean; + } + if (p.z < p1.z && p.z < p2.z && p.z < p3.z && p.z < p4.z) { + p.z = mean; + } + sar_c(ii - min_row, jj) = p.z; + //} + } + } + + } + } + } + + omp_set_lock(&lock); //获得互斥器 + sim_sar_img.saveImage(sar_r, min_row, 0, 1); + sim_sar_img.saveImage(sar_c, min_row, 0, 2); + allCount = allCount + conver_lines; + std::cout << "rows:\t" << allCount << "/" << sim_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + + std::cout << "\t resample computing.....\t" << getCurrentTimeString() << endl; + { int conver = 5000; + int line_invert = 4000;// 计算重叠率 + ResampleGDALs(this->out_ori_sim_tiff.c_str(), 1, GRIORA_Bilinear); + ResampleGDALs(this->out_ori_sim_tiff.c_str(), 2, GRIORA_Bilinear); + } + + return 0; +} + +int simProcess::InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_paths, std::string out_inc_angle_path, std::string out_local_inc_angle_path, std::string out_inc_angle_geo_path, std::string out_local_inc_angle_geo_path) +{ + this->pstn = PSTNAlgorithm(paras_path); // 初始化参数文件 + + this->in_rpc_lon_lat_path = in_rpc_lon_lat_paths; + this->in_dem_path = in_dem_path; + this->outSpace_path = out_dir_path; + this->workSpace_path = workspace_path; + + // 临时文件 + this->dem_path = JoinPath(this->workSpace_path, "SAR_dem.tiff"); + this->dem_rc_path = JoinPath(this->workSpace_path, "dem_rc.tiff"); + this->dem_r_path = JoinPath(this->workSpace_path, "dem_r.tiff"); + this->out_incidence_path = out_inc_angle_geo_path; + this->out_localIncidenct_path = out_local_inc_angle_geo_path; + this->rpc_wgs_path = JoinPath(this->workSpace_path, "rcp2dem_wgs.tiff"); + // 输出文件 + this->out_inc_angle_rpc_path = out_inc_angle_path; + this->out_local_inc_angle_rpc_path = out_local_inc_angle_path; + + std::cout << "==========================================================================" << endl; + std::cout << "in_dem_path" << ":\t" << this->in_dem_path << endl; + std::cout << "in_rpc_lon_lat_path" << ":\t" << this->in_rpc_lon_lat_path << endl; + std::cout << "workSpace_path" << ":\t" << this->workSpace_path << endl; + std::cout << "out_dir_path" << ":\t" << this->out_dir_path << endl; + std::cout << "out_inc_angle_path" << ":\t" << this->out_incidence_path << endl; + std::cout << "out_local_inc_angle_path" << ":\t" << this->out_localIncidenct_path << endl; + std::cout << "==========================================================================" << endl; + this->createRPCDEM(); + this->dem2SAR_row(); // 获取行号 + this->SARIncidentAngle(); + this->SARIncidentAngle_RPC(); + this->in_sar_power(); + return 0; + return 0; +} + +int simProcess::dem2SAR_row() +{ + + std::cout << "the row of the sar in dem:" << getCurrentTimeString() << std::endl; + { + gdalImage dem_clip(this->dem_path); + double dem_mean = dem_clip.mean(); + gdalImage sim_r_reprocess = CreategdalImage(this->dem_r_path, dem_clip.height, dem_clip.width, 1, dem_clip.gt, dem_clip.projection); + gdalImage sim_rc_reprocess = CreategdalImage(this->dem_rc_path, dem_clip.height, dem_clip.width, 2, dem_clip.gt, dem_clip.projection); + int line_invert = int(15000000 / dem_clip.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < dem_clip.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd demdata = dem_clip.getData(max_rows_ids, 0, line_invert, dem_clip.width, 1); + + Eigen::MatrixXd sim_r = demdata.array() * 0; + Eigen::MatrixXd sim_c = demdata.array() * 0; + + int datarows = demdata.rows(); + int datacols = demdata.cols(); + Eigen::MatrixX landpoint(datarows * datacols, 3); + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + landpoint(i * datacols + j, 0) = i + max_rows_ids; + landpoint(i * datacols + j, 1) = j; + landpoint(i * datacols + j, 2) = demdata(i, j); // 设为0 ,则为初始0值 + } + } + landpoint = dem_clip.getLandPoint(landpoint); + //landpoint.col(2) = landpoint.col(2).array() * 0; + landpoint = LLA2XYZ(landpoint); + landpoint = this->pstn.PSTN(landpoint, dem_mean); // time,r,c + //std::cout << "for time " << getCurrentTimeString() << std::endl; + for (int i = 0; i < datarows; i++) { + for (int j = 0; j < datacols; j++) { + sim_r(i, j) = landpoint(i * datacols + j, 1); + sim_c(i, j) = landpoint(i * datacols + j, 2); + } + } + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + sim_r_reprocess.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc_reprocess.saveImage(sim_r, max_rows_ids, 0, 1); + sim_rc_reprocess.saveImage(sim_c, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << dem_clip.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "dem2SAR_Row_col dem_2_sarRC over " << getCurrentTimeString() << std::endl; + + std::cout << "=========================================\n"; + std::cout << "the row and col of the sar in dem:\n"; + std::cout << this->dem_r_path << "\n"; + std::cout << "band 1 : the row of the sar \n"; + std::cout << "=========================================\n"; + } + return 0; +} + +/// +/// 计算RPC的入射角 +/// +/// +int simProcess::SARIncidentAngle_RPC() { + this->calGEC_Incident_localIncident_angle(this->dem_path, this->in_rpc_lon_lat_path, this->out_inc_angle_rpc_path, this->out_local_inc_angle_rpc_path, this->pstn); + return 0; +} + +int simProcess::createRPCDEM() +{ + std::cout << "dem2SAR_Row_col begin time:" << getCurrentTimeString() << std::endl; + { + gdalImage dem(this->in_dem_path); + gdalImage lonlat(this->in_rpc_lon_lat_path); + DemBox box{ 9999,9999,-9999,-9999 }; + { + int start_ids = 0; + int line_invert = int(4000000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + for (start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) { + std::cout << "rows:\t" << start_ids << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd lon = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd lat = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 2); + double min_lat = lat.array().minCoeff(); + double max_lat = lat.array().maxCoeff(); + double min_lon = lon.array().minCoeff(); + double max_lon = lon.array().maxCoeff(); + box.min_lat = min_lat < box.min_lat ? min_lat : box.min_lat; + box.max_lat = max_lat > box.max_lat ? max_lat : box.max_lat;; + box.min_lon = min_lon < box.min_lon ? min_lon : box.min_lon;; + box.max_lon = max_lon > box.max_lon ? max_lon : box.max_lon;; + + } + } + std::cout << "prepare over" << getCurrentTimeString() << std::endl; + double dist_lat = box.max_lat - box.min_lat; + double dist_lon = box.max_lon - box.min_lon; + dist_lat = 0.1 * dist_lat; + dist_lon = 0.1 * dist_lon; + box.min_lat = box.min_lat - dist_lat; + box.max_lat = box.max_lat + dist_lat; + box.min_lon = box.min_lon - dist_lon; + box.max_lon = box.max_lon + dist_lon; + + std::cout << "box:" << endl; + std::cout << "min_lat-max_lat:\t" << box.min_lat << "\t" << box.max_lat << endl; + std::cout << "min_lon-max_lon:\t" << box.min_lon << "\t" << box.max_lon << endl; + std::cout << "cal box of sar over" << endl; + + // 计算采样之后的影像大小 + int width = 1.5 * this->pstn.width; + int height = 1.5 * this->pstn.height; + + double heightspace = (box.max_lat - box.min_lat) / height; + double widthspace = (box.max_lon - box.min_lon) / width; + std::cout << "resample dem:\n" << getCurrentTimeString() << std::endl; + std::cout << "in_dem:\t" << this->in_dem_path << endl; + std::cout << "out_dem:\t" << this->dem_path << endl; + std::cout << "width-height:\t" << width << "-" << height << endl; + std::cout << "widthspace\t-\theight\tspace:\t" << widthspace << "\t-\t" << heightspace << endl; + + int pBandIndex[1] = { 1 }; + int pBandCount[1] = { 1 }; + + double gt[6] = { + box.min_lon,widthspace,0, //x + box.max_lat,0,-heightspace//y + }; + + //boost::filesystem::copy(dem_path, this->dem_path); + ResampleGDAL(this->in_dem_path.c_str(), this->dem_path.c_str(), gt, width, height, GRA_Bilinear); + + std::cout << "resample dem over:\n" << getCurrentTimeString() << std::endl; + std::cout << "remove sim_rc_path:\t" << this->dem_rc_path << std::endl; + } + + return 0; +} + + +/// +/// 模拟SAR影像 +/// +/// dem影像 +/// rc 影像 +/// 结果:模拟sar影像 +/// 参数类 +/// 执行状态 +int simProcess::sim_SAR(std::string dem_path, std::string sim_rc_path, std::string sim_sar_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage dem_img(dem_path); + gdalImage sim_rc(sim_rc_path); + gdalImage sim_sar = CreategdalImage(sim_sar_path, dem_img.height, dem_img.width, 2, dem_img.gt, dem_img.projection);// 注意这里保留仿真结果 + sim_sar.setNoDataValue(-9999, 1); + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(50000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + Eigen::MatrixX sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd dem(line_invert, line_width); + Eigen::MatrixXd sim_rsc(line_invert, line_width); + Eigen::MatrixXd sim_inclocal(line_invert, line_width); + + int rowcount = 0, colcount = 0; + //omp_lock_t lock; + //omp_init_lock(&lock); // 初始化互斥锁 + do { + std::cout << "rows:\t" << start_ids << "-" << start_ids + line_invert + 2 << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + dem = dem_img.getData(start_ids, 0, line_invert + 2, line_width, 1); + sim_r = sim_rc.getData(start_ids, 0, line_invert + 2, line_width, 1).cast(); + sim_r = sim_r.array() * (1 / PRF) + imgstarttime; + //sim_c = sim_rc.getData(start_ids, 0, line_invert + 1, line_width, 2); + sim_rsc = dem.array() * 0; + sim_inclocal = dem.array() * 0 - 9999; + rowcount = dem.rows(); + colcount = dem.cols(); + + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + Eigen::MatrixX sataState = sim_r.row(i).reshaped(line_width, 1); + sataState = this->pstn.orbit.SatelliteSpacePoint(sataState); + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle; + for (int j = 1; j < colcount - 1; j++) { + p0 = dem_img.getLandPoint(i + start_ids, j, dem(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, dem(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, dem(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, dem(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, dem(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(j,0),sataState(j,1) ,sataState(j,2) }; + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector); + sim_inclocal(i, j) = localincangle; + if (localincangle < 90) + { + localincangle = localincangle * d2r; + sim_rsc(i, j) = 100 * double((0.0133 * cos(localincangle) / pow(sin(localincangle + 0.1 * localincangle), 3))); + //sim_rsc(i, j) = sim_rsc(i, j) > 100 ? -9999 : sim_rsc(i, j); + } + } + } + //omp_set_lock(&lock); //获得互斥器 + //std::cout << sim_rsc(1, 1961) << endl; + sim_sar.saveImage(sim_rsc.block(1, 0, rowcount - 2, colcount), start_ids + 1, 0, 1); + sim_sar.saveImage(sim_inclocal.block(1, 0, rowcount - 2, colcount), start_ids + 1, 0, 2); + //omp_unset_lock(&lock); //释放互斥器 + start_ids = start_ids + line_invert - 4; + } while (start_ids < dem_img.height); + //omp_destroy_lock(&lock); //销毁互斥器 + std::cout << "computer the simulation value of evering dem meta, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the simulation sar value Raster has the projection that is same of dem" << endl; + std::cout << sim_sar_path << endl; + std::cout << "band 1: the simulation sar value" << endl; + std::cout << "band 2: the local incident angle " << endl; + std::cout << "==========================================================" << endl; + return 0; +} + + +int simProcess::dem2aspect_slope(std::string dem_path, std::string aspect_path, std::string slope_path) +{ + std::cout << "computer aspect and slop begining:\t" << getCurrentTimeString() << endl; + + GDALAllRegister();// 注册格式的驱动 + GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); + GDALDataset* dem = (GDALDataset*)(GDALOpen(dem_path.c_str(), GA_ReadOnly)); + GDALDEMProcessing(aspect_path.c_str(), dem, "aspect", NULL, NULL, NULL); + GDALDEMProcessing(slope_path.c_str(), dem, "slope", NULL, NULL, NULL); + GDALClose(dem); + std::cout << "computer aspect and slop overing:\t" << getCurrentTimeString() << endl; + return 0; +} + +/// +/// 根据前面模拟结果与行列号,生成模拟仿真图,分批生成并计算目标对象 +/// +/// 仿真行列号 +/// 正射单元格结果 +/// 模拟影像路径 +/// +int simProcess::sim_sum_SAR(std::string sim_dem_path, std::string sim_rc_path, std::string sim_orth_path, std::string sim_sum_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of sim_sar, begining:\t" << getCurrentTimeString() << endl; + //gdalImage dem_img(dem_path); + gdalImage sim_rc(sim_rc_path); + gdalImage sim_rsc(sim_orth_path); + gdalImage dem(sim_dem_path); + gdalImage sim_sar = CreategdalImage(sim_sum_path, this->pstn.height, this->pstn.width, 1, sim_rc.gt, sim_rc.projection, false);// 注意这里保留仿真结果 + { + sim_sar.setNoDataValue(-9999, 1); + //double PRF = this->pstn.PRF; + //double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(16000000 / sim_rc.width);// 基本大小 + line_invert = line_invert > 100 ? line_invert : 100; + int start_ids = 0; // 表示1 + int line_width = sim_rc.width; + Eigen::MatrixX sim_r(line_invert, line_width); + Eigen::MatrixXd sim_c(line_invert, line_width); + Eigen::MatrixXd sim_sum_h(line_invert, line_width); + Eigen::MatrixXd sim_rsc_orth(line_invert, line_width); + Eigen::MatrixXd sim_sum_sar(line_invert, line_width); + Eigen::MatrixXd sim_sum_count(line_invert, line_width); + Eigen::MatrixXd demdata(line_invert, line_width); + + // 初始化 + do { + sim_sum_sar = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 1).cast(); + sim_sum_sar = sim_sum_sar.array() * 0; + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 1); + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 2); + sim_sar.saveImage(sim_sum_sar, start_ids, 0, 3); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + { + // 累加计算模拟值 + int rowcount = 0, colcount = 0; + int row_min = 0, row_max = 0; + start_ids = 0; + std::cout << "time:\tsim_arr_row_min\tsim_arr_row_max\tsim_arr_all_lines\tsim_row_min\tsim_row_max\tsim_row_min0\tsim_row_max0" << std::endl;; + + + do { + std::cout << "\n" << getCurrentTimeString() << "\t" << start_ids << "\t" << start_ids + line_invert << "\t" << sim_rc.height << "\t"; + sim_r = sim_rc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 行 + sim_c = sim_rc.getData(start_ids, 0, line_invert, line_width, 2).cast(); // 列 + + sim_rsc_orth = sim_rsc.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + demdata = dem.getData(start_ids, 0, line_invert, line_width, 1).cast(); // 计算值 + // 范围 + row_min = (floor(sim_r.minCoeff())); + row_max = (ceil(sim_r.maxCoeff())); + std::cout << row_min << "\t" << row_max << "\t"; + + //std::cout << "line range:\t" << row_min << " - " << row_max << "\t computing.....\t" << getCurrentTimeString() << endl; + + if (row_max < 0 || row_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + row_min = row_min <= 0 ? 0 : row_min; + row_max = row_max >= this->pstn.height ? this->pstn.height : row_max; + std::cout << row_min << "\t" << row_max << std::endl; + //sim_sum_sar =sim_sar.getData(row_min, 0, row_max-row_min+1, this->pstn.width, 1).cast(); + //sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + if (row_min >= row_max) { + break; + } + sim_sum_sar = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 1).cast(); + sim_sum_count = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 2).cast(); + sim_sum_h = sim_sar.getData(row_min, 0, row_max - row_min + 1, this->pstn.width, 3).cast(); // 列 + rowcount = sim_r.rows(); + colcount = sim_r.cols(); + +#pragma omp parallel for num_threads(4) // NEW ADD + for (int i = 0; i < rowcount; i++) { + int row_ids = 0, col_ids = 0; + for (int j = 0; j < colcount; j++) { + row_ids = int(round(sim_r(i, j))); + col_ids = int(round(sim_c(i, j))); + if (row_ids >= 0 && row_ids < this->pstn.height && col_ids >= 0 && col_ids < this->pstn.width) { + sim_sum_sar(row_ids - row_min, col_ids) += sim_rsc_orth(i, j); + sim_sum_count(row_ids - row_min, col_ids) += 1; + sim_sum_h(row_ids - row_min, col_ids) += demdata(i, j); + } + } + } + sim_sar.saveImage(sim_sum_sar, row_min, 0, 1); + sim_sar.saveImage(sim_sum_count, row_min, 0, 2); + sim_sar.saveImage(sim_sum_h, row_min, 0, 3); + + start_ids = start_ids + line_invert; + } while (start_ids < sim_rc.height); + std::cout << "\ncomputer the simulation value of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + } + { + std::cout << "computer the height of sim_sar, begining :\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sim_sum_h(1, 1); + Eigen::MatrixXd sim_sum_count(1, 1); + + int start_ids = 0; + int line_invert = int(8000000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + sim_sum_count = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 2).cast(); // 行 + sim_sum_h = sim_sar.getData(start_ids, 0, line_invert, this->pstn.width, 3).cast(); // 列 + row_count = sim_sum_h.rows(); + col_count = sim_sum_h.cols(); + std::cout << "min~max:" << endl; + std::cout << sim_sum_count.minCoeff() << "\t" << sim_sum_count.maxCoeff() << endl; + std::cout << sim_sum_h.minCoeff() << "\t" << sim_sum_h.maxCoeff() << endl; + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + if (sim_sum_count(i, j) == 0) { + sim_sum_h(i, j) = 0; + } + else { + sim_sum_h(i, j) = sim_sum_h(i, j) / sim_sum_count(i, j); + } + } + } + sim_sar.saveImage(sim_sum_h, start_ids, 0, 3); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + + std::cout << "computer the height of sim_sar, overing :\t" << getCurrentTimeString() << endl; + } + + { + std::cout << "compute the average value of sim_sar, beiging:\t" << getCurrentTimeString() << endl; + + //ResampleGDALs(sim_sum_path.c_str(), 1, GRIORA_Bilinear); + //ResampleGDALs(sim_sum_path.c_str(), 3, GRIORA_Bilinear); + std::cout << "compute the average value of sim_sar, over :\t" << getCurrentTimeString() << endl; + } + { + std::cout << "=========================================\n"; + std::cout << "sim_sar_tif infomation :\n"; + std::cout << sim_sum_path << "\n"; + std::cout << "band 1 : simulation sar value \n"; + std::cout << "band 2 : the sum of the effective value from the dem \n"; + std::cout << "band 3 : the dem altitude of the effective value from the dem \n"; + std::cout << "=========================================\n"; + + } + return 0; +} + + +/// +/// 计算 +/// +/// +/// +/// +int simProcess::ori_sar_power(std::string ori_sar_path, std::string out_sar_power_path) +{ + std::cout << "compute the power value of ori sar, beiging:\t" << getCurrentTimeString() << endl; + gdalImage ori_sar(ori_sar_path); + gdalImage sim_power = CreategdalImage(out_sar_power_path, ori_sar.height, ori_sar.width, 1, ori_sar.gt, ori_sar.projection); + sim_power.setNoDataValue(-9999, 1); + { + Eigen::MatrixXd band1(1, 1); + Eigen::MatrixXd band2(1, 1); + Eigen::MatrixXd power_value(1, 1); + int start_ids = 0; + int line_invert = int(8000000 / ori_sar.width); + line_invert = line_invert > 10 ? line_invert : 10; + int row_count = 0, col_count = 0; + do { + std::cout << "rows:\t" << start_ids << "/" << ori_sar.height << "\t computing.....\t" << getCurrentTimeString() << endl; + band1 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 1).cast(); // a + band2 = ori_sar.getData(start_ids, 0, line_invert, ori_sar.width, 2).cast(); // b + //power_value = band2.array() * 0-9999; + power_value = (band1.array().pow(2) + band2.array().pow(2) + 1).log10() * 10;// 10 * Eigen::log10(Eigen::pow(0.5, Eigen::pow(2, band1.array()) + Eigen::pow(2, band2.array()))).array(); + //if () { + // + //}// power_value.isNaN()) + //std::cout << power_value.minCoeff() << "\t" << power_value.maxCoeff() << "\t" << endl; + //std::cout << "band 1\t" << band1.minCoeff() << "\t" << band1.maxCoeff() << "\t" << endl; + //std::cout << "band 2\t" << band2.minCoeff() << "\t" << band2.maxCoeff() << "\t" << endl; + sim_power.saveImage(power_value, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < ori_sar.height); + } + { + std::cout << "Resample the power value of ori sar :\t" << getCurrentTimeString() << endl; + ResampleGDALs(out_sar_power_path.c_str(), 1, GRIORA_Cubic); + } + std::cout << "compute the power value of ori sar, ending:\t" << getCurrentTimeString() << endl; + { + std::cout << "=========================================\n"; + std::cout << " the power image of sar :\n"; + std::cout << out_sar_power_path << "\n"; + std::cout << "band 1 : power value \t 10*log10(b1^2+b2^2) \n"; + std::cout << "=========================================\n"; + + } + return 0; +} + +int simProcess::createImageMatchModel(std::string ori_sar_rsc_path, std::string ori_sar_rsc_jpg_path, std::string sim_sar_path, std::string sim_sar_jpg_path, std::string matchmodel_path) +{ + // 转换影像 + { + std::cout << "compute the power value of sar, begining:\t" << getCurrentTimeString() << endl; + this->matchmodel.gdal2JPG(ori_sar_rsc_path, ori_sar_rsc_jpg_path, 1); + this->matchmodel.gdal2JPG(sim_sar_path, sim_sar_jpg_path, 1); + std::cout << "compute the power value of sar, ending:\t" << getCurrentTimeString() << endl; + } + // 构建匹配模型 + { + this->matchmodel.offsetXY_matrix = this->matchmodel.ImageMatch_ori_sim(ori_sar_rsc_jpg_path, sim_sar_jpg_path); + if (this->matchmodel.offsetXY_matrix.rows() < 7) { // 无法进行精校准 + this->isMatchModel = false; + } + else { + //this->matchmodel.match_model = this->matchmodel.CreateMatchModel(this->matchmodel.offsetXY_matrix); + //this->matchmodel.outMatchModel(matchmodel_path); + } + } + return 0; +} + + +/// +/// 根据精确匹配得到的纠正模型,纠正坐标偏移 +/// +/// +/// +/// +int simProcess::correctOrth_rc(std::string sim_rc_path, ImageMatch matchmodel) +{ + gdalImage sim_rc(sim_rc_path); + { + int lineVert = (1000000 / sim_rc.width); + int start_ids = 0; + do { + Eigen::MatrixXd sim_r = sim_rc.getData(start_ids, 0, lineVert, sim_rc.width, 1); + Eigen::MatrixXd sim_c = sim_rc.getData(start_ids, 0, lineVert, sim_rc.width, 2); + // 计算偏移结果 + int rowcount = sim_r.rows(); + int colcount = sim_r.cols(); + for (int i = 0; i < rowcount; i++) { + Eigen::MatrixXd temp = matchmodel.correctMatchModel(sim_r.row(i), sim_c.col(i)); + sim_r.row(i) = temp.row(0).array(); + sim_c.row(i) = temp.row(1).array(); + } + + // 写入影像 + sim_rc.saveImage(sim_r, start_ids, 0, 1); + sim_rc.saveImage(sim_c, start_ids, 0, 2); + start_ids = start_ids + lineVert; + } while (start_ids < sim_rc.height); + } + return 0; +} + +/// +/// +/// +/// +/// +/// 输出内入射角 +/// 输出dem +/// count的tif +/// +int simProcess::correct_ati(std::string orth_rc_path, std::string dem_path, std::string out_inclocal_path, std::string out_dem_path, std::string out_count_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer the simulation value of evering dem meta, begining:\t" << getCurrentTimeString() << endl; + gdalImage dem_img(dem_path); + gdalImage orth_rc(orth_rc_path); + + //gdalImage ori_inclocal = CreategdalImage(out_inclocal_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真结果 + gdalImage ori_dem = CreategdalImage(out_dem_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真结果 + gdalImage ori_count = CreategdalImage(out_count_path, this->pstn.height, this->pstn.width, 1, orth_rc.gt, orth_rc.projection, false);// 注意这里保留仿真 + + + // 初始化 + { + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_dem = ori_dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + //Eigen::MatrixXd sar_inclocal = ori_inclocal.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_count = ori_count.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_dem = sar_dem.array() * 0; + //sar_inclocal = sar_inclocal.array() * 0; + sar_count = sar_count.array() * 0; + + ori_dem.saveImage(sar_dem, start_ids, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, start_ids, 0, 1); + ori_count.saveImage(sar_count, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + { + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + int line_invert = int(50000000 / dem_img.width);// 基本大小 + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; // 表示1 + int line_width = dem_img.width; + Eigen::MatrixX sar_r(line_invert, line_width); + Eigen::MatrixXd sar_c(line_invert, line_width); + Eigen::MatrixXd dem(line_invert, line_width); + Eigen::MatrixXd sar_dem; + Eigen::MatrixXd sar_inclocal; + Eigen::MatrixXd sar_count; + + int rowcount = 0, colcount = 0; + int r_min, r_max, c_min, c_max; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + do { + std::cout << "rows:\t" << start_ids << "-" << start_ids + line_invert + 2 << "/" << dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + dem = dem_img.getData(start_ids, 0, line_invert + 2, line_width, 1); + sar_r = orth_rc.getData(start_ids, 0, line_invert + 2, line_width, 1).cast(); + sar_c = orth_rc.getData(start_ids, 0, line_invert + 2, line_width, 2).cast(); + + r_min = int(floor(sar_r.minCoeff())); + r_max = int(ceil(sar_r.maxCoeff())); + + c_min = int(floor(sar_c.minCoeff())); + c_max = int(ceil(sar_c.maxCoeff())); + + + // 计算数据结果 + rowcount = r_max - r_min + 1; + colcount = c_max - c_min + 1; + + if (r_max < 0 || r_min>this->pstn.height) { + start_ids = start_ids + line_invert; + continue; + } + r_min = r_min <= 0 ? 0 : r_min; + r_max = r_max >= this->pstn.height ? this->pstn.height : r_max; + + sar_dem = ori_dem.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); + sar_count = ori_count.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); + //sar_inclocal = ori_inclocal.getData(r_min, 0, r_max - r_min + 1, this->pstn.width, 1).cast(); // 列 + + rowcount = dem.rows(); + colcount = dem.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 1; i < rowcount - 1; i++) { + Eigen::MatrixX sataState = sar_r.row(i).reshaped(line_width, 1).array() * (1 / PRF) + imgstarttime; + sataState = this->pstn.orbit.SatelliteSpacePoint(sataState); + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle; + int r, c; + for (int j = 1; j < colcount - 1; j++) { + p0 = dem_img.getLandPoint(i + start_ids, j, dem(i, j)); // 中心 + p1 = dem_img.getLandPoint(i + start_ids - 1, j, dem(i - 1, j)); // 1 + p2 = dem_img.getLandPoint(i + start_ids, j + 1, dem(i, j + 1)); // 2 + p3 = dem_img.getLandPoint(i + start_ids + 1, j, dem(i + 1, j)); // 3 + p4 = dem_img.getLandPoint(i + start_ids, j - 1, dem(i, j - 1)); // 4 + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); + landpoint = LLA2XYZ(p0); + satepoint = Landpoint{ sataState(j,0),sataState(j,1) ,sataState(j,2) }; + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector); + + if (localincangle < 90) + { + r = sar_r(i, j); + c = sar_c(i, j); + if (r >= 0 && r < this->pstn.height && c >= 0 && c < this->pstn.width) { + //sar_inclocal(r - r_min, c) += localincangle; + sar_count(r - r_min, c) += 1; + sar_dem(r - r_min, c) += dem(i, j); + } + } + } + } + //std::cout << sim_rsc(1, 1961) << endl; + ori_dem.saveImage(sar_dem, r_min, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, r_min, 0, 1); + ori_count.saveImage(sar_count, r_min, 0, 1); + start_ids = start_ids + line_invert - 4; + } while (start_ids < dem_img.height); + omp_destroy_lock(&lock); //销毁互斥器 + } + + // 平均化 + { + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_dem = ori_dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + //Eigen::MatrixXd sar_inclocal = ori_inclocal.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_count = ori_count.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_dem = sar_dem.array() / sar_count.array(); + //sar_inclocal = sar_inclocal.array() / sar_count.array(); + + ori_dem.saveImage(sar_dem, start_ids, 0, 1); + //ori_inclocal.saveImage(sar_inclocal, start_ids, 0, 1); + + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + std::cout << "repair dem by resample, begining:\t" << getCurrentTimeString() << endl; + { + + + } + std::cout << "repair dem by resample, overing:\t" << getCurrentTimeString() << endl; + + std::cout << "correct the evering dem meta, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the dem of sar:\t" << out_dem_path << endl; + std::cout << "the local incident angle of sar:\t " << out_inclocal_path << endl; + std::cout << "==========================================================" << endl; + return 0; +} + +int simProcess::ASF(std::string in_dem_path, std::string out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN) +{ + std::cout << "computer ASF, begining:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "in parameters" << endl; + std::cout << "the dem of sar:\t" << in_dem_path << endl; + std::cout << "in sar rc path:\t" << in_dem_path << endl; + std::cout << "out parameters" << endl; + std::cout << "out latlon of sar:\t" << out_latlon_path << endl; + std::cout << "==========================================================" << endl; + + + gdalImage dem(in_dem_path); + gdalImage latlon = CreategdalImage(out_latlon_path, this->pstn.height, this->pstn.width, 2, dem.gt, dem.projection, false); + //gdalImage sar_rc(in_sar_rc_path); + // 初始化坐标 + double aveageAti = 0; + { + int line_invert = int(500000 / dem.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + int count = 0; + do { + Eigen::MatrixXd sar_dem = dem.getData(start_ids, 0, line_invert, dem.width, 1); + int row_count = sar_dem.rows(); + int col_count = sar_dem.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + if (!isnan(sar_dem(i, j)) && !isinf(sar_dem(i, j))) { + aveageAti += sar_dem(i, j); + count = count + 1; + } + } + } + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + aveageAti = aveageAti / count; + } + cout << "the aveage ati of dem:\t" << aveageAti << endl; + // 初始化坐标 + Landpoint initp = dem.getLandPoint(int(dem.height / 2), int(dem.width / 2), aveageAti); + + cout << "initlandpoint lon lat ati\t" << initp.lon << "\t" << initp.lat << "\t" << initp.ati << "\t" << endl; + initp = LLA2XYZ(initp); + cout << "initlandpoint lon lat ati\t" << initp.lon << "\t" << initp.lat << "\t" << initp.ati << "\t" << endl; + + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + double alpha0 = 0; + // 迭代计算 + { + int line_invert = int(1000000 / dem.width) > 10 ? int(1000000 / dem.width) : 10; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(8) // NEW ADD + for (int start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) + { + Eigen::MatrixXd sar_dem = dem.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_lon = latlon.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_lat = latlon.getData(start_ids, 0, line_invert, this->pstn.width, 2); + Eigen::Vector3d initTagetPoint(initp.lon, initp.lat, initp.ati); + int row_min = start_ids; + int row_max = sar_lon.rows() + row_min; + std::cout << "rows:\t" << row_min << "-" << row_max << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + + for (int i = row_min; i < row_max; i++) { + long double satetime = i * (1 / PRF) + imgstarttime; + Eigen::MatrixXd sataspace = this->pstn.orbit.SatelliteSpacePoint(satetime); // 空间坐标 + Eigen::Vector3d SatellitePosition(sataspace(0, 0), sataspace(0, 1), sataspace(0, 2)); + Eigen::Vector3d SatelliteVelocity(sataspace(0, 3), sataspace(0, 4), sataspace(0, 5)); + Landpoint sata{ sataspace(0,0), sataspace(0, 1), sataspace(0, 2) }; + + double beta0 = 50 * d2r;// (180-getAngle(sata, sata-initp))* d2r; + + for (int j = 0; j < this->pstn.width; j++) { + double R = getRangebyColumn(j, this->pstn.R0, this->pstn.fs, this->pstn.lamda); + double ati_H = sar_dem(i - row_min, j); + if (!isnan(ati_H) && !isinf(ati_H)) { + ati_H = aveageAti; + } + Eigen::Vector3d landp = asfclass.ASF(R, SatellitePosition, SatelliteVelocity, initTagetPoint, PSTN, this->pstn.R0, ati_H, alpha0, beta0); + Landpoint landpoint{ landp(0),landp(1) ,landp(2) }; + landpoint = XYZ2LLA(landpoint); + sar_lon(i - row_min, j) = landpoint.lon; + sar_lat(i - row_min, j) = landpoint.lat; + } + } + omp_set_lock(&lock); + latlon.saveImage(sar_lon, row_min, 0, 1); + latlon.saveImage(sar_lat, row_min, 0, 2); + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); //销毁互斥器 + } + std::cout << "out lon and lat of sar, over:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "the lon lat of sar:\t" << out_latlon_path << endl; + std::cout << "band 1: lon" << endl; + std::cout << "band 2: lat " << endl; + std::cout << "==========================================================" << endl; + + return 0; +} +/// +/// 计算入射角和具体入射角 +/// +/// +/// +/// +/// +/// +void simProcess::calcalIncident_localIncident_angle(std::string in_dem_path, std::string in_rc_wgs84_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN) +{ + this->calGEC_Incident_localIncident_angle(in_dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, PSTN); +} + +/// +/// 获取GEC坐标系下的入射角与距地入射角 +/// +/// +/// +/// +/// +/// +void simProcess::calGEC_Incident_localIncident_angle(std::string in_dem_path, std::string in_gec_lon_lat_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN) +{ + std::cout << "computer Incident_localIncident_angle in sar, begining:\t" << getCurrentTimeString() << endl; + std::cout << "==========================================================" << endl; + std::cout << "in parameters" << endl; + std::cout << "the dem in wgs84 of sar:\t" << in_dem_path << endl; + std::cout << "in gec lon lat path:\t" << in_gec_lon_lat_path << endl; + std::cout << "out parameters" << endl; + std::cout << "out incident_angle of sar:\t" << out_incident_angle_path << endl; + std::cout << "out local incident_angle of sar:\t" << out_local_incident_angle_path << endl; + std::cout << "==========================================================" << endl; + + gdalImage dem_img(in_dem_path); + gdalImage lonlat(in_gec_lon_lat_path); + gdalImage incident_angle = CreategdalImage(out_incident_angle_path, this->pstn.height, this->pstn.width, 1, dem_img.gt, dem_img.projection, false); + gdalImage local_incident_angle = CreategdalImage(out_local_incident_angle_path, this->pstn.height, this->pstn.width, 1, dem_img.gt, dem_img.projection, false); + // 初始化 + { + dem_img.InitInv_gt(); + int line_invert = int(500000 / this->pstn.width); + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + Eigen::MatrixXd sar_inc = incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_local_incident = local_incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + + sar_inc = sar_inc.array() * 0; + sar_local_incident = sar_local_incident.array() * 0; + + incident_angle.saveImage(sar_inc, start_ids, 0, 1); + local_incident_angle.saveImage(sar_local_incident, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < this->pstn.height); + } + + { + double PRF = this->pstn.PRF; + double imgstarttime = this->pstn.imgStartTime; + + int line_invert = 500; + int start_ids = 0; + int line_cound_sum = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 + + for (start_ids = 0; start_ids < this->pstn.height; start_ids = start_ids + line_invert) { + Eigen::MatrixXd lon = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd lat = lonlat.getData(start_ids, 0, line_invert, this->pstn.width, 2); + Eigen::MatrixXd dem_col = dem_img.inv_gt(0, 0) + dem_img.inv_gt(0, 1) * lon.array() + dem_img.inv_gt(0, 2) * lat.array(); + Eigen::MatrixXd dem_row = dem_img.inv_gt(1, 0) + dem_img.inv_gt(1, 1) * lon.array() + dem_img.inv_gt(1, 2) * lat.array(); + //lon = Eigen::MatrixXd::Ones(1,1); + //lat= Eigen::MatrixXd::Ones(1,1); + int min_row = floor(dem_row.array().minCoeff()); + int max_row = ceil(dem_row.array().maxCoeff()); + min_row = min_row - 1 >= 0 ? min_row - 1 : 0; + max_row = max_row + 1 < dem_img.height ? max_row + 1 : dem_img.height; + int row_len = max_row - min_row + 1; + Eigen::MatrixXd dem = dem_img.getData(min_row, 0, row_len, dem_img.width, 1); + + Eigen::MatrixXd sar_inc = incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + Eigen::MatrixXd sar_local_incident = local_incident_angle.getData(start_ids, 0, line_invert, this->pstn.width, 1); + int min_col = 0; + int lon_row_count = dem_col.rows(); + int lon_col_count = dem_col.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < lon_row_count; i++) + { + Landpoint p0, p1, p2, p3, p4, slopeVector, landpoint, satepoint; + double localincangle, inc_angle; + // 同一行,卫星坐标一致 + long double satatime = (i + start_ids) * (1 / PRF) + imgstarttime; + Eigen::MatrixXd sataState = this->pstn.orbit.SatelliteSpacePoint(satatime); + satepoint = Landpoint{ sataState(0,0),sataState(0,1) ,sataState(0,2) }; + double dem_r, dem_c; + int r0, r1; + int c0, c1; + for (int j = 0; j < lon_col_count; j++) { + // 计算行列号 + dem_r = dem_row(i, j); //y + dem_c = dem_col(i, j); // x + r0 = floor(dem_r); + r1 = ceil(dem_r); + c0 = floor(dem_c); + c1 = ceil(dem_c); + + p0 = Landpoint{ dem_c - c0,dem_r - r0,0 }; + p1 = Landpoint{ 0,0,dem(r0 - min_row, c0 - min_col) }; // p11(0,0) + p2 = Landpoint{ 0,1,dem(r0 - min_row + 1, c0 - min_col) }; // p21(0,1) + p3 = Landpoint{ 1,0,dem(r0 - min_row , c0 + 1 - min_col) }; // p12(1,0) + p4 = Landpoint{ 1,1,dem(r0 - min_row + 1, c0 + 1 - min_col) }; // p22(1,1) + p0.ati = Bilinear_interpolation(p0, p1, p2, p3, p4); + + p0 = dem_img.getLandPoint(dem_r, dem_c, p0.ati); // 中心 + p1 = dem_img.getLandPoint(r0, c0, dem(r0 - min_row, c0 - min_col)); // p11(0,0) + p2 = dem_img.getLandPoint(r1, c0, dem(r1 - min_row, c0 - min_col)); // p21(0,1) + p3 = dem_img.getLandPoint(r0, c1, dem(r0 - min_row, c1 - min_col)); // p12(1,0) + p4 = dem_img.getLandPoint(r1, c1, dem(r1 - min_row, c1 - min_col)); // p22(1,1) + + slopeVector = getSlopeVector(p0, p1, p2, p3, p4); // 地面坡向矢量 + landpoint = LLA2XYZ(p0); + localincangle = getlocalIncAngle(satepoint, landpoint, slopeVector);// 局地入射角 + inc_angle = getIncAngle(satepoint, landpoint); // 侧视角 + + // 记录值 + sar_local_incident(i, j) = localincangle; + sar_inc(i, j) = inc_angle; + } + } + omp_set_lock(&lock); + incident_angle.saveImage(sar_inc, start_ids, 0, 1); + local_incident_angle.saveImage(sar_local_incident, start_ids, 0, 1); + line_cound_sum = line_cound_sum + line_invert; + std::cout << "rows:\t" << start_ids << "\t" << line_cound_sum << "/" << this->pstn.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); + } + omp_destroy_lock(&lock); //销毁互斥器 + } + + + std::cout << "computer Incident_localIncident_angle in sar, overing:\t" << getCurrentTimeString() << endl; +} + +/// +/// 插值GTC的影像值 +/// +/// +/// +/// +/// +void simProcess::interpolation_GTC_sar(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + + + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 2, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0 - 9999; + sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 500; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX> ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + ori(i, j) = complex{ ori_a(i, j), ori_b(i, j) }; + } + } + ori_a = Eigen::MatrixXd(1, 1); + ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows(); + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 - 1; r2 = r1 + 1; r3 = r1 + 2; // 获取行 + c1 = floor(c); + c0 = c1 - 1; c2 = c1 + 1; c3 = c1 + 2; // 获取列 + // 考虑边界情况 + if (r0<-1 || c0<-1 || c3>this->pstn.width || r3>this->pstn.height) { + continue; + } + // 边界插值计算,插值模块权重 + Eigen::MatrixX> img_block(4, 4); + if (r0 == -1 || c0 == -1) { + if (r0 == -1) { + if (c0 == -1) { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c1) *complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c2) + ori(r3 - min_r, c3); // k,-1 + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3); // k,-1 + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3); // k,-1 + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = img_block(1, 0) * complex{3, 0} - complex{3, 0} *img_block(2, 0) + img_block(3, 0);// -1,-1 + } + else if (c3 == this->pstn.width) { + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(2, 3) + img_block(3, 3);//-1,M+1 + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1,k + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1 + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1 + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1 + } + + } + + else if (c0 == -1)//r0 != -1 + { + if (r3 == this->pstn.height) { + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + else { // + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 3) = ori(r3 - min_r, c3); + } + } + + } + else if (r3 == this->pstn.height || c3 == this->pstn.width) { + if (r3 == this->pstn.height) { + if (c3 == this->pstn.width) { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);;//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);;//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);;//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(1, 3) + img_block(0, 3);//N+1,M+1 + + } + else { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3);//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3);//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3);//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + } + else if (c3 == this->pstn.width) { // r3 != this->pstn.height + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);//0,M+1 + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r0 - min_r, c3); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + + complex interpolation_value = Cubic_Convolution_interpolation(r - r1, c - c1, img_block); + // + sar_a(i, j) = interpolation_value.real(); + sar_b(i, j) = interpolation_value.imag(); + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + sar_img.saveImage(sar_b, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + } + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, over:\t" << getCurrentTimeString() << std::endl; +} + + +/// +/// 插值GTC的影像值 +/// +/// +/// +/// +/// +void simProcess::interpolation_GTC_sar_sigma(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 1, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0; + //sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + //sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 600; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + //Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX> ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + ori(i, j) = complex{ ori_a(i, j), 0 }; + } + } + ori_a = Eigen::MatrixXd(1, 1); + //ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows()-100; + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 - 1; r2 = r1 + 1; r3 = r1 + 2; // 获取行 + c1 = floor(c); + c0 = c1 - 1; c2 = c1 + 1; c3 = c1 + 2; // 获取列 + // 考虑边界情况 + if (r0<-1 || c0<-1 || c3>this->pstn.width || r3>this->pstn.height) { + continue; + } + // 边界插值计算,插值模块权重 + Eigen::MatrixX> img_block(4, 4); + if (r0 == -1 || c0 == -1) { + if (r0 == -1) { + if (c0 == -1) { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c1) * complex{3, 0} - complex{3,0} *ori(r3 - min_r, c2) + ori(r3 - min_r, c3); // k,-1 + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3); // k,-1 + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3); // k,-1 + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = img_block(1, 0) * complex{3, 0} - complex{3, 0} *img_block(2, 0) + img_block(3, 0);// -1,-1 + } + else if (c3 == this->pstn.width) { + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(2, 3) + img_block(3, 3);//-1,M+1 + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1, + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1, + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1,k + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r1 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c3) + ori(r3 - min_r, c3);//-1,k + img_block(0, 2) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r3 - min_r, c2);//-1 + img_block(0, 1) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r3 - min_r, c1);//-1 + img_block(0, 0) = ori(r1 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c0) + ori(r3 - min_r, c0);//-1 + } + + } + + else if (c0 == -1)//r0 != -1 + { + if (r3 == this->pstn.height) { + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + else { // + img_block(0, 0) = ori(r0 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c2) + ori(r0 - min_r, c3);//j,-1 + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3); + + img_block(1, 0) = ori(r1 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r1 - min_r, c3);//j,-1 + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3); + + img_block(2, 0) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c2) + ori(r2 - min_r, c3);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3); + + img_block(3, 0) = img_block(2, 0) * complex{3, 0} - complex{3, 0} *img_block(1, 0) + img_block(0, 0);//N+1,-1 + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 3) = ori(r3 - min_r, c3); + } + } + + } + else if (r3 == this->pstn.height || c3 == this->pstn.width) { + if (r3 == this->pstn.height) { + if (c3 == this->pstn.width) { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);;//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);;//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);;//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = img_block(2, 3) * complex{3, 0} - complex{3, 0} *img_block(1, 3) + img_block(0, 3);//N+1,M+1 + + } + else { + img_block(0, 0) = ori(r0 - min_r, c0); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 3) = ori(r0 - min_r, c3);//j,M+1 + + img_block(1, 0) = ori(r1 - min_r, c0); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 3) = ori(r1 - min_r, c3);//j,M+1 + + img_block(2, 0) = ori(r2 - min_r, c0);//j,-1 + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 3) = ori(r2 - min_r, c3);//j,M+1 + + img_block(3, 0) = ori(r2 - min_r, c0) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c0) + ori(r0 - min_r, c0);//N+1,-1 + img_block(3, 1) = ori(r2 - min_r, c1) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r0 - min_r, c1);//N+1,j + img_block(3, 2) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c2) + ori(r0 - min_r, c2);//N+1,j + img_block(3, 3) = ori(r2 - min_r, c3) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c3) + ori(r0 - min_r, c3);//N+1,j + } + } + else if (c3 == this->pstn.width) { // r3 != this->pstn.height + img_block(3, 3) = ori(r3 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r3 - min_r, c1) + ori(r3 - min_r, c0);//2,M+1 + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0);//j,M-2 + + img_block(2, 3) = ori(r2 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r2 - min_r, c1) + ori(r2 - min_r, c0);//1,M+1 + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0);//j,M-2 + + img_block(1, 3) = ori(r1 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r1 - min_r, c1) + ori(r1 - min_r, c0);//0,M+1 + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0);//j,M-2 + + img_block(0, 3) = ori(r0 - min_r, c2) * complex{3, 0} - complex{3, 0} *ori(r0 - min_r, c1) + ori(r0 - min_r, c0);//0,M+1 + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + } + else { + img_block(3, 3) = ori(r3 - min_r, c3); + img_block(3, 2) = ori(r3 - min_r, c2); + img_block(3, 1) = ori(r3 - min_r, c1); + img_block(3, 0) = ori(r3 - min_r, c0); + + img_block(2, 3) = ori(r2 - min_r, c3); + img_block(2, 2) = ori(r2 - min_r, c2); + img_block(2, 1) = ori(r2 - min_r, c1); + img_block(2, 0) = ori(r2 - min_r, c0); + + img_block(1, 3) = ori(r1 - min_r, c3); + img_block(1, 2) = ori(r1 - min_r, c2); + img_block(1, 1) = ori(r1 - min_r, c1); + img_block(1, 0) = ori(r1 - min_r, c0); + + img_block(0, 3) = ori(r0 - min_r, c3); + img_block(0, 2) = ori(r0 - min_r, c2); + img_block(0, 1) = ori(r0 - min_r, c1); + img_block(0, 0) = ori(r0 - min_r, c0); + } + + complex interpolation_value = Cubic_Convolution_interpolation(r - r1, c - c1, img_block); + // + //if (interpolation_value.real() < 0) { + // int a = 1; + //} + sar_a(i, j) = interpolation_value.real(); + //sar_b(i, j) = interpolation_value.imag(); + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_b, start_ids, 0, 2); + start_ids = start_ids + line_invert-100; + } while (start_ids < sar_rc.height); + } + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, over:\t" << getCurrentTimeString() << std::endl; +} + +void simProcess::interpolation_bil(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn) +{ + std::cout << "interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model, begin time:" << getCurrentTimeString() << std::endl; + + gdalImage sar_rc(in_rc_wgs84_path); + gdalImage ori_sar(in_ori_sar_path); + + this->pstn.width = ori_sar.width; + this->pstn.height = ori_sar.height; + gdalImage sar_img = CreategdalImage(out_orth_sar_path, sar_rc.height, sar_rc.width, 1, sar_rc.gt, sar_rc.projection); + + // 初始化 + { + sar_rc.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + sar_a = sar_a.array() * 0 - 9999; + //sar_b = sar_b.array() * 0 - 9999; + + sar_img.saveImage(sar_a, start_ids, 0, 1); + //sar_img.saveImage(sar_a, start_ids, 0, 2); + start_ids = start_ids + line_invert; + } while (start_ids < sar_rc.height); + sar_img.setNoDataValue(-9999, 1); + //sar_img.setNoDataValue(-9999, 2); + } + + // 正式计算插值 + { + int line_invert = 500; + line_invert = line_invert > 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + + // 处理行列号获取范围 + int min_r = floor(sar_r.array().minCoeff()); + int max_r = ceil(sar_r.array().maxCoeff()); + int min_c = floor(sar_c.array().minCoeff()); + int max_c = ceil(sar_c.array().maxCoeff()); + + if (max_r < 0 || max_c < 0 || min_r >= this->pstn.height || min_c >= this->pstn.width) { + start_ids = start_ids + line_invert; + if (start_ids < sar_rc.height) { + continue; + } + else { + break; + } + } + + if (start_ids == 13500) { + int sdaf = 1; + } + + min_r = min_r >= 0 ? min_r : 0; + max_r = max_r < this->pstn.height ? max_r : this->pstn.height; + min_c = min_c >= 0 ? min_c : 0; + max_c = max_c < this->pstn.width ? max_c : this->pstn.width; + + // 获取影像 + int len_row = max_r - min_r + 4; + Eigen::MatrixXd ori_a = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 1); + //Eigen::MatrixXd ori_b = ori_sar.getData(min_r, 0, len_row, this->pstn.width, 2); + int row_count = ori_a.rows(); + int col_count = ori_a.cols(); + + Eigen::MatrixX ori(ori_a.rows(), ori_a.cols()); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + //ori(i, j) = complex{ ori_a(i, j), ori_b(i, j) }; + ori(i, j) = double{ ori_a(i, j)}; + } + } + ori_a = Eigen::MatrixXd(1, 1); + //ori_b = Eigen::MatrixXd(1, 1); // 释放内存 + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + //Eigen::MatrixXd sar_b = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 2); + sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + sar_c = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 2); + row_count = sar_r.rows(); + col_count = sar_r.cols(); +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, c0, c1; + double r, c; + for (int j = 0; j < col_count; j++) { + r = sar_r(i, j); + c = sar_c(i, j); + if (r < 0 || c < 0 || r >= this->pstn.height || c >= this->pstn.width) { + continue; + } + else { + int kkkkk = 0; + + } + r1 = floor(r); + r0 = r1 + 1; // 获取行 + c1 = floor(c); + c0 = c1 + 1; // 获取列 + // 考虑边界情况 + if (r1<=0 || c1<=0 || c0>= this->pstn.width || r0>=this->pstn.height) { + continue; + } + /* if (c1 <= 0 || c0 >= this->pstn.width || (r1 - min_r) <= 0 || (r0 - min_r) <= 0 || (r1 - min_r) >= ori_a.rows() || (r0 - min_r) >= ori_a.cols()) { + continue; + }*/ + /* if ((r1 - min_r) <= 0 || (r0 - min_r) <= 0 || (r1 - min_r) >= ori_a.rows() || (r0 - min_r) >= ori_a.cols() || c1 >= ori_a.cols() || c0 >= ori_a.cols()) { + continue; + }*/ + Landpoint p0, p1, p2, p3, p4; + //std::cout << "r= " << r << " r1= " << r1 << " c= " << c << " c1= " << c1 << " min_r = " << min_r << std::endl; + p0 = Landpoint{ r - r1,c - c1,0 }; + //std::cout << "row= " << r1 - min_r << "col= " < 10 ? line_invert : 10; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << sar_rc.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd sar_r = sar_rc.getData(start_ids, 0, line_invert, sar_rc.width, 1); + Eigen::MatrixXd sar_a = sar_img.getData(start_ids, 0, line_invert, sar_rc.width, 1); + int row_count = sar_r.rows() - 100; + int col_count = sar_r.cols(); + int win_s = floor(w_size / 2); + int count = w_size * w_size; +#pragma omp parallel for num_threads(8) // NEW ADD + for (int i = 0; i < row_count; i++) { + int r0, r1, r2, r3, c0, c1, c2, c3; + double r, c, snr; + for (int j = 0; j < col_count; j++) { + double sum = 0; + double ave = 0; + double sumSquared = 0; + double variance = 0; + //((i - win_s) < 0 || (j - win_s) < 0 || (i + win_s) > sar_rc.height || (j + win_s) > sar_rc.width) + if (i == 0 || j == 0 || i == sar_rc.height || j == sar_rc.width || (i - win_s) <= 0 || (j - win_s) <= 0 || (i + win_s) >= sar_rc.height || (j + win_s) >= sar_rc.width) + { + sar_a(i, j) = sar_r(i, j); + } + else + { + r0 = i - win_s; + r1 = i + win_s; + c0 = j - win_s; + c1 = j + win_s; + // 计算窗口均值与方差 + for (int n = r0; n <= r1; n++) + { + for (int m = c0; m <= c1; m++) + { + sum += sar_r(n, m); + sumSquared += sar_r(n, m) * sar_r(n, m); + } + } + //均值 + ave = sum / count; + //方差 + variance = sumSquared / count - ave * ave; + if (variance == 0) { + sar_a(i, j) = sar_r(i, j); + } + else { + sar_a(i, j) = sar_r(i, j) + noise_var * (ave - sar_r(i, j)); + + } + } + + } + } + sar_img.saveImage(sar_a, start_ids, 0, 1); + start_ids = start_ids + line_invert - 100; + } while (start_ids < sar_rc.height); + + } + +} + + + +/// +/// 根据RPC的行列号,生成RPC对应的DEM文件 +/// +/// +/// +/// +void simProcess::CreateRPC_DEM(std::string in_rpc_rc_path, std::string in_dem_path, std::string out_rpc_dem_path) +{ + gdalImage rpc_rc(in_rpc_rc_path); + gdalImage dem_img(in_dem_path); + gdalImage rpc_dem_img = CreategdalImage(out_rpc_dem_path, rpc_rc.height, rpc_rc.width, 1, rpc_rc.gt, rpc_rc.projection); + + // 初始化 + { + dem_img.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + Eigen::MatrixXd rpc_dem = rpc_dem_img.getData(start_ids, 0, line_invert, rpc_dem_img.width, 1); + rpc_dem = rpc_dem.array() * 0 - 9999; + rpc_dem_img.saveImage(rpc_dem, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < rpc_dem_img.height); + rpc_dem_img.setNoDataValue(-9999, 1); + } + + // 插值计算结果 + { + dem_img.InitInv_gt(); + int line_invert = 100; + int start_ids = 0; + do { + + std::cout << "rows:\t" << start_ids << "/" << rpc_dem_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + Eigen::MatrixXd rpc_dem = rpc_dem_img.getData(start_ids, 0, line_invert, rpc_dem_img.width, 1); + Eigen::MatrixXd rpc_row = rpc_dem.array() * 0 - 1; + Eigen::MatrixXd rpc_col = rpc_dem.array() * 0 - 1; + int row_count = rpc_dem.rows(); + int col_count = rpc_dem.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + Landpoint landpoint = rpc_dem_img.getLandPoint(i + start_ids, j, 0); + Landpoint land_row_col = dem_img.getRow_Col(landpoint.lon, landpoint.lat); // x,y,z + rpc_row(i, j) = land_row_col.lat; // row + rpc_col(i, j) = land_row_col.lon; // col + } + } + + double min_r = floor(rpc_row.minCoeff()) - 1; + double max_r = ceil(rpc_row.maxCoeff()) + 1; + min_r = min_r >= 0 ? min_r : 0; + int len_r = max_r - min_r; + Eigen::MatrixXd dem = dem_img.getData(min_r, 0, len_r + 2, dem_img.width, 1); + + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + Landpoint p0 = Landpoint{ rpc_row(i,j),rpc_col(i,j),0 }; + Landpoint p1 = Landpoint{ floor(p0.lon),floor(p0.lat),0 }; p1.ati = dem(int(p1.lon - min_r), int(p1.lat)); p1 = Landpoint{ 0,0,p1.ati }; + Landpoint p2 = Landpoint{ floor(p0.lon),ceil(p0.lat),0 }; p2.ati = dem(int(p2.lon - min_r), int(p2.lat)); p2 = Landpoint{ 0,1,p2.ati }; + Landpoint p3 = Landpoint{ ceil(p0.lon),floor(p0.lat),0 }; p3.ati = dem(int(p3.lon - min_r), int(p3.lat)); p3 = Landpoint{ 1,0,p3.ati }; + Landpoint p4 = Landpoint{ ceil(p0.lon),ceil(p0.lat),0 }; p4.ati = dem(int(p4.lon - min_r), int(p4.lat)); p4 = Landpoint{ 1,1,p4.ati }; + p0 = Landpoint{ p0.lon - floor(p0.lon), p0.lat - floor(p0.lat), 0 }; + p0.ati = Bilinear_interpolation(p0, p1, p2, p3, p4); + rpc_dem(i, j) = p0.ati; + } + } + rpc_dem_img.saveImage(rpc_dem, start_ids, 0, 1); + start_ids = start_ids + line_invert; + } while (start_ids < rpc_dem_img.height); + } + + +} + +void simProcess::CreateRPC_refrenceTable(string in_rpc_tiff_path,string in_merge_dem,string out_rpc_lon_lat_tiff_path) +{ + CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); + CPLSetConfigOption("GDAL_DATA", "./data"); + GDALAllRegister();//注册驱动 + + const char* pszTif = in_rpc_tiff_path.c_str(); + + gdalImage rpc_img(in_rpc_tiff_path); + + GDALRPCInfo oInfo = rpc_img.getRPC(); + + //设置RPC模型中所需的DEM路径 + char** papszTransOption = NULL; + //papszTransOption = CSLSetNameValue(papszTransOption, "RPC_DEM", "E:\\DEM.img"); //设置DEM + + //使用RPC信息,DEM等构造RPC转换参数 + void* pRPCTransform = GDALCreateRPCTransformer(&oInfo, FALSE, 0, papszTransOption); + + + // 创建影像 + + gdalImage lon_lat_img = CreategdalImage(out_rpc_lon_lat_tiff_path, rpc_img.height, rpc_img.width, 2, rpc_img.gt, rpc_img.projection, false); + // 计算角点 + string temp_dem_path = in_merge_dem + ".bak"; + double merge_gt[6] = { + rpc_img.gt(0,0), rpc_img.gt(0,1), rpc_img.gt(0,2), + rpc_img.gt(0,3), rpc_img.gt(0,4), rpc_img.gt(0,5) + } ; + ResampleGDAL(in_merge_dem.c_str(), temp_dem_path.c_str(), merge_gt, rpc_img.width, rpc_img.height, GRA_Bilinear); + + gdalImage merger_dem_tiff(temp_dem_path); + double X[4] = { 0,0,rpc_img.width - 1,rpc_img.width - 1 }; + double Y[4] = { 0,rpc_img.height - 1,rpc_img.height - 1,0 }; + double Z[4] = { 0,0,0,0 }; + int sucess_num[4] = { false,false,false,false }; + GDALRPCTransform(pRPCTransform, FALSE, 4, X, Y, Z, sucess_num); + for (int i = 0; i < 4; i++) { + std::cout << X[i] << "\t" << Y[i] << "\t" << Z[i] << "\t" << sucess_num[i] << std::endl; + } + int line_invert = int(1500000 / rpc_img.width); + line_invert = line_invert > 10 ? line_invert : 10; + int count_lines = 0; + omp_lock_t lock; + omp_init_lock(&lock); // 初始化互斥锁 +#pragma omp parallel for num_threads(6) // NEW ADD + for (int max_rows_ids = 0; max_rows_ids < lon_lat_img.height; max_rows_ids = max_rows_ids + line_invert) { + //line_invert = dem_clip.height - max_rows_ids > line_invert ? line_invert : dem_clip.height - max_rows_ids; + + Eigen::MatrixXd lon = lon_lat_img.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 1); + Eigen::MatrixXd lat = lon_lat_img.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 2); + Eigen::MatrixXd dem = merger_dem_tiff.getData(max_rows_ids, 0, line_invert, lon_lat_img.width, 2); + int row_count = lon.rows(); + int col_count = lon.cols(); + for (int i = 0; i < row_count; i++) { + for (int j = 0; j < col_count; j++) { + //定义图像的四个角点行列号坐标 + double dY[1] = { i + max_rows_ids }; + double dX[1] = { j }; + double dZ[1] = { dem(i,j)}; + int nSuccess[1] = { FALSE }; + GDALRPCTransform(pRPCTransform, FALSE, 1, dX, dY, dZ, nSuccess); + lon(i, j) = dX[0]; + lat(i, j) = dY[0]; + } + } + + //std::cout << "for time " << getCurrentTimeString() << std::endl; + // 写入到文件中 + omp_set_lock(&lock); //获得互斥器 + std::cout << lon.array().minCoeff() << endl; + lon_lat_img.saveImage(lon, max_rows_ids, 0, 1); + lon_lat_img.saveImage(lat, max_rows_ids, 0, 2); + count_lines = count_lines + line_invert; + std::cout << "rows:\t" << max_rows_ids << "\t-\t" << max_rows_ids + line_invert << "\t" << count_lines << "/" << lon_lat_img.height << "\t computing.....\t" << getCurrentTimeString() << endl; + omp_unset_lock(&lock); //释放互斥器 + } + omp_destroy_lock(&lock); //销毁互斥器 + //释放资源 + GDALDestroyRPCTransformer(pRPCTransform); + CSLDestroy(papszTransOption); +} + +/// +/// 映射表插值计算 +/// +/// 映射表 +/// 输入数据 +/// 输出数据 +void simProcess::CorrectionFromSLC2Geo(string in_lon_lat_path, string in_radar_path, string out_radar_path,int in_band_ids) +{ + gdalImage in_lon_lat(in_lon_lat_path); + gdalImage in_image(in_radar_path); + gdalImage out_radar(out_radar_path); + + cv::Mat in_mat; + cv::Mat out_mat; + + cv::eigen2cv(in_image.getData(0, 0, in_lon_lat.height, in_lon_lat.width, in_band_ids),in_mat); + + // 定义映射关系 + cv::Mat in_x,in_y; + cv::eigen2cv(in_lon_lat.getData(0, 0, in_lon_lat.height, in_lon_lat.width, 1), in_x); + cv::eigen2cv(in_lon_lat.getData(0, 0, in_lon_lat.height, in_lon_lat.width, 1), in_y); + + // 重新进行插值计算 + +} +/// +/// 根据DEM创建SAR_rc +/// +/// +/// +/// +/// + + +double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda) +{ + return (double)(2 * (R - NearRange) / LIGHTSPEED * Fs); // 计算采样率; +} + +Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda) +{ + return ((R.array() - NearRange).array() / lamda * Fs).array().cast(); +} + +double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda) +{ + return (j * lamda / 2) / Fs + NearRange; + +} + +Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda) +{ + return ((j.array() * lamda / 2) / Fs + NearRange).array().cast(); +} + +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector) { + Landpoint Rsc = satepoint - landpoint; // AB=B-A + //double R = getlength(Rsc); + //std::cout << R << endl; + double angle = getAngle(Rsc, slopeVector); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + +double getIncAngle(Landpoint& satepoint, Landpoint& landpoint) { + + Landpoint Rsc = satepoint - landpoint; // AB=B-A + Landpoint Rs = landpoint;// landpoint; + double angle = getAngle(Rsc, Rs); + if (angle >= 180) { + return 360 - angle; + } + else { + return angle; + } +} + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////// ASF 计算 /////////////////////////////////////////////////// +////// 《星载合成孔径雷达影像正射校正方法研究》 陈尔学 ///////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////// + +/// +/// 计算 变换矩阵 卫星坐标系-> ECR +/// +/// [x,y,z,vx,vy,vz] nx6 +/// +Eigen::MatrixXd ASFOrthClass::Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc) +{ + + Eigen::Vector3d x, y, z; + + Eigen::MatrixXd M(3, 3); + + z = Rsc / Rsc.norm(); + y = Rsc.cross(Vsc) / (Rsc.norm() * Vsc.norm()); + x = y.cross(z); + + M.col(0) = x; + M.col(1) = y; + M.col(2) = z; + return M; +} +/// +/// 获取从卫星指向地面目标的单位矢量 +/// +/// 弧度值 +/// 弧度值 +/// 变换矩阵 +/// +Eigen::Vector3d ASFOrthClass::UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M) +{ + // 目标T的单位向量 ST = R * M * P + Eigen::Vector3d P(sin(alpha), -1.0 * cos(alpha) * sin(beta), -1.0 * cos(alpha) * cos(beta)); + return M * P; +} + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H) +{ + /** + 根据R和alpha 计算出beta来。 + 根据参考论文,式3 - 13,完成此方法。(注意这是近似法 + args : + R:斜距 + alpha : 雷达侧视角 + beta0 : beta初始值 + SatellitePosition : 3x1 卫星空间位置 + TargetPosition:3x1 目标对象 + */ + Eigen::MatrixXd M = this->Satellite2ECR(SatellitePosition, SatelliteVelocity); + // 地球半径 + double Rp = earth_Rp + H; + double Rs_norm = SatellitePosition.norm(); + // 初始化beta + if (beta == 0) { + double beta_cos = (Rs_norm * Rs_norm + R * R - Rp * Rp) / (2 * Rs_norm * R); + beta = acos(beta_cos); + } + + double delta_R, sin_eta, delta_beta, tan_eta; + // 迭代 + int i = 0; + do { + // 计算斜率的增加 + delta_R = R - this->FR(alpha, beta, SatellitePosition, M, R_threshold, H); + // 计算入射角 + sin_eta = Rs_norm * sin(beta) / Rp; + tan_eta = sin_eta / sqrt(1 - sin_eta * sin_eta); + // 计算增量 + delta_beta = delta_R / (R * tan_eta); + // 更新 + beta = beta + delta_beta; + // 判断循环终止条件 + i = i + 1; + if (i >= 10000) // 达到终止条件 + { + return -9999; + } + } while (abs(delta_R) > 0.01); + return beta; +} + +/// +/// 从beta,alpha获取获取目标的空间位置 +/// +/// +/// +/// +/// +/// +/// +Eigen::Vector3d ASFOrthClass::GetXYZByBetaAlpha(double alpha, double beta, Eigen::Vector3d SatellitePosition, double R, Eigen::MatrixXd M) +{ + return SatellitePosition + R * this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); +} + +/// +/// FD +/// +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity, double R, double lamda, Eigen::MatrixXd M) +{ + /** + 根据beta, alpha, 卫星空间位置, 斜距,转换矩阵 + */ + Eigen::Vector3d UnitVector = this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); + Eigen::Vector3d Rst = -1 * R * UnitVector; + double Rst_Vst = Rst.dot(SatelliteVelocity - TargetVelocity); + return -2 / (R * lamda) * Rst_Vst; +} + + +/// +/// FR +/// +/// +/// +/// +/// +/// +/// +/// +double ASFOrthClass::FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H) +{ + /* + 根据 雷达侧视角,雷达视角,卫星位置,坐标系变换矩阵,大地高等参数,根据参考论文中公式3 - 1 == 》3 - 10的计算过程,设计此方程 + args : + alpha:雷达侧视角 卫星与地物间速度运动差导致的(即多普勒频移的结果) + beta : 雷达视角 + Satellite_position : 卫星空间位置 + M:坐标系转换矩阵 + H:大地高 + return : + R:斜距 + */ + //std::cout << beta << endl; + Eigen::Vector3d UnitVector = R_threshold * this->UnitVectorOfSatelliteAndTarget(alpha, beta, M); + // 解方程 3 - 10 纠正错误,A公式有问题 + double a = (earth_Re + H) * (earth_Re + H); + double b = earth_Rp * earth_Rp; + long double Xs = SatellitePosition(0); + long double Ys = SatellitePosition(1); + long double Zs = SatellitePosition(2); + long double Xp = UnitVector(0); + long double Yp = UnitVector(1); + long double Zp = UnitVector(2); + //std::cout << Xp<<"\t"<< Yp<<"\t"<< Zp << endl; + long double A = (Xp * Xp + Yp * Yp) / a + (Zp * Zp) / b; + long double B = 2 * (Xs * Xp + Ys * Yp) / a + 2 * Zs * Zp / b; + long double C = (Xs * Xs + Ys * Ys) / a + Zs * Zs / b - 1; + //std::cout << A << "\t" << B << "\t" << C << endl; + C = B * B - 4 * A * C; + //std::cout << A << "\t" << B << "\t" << C << endl; + double R1 = (-B - sqrt(C)) / (2 * A); + //double R2 = (-B + sqrt(C)) / (2 * A); + //std::cout << R1 << "\t" << R2 << endl; + if (R1 > 1) { + return R1 * R_threshold; + } + else { + return -9999; + //return (-B + math.sqrt(t)) / (2 * A) # 这里通过几何分析排除这个解 + } + +} + +/// +/// ASF方法 +/// +/// +/// 卫星高度 +/// 卫星速度 +/// 初始化地面坐标 +/// +/// +/// 初始高程 +/// +/// +/// +Eigen::Vector3d ASFOrthClass::ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H, double alpha0, double beta0) +{ + // 部分参数初始化 + double alpha = alpha0; + double beta = beta0; + double delta_alpha = 0; + // 这个公式是根据《中国海洋合成孔径雷达卫星工程、产品与处理》 + // P164 5.8.4 多普勒参数计算 + double fd = PSTN.calNumericalDopplerValue(R); + Eigen::MatrixXd M = this->Satellite2ECR(SatellitePosition, SatelliteVelocity); + double FD_, delta_fd; + Eigen::Vector3d XYZ; + int i = 0;// 统计迭代次数 + while (true) { + Eigen::Vector3d TargetVelocity = Eigen::Vector3d(-1 * earth_We * TargetPosition(1), earth_We * TargetPosition(0), 0);// 计算地面速度, 粗糙计算时,默认为0 + beta = this->GetLookFromRangeYaw(R, alpha, beta, SatellitePosition, SatelliteVelocity, R_threshold, H); + FD_ = this->FD(alpha, beta, SatelliteVelocity, TargetVelocity, R, PSTN.lamda, M); + delta_fd = FD_ - fd; + delta_alpha = -1 * delta_fd * PSTN.lamda / (2 * (SatelliteVelocity - TargetVelocity).norm()); + TargetPosition = this->GetXYZByBetaAlpha(alpha, beta, SatellitePosition, R, M); + //cout << i << "\t" << delta_alpha * R << "\t" << delta_alpha<<"\t"<< (abs(delta_alpha * R) < 0.1)<<"\t"<< (abs(delta_alpha) < 0.001) << endl; + if (abs(delta_alpha * R) < 0.1 || abs(delta_alpha) < 0.0003) + { + break; + } + alpha = alpha + delta_alpha; + i = i + 1; + if (i > 10000) { + throw new exception("ASF 失败"); + } + + } + return TargetPosition; +} + diff --git a/simorthoprogram-orth_s_sar-strip/simptsn.h b/simorthoprogram-orth_s_sar-strip/simptsn.h new file mode 100644 index 0000000..24e3f8d --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/simptsn.h @@ -0,0 +1,241 @@ +#pragma once +/// +/// 仿真成像算法 +/// +//#define EIGEN_USE_MKL_ALL +//#define EIGEN_VECTORIZE_SSE4_2 +//#include +// 本地方法 +#include "baseTool.h" +#include +#include +#include +#include +//#include +#include +#include "SateOrbit.h" +#include "ImageMatch.h" +using namespace std; +using namespace Eigen; + +////////////// 常用函数 //////////////////////// + +double getRangeColumn(long double R, long double NearRange, long double Fs, long double lamda); +Eigen::MatrixXd getRangeColumn(Eigen::MatrixXd R, long double NearRange, long double Fs, long double lamda); + +double getRangebyColumn(double j, long double NearRange, long double Fs, long double lamda); +Eigen::MatrixXd getRangebyColumn(Eigen::MatrixXd j, long double NearRange, long double Fs, long double lamda); +///////////// ptsn 算法 ///////////////////// + +class PSTNAlgorithm { +public: + // 初始化与析构函数 + PSTNAlgorithm(); + PSTNAlgorithm(string parameterPath); + ~PSTNAlgorithm(); + + int dem2lat_lon(std::string dem_path, std::string lon_path, std::string lat_path); + int dem2SAR_RC(std::string dem_path, std::string sim_rc_path); + + // 模拟算法函数 + Eigen::MatrixX calNumericalDopplerValue(Eigen::MatrixX R);// 数值模拟法计算多普勒频移值 + double calNumericalDopplerValue(double R);// 数值模拟法计算多普勒频移值 + Eigen::MatrixX calTheoryDopplerValue(Eigen::MatrixX R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1);//根据理论模型计算多普勒频移值 + double calTheoryDopplerValue(double R, Eigen::MatrixX R_s1, Eigen::MatrixX V_s1); + Eigen::MatrixX PSTN(Eigen::MatrixX TargetPostion, double ave_dem, double dt, bool isCol ); // 输入DEM + //Eigen::MatrixXd WGS842J2000(Eigen::MatrixXd blh); + //Landpoint WGS842J2000(Landpoint p); +public: // WGS84 到 J2000 之间的变换参数 + Eigen::MatrixXd UTC; + double Xp = 0.204071; + double Yp = 0.318663; + double Dut1 = 0.0366742; + double Dat = 37; +public: + int height; // 影像的高 + int width; + + // 入射角 + double near_in_angle;// 近入射角 + double far_in_angle;// 远入射角 + + // SAR的成像参数 + double fs;// 距离向采样率 + double R0;//近斜距 + double LightSpeed; // 光速 + double lamda;// 波长 + double refrange;// 参考斜距 + double doppler_reference_time; //多普勒参考时间 + + double imgStartTime;// 成像起始时间 + double PRF;// 脉冲重复率 + + int doppler_paramenter_number;//多普勒系数个数 + MatrixX doppler_paras;// 多普勒系数 + + OrbitPoly orbit; // 轨道模型 + +}; + + +/// +/// 获取局地入射角,角度值 +/// +/// +/// +/// +/// +double getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector); + + +/// +/// 侧视入射角,角度值 +/// +/// +/// +/// +double getIncAngle(Landpoint& satepoint, Landpoint& landpoint); + + +/// +/// ASF计算方法 +/// +class ASFOrthClass { + +public: + Eigen::MatrixXd Satellite2ECR(Eigen::Vector3d Rsc, Eigen::Vector3d Vsc); // 根据卫星坐标计算变换矩阵 M + Eigen::Vector3d UnitVectorOfSatelliteAndTarget(double alpha, double beta, Eigen::MatrixXd M); + double GetLookFromRangeYaw(double R, double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, double R_threshold, double H = 0); + + Eigen::Vector3d GetXYZByBetaAlpha(double alpha,double beta, Eigen::Vector3d SatellitePosition,double R, Eigen::MatrixXd M); + + double FD(double alpha, double beta, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetVelocity,double R,double lamda, Eigen::MatrixXd M); + double FR(double alpha, double beta, Eigen::Vector3d SatellitePosition, Eigen::MatrixXd M, double R_threshold, double H = 0); + + Eigen::Vector3d ASF(double R, Eigen::Vector3d SatellitePosition, Eigen::Vector3d SatelliteVelocity, Eigen::Vector3d TargetPosition, PSTNAlgorithm PSTN, double R_threshold, double H = 0, double alpha0 = 0, double beta0 = 0); + +}; + +/// +/// 仿真处理流程 +/// +class simProcess { +public: + simProcess(); + ~simProcess(); + + int parameters(int argc, char* argv[]); + + int InitSimulationSAR(std::string paras_path,std::string workspace_path,std::string out_dir_path,std::string in_dem_path,std::string in_sar_path); // 间接定位法 + + int CreateSARDEM(); + int dem2SAR(); // 切换行号 + int SARIncidentAngle(); + int SARSimulationWGS(); + int SARSimulation(); + int in_sar_power(); + int ReflectTable_WGS2Range(); + + int InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path,std::string in_rpc_lon_lat_path,std::string out_inc_angle_path, std::string out_local_inc_angle_path, std::string out_inc_angle_geo_path, std::string out_local_inc_angle_geo_path); + int dem2SAR_row(); // 切换行号 + int SARIncidentAngle_RPC(); + int createRPCDEM(); + + // 格网离散插值 + int Scatter2Grid(std::string lon_lat_path, std::string data_tiff, std::string grid_path, double space); + + // ASF 模块计算 + int InitASFSAR(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path); + + int ASF(std::string in_dem_path, std::string out_latlon_path, ASFOrthClass asfclass, PSTNAlgorithm PSTN); + + //int dem2simSAR(std::string dem_path, std::string out_sim_path, PSTNAlgorithm PSTN); // 根据DEM生成输出仿真图像 + int sim_SAR(std::string dem_path, std::string sim_rc_path, std::string sim_sar_path, PSTNAlgorithm PSTN); + int dem2aspect_slope(std::string dem_path, std::string aspect_path, std::string slope_path); + int sim_sum_SAR(std::string sim_dem_path,std::string sim_rc_path, std::string sim_orth_path, std::string sim_sum_path,PSTNAlgorithm pstn); + void interpolation_GTC_sar_sigma(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + + //双线性插值 + void interpolation_bil(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + //lee滤波 + void lee_process(std::string in_ori_sar_path, std::string out_orth_sar_path, int w_size, double noise_var); + // 原始影像强度图 + int ori_sar_power(std::string ori_sar_path, std::string out_sar_power_path); + + // 匹配偏移模型构建 + int createImageMatchModel(std::string ori_sar_rsc_path, std::string ori_sar_rsc_jpg_path, std::string sim_sar_path, std::string sim_sar_jpg_path, std::string matchmodel_path); + + // 纠正影像 + int correctOrth_rc(std::string sim_rc_path,ImageMatch matchmodel); + + int correct_ati(std::string orth_rc_path, std::string dem_path, std::string out_inclocal_path, std::string out_dem_path, std::string out_count_path, PSTNAlgorithm PSTN); + + void calcalIncident_localIncident_angle(std::string in_dem_path, std::string in_rc_wgs84_path, std::string out_incident_angle_path, std::string out_local_incident_angle_path, PSTNAlgorithm PSTN); + + void calGEC_Incident_localIncident_angle(std::string in_dem_path, std::string in_gec_lon_lat_path,std::string out_incident_angle_path, std::string out_local_incident_angle_path,PSTNAlgorithm PSTN); + + void interpolation_GTC_sar(std::string in_rc_wgs84_path, std::string in_ori_sar_path, std::string out_orth_sar_path, PSTNAlgorithm pstn); + // RPC + void CreateRPC_DEM(std::string in_rpc_rc_path, std::string in_dem_path, std::string out_rpc_dem_path); + + void CreateRPC_refrenceTable(string in_rpc_tiff_path, string in_merge_dem, string out_rpc_lon_lat_tiff_path); + + void CorrectionFromSLC2Geo(string in_lon_lat_path, string in_radar_path, string out_radar_path, int in_band_ids); + + +// 内部参数 +public: + ImageMatch matchmodel; + bool isMatchModel; + + std::string workSpace_path;// 工作空间路径 + std::string outSpace_path;// 输出工作空间路径 + PSTNAlgorithm pstn; // 参数组件 + ///// RPC 局地入射角 /////////////////////////////////// + std::string in_rpc_lon_lat_path; + std::string out_dir_path; + std::string workspace_path; + // 临时文件 + std::string rpc_wgs_path; + std::string ori_sim_count_tiff;// 映射角文件 + // 输出文件 + std::string out_inc_angle_rpc_path; + std::string out_local_inc_angle_rpc_path; + + // 输出文件 + std::string out_inc_angle_geo_path; + std::string out_local_inc_angle_geo_path; + + ///// 正向仿真方法 ///////// + + + + // 临时产品文件 + std::string in_dem_path; // 输入DEM + std::string dem_path; // 重采样之后DEM + std::string dem_r_path;// 行号影像 + std::string dem_rc_path; // 行列号 + std::string sar_sim_wgs_path; + std::string sar_sim_path; + std::string in_sar_path; + std::string sar_jpg_path; + std::string sar_power_path; + // 最终产品 + std::string out_dem_rc_path; // 经纬度与行列号变换文件 + + std::string out_dem_slantRange_path; // 斜距文件 + std::string out_plant_slantRange_path;// 平面斜距文件 + + //// ASF 方法 ///////////// + std::string out_lon_path;// 经度 + std::string out_lat_path;// 纬度 + std::string out_slantRange_path;// 斜距文件 + + /// 共同文件 /// + std::string out_localIncidenct_path;// 计算局地入射角 + std::string out_incidence_path; // 入射角文件 + std::string out_ori_sim_tiff;// 映射角文件' + std::string out_sim_ori_tiff; +}; + +bool PtInRect(Point_3d pCur, Point_3d pLeftTop, Point_3d pRightTop, Point_3d pRightBelow, Point_3d pLeftBelow); \ No newline at end of file diff --git a/simorthoprogram-orth_s_sar-strip/test_moudel.cpp b/simorthoprogram-orth_s_sar-strip/test_moudel.cpp new file mode 100644 index 0000000..30cfe4d --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/test_moudel.cpp @@ -0,0 +1,282 @@ +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +using namespace std; +using namespace Eigen; + +#include "test_moudel.h" + + +int test_main(int mode, string rootpath) +{ + switch (mode) + { + case 0: + { + test_mode_0(); + break; + }; + case 1: + { + test_mode_1(rootpath); + break; + } + case 7: { + test_mode_7(); + break; + } + case 8: { + std::string in_rpc_tiff = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\GF3_MYN_QPSI_011437_E99.2_N28.6_20181012_L1B_HH_L10003514912_db.tif"; + std::string out_lon_lat_path = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\RPC_ori_sim.tif"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.CreateRPC_refrenceTable(in_rpc_tiff, dem_path,out_lon_lat_path); + std::cout << "==========================================================================" << endl; + break; + } + default: + test_ASF(rootpath); + break; + } + return 0; +} + + +int test_mode_7() { + // + std::cout << "mode 7: get rpc incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 7 in_parameter_path in_dem_path in_gec_lon_lat_path work_path taget_path out_incident_angle_path out_local_incident_angle_path"; + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\orth_para.txt"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\TestDEM\\mergedDEM.tif"; + std::string in_gec_lon_lat_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\RPC_ori_sim.tif"; + std::string work_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary"; + std::string taget_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\inc_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\local_inc_angle.tiff"; + std::string out_incident_angle_geo_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\inc_angle_geo.tiff"; + std::string out_local_incident_angle_geo_path = "D:\\MicroSAR\\C-SAR\\Ortho\\Temporary\\package\\local_inc_angle_geo.tiff"; + simProcess process; + //InitRPCIncAngle(std::string paras_path, std::string workspace_path, std::string out_dir_path, std::string in_dem_path, std::string in_rpc_lon_lat_path) + std::cout << "==========================================================================" << endl; + process.InitRPCIncAngle(parameter_path, work_path, taget_path, dem_path, in_gec_lon_lat_path, out_incident_angle_path, out_local_incident_angle_path, out_incident_angle_geo_path, out_local_incident_angle_geo_path); + std::cout << "==========================================================================" << endl; + return 0; +} + + +int test_mode_0() +{ + std::cout << "State:\tTEST MODE" << endl; + test_LLA2XYZ_XYZ2LLA(); + return 0; +} + +int test_mode_1(string rootpath) +{ + // .\baseTool\x64\Release\SIMOrthoProgram.exe 1 D:\MicroWorkspace\C-SAR\Ortho\Temporary\unpack\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff +//??????? + + std::string root_path = rootpath;// "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary2"; + std::string workspace = "D:\\MicroSAR\\C-SAR\\MicroWorkspace\\Ortho\\Temporary"; + std::string parameter_path =workspace+ "\\package\\orth_para.txt"; // + std::string dem_path = workspace + "\\TestDEM\\pindem.tif"; // + std::string in_sar_path = workspace + "\\unpack\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HHHV_L10004871459\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HH_L10004871459.tiff"; // + std::string work_path = workspace ; // + std::string taget_path = workspace + "\\package"; // + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the sar image:\n" << in_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + std::cout << "==========================================================================" << endl; + process.InitSimulationSAR(parameter_path, work_path, taget_path, dem_path, in_sar_path); + std::cout << "==========================================================================" << endl; + return 0; +} + + +int test_ASF(string rootpath) { + std::string root_path = rootpath;// "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary2"; + std::string parameter_path = root_path + "\\package\\orth_para.txt"; + std::string dem_path = root_path + "\\TestDEM\\mergedDEM.tif"; + std::string ori_sar_path = root_path + "\\unpack\\" + "GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HHHV_L10004871459\\GF3_KAS_FSI_020253_E110.8_N25.5_20200614_L1A_HH_L10003923848.tiff"; + std::string work_path = root_path + "\\TestSim"; + std::string taget_path = root_path + "\\output"; + std::string out_GEC_dem_path = root_path + "\\output\\GEC_dem.tif"; + std::string out_GTC_rc_path = root_path + "\\output\\GTC_rc_wgs84.tif"; + std::string out_GEC_lon_lat_path = root_path + "\\output\\GEC_lon_lat.tif"; + std::string out_clip_DEM_path = root_path + "\\output\\Orth_dem.tif"; + std::cout << "==========================================================================" << endl; + std::cout << "????????????????????DEM ??Χ" << endl; + std::cout << "SIMOrthoProgram.exe 1 in_parameter_path in_dem_path in_ori_sar_path in_work_path in_taget_path "; + std::cout << "out_GEC_dem_path out_GTC_rc_path out_GEC_lon_lat_path out_clip_dem_path" << endl; + std::cout << "==========================================================================" << endl; + std::cout << "in parameters:========================================================" << endl; + std::cout << "parameters file path:\t" << parameter_path << endl; + std::cout << "input dem image(WGS84)" << dem_path << endl; + std::cout << "the reference sar image for match simulation sar image:\n" << ori_sar_path << endl; + std::cout << "the work path for outputing temp file :\t" << work_path << endl; + std::cout << "the out file for finnal file:\t" << taget_path << endl; + simProcess process; + ASFOrthClass ASFClass; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + // + dem_path = out_clip_DEM_path;// JoinPath(work_path, "clipDEM.tif"); + std::string out_simrc_path = JoinPath(work_path, "dem_sar_rc.tif"); //r,c + std::string sim_sar_orth_path = JoinPath(work_path, "sim_sar_orth.tif"); // orth_sim,orth_inclocal + + std::string dem_slope_path = JoinPath(work_path, "dem_slope.tif"); + std::string dem_aspect_path = JoinPath(work_path, "dem_aspect.tif"); + + std::string sim_sar_path = JoinPath(work_path, "sim_sar_sum.tif"); // sim count dem + std::string ori_sar_rsc_path = JoinPath(work_path, "ori_sar_power.tif"); // ori_power + std::string ori_sar_rsc_jpg_path = JoinPath(work_path, "ori_sar_power.jpg"); + std::string sim_sar_jpg_path = JoinPath(work_path, "sim_sar_sum.jpg"); + std::string matchmodel_path = JoinPath(work_path, "matchmodel.txt"); // matchmodel + + std::string out_dem_count_path = JoinPath(work_path, "dem_count.tif"); + + std::string out_dem_path = out_GEC_dem_path; + std::string out_inclocal_path = JoinPath(taget_path, "inclocal.tif"); + std::string out_sar_rc_path = out_GTC_rc_path; + std::string out_lon_lat_path = out_GEC_lon_lat_path; + + if (process.isMatchModel) { + process.correctOrth_rc(out_simrc_path, process.matchmodel); + } + if (boost::filesystem::exists(boost::filesystem::path(out_sar_rc_path))) { + boost::filesystem::remove(boost::filesystem::path(out_sar_rc_path)); + } + boost::filesystem::copy_file(boost::filesystem::path(out_simrc_path), boost::filesystem::path(out_sar_rc_path)); + + process.correct_ati(out_sar_rc_path, dem_path, out_inclocal_path, out_dem_path, out_dem_count_path, pstn); + // ASF + + process.ASF(out_dem_path, out_lon_lat_path, ASFClass, pstn); + + return 0; +} + + +int test_mode_2() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_DEM.tiff"; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_sar_rc.tiff"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_incident_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\RPC_Ortho\\RPC_local_incident_angle.tiff"; + + std::cout << "mode 2: get incident angle and local incident angle by rc_wgs84 and dem and statellite model:\n"; + std::cout << "SIMOrthoProgram.exe 2 in_parameter_path in_dem_path in_rc_wgs84_path out_incident_angle_path out_local_incident_angle_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + + process.calcalIncident_localIncident_angle(dem_path, in_rc_wgs84_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + + return 0; +} + +int test_mode_3() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string in_rc_wgs84_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GTC_rc_wgs84.tiff"; + std::string in_ori_sar_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\unpack\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_AHV_L10003923848\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff"; + std::string out_orth_sar_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GTC\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848.tiff"; + + std::cout << "mode 3: interpolation(cubic convolution) orth sar value by rc_wgs84 and ori_sar image and model:\n "; + std::cout << "SIMOrthoProgram.exe 3 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.interpolation_GTC_sar(in_rc_wgs84_path, in_ori_sar_path, out_orth_sar_path, pstn); + + return 0; +} + +int test_mode_4() +{ + std::string parameter_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\orth_para.txt"; + std::string in_dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\Orth_dem.tiff"; + std::string in_rpc_rc_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\\RPC_Ortho\\RPC_sar_rc.tiff"; + std::string out_rpc_dem_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_DEM.tiff"; + std::string out_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_incident_angle.tiff"; + std::string out_local_incident_angle_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\RPC_Ortho\\RPC_local_incident_angle.tiff"; + + std::cout << "mode 4: get RPC incident and local incident angle sar model:"; + std::cout << "SIMOrthoProgram.exe 4 in_parameter_path in_dem_path in_rpc_rc_path out_rpc_dem_path out_incident_angle_path out_local_incident_angle_path"; + + simProcess process; + std::cout << "==========================================================================" << endl; + PSTNAlgorithm pstn(parameter_path); + std::cout << "==========================================================================" << endl; + process.CreateRPC_DEM(in_rpc_rc_path, in_dem_path, out_rpc_dem_path); + process.calcalIncident_localIncident_angle(out_rpc_dem_path, in_rpc_rc_path, out_incident_angle_path, out_local_incident_angle_path, pstn); + return 0; +} + +int test_mode_5() +{ + std::string in_ori_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\output\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848_GTC_geo_wp.tif"; + std::string out_power_path = "D:\\MicroSAR\\C-SAR\\SIMOrthoProgram\\Temporary\\package\\GF3_SAY_QPSI_013952_E118.9_N31.5_20190404_L1A_HH_L10003923848_GTC_geo_OrthoResult.tif"; + std::cout << "mode 5: convert ori tiff to power tiff:"; + std::cout << "SIMOrthoProgram.exe 5 in_ori_path out_power_path"; + simProcess process; + process.ori_sar_power(in_ori_path, out_power_path); + return 0; +} + +int test_mode_6() +{ + + return 0; +} + +int test_LLA2XYZ_XYZ2LLA() +{ + std::cout << "===========================================" << endl; + std::cout << "TEST LLA2XYZ and XYZ2LLA " << endl; + bool pass = false; + + Landpoint lla_p{ 30,40,500 }; + Landpoint xyz_p = LLA2XYZ(lla_p); + Landpoint lla_p2 = XYZ2LLA(xyz_p); + + std::cout << "LLA:\t" << lla_p.lon << "," << lla_p.lat << "," << lla_p.ati << endl; + std::cout << "XYZ:\t" << xyz_p.lon << "," << xyz_p.lat << "," << xyz_p.ati << endl; + std::cout<<"LLA2:\t"<< lla_p2.lon << "," << lla_p2.lat << "," << lla_p2.ati << endl; + + pass = (lla_p2.lon-lla_p.lon==0) && (lla_p2.lat- lla_p.lat==0) && (lla_p2.ati-lla_p.ati==0); + std::cout << "TEST LLA2XYZ and XYZ2LLA passed:" << pass << endl; + std::cout << "===========================================" << endl; + return pass?1:0; +} + +int test_vector_operator() +{ + // ???? + return 0; +} diff --git a/simorthoprogram-orth_s_sar-strip/test_moudel.h b/simorthoprogram-orth_s_sar-strip/test_moudel.h new file mode 100644 index 0000000..3e8638a --- /dev/null +++ b/simorthoprogram-orth_s_sar-strip/test_moudel.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +//#include +#include +#include +// gdal +#include +#include +#include "gdal_priv.h" +#include "ogr_geometry.h" +#include "gdalwarper.h" +#include "baseTool.h" +#include "simptsn.h" +using namespace std; +using namespace Eigen; + +class test_moudel +{ + + + +}; + +int test_main(int mode, string rootpath); +int test_mode_0(); +int test_mode_1(string rootpath); +int test_ASF(string rootpath); +int test_mode_2(); +int test_mode_3(); +int test_mode_4(); +int test_mode_5(); +int test_mode_6(); +int test_mode_7(); +int test_LLA2XYZ_XYZ2LLA(); + +int test_vector_operator(); +