pgx is a pure Go driver and toolkit for PostgreSQL providing a native high-performance interface with PostgreSQL-specific features plus a database/sql compatibility adapter.
PostgreSQL geometric type support.
import "github.com/jackc/pgx/v5/pgtype"type Vec2 struct {
X float64
Y float64
}
type Point struct {
P Vec2
Valid bool
}
type Box struct {
P [2]Vec2
Valid bool
}
type Circle struct {
P Vec2
R float64
Valid bool
}
type Line struct {
A float64
B float64
C float64
Valid bool
}
type Lseg struct {
P [2]Vec2
Valid bool
}
type Path struct {
P []Vec2
Closed bool
Valid bool
}
type Polygon struct {
P []Vec2
Valid bool
}point := pgtype.Point{
P: pgtype.Vec2{X: 1.5, Y: 2.5},
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO locations (coords) VALUES ($1)", point)
var location pgtype.Point
err = conn.QueryRow(ctx, "SELECT coords FROM locations WHERE id = $1", id).Scan(&location)
fmt.Printf("Location: (%f, %f)
", location.P.X, location.P.Y)box := pgtype.Box{
P: [2]pgtype.Vec2{
{X: 0.0, Y: 0.0}, // lower-left
{X: 10.0, Y: 10.0}, // upper-right
},
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO regions (bounds) VALUES ($1)", box)circle := pgtype.Circle{
P: pgtype.Vec2{X: 5.0, Y: 5.0}, // center
R: 3.0, // radius
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO zones (area) VALUES ($1)", circle)Represents an infinite line: Ax + By + C = 0
line := pgtype.Line{
A: 1.0,
B: -1.0,
C: 0.0,
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO boundaries (line) VALUES ($1)", line)lseg := pgtype.Lseg{
P: [2]pgtype.Vec2{
{X: 0.0, Y: 0.0},
{X: 5.0, Y: 5.0},
},
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO segments (seg) VALUES ($1)", lseg)// Closed path
closedPath := pgtype.Path{
P: []pgtype.Vec2{
{X: 0.0, Y: 0.0},
{X: 1.0, Y: 0.0},
{X: 1.0, Y: 1.0},
{X: 0.0, Y: 1.0},
},
Closed: true,
Valid: true,
}
// Open path
openPath := pgtype.Path{
P: []pgtype.Vec2{
{X: 0.0, Y: 0.0},
{X: 1.0, Y: 1.0},
{X: 2.0, Y: 0.0},
},
Closed: false,
Valid: true,
}polygon := pgtype.Polygon{
P: []pgtype.Vec2{
{X: 0.0, Y: 0.0},
{X: 4.0, Y: 0.0},
{X: 4.0, Y: 4.0},
{X: 0.0, Y: 4.0},
},
Valid: true,
}
_, err := conn.Exec(ctx, "INSERT INTO shapes (poly) VALUES ($1)", polygon)type PointScanner interface { ScanPoint(v Point) error }
type PointValuer interface { PointValue() (Point, error) }
type BoxScanner interface { ScanBox(v Box) error }
type BoxValuer interface { BoxValue() (Box, error) }
type CircleScanner interface { ScanCircle(v Circle) error }
type CircleValuer interface { CircleValue() (Circle, error) }
type LineScanner interface { ScanLine(v Line) error }
type LineValuer interface { LineValue() (Line, error) }
type LsegScanner interface { ScanLseg(v Lseg) error }
type LsegValuer interface { LsegValue() (Lseg, error) }
type PathScanner interface { ScanPath(v Path) error }
type PathValuer interface { PathValue() (Path, error) }
type PolygonScanner interface { ScanPolygon(v Polygon) error }
type PolygonValuer interface { PolygonValue() (Polygon, error) }Implement these for custom geometric types.
PostgreSQL provides many geometric operators and functions. Access them through queries:
// Distance between two points
var distance float64
err := conn.QueryRow(ctx,
"SELECT point '(0,0)' <-> point '(3,4)'").Scan(&distance)
// distance = 5.0
// Check if point is inside circle
var inside bool
err = conn.QueryRow(ctx,
"SELECT point '(1,1)' <@ circle '((0,0),2)'").Scan(&inside)
// Get center of box
var center pgtype.Point
err = conn.QueryRow(ctx,
"SELECT center(box '((0,0),(10,10))')").Scan(¢er)Install with Tessl CLI
npx tessl i tessl/golang-github-com-jackc-pgx-v5@5.8.0