go-shapefile
is a Go parser for the "shapefile" GIS file format. The package can be used to read shapefiles, and optionally convert them into GeoJSON "features" (supported by go-geojson
) - allowing a shapefile to be written directly to databases such as PostGIS, MongoDB, or Couchbase, etc.
The package does not currently support writing of files.
How you choose to use this package will depend on your use case. go-shapefile
supports reading the shapefiles in the following forms:
- .zip file containing mandatory .shp and .dbf files, with optional .cpg file
- Unzipped .shp and .dbf files, with optional character encoding
- .shp and .dbf files separately, with optional character encoding
Reading a zipped shapefile is achieved by using the ZipScanner
. The example below shows a basic example of this, where error handling has been omitted for brevity.
file, err := os.Open("path/to/ne_110m_admin_0_sovereignty.zip")
stat, err := r.Stat()
// Create new ZipScanner
// The filename can be replaced with an empty string if you don't want to check filenames inside the zip file
scanner := shapefile.NewZipScanner(file, stat.Size(), "ne_110m_admin_0_sovereignty.zip")
// Optionally get file info: shape type, number of records, bounding box, etc.
info, err := scanner.Info()
fmt.Println(info)
// Start the scanner
err = scanner.Scan()
// Call Record() to get each record in turn, until either the end of the file, or an error occurs
for {
record := scanner.Record()
if record == nil {
break
}
// Each record contains a shape (from .shp file) and attributes (from .dbf file)
fmt.Println(record)
}
// Err() returns the first error encountered during calls to Record()
err = scanner.Err()
Using the example above, we can optionally convert shapefile records to GeoJSON features. go-shapefile
achieves this by using go-geojson
, meaning that you can use the standard json.Marshal
to produce a JSON object that can be understood by any software that can work with the GeoJSON standard.
record := scanner.Record()
feature := record.GeoJSONFeature()
jsonData, err := json.Marshal(feature)
fmt.Println(string(jsonData))
This package has been primarily developed to work with Natural Earth, so may only contain the subset of shapefile features relevant to those data files. The "shapefile" format is actually a collection of files, of which this package currently supports the "shape" (.shp), "attribute" (.dbf) and character encoding (.cpg) files.
The .shp file contains the geometry data in the form of variable-length records. A single record represents a particular shape type, although the records in a single file must all represent the same type. go-shapefile
supports the following types:
Shape type | Supported |
---|---|
Point | ✔️ |
Polyline | ✔️ |
Polygon | ✔️ |
MultiPoint | ❌ |
PointZ | ❌ |
PolylineZ | ❌ |
PolygonZ | ❌ |
MultiPointZ | ❌ |
PointM | ❌ |
PolylineM | ❌ |
PolygonM | ❌ |
MultiPointM | ❌ |
MultiPatch | ❌ |
Format specification: https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf.
The .dbf file contains attributes for each shape in the .shp file. Attributes are stored in the form of records, which consist of a number of fields. Field names and values are not standardized - they are specified as part of the .dbf file to suit the particular use case.
This file uses a format called "dBase", of which there are several variations in varying degrees of usage. The most common are dBase IV and dBase V, but go-shapefile
currently only supports IV. Below is an overview of the supported field types:
Field type | Supported |
---|---|
Character/string | ✔️ |
Numeric | ✔️ |
Date | ✔️ |
Floating point | ✔️ |
Logical | ❌ |
Memo | ❌ |
Note that dBase V contains many more field types.
The .cpg file is optional and contains the character encoding used inside the .dbf file. By default, and in this file's absense, the character encoding is assumed to be ASCII, but this file can be used to support Unicode strings. go-shapefile
supports the encoding labels defined by https://encoding.spec.whatwg.org/#names-and-labels.