# HG changeset patch # User Sascha L. Teichmann # Date 1553535433 -3600 # Node ID 46a9a7c1281ff9b45ac98dfc45910ec9dea94e47 # Parent 054f5d61452d9993a6cd0d5e170fad87e096dcd1 Added GET /api/data/year-waterlevels/{gauge}/{year} diff -r 054f5d61452d -r 46a9a7c1281f pkg/controllers/gauges.go --- 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"] diff -r 054f5d61452d -r 46a9a7c1281f pkg/controllers/routes.go --- 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)