/geojson

GeoJSON / RFC7946 codec for Golang

Primary LanguageGoMIT LicenseMIT

GeoJSON

GeoJSON codec for Go structs


The library implements a type safe codec for GeoJSON.

Inspiration

GeoJSON is a popular format for encoding a variety of geographic data structures. It defines a standard way to express points, curves, and surfaces in coordinate space together with an application specific metadata about it.

{
  "type": "Feature",
  "id": "[wikipedia:Helsinki]",
  "geometry": {
    "type": "Point",
    "coordinates": [24.9384, 60.1699]
  },
  "properties": {
    "name": "Helsinki"
  }
}

Unfortunately, efficient and type-safe implementation of GeoJSON codec can be challenging:

(i) Pure structs are verbose. The properties is an application specific and it's type is controlled outside of the codec library. Usage of duck type (interface{}) is a common trait used by other GeoJSON Golang libraries. As the results, developers are misses an ability to caught errors at compile time, any mistake becomes visible at run time as a panic. interface{} says nothing..

(ii) Implementing GeoJSON types using generics is requires overly complex type definitions. It can lead to complex type hierarchies, especially in nested GeoJSON structures like FeatureCollection. It suffers from usability for consumers. Specifying types for properties at every level (e.g., Feature or FeatureCollection) adds boilerplate and increases the learning curve.

Key features

The library allows developers to use Golang pure struct to define domain models using a type safe approach of encoding/decoding these models to GeoJSON and back. The library uses type tagging technique to annotate any structure as GeoJSON feature:

type City struct {
  geojson.Feature
  Name      string `json:"name,omitempty"`
}

Getting started

The latest version of the library is available at main branch of this repository. All development, including new features and bug fixes, take place on the main branch using forking and pull requests as described in contribution guidelines. The stable version is available via Golang modules.

The following code snippet demonstrates a typical usage scenario.

import "github.com/fogfish/geojson"

//
// declare any domain type and annotate as a geojson.Feature
type City struct {
  geojson.Feature
  Name      string `json:"name,omitempty"`
}

//
// Each GeoJSON type declares codes using helper functions. 
func (x City) MarshalJSON() ([]byte, error) {
	type tStruct City
	return x.Feature.EncodeGeoJSON(tStruct(x))
}

func (x *City) UnmarshalJSON(b []byte) error {
	type tStruct *City
	return x.Feature.DecodeGeoJSON(b, tStruct(x))
}

//
// Create new instance of the type
city := City{
  Feature: geojson.NewPoint(
    "[wikipedia:Helsinki]",
    geojson.Coord{24.9384, 60.1699},
  ),
  Name: "Helsinki",
}

//
// Use type checks to validate the type of the Geometry 
city.Feature.Geometry.Coords.(*geojson.Point)

Feature Collection

The library supports FeatureCollection object via Golang generic.

seq := geojson.Collection[City]{
	Features: []City{city},
}

How To Contribute

The library is MIT licensed and accepts contributions via GitHub pull requests:

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

The build and testing process requires Go version 1.16 or later.

build and test library.

git clone https://github.com/fogfish/geojson
cd geojson
go test

commit message

The commit message helps us to write a good release note, speed-up review process. The message should address two question what changed and why. The project follows the template defined by chapter Contributing to a Project of Git book.

bugs

If you experience any issues with the library, please let us know via GitHub issues. We appreciate detailed and accurate reports that help us to identity and replicate the issue.

License

See LICENSE