changeset 4890:5d9c7fcda566

Fix drawing of fairway profile. The basic functionality for calculating the graph to draw resides in geo.js This was a port of existing code from the backend (cross.go). For historic reasons there was a bug present in this code which was fixed in the backend. The height was transformed via Math.abs() which results in strange behavior for measurements above the waterlevel. Points which are 1.5m above the waterlevel were drawn 1.5m below the waterlevel. There were two fixes: 1) The y-component of the x/y-pair of the fairwayprofile point is taken as is without Math.abs() 2) To draw the diagram, there is the definition of a domain necessarry. A minimum value for the values above the waterlevel is constructed in case there is no point above (10 percent of the range below the waterlevel). In case there are values above the waterlevel which in turn means the minumum value is < 0, there is this value taken as a minimum. D3 scales accordingly.
author Thomas Junk <thomas.junk@intevation.de>
date Mon, 10 Feb 2020 15:09:59 +0100
parents ab6eb160cd29
children e68220372832
files client/src/components/fairway/Fairwayprofile.vue client/src/lib/geo.js
diffstat 2 files changed, 22 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/fairway/Fairwayprofile.vue	Sun Feb 09 20:24:54 2020 +0100
+++ b/client/src/components/fairway/Fairwayprofile.vue	Mon Feb 10 15:09:59 2020 +0100
@@ -197,6 +197,7 @@
       "startPoint",
       "endPoint",
       "fairwayData",
+      "minAlt",
       "maxAlt",
       "selectedWaterLevel",
       "depth",
@@ -652,21 +653,28 @@
         .scaleLinear()
         .domain([0, this.totalLength])
         .rangeRound([0, width]);
-
+      // Upper limit is relevant for the extension of the y-Axis
+      // If there is no measure above the waterlevel we choose a cosmetic value of this.maxAlt *0.1
+      // to get a bit of space above the waterlevel.
+      // Otherwise we take the maximum measured value
+      const upperLimit =
+        this.minAlt > 0 ? this.maxAlt * 0.1 : Math.abs(this.minAlt);
+      // In order to draw positive values downwards, we switch both values in the
+      // domain definition [min, max] => [max, min] has the desired effect.
       let yScaleRight = d3
         .scaleLinear()
         .domain([
           this.maxAlt * 1.1 + (this.waterlevel - this.refWaterlevel) / 100,
-          -(this.maxAlt * 0.1)
+          -upperLimit
         ])
         .rangeRound([height, 0]);
-
+      // This definition is accordingly but uses values * 100 for the tickformatter
       let yScaleLeft = d3
         .scaleLinear()
         .domain([
           this.waterlevel -
             (this.maxAlt * 110 + (this.waterlevel - this.refWaterlevel)),
-          this.waterlevel + this.maxAlt * 10
+          this.waterlevel + upperLimit * 100
         ])
         .rangeRound([height, 0]);
 
--- a/client/src/lib/geo.js	Sun Feb 09 20:24:54 2020 +0100
+++ b/client/src/lib/geo.js	Mon Feb 10 15:09:59 2020 +0100
@@ -20,19 +20,20 @@
  *
  */
 
-import { GeoJSON } from "ol/format";
-import Feature from "ol/Feature";
-import distance from "@turf/distance";
 import {
   lineString as turfLineString,
-  polygon as turfPolygon,
-  point as turfPoint
+  point as turfPoint,
+  polygon as turfPolygon
 } from "@turf/helpers";
-import lineSplit from "@turf/line-split";
-import lineSlice from "@turf/line-slice";
-import lineIntersect from "@turf/line-intersect";
+
+import Feature from "ol/Feature";
+import { GeoJSON } from "ol/format";
 // import booleanWithin from "@turf/boolean-within";
 import booleanContains from "@turf/boolean-contains";
+import distance from "@turf/distance";
+import lineIntersect from "@turf/line-intersect";
+import lineSlice from "@turf/line-slice";
+import lineSplit from "@turf/line-split";
 
 const EARTHRADIUS = 6378137.0;
 
@@ -113,7 +114,7 @@
     for (let coordinateTriplet of segment) {
       currentPoint = Point(coordinateTriplet);
       lengthPolyLine += distanceBetween(referencePoint, currentPoint);
-      let y = Math.abs(currentPoint.alt);
+      let y = currentPoint.alt;
       points.push({
         x: lengthPolyLine,
         y: y