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

Barbara Streisand
Release: 2024-11-08 22:11:02
Original
632 people have browsed it

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>
Copy after login

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>
Copy after login

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!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template