Skip to content

Add ewkb encoding/decoding support#88

Merged
paulmach merged 8 commits intomasterfrom
ewkb
May 4, 2022
Merged

Add ewkb encoding/decoding support#88
paulmach merged 8 commits intomasterfrom
ewkb

Conversation

@paulmach
Copy link
Copy Markdown
Owner

@paulmach paulmach commented Mar 3, 2022

This PR adds support for encoding and decoding of extended WKB
data.

The API interface looks like, please provide feedback

func Marshal(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) ([]byte, error)
func MarshalToHex(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) (string, error)
func MustMarshal(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) []byte
func MustMarshalToHex(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) string
func NewEncoder(w io.Writer) *Encoder
func (e *Encoder) SetByteOrder(bo binary.ByteOrder) *Encoder
func (e *Encoder) SetSRID(srid int) *Encoder
func (e *Encoder) Encode(geom orb.Geometry) error
func Unmarshal(b []byte) (orb.Geometry, int, error)
func NewDecoder(r io.Reader) *Decoder
func (d *Decoder) Decode() (orb.Geometry, int, error)

Inserting geometry into a database

Depending on the database different formats and functions are supported.

PostgreSQL and PostGIS

PostGIS stores geometry as EWKB internally. As a result it can be inserted without
a wrapper function.

db.Exec("INSERT INTO geodata(geom) VALUES (ST_GeomFromEWKB($1))", ewkb.Value(coord, 4326))
db.Exec("INSERT INTO geodata(geom) VALUES ($1)", ewkb.Value(coord, 4326))

MySQL/MariaDB

MySQL and MariaDB
store geometry
data in WKB format with a 4 byte SRID prefix.

coord := orb.Point{1, 2}
// as WKB in hex format
data := wkb.MustMarshalToHex(coord)
db.Exec("INSERT INTO geodata(geom) VALUES (ST_GeomFromWKB(UNHEX(?), 4326))", data)
// relying on the raw encoding
db.Exec("INSERT INTO geodata(geom) VALUES (?)", ewkb.ValuePrefixSRID(coord, 4326))

Reading geometry from a database query

As stated above, different databases supported different formats and functions.

PostgreSQL and PostGIS

When working with PostGIS the raw format is EWKB so the wrapper function is not necessary

// both of these queries return the same data
row := db.QueryRow("SELECT ST_AsEWKB(geom) FROM geodata")
row := db.QueryRow("SELECT geom FROM geodata")
// if you don't need the SRID
p := orb.Point{}
err := row.Scan(ewkb.Scanner(&p))
log.Printf("geom: %v", p)
// if you need the SRID
p := orb.Point{}
gs := ewkb.Scanner(&p)
err := row.Scan(gs)
log.Printf("srid: %v", gs.SRID)
log.Printf("geom: %v", gs.Geometry)
log.Printf("also geom: %v", p)

MySQL/MariaDB

// using the ST_AsBinary function
row := db.QueryRow("SELECT st_srid(geom), ST_AsBinary(geom) FROM geodata")
row.Scan(&srid, ewkb.Scanner(&data))
// relying on the raw encoding
row := db.QueryRow("SELECT geom FROM geodata")
// if you don't need the SRID
p := orb.Point{}
err := row.Scan(ewkb.ScannerPrefixSRID(&p))
log.Printf("geom: %v", p)
// if you need the SRID
p := orb.Point{}
gs := ewkb.ScannerPrefixSRID(&p)
err := row.Scan(gs)
log.Printf("srid: %v", gs.SRID)
log.Printf("geom: %v", gs.Geometry)

@paulmach
Copy link
Copy Markdown
Owner Author

paulmach commented May 4, 2022

@asmeikal Thank you for testing #68 (comment)

@paulmach paulmach merged commit 7ee1a33 into master May 4, 2022
@paulmach paulmach deleted the ewkb branch May 4, 2022 17:51
@paulmach
Copy link
Copy Markdown
Owner Author

paulmach commented May 4, 2022

This change is included in v0.6.0 https://github.com/paulmach/orb/releases/tag/v0.6.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant