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],
 		})
 	}