initial upload

This commit is contained in:
2024-09-10 20:25:18 +08:00
parent b8de03ee4f
commit f1cc876972
377 changed files with 2721267 additions and 34 deletions

33
archive/sph2random/.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
# 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
*.ex

View File

@@ -0,0 +1,91 @@
#include "sph2random.h"
void disp_help()
{
cout << "sph2random - v0.1 data interpolation under the spherical coordinates" << endl
<< "Author: zhangyi.cugwuhan@gmail.com" << endl << endl
<< "usage: sph2random -t<grid-table>[+d<x-col>,<y-col>,<val-col>] -l<random-loc>[+d<x-col>,<y-col>[,<z-col>]] -i<dlon>/<dlat> -c<start-corner> [-s] [-h] > output-file" << endl
<< "-t\tinput grid table. a +d option could be attached to the filename to select data columns of the input data, the default is 0,1,2. Note that any line starts with '#' will be skipped" << endl
<< "-l\tinput spherical locations, a +d option could be attached to the filename to select data columns of the input data, the default is 0,1. Note that any line starts with '#' will be skipped" << endl
<< "-i\tdata intervals" << endl
<< "-c\tstart corner of the grid data, 'leftTopo' (default) or 'leftDown'" << endl
<< "-s\tconvert input coordinates to spherical coordinates" << endl
<< "-h\tshow this info" << endl;
}
int main(int argc, char** argv)
{
char infilename[1024] = "NULL";
char infileloc[1024] = "NULL";
char interval[1024] = "NULL";
char startPoint[1024] = "leftTopo";
char use_sc[1024] = "no";
opterr = 0; //内置参数 若不为0则会在发生遭遇错误时输出一条信息到屏幕
int curr;
/*循环拾取参数 最后一个参数为-1 需要变量的参数后跟一个冒号 可有可无参数跟两个冒号*/
while((curr = getopt(argc,argv,"hst:l:i:c:")) != -1)
{
/*匹配命令*/
switch (curr)
{
case 'h': //显示帮助信息
disp_help();
break;
case 's':
strcpy(use_sc,"yes");
break;
case 't':
if (1!=sscanf(optarg,"%[^\0]",infilename))
{
cout << "error ==> wrong format of " << optarg << endl;
}
break;
case 'l':
if (1!=sscanf(optarg,"%[^\0]",infileloc))
{
cout << "error ==> wrong format of " << optarg << endl;
}
break;
case 'i':
if (1!=sscanf(optarg,"%[^\0]",interval))
{
cout << "error ==> wrong format of " << optarg << endl;
}
break;
case 'c':
if (1!=sscanf(optarg,"%[^\0]",startPoint))
{
cout << "error ==> wrong format of " << optarg << endl;
}
break;
case '?': //处理未定义或错误参数
if (optopt == 'i' || optopt == 'l')
{
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
return -1;
}
else if (isprint(optopt))
{
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
return -1;
}
else
{
fprintf (stderr,"Unknown option character `\\x%x'.\n",optopt);
return -1;
}
break;
default:
abort();
}
}
sphInterpolate si;
if (si.readGrid(infilename,interval,use_sc)) return -1;
if (si.readRandom(infileloc,use_sc)) return -1;
si.interpolate(startPoint);
si.outRes();
return 0;
}

View File

@@ -0,0 +1,15 @@
CC = g++-8
PROM = /usr/local/sbin/sph2random
CFLAGS = -I.
DEPS = $(shell find . -name "*.h")
SRC = $(shell find . -name "*.cpp")
OBJ = $(SRC:%.cpp=%.o)
$(PROM): $(OBJ)
$(CC) -o $(PROM) $(OBJ) $(CFLAGS) -O2
%.o:%.cpp $(DEPS)
$(CC) -c $< -o $@ $(CFLAGS) -O2
clean:
rm -rf $(OBJ)

View File

@@ -0,0 +1,210 @@
#ifndef _SPHINTERPOLATE_H
#define _SPHINTERPOLATE_H
#include "sysDefine.h"
class sphInterpolate
{
public:
sphInterpolate(){}
~sphInterpolate(){}
int readGrid(char*,char*,char*);
int readRandom(char*,char*);
int outRes();
void interpolate(char*);
private:
spointArray gridData;
spointArray randomData;
double lonmin,lonmax,latmin,latmax;
double dlon,dlat;
int lonNum,latNum;
};
int sphInterpolate::readGrid(char* filepara,char* intervals,char* use_spherical_coor)
{
char filename[1024];
int orders[3] = {0,1,2}; //默认的读入的数据列为前三列
//解析文件名中是否含有+d标示 如果有则将+d以前解释为filename 之后为需要读入的数据列 默认为逗号分隔
//否则将filepara赋值为filename
if (4 != sscanf(filepara,"%[^\+]+d%d,%d,%d",filename,&orders[0],&orders[1],&orders[2]))
strcpy(filename,filepara);
ifstream infile;
if (open_infile(infile,filename)) return -1;
//解析网格数据间隔
if (2!=sscanf(intervals,"%lf/%lf",&dlon,&dlat))
{
cerr << BOLDRED << "error ==> " << RESET << "wrong grid data spacing: " << intervals << endl;
return -1;
}
lonmin = latmin = MAX_DBL;
lonmax = latmax = MIN_BDL;
string temp_str;
stringstream temp_ss;
double temp_d;
_1dArray temp_row;
spoint temp_vert;
while(getline(infile,temp_str))
{
if (*(temp_str.begin()) == '#') continue;
temp_ss.str(""); temp_ss.clear(); temp_ss << temp_str;
if(!temp_row.empty()) temp_row.clear();
while(temp_ss >> temp_d)
temp_row.push_back(temp_d);
temp_vert.lon = temp_row[orders[0]];
if (!strcmp(use_spherical_coor,"yes")){
if (temp_vert.lon < 0){
temp_vert.lon += 360.0;
}
}
temp_vert.lat = temp_row[orders[1]];
temp_vert.rad = defaultR;
temp_vert.val = temp_row[orders[2]];
gridData.push_back(temp_vert);
if (temp_vert.lon < lonmin) lonmin = temp_vert.lon;
if (temp_vert.lon > lonmax) lonmax = temp_vert.lon;
if (temp_vert.lat < latmin) latmin = temp_vert.lat;
if (temp_vert.lat > latmax) latmax = temp_vert.lat;
}
infile.close();
lonNum = round((lonmax-lonmin)/dlon+1);
latNum = round((latmax-latmin)/dlat+1);
return 0;
}
int sphInterpolate::readRandom(char* filepara,char* use_spherical_coor)
{
char filename[1024];
int orders[3] = {0,1,-1}; //默认的读入的数据列为前三列
//解析文件名中是否含有+d标示 如果有则将+d以前解释为filename 之后为需要读入的数据列 默认为逗号分隔
//否则将filepara赋值为filename
if (4 != sscanf(filepara,"%[^\+]+d%d,%d,%d",filename,&orders[0],&orders[1],&orders[2]))
{
if (3 != sscanf(filepara,"%[^\+]+d%d,%d",filename,&orders[0],&orders[1]))
strcpy(filename,filepara);
}
ifstream infile;
if (open_infile(infile,filename)) return -1;
string temp_str;
stringstream temp_ss;
double temp_d;
_1dArray temp_row;
spoint temp_vert;
while(getline(infile,temp_str))
{
if (*(temp_str.begin()) == '#') continue;
temp_ss.str(""); temp_ss.clear(); temp_ss << temp_str;
if(!temp_row.empty()) temp_row.clear();
while(temp_ss >> temp_d)
temp_row.push_back(temp_d);
temp_vert.lon = temp_row[orders[0]];
if (!strcmp(use_spherical_coor,"yes")){
if (temp_vert.lon < 0){
temp_vert.lon += 360.0;
temp_vert.convert = 1;
}
}
temp_vert.lat = temp_row[orders[1]];
if (orders[2] == -1)
temp_vert.rad = 0.0;
else
temp_vert.rad = temp_row[orders[2]];
randomData.push_back(temp_vert);
temp_vert.convert = 0;
}
infile.close();
return 0;
}
int sphInterpolate::outRes()
{
for (int i = 0; i < randomData.size(); i++)
{
if (randomData[i].convert && randomData[i].val != MAX_DBL){
cout << setprecision(12) << randomData[i].lon - 360.0 << " " << randomData[i].lat << " " << randomData[i].rad << " " << randomData[i].val << endl;
}
else if (randomData[i].val != MAX_DBL){
cout << setprecision(12) << randomData[i].lon << " " << randomData[i].lat << " " << randomData[i].rad << " " << randomData[i].val << endl;
}
}
return 0;
}
void sphInterpolate::interpolate(char* startCorner)
{
int tempM,tempN;
double temp_val,lon1,lon2,lat1,lat2;
if (!strcmp(startCorner,"leftTopo")) //数据从左上角开始的情况
{
for (int i = 0; i < randomData.size(); i++)
{
tempM = floor((latmax-randomData[i].lat)/dlat);
tempN = floor((randomData[i].lon-lonmin)/dlon);
if (tempM == (latNum-1)) tempM -= 1;
if (tempN == (lonNum-1)) tempN -= 1;
if (tempM >= 0 && tempN >= 0 && tempM <= latNum-2 && tempN <= lonNum-2)
{
lon1 = lonmin+tempN*dlon;
lon2 = lonmin+(tempN+1)*dlon;
lat1 = latmax-(tempM+1)*dlat;
lat2 = latmax-tempM*dlat;
temp_val = SphBiInterp_deg(90-lat1,90-lat2,lon1,lon2,
90-randomData[i].lat,randomData[i].lon,
gridData[(tempM+1)*lonNum+tempN].val,
gridData[(tempM+1)*lonNum+tempN+1].val,
gridData[tempM*lonNum+tempN].val,
gridData[tempM*lonNum+tempN+1].val);
randomData[i].val = temp_val;
}
}
}
else if (!strcmp(startCorner,"leftDown")) //数据从左下角开始的情况
{
for (int i = 0; i < randomData.size(); i++)
{
tempM = floor((randomData[i].lat-latmin)/dlat);
tempN = floor((randomData[i].lon-lonmin)/dlon);
if (tempM == (latNum-1)) tempM -= 1;
if (tempN == (lonNum-1)) tempN -= 1;
if (tempM >= 0 && tempN >= 0 && tempM <= latNum-2 && tempN <= lonNum-2)
{
lon1 = lonmin+tempN*dlon;
lon2 = lonmin+(tempN+1)*dlon;
lat1 = latmin+tempM*dlat;
lat2 = latmin+(tempM+1)*dlat;
temp_val = SphBiInterp_deg(90-lat1,90-lat2,lon1,lon2,
90-randomData[i].lat,randomData[i].lon,
gridData[tempM*lonNum+tempN].val,
gridData[tempM*lonNum+tempN+1].val,
gridData[(tempM+1)*lonNum+tempN].val,
gridData[(tempM+1)*lonNum+tempN+1].val);
randomData[i].val = temp_val;
}
}
}
return;
}
#endif

View File

@@ -0,0 +1,106 @@
#ifndef _SYSDEFINE_H
#define _SYSDEFINE_H
#include "iostream"
#include "fstream"
#include "sstream"
#include "string.h"
#include "cmath"
#include "iomanip"
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "vector"
#include "map"
#include "algorithm"
#include "ctime"
#define MAX_DBL 1.0e+30
#define MIN_BDL -1.0e+30
#define ZERO 1.0e-20
#define pole_radius 6351251.669//WGS84椭球极半径
#define equator_radius 6378137//WGS84椭球长半径
#define pi (4.0*atan(1.0))
#define golden_mean (sqrt(5.0)+1)/2//黄金比例
#define defaultR 1e+5
#define BOLDRED "\033[1m\033[31m"
#define RESET "\033[0m"
using namespace std;
typedef vector<int> _1iArray;
typedef vector<vector<int> > _2iArray;
typedef vector<double> _1dArray;
struct spoint
{
int convert = 0;
double lon,lat,rad;
double val;
spoint(){lon=lat=rad=val=MAX_DBL;}
};
typedef vector<spoint> spointArray;
//操作计时
clock_t start,finish;
//以度计算的正弦函数
inline double sind(double degree)
{
return sin(degree*pi/180.0);
}
//以度计算的余弦函数
inline double cosd(double degree)
{
return cos(degree*pi/180.0);
}
//全局函数
int open_infile(ifstream &infile,char* filename)
{
infile.open(filename);
if (!infile)
{
cerr << BOLDRED << "error ==> " << RESET << "file not found: " << filename << endl;
return -1;
}
return 0;
}
int open_outfile(ofstream &outfile,char* filename)
{
outfile.open(filename);
if (!outfile)
{
cerr << BOLDRED << "error ==> " << RESET << "fail to create the file: " << filename << endl;
return -1;
}
return 0;
}
//计算WGS84椭球半径
double WGS84_r(double lati)
{
return pole_radius*equator_radius/sqrt(pow(pole_radius,2)*pow(cos((double) lati*pi/180.0),2)+pow(equator_radius,2)*pow(sin((double) lati*pi/180.0),2));
}
//计算一个参考椭球或者参考球在纬度位置的半径
double REF_r(double lati,double refr,double refR)
{
return refr*refR/sqrt(pow(refr,2)*pow(cos((double) lati*pi/180.0),2)+pow(refR,2)*pow(sin((double) lati*pi/180.0),2));
}
// 球面双线性插值函数 以度为单位的版本
double SphBiInterp_deg(double CoLat1,double CoLat2,double Lon1,double Lon2,double CoLat0,double Lon0,double h11,double h12,double h21,double h22)
{
double Delta=(Lon2-Lon1)*(cosd(CoLat2)-cosd(CoLat1));
double A=(Lon1*(h12-h22)+Lon2*(h21-h11))/Delta;
double B=(cosd(CoLat1)*(h21-h22)+cosd(CoLat2)*(h12-h11))/Delta;
double C=(h11+h22-h21-h12)/Delta;
double D=(Lon2*cosd(CoLat2)*h11-Lon2*cosd(CoLat1)*h21+Lon1*cosd(CoLat1)*h22-Lon1*cosd(CoLat2)*h12)/Delta;
double h0=A*cosd(CoLat0)+B*Lon0+C*Lon0*cosd(CoLat0)+D;
return h0;
}
#endif