Home > Article > Backend Development > How Can I Insert and Retrieve PostGIS Geometries with Gorm in Golang?
Inserting and Selecting PostGIS Geometry with Gorm: A Comprehensive Guide
Using Golang, you can effortlessly insert and retrieve geometric types via Gorm, a popular ORM. This guide will walk you through the process, utilizing the orb library for defining and encoding/decoding geometries.
Orb and Well-Known Binary (WKB) Format
Orb offers Scan() and Value() methods, enabling Gorm's Insert() and Scan() functions to work beyond primitives. Orb requires geometries in the WKB format. Hence, we use the PostGIS functions ST_AsBinary() and ST_GeomFromWKB() during querying and inserting, respectively.
Challenges with Gorm
Gorm automatically handles value insertion and data scanning, making it challenging to apply our custom functions. Direct insertion of binary data fails, while querying yields results in hex format.
Potential Solutions
a. Views: Creating views that automatically apply the required functions can facilitate querying, but not insertion.
b. Triggers or Rules: Automating function calls on incoming/outgoing data via triggers or rules could offer a solution but is not universally applicable.
c. Custom Data Model Scanning: Scanning the entire data model and programmatically generating queries is a possible approach but is suboptimal.
Solution with GeoJSON Encoding
An effective alternative to Orb is to employ the geojson encoding library. This approach eliminates the need for manual byte manipulation:
Code:
<code class="go">import "github.com/twpayne/go-geom/encoding/geojson" type EWKBGeomPoint geom.Point func (g *EWKBGeomPoint) Scan(input interface{}) error { gt, err := ewkb.Unmarshal(input.([]byte)) if err != nil { return err } g = gt.(*EWKBGeomPoint) return nil } func (g EWKBGeomPoint) Value() (driver.Value, error) { b := geom.Point(g) bp := &b ewkbPt := ewkb.Point{Point: bp.SetSRID(4326)} return ewkbPt.Value() } type Track struct { gorm.Model GeometryPoint EWKBGeomPoint `gorm:"column:geom"` }</code>
Table Setup Customization:
<code class="go">err := db.Exec(`CREATE TABLE IF NOT EXISTS tracks ( id SERIAL PRIMARY KEY, geom geometry(POINT, 4326) NOT NULL );`).Error if err != nil { return err } err = gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{ { ID: "init", Migrate: func(tx *gorm.DB) error { return tx.CreateTable( Tables..., ).Error }, }, { ID: "tracks_except_geom", Migrate: func(tx *gorm.DB) error { return db.AutoMigrate(Track{}).Error }, }, }).Migrate()</code>
With these modifications, you can seamlessly insert and extract geometric types using Gorm, empowering your Go applications with geospatial capabilities.
The above is the detailed content of How Can I Insert and Retrieve PostGIS Geometries with Gorm in Golang?. For more information, please follow other related articles on the PHP Chinese website!