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.
- Simple types - allow for natural operations using the
make,append,len,[s:e]builtins. - GeoJSON - support as part of the
geojsonsub-package. - Mapbox Vector Tile - encoding and decoding as part of the
encoding/mvtsub-package. - Direct to type from DB query results - by scanning WKB data directly into types.
- Rich set of sub-packages - including
clipping,simplifying,quadtreeand more.
typePoint [2]float64typeMultiPoint []PointtypeLineString []PointtypeMultiLineString []LineStringtypeRingLineStringtypePolygon []RingtypeMultiPolygon []PolygontypeCollection []GeometrytypeBoundstruct { Min, MaxPoint }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]All of the base types implement the orb.Geometry interface defined as:
typeGeometryinterface {
GeoJSONType() stringDimensions() int// e.g. 0d, 1d, 2dBound() 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)
The geojson sub-package implements Marshalling and Unmarshalling of GeoJSON data. Features are defined as:
typeFeaturestruct {
IDany`json:"id,omitempty"`Typestring`json:"type"`Geometry orb.Geometry`json:"geometry"`PropertiesProperties`json:"properties"`
}
// or a generic version with user defined properties type:typeFeatureOf[P] struct {
IDany`json:"id,omitempty"`Typestring`json:"type"`Geometry orb.Geometry`json:"geometry"`PropertiesP`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:=rangefc {
f.Geometry=clip.Geometry(bound, f.Geometry)
}An example using generic properties:
typeMyPropertiesstruct {
Namestring`json:"name"`Ageint`json:"age"`
}
fc:= geojson.FeatureCollectionOf[MyProperties]{}
err:=json.Unmarshal(rawJSON, &fc)
fc.Features[0].Properties.Name// == "Alice"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.
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 transferred gzip compressed. In that case:data, err:=mvt.MarshalGzipped(layers)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")
varp orb.Pointerr:=row.Scan(ewkb.Scanner(&p))For more information see the readme in the encoding/ewkb package.
clip- clipping geometry to a bounding boxencoding/mvt- encoded and decoding from Mapbox Vector Tilesencoding/wkb- well-known binary as well as helpers to decode from the database queriesencoding/ewkb- extended well-known binary format that includes the SRIDencoding/wkt- well-known text encodinggeo- algorithms for WGS84 geometrygeojson- working with geojson and the types in this packagemaptile- working with mercator map tiles and quadkeysplanar- algorithms for planar geometryproject- project geometries between geo and planar contextsquadtree- quadtree implementation using the types in this packageresample- resample points in a line string geometrysimplify- linear geometry simplifications like Douglas-Peucker