Class ShapefileGeometryReader
- All Implemented Interfaces:
Closeable,AutoCloseable
.shp) files.
File structure
A .shp file consists of:
- A 100-byte file header (mixed endianness — see below).
- A sequence of variable-length geometry records, each preceded by an 8-byte big-endian record header.
Endianness quirk
The ESRI specification uses big-endian integers in the file
header (file code, file length) and in each record header (record number,
content length), but little-endian integers and doubles everywhere
else. This reader handles both transparently using ByteBuffer.order().
Supported shape types
| Type value | Name | Used for |
|---|---|---|
| 0 | Null Shape | Returned with empty geometry |
| 1 | Point | City / populated-place data |
| 3 | PolyLine | Road, river, and boundary data |
| 5 | Polygon | Country boundary data |
| 8 | MultiPoint | Multi-point city data |
Unsupported types, including Z/M variants, cause an
IOException.
Polygon ring handling
ESRI Polygons store all rings (outer shells and interior holes) in a
flat Parts array. The winding order distinguishes shells (clockwise
in the ESRI convention, which is counter-clockwise in geographic north-up
orientation) from holes (opposite winding). This reader returns all
rings without filtering holes so that the country renderer — which
simply fills every ring — produces correct results for filled rendering.
Callers that need topologically correct hole handling can use
isClockwise(List) to classify rings.
Coordinate output
All returned coordinates are in the source file's native units. For
Natural Earth data this is decimal degrees (WGS84). Callers must convert
to radians and wrap longitude before passing to IMapProjection.
Usage
try (ShapefileGeometryReader shp = new ShapefileGeometryReader(path)) {
ShapefileGeometryReader.ShapeRecord record;
while ((record = shp.nextRecord()) != null) {
int type = record.shapeType();
if (type == ShapefileGeometryReader.TYPE_POLYGON) {
for (List<Point2D.Double> ring : record.rings()) {
// process ring
}
}
}
}
Thread safety
Instances are not thread-safe. Each calling thread should open its own reader.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordImmutable container for the geometry data of a single shapefile record. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intShape type: a set of points.static final intShape type: no geometry present.static final intShape type: a single (X, Y) point.static final intShape type: one or more rings forming a polygon.static final intShape type: an ordered set of vertices forming connected line segments. -
Constructor Summary
ConstructorsConstructorDescriptionShapefileGeometryReader(Path path) Opens the.shpfile at the given path and validates the file header. -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()intReturns the shape type declared in the file header.static booleanisClockwise(List<Point2D.Double> ring) Tests whether a polygon ring is oriented clockwise in the ESRI convention (which uses a screen-space y-axis pointing downward).Reads and returns the next geometry record from the file, ornullwhen the end of the file is reached.Reads all records from the file sequentially and returns them as an unmodifiable list.
-
Field Details
-
TYPE_NULL
public static final int TYPE_NULLShape type: no geometry present. Records of this type are skipped.- See Also:
-
TYPE_POINT
public static final int TYPE_POINTShape type: a single (X, Y) point.- See Also:
-
TYPE_POLYLINE
public static final int TYPE_POLYLINEShape type: an ordered set of vertices forming connected line segments.- See Also:
-
TYPE_POLYGON
public static final int TYPE_POLYGONShape type: one or more rings forming a polygon.- See Also:
-
TYPE_MULTIPOINT
public static final int TYPE_MULTIPOINTShape type: a set of points.- See Also:
-
-
Constructor Details
-
ShapefileGeometryReader
Opens the.shpfile at the given path and validates the file header.- Parameters:
path- path to the.shpfile; must not benull- Throws:
IOException- if the file cannot be opened, the file code is wrong, or the version is unsupported
-
-
Method Details
-
getFileShapeType
public int getFileShapeType()Returns the shape type declared in the file header.All records in a well-formed shapefile have this shape type (or
TYPE_NULL). Use theTYPE_*constants to identify the type.- Returns:
- file-level shape type
-
nextRecord
Reads and returns the next geometry record from the file, ornullwhen the end of the file is reached.Null-shape records (
TYPE_NULL) are returned with empty point and ring lists. Retaining the record is essential because shapefile geometry and DBF attributes are paired by record position.The returned
ShapefileGeometryReader.ShapeRecordcontains:- The record's one-based
ShapefileGeometryReader.ShapeRecord.recordNumber(). - The
ShapefileGeometryReader.ShapeRecord.shapeType()for this record. - For
TYPE_POINT: a single-elementShapefileGeometryReader.ShapeRecord.points()list. - For
TYPE_POLYGONandTYPE_POLYLINE: aShapefileGeometryReader.ShapeRecord.rings()list of ring/part coordinate lists. - For
TYPE_MULTIPOINT: a flatShapefileGeometryReader.ShapeRecord.points()list.
- Returns:
- the next record, or
nullat end of file - Throws:
IOException- if a read error occurs or the record contains an unrecognized shape type
- The record's one-based
-
readAllRecords
Reads all records from the file sequentially and returns them as an unmodifiable list.This is a convenience method that repeatedly calls
nextRecord()untilnullis returned. The channel is not rewound before reading — callers that need a fresh read should close and reopen the reader.- Returns:
- unmodifiable list of all geometry records, including null shapes
- Throws:
IOException- if any read error occurs
-
close
- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Throws:
IOException
-
isClockwise
Tests whether a polygon ring is oriented clockwise in the ESRI convention (which uses a screen-space y-axis pointing downward).Uses the shoelace formula: a positive signed area indicates clockwise orientation in ESRI coordinates (outer shells are clockwise; holes are counter-clockwise).
Note that geographic coordinates have the y-axis pointing upward, so the convention is inverted relative to screen space. For Natural Earth data this distinction rarely matters because the renderer fills all rings regardless of winding order.
- Parameters:
ring- list of (longitude, latitude) points forming a closed ring- Returns:
trueif the ring is clockwise in ESRI screen convention
-