#ifndef _SYSDEFINE_H
#define _SYSDEFINE_H
#include "iostream"
#include "fstream"
#include "sstream"
#include "string"
#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;

//操作计时
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