Created
June 7, 2017 21:55
-
-
Save brandonbloom/ba1f2874ce80b77f2ca0b3b1799c53d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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