如何用entgo / pgx存储PostGIS Point?

问题描述 投票:0回答:1

我在使用 entgopgx 保存 PostGIS 点时遇到问题。

我尝试使用 pgx 中的 pgtype.Point 类型,架构如下所示:

// Fields of the Event.
func (EventSchema) Fields() []ent.Field {
    return []ent.Field{
        field.UUID("id", uuid.UUID{}).Immutable().
            Annotations(&entsql.Annotation{
                Default: "gen_random_uuid()"
            }),
        field.Other("location", &pgtype.Point{}).
            SchemaType(map[string]string{
                dialect.Postgres: "geometry(point, 4326)"
            }).StorageKey("location").Optional(),
    }
}

在数据库中,“位置”的类型也是

geometry(point, 4326)

要创建的查询:

db.EventSchema.Create().SetLocation(point).Save()

导致错误:

ERROR: parse error - invalid geometry (SQLSTATE XX000)

我不能在这里只使用 pgtype.Point,但进行一些格式化吗?或者有人有不同点类型的工作示例,例如与 go-geom

感谢您的帮助!

go postgis pgx ent
1个回答
0
投票

这个解决方案对我有用,希望对你也有帮助。

架构

field.Other("location", &database.GeoJson{}).
  SchemaType(map[string]string{
    dialect.Postgres: "geometry(point, 4326)",
}).StorageKey("location").Optional(),

基于 geojson.Geometry

的自定义 GeoJson 类型
type GeoJson struct {
    *geojson.Geometry
}

func (t *GeoJson) Value() (driver.Value, error) {
    geometry, err := t.Decode()
    if err != nil {
        logging.Logger.Debug(err)
        return nil, err
    }

    encodedGeometry, err := ewkbhex.Encode(geometry, binary.LittleEndian)
    if err != nil {
        logging.Logger.Debug(err)
        return nil, err
    }

    return encodedGeometry, nil
}

func (t *GeoJson) Scan(value interface{}) error {
    // handle nil
    if value == nil {
        t = nil
        return nil
    }

    // parse as string
    stringValue, ok := value.(string)
    if !ok {
        return errors.New("value is no string")
    }

    geometry, err := ewkbhex.Decode(stringValue)
    if err != nil {
        return err
    }

    geometryAsBytes, err := geojson.Marshal(geometry)
    if err != nil {
        return err
    }

    var geoJson GeoJson
    if err := json.Unmarshal(geometryAsBytes, &geoJson); err != nil {
        return err
    }

    *t = geoJson

    return nil
}

示例 json 负载

"location": {
  "type": "Point",
  "coordinates": [22.666460, 31.180481]
 }
© www.soinside.com 2019 - 2024. All rights reserved.