第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會有你想問的

使用 Gorm 和 MySQL 處理空間數(shù)據(jù)

使用 Gorm 和 MySQL 處理空間數(shù)據(jù)

Go
炎炎設(shè)計(jì) 2022-05-18 16:40:39
我參考了 irbanana關(guān)于支持 PostGIS 的空間數(shù)據(jù)類型的回答。我正在使用 MySQL 并嘗試實(shí)現(xiàn)Value()自定義數(shù)據(jù)類型EWKBGeomPoint。我的戈姆模型:import (    "github.com/twpayne/go-geom"    "github.com/twpayne/go-geom/encoding/ewkb")type EWKBGeomPoint geom.Pointtype Tag struct {    Name string `json:"name"`json:"siteID"` // forign key    Loc EWKBGeomPoint `json:"loc"`}據(jù)我所知,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'))如果我自己做一個(gè)Value()來滿足database/sql's 的Valuer界面: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}包括在內(nèi)的整個(gè)值ST_GeomFromText()在 Gorm 的單引號中引用,因此它不起作用:INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name','ST_GeomFromText('POINT(10.000000 20.000000)')');我如何使它工作?編輯1:我追蹤到 Gorm 代碼,最終它得到了 tocallback_create.go的createCallback功能。在里面檢查if primaryField == nil它是真的,它進(jìn)入調(diào)用scope.SQLDB().Exec然后我沒有進(jìn)一步追蹤。scope.SQL 是字符串INSERT INTO標(biāo)記(名稱,loc) VALUES (?,?)并scope.SQLVars打印[tag name {{1 2 [10 20] 0}}]. 看起來插值發(fā)生在這個(gè)調(diào)用中。這是調(diào)用database/sql代碼嗎?
查看完整描述

2 回答

?
叮當(dāng)貓咪

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 制圖庫。)


查看完整回答
反對 回復(fù) 2022-05-18
?
慕桂英3389331

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

}


查看完整回答
反對 回復(fù) 2022-05-18
  • 2 回答
  • 0 關(guān)注
  • 152 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號