237 lines
7.6 KiB
C++
237 lines
7.6 KiB
C++
#include "../lib/tin.h"
|
|
#include "display_help.h"
|
|
|
|
#include "iostream"
|
|
#include "fstream"
|
|
#include "sstream"
|
|
#include "string"
|
|
#include "getopt.h"
|
|
|
|
void display_help(std::string exe_name)
|
|
{
|
|
dispHelp dh;
|
|
dh.changeLayerOut(0, 10);
|
|
dh.addHeadInfo(exe_name, "1.0", "Generating the Triangular Irregular Networks (TIN) from random DEM points.",
|
|
"Yi Zhang (zhangyiss@icloud.com)");
|
|
dh.addUsage(exe_name+" -f<xyz-file> -m<mesh-file> [-p<poly-file>] [-t<threshold>] [-l<log-file>] [-n<neighbor-file>]");
|
|
dh.addOption("Input DEM xyz file.", "-f", "--xyz-file");
|
|
dh.addOption("Output Gmsh file (.msh) of the generated TIN.", "-m", "--mesh-file");
|
|
dh.addOption("Input text file of a polygon to control the outline shape of the generated TIN.", "-p", "--polygon-file");
|
|
dh.addOption("Threshold of the maximal error of the generated TIN with respect to the input DEM grid. (Default is 1.0)", "-t", "--threshold");
|
|
dh.addOption("Output text file of a log file of the maximal error of the generated TIN.", "-l", "--log-file");
|
|
dh.addOption("Output text file of neighborships of the generated TIN.", "-n", "--neighbor-file");
|
|
dh.addOption("Display help information.", "-h", "--help");
|
|
dh.show();
|
|
return;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
try
|
|
{
|
|
static struct option long_opts[] =
|
|
{
|
|
{"xyz-file", required_argument, NULL, 'f'},
|
|
{"mesh-file", required_argument, NULL, 'm'},
|
|
{"polygon-file", required_argument, NULL, 'p'},
|
|
{"threshold", required_argument, NULL, 't'},
|
|
{"log-file", required_argument, NULL, 'l'},
|
|
{"neighbor-file", required_argument, NULL, 'n'},
|
|
{"help", no_argument, NULL, 'h'},
|
|
{0, 0, 0, 0},
|
|
};
|
|
|
|
if (argc == 1)
|
|
{
|
|
display_help(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
double threshold = 1.0;
|
|
std::string xyz_file, mesh_file, poly_file, log_file, neigh_file;
|
|
xyz_file = mesh_file = "NULL";
|
|
poly_file = log_file = neigh_file = "NULL";
|
|
bool z_table = false;
|
|
|
|
int curr;
|
|
while (1)
|
|
{
|
|
int optIndex = 0;
|
|
|
|
curr = getopt_long(argc, argv, "hf:m:p:t:l:n:", long_opts, &optIndex);
|
|
|
|
if (curr == -1) break;
|
|
|
|
switch (curr)
|
|
{
|
|
case 'h':
|
|
display_help(argv[0]);
|
|
return 0;
|
|
case 'z':
|
|
z_table = true;
|
|
break;
|
|
case 'f':
|
|
xyz_file = optarg; break;
|
|
case 'm':
|
|
mesh_file = optarg; break;
|
|
case 'p':
|
|
poly_file = optarg; break;
|
|
case 't':
|
|
if (1 != sscanf(optarg,"%lf", &threshold)) //格式化读入参数
|
|
{
|
|
throw "Invalid threshold";
|
|
}
|
|
break;
|
|
case 'l':
|
|
log_file = optarg; break;
|
|
case 'n':
|
|
neigh_file = optarg; break;
|
|
case '?':
|
|
display_help(argv[0]);
|
|
return 0;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
if (xyz_file == "NULL" || mesh_file == "NULL")
|
|
{
|
|
throw "No input grid text file or Gmsh mesh file";
|
|
}
|
|
|
|
// Prepare DEM parameters
|
|
|
|
|
|
// Read DEM grid
|
|
dem_point tmp_dem;
|
|
std::vector<dem_point> topo;
|
|
std::ifstream infile;
|
|
|
|
infile.open(xyz_file);
|
|
while (infile >> tmp_dem.x >> tmp_dem.y >> tmp_dem.elev)
|
|
{
|
|
topo.push_back(tmp_dem);
|
|
}
|
|
infile.close();
|
|
|
|
// Read Polygon file
|
|
int tmp_count;
|
|
double tmp_x, tmp_y;
|
|
std::vector<vertex2dc> poly_vert;
|
|
if (poly_file != "NULL")
|
|
{
|
|
infile.open(poly_file);
|
|
infile >> tmp_count;
|
|
poly_vert.resize(tmp_count);
|
|
for (int i = 0; i < tmp_count; i++)
|
|
{
|
|
infile >> tmp_x >> tmp_y;
|
|
poly_vert[i].set(tmp_x, tmp_y, 0.0, i);
|
|
}
|
|
infile.close();
|
|
}
|
|
|
|
std::vector<double> err_records;
|
|
std::vector<vertex2dc*> tin_vert;
|
|
std::vector<triangle*> tin_ele;
|
|
if (poly_file == "NULL" && log_file == "NULL")
|
|
{
|
|
rnd2tin(topo, tin_vert, tin_ele, threshold, nullptr, nullptr);
|
|
}
|
|
else if (poly_file == "NULL")
|
|
{
|
|
rnd2tin(topo, tin_vert, tin_ele, threshold, nullptr, &err_records);
|
|
}
|
|
else if (log_file == "NULL")
|
|
{
|
|
rnd2tin(topo, tin_vert, tin_ele, threshold, &poly_vert, nullptr);
|
|
}
|
|
else
|
|
{
|
|
rnd2tin(topo, tin_vert, tin_ele, threshold, &poly_vert, &err_records);
|
|
}
|
|
|
|
// Write a log file
|
|
if (log_file != "NULL")
|
|
{
|
|
std::ofstream logfile(log_file);
|
|
logfile << "# Insertion Maxi-Error\n";
|
|
for (int i = 0; i < err_records.size(); ++i)
|
|
{
|
|
logfile << i+1 << " " << err_records[i] << std::endl;
|
|
}
|
|
logfile.close();
|
|
}
|
|
|
|
// Write a Gmsh's .msh file
|
|
std::ofstream outfile(mesh_file);
|
|
outfile << "$MeshFormat" << std::endl << "2.2 0 8" << std::endl << "$EndMeshFormat "<<std::endl;
|
|
outfile << "$Nodes" << std::endl << tin_vert.size() << std::endl;
|
|
for (int i = 0; i < tin_vert.size(); i++)
|
|
{
|
|
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16)
|
|
<< tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl;
|
|
}
|
|
outfile<<"$EndNodes"<<std::endl;
|
|
outfile << "$Elements" << std::endl << tin_ele.size() <<std::endl;
|
|
for (int i = 0; i < tin_ele.size(); i++)
|
|
{
|
|
outfile << i + 1 << " 2 0";
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
outfile << " " << tin_ele[i]->vert[j]->id + 1;
|
|
}
|
|
outfile << std::endl;
|
|
}
|
|
outfile << "$EndElements"<< std::endl;
|
|
outfile<<"$NodeData"<<std::endl;
|
|
outfile<<1<<std::endl
|
|
<<"\"Topography (m)\"" <<std::endl
|
|
<< 1 <<std::endl<< 0.0 <<std::endl
|
|
<< 3 <<std::endl<< 0<<std::endl
|
|
<< 1 <<std::endl<< tin_vert.size() <<std::endl;
|
|
for (int i = 0; i < tin_vert.size(); i++)
|
|
{
|
|
outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16) << tin_vert[i]->elev << std::endl;
|
|
}
|
|
outfile << "$EndNodeData" << std::endl;
|
|
outfile.close();
|
|
|
|
// write a neighbor file
|
|
if (neigh_file != "NULL")
|
|
{
|
|
outfile.open(neigh_file);
|
|
outfile << tin_ele.size() << std::endl;
|
|
for (int i = 0; i < tin_ele.size(); i++)
|
|
{
|
|
outfile << i + 1;
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
if (tin_ele[i]->neigh[j] != nullptr)
|
|
{
|
|
outfile << " " << tin_ele[i]->neigh[j]->id + 1;
|
|
}
|
|
else outfile << " -1";
|
|
}
|
|
outfile << std::endl;
|
|
}
|
|
outfile.close();
|
|
}
|
|
|
|
// Destroy memories allocated by the dem2tin function
|
|
for (int i = 0; i < tin_vert.size(); ++i)
|
|
{
|
|
delete tin_vert[i];
|
|
}
|
|
|
|
for (int i = 0; i < tin_ele.size(); ++i)
|
|
{
|
|
delete tin_ele[i];
|
|
}
|
|
}
|
|
catch(const char* err_char)
|
|
{
|
|
std::cerr << err_char << '\n';
|
|
}
|
|
return 0;
|
|
} |