view pkg/octree/contours.go @ 1131:2e6b47cdb2ca

Store octrees along with sounding results The extra table with 1:1-relation to sounding results was a provisorial solution with the intention to make it easily removable.
author Tom Gottfried <tom@intevation.de>
date Wed, 07 Nov 2018 17:54:50 +0100
parents a244b18cb916
children 0420761c1c3f
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) 2018 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>

package octree

import (
	"runtime"
	"sync"
)

type ContourResult struct {
	Height float64
	Lines  MultiLineStringZ
}

func DoContours(tree *Tree, step float64, store func(*ContourResult)) {

	results := make(chan *ContourResult)
	done := make(chan struct{})
	jobs := make(chan float64)

	go func() {
		for {
			select {
			case r := <-results:
				store(r)
			case <-done:
				return
			}
		}
	}()

	var wg sync.WaitGroup
	for i, n := 0, runtime.NumCPU(); i < n; i++ {
		wg.Add(1)
		go processLevels(tree, jobs, results, &wg)
	}
	for h := tree.Min.Z; h <= tree.Max.Z; h += step {
		jobs <- h
	}
	close(jobs)
	wg.Wait()
	done <- struct{}{}
}

func processLevels(
	tree *Tree,
	jobs <-chan float64,
	results chan<- *ContourResult,
	wg *sync.WaitGroup,
) {
	defer wg.Done()
	for h := range jobs {
		var lines MultiLineStringZ
		tree.Horizontal(h, func(t *Triangle) {
			line := t.IntersectHorizontal(h)
			if len(line) > 1 {
				lines = append(lines, line)
			}
		})
		lines = lines.Merge()
		results <- &ContourResult{h, lines}
	}
}