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

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 格式。

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)它們非常整潔且有用。

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ù)雜,是的,但它有效。
- 4 回答
- 0 關(guān)注
- 489 瀏覽
添加回答
舉報(bào)