2 回答

TA貢獻(xiàn)1776條經(jīng)驗(yàn) 獲得超12個(gè)贊
這是另一種方法;使用二進(jìn)制編碼。
根據(jù)此文檔,MySQL 使用 4 個(gè)字節(jié)存儲幾何值以指示 SRID(空間參考 ID),然后是值的 WKB(眾所周知的二進(jìn)制)表示。
因此,一個(gè)類型可以使用 WKB 編碼并在 Value() 和 Scan() 函數(shù)中添加和刪除四字節(jié)前綴。在其他答案中找到的 go-geom 庫有一個(gè) WKB 編碼包,github.com/twpayne/go-geom/encoding/wkb。
例如:
type MyPoint struct {
Point wkb.Point
}
func (m *MyPoint) Value() (driver.Value, error) {
value, err := m.Point.Value()
if err != nil {
return nil, err
}
buf, ok := value.([]byte)
if !ok {
return nil, fmt.Errorf("did not convert value: expected []byte, but was %T", value)
}
mysqlEncoding := make([]byte, 4)
binary.LittleEndian.PutUint32(mysqlEncoding, 4326)
mysqlEncoding = append(mysqlEncoding, buf...)
return mysqlEncoding, err
}
func (m *MyPoint) Scan(src interface{}) error {
if src == nil {
return nil
}
mysqlEncoding, ok := src.([]byte)
if !ok {
return fmt.Errorf("did not scan: expected []byte but was %T", src)
}
var srid uint32 = binary.LittleEndian.Uint32(mysqlEncoding[0:4])
err := m.Point.Scan(mysqlEncoding[4:])
m.Point.SetSRID(int(srid))
return err
}
使用 MyPoint 類型定義標(biāo)簽:
type Tag struct {
Name string `gorm:"type:varchar(50);primary_key"`
Loc *MyPoint `gorm:"column:loc"`
}
func (t Tag) String() string {
return fmt.Sprintf("%s @ Point(%f, %f)", t.Name, t.Loc.Point.Coords().X(), t.Loc.Point.Coords().Y())
}
使用以下類型創(chuàng)建標(biāo)簽:
tag := &Tag{
Name: "London",
Loc: &MyPoint{
wkb.Point{
geom.NewPoint(geom.XY).MustSetCoords([]float64{0.1275, 51.50722}).SetSRID(4326),
},
},
}
err = db.Create(&tag).Error
if err != nil {
log.Fatalf("create: %v", err)
}
MySQL結(jié)果:
mysql> describe tag;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name | varchar(50) | NO | PRI | NULL | |
| loc | geometry | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> select name, st_astext(loc) from tag;
+--------+------------------------+
| name | st_astext(loc) |
+--------+------------------------+
| London | POINT(0.1275 51.50722) |
+--------+------------------------+
(ArcGIS 說4326 是用于在全世界存儲參考數(shù)據(jù)的最常見的空間參考。它是 PostGIS 空間數(shù)據(jù)庫和 GeoJSON 標(biāo)準(zhǔn)的默認(rèn)值。它也被默認(rèn)用于大多數(shù) Web 制圖庫。)

TA貢獻(xiàn)2036條經(jīng)驗(yàn) 獲得超8個(gè)贊
Hooks可以讓你在 Gorm 的 sql 生成之前將列設(shè)置為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
}
- 2 回答
- 0 關(guān)注
- 152 瀏覽
添加回答
舉報(bào)