Esri TIN
The Esri TIN format is a popular yet proprietary geospatial vector data format for geographic information system software for storing elevation data as a triangulated irregular network. It is developed and regulated by Esri. The Esri TIN format can spatially describe elevation information including breaking edge features. Each points and triangle can carry a tag information.
A TIN stored in this file format can have any shape, cover multiple regions and contain holes.
In 2007 a reverse-engineered description of Esri TIN format came to light. Since then, the Virtual Terrain Project, an open-source software, has implemented support for reading the format, without the need of ArcGIS being installed.
Overview
The Esri TIN format is a digital vector storage format for storing elevation information including breaking edge features. The Esri TIN format was introduced with ArcView GIS.The Esri TIN format consists of a collection of files with specific filenames and a common filename extension, stored in the same directory. Most of the files are mandatory files, optionally a file containing the coordinate system and projection information and files containing point tag information and triangle tag information can be given.
;Mandatory files :
- tdenv.adf — header and statistical data
- tedg.adf — edges data and topology
- thul.adf — outer and inner hull polygon data
- tmsk.adf — mask data, masks invisible triangles
- tmsx.adf — index file for tmsk.adf
- tnod.adf — triangle node data
- tnxy.adf — position information
- tnz.adf — height information
;Other files :
- prj.adf — projection description, using a well-known text representation of coordinate reference systems; are single line signifies an unknown coordinate system
- tndsc.adf — statistic on point tag usage
- tnval.adf — point tag data
- ttdsc.adf — description of triangle tag data
- ttval.adf — triangle tag data
;Files generated by ArcGIS 10 :
- tnodinfo.adf — point types and more
- teval.adf — edges data
- tdenv9.adf — the file tdenv.adf renamed
A TIN with n points and k triangles, the file sizes calculate to:
- tnxy.adf : 16*n bytes
- tnz.adf : 4*n bytes
- tnod.adf : 12*k bytes
- tedg.adf : 12*k bytes
- tmsx.adf : 116 bytes
- tdenv.adf/tdenv9.adf : 104 bytes
- tmsk.adf : 132 + 4*ceiling bytes
- thul.adf : min. 12 bytes, depends on the number of points in the convex hull polygon
- tndsc.adf : 24* the number of tag entries specified in tndsc.adf bytes
- tnval.adf : 4*n' bytes
- tnodinfo.adf : 2*n bytes
- teval.adf : 16* the number of breaking edges entries specified in tdenv9.adf bytes
Mandatory files
tnxy.adf - X and Y coordinates of the points of the TIN
Contains and array of X and Y coordinate values, one pair for each point of the TIN. The data set for each point can be described by the following structure:Bytes | Type | Endianness | Usage |
0–7 | double | big | X coordinate value |
8–15 | double | big | Y coordinate value |
tnz.adf - Z coordinates of the points of the TIN
Contains an array of Z coordinate values, one for each point of the TIN. The values are in same order as the values in tnxy.adf and together store the 3 dimensional coordinate of each point of the TIN. The data set for each point can be described by the following structure:Bytes | Type | Endianness | Usage |
0–3 | float | big | Z coordinate value |
tnod.adf - Indices of the points that form the triangles of the TIN
Contains an array of indices to the points that form the triangles of the TIN, 3 indices for each triangle. The indices are in the range of 1 to the number of points. The front face of a triangle is that face, that has the 3 points/corners ordered clockwise when viewed. The data set for each triangle can be described by the following structure:Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Index of the first point of a triangle |
4–7 | int32 | big | Index of the second point of a triangle |
8–11 | int32 | big | Index of the third point of a triangle |
tedg.adf - Topology of the triangles and the type of its edges
Contains information about the topology of the triangles and the type of their edges.There is an entry for each triangle with each 3 indices, that point to the position in tnod.adf file to identify the triangle, that shares an edge with the triangle described by the current data set, and the point of that triangle, that form that edge.
For each triangle in tnod.adf exists a data set at the same file location in tedg.adf. Each of the values point to the location in tnod.adf, where the point is specified that form an edge. At the same time, since the location in tnod.adf and tedg.adf correspond, each of the values point to the location in tedg.adf, where the location of the value is specified. Rule: If edge a of triangle A points to edge b of triangle B, then edge b of triangle B must point to edge a of triangle A. Since edge definition in tedg.adf and point definition in tnod.adf of each triangle are at the same location the files, the indices in tedg.adf point to the point definition in tnod.adf of the neighbouring triangles.
The indices encode the actual index and type of the edge. The actual indices are not file offsets in bytes, but rather in int32 values, in the range of 1 to the number of points. If the value is negative the edge is a breaking edge. Furthermore, bit 30 of the int32 values is used to determine if the edge is a hard or soft breaking edge. If the actual index would be 1234 then a hard breaking edge would be encoded as -1234 and a soft breaking edge as -1073743058. The edge definition of the neighbouring triangle must mirror the edge type. ATTENTION: This behaviour has changed since ArcGIS 10. Please compare with the information given in section 'Format changes and files new with ArcGIS 10'.
The data set for each triangle can be described by the following structure:
Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Encoded index of point definition of the neighbouring triangle in tnod.adf that form an edge with the first point of the triangle |
4–7 | int32 | big | Encoded index of point definition of the neighbouring triangle in tnod.adf that form an edge with the second point of the triangle |
8–11 | int32 | big | Encoded index of point definition of the neighbouring triangle in tnod.adf that form an edge with the third point the a triangle |
tdenv.adf - Header or statistics
This file contains information that could be seen as a mix of file header and statistic data.Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Number of points |
4–7 | int32 | big | Number of triangles |
8–11 | int32 | big | Number of indices and separators in thul.adf |
12–15 | int32 | big | 0 / number of breaking edge entries in teval.adf |
16–19 | int32 | big | Number of triangles, not masked in tmsk.adf |
20–23 | int32 | big | Number of regular points |
24–27 | int32 | big | Number of [|superpoints] |
28–31 | float | big | Minimum height |
32–35 | float | big | Maximum height |
36–39 | int32 ? | big | Unknown, different values encountered |
40–47 | double | big | Minimum extent in X direction |
48–55 | double | big | Minimum extent in Y direction |
56–63 | double | big | Maximum extent in X direction |
64–71 | double | big | Maximum extent in Y direction |
72–79 | double ? | big | Unknown, always 0 |
80–87 | double ? | big | Unknown, different values encountered |
88–91 | int32 | big | Unknown, always 70001 / 90001 ; maybe a version number |
92–95 | int32 | little | Number of used tags |
96–99 | int32 ? | big | Unknown, always 0; maybe unused |
100–103 | int32 ? | big | Unknown, always 0; maybe unused |
thul.adf - Hull, bounding polygon and holes
Contains an array of indices and separators, that defines the outer boundary of the TIN and its holes. The indices are in the range of 1 to the number of points. The separators are -1 and zero.If the TIN is constructed using superpoints, thul.adf lists the indices of these points and then -1. After the separator follows one or more lists of indices that form bounding polygons and maybe holes. These lists are separated by zero values.
If the TIN does not contain superpoints, thul.adf starts with the -1 separator, which is followed by one or more lists of indices that form bounding polygons and maybe holes. These lists are separated by zero values.
The indices and separators are 4 byte integer values, stored in big-endian byte order.
tmsk.adf - Mask
Contains an array of bits that specify the visibility of the triangles of the TIN. This can be used to hide the triangles inside of terrain holes or outside the terrain.The file is stored using the same structures as a shapefile, but since it only stores the visibility values of the triangles many fields of the header are used.
The file header is fixed at 100 bytes in length and contains 17 fields; nine 4-byte integer fields followed by eight 8-byte signed floating point fields:
Bytes | Type | Endianness | Usage |
0–3 | int32 | big | File code |
4–23 | int32 | big | Unused; five uint32 |
24–27 | int32 | big | File length |
28–31 | int32 | little | Version 0 ; probably unused |
32–35 | int32 | little | Shape type 0 ; probably unused |
36–43 | double | little | Minimum X extent ; unused |
44–51 | double | little | Minimum Y extent ; unused |
52–59 | double | little | Maximum X extent ; unused |
60–67 | double | little | Maximum Y extent ; unused |
68–75 | double | little | Minimum Z extent ; unused |
76–83 | double | little | Maximum Z extent ; unused |
84–91 | double | little | Minimum M extent ; unused |
92–99 | double | little | Maximum M extent ; unused |
The file then contains at least 2 records. Each record is prefixed with a record-header of 8 bytes:
Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Record number |
4–7 | int32 | big | Record length |
Following the record header is the actual data.
Record 1: The data of record number 1 is 2 word long and contains only the size of the data of record number 2 in 4 byte integers, stored as 4 byte integer itself.
Record 2: The data of record number 2 contain the following variable length structure:
Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Number of integer in the mask array |
4–7 | int32 | big | Unused; always 0; maybe an offset into the mask array, where the actual mask bits start |
8–11 | int32 | big | Number of used bits in the mask array |
12– | uint32 | big | Mask array |
Bit 0 of the first integer contains the visibility flag of the first triangle defined in tnod.adf. Bit 1 of the first integer contains the visibility flag of the second triangle, and so on. All 32 bits of the integers get used.
Record 0: Records with the record number 0 must be ignored.
tmsx.adf - Index file for the mask
The index file contains the same 100-byte header as the tmsk.adf file, followed by any number of 8-byte fixed-length records which consist of the following two fields:Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Record offset |
4–7 | int32 | big | Record length |
Using this index, it is possible to seek backwards in the tmsk.adf file by, first, seeking backwards in the index, then reading the record offset, and using that offset to seek to the correct position in the tmsk.adf file. It is also possible to seek forwards an arbitrary number of records using the same method.
Optional files
Depending of the information stored in the TIN, some extra files are needed.prj.abf - Projection and CRS
Contains the coordinate system and projection information. The file can be either in the Esri flavour of the well-known text representation of coordinate reference systems format, a simple keyword-value notation or have a single line , which signifies an unknown coordinate system.tndcs.abf - Statistic of tag usage
Contains an array of 24 byte big data set, one for each used tag. The data set contains the tag and the number of points with that tag. Each data set is structured as follows:Bytes | Type | Endianness | Usage |
0–3 | int32 | little | Number of the entry; starting with 1 |
4–7 | int32 | little | Tag value |
8–11 | int32 | little | Unused; always 0; maybe reserved for extending tag values to 64 bit |
12–15 | int32 | little | Number of points with the tag |
16–19 | int32 ? | little | Unused; always 0 |
20–23 | int32 ? | little | Unknown; always 0 in ArcGIS 9, different values in ArcGIS 10 |
tnval.abf - Point tag file
Contains are array of 4 byte integer value, one for each point of the TIN. The values are stored in little-endian byte order. [|Superpoints] have the value 0. Points without a tag must be stored last in the TIN, and don't have an entry in this file.Format changes and files new with ArcGIS 10
Since ArcGIS 10 there were some changes in the TIN file format. 2 new files and 1 file got remained.tdenv9.dbf - tdenv.dbf renamed
The file structure remains the same, just the field containing the number of breaking edges is additionally used.tnodinfo.dbf - More information for the points
Contains an array of 2 byte integer values. One short for each point. The purpose is still not publicly known. So far it seems to be some kind of bitmask or code, describing the usage of the point. The values seem to be stored in big-endian byte order.Value | Hexadecimal value | Usage |
2 | 0x0002 | Superpoint |
4 | 0x0004 | Regular point |
24 | 0x0018 | ? |
88 | 0x0058 | ? |
132 | 0x0084 | ? |
280 | 0x0118 | ? |
284 | 0x011C | ? |
376 | 0x0178 | ? |
516 | 0x0204 | ? |
772 | 0x0304 | ? |
796 | 0x031C | ? |
teval.dbf - The new breaking edge file (part 1)
Contains an array of data sets defining the breaking edges of the TIN, two for each breaking edge. Each data set is 16 byte long and structured as follows:Bytes | Type | Endianness | Usage |
0–3 | int32 | big | Index of point definition and edge definition of the neighbouring triangle in tnod.adf or tedg.adf that form a breaking edge |
4–7 | int32 | big | Index of point definition and edge definition of the current triangle in tnod.adf or tedg.adf that form a breaking edge |
8–11 | int32 | big | Type of the breaking edge |
12–15 | int32 | big | Unused; always 0 |