Skip to content

Instantly share code, notes, and snippets.

@brandonbloom
Created June 7, 2017 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonbloom/ba1f2874ce80b77f2ca0b3b1799c53d9 to your computer and use it in GitHub Desktop.
Save brandonbloom/ba1f2874ce80b77f2ca0b3b1799c53d9 to your computer and use it in GitHub Desktop.
package mvt
// See https://www.mapbox.com/vector-tiles/specification/
// and https://github.com/mapbox/vector-tile-spec/tree/master/2.1
// Zero value is ready to use.
type GeomBuffer struct {
geom []uint32
begun bool // True if a command sequence has begun.
start int // Index of the command header.
count uint32 // Number of commands written so far in this sequence.
}
func (buf *GeomBuffer) begin(cmd uint32) {
if buf.begun {
panic("already inside command sequence")
}
start := len(buf.geom)
buf.geom = append(buf.geom, cmd&0x7)
buf.begun = true
buf.start = start
buf.count = 0
}
func (buf *GeomBuffer) MoveTo(x, y int32) {
buf.BeginMoves()
buf.Call(x, y)
buf.End()
}
func (buf *GeomBuffer) BeginMoves() {
buf.begin(1)
}
func (buf *GeomBuffer) BeginLines() {
buf.begin(2)
}
func (buf *GeomBuffer) Call(x, y int32) {
if !buf.begun {
panic("arguments outside of command sequence")
}
buf.count++
buf.geom = append(buf.geom, zigZag(x), zigZag(y))
}
func (buf *GeomBuffer) ClosePath() {
buf.begin(7)
buf.count = 1 // No parameters, but still one command to execute.
buf.End()
}
func (buf *GeomBuffer) End() {
if !buf.begun {
panic("end outside of command sequence")
}
buf.geom[buf.start] |= (buf.count << 3)
buf.begun = false
}
// Finish extracts the encoded data and resets the buffer.
func (buf *GeomBuffer) Finish() []uint32 {
if buf.begun {
panic("finish inside command sequence")
}
res := buf.geom
*buf = GeomBuffer{}
return res
}
// ZigZag-encodes a signed integer so that small absolute
// values have small, positive varint encodings.
// See https://developers.google.com/protocol-buffers/docs/encoding#types
func zigZag(i int32) uint32 {
return uint32((i << 1) ^ (i >> 31))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment