Closed tbruyelle closed 4 years ago
For generic geometry (or geography) types you need to call wkb.Unmarshal
directly, which returns a geom.T
.
Here is most of a worked example, working on a database called geogtest
:
create table test (id int primary key, geog geography);
insert into test (id, geog) values (1, null);
insert into test (id, geog) values (2, 'POINT(1 2)'::geography);
insert into test (id, geog) values (3, 'LINESTRING(3 4, 5 6)'::geography);
db, err := sql.Open("postgres", "postgres://localhost/geogtest?binary_parameters=yes&sslmode=disable")
if err != nil {
return err
}
rows, err := db.Query(`
SELECT id, ST_AsBinary(geog) FROM test ORDER BY id;
`)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var id int
var geog []byte
if err := rows.Scan(&id, &geog); err != nil {
return err
}
var geometry geom.T
if len(geog) != 0 {
var err error
geometry, err = wkb.Unmarshal(geog)
if err != nil {
return err
}
}
fmt.Printf("%d\t%+v\n", id, geometry)
}
return rows.Err()
Note that we call ST_AsBinary
on the GEOGRAPHY
column and scan into a []byte
which we then unmarshal using wkb.Unmarshal
. The len(geog) != 0
is a test against NULL
values (which wkb.Unmarshal
should probably handle better).
Hope this helps - please follow-up with any questions.
Thank you for the hint, this is helpful.
I was able to create a custom Scanner for that purpose :
type Geom struct {
geom.T
}
func (g *Geom) Scan(src interface{}) error {
b, ok := src.([]byte)
if !ok {
return errors.Errorf("expected []byte, got %T", src)
}
if len(b) == 0 {
return nil
}
var err error
g.T, err = wkb.Unmarshal(b)
return err
}
Maybe this is something that could be added in wkb package ?
Maybe this is something that could be added in wkb package ?
Yes, please do open a PR. It's a very useful addition.
Sure, how should I name this new type ? wkb.Geom
or wkb.T
? I think I prefer wkb.Geom
since wkb.T
won't be an interface like geom.T
and this could be confusing.
I agree with you: wkb.Geom
is nicer. It should probably have a Geom()
method that returns the wrapped geom.T
.
Fixed by @tbruyelle in #178.
My geo data are stored in a column of type GEOMETRY in postgis, because it can be a point, a line or a polygon.
Thus I wonder which
encoding/wkb
type should I use to decode its value when I fetch the data. Indeed for instance it can't be awkb.Point
because it will work only for a geometry of kind point, and I will have an error for other kinds.Any help would be appreciated :)