imposm3/geom/wkb.go

66 lines
1.7 KiB
Go

package geom
import (
"bytes"
"encoding/binary"
"encoding/hex"
"github.com/omniscale/imposm3/element"
)
const (
wkbSridFlag = 0x20000000
wkbLineStringType = 2
wkbPolygonType = 3
)
func NodesAsEWKBHexLineString(nodes []element.Node, srid int) ([]byte, error) {
nodes = unduplicateNodes(nodes)
if len(nodes) < 2 {
return nil, ErrorOneNodeWay
}
buf := &bytes.Buffer{}
binary.Write(buf, binary.LittleEndian, uint8(1)) // little endian
if srid != 0 {
binary.Write(buf, binary.LittleEndian, uint32(wkbLineStringType|wkbSridFlag))
binary.Write(buf, binary.LittleEndian, uint32(srid))
} else {
binary.Write(buf, binary.LittleEndian, uint32(wkbLineStringType))
}
binary.Write(buf, binary.LittleEndian, uint32(len(nodes)))
for _, nd := range nodes {
binary.Write(buf, binary.LittleEndian, nd.Long)
binary.Write(buf, binary.LittleEndian, nd.Lat)
}
src := buf.Bytes()
dst := make([]byte, hex.EncodedLen(len(src)))
hex.Encode(dst, src)
return dst, nil
}
func NodesAsEWKBHexPolygon(nodes []element.Node, srid int) ([]byte, error) {
// TODO undup nodes and check if closed
buf := &bytes.Buffer{}
binary.Write(buf, binary.LittleEndian, uint8(1)) // little endian
if srid != 0 {
binary.Write(buf, binary.LittleEndian, uint32(wkbPolygonType|wkbSridFlag))
binary.Write(buf, binary.LittleEndian, uint32(srid))
} else {
binary.Write(buf, binary.LittleEndian, uint32(wkbPolygonType))
}
binary.Write(buf, binary.LittleEndian, uint32(1)) // one ring
binary.Write(buf, binary.LittleEndian, uint32(len(nodes)))
for _, nd := range nodes {
binary.Write(buf, binary.LittleEndian, nd.Long)
binary.Write(buf, binary.LittleEndian, nd.Lat)
}
src := buf.Bytes()
dst := make([]byte, hex.EncodedLen(len(src)))
hex.Encode(dst, src)
return dst, nil
}