changeset 3337:146bf3a1752c

Fixed waterlevel classifications.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 May 2019 18:27:58 +0200
parents db1dc197dc43
children 8c435f9a85bb
files pkg/controllers/bottlenecks.go
diffstat 1 files changed, 49 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/bottlenecks.go	Mon May 20 17:40:16 2019 +0200
+++ b/pkg/controllers/bottlenecks.go	Mon May 20 18:27:58 2019 +0200
@@ -141,7 +141,6 @@
 	if len(measurements) == 0 ||
 		to.Before(measurements[0].when) ||
 		from.After(measurements[len(measurements)-1].when) {
-		log.Println("empty")
 		return result
 	}
 
@@ -178,48 +177,41 @@
 			continue pairs
 
 		case (p1.when.Before(from) || p1.when.Equal(from)) && (to.Before(p2.when) || to.Equal(p2.when)):
-			//case !p1.when.After(from) && !p2.when.Before(to):
-			// (from-to) is complete inside segment.
-			// invalid += p1.when.Sub(from)
-			// invalid += to.Sub(p2.when)
-			// log.Println("complete inside")
+			// log.Println("(from, to) complete inside current interval")
 			v := vbt(p1, p2)
 			f, _ := v(from)
 			t, _ := v(to)
 			classify(common.InterpolateTimeByValue(from, f, to, t))
 			start, end = from, to
 
-		case p1.when.After(from):
-			// from is inside segment
-			// invalid += p1.when.Sub(from)
-			// log.Println("from is inside")
-			f, _ := vbt(p1, p2)(from)
-			classify(common.InterpolateTimeByValue(
-				from, f,
-				p2.when, access(p2),
-			))
-			start, end = from, p2.when
-
-		case p2.when.Before(to):
-			// to is inside segment
-			// invalid += to.Sub(p2.when)
-			// log.Println("to is inside")
-			t, _ := vbt(p1, p2)(to)
-			classify(common.InterpolateTimeByValue(
-				p1.when, access(p1),
-				to, t,
-			))
-			start, end = p1.when, to
-
-		case !p1.when.Before(from) && !to.After(p2.when):
-			// Segment complete inside.
-			// log.Println("is complete inside")
+		case (from.Before(p1.when) || from.Equal(p1.when)) && (p2.when.Before(to) || p2.when.Equal(to)):
+			//log.Println("current interval complete inside (from, to)")
 			classify(common.InterpolateTimeByValue(
 				p1.when, access(p1),
 				p2.when, access(p2),
 			))
 			start, end = p1.when, p2.when
 
+		case p1.when.After(from):
+			// log.Println("p1 > from")
+			pt := minTime(to, p2.when)
+			t, _ := vbt(p1, p2)(pt)
+			classify(common.InterpolateTimeByValue(
+				p1.when, access(p1),
+				pt, t,
+			))
+			start, end = p1.when, pt
+
+		case p2.when.Before(to):
+			// log.Println("p2 < to")
+			pf := maxTime(from, p1.when)
+			f, _ := vbt(p1, p2)(pf)
+			classify(common.InterpolateTimeByValue(
+				pf, f,
+				p2.when, access(p2),
+			))
+			start, end = pf, p2.when
+
 		default:
 			log.Printf("warn: unexpected case. That should not happen. %v - %v, %v - %v\n",
 				p1.when, p2.when, from, to)
@@ -238,11 +230,13 @@
 				// -> split
 				if access(p1) < classes[i].value {
 					// started below -> second part above
-					result[i+1] = end.Sub(cvs[i].when)
+					diff := absDuration(end.Sub(cvs[i].when))
+					result[i+1] += diff
 					end = cvs[i].when
 				} else {
 					// started above -> first part above
-					result[i+1] = cvs[i].when.Sub(start)
+					diff := absDuration(cvs[i].when.Sub(start))
+					result[i+1] += diff
 					start = cvs[i].when
 				}
 			}
@@ -256,6 +250,28 @@
 	return result
 }
 
+func minTime(a, b time.Time) time.Time {
+	if a.Before(b) {
+		return a
+	}
+	return b
+}
+
+func maxTime(a, b time.Time) time.Time {
+	if a.After(b) {
+		return a
+	}
+	return b
+}
+
+func absDuration(x time.Duration) time.Duration {
+	if x < 0 {
+		log.Printf("warn: negative duration %v\n", x)
+		return -x
+	}
+	return x
+}
+
 func durationsToPercentage(from, to time.Time, classes []time.Duration) []float64 {
 	percents := make([]float64, len(classes))
 	total := 100 / to.Sub(from).Seconds()