diff --git a/build/pbf2json.darwin-x64 b/build/pbf2json.darwin-x64 index 64ab666..2884eeb 100755 Binary files a/build/pbf2json.darwin-x64 and b/build/pbf2json.darwin-x64 differ diff --git a/build/pbf2json.linux-arm b/build/pbf2json.linux-arm index 06783c6..4c0562c 100755 Binary files a/build/pbf2json.linux-arm and b/build/pbf2json.linux-arm differ diff --git a/build/pbf2json.linux-x64 b/build/pbf2json.linux-x64 index 135e112..ac4ea77 100755 Binary files a/build/pbf2json.linux-x64 and b/build/pbf2json.linux-x64 differ diff --git a/build/pbf2json.win32-x64 b/build/pbf2json.win32-x64 index 16ba5f2..40c6eb2 100755 Binary files a/build/pbf2json.win32-x64 and b/build/pbf2json.win32-x64 differ diff --git a/encoding_test.go b/encoding_test.go index 62a78d2..f28e82c 100644 --- a/encoding_test.go +++ b/encoding_test.go @@ -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 @@ -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 @@ -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 diff --git a/pbf2json.go b/pbf2json.go index 23191c3..8d3f606 100644 --- a/pbf2json.go +++ b/pbf2json.go @@ -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)