Mercurial > gemma
changeset 3076:e0daeb05bf50
Display Available Fairway Depths vs. LNWL: Completed backend (untested).
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Wed, 17 Apr 2019 15:04:28 +0200 |
parents | 3cf7189fa93e |
children | db890b71f070 |
files | pkg/controllers/bottlenecks.go |
diffstat | 1 files changed, 114 insertions(+), 82 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/controllers/bottlenecks.go Wed Apr 17 13:02:30 2019 +0200 +++ b/pkg/controllers/bottlenecks.go Wed Apr 17 15:04:28 2019 +0200 @@ -81,7 +81,7 @@ ) type ( - availReferenceValue struct { + referenceValue struct { level int value float64 } @@ -96,7 +96,7 @@ func classifyAvailMeasurements( from, to time.Time, measurements []availMeasurement, - classes []availReferenceValue, + classes []referenceValue, access func(*availMeasurement) float64, ) []time.Duration { @@ -203,6 +203,15 @@ return result } +func durationsToPercentage(from, to time.Time, classes []time.Duration) []float64 { + percents := make([]float64, len(classes)) + total := 100 / to.Sub(from).Seconds() + for i, v := range classes { + percents[i] = v.Seconds() * total + } + return percents +} + func bottleneckAvailabilty( _ interface{}, req *http.Request, @@ -218,68 +227,6 @@ return } - ctx := req.Context() - - loadReferenceValues := func() ([]availReferenceValue, error) { - rows, err := conn.QueryContext(ctx, selectGaugeLevelsSQL, bn) - if err != nil { - return nil, err - } - defer rows.Close() - - var levels []availReferenceValue - - loop: - for rows.Next() { - var what string - var value int - if err := rows.Scan(&what, &value); err != nil { - return nil, err - } - var level int - switch { - case strings.HasPrefix(what, "LDC"): - level = 0 - case strings.HasPrefix(what, "MW"): - level = 1 - case strings.HasPrefix(what, "HDC"): - level = 2 - default: - return nil, fmt.Errorf("Unexpected reference level type '%s'", what) - } - for i := range levels { - if levels[i].level == level { - levels[i].value = float64(value) - continue loop - } - } - levels = append(levels, availReferenceValue{ - level: level, - value: float64(value), - }) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - sort.Slice(levels, func(i, j int) bool { return levels[i].level < levels[j].level }) - - return levels, nil - } - - var refVals []availReferenceValue - if refVals, err = loadReferenceValues(); err != nil { - return - } - - if len(refVals) == 0 { - err = JSONError{ - Code: http.StatusNotFound, - Message: "No gauge reference values found for bottleneck", - } - } - var from, to time.Time if f := req.FormValue("from"); f != "" { @@ -327,6 +274,68 @@ los = 1 } + ctx := req.Context() + + loadLNWLReferenceValues := func() ([]referenceValue, error) { + rows, err := conn.QueryContext(ctx, selectGaugeLevelsSQL, bn) + if err != nil { + return nil, err + } + defer rows.Close() + + var levels []referenceValue + + loop: + for rows.Next() { + var what string + var value int + if err := rows.Scan(&what, &value); err != nil { + return nil, err + } + var level int + switch { + case strings.HasPrefix(what, "LDC"): + level = 0 + case strings.HasPrefix(what, "MW"): + level = 1 + case strings.HasPrefix(what, "HDC"): + level = 2 + default: + return nil, fmt.Errorf("Unexpected reference level type '%s'", what) + } + for i := range levels { + if levels[i].level == level { + levels[i].value = float64(value) + continue loop + } + } + levels = append(levels, referenceValue{ + level: level, + value: float64(value), + }) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + sort.Slice(levels, func(i, j int) bool { return levels[i].level < levels[j].level }) + + return levels, nil + } + + var lnwlRefs []referenceValue + if lnwlRefs, err = loadLNWLReferenceValues(); err != nil { + return + } + + if len(lnwlRefs) == 0 { + err = JSONError{ + Code: http.StatusNotFound, + Message: "No gauge reference values found for bottleneck", + } + } + loadDepthValues := func() ([]availMeasurement, error) { rows, err := conn.QueryContext( @@ -355,7 +364,6 @@ } var ms []availMeasurement - if ms, err = loadDepthValues(); err != nil { return } @@ -368,34 +376,50 @@ return } - results := classifyAvailMeasurements( + lnwl := classifyAvailMeasurements( from, to, ms, - refVals, + lnwlRefs, func(m *availMeasurement) float64 { return float64(m.value) }, ) - classes := make([]float64, len(results)) - total := 100 / to.Sub(from).Seconds() - for i, v := range results { - classes[i] = v.Seconds() * total + afdRefs := []referenceValue{ + {0, 200}, + {1, 230}, + {2, 250}, } - type outputLevel struct { - Level string `json:"level"` - Value float64 `json:"value"` + afd := classifyAvailMeasurements( + from, to, + ms, + afdRefs, + func(m *availMeasurement) float64 { return float64(m.depth) }, + ) + + lnwlPercents := durationsToPercentage(from, to, lnwl) + afdPercents := durationsToPercentage(from, to, afd) + + type lnwlOutput struct { + Level string `json:"level"` + Value float64 `json:"value"` + Percent float64 `json:"percent"` + } + + type afdOutput struct { + Value float64 `json:"value"` + Percent float64 `json:"percent"` } type output struct { - Levels []outputLevel `json:"levels"` - Classes []float64 `json:"classes"` + LNWL []lnwlOutput `json:"lnwl"` + AFD []afdOutput `json:"afd"` } - out := output{Classes: classes} + out := output{} - for i := range refVals { + for i := range lnwlRefs { var level string - switch refVals[i].level { + switch lnwlRefs[i].level { case 0: level = "LDC" case 1: @@ -403,9 +427,17 @@ case 2: level = "HDC" } - out.Levels = append(out.Levels, outputLevel{ - Level: level, - Value: refVals[i].value, + out.LNWL = append(out.LNWL, lnwlOutput{ + Level: level, + Value: lnwlRefs[i].value, + Percent: lnwlPercents[i], + }) + } + + for i := range afdRefs { + out.AFD = append(out.AFD, afdOutput{ + Value: afdRefs[i].value, + Percent: afdPercents[i], }) }