Shapefile index file: GraphViz block diagram (.dot) source

File extension

shx

KS implementation details

License: CC0-1.0

This page hosts a formal specification of Shapefile index file using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

GraphViz block diagram source

shapefile_index.dot

digraph {
	rankdir=LR;
	node [shape=plaintext];
	subgraph cluster__shapefile_index {
		label="ShapefileIndex";
		graph[style=dotted];

		shapefile_index__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
			<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
			<TR><TD PORT="header_pos">0</TD><TD PORT="header_size">100</TD><TD>FileHeader</TD><TD PORT="header_type">header</TD></TR>
			<TR><TD PORT="records_pos">100</TD><TD PORT="records_size">8</TD><TD>Record</TD><TD PORT="records_type">records</TD></TR>
			<TR><TD COLSPAN="4" PORT="records__repeat">repeat to end of stream</TD></TR>
		</TABLE>>];
		subgraph cluster__file_header {
			label="ShapefileIndex::FileHeader";
			graph[style=dotted];

			file_header__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="file_code_pos">0</TD><TD PORT="file_code_size">4</TD><TD>00 00 27 0A</TD><TD PORT="file_code_type">file_code</TD></TR>
				<TR><TD PORT="unused_field_1_pos">4</TD><TD PORT="unused_field_1_size">4</TD><TD>00 00 00 00</TD><TD PORT="unused_field_1_type">unused_field_1</TD></TR>
				<TR><TD PORT="unused_field_2_pos">8</TD><TD PORT="unused_field_2_size">4</TD><TD>00 00 00 00</TD><TD PORT="unused_field_2_type">unused_field_2</TD></TR>
				<TR><TD PORT="unused_field_3_pos">12</TD><TD PORT="unused_field_3_size">4</TD><TD>00 00 00 00</TD><TD PORT="unused_field_3_type">unused_field_3</TD></TR>
				<TR><TD PORT="unused_field_4_pos">16</TD><TD PORT="unused_field_4_size">4</TD><TD>00 00 00 00</TD><TD PORT="unused_field_4_type">unused_field_4</TD></TR>
				<TR><TD PORT="unused_field_5_pos">20</TD><TD PORT="unused_field_5_size">4</TD><TD>00 00 00 00</TD><TD PORT="unused_field_5_type">unused_field_5</TD></TR>
				<TR><TD PORT="file_length_pos">24</TD><TD PORT="file_length_size">4</TD><TD>s4be</TD><TD PORT="file_length_type">file_length</TD></TR>
				<TR><TD PORT="version_pos">28</TD><TD PORT="version_size">4</TD><TD>E8 03 00 00</TD><TD PORT="version_type">version</TD></TR>
				<TR><TD PORT="shape_type_pos">32</TD><TD PORT="shape_type_size">4</TD><TD>s4le→ShapeType</TD><TD PORT="shape_type_type">shape_type</TD></TR>
				<TR><TD PORT="bounding_box_pos">36</TD><TD PORT="bounding_box_size">64</TD><TD>BoundingBoxXYZM</TD><TD PORT="bounding_box_type">bounding_box</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__record {
			label="ShapefileIndex::Record";
			graph[style=dotted];

			record__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="offset_pos">0</TD><TD PORT="offset_size">4</TD><TD>s4be</TD><TD PORT="offset_type">offset</TD></TR>
				<TR><TD PORT="content_length_pos">4</TD><TD PORT="content_length_size">4</TD><TD>s4be</TD><TD PORT="content_length_type">content_length</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__bounding_box_x_y_z_m {
			label="ShapefileIndex::BoundingBoxXYZM";
			graph[style=dotted];

			bounding_box_x_y_z_m__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="x_pos">0</TD><TD PORT="x_size">16</TD><TD>BoundsMinMax</TD><TD PORT="x_type">x</TD></TR>
				<TR><TD PORT="y_pos">16</TD><TD PORT="y_size">16</TD><TD>BoundsMinMax</TD><TD PORT="y_type">y</TD></TR>
				<TR><TD PORT="z_pos">32</TD><TD PORT="z_size">16</TD><TD>BoundsMinMax</TD><TD PORT="z_type">z</TD></TR>
				<TR><TD PORT="m_pos">48</TD><TD PORT="m_size">16</TD><TD>BoundsMinMax</TD><TD PORT="m_type">m</TD></TR>
			</TABLE>>];
		}
		subgraph cluster__bounds_min_max {
			label="ShapefileIndex::BoundsMinMax";
			graph[style=dotted];

			bounds_min_max__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
				<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
				<TR><TD PORT="min_pos">0</TD><TD PORT="min_size">8</TD><TD>f8be</TD><TD PORT="min_type">min</TD></TR>
				<TR><TD PORT="max_pos">8</TD><TD PORT="max_size">8</TD><TD>f8be</TD><TD PORT="max_type">max</TD></TR>
			</TABLE>>];
		}
	}
	shapefile_index__seq:header_type -> file_header__seq [style=bold];
	shapefile_index__seq:records_type -> record__seq [style=bold];
	file_header__seq:bounding_box_type -> bounding_box_x_y_z_m__seq [style=bold];
	bounding_box_x_y_z_m__seq:x_type -> bounds_min_max__seq [style=bold];
	bounding_box_x_y_z_m__seq:y_type -> bounds_min_max__seq [style=bold];
	bounding_box_x_y_z_m__seq:z_type -> bounds_min_max__seq [style=bold];
	bounding_box_x_y_z_m__seq:m_type -> bounds_min_max__seq [style=bold];
}