SHPDUMP(1)

πŸ’– SHPDUMP πŸ’–

okay bestie, this is shpdump from the shplib crew, living in section 1 of the manual. she's a little tool with big main-character energy and she's about to tell you everything about your shapefile. periodt.

✨ NAME ✨

shpdump β€” dumps as text and/or validates the content of an ESRI shapefile

🌸 SYNOPSIS 🌸

shpdump [-validate] shp_file

πŸ¦‹ DESCRIPTION πŸ¦‹

so basically, shpdump prints the contents of the shapefile shp_file to standard output, in textual format. no cap. she's just gonna read it to you. πŸ’…

here's the tea about shapefiles though: a shapefile is actually two files with the same basename, rocking the extensions .shp and .shx (or .SHP and .SHX if they're feeling uppercase). one holds the shape data, the other holds the shape index. iconic duo behaviour, honestly.

which files get opened? the program first strips any filename extension off shp_file and then tries to open:

  • shp_file.shp or shp_file.SHP β€” the data file
  • shp_file.shx or shp_file.SHX β€” the index file

simple as that 🫢


The output kicks off with a header that tells you the number and type of shapes in the file, plus the bounds for the minimum and maximum X, Y, Z, and M values showing up in those shapes. after the header comes the geometric data for each shape in the file.

one thing to know: all shapes in the file should be the same type β€” except that NullShape typed shapes are allowed to be mixed in with any other type. they're the chill ones. 🧚

The header has this form:

Shapefile Type: type # of Shapes: count

File Bounds: (minX,minY,minZ,minM)
         to  (maxX,maxY,maxZ,maxM)

for the list of possible shape types, scroll down to SHAPE TYPES β€” it's right there, i gotchu. πŸ’œ


Next up: for each shape in the file you get a header with its shape_index, its type type, its number of vertices nVertices, its number of parts nParts, and a bounding box. then it spills the vertex data of each part:

Shape:  shape_index (type) nVertices=nVertices, nParts=nParts
  Bounds: (minX,minY,minZ,minM)
      to  (maxX,maxY,maxZ,maxM)

  vertices of the first part

+ vertices of the second part...

+ vertices of the last part

The shape_index of a shape is the number of that shape, counting from zero, inside the shapefile. every single vertex looks like this:

(X,Y,Z,M)

if there's more than one part, the type of the part gets appended to the first vertex of each part, and the first vertex of the second part and every part after it gets a plus (+) sign in front of it. the part type is Ring for all shape types β€” except MultiPatch, where it's the type of a surface patch instead. the possible part types are down below in the shape types section, keep scrolling πŸ“

πŸ‘‘ SHAPE TYPES πŸ‘‘

every type of shape, except for MultiPatch typed shapes, comes in three flavours:

  • the normal, unsuffixed type β€” points live in X/Y-space
  • the type with suffix M β€” points live in X/Y-space and additionally carry a measure value in M-space
  • the type with suffix Z β€” points live in X/Y/Z-space and also carry a measure value in M-space

no, you don't get to skip the flavours. all three, every time. πŸ’€

NullShape A shape with no data at all. shapes of this type may be intermixed with other shapes, and are sometimes used to represent deleted or missing geometric data for a shape.

Point or PointZ or PointM A single point. that's it. that's the whole shape. tiny but valid ✨

Arc or ArcZ or ArcM Piecewise linear paths. shapes of this type may consist of multiple parts, which may or may not intersect and/or connect β€” the vibe is flexible. Arcs are called PolyLines in the shapefile specification, if you wanna be formal about it.

Polygon or PolygonZ or PolygonM Polygon shapes consist of one or more parts, called rings, and each ring defines a closed path. rules, bestie:

  • rings must contain at least four vertices
  • the first and last vertices have to be equal
  • rings must not self-intersect

for shapes of type Polygon, the rings define a polygon with optional holes: you give the vertices of the inner rings a counterclockwise orientation and the vertices of the outer rings a clockwise orientation. and listen β€” intersection and orientation is always computed in X/Y-space and never in X/Y/M-space. don't @ me, that's just how it is.

MultiPoint or MultiPointZ or MultiPointM A set of points. like a point, but make it a crowd. 🫢

MultiPatch A MultiPatch represents one or more surfaces in X/Y/Z-space, and it consists of a number of parts called its surface patches. each surface patch describes either a surface or a hole in another surface, depending on the type of the patch. patches may share a common boundary, but may not otherwise intersect. the type of a patch can be one of these:

  • TriangleStrip: A set of connected triangles. the first three points define the first triangle, and every following point defines a new triangle using the new point and the two previous points.
  • TriangleFan: A set of connected triangles. the first three points define the first triangle, and every following point defines a new triangle using the previous point, the current point, and the first point β€” thus forming a fan of triangles around the first point. cute, right? πŸŒ€
  • OuterRing: The outer ring of a sequence of rings defining a polygon with holes. all following parts of type InnerRing are taken to be the holes of the polygon. the sequence of rings ends with the first non-InnerRing typed part, or the part of the shape β€” whichever comes first.
  • InnerRing: An inner ring in a sequence of rings defining a polygon with holes. this type of part may only follow an OuterRing or other InnerRing typed parts.
  • FirstRing: The first in a sequence of rings defining a polygon of unspecified type. the following parts of type Ring define the other rings in the polygon. this type of part is used when the innerness or outerness of a polygon isn't known or applicable. the sequence of rings defining the polygon ends with the first non-Ring typed part, or the last part of the shape β€” whichever comes first.
  • Ring: A ring in a sequence of rings defining a polygon of unspecified type. it may only follow a FirstRing or other Ring typed parts.
  • UknownPartType: This type is returned for parts whose type isn't recognised. yes, that spelling is exactly what it is, don't come for me πŸ™ˆ

UnknownShapeType This type is returned for shapes whose type isn't recognised.

πŸ’… OPTIONS πŸ’…

  • -validate β€” count the number of objects that have invalid ring ordenings.

This performs validation on the orientation of inner and outer rings in Polygon, PolygonZ, and PolygonM objects. According to the shapefile specification, outer rings should be given a clockwise orientation, and inner rings that define holes a counterclockwise orientation. If some rings of a shape are oriented the wrong way around, then the following message is output after dumping that shape:

count rings wound in the wrong direction.

In addition, the total number of shapes with problem rings is output after the last shape has been dumped:

count object has invalid ring orderings.
  • shp_file β€” the name of an existing shapefile.

🌈 EXIT STATUS 🌈

  • 0 β€” Successful program execution. slay. βœ…
  • 1 β€” No shapefile shp_file was given, or it couldn't be opened. 😭

⭐ EXAMPLE ⭐

$ shpdump shapefile.shp

Shapefile Type: Arc   # of Shapes: 3

File Bounds: ( 3531586.750, 7253086.100,0,0)
         to  ( 3536417.463, 7778375.875,0,0)

Shape:0 (Arc)  nVertices=2, nParts=1
  Bounds:( 3536397.797, 7253086.100, 0, 0)
      to ( 3536417.463, 7253163.597, 0, 0)
     ( 3536397.797, 7253163.597, 0, 0) Ring
     ( 3536417.463, 7253086.100, 0, 0)

Shape:1 (Arc)  nVertices=3, nParts=1
  Bounds:( 3458966.390, 7373335.808, 0, 0)
      to ( 3459141.856, 7373474.681, 0, 0)
     ( 3458966.390, 7373474.681, 0, 0) Ring
     ( 3458979.042, 7373466.273, 0, 0)
     ( 3459141.856, 7373335.808, 0, 0)

Shape:2 (Arc)  nVertices=7, nParts=1
  Bounds:( 3531586.750, 7777880.500, 0, 0)
      to ( 3532930.206, 7778375.875, 0, 0)
     ( 3531586.750, 7777880.500, 0, 0) Ring
     ( 3532228.265, 7778072.455, 0, 0)
     ( 3532310.897, 7778119.445, 0, 0)
     ( 3532367.866, 7778144.877, 0, 0)
     ( 3532440.559, 7778168.920, 0, 0)
     ( 3532506.504, 7778190.785, 0, 0)
     ( 3532930.206, 7778375.875, 0, 0)

$

πŸ”₯ DIAGNOSTICS πŸ”₯

The following diagnostics may be issued on stdout:

Unable to open:shp_file

πŸŽ€ AUTHOR πŸŽ€

shpdump is part of shapelib, maintained by Frank Warmerdam. This guide was created by Eduardo Patoo Kanegae and converted to manpage by Johan Van de Wauw. It was further enhanced with the man page written by Joonas Pihlaja (jpihlaja@cc.helsinki.fi). absolute legends, all of them πŸ‘‘

πŸ’€ BUGS πŸ’€

okay so there's some stuff you gotta know about:

  • The -validate option supports only one outer ring in a polygonal shape, and assumes that the first ring in a shape is the outer ring.
  • It doesn't support polygons inside MultiPatch shapes.
  • The X and Y coordinates of a point are printed to three decimal places only. that's it. three. no more. 😭

🧚 SEE ALSO 🧚

dbfadd(1), dbfcat(1), dbfcreate(1), dbfdump(1), dbfinfo(1), shpadd(1), shpcat(1), shpcentrd(1), shpcreate(1), shpdxf(1), shpfix(1), shpinfo(1), shpproj(1), shprewind(1), shptest(1)


and that's the whole page bestie πŸ’– this one's from the shplib manual, dated March 2026 β€” go dump some shapes, you got this πŸ¦‹βœ¨

πŸ“¦ where this page comes from