#include "iostream" #include "fstream" #include "stdio.h" #include "stdlib.h" #include "unistd.h" #include "sstream" #include "vector" #include "string.h" #include "cmath" #include "iomanip" #include "map" #define WGS84_PoleRadius 6356752.3//WGS84椭球极半径 #define WGS84_EquatorRadius 6378137//WGS84椭球长半径 #define EarthRadius 6371008.8 #define Pi (4.0*atan(1.0)) #define BOLDRED "\033[1m\033[31m" #define RESET "\033[0m" #define MAX_DBL 1e+30 #define ZERO 1e-20 using namespace std; int open_infile(ifstream &infile,char* filename) { infile.open(filename); if (!infile) { cout << BOLDRED << "error ==> " << RESET << "file not found: " << filename << endl; return -1; } return 0; } int open_outfile(ofstream &outfile,char* filename) { outfile.open(filename); if (!outfile) { cout << BOLDRED << "error ==> " << RESET << "fail to create the file: " << filename << endl; return -1; } return 0; } //计算一个参考椭球或者参考球在纬度位置的半径 double refRadius(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)); } //直角坐标系下的一个点 struct cpoint { double x,y,z; cpoint() //初始化坐标值 { x = y = z = MAX_DBL; } }; //球坐标系下的一个点 struct spoint { double lon,lat,rad; spoint() //初始化坐标值 { lon = lat = rad = MAX_DBL; } }; /*直角坐标与球坐标相互转换函数 注意这里使用的球坐标是地理坐标范围 即经度为-180~180 纬度为-90~90*/ cpoint s2c(spoint s) { cpoint c; c.x = s.rad*sin((0.5 - s.lat/180.0)*Pi)*cos((2.0 + s.lon/180.0)*Pi); c.y = s.rad*sin((0.5 - s.lat/180.0)*Pi)*sin((2.0 + s.lon/180.0)*Pi); c.z = s.rad*cos((0.5 - s.lat/180.0)*Pi); return c; } spoint c2s(cpoint c) { spoint s; s.rad = sqrt(pow(c.x,2)+pow(c.y,2)+pow(c.z,2)); if (fabs(s.rad) nodeArray; typedef map strMap; //顶点位置映射 用于通过顶点位置寻找相应顶点 struct triangle { int id; int index[3]; }; typedef vector triArray; class gmt2msh { public: gmt2msh(){} ~gmt2msh(){} int getRef(char*); int getNode(char*,double,double); int getNode(char*,double); int outMsh(char*); private: double refr,refR; nodeArray Nodes; strMap mapStr; strMap::iterator ivm; triArray Triangles; }; int gmt2msh::getRef(char* para) { //首先匹配预定义类型 if (!strcmp(para,"WGS84")) { refr = WGS84_PoleRadius; refR = WGS84_EquatorRadius; } else if (!strcmp(para,"EarthRadius")) { refr = EarthRadius; refR = EarthRadius; } //匹配参数格式 else if (2 == sscanf(para,"%lf/%lf",&refr,&refR)) { if (refr <= 0 || refR <= 0) { cout << BOLDRED << "Error ==> " << RESET << "fail to initial reference system" << endl; return -1; } } else { cout << BOLDRED << "Error ==> " << RESET << "fail to initial reference system" << endl; return -1; } return 0; } int gmt2msh::getNode(char* filename,double refr,double refR) { ifstream infile; if (open_infile(infile,filename)) return -1; string temp_str; stringstream temp_ss; node temp_node; triangle temp_tri; while (getline(infile,temp_str)) { if (*(temp_str.begin()) == '#') continue; if (1 == sscanf(temp_str.c_str(),"> Triangle: %d",&temp_tri.id)) { for (int i = 0; i < 3; i++) { getline(infile,temp_str); temp_ss.str(""); temp_ss.clear(); temp_ss << temp_str; temp_ss >> temp_node.posis.lon >> temp_node.posis.lat; temp_node.posis.rad = refRadius(temp_node.posis.lat,refr,refR); temp_node.set(temp_node.posis); //查找映射表 ivm = mapStr.find(temp_str); if (ivm == mapStr.end()) { temp_node.id = Nodes.size(); Nodes.push_back(temp_node); temp_tri.index[i] = temp_node.id; //添加映射 mapStr[temp_str] = temp_node.id; } else temp_tri.index[i] = ivm->second; } } Triangles.push_back(temp_tri); } infile.close(); } int gmt2msh::getNode(char* filename,double alti) { ifstream infile; if (open_infile(infile,filename)) return -1; string temp_str; stringstream temp_ss; node temp_node; triangle temp_tri; while (getline(infile,temp_str)) { if (*(temp_str.begin()) == '#') continue; if (sscanf(temp_str.c_str(),"> Triangle: %d",&temp_tri.id)) { for (int i = 0; i < 3; i++) { getline(infile,temp_str); temp_ss.str(""); temp_ss.clear(); temp_ss << temp_str; temp_ss >> temp_node.posic.x >> temp_node.posic.y; temp_node.posic.z = alti; temp_node.set(temp_node.posic); //查找映射表 ivm = mapStr.find(temp_str); if (ivm == mapStr.end()) { temp_node.id = Nodes.size(); Nodes.push_back(temp_node); temp_tri.index[i] = temp_node.id; //添加映射 mapStr[temp_str] = temp_node.id; } else temp_tri.index[i] = ivm->second; } } Triangles.push_back(temp_tri); } infile.close(); } int gmt2msh::outMsh(char* filename) { ofstream outfile; if(open_outfile(outfile,filename)) return -1; outfile<<"$MeshFormat"<