GoGIS is a comprehensive Go library that provides PostGIS geometry types for GORM, enabling seamless integration of spatial data with your Go applications.
β¨ Complete PostGIS Integration - Full support for Point, LineString, Polygon, and GeometryCollection types
π GORM Compatible - Implements sql.Scanner and driver.Valuer for automatic ORM integration
πΊοΈ WGS 84 Support - Uses SRID 4326 coordinate system for global geographic data
π Well-Known Formats - Supports both WKB (Well-Known Binary) and WKT (Well-Known Text)
β‘ High Performance - Optimized for spatial queries with proper indexing support
π§ͺ Thoroughly Tested - Comprehensive test suite with >95% coverage
π Well Documented - Complete API documentation and usage examples
go get github.com/restayway/gogis- Go 1.19+
- PostgreSQL 12+ with PostGIS 3.0+
- GORM v2
Enable PostGIS extension in your PostgreSQL database:
CREATE EXTENSION IF NOT EXISTS postgis;package main import ( "github.com/restayway/gogis" "gorm.io/driver/postgres" "gorm.io/gorm" ) type Location struct { ID uint `gorm:"primaryKey"` Name string `gorm:"not null"` Point gogis.Point `gorm:"type:geometry(Point,4326)"` } func main() { // Connect to database db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } // Auto-migrate db.AutoMigrate(&Location{}) // Create location location := Location{ Name: "Statue of Liberty", Point: gogis.Point{ Lng: -74.0445, // Longitude Lat: 40.6892, // Latitude }, } db.Create(&location) // Spatial query - find locations within 1km var nearby []Location db.Where("ST_DWithin(point, ST_Point(?, ?), ?)", -74.0445, 40.6892, 0.009).Find(&nearby) }Represents a single location with longitude and latitude coordinates.
type Location struct { ID uint `gorm:"primaryKey"` Name string Point gogis.Point `gorm:"type:geometry(Point,4326)"` } location := Location{ Name: "Central Park", Point: gogis.Point{ Lng: -73.9665, // Longitude (X) Lat: 40.7812, // Latitude (Y) }, }Represents paths, routes, or any sequence of connected points.
type Route struct { ID uint `gorm:"primaryKey"` Name string Path gogis.LineString `gorm:"type:geometry(LineString,4326)"` } route := Route{ Name: "Broadway Walk", Path: gogis.LineString{ Points: []gogis.Point{ {Lng: -73.9857, Lat: 40.7580}, // Times Square {Lng: -73.9857, Lat: 40.7614}, // North on Broadway {Lng: -73.9855, Lat: 40.7682}, // Further north }, }, }Represents areas with outer boundaries and optional holes.
type Region struct { ID uint `gorm:"primaryKey"` Name string Area gogis.Polygon `gorm:"type:geometry(Polygon,4326)"` } region := Region{ Name: "Central Park", Area: gogis.Polygon{ Rings: [][]gogis.Point{ { // Outer boundary {Lng: -73.9812, Lat: 40.7644}, {Lng: -73.9734, Lat: 40.7644}, {Lng: -73.9734, Lat: 40.7947}, {Lng: -73.9812, Lat: 40.7947}, {Lng: -73.9812, Lat: 40.7644}, // Close the ring }, // Optional: holes can be added as additional rings }, }, }Represents collections of heterogeneous geometries.
type Place struct { ID uint `gorm:"primaryKey"` Name string Geometries gogis.GeometryCollection `gorm:"type:geometry(GeometryCollection,4326)"` } place := Place{ Name: "Campus", Geometries: gogis.GeometryCollection{ Geometries: []gogis.Geometry{ &gogis.Point{Lng: -73.9550, Lat: 40.8050}, // Building &gogis.LineString{Points: walkwayPoints}, // Walkway &gogis.Polygon{Rings: campusAreaRings}, // Campus area }, }, }// Find locations within 1km of a point var locations []Location db.Where("ST_DWithin(point, ST_Point(?, ?), ?)", lng, lat, 0.009).Find(&locations) // Find nearest 10 locations db.Order("ST_Distance(point, ST_Point(?, ?))"). Limit(10).Find(&locations, lng, lat)// Find points within a polygon var pointsInside []Location db.Where("ST_Contains(?, point)", polygon.String()).Find(&pointsInside) // Find polygons containing a point var regions []Region db.Where("ST_Contains(area, ST_Point(?, ?))", lng, lat).Find(®ions)// Find routes that intersect with an area var routes []Route db.Where("ST_Intersects(path, ?)", polygon.String()).Find(&routes) // Find overlapping regions var overlapping []Region db.Where("ST_Overlaps(area, ?)", otherPolygon.String()).Find(&overlapping)// Calculate polygon areas in square meters db.Select("*, ST_Area(ST_Transform(area, 3857)) as area_meters").Find(®ions) // Calculate route lengths in meters db.Select("*, ST_Length(ST_Transform(path, 3857)) as length_meters").Find(&routes)Create spatial indexes for optimal query performance:
-- For points CREATE INDEX idx_locations_point ON locations USING GIST (point); -- For linestrings CREATE INDEX idx_routes_path ON routes USING GIST (path); -- For polygons CREATE INDEX idx_regions_area ON regions USING GIST (area); -- For geometry collections CREATE INDEX idx_places_geometries ON places USING GIST (geometries);- Use ST_DWithin instead of ST_Distance with WHERE clauses
- Create compound indexes for frequently filtered queries
- Use ST_Transform for accurate distance/area calculations
- Consider partial indexes for large datasets
See INDEXING.md for detailed performance optimization guide.
Comprehensive examples are available in the examples/ directory:
- basic_usage/ - Point operations and spatial queries
- linestring_example/ - Routes and path analysis
- polygon_example/ - Area operations and containment
- geometry_collection_example/ - Complex geometries
Run examples:
cd examples/basic_usage && go run main.go cd examples/linestring_example && go run main.go cd examples/polygon_example && go run main.go cd examples/geometry_collection_example && go run main.gogo test -v# Set up test database createdb gogis_test psql gogis_test -c "CREATE EXTENSION postgis;" # Run integration tests go test -tags=integration -vgo test -bench=. -benchmemFull API documentation is available at pkg.go.dev.
If migrating from other PostGIS Go libraries:
- Update imports: Change to
github.com/restayway/gogis - Update struct tags: Use
gorm:"type:geometry(Type,4326)" - Update coordinate order: GoGIS uses
{Lng, Lat}(longitude, latitude) - Update method calls: Check method names in documentation
See CHANGELOG.md for detailed migration information between versions.
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Ensure all tests pass
- Submit a pull request
- 3D Geometry Support - PointZ, LineStringZ, PolygonZ
- Additional Geometry Types - MultiPoint, MultiLineString, MultiPolygon
- Custom SRID Support - Beyond SRID 4326
- Spatial Functions - Built-in Go implementations of common operations
- GeoJSON Integration - Direct GeoJSON marshaling/unmarshaling
- Performance Optimizations - Further query performance improvements
This project is licensed under the MIT License - see the LICENSE file for details.
- PostGIS Team - For the excellent spatial database extension
- GORM Team - For the fantastic ORM library
- Go Community - For the great language and ecosystem
- π Documentation: pkg.go.dev
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
- π§ Email: For security issues
GoGIS - Bringing PostGIS spatial capabilities to the Go ecosystem with GORM integration. Build location-aware applications with confidence! π