Categorygithub.com/paulmach/orb
modulepackage
0.11.1
Repository: https://github.com/paulmach/orb.git
Documentation: pkg.go.dev

# README

orb CI codecov Go Report Card Go Reference

Package orb defines a set of types for working with 2d geo and planar/projected geometric data in Golang. There are a set of sub-packages that use these types to do interesting things. They each provide their own README with extra info.

Interesting features

  • Simple types - allow for natural operations using the make, append, len, [s:e] builtins.
  • GeoJSON - support as part of the geojson sub-package.
  • Mapbox Vector Tile - encoding and decoding as part of the encoding/mvt sub-package.
  • Direct to type from DB query results - by scanning WKB data directly into types.
  • Rich set of sub-packages - including clipping, simplifing, quadtree and more.

Type definitions

type Point [2]float64
type MultiPoint []Point

type LineString []Point
type MultiLineString []LineString

type Ring LineString
type Polygon []Ring
type MultiPolygon []Polygon

type Collection []Geometry

type Bound struct { Min, Max Point }

Defining the types as slices allows them to be accessed in an idiomatic way using Go's built-in functions such at make, append, len and with slice notation like [s:e]. For example:

ls := make(orb.LineString, 0, 100)
ls = append(ls, orb.Point{1, 1})
point := ls[0]

Shared Geometry interface

All of the base types implement the orb.Geometry interface defined as:

type Geometry interface {
    GeoJSONType() string
    Dimensions() int // e.g. 0d, 1d, 2d
    Bound() Bound
}

This interface is accepted by functions in the sub-packages which then act on the base types correctly. For example:

l := clip.Geometry(bound, geom)

will use the appropriate clipping algorithm depending on if the input is 1d or 2d, e.g. a orb.LineString or a orb.Polygon.

Only a few methods are defined directly on these type, for example Clone, Equal, GeoJSONType. Other operation that depend on geo vs. planar contexts are defined in the respective sub-package. For example:

  • Computing the geo distance between two point:

    p1 := orb.Point{-72.796408, -45.407131}
    p2 := orb.Point{-72.688541, -45.384987}
    
    geo.Distance(p1, p2)
    
  • Compute the planar area and centroid of a polygon:

    poly := orb.Polygon{...}
    centroid, area := planar.CentroidArea(poly)
    

GeoJSON

The geojson sub-package implements Marshalling and Unmarshalling of GeoJSON data. Features are defined as:

type Feature struct {
    ID         interface{}  `json:"id,omitempty"`
    Type       string       `json:"type"`
    Geometry   orb.Geometry `json:"geometry"`
    Properties Properties   `json:"properties"`
}

Defining the geometry as an orb.Geometry interface along with sub-package functions accepting geometries allows them to work together to create easy to follow code. For example, clipping all the geometries in a collection:

fc, err := geojson.UnmarshalFeatureCollection(data)
for _, f := range fc {
    f.Geometry = clip.Geometry(bound, f.Geometry)
}

The library supports third party "encoding/json" replacements such github.com/json-iterator/go. See the geojson readme for more details.

The types also support BSON so they can be used directly when working with MongoDB.

Mapbox Vector Tiles

The encoding/mvt sub-package implements Marshalling and Unmarshalling MVT data. This package uses sets of geojson.FeatureCollection to define the layers, keyed by the layer name. For example:

collections := map[string]*geojson.FeatureCollection{}

// Convert to a layers object and project to tile coordinates.
layers := mvt.NewLayers(collections)
layers.ProjectToTile(maptile.New(x, y, z))

// In order to be used as source for MapboxGL geometries need to be clipped
// to max allowed extent. (uncomment next line)
// layers.Clip(mvt.MapboxGLDefaultExtentBound)

// Simplify the geometry now that it's in tile coordinate space.
layers.Simplify(simplify.DouglasPeucker(1.0))

// Depending on use-case remove empty geometry, those too small to be
// represented in this tile space.
// In this case lines shorter than 1, and areas smaller than 2.
layers.RemoveEmpty(1.0, 2.0)

// encoding using the Mapbox Vector Tile protobuf encoding.
data, err := mvt.Marshal(layers) // this data is NOT gzipped.

// Sometimes MVT data is stored and transfered gzip compressed. In that case:
data, err := mvt.MarshalGzipped(layers)

Decoding WKB/EWKB from a database query

Geometries are usually returned from databases in WKB or EWKB format. The encoding/ewkb sub-package offers helpers to "scan" the data into the base types directly. For example:

db.Exec(
  "INSERT INTO postgis_table (point_column) VALUES (ST_GeomFromEWKB(?))",
  ewkb.Value(orb.Point{1, 2}, 4326),
)

row := db.QueryRow("SELECT ST_AsBinary(point_column) FROM postgis_table")

var p orb.Point
err := row.Scan(ewkb.Scanner(&p))

For more information see the readme in the encoding/ewkb package.

List of sub-package utilities

  • clip - clipping geometry to a bounding box
  • encoding/mvt - encoded and decoding from Mapbox Vector Tiles
  • encoding/wkb - well-known binary as well as helpers to decode from the database queries
  • encoding/ewkb - extended well-known binary format that includes the SRID
  • encoding/wkt - well-known text encoding
  • geojson - working with geojson and the types in this package
  • maptile - working with mercator map tiles and quadkeys
  • project - project geometries between geo and planar contexts
  • quadtree - quadtree implementation using the types in this package
  • resample - resample points in a line string geometry
  • simplify - linear geometry simplifications like Douglas-Peucker

# Packages

Package clip is a library for clipping geometry to a bounding box.
Package geo computes properties on geometries assuming they are lon/lat data.
Package geojson is a library for encoding and decoding GeoJSON into Go structs using the geometries in the orb package.
Package maptile defines a Tile type and methods to work with web map projected tile data.
Package planar computes properties on geometries assuming they are in 2d euclidean space.
Package project defines projections to and from Mercator and WGS84 along with helpers to apply them to orb geometry types.
Package quadtree implements a quadtree using rectangular partitions.
Package resample has a couple functions for resampling line geometry into more or less evenly spaces points.
Package simplify implements several reducing/simplifying functions for `orb.Geometry` types.

# Functions

Clone will make a deep copy of the geometry.
Equal returns if the two geometrires are equal.
Round will round all the coordinates of the geometry to the given factor.

# Constants

CCW stands for Counter Clock Wise.
CW stands for Clock Wise.
meters.

# Variables

AllGeometries lists all possible types and values that a geometry interface can be.
6 decimal places.

# Structs

A Bound represents a closed box or rectangle.

# Interfaces

Geometry is an interface that represents the shared attributes of a geometry.
Pointer is something that can be represented by a point.
A Simplifier is something that can simplify geometry.

# Type aliases

A Collection is a collection of geometries that is also a Geometry.
A DistanceFunc is a function that computes the distance between two points.
LineString represents a set of points to be thought of as a polyline.
MultiLineString is a set of polylines.
A MultiPoint represents a set of points in the 2D Eucledian or Cartesian plane.
MultiPolygon is a set of polygons.
Orientation defines the order of the points in a polygon or closed ring.
A Point is a Lon/Lat 2d point.
Polygon is a closed area.
A Projection a function that moves a point from one space to another.
Ring represents a set of ring on the earth.