Mercurial > gemma
view pkg/mesh/meshserialize_v1.go @ 5736:55892008ec96 default tip
Fixed a bunch of corner cases in WG import.
author | Sascha Wilde <wilde@sha-bang.de> |
---|---|
date | Wed, 29 May 2024 19:02:42 +0200 |
parents | ef80748ae4f3 |
children |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2024 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package mesh import ( "bufio" "encoding/binary" "io" "math" "gemma.intevation.de/gemma/pkg/log" ) func (s *STRTree) serializeV1(w io.Writer) error { return serializer(w, s, (*STRTree).serializeTinV1, (*STRTree).serializeEntries, (*STRTree).serializeIndexV1, (*STRTree).serializeBBoxesV1, ) } func (s *STRTree) serializeTinV1(w io.Writer) error { return s.tin.serializeV1(w) } func (s *STRTree) serializeBBoxesV1(w io.Writer) 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) serializeIndexV1(w io.Writer) error { if err := binary.Write(w, binary.LittleEndian, int32(len(s.index))); err != nil { return err } var buf [binary.MaxVarintLen32]byte var last int32 var written int for _, x := range s.index { 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.Infof("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 (t *Tin) serializeV1(w io.Writer) error { return serializer(w, t, (*Tin).serializeEPSG, (*Tin).serializeExtent, (*Tin).serializeVerticesV1, (*Tin).serializeTrianglesV1, ) } func (t *Tin) serializeTrianglesV1(w io.Writer) error { if err := binary.Write( w, binary.LittleEndian, uint32(len(t.Triangles))); err != nil { return err } var buf [binary.MaxVarintLen32]byte var written int var last int32 for _, triangle := range t.Triangles { for _, idx := range triangle { value := idx - last n := binary.PutVarint(buf[:], int64(value)) 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 = idx } } log.Infof("compressed tin indices in bytes: %d (%d)\n", written, 3*4*len(t.Triangles)) return nil } func (t *Tin) serializeVerticesV1(w io.Writer) error { if err := binary.Write( w, binary.LittleEndian, uint32(len(t.Vertices))); err != nil { return err } var err error vwrite := func(v float64) { if err == nil { err = binary.Write(w, binary.LittleEndian, math.Float64bits(v)) } } for _, v := range t.Vertices { vwrite(v.X) vwrite(v.Y) vwrite(v.Z) } if err != nil { return err } log.Infof("vertices %d (%d)\n", len(t.Vertices), len(t.Vertices)*3*8) return nil } func (s *STRTree) deserializeV1(r *bufio.Reader) error { return serializer(r, s, (*STRTree).deserializeTinV1, (*STRTree).deserializeEntries, (*STRTree).deserializeIndexV1, (*STRTree).deserializeBBoxesV1, ) } func (s *STRTree) deserializeBBoxesV1(r *bufio.Reader) error { var numBBoxes int32 if err := binary.Read(r, binary.LittleEndian, &numBBoxes); err != nil { return err } bboxes := make([]Box2D, numBBoxes) s.bboxes = bboxes var err error read := func(v *float64) { if err == nil { err = binary.Read(r, binary.LittleEndian, v) } } for i := range bboxes { read(&bboxes[i].X1) read(&bboxes[i].Y1) read(&bboxes[i].X2) read(&bboxes[i].Y2) } return err } func (s *STRTree) deserializeIndexV1(r *bufio.Reader) error { var numIndex int32 if err := binary.Read(r, binary.LittleEndian, &numIndex); err != nil { return err } index := make([]int32, numIndex) s.index = index var last int32 for i := range index { v, err := binary.ReadVarint(r) if err != nil { return err } value := int32(v) + last index[i] = value last = value } return nil } func (s *STRTree) deserializeTinV1(r *bufio.Reader) error { s.tin = new(Tin) return s.tin.deserializeV1(r) } // deserializeV1 restores a TIN from a binary representation. func (t *Tin) deserializeV1(r *bufio.Reader) error { return serializer(r, t, (*Tin).deserializeEPSG, (*Tin).deserializeExtent, (*Tin).deserializeVerticesV1, (*Tin).deserializeTrianglesV1, ) } func (t *Tin) deserializeVerticesV1(r *bufio.Reader) error { var numVertices uint32 if err := binary.Read(r, binary.LittleEndian, &numVertices); err != nil { return err } log.Infof("vertices: %d\n", numVertices) vertices := make([]Vertex, numVertices) t.Vertices = vertices for i := range vertices { if err := vertices[i].Read(r); err != nil { return err } } return nil } func (t *Tin) deserializeTrianglesV1(r *bufio.Reader) error { var numTriangles uint32 if err := binary.Read(r, binary.LittleEndian, &numTriangles); err != nil { return err } log.Infof("triangles: %d\n", numTriangles) indices := make([]int32, 3*numTriangles) triangles := make([][]int32, numTriangles) t.Triangles = triangles var last int32 for i := range triangles { tri := indices[:3] indices = indices[3:] triangles[i] = tri for j := range tri { v, err := binary.ReadVarint(r) if err != nil { return err } value := int32(v) + last tri[j] = value last = value } } return nil }