Skip to content

Format mapping ​

How GeoJSON concepts land in the shapefile format, and back.

Geometry types ​

GeoJSONShapefileNotes
PointPoint
MultiPointMultipoint
LineStringPolylineOne part
MultiLineStringPolylineSeveral parts
PolygonPolygonExterior ring plus holes
MultiPolygonPolygonAll rings flattened into one record
GeometryCollection—Not representable; rejected

Reading back, single-part geometry returns the simple type: a one-part Polyline becomes a LineString, not a one-element MultiLineString.

Mixing types ​

A shapefile holds exactly one geometry type.

InputResult
Point + MultiPointPromoted to Multipoint
LineString + MultiLineStringBoth are Polyline already
Polygon + MultiPolygonBoth are Polygon already
Anything else mixedError naming the feature index

Dimensions ​

CoordinateDetectedShape type
[x, y]xyPoint, Polyline, …
[x, y, z]xyzPointZ, PolylineZ, …
[x, y, z, m]xyzmPointZ with measures

Detection uses the richest coordinate anywhere in the input. Override with dimensions; 'xym' reads the third ordinate as a measure instead of Z.

Reading back, Z is emitted as a third ordinate. M is dropped unless includeM: true, because GeoJSON has no concept of measures.

Attribute types ​

Writing:

Property valuesdBase column
Numbers onlynumeric, width and decimals measured from the data
Booleans onlylogical
Strings onlycharacter, width = longest value
Objects or arrayscharacter, JSON-encoded
Mixed typescharacter
All nullcharacter, width 1
No properties at allA synthetic FID numeric column

Reading:

dBase columnJSON value
characterstring, trimmed; null when empty
numeric, float, double, currencynumber, or null
logicalboolean, or null
integernumber
datestring, "YYYY-MM-DD"
datetimestring, ISO 8601
memostring

Field names ​

dBase caps names at 11 bytes and expects a leading letter.

PropertyColumnWhy
namenameFits
population_densitypopulatio_2Truncated, then de-duplicated
2020_popF2020_popPrefixed — cannot start with a digit
my property!my_propertNon-alphanumerics replaced, then truncated

The full mapping is in parts.fields.

Encoding ​

The .dbf is always written as UTF-8, with a .cpg saying so. On read, the .cpg decides, falling back to UTF-8; legacy single-byte code pages are supported.

Ring winding ​

FormatExteriorHoles
ShapefileClockwiseCounter-clockwise
GeoJSON (RFC 7946)Counter-clockwiseClockwise

Converted automatically in both directions. Rings are closed if they are not.

Record alignment ​

The .shp and .dbf are matched by position — record n of one belongs to record n of the other. Nothing links them by id.

That is why features with null geometry are skipped entirely rather than written as an attribute row with no shape: one such row would shift every subsequent pairing.

Released under the MIT License.