PostGIS geometry type support for pgx v5 through orb
A Go library that seamlessly integrates PostGIS geometry types with github.com/jackc/pgx/v5 using the github.com/paulmach/orb geometry library. This package provides a codec for encoding and decoding PostGIS geometries directly to and from orb types.
- Features
- Installation
- Usage
- Technology Stack
- Project Structure
- Development
- Testing
- License
- Author
- Contributing
- FAQ
- Full PostGIS geometry support via orb types (Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection)
- Binary and text format support for optimal performance
- EWKB encoding/decoding with SRID support
- Type-safe codec implementation using pgx v5's type system
- Zero-copy decoding where possible
- Easy registration with both single connections and connection pools
- Comprehensive test coverage with testcontainers for integration testing
go get github.com/moeryomenko/pgxorbRequirements:
- Go 1.24.4 or higher
- PostgreSQL with PostGIS extension
- github.com/jackc/pgx/v5 v5.7.5+
- github.com/paulmach/orb v0.11.1+
package main
import (
"context"
"log"
"os"
"github.com/jackc/pgx/v5"
"github.com/moeryomenko/pgxorb"
"github.com/paulmach/orb"
)
func main() {
ctx := context.Background()
connectionStr := os.Getenv("DATABASE_URL")
conn, err := pgx.Connect(ctx, connectionStr)
if err != nil {
log.Fatal(err)
}
defer conn.Close(ctx)
// Register pgxorb codec for PostGIS geometry types
if err := pgxorb.Register(ctx, conn); err != nil {
log.Fatal(err)
}
// Now you can use orb types directly
point := orb.Point{1.5, 2.5}
var result orb.Point
err = conn.QueryRow(ctx, "SELECT $1::geometry", point).Scan(&result)
if err != nil {
log.Fatal(err)
}
log.Printf("Point: %v\n", result)
}package main
import (
"context"
"log"
"os"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/moeryomenko/pgxorb"
)
func main() {
ctx := context.Background()
connectionStr := os.Getenv("DATABASE_URL")
config, err := pgxpool.ParseConfig(connectionStr)
if err != nil {
log.Fatal(err)
}
// Register codec on each new connection
config.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
return pgxorb.Register(ctx, conn)
}
pool, err := pgxpool.NewWithConfig(ctx, config)
if err != nil {
log.Fatal(err)
}
defer pool.Close()
// Use the pool normally
// ...
}package main
import (
"context"
"fmt"
"log"
"github.com/jackc/pgx/v5"
"github.com/moeryomenko/pgxorb"
"github.com/paulmach/orb"
)
type Location struct {
ID int
Name string
Position orb.Point
}
func main() {
ctx := context.Background()
conn, err := pgx.Connect(ctx, "postgres://user:pass@localhost/dbname")
if err != nil {
log.Fatal(err)
}
defer conn.Close(ctx)
if err := pgxorb.Register(ctx, conn); err != nil {
log.Fatal(err)
}
// Create table with geometry column
_, err = conn.Exec(ctx, `
CREATE TABLE IF NOT EXISTS locations (
id SERIAL PRIMARY KEY,
name TEXT,
position GEOMETRY(POINT, 4326)
)
`)
if err != nil {
log.Fatal(err)
}
// Insert location with orb.Point
location := Location{
Name: "Tokyo Tower",
Position: orb.Point{139.7454, 35.6586},
}
err = conn.QueryRow(ctx, `
INSERT INTO locations (name, position)
VALUES ($1, ST_SetSRID($2::geometry, 4326))
RETURNING id
`, location.Name, location.Position).Scan(&location.ID)
if err != nil {
log.Fatal(err)
}
// Query location
var result Location
err = conn.QueryRow(ctx, `
SELECT id, name, position
FROM locations
WHERE id = $1
`, location.ID).Scan(&result.ID, &result.Name, &result.Position)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Location: %s at %v\n", result.Name, result.Position)
}Core Dependencies:
- Language: Go 1.24.4
- Database Driver: pgx v5 v5.7.5 - High-performance PostgreSQL driver
- Geometry Library: orb v0.11.1 - 2D geometry types and utilities
- PostGIS: PostGIS extension for spatial operations
Development & Testing:
- Testing: testcontainers-go v0.37.0 - Integration testing with Docker containers
- Test Comparison: go-cmp v0.7.0 - Deep equality testing
- Linting: golangci-lint (configured via
.golangci.yml)
Build Tools:
Makefilefor common development tasksgo.workfor multi-module workspace support
pgxorb/
βββ geom.go # Core geometry codec implementation (EWKB encoding/decoding)
βββ geom_test.go # Comprehensive integration tests with PostGIS
βββ pgxorb.go # Public API (Register function)
βββ go.mod # Go module dependencies
βββ go.sum # Dependency checksums
βββ go.work # Go workspace configuration
βββ go.work.sum # Workspace checksums
βββ Makefile # Development commands (test, lint, cover, mod)
βββ .golangci.yml # Linter configuration
βββ .gitignore # Git ignore rules
βββ LICENSE-MIT # MIT License
βββ LICENSE-APACHE # Apache 2.0 License
βββ README.md # This file
βββ tools/ # Development tools directory
βββ go.mod
βββ go.sum
Key Files:
geom.go- Implements the pgx codec interface for PostGIS geometry types, handling both binary (EWKB) and text format encoding/decodingpgxorb.go- Main entry point providing theRegister()function to register the codec with a pgx connectiongeom_test.go- Integration tests using testcontainers to spin up a PostGIS database for testing
The project uses a Makefile for common development tasks:
# Run tests with coverage
make test
# Run tests with race detector
RACE_DETECTOR=1 make test
# View coverage in browser
make cover
# Run linter
make lint
# Tidy dependencies
make mod
# Show all available commands
make helpTests use testcontainers-go to automatically spin up a PostGIS-enabled PostgreSQL container:
# Run all tests
go test ./...
# Run with race detector
go test -race ./...
# Run with coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.outThe test suite covers:
- Null value handling
- Binary and text format encoding/decoding
- All orb geometry types (Point, LineString, Polygon, etc.)
- SRID support via PostGIS functions
This project is dual-licensed under:
You may choose either license for your use of this software.
Maxim Eryomenko
- GitHub: @moeryomenko
- Email: [email protected]
Contributions are welcome! Please feel free to submit a Pull Request.
Guidelines:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run tests and linter (
make test lint) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
pgxorb is specifically designed for pgx v5 (the recommended PostgreSQL driver for Go) and uses the popular orb geometry library, providing a modern, type-safe, and performant solution with zero external C dependencies.
All PostGIS geometry types through orb: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection.
Yes, SRID is preserved during encoding/decoding through EWKB format. Use PostGIS functions like ST_SetSRID() to set SRID values.
Yes, the library includes comprehensive test coverage with integration tests against a real PostGIS database. It follows pgx v5's type system best practices.
No, pgxorb is designed specifically for pgx v5's new type system. For pgx v4, consider other libraries like github.com/cridenour/go-postgis.
If you find PgxOrb useful, please consider giving it a βοΈ!
Made with β€οΈ by Maxim Eryomenko