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

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

使用 Gorm 插入和選擇 PostGIS 幾何

使用 Gorm 插入和選擇 PostGIS 幾何

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

4 回答

?
元芳怎么了

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊

包括要點(diǎn)以供參考。


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

}

然后在表設(shè)置/遷移部分使用了一些定制:


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


查看完整回答
反對(duì) 回復(fù) 2023-06-05
?
慕尼黑8549860

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超11個(gè)贊

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

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

type Polygon4326 orb.Polygon
type Point4326 orb.Point

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

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

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


查看完整回答
反對(duì) 回復(fù) 2023-06-05
?
拉莫斯之舞

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超10個(gè)贊

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


曾經(jīng)嘗試過(guò) 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)它們非常整潔且有用。



查看完整回答
反對(duì) 回復(fù) 2023-06-05
?
神不在的星期二

TA貢獻(xiàn)1963條經(jīng)驗(yàn) 獲得超6個(gè)贊

我最終使用的另一個(gè)解決方案是使用go-geos,因?yàn)槲野l(fā)現(xiàn)我需要使用 GEOS C 庫(kù)。這樣,我就可以將結(jié)構(gòu)轉(zhuǎn)換為WKT用于插入(因?yàn)?postgis 接受它作為常規(guī)文本)并WKB在掃描時(shí)從中轉(zhuǎn)換。

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

}

此解決方案可能并不適合所有人,因?yàn)椴⒎撬腥硕夹枰褂?GEOS C 庫(kù),這在 Windows 上工作可能會(huì)很痛苦。我確信同樣的事情可以使用不同的庫(kù)來(lái)完成。

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


查看完整回答
反對(duì) 回復(fù) 2023-06-05
  • 4 回答
  • 0 關(guān)注
  • 489 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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