Skip to content

pchchv/geo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

612 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

geo CI Go Report Card Go Reference

Package geo defines a set of types for working with 2D geo and planar/projected geometric data in Golang.

Features

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

Types

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 types as slices allows them to be accessed idiomatically using Go's built-in functions such as make, append, len.
And also by using slice designators such as [s:e] e.g.:

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

Shared Geometry interface

All of the base types implement the geo.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, e. g.:

l := clip.Geometry(bound, geom)

will use the appropriate clipping algorithm depending on if the input is 1d or 2d, e.g. a geo.LineString or a geo.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 := geo.Point{-72.796408, -45.407131}
    p2 := geo.Point{-72.688541, -45.384987}
    
    geo.Distance(p1, p2)
  • Compute the planar area and centroid of a polygon:

    poly := geo.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   geo.Geometry `json:"geometry"`
    Properties Properties   `json:"properties"`
}

Defining geometry as the geo.Geometry interface, along with the subpackage functions of the accepting geometries, allows them to work together to create usable 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)
}

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

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)

// Simplifier the geometry now that it's in tile coordinate space.
layers.Simplifier(simplifier.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(geo.Point{1, 2}, 4326),
)

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

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

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

List of subpackage utilities

  • clip - clipping geometry to a bounding box
  • encoding/mvt - encoded and decoding from Mapbox Vector Tiles
  • encoding/ewkb - extended well-known binary format that includes the SRID
  • encoding/wkb - well-known binary as well as helpers to decode from the database queries
  • encoding/wkt - well-known text encoding
  • geojson - working with geojson and the types in this package
  • geometries - defines common 2d geometries
  • maptile - working with mercator map tiles and quadkeys
  • planar - area and distance calculations
  • 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
  • simplifier - linear geometry simplifications like Douglas-Peucker
  • tilecover - computes the covering set of tiles

About

Package defining a set of types for working with 2D geo and planar/projected geometric data in Golang

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages