changeset 2803:46a9a7c1281f

Added GET /api/data/year-waterlevels/{gauge}/{year}
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 25 Mar 2019 18:37:13 +0100
parents 054f5d61452d
children e3c5efd21cb4
files pkg/controllers/gauges.go pkg/controllers/routes.go
diffstat 2 files changed, 105 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/gauges.go	Mon Mar 25 18:17:18 2019 +0100
+++ b/pkg/controllers/gauges.go	Mon Mar 25 18:37:13 2019 +0100
@@ -82,6 +82,24 @@
     $5::int
   )
 `
+	selectYearWaterlevelsMeasuredSQL = `
+SELECT
+  measure_date,
+  water_level
+FROM waterway.gauge_measurements
+WHERE
+  NOT predicted
+  AND fk_gauge_id = (
+    $1::char(2),
+    $2::char(3),
+    $3::char(5),
+    $4::char(5),
+    $5::int
+  )
+  AND extract(year from measure_date) = $6
+ORDER BY measure_date
+`
+
 	selectWaterlevelsMeasuredSQL = `
 SELECT
   measure_date,
@@ -121,6 +139,90 @@
 	return "f"
 }
 
+func yearWaterlevels(rw http.ResponseWriter, req *http.Request) {
+
+	gauge := mux.Vars(req)["gauge"]
+
+	isrs, err := models.IsrsFromString(gauge)
+	if err != nil {
+		http.Error(
+			rw, fmt.Sprintf("error: Invalid ISRS code: %v", err),
+			http.StatusBadRequest)
+		return
+	}
+
+	year, _ := strconv.ParseInt(mux.Vars(req)["year"], 10, 64)
+
+	conn := middleware.GetDBConn(req)
+
+	ctx := req.Context()
+
+	rows, err := conn.QueryContext(
+		ctx,
+		selectYearWaterlevelsMeasuredSQL,
+		isrs.CountryCode,
+		isrs.LoCode,
+		isrs.FairwaySection,
+		isrs.Orc,
+		isrs.Hectometre,
+		year,
+	)
+	if err != nil {
+		http.Error(
+			rw, fmt.Sprintf("error: %v", err),
+			http.StatusInternalServerError)
+		return
+	}
+	defer rows.Close()
+
+	var values []float64
+
+	lastDay, lastMonth := -1, -1
+
+	write := func() error {
+		var err error
+		if len(values) > 0 {
+			mean := stat.Mean(values, nil)
+			_, err = fmt.Fprintf(
+				rw, "%02d-%02d,%s\n", lastDay, lastMonth,
+				float64format(mean))
+			values = values[:0]
+		}
+		return err
+	}
+
+	for rows.Next() {
+		var when time.Time
+		var value float64
+		if err := rows.Scan(&when, &value); err != nil {
+			log.Printf("error: %v", err)
+			// Too late for an HTTP error code.
+			return
+		}
+		day, month := when.Day(), int(when.Month())
+		if day != lastDay || month != lastMonth {
+			if err := write(); err != nil {
+				log.Printf("error: %v", err)
+				// Too late for an HTTP error code.
+				return
+			}
+			lastDay, lastMonth = day, month
+		}
+		values = append(values, value)
+	}
+
+	if err := rows.Err(); err != nil {
+		log.Printf("error: %v", err)
+		// Too late for an HTTP error code.
+		return
+	}
+
+	if err := write(); err != nil {
+		log.Printf("error: %v", err)
+		// Too late for an HTTP error code.
+	}
+}
+
 func longtermWaterlevels(rw http.ResponseWriter, req *http.Request) {
 
 	gauge := mux.Vars(req)["gauge"]
--- a/pkg/controllers/routes.go	Mon Mar 25 18:17:18 2019 +0100
+++ b/pkg/controllers/routes.go	Mon Mar 25 18:37:13 2019 +0100
@@ -308,6 +308,9 @@
 	api.Handle("/data/longterm-waterlevels/{gauge}", any(
 		middleware.DBConn(http.HandlerFunc(longtermWaterlevels)))).Methods(http.MethodGet)
 
+	api.Handle("/data/year-waterlevels/{gauge}/{year:[0-9]+}", any(
+		middleware.DBConn(http.HandlerFunc(yearWaterlevels)))).Methods(http.MethodGet)
+
 	api.Handle("/data/nash-sutcliffe/{gauge}", any(&JSONHandler{
 		Handle: nashSutcliffe,
 	})).Methods(http.MethodGet)