Mercurial > gemma
changeset 3882:37d5c4441c70
Use custom morpho class breaks in sounding result contour generation.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 10 Jul 2019 11:45:55 +0200 |
parents | 7db6999962db |
children | 0b382767b5ab |
files | pkg/imports/sr.go pkg/octree/classbreaks.go |
diffstat | 2 files changed, 64 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/imports/sr.go Wed Jul 10 09:47:02 2019 +0200 +++ b/pkg/imports/sr.go Wed Jul 10 11:45:55 2019 +0200 @@ -614,7 +614,7 @@ feedback.Info("Generate contour lines") start = time.Now() - err = generateContours(ctx, tx, builder.Tree(), id) + err = generateContours(ctx, tx, feedback, builder.Tree(), id) if err != nil { return nil, err } @@ -817,6 +817,7 @@ func generateContours( ctx context.Context, tx *sql.Tx, + feedback Feedback, tree *octree.Tree, id int64, ) error { @@ -826,13 +827,30 @@ } defer stmt.Close() - // Adjust contour lines heights to multiples of contourStepWidth - var heights []float64 - h := contourStepWidth * math.Ceil(tree.Min.Z/contourStepWidth) - for ; h <= tree.Max.Z; h += contourStepWidth { - heights = append(heights, h) + heights, err := octree.LoadClassBreaks( + ctx, tx, + "morphology_classbreaks", + ) + if err != nil { + feedback.Warn("Loading class breaks failed: %v", err) + feedback.Info("Using default class breaks") + heights = nil + h := contourStepWidth * math.Ceil(tree.Min.Z/contourStepWidth) + for ; h <= tree.Max.Z; h += contourStepWidth { + heights = append(heights, h) + } + } else { + heights = octree.ExtrapolateClassBreaks(heights, tree.Min.Z, tree.Max.Z) + heights = octree.InBetweenClassBreaks(heights, 0.05, 2) } + /* + for i, v := range heights { + fmt.Printf("%d %.2f\n", i, v) + } + log.Printf("%.2f - %.2f\n", tree.Min.Z, tree.Max.Z) + */ + octree.DoContours(tree, heights, func(res *octree.ContourResult) { if err == nil && len(res.Lines) > 0 { _, err = stmt.ExecContext(
--- a/pkg/octree/classbreaks.go Wed Jul 10 09:47:02 2019 +0200 +++ b/pkg/octree/classbreaks.go Wed Jul 10 11:45:55 2019 +0200 @@ -77,7 +77,7 @@ classes := make([]float64, 0, len(parts)) for _, part := range parts { if idx := strings.IndexRune(part, ':'); idx >= 0 { - part = part[idx+1:] + part = part[:idx] } if part = strings.TrimSpace(part); part == "" { continue @@ -93,6 +93,45 @@ return classes, nil } +func ExtrapolateClassBreaks(cbs []float64, min, max float64) []float64 { + if min > max { + min, max = max, min + } + + if len(cbs) < 2 { + return cbs + } + + if min >= cbs[0] && max <= cbs[len(cbs)-1] { + return cbs + } + + n := make([]float64, len(cbs)) + copy(n, cbs) + sort.Float64s(n) + + for min < n[0] { + diff := n[1] - n[0] + if diff == 0 { + break + } + m := make([]float64, len(n)+1) + m[0] = n[0] - diff + copy(m[1:], n) + n = m + } + + for max > n[len(n)-1] { + diff := n[len(n)-1] - n[len(n)-2] + if diff == 0 { + break + } + n = append(n, n[len(n)-1]+diff) + } + + return n +} + func InBetweenClassBreaks(cbs []float64, min float64, steps int) []float64 { if len(cbs) < 2 || steps < 2 { return cbs