postgresql - 使用 Gorm 插入和选择 PostGIS 几何

标签 postgresql go postgis go-gorm wkb

我一直在尝试寻找一种使用 Golang 插入和检索几何类型的方法,特别是库 gorm .我也在尝试使用库 orb定义不同类型的几何图形,并提供不同格式之间的编码/解码。

Orb 已经为每种类型实现了 Scan()Value() 方法。这允许 go 的 Insert()Scan() 函数可以处理基元以外的类型。然而,Orb 希望使用以众所周知的二进制 (WKB) 格式表示的几何图形。

orb 文档表明,要实现此目的,您应该简单地将字段包装在 PostGIS 函数 ST_AsBinary()ST_GeomFromWKB() 中,以分别进行查询和插入。例如,表定义为:

_, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS orbtest (
            id SERIAL PRIMARY KEY,
            name TEXT NOT NULL,
            geom geometry(POLYGON, 4326) NOT NULL
        );
    `)

你可以这样做:

rows, err := db.Query("SELECT id, name, ST_AsBinary(geom) FROM orbtest LIMIT 1")

对于插入(其中 p 是一个 orb.Point):

db.Exec("INSERT INTO orbtest (id, name, geom) VALUES ($1, $2, ST_GeomFromWKB($3))", 1, "Test", wkb.Value(p))

这是我的问题:通过使用 GORM,我无法使用这些函数构建那些查询。 GORM 会自动将值插入给定结构的数据库,并将数据扫描到结构的整个层次结构中。那些 Scan()Value() 方法是在幕后调用的,不受我的控制。

尝试直接将二进制数据插入几何列是行不通的,直接查询几何列将给出十六进制的结果。

我尝试了多种数据库方法来解决这个问题。我试图创建自动调用几何列上所需函数的 View 。这适用于查询,但不适用于插入。

是否可以制作某种触​​发器或规则,自动调用传入/传出数据所需的函数?

我还应该注意,我正在使用的库完全独立于数据和模式工作,因此我没有硬编码任何类型查询的奢侈。我当然可以编写一个函数来扫描整个数据模型,并从头开始生成查询,但如果有更好的选择,我会更愿意。

有谁知道在 SQL 中实现此功能的方法吗?能够仅通过查询列本身来自动调用列上的函数吗?

如有任何建议,我们将不胜感激。

最佳答案

我将@robbieperry22 的答案与不同的编码库一起使用,发现我根本不需要修改字节。

包含要点以供引用。

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"`
}

然后在表设置/迁移部分使用了一些定制:

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()

关于postgresql - 使用 Gorm 插入和选择 PostGIS 几何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54602557/

相关文章:

postgresql - 通用 REST API Golang

SQL根据另一列中的值从一列中选择值

go - 在 Go 中实现构造函数/init 方法的最佳方法是什么

sql - 如果我使用的是 postGIS,如果我已经存储了几何列,我是否应该存储纬度和经度列?

django - Postgresql 与 Postgis Geodjango 安装

PostgreSQL PostGIS 与 ElasticSearch 空间搜索

sql - PostgreSQL 查找重复字段

postgresql - 修复或避免在 postgresql 中使用 FOR 循环

go - 这个语法是指向 slice 的指针还是指针的 slice ?

go - Go SDK使用的Gcloud身份验证帐户