使用Gorm和MySQL处理空间数据

问题描述 投票:1回答:1

我参考irbanana's answer关于为PostGIS支持空间数据类型。我正在使用MySQL,并尝试为自定义数据类型Value()实现EWKBGeomPoint

我的Gorm模型:

import (
    "github.com/twpayne/go-geom"
    "github.com/twpayne/go-geom/encoding/ewkb"
)

type EWKBGeomPoint geom.Point

type Tag struct {
    Name string `json:"name"`
json:"siteID"` // forign key
    Loc EWKBGeomPoint `json:"loc"`
}

据我所知,MySQL支持这样的插入:

INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name',ST_GeomFromText('POINT(10.000000 20.000000)'))

INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name', ST_GeomFromWKB(X'0101000000000000000000F03F000000000000F03F'))

如果我用自己的Value()来满足database/sqlValuer接口:

func (g EWKBGeomPoint) Value() (driver.Value, error) {
    log.Println("EWKBGeomPoint value called")
    b := geom.Point(g)
    bp := &b

    floatArr := bp.Coords()
    return fmt.Sprintf("ST_GeomFromText('POINT(%f %f)')", floatArr[0], floatArr[1]), nil
}

包含ST_GeomFromText()的整个值都用Gorm的单引号引起来,因此它将不起作用:

INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name','ST_GeomFromText('POINT(10.000000 20.000000)')');

我如何使其起作用?

编辑1:

我追踪到Gorm代码,最终它到达了callback_create.gocreateCallback函数。在它里面检查if primaryField == nil,这是真的,它进入了scope.SQLDB().Exec的调用,所以我无法进一步追踪。

scope.SQL是字符串INSERT INTO tag(name,loc ) VALUES (?,?)scope.SQLVars打印[tag name {{1 2 [10 20] 0}}]。看起来插值发生在此调用内。

这是调用database/sql代码吗?

编辑2:

发现了类似的Stackoverflow问题here。但是我不明白解决方案。

mysql go gorm spatial go-geom
1个回答
0
投票

[Hooks可以让您在Gorm的sql生成之前将列设置为gorm.Expr

例如,在插入之前是这样的:

func (t *Tag) BeforeCreate(scope *gorm.Scope) error {

  x, y := .... // tag.Loc coordinates

  text := fmt.Sprintf("POINT(%f %f)", x, y)

  expr := gorm.Expr("ST_GeomFromText(?)", text)

  scope.SetColumn("loc", expr)

  return nil
}
© www.soinside.com 2019 - 2024. All rights reserved.