refactored pbf counter

master
Oliver Tonnhofer 2012-12-26 17:30:07 +01:00
parent d6d3928bfd
commit 4f2a3b53a0
1 changed files with 89 additions and 51 deletions

140
parser.go
View File

@ -7,78 +7,116 @@ import (
// "goposm/osmpbf/fileformat"
"bytes"
"compress/zlib"
"io/ioutil"
"io"
"log"
"os"
"osmpbf"
)
func nextBlobHeader(file *os.File, offset int64) (position int64, size int32) {
newOffset, err := file.Seek(offset, 0)
if offset != newOffset {
log.Fatal(err)
return
type PBF struct {
file *os.File
filename string
offset int64
}
func Open(filename string) (f *PBF, err error) {
f = new(PBF)
f.filename = filename
file, err := os.Open(filename)
f.file = file
if err != nil {
return nil, err
}
return f, nil
}
func (pbf *PBF) NextDataPosition() (offset int64, size int32) {
header := pbf.nextBlobHeader()
size = header.GetDatasize()
offset = pbf.offset
pbf.offset += int64(size)
pbf.file.Seek(pbf.offset, 0)
if header.GetType() == "OSMHeader" {
return pbf.NextDataPosition()
}
position = offset + 4
binary.Read(file, binary.BigEndian, &size)
return
}
func (pbf *PBF) nextBlobHeaderSize() (size int32) {
pbf.offset += 4
binary.Read(pbf.file, binary.BigEndian, &size)
return
}
func (pbf *PBF) nextBlobHeader() *osmpbf.BlobHeader {
var blobHeader = &osmpbf.BlobHeader{}
size := pbf.nextBlobHeaderSize()
if size == 0 {
return blobHeader
}
data := make([]byte, size)
io.ReadFull(pbf.file, data)
err := proto.Unmarshal(data, blobHeader)
if err != nil {
log.Fatal("unmarshaling error (header): ", err)
}
pbf.offset += int64(size)
return blobHeader
}
func ReadPrimitiveBlock(file *os.File, offset int64, size int32) *osmpbf.PrimitiveBlock {
var block = &osmpbf.PrimitiveBlock{}
var blob = &osmpbf.Blob{}
blobData := make([]byte, size)
file.Seek(offset, 0)
io.ReadFull(file, blobData)
err := proto.Unmarshal(blobData, blob)
if err != nil {
log.Fatal("unmarshaling error blob: ", err)
}
buf := bytes.NewBuffer(blob.GetZlibData())
r, err := zlib.NewReader(buf)
if err != nil {
log.Fatal("zlib error: ", err)
}
raw := make([]byte, blob.GetRawSize())
io.ReadFull(r, raw)
if err != nil {
log.Fatal("zlib read error: ", err)
}
err = proto.Unmarshal(raw, block)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
return block
}
func blockPositions(filename string) {
pbf, err := Open(filename)
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
var offset int64
var blobHeader = &osmpbf.BlobHeader{}
var blob = &osmpbf.Blob{}
var block = &osmpbf.PrimitiveBlock{}
var nodesCounter, relationsCounter, waysCounter int
for {
position, size := nextBlobHeader(file, offset)
offset, size := pbf.NextDataPosition()
if size == 0 {
break
}
data := make([]byte, size)
file.Read(data)
err = proto.Unmarshal(data, blobHeader)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
offset = position + int64(size) + int64(blobHeader.GetDatasize())
if blobHeader.GetType() == "OSMHeader" {
fmt.Println("Skip header", blobHeader.GetType())
continue
}
blobData := make([]byte, blobHeader.GetDatasize())
file.Read(blobData)
err = proto.Unmarshal(blobData, blob)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
buf := bytes.NewBuffer(blob.GetZlibData())
r, err := zlib.NewReader(buf)
if err != nil {
log.Fatal("zlib error: ", err)
}
// raw := make([]byte, blob.GetRawSize())
raw, err := ioutil.ReadAll(r)
// bytes, err := r.Read(raw)
if err != nil {
log.Fatal("zlib read error: ", err)
}
err = proto.Unmarshal(raw, block)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
block := ReadPrimitiveBlock(file, offset, size)
for _, group := range block.Primitivegroup {
dense := group.GetDense()