# HG changeset patch # User Sascha L. Teichmann # Date 1562318950 -7200 # Node ID 631f5eaf29de5569c86e2af0f57d0f1b60c0cf58 # Parent 49052775f57f7e7c3a3c3740cf33539bd280f50c First preparation to use custom classbreaks in contour generation. diff -r 49052775f57f -r 631f5eaf29de pkg/octree/classbreaks.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/octree/classbreaks.go Fri Jul 05 11:29:10 2019 +0200 @@ -0,0 +1,126 @@ +// 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) 2019 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha L. Teichmann + +package octree + +import ( + "context" + "database/sql" + "errors" + "math" + "sort" + "strconv" + "strings" +) + +const ( + selectClassBreaksSQL = ` +SELECT config_val FROM sys_admin.system_config +WHERE config_key = $1` +) + +func SampleDiffHeights(min, max, step float64) []float64 { + var heights []float64 + switch { + case min >= 0: // All values positive. + for v := 0.0; v <= max; v += step { + if v >= min { + heights = append(heights, v) + } + } + case max <= 0: // All values negative. + for v := 0.0; v >= min; v -= step { + if v <= max { + heights = append(heights, v) + } + } + default: // Positive and negative. + for v := step; v <= max; v += step { + heights = append(heights, v) + } + for i, j := 0, len(heights)-1; i < j; i, j = i+1, j-1 { + heights[i], heights[j] = heights[j], heights[i] + } + for v := 0.0; v >= min; v -= step { + heights = append(heights, v) + } + } + return heights +} + +func LoadClassBreaks(ctx context.Context, tx *sql.Tx, key string) ([]float64, error) { + + var config sql.NullString + + err := tx.QueryRowContext(ctx, selectClassBreaksSQL, key).Scan(&config) + + switch { + case err == sql.ErrNoRows: + return nil, nil + case err != nil: + return nil, err + case !config.Valid: + return nil, errors.New("Invalid config string") + } + + parts := strings.Split(config.String, ",") + classes := make([]float64, 0, len(parts)) + for _, part := range parts { + if idx := strings.IndexRune(part, ':'); idx >= 0 { + part = part[idx+1:] + } + if part = strings.TrimSpace(part); part == "" { + continue + } + v, err := strconv.ParseFloat(part, 64) + if err != nil { + return nil, err + } + classes = append(classes, v) + } + + sort.Float64s(classes) + return classes, nil +} + +func InBetweenClassBreaks(cbs []float64, min float64, steps int) []float64 { + if len(cbs) < 2 || steps < 2 { + return cbs + } + + out := make([]float64, 1, len(cbs)*steps) + + out[0] = cbs[0] + + _1steps := 1 / float64(steps) + + for i := 1; i < len(cbs); i++ { + last, curr := cbs[i-1], cbs[i] + + // Gap already too small -> proceed with next gap. + diff := curr - last + if math.Abs(diff) < min { + out = append(out, curr) + continue + } + + delta := diff * _1steps + for p := last + delta; p < curr; p += delta { + out = append(out, p) + } + + out = append(out, curr) + } + + return out +} diff -r 49052775f57f -r 631f5eaf29de pkg/octree/contours.go --- a/pkg/octree/contours.go Fri Jul 05 10:31:23 2019 +0200 +++ b/pkg/octree/contours.go Fri Jul 05 11:29:10 2019 +0200 @@ -19,35 +19,6 @@ "sync" ) -func SampleDiffHeights(min, max, step float64) []float64 { - var heights []float64 - switch { - case min >= 0: // All values positive. - for v := 0.0; v <= max; v += step { - if v >= min { - heights = append(heights, v) - } - } - case max <= 0: // All values negative. - for v := 0.0; v >= min; v -= step { - if v <= max { - heights = append(heights, v) - } - } - default: // Positive and negative. - for v := step; v <= max; v += step { - heights = append(heights, v) - } - for i, j := 0, len(heights)-1; i < j; i, j = i+1, j-1 { - heights[i], heights[j] = heights[j], heights[i] - } - for v := 0.0; v >= min; v -= step { - heights = append(heights, v) - } - } - return heights -} - // ContourResult stores an calculated iso line for a given height. // Is used as a future variable in the concurrent iso line calculation. type ContourResult struct {