# HG changeset patch # User Sascha L. Teichmann # Date 1562751955 -7200 # Node ID 37d5c4441c7016c1e6a7026a01679bbf084b218f # Parent 7db6999962dbceafe45a85887fba44decdc4e398 Use custom morpho class breaks in sounding result contour generation. diff -r 7db6999962db -r 37d5c4441c70 pkg/imports/sr.go --- 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( diff -r 7db6999962db -r 37d5c4441c70 pkg/octree/classbreaks.go --- 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