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

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

使用 Gorm 插入和選擇 PostGIS 幾何

使用 Gorm 插入和選擇 PostGIS 幾何

Go
繁星淼淼 2023-06-05 17:49:15
我一直在嘗試尋找一種使用 Golang 插入和檢索幾何類型的方法,特別是庫gorm。我還嘗試使用為幾何定義不同類型并提供不同格式之間的編碼/解碼的庫orb 。Orb已經(jīng)為每種類型Scan()實現(xiàn)Value()了方法。這允許 goInsert()和Scan()函數(shù)與基元以外的類型一起工作。然而,Orb 希望使用以眾所周知的二進制 (WKB) 格式表示的幾何圖形。orb 文檔表明,要完成此操作,您應該簡單地將字段包裝在 PostGIS 函數(shù)中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,我無法使用這些函數(shù)構建那些查詢。GORM 會自動將值插入給定結構的數(shù)據(jù)庫,并將數(shù)據(jù)掃描到結構的整個層次結構中。這些Scan()和Value()方法是在幕后調(diào)用的,不受我的控制。嘗試將二進制數(shù)據(jù)直接插入幾何列是行不通的,直接查詢幾何列將給出十六進制的結果。我嘗試了多種數(shù)據(jù)庫方法來解決這個問題。我試圖創(chuàng)建自動調(diào)用幾何列上所需函數(shù)的視圖。這適用于查詢,但不適用于插入。是否可以制作某種觸發(fā)器或規(guī)則來自動調(diào)用傳入/傳出數(shù)據(jù)所需的函數(shù)?我還應該注意,我正在使用的庫完全獨立于數(shù)據(jù)和模式工作,因此我沒有硬編碼任何查詢的奢侈。我當然可以編寫一個函數(shù)來掃描整個數(shù)據(jù)模型,并從頭開始生成查詢,但如果有更好的選擇,我會更喜歡。有誰知道在 SQL 中進行這項工作的方法嗎?能夠通過查詢列本身自動調(diào)用列上的函數(shù)嗎?任何建議將不勝感激。
查看完整描述

4 回答

?
元芳怎么了

TA貢獻1798條經(jīng)驗 獲得超7個贊

包括要點以供參考。


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


查看完整回答
反對 回復 2023-06-05
?
慕尼黑8549860

TA貢獻1818條經(jīng)驗 獲得超11個贊

我最終使用的解決方案如下:

首先,我創(chuàng)建了包含所有 orb 類型的新類型,例如:

type Polygon4326 orb.Polygon
type Point4326 orb.Point

然后我在每種類型上實現(xiàn)了Scan(),方法。Value()然而,我不得不編輯字節(jié)并轉換為十六進制或從十六進制轉換。當您直接查詢 PostGIS 中的空間列時,它將返回 EWKB 的十六進制表示形式,本質上是 WKB,但包括 4 個字節(jié)來表示投影 ID(在我的例子中是 4326)。

在插入之前,我必須添加代表 4326 投影的字節(jié)。

在閱讀之前,我不得不剝離那些字節(jié),因為 orb 內(nèi)置掃描預期的 WKB 格式。


查看完整回答
反對 回復 2023-06-05
?
拉莫斯之舞

TA貢獻1820條經(jīng)驗 獲得超10個贊

是否可以制作某種觸發(fā)器或規(guī)則來自動調(diào)用傳入/傳出數(shù)據(jù)所需的函數(shù)?


曾經(jīng)嘗試過 gorm 鉤子,例如:


type Example struct {

? ? ID? ?int

? ? Name string

? ? Geom ...

}


func (e *Example) AfterFind() (err error) {

? ? e.Geom = ... // Do whatever you like here

? ? return

}

您可以使用一些掛鉤。我發(fā)現(xiàn)它們非常整潔且有用。



查看完整回答
反對 回復 2023-06-05
?
神不在的星期二

TA貢獻1963條經(jīng)驗 獲得超6個贊

我最終使用的另一個解決方案是使用go-geos,因為我發(fā)現(xiàn)我需要使用 GEOS C 庫。這樣,我就可以將結構轉換為WKT用于插入(因為 postgis 接受它作為常規(guī)文本)并WKB在掃描時從中轉換。

type Geometry4326 *geos.Geometry


// Value converts the given Geometry4326 struct into WKT such that it can be stored in a?

// database. Implements Valuer interface for use with database operations.

func (g Geometry4326) Value() (driver.Value, error) {


? ? str, err := g.ToWKT()

? ? if err != nil {

? ? ? ? return nil, err

? ? }


? ? return "SRID=4326;" + str, nil

}


// Scan converts the hexadecimal representation of geometry into the given Geometry4326?

// struct. Implements Scanner interface for use with database operations.

func (g *Geometry4326) Scan(value interface{}) error {


? ? bytes, ok := value.([]byte)

? ? if !ok {

? ? ? ? return errors.New("cannot convert database value to geometry")

? ? }


? ? str := string(bytes)


? ? geom, err := geos.FromHex(str)

? ? if err != nil {

? ? ? ? return errors.Wrap(err, "cannot get geometry from hex")

? ? }


? ? geometry := Geometry4326(geom)

? ? *g = geometry


? ? return nil

}

此解決方案可能并不適合所有人,因為并非所有人都需要使用 GEOS C 庫,這在 Windows 上工作可能會很痛苦。我確信同樣的事情可以使用不同的庫來完成。

我另外在結構上實現(xiàn)了UnmarshalJSON()and ,以便它可以自動編組/解組 GeoJSON,然后無縫地保存/從數(shù)據(jù)庫中獲取。我使用geojson-go將 GeoJSON 轉換為結構或從結構轉換,然后使用geojson-geos-go將所述結構轉換為我正在使用的go-geosMarshalJSON()結構來完成此操作。有點復雜,是的,但它有效。


查看完整回答
反對 回復 2023-06-05
  • 4 回答
  • 0 關注
  • 416 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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