From 4f2a3b53a0520f3f53ade1da3056b32417b61fcd Mon Sep 17 00:00:00 2001 From: Oliver Tonnhofer Date: Wed, 26 Dec 2012 17:30:07 +0100 Subject: [PATCH] refactored pbf counter --- parser.go | 140 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 51 deletions(-) diff --git a/parser.go b/parser.go index a27edd5..3ee57bf 100644 --- a/parser.go +++ b/parser.go @@ -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()