Mercurial > gemma
diff pkg/octree/strtree.go @ 4646:89a72e0e2f9b stree-experiment
Add a method to serialize an STRTree.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sun, 13 Oct 2019 15:45:39 +0200 |
parents | a1a9b1eab57c |
children | 18331577a251 |
line wrap: on
line diff
--- a/pkg/octree/strtree.go Fri Oct 11 23:46:35 2019 +0200 +++ b/pkg/octree/strtree.go Sun Oct 13 15:45:39 2019 +0200 @@ -14,8 +14,14 @@ package octree import ( + "bytes" + "encoding/binary" + "io" + "log" "math" "sort" + + "github.com/pierrec/lz4" ) const STRTreeDefaultEntries = 8 @@ -44,6 +50,9 @@ } } else { // leaf top = -top - 1 + if !s.bbox(top).Contains(x, y) { + continue + } for i, n := int32(0), s.index[top+1]; i < n; i++ { idx := s.index[top+2+i] ti := s.tin.Triangles[idx] @@ -150,6 +159,95 @@ return removed } +func (s *STRTree) serializeIndex(w io.Writer) error { + + if err := binary.Write(w, binary.LittleEndian, int32(len(s.index))); err != nil { + return err + } + + if err := binary.Write(w, binary.LittleEndian, s.index[0]); err != nil { + return err + } + + var buf [binary.MaxVarintLen32]byte + + var last int32 + var written int + + for _, x := range s.index[1:] { + delta := x - last + n := binary.PutVarint(buf[:], int64(delta)) + for p := buf[:n]; len(p) > 0; p = p[n:] { + var err error + if n, err = w.Write(p); err != nil { + return err + } + written += n + } + + last = x + } + log.Printf("info: compressed index in bytes: %d %.2f (%d %.2f)\n", + written, + float64(written)/(1024*1024), + 4*len(s.index), + float64(4*len(s.index))/(1024*1024), + ) + + return nil +} + +func (s *STRTree) serializeBBoxes(w io.Writer) (rr error) { + + if err := binary.Write(w, binary.LittleEndian, int32(len(s.bboxes))); err != nil { + return err + } + + var err error + + write := func(v float64) { + if err == nil { + err = binary.Write(w, binary.LittleEndian, math.Float64bits(v)) + } + } + for _, box := range s.bboxes { + write(box.X1) + write(box.Y1) + write(box.X2) + write(box.Y2) + } + + return err +} + +func (s *STRTree) Bytes() ([]byte, error) { + + var buf bytes.Buffer + w := lz4.NewWriter(&buf) + + if err := s.tin.serialize(w); err != nil { + return nil, err + } + + if err := binary.Write(w, binary.LittleEndian, uint8(s.Entries)); err != nil { + return nil, err + } + + if err := s.serializeIndex(w); err != nil { + return nil, err + } + + if err := s.serializeBBoxes(w); err != nil { + return nil, err + } + + if err := w.Flush(); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + func (s *STRTree) allTriangles(pos int32, tris map[int32]struct{}) { stack := []int32{pos} for len(stack) > 0 {