我在使用 entgo 和 pgx 保存 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?
感谢您的帮助!
这个解决方案对我有用,希望对你也有帮助。
架构
field.Other("location", &database.GeoJson{}).
SchemaType(map[string]string{
dialect.Postgres: "geometry(point, 4326)",
}).StorageKey("location").Optional(),
的自定义 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]
}