Home  >  Article  >  Backend Development  >  How Can I Insert and Retrieve PostGIS Geometries with Gorm in Golang?

How Can I Insert and Retrieve PostGIS Geometries with Gorm in Golang?

Barbara Streisand
Barbara StreisandOriginal
2024-11-08 22:11:02662browse

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn