changeset 4362:89d2d9309a38

Merge in fa-round-in-backend branch
author Bernhard Reiter <bernhard@intevation.de>
date Mon, 09 Sep 2019 17:25:28 +0200
parents 90b72e811efd (diff) 8a26225b6133 (current diff)
children d6439e7c8b1c
files
diffstat 7 files changed, 229 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/fairway/AvailableFairwayDepthLNWL.vue	Mon Sep 09 17:24:14 2019 +0200
+++ b/client/src/components/fairway/AvailableFairwayDepthLNWL.vue	Mon Sep 09 17:25:28 2019 +0200
@@ -42,6 +42,17 @@
             >Download CSV</a
           >
         </div>
+        <div class="btn-group-toggle w-100 mt-2">
+          <label
+            class="btn btn-outline-secondary btn-sm"
+            :class="{ active: showNumbers }"
+            ><input
+              type="checkbox"
+              v-model="showNumbers"
+              autocomplete="off"
+            />Numbers
+          </label>
+        </div>
       </DiagramLegend>
       <div
         ref="diagramContainer"
@@ -69,6 +80,7 @@
  * * Thomas Junk <thomas.junk@intevation.de>
  * * Markus Kottländer <markus.kottlaender@intevation.de>
  * * Fadi Abbud <fadi.abbud@intevation.de>
+ * * Bernhard Reiter <bernhard.reiter@intevation.de>
  */
 import * as d3 from "d3";
 import app from "@/main";
@@ -103,7 +115,8 @@
       },
       templateData: null,
       templates: [],
-      defaultTemplate: defaultDiagramTemplate
+      defaultTemplate: defaultDiagramTemplate,
+      showNumbers: false
     };
   },
   created() {
@@ -477,6 +490,28 @@
         .attr("fill", (d, i) => {
           return this.$options.AFDCOLORS[i];
         });
+      if (this.showNumbers) {
+        afd
+          .selectAll("text")
+          .data([data.above, data.between, data.below])
+          .enter()
+          .append("text")
+          .attr("fill", "black")
+          .attr("text-anchor", "middle")
+          .attr("x", ldcWidth / 2)
+          .attr("y", (d, i) => {
+            let h = d; // i == 0
+            if (i > 0) {
+              h += data.above;
+            }
+            if (i > 1) {
+              h += data.between;
+            }
+            return yScale(h + 0.8) + this.paddingTop;
+          })
+          .text(d => (d > 0 ? Math.round(d) : ""))
+          .attr("font-size", "8");
+      }
     },
     drawLNWL(data, i, diagram, spaceBetween, widthPerItem, ldcWidth, yScale) {
       let lnwl = diagram
@@ -510,17 +545,24 @@
           //d3.event.pageX gives coordinates relative to SVG
           //dy gives offset of svg on page
         })
-        .attr("height", d => {
-          return yScale(0) - yScale(d);
-        })
-        .attr("y", d => {
-          return yScale(d);
-        })
+        .attr("height", d => yScale(0) - yScale(d))
+        .attr("y", d => yScale(d))
         .attr("transform", `translate(0 ${this.paddingTop})`)
         .attr("width", ldcWidth)
         .attr("fill", () => {
           return this.$options.LWNLCOLORS.LDC;
         });
+      if (this.showNumbers) {
+        // we do not need to bind data or a datum as the forEach in drawBars
+        // already brings us only one datum in data
+        lnwl
+          .append("text")
+          .attr("y", yScale(data.ldc + 0.8) + this.paddingTop)
+          .text(data.ldc)
+          .attr("text-anchor", "left")
+          .attr("fill", "black")
+          .attr("font-size", "8");
+      }
     },
     drawScaleLabel({ diagram, dimensions }) {
       diagram
@@ -530,6 +572,7 @@
         .attr("x", 0)
         .attr("y", 0)
         .attr("dy", "20")
+        .attr("fill", "black")
         // translate a few mm to the right to allow for slightly higher letters
         .attr(
           "transform",
@@ -603,6 +646,9 @@
   watch: {
     fwLNWLData() {
       this.drawDiagram();
+    },
+    showNumbers() {
+      this.drawDiagram();
     }
   },
   LEGEND: app.$gettext("Percent"),
--- a/client/src/components/identify/Identify.vue	Mon Sep 09 17:24:14 2019 +0200
+++ b/client/src/components/identify/Identify.vue	Mon Sep 09 17:25:28 2019 +0200
@@ -241,7 +241,9 @@
   data() {
     return {
       refGaugeStatus: "",
-      gaugeStatus: ""
+      gaugeStatus: "",
+      gaugeCoeffs: null,
+      refGaugeCoeffs: null
     };
   },
   computed: {
@@ -262,10 +264,17 @@
     gaugeStatusText() {
       const nsc24 = this.config.gm_forecast_vs_reality_nsc_24h;
       const nsc72 = this.config.gm_forecast_vs_reality_nsc_72h;
+      const coeffWarn = this.gaugeCoeffs ? this.gaugeCoeffs[2].value : "";
+      const coeffDanger = this.gaugeCoeffs ? this.gaugeCoeffs[0].value : "";
       const messagesPerState = {
-        OK: this.$gettext("Nash-Sutcliffe") + `>${nsc24} /24h >${nsc72} / 72h`,
-        WARNING: this.$gettext("Nash-Sutcliffe") + ` < ${nsc72} / 72h`,
-        DANGER: this.$gettext("Nash-Sutcliffe") + ` < ${nsc24} / 72h`,
+        OK:
+          this.$gettext("Nash-Sutcliffe") +
+          `(${coeffDanger} >${nsc24} /24h ${coeffWarn} >${nsc72} / 72h)`,
+        WARNING:
+          this.$gettext("Nash-Sutcliffe") + ` (${coeffWarn} < ${nsc72} / 72h)`,
+        DANGER:
+          this.$gettext("Nash-Sutcliffe") +
+          ` (${coeffDanger} < ${nsc24} / 72h)`,
         NEUTRAL: this.$gettext("Nash-Sutcliffe not available")
       };
       return messagesPerState[this.gaugeStatus];
@@ -276,10 +285,19 @@
     refGaugeStatusText() {
       const nsc24 = this.config.gm_forecast_vs_reality_nsc_24h;
       const nsc72 = this.config.gm_forecast_vs_reality_nsc_72h;
+      const coeffWarn = this.refGaugeCoeffs ? this.refGaugeCoeffs[2].value : "";
+      const coeffDanger = this.refGaugeCoeffs
+        ? this.refGaugeCoeffs[0].value
+        : "";
       const messagesPerState = {
-        OK: this.$gettext("Nash-Sutcliffe") + `>${nsc24} /24h >${nsc72} / 72h`,
-        WARNING: this.$gettext("Nash-Sutcliffe") + ` < ${nsc72} / 72h`,
-        DANGER: this.$gettext("Nash-Sutcliffe") + ` < ${nsc24} / 72h`,
+        OK:
+          this.$gettext("Nash-Sutcliffe") +
+          `(${coeffDanger} >${nsc24} /24h ${coeffWarn} >${nsc72} / 72h)`,
+        WARNING:
+          this.$gettext("Nash-Sutcliffe") + ` (${coeffWarn} < ${nsc72} / 72h)`,
+        DANGER:
+          this.$gettext("Nash-Sutcliffe") +
+          ` (${coeffDanger} < ${nsc24} / 72h)`,
         NEUTRAL: this.$gettext("Nash-Sutcliffe not available")
       };
       return messagesPerState[this.refGaugeStatus];
@@ -298,6 +316,7 @@
         this.$store
           .dispatch("gauges/getNashSutcliffeForISRS", isrs)
           .then(response => {
+            this.gaugeCoeffs = response.coeffs;
             this.gaugeStatus = classifications.calcForecastVsRealityForNSC(
               response
             );
@@ -311,6 +330,7 @@
         this.$store
           .dispatch("gauges/getNashSutcliffeForISRS", isrs)
           .then(response => {
+            this.refGaugeCoeffs = response.coeffs;
             this.refGaugeStatus = classifications.calcForecastVsRealityForNSC(
               response
             );
--- a/client/src/lib/classifications.js	Mon Sep 09 17:24:14 2019 +0200
+++ b/client/src/lib/classifications.js	Mon Sep 09 17:25:28 2019 +0200
@@ -12,6 +12,9 @@
  * Raimund Renkert <raimund.renkert@intevation.de>
  * Markus Kottländer <markus.kottlaender@intevation.de>
  */
+
+/*eslint no-unused-vars: ["error", { "varsIgnorePattern": "_" }]*/
+
 import store from "@/store/index";
 
 const getGauge = f => {
@@ -32,18 +35,21 @@
 };
 
 const calcForecastVsRealityForNSC = nsc => {
-  if (nsc && nsc.coeffs.reduce((sum, coeff) => sum + coeff.samples, 0)) {
+  const hasSamples =
+    nsc && nsc.coeffs.reduce((sum, coeff) => sum + coeff.samples, 0);
+  if (hasSamples) {
+    const [nsc24h, _, nsc72h] = nsc.coeffs;
     // 24h < configured value
     if (
-      nsc.coeffs[0].samples &&
-      nsc.coeffs[0].value <
+      nsc24h.samples &&
+      nsc24h.value <
         store.state.application.config.gm_forecast_vs_reality_nsc_24h
     )
       return "DANGER";
     // 72h < configured value
     if (
-      nsc.coeffs[2].samples &&
-      nsc.coeffs[2].value <
+      nsc72h.samples &&
+      nsc72h.value <
         store.state.application.config.gm_forecast_vs_reality_nsc_72h
     )
       return "WARNING";
--- a/schema/gemma.sql	Mon Sep 09 17:24:14 2019 +0200
+++ b/schema/gemma.sql	Mon Sep 09 17:25:28 2019 +0200
@@ -777,8 +777,8 @@
 
 -- Configure primary keys for geoserver views
 INSERT INTO waterway.gt_pk_metadata VALUES
-  ('waterway', 'gauges_geoserver', 'location'),
-  ('waterway', 'distance_marks_geoserver', 'location_code'),
+  ('waterway', 'gauges_geoserver', 'isrs_code'),
+  ('waterway', 'distance_marks_geoserver', 'location'),
   ('waterway', 'distance_marks_ashore_geoserver', 'id'),
   ('waterway', 'bottlenecks_geoserver', 'id'),
   ('waterway', 'stretches_geoserver', 'id'),
--- a/schema/geoserver_views.sql	Mon Sep 09 17:24:14 2019 +0200
+++ b/schema/geoserver_views.sql	Mon Sep 09 17:25:28 2019 +0200
@@ -55,13 +55,11 @@
 
 CREATE OR REPLACE VIEW waterway.gauges_geoserver AS
     SELECT
-        location,
         isrs_code,
         objname,
         geom,
         applicability_from_km,
         applicability_to_km,
-        validity,
         zero_point,
         geodref,
         date_info,
@@ -76,7 +74,7 @@
     WHERE NOT erased;
 
 CREATE OR REPLACE VIEW waterway.distance_marks_geoserver AS
-    SELECT location_code,
+    SELECT
        isrs_asText(location_code) AS location,
        geom::Geometry(POINT, 4326),
        related_enc,
@@ -99,7 +97,6 @@
         b.bottleneck_id,
         b.objnam,
         b.nobjnm,
-        b.stretch,
         b.area,
         b.rb,
         b.lb,
@@ -108,7 +105,6 @@
         b.limiting,
         b.date_info,
         b.source_organization,
-        g.location AS gauge_isrs_code,
         g.objname AS gauge_objname,
         g.reference_water_levels,
         fal.date_info AS fa_date_info,
@@ -155,7 +151,8 @@
         max(g.forecast_accuracy_3d) AS forecast_accuracy_3d,
         max(g.forecast_accuracy_1d) AS forecast_accuracy_1d
     FROM waterway.stretches s
-        LEFT JOIN waterway.gauges_geoserver g ON g.location <@ s.stretch
+        LEFT JOIN waterway.gauges_geoserver g
+            ON isrs_fromtext(g.isrs_code) <@ s.stretch
     GROUP BY s.id;
 
 CREATE OR REPLACE VIEW waterway.sections_geoserver AS
@@ -175,7 +172,8 @@
         max(g.forecast_accuracy_3d) AS forecast_accuracy_3d,
         max(g.forecast_accuracy_1d) AS forecast_accuracy_1d
     FROM waterway.sections s
-        LEFT JOIN waterway.gauges_geoserver g ON g.location <@ s.section
+        LEFT JOIN waterway.gauges_geoserver g
+            ON isrs_fromtext(g.isrs_code) <@ s.section
     GROUP BY s.id;
 
 CREATE OR REPLACE VIEW waterway.sounding_results_contour_lines_geoserver AS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/updates/1112/01.cleanup_views.sql	Mon Sep 09 17:25:28 2019 +0200
@@ -0,0 +1,130 @@
+DROP VIEW waterway.gauges_geoserver CASCADE;
+CREATE VIEW waterway.gauges_geoserver AS
+    SELECT
+        isrs_code,
+        objname,
+        geom,
+        applicability_from_km,
+        applicability_to_km,
+        zero_point,
+        geodref,
+        date_info,
+        source_organization,
+        reference_water_levels,
+        gm_measuredate,
+        gm_waterlevel,
+        gm_n_14d,
+        forecast_accuracy_3d,
+        forecast_accuracy_1d
+    FROM waterway.gauges_base_view
+    WHERE NOT erased;
+
+DROP VIEW waterway.distance_marks_geoserver;
+CREATE VIEW waterway.distance_marks_geoserver AS
+    SELECT
+       isrs_asText(location_code) AS location,
+       geom::Geometry(POINT, 4326),
+       related_enc,
+       (location_code).hectometre
+    FROM waterway.distance_marks_virtual;
+
+DROP VIEW waterway.bottlenecks_geoserver;
+CREATE OR REPLACE VIEW waterway.bottlenecks_geoserver AS
+    SELECT
+        b.id,
+        b.bottleneck_id,
+        b.objnam,
+        b.nobjnm,
+        b.area,
+        b.rb,
+        b.lb,
+        b.responsible_country,
+        b.revisiting_time,
+        b.limiting,
+        b.date_info,
+        b.source_organization,
+        g.objname AS gauge_objname,
+        g.reference_water_levels,
+        fal.date_info AS fa_date_info,
+        fal.critical AS fa_critical,
+        g.gm_measuredate,
+        g.gm_waterlevel,
+        g.gm_n_14d,
+        srl.date_max,
+        g.forecast_accuracy_3d,
+        g.forecast_accuracy_1d
+    FROM waterway.bottlenecks b
+        LEFT JOIN waterway.gauges_base_view g
+            ON b.gauge_location = g.location AND g.validity @> current_timestamp
+        LEFT JOIN (SELECT DISTINCT ON (bottleneck_id)
+                    bottleneck_id, date_info, critical
+                FROM waterway.fairway_availability
+                ORDER BY bottleneck_id, date_info DESC) AS fal
+            ON b.bottleneck_id = fal.bottleneck_id
+        LEFT JOIN (SELECT DISTINCT ON (bottleneck_id)
+                    bottleneck_id, max(date_info) AS date_max
+                FROM waterway.sounding_results
+                GROUP BY bottleneck_id
+                ORDER BY bottleneck_id DESC) AS srl
+            ON b.bottleneck_id = srl.bottleneck_id
+    WHERE b.validity @> current_timestamp;
+
+CREATE VIEW waterway.stretches_geoserver AS
+    SELECT
+        s.id,
+        s.name,
+        (s.stretch).lower::varchar as lower,
+        (s.stretch).upper::varchar as upper,
+        s.area::Geometry(MULTIPOLYGON, 4326),
+        s.objnam,
+        s.nobjnam,
+        s.date_info,
+        s.source_organization,
+        (SELECT string_agg(country_code, ', ')
+            FROM waterway.stretch_countries
+            WHERE stretches_id = s.id) AS countries,
+        s.staging_done,
+        min(g.gm_measuredate) AS gm_measuredate,
+        min(g.gm_n_14d) AS gm_n_14d,
+        max(g.forecast_accuracy_3d) AS forecast_accuracy_3d,
+        max(g.forecast_accuracy_1d) AS forecast_accuracy_1d
+    FROM waterway.stretches s
+        LEFT JOIN waterway.gauges_geoserver g
+            ON isrs_fromtext(g.isrs_code) <@ s.stretch
+    GROUP BY s.id;
+
+CREATE VIEW waterway.sections_geoserver AS
+    SELECT
+        s.id,
+        s.name,
+        (s.section).lower::varchar as lower,
+        (s.section).upper::varchar as upper,
+        s.area::Geometry(MULTIPOLYGON, 4326),
+        s.objnam,
+        s.nobjnam,
+        s.date_info,
+        s.source_organization,
+        s.staging_done,
+        min(g.gm_measuredate) AS gm_measuredate,
+        min(g.gm_n_14d) AS gm_n_14d,
+        max(g.forecast_accuracy_3d) AS forecast_accuracy_3d,
+        max(g.forecast_accuracy_1d) AS forecast_accuracy_1d
+    FROM waterway.sections s
+        LEFT JOIN waterway.gauges_geoserver g
+            ON isrs_fromtext(g.isrs_code) <@ s.section
+    GROUP BY s.id;
+
+UPDATE waterway.gt_pk_metadata SET pk_column = 'isrs_code'
+    WHERE table_schema = 'waterway'
+        AND table_name = 'gauges_geoserver';
+UPDATE waterway.gt_pk_metadata SET pk_column = 'location'
+    WHERE table_schema = 'waterway'
+        AND table_name = 'distance_marks_geoserver';
+
+GRANT SELECT ON
+        waterway.gauges_geoserver,
+        waterway.distance_marks_geoserver,
+        waterway.bottlenecks_geoserver,
+        waterway.stretches_geoserver,
+        waterway.sections_geoserver
+    TO waterway_user;
--- a/schema/version.sql	Mon Sep 09 17:24:14 2019 +0200
+++ b/schema/version.sql	Mon Sep 09 17:25:28 2019 +0200
@@ -1,1 +1,1 @@
-INSERT INTO gemma_schema_version(version) VALUES (1111);
+INSERT INTO gemma_schema_version(version) VALUES (1112);