gctl_toolkits/archive/grd2msh/func.h
2024-09-10 20:25:18 +08:00

291 lines
5.7 KiB
C++

#ifndef _FUNC_H
#define _FUNC_H
#include "struct.h"
class func
{
public:
func();
~func();
int run(char*,char*,char*,double,int,double,double,int,int);
int readgrd(char*);
int readxyz(char*,double,double);
int readxyz(char*);
int changeToSph(char*);
int outmsh(char*,double);
private:
posi* topo;
int M,N;
int posi_num;
PosiList list_posi;
PosiList::iterator ip;
};
func::func()
{
topo = NULL;
}
func::~func()
{
if(topo!=NULL) delete[] topo;
if(!list_posi.empty()) list_posi.clear();
}
int func::run(char* filename,char* mshname,char* refsys,double factor,int type,double dx,double dy,int input_N,int input_M)
{
if (type == 1)
{
readgrd(filename);
}
else if (type == 2)
{
if (input_N==-1)
{
readxyz(filename,dx,dy);
}
else
{
readxyz(filename);
M = input_M;
N = input_N;
}
}
if(strcmp(refsys,"NULL"))
changeToSph(refsys);
outmsh(mshname,factor);
return 0;
}
int func::readgrd(char* inname)
{
double xmin,xmax,ymin,ymax,zmin,zmax;
double dx,dy;
string head_info = "";
ifstream infile(inname);
if (!infile)
{
cout<<BOLDRED<<"==> "<<RESET<<inname<<" not found..."<<endl;
return 1;
}
else
{
infile>>head_info;
if (head_info!="DSAA")
{
cout<<BOLDRED<<"==> "<<RESET<<"The format of "<<inname<<" is not supported..."<<endl;
return 1;
}
else
{
infile>>N>>M>>xmin>>xmax>>ymin>>ymax>>zmin>>zmax;
dx = (xmax-xmin)/(N-1);
dy = (ymax-ymin)/(M-1);
posi_num = M*N;
topo = new posi [posi_num];
for (int i = 0; i < posi_num; ++i)
{
topo[i].id = i+1;
infile>>topo[i].z;
topo[i].alti = topo[i].z;
topo[i].x = xmin + dx*(i%N);
topo[i].y = ymin + dy*(i/N);
}
infile.close();
return 0;
}
}
}
int func::readxyz(char* inname,double dx,double dy)
{
int count;
posi temp_posi;
string line;
stringstream sline;
double xmax,ymax;
double xmin,ymin;
ifstream infile(inname);
if (!infile)
{
cout<<BOLDRED<<"==> "<<RESET<<inname<<" not found..."<<endl;
return 1;
}
else
{
xmax = ymax = -1e+30;
xmin = ymin = 1e+30;
count = 1;
while(getline(infile,line))
{
if (*(line.begin()) == '#') continue;
if (line!="")
{
sline.clear();
sline.str(line);
temp_posi.id = count;
sline >> temp_posi.x >> temp_posi.y >> temp_posi.z;
list_posi.push_back(temp_posi);
count++;
if (temp_posi.x>xmax) xmax = temp_posi.x;
if (temp_posi.y>ymax) ymax = temp_posi.y;
if (temp_posi.x<xmin) xmin = temp_posi.x;
if (temp_posi.y<ymin) ymin = temp_posi.y;
}
}
infile.close();
M = (ymax-ymin)/dy+1;
N = (xmax-xmin)/dx+1;
posi_num = list_posi.size();
topo = new posi [posi_num];
count = 0;
for(ip=list_posi.begin();ip!=list_posi.end();++ip)
{
temp_posi = *ip;
topo[count].id = temp_posi.id;
topo[count].x = temp_posi.x;
topo[count].y = temp_posi.y;
topo[count].z = temp_posi.z;
topo[count].alti = topo[count].z;
count++;
}
return 0;
}
}
int func::readxyz(char* inname)
{
int count;
posi temp_posi;
string line;
stringstream sline;
double xmax,ymax;
double xmin,ymin;
ifstream infile(inname);
if (!infile)
{
cout<<BOLDRED<<"==> "<<RESET<<inname<<" not found..."<<endl;
return 1;
}
else
{
count = 1;
while(getline(infile,line))
{
if (*(line.begin()) == '#') continue;
if (line!="")
{
sline.clear();
sline.str(line);
temp_posi.id = count;
sline >> temp_posi.x >> temp_posi.y >> temp_posi.z;
list_posi.push_back(temp_posi);
count++;
}
}
infile.close();
posi_num = list_posi.size();
topo = new posi [posi_num];
count = 0;
for(ip=list_posi.begin();ip!=list_posi.end();++ip)
{
temp_posi = *ip;
topo[count].id = temp_posi.id;
topo[count].x = temp_posi.x;
topo[count].y = temp_posi.y;
topo[count].z = temp_posi.z;
topo[count].alti = topo[count].z;
count++;
}
return 0;
}
}
int func::changeToSph(char* refer)
{
double refr,refR;
if (!strcmp(refer,"WGS84"))
{
refr = WGS84_PoleRadius;
refR = WGS84_EquatorRadius;
}
else if (!strcmp(refer,"EarthR"))
{
refr = EarthRadius;
refR = EarthRadius;
}
else if (2 != sscanf(refer,"%lf/%lf",&refr,&refR))
{
cout << BOLDRED <<"==> "<< RESET <<" wrong reference system: "<<refer<<endl;
return 1;
}
double lon,lat,rad;
for (int i = 0; i < posi_num; ++i)
{
lon = topo[i].x;
lat = topo[i].y;
rad = topo[i].z + refRadius(lat,refr,refR);
topo[i].x = rad*sin((0.5 - lat/180.0)*Pi)*cos((2.0 + lon/180.0)*Pi);
topo[i].y = rad*sin((0.5 - lat/180.0)*Pi)*sin((2.0 + lon/180.0)*Pi);
topo[i].z = rad*cos((0.5 - lat/180.0)*Pi);
}
return 0;
}
int func::outmsh(char* outname,double magify)
{
ofstream outfile(outname);
if (!outfile)
{
cout<<BOLDRED<<"==> "<<RESET<<"can not create "<<outname<<endl;
return 1;
}
else
{
outfile<<"$MeshFormat"<<endl<<"2.2 0 8"<<endl<<"$EndMeshFormat"<<endl<<"$Nodes"<<endl<<posi_num<<endl;
for (int i = 0; i < posi_num; ++i)
{
outfile<<topo[i].id<<" "<<topo[i].x<<" "<<topo[i].y<<" "<<magify*topo[i].z<<endl;
}
outfile<<"$EndNodes"<<endl<<"$Elements"<<endl<<(M-1)*(N-1)*2<<endl;
int element_count = 1;
for(int i=1;i<=M-1;i++)
{
for(int j=1;j<=N-1;j++)
{
outfile<<element_count<<" 2 1 10 "<<(i-1)*N+j<<" "<<(i-1)*N+j+1<<" "<<i*N+j+1<<endl;
element_count++;
}
}
for(int i=M;i>=2;i--)
{
for(int j=N;j>=2;j--)
{
outfile<<element_count<<" 2 1 10 "<<(i-1)*N+j<<" "<<(i-1)*N+j-1<<" "<<(i-2)*N+j-1<<endl;
element_count++;
}
}
outfile<<"$EndElements"<<endl<<"$NodeData"<<endl;
outfile<<1<<endl<<"\"GRD TOPO\""<<endl<<1<<endl<<0.0<<endl<<3<<endl<<0<<endl<<1<<endl<<posi_num<<endl;
for (int i = 0; i < posi_num; ++i)
{
outfile<<i+1<<" "<<setprecision(16)<<topo[i].alti<<endl;
}
outfile<<"$EndNodeData";
outfile.close();
return 0;
}
}
#endif