ewkb

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2023 License: MIT Imports: 9 Imported by: 0

README

encoding/ewkb Godoc Reference

This package provides encoding and decoding of extended WKB data. This format includes the SRID in the data. If the SRID is not needed use the wkb package for a simpler interface. The interface is defined as:

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)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedDataType is returned by Scan methods when asked to scan
	// non []byte data from the database. This should never happen
	// if the driver is acting appropriately.
	ErrUnsupportedDataType = errors.New("wkb: scan value must be []byte")

	// ErrNotEWKB is returned when unmarshalling EWKB and the data is not valid.
	ErrNotEWKB = errors.New("wkb: invalid data")

	// ErrIncorrectGeometry is returned when unmarshalling EWKB data into the wrong type.
	// For example, unmarshaling linestring data into a point.
	ErrIncorrectGeometry = errors.New("wkb: incorrect geometry")

	// ErrUnsupportedGeometry is returned when geometry type is not supported by this lib.
	ErrUnsupportedGeometry = errors.New("wkb: unsupported geometry")
)

DefaultByteOrder is the order used for marshalling or encoding is none is specified.

View Source
var DefaultSRID int = 4326

DefaultSRID is set to 4326, a common SRID, which represents spatial data using longitude and latitude coordinates on the Earth's surface as defined in the WGS84 standard, which is also used for the Global Positioning System (GPS). This will be used by the encoder if non is specified.

Functions

func Marshal

func Marshal(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) ([]byte, error)

Marshal encodes the geometry with the given byte order. An SRID of 0 will not be included in the encoding and the result will be a wkb encoding of the geometry.

func MarshalToHex

func MarshalToHex(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) (string, error)

MarshalToHex will encode the geometry into a hex string representation of the binary ewkb.

func MustMarshal

func MustMarshal(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) []byte

MustMarshal will encode the geometry and panic on error. Currently there is no reason to error during geometry marshalling.

func MustMarshalToHex

func MustMarshalToHex(geom orb.Geometry, srid int, byteOrder ...binary.ByteOrder) string

MustMarshalToHex will encode the geometry and panic on error. Currently there is no reason to error during geometry marshalling.

func Unmarshal

func Unmarshal(data []byte) (orb.Geometry, int, error)

Unmarshal will decode the type into a Geometry.

func Value

func Value(g orb.Geometry, srid int) driver.Valuer

Value will create a driver.Valuer that will EWKB the geometry into the database query.

db.Exec("INSERT INTO table (point_column) VALUES (?)", ewkb.Value(p, 4326))

func ValuePrefixSRID

func ValuePrefixSRID(g orb.Geometry, srid int) driver.Valuer

ValuePrefixSRID will create a driver.Valuer that will WKB the geometry but add the srid as a 4 byte prefix.

db.Exec("INSERT INTO table (point_column) VALUES (?)", ewkb.Value(p, 4326))

Types

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder can decoder WKB geometry off of the stream.

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

NewDecoder will create a new EWKB decoder.

func (*Decoder) Decode

func (d *Decoder) Decode() (orb.Geometry, int, error)

Decode will decode the next geometry off of the stream.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

An Encoder will encode a geometry as EWKB to the writer given at creation time.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder creates a new Encoder for the given writer.

func (*Encoder) Encode

func (e *Encoder) Encode(geom orb.Geometry, srid ...int) error

Encode will write the geometry encoded as EWKB to the given writer.

func (*Encoder) SetByteOrder

func (e *Encoder) SetByteOrder(bo binary.ByteOrder) *Encoder

SetByteOrder will override the default byte order set when the encoder was created.

func (*Encoder) SetSRID

func (e *Encoder) SetSRID(srid int) *Encoder

SetSRID will override the default srid.

type GeometryScanner

type GeometryScanner struct {
	SRID     int
	Geometry orb.Geometry
	Valid    bool // Valid is true if the geometry is not NULL
	// contains filtered or unexported fields
}

GeometryScanner is a thing that can scan in sql query results. It can be used as a scan destination:

var s wkb.GeometryScanner
err := db.QueryRow("SELECT latlon FROM foo WHERE id=?", id).Scan(&s)
...
if s.Valid {
  // use s.Geometry
  // use s.SRID
} else {
  // NULL value
}

func Scanner

func Scanner(g interface{}) *GeometryScanner

Scanner will return a GeometryScanner that can scan sql query results. The geometryScanner.Geometry attribute will be set to the value. If g is non-nil, it MUST be a pointer to an orb.Geometry type like a Point or LineString. In that case the value will be written to g and the Geometry attribute.

var p orb.Point
err := db.QueryRow("SELECT latlon FROM foo WHERE id=?", id).Scan(wkb.Scanner(&p))
...
// use p

If the value may be null check Valid first:

var point orb.Point
s := wkb.Scanner(&point)
err := db.QueryRow("SELECT latlon FROM foo WHERE id=?", id).Scan(s)
...
if s.Valid {
  // use p
} else {
  // NULL value
}

func ScannerPrefixSRID

func ScannerPrefixSRID(g interface{}) *GeometryScanner

ScannerPrefixSRID will scan ewkb data were the SRID is in the first 4 bytes of the data. Databases like mysql/mariadb use this as their raw format. This method should only be used when working with such a database.

var p orb.Point
err := db.QueryRow("SELECT latlon FROM foo WHERE id=?", id).Scan(wkb.PrefixSRIDScanner(&p))

However, it is recommended to covert to wkb explicitly using something like:

var srid int
var p orb.Point
err := db.QueryRow("SELECT ST_SRID(latlon), ST_AsBinary(latlon) FROM foo WHERE id=?", id).
	Scan(&srid, wkb.Scanner(&p))

https://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html

func (*GeometryScanner) Scan

func (s *GeometryScanner) Scan(d interface{}) error

Scan will scan the input []byte data into a geometry. This could be into the orb geometry type pointer or, if nil, the scanner.Geometry attribute.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL