data | ||
src | ||
.gitignore | ||
CMakeLists.txt | ||
config.sh | ||
LibTINConfig.cmake.in | ||
LICENSE | ||
README.md | ||
topo_TIN.png |
LibTIN - C++ library of the Triangular Irregular Network (TIN)

Introduction
LibTIN is a stand alone C++ library for generating the Triangular Irregular Networks (TIN) using DEM data that are located at a regular grid or random locations. No dependences are needed. The generated TINs that are fully Delaunay, and neighboring information is also retrieved during the construction. Additionally, a polygon could be provided to control the outline shape of the generated TIN.
Installation
The LibTIN compiles using the CMake software. Typically, you need following commands to compile and install the library and tools after you navigated into the package's directory:
make build
cd build
cmake ..
make install
This will compile the library and two command line tools, grd2tin and rnd2tin, which will be introduced bellow. The library and tools are installed in the directories /usr/local/lib and /usr/local/sbin by default. You can specify a different directory for installation using the CMAKE_INSTALL_PREFIX option.
Data Structures
vertex2dc
Vertex defined on the 2-D Cartesian coordinates. It is used to represent the vertex of the TIN or the polygon's corners. Included variables are as following:
struct vertex2dc
{
unsigned int id; // index of the vertex
double x, y; // position of the vertex
double elev; // elevation at the vertex
}
triangle
Triangular facet defined on the 2-D Cartesian coordinates. It is used to represent the facet of the TIN. Included variables are as following:
struct triangle
{
int id;
vertex2dc *vert[3]; // vertex of the triangle
triangle *neigh[3]; // neighbors of the triangle
double cx, cy; // center of the triangle's circumcircle
double cr; // radius of the circumcircle
std::vector<dem_point*> hosted_dem; // DEM points that are located within the triangle
}
dem_point
DEM point defined on the 2-D Cartesian coordinate. It is used to store the input DEM data. Included variables are as following:
struct dem_point
{
double x, y; // position of the DEM location
double elev; // elevation at the DEM location
double err; // error of the TIN with respect to the elevation
triangle *host; // pointer of the triangle that the dem_point falls inside of
}
Tools
grd2tin: generation of the TIN using regular DEM data
usage
grd2tin -f<grid-file> -r<xmin>/<xmax>/<ymin>/<ymax> -i<dx>/<dy> -m<mesh-file> [-p<poly-file>] [-t<threshold>] [-l<log-file>] [-n<neighbor-file>] [-z]
options
- -f Input DEM data. The program takes DEM data that are stored as a simple ASCII text file. Each line of the file contains the x, y and elevation values of a DEM point separated by spaces. Moreover, the DEM data should be stored in an order that starts from the lower-left corner of the DEM grid and travels in a row-major manner till the upper-right corner of the grid. Specially, the x and y values in the file could be omitted by setting the -z option.
- -r Range of the input DEM grid in the x and y directions, respectively.
- -i Intervals of the input DEM grid in the x and y directions, respectively.
- -m Output Gmsh file (.msh) of the generated TIN.
- -p (optional) Input text file of a polygon to control the outline shape of the generated TIN. The polygon is represented using its corners' locations. Each line of the file should contain the x, y values of a corner vertex. The vertexes could be ordered either clockwise or anti-clockwise.
- -t (optional) Threshold of the maximal error of the generated TIN with respect to the input DEM grid.
- -l (optional) Output text file of a log file of the maximal error of the generated TIN.
- -n (optional) Output text file of neighbor-ships of the generated TIN.
- -z (optional) The input DEM grid is a 1-column z-table.
rnd2tin: generation of the TIN using random DEM data
usage
rnd2tin -f<xyz-file> -m<mesh-file> [-p<poly-file>] [-t<threshold>] [-l<log-file>] [-n<neighbor-file>]
options
- -f Input DEM data. The program takes DEM data that are stored as a simple ASCII text file. Each line of the file contains the x, y and elevation values of a DEM point separated by spaces.
- -m Output Gmsh file (.msh) of the generated TIN.
- -p (optional) Input text file of a polygon to control the outline shape of the generated TIN. The polygon is represented using its corners' locations. Each line of the file should contain the x, y values of a corner vertex. The vertexes could be ordered either clockwise or anti-clockwise.
- -t (optional) Threshold of the maximal error of the generated TIN with respect to the input DEM grid.
- -l (optional) Output text file of a log file of the maximal error of the generated TIN.
- -n (optional) Output text file of neighbor-ships of the generated TIN.
Examples
The following is a simple example for using the library to generate the TIN you see on top of this page. More examples could be found at the src/demo folder.
#include "../lib/tin.h"
#include "iostream"
#include "fstream"
#include "iomanip"
int main(int argc, char const *argv[])
{
// read dem grid
std::vector<double> topo(10201);
std::ifstream infile("data/topo");
for (int i = 0; i < 10201; ++i)
{
infile >> topo[i];
}
infile.close();
// prepare variables and vectors
std::vector<double> err_records;
std::vector<vertex2dc*> tin_vert;
std::vector<triangle*> tin_ele;
// call the grd2tin function to generate the TIN
// the resultant vertexes and facets are stored in
// vectors tin_vert and tin_ele, respetively.
grd2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records);
// Write a log file of the construciton process
// which you can examine later.
std::ofstream logfile("data/topo_TIN.log");
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 for visualization
std::ofstream outfile("data/topo_TIN.msh");
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 neighboring file
outfile.open("data/topo_TIN.neigh");
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 grd2tin 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];
}
return 0;
}