Skip to content

Commit

Permalink
feat(binary_encoding): improved compression
Browse files Browse the repository at this point in the history
  • Loading branch information
missinglink authored and orangejulius committed Jul 13, 2018
1 parent 8a369d1 commit aafe5e6
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 14 deletions.
Binary file modified build/pbf2json.darwin-x64
Binary file not shown.
Binary file modified build/pbf2json.linux-arm
Binary file not shown.
Binary file modified build/pbf2json.linux-x64
Binary file not shown.
Binary file modified build/pbf2json.win32-x64
Binary file not shown.
6 changes: 3 additions & 3 deletions encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func TestEncodingSimple(t *testing.T) {

var node = &osmpbf.Node{ID: 100, Lat: -50, Lon: 77}
var expectedBytes = []byte{0xc0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x53, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0}
var expectedBytes = []byte{0xc0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x40, 0x53, 0x40, 0x0, 0x0, 0x0}
var expectedLatlon = map[string]string{"lon": "77.0000000", "lat": "-50.0000000"}

// encode
Expand All @@ -26,7 +26,7 @@ func TestEncodingSimple(t *testing.T) {
func TestEncodingFloatPrecision(t *testing.T) {

var node = &osmpbf.Node{ID: 100, Lat: -50.555555555, Lon: 77.777777777}
var expectedBytes = []byte{0xc0, 0x49, 0x47, 0x1c, 0x71, 0xc5, 0xeb, 0x6, 0x40, 0x53, 0x71, 0xc7, 0x1c, 0x70, 0xf1, 0x51}
var expectedBytes = []byte{0xc0, 0x49, 0x47, 0x1c, 0x71, 0xc5, 0x40, 0x53, 0x71, 0xc7, 0x1c, 0x70}
var expectedLatlon = map[string]string{"lon": "77.7777778", "lat": "-50.5555556"}

// encode
Expand All @@ -43,7 +43,7 @@ func TestEncodingBitmaskValues(t *testing.T) {

var tags = map[string]string{"entrance": "main", "wheelchair": "yes"}
var node = &osmpbf.Node{ID: 100, Lat: -50, Lon: 77, Tags: tags}
var expectedBytes = []byte{0xc0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x53, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0}
var expectedBytes = []byte{0xc0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x40, 0x53, 0x40, 0x0, 0x0, 0x0, 0xa0}
var expectedLatlon = map[string]string{"lon": "77.0000000", "lat": "-50.0000000", "entrance": "2", "wheelchair": "2"}

// encode
Expand Down
33 changes: 22 additions & 11 deletions pbf2json.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,31 +288,42 @@ func bytesToLatLon(data []byte) map[string]string {

var latlon = make(map[string]string)

var lat64 = math.Float64frombits(binary.BigEndian.Uint64(data[0:8]))
var lon64 = math.Float64frombits(binary.BigEndian.Uint64(data[8:16]))
// first 6 bytes are the latitude
var latBytes = append([]byte{}, data[0:6]...)
var lat64 = math.Float64frombits(binary.BigEndian.Uint64(append(latBytes, []byte{0x0, 0x0}...)))
latlon["lat"] = strconv.FormatFloat(lat64, 'f', 7, 64)

// next 6 bytes are the longitude
var lonBytes = append([]byte{}, data[6:12]...)
var lon64 = math.Float64frombits(binary.BigEndian.Uint64(append(lonBytes, []byte{0x0, 0x0}...)))
latlon["lon"] = strconv.FormatFloat(lon64, 'f', 7, 64)

// check for the bitmask byte which indicates things like an
// entrance and the level of wheelchair accessibility
if len(data) > 16 {
latlon["entrance"] = fmt.Sprintf("%d", (data[16]&0xC0)>>6)
latlon["wheelchair"] = fmt.Sprintf("%d", (data[16]&0x30)>>4)
if len(data) > 12 {
latlon["entrance"] = fmt.Sprintf("%d", (data[12]&0xC0)>>6)
latlon["wheelchair"] = fmt.Sprintf("%d", (data[12]&0x30)>>4)
}

return latlon
}

// encode a node as bytes (between 16 & 17 bytes used)
// encode a node as bytes (between 12 & 13 bytes used)
func nodeToBytes(node *osmpbf.Node) (string, []byte) {

var bufval bytes.Buffer

// encode lat/lon as two 64 bit floats packed in to 16 bytes
var bufLatLon = make([]byte, 16)
binary.BigEndian.PutUint64(bufLatLon[:8], math.Float64bits(node.Lat))
binary.BigEndian.PutUint64(bufLatLon[8:], math.Float64bits(node.Lon))
bufval.Write(bufLatLon)
// encode lat/lon as 64 bit floats packed in to 8 bytes,
// each float is then truncated to 6 bytes because we don't
// need the additional precision (> 8 decimal places)

var latBytes = make([]byte, 8)
binary.BigEndian.PutUint64(latBytes, math.Float64bits(node.Lat))
bufval.Write(latBytes[0:6])

var lonBytes = make([]byte, 8)
binary.BigEndian.PutUint64(lonBytes, math.Float64bits(node.Lon))
bufval.Write(lonBytes[0:6])

// generate a bitmask for relevant tag features
var isEntrance = isEntranceNode(node)
Expand Down

0 comments on commit aafe5e6

Please sign in to comment.