view pkg/mesh/serialize_v1.go @ 5675:b8da63027b48 sr-v2

Started to separate mesh serialisation in different files.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sat, 10 Feb 2024 22:22:03 +0100
parents
children d56e043bbbca
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 (
	"encoding/binary"
	"io"
	"math"

	"gemma.intevation.de/gemma/pkg/log"
)

func (s *STRTree) serializeV1(w io.Writer) error {
	if err := s.tin.serializeV1(w); err != nil {
		return err
	}

	if err := binary.Write(w, binary.LittleEndian, uint8(s.Entries)); err != nil {
		return err
	}

	if err := s.serializeIndexV1(w); err != nil {
		return err
	}

	if err := s.serializeBBoxesV1(w); err != nil {
		return err
	}

	return nil
}

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 {

	if err := binary.Write(w, binary.LittleEndian, t.EPSG); err != nil {
		return err
	}

	if err := t.Min.Write(w); err != nil {
		return err
	}
	if err := t.Max.Write(w); err != nil {
		return err
	}

	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)

	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
}