# HG changeset patch # User Tom Gottfried # Date 1568044011 -7200 # Node ID 32d3e0cecf4f7c424ff82cfe031fab99ca5a7b0e # Parent 970e90d3d5ebc8c8096173d6d40e639b8981df22# Parent 496bbf0f618c27416b3668424e9ea8b85043e198 Merge default into geoserver_sql_views diff -r 970e90d3d5eb -r 32d3e0cecf4f client/docs/developers.md --- a/client/docs/developers.md Mon Sep 09 17:24:07 2019 +0200 +++ b/client/docs/developers.md Mon Sep 09 17:46:51 2019 +0200 @@ -36,16 +36,16 @@ ```javascript data = store.state.fairwayavailability.csv // see current data -data=`#time,# < LDC (164.0) [h],# >= LDC (164.0) [h],# < 230.0 [h],# >= 230.0 [h],# >= 250.0 [h] -01-2019,0 ,744, 0, 0,744 -02-2019,324,324,150,174,324 -03-2019, 24,696, 80, 45, 50 -04-2019,120,600, 24, 24,672.5 -05-2019,140,80 , 80, 45, 50 -06-2019, 0, 0, 0, 0, 0.000 -07-2019, 0,300, 0, 0, 0 -08-2019, 0, 0,744, 0, 0 -09-2019, 0,720, 0, 96,624 +data=`#time,# < LDC (164.0) [d],# >= LDC (164.0) [d],# < 230.0 [d],# >= 230.0 [d],# >= 250.0 [d] +01-2019, 0,31, 0, 0,31 +02-2019,14,14, 6, 8,14 +03-2019, 1,30, 3, 2, 2 +04-2019, 5,25, 1, 1,28 +05-2019, 6,25, 3, 2, 3 +06-2019, 0, 0, 0, 0, 0 +07-2019, 0,16, 0, 0, 0 +08-2019, 0, 0,31, 0, 0 +09-2019, 0, 9, 0, 3, 9 ` store.commit("fairwayavailability/setAvailableFairwayDepthData", data) @@ -55,8 +55,7 @@ ```javascript data = store.state.fairwayavailability.csv // see current data -data=` -#time,# < LDC (162.0) [h],# >= LDC (162.0) [h],#d < 230.0 [%],#d >= 230.0 [%],#d >= 250.0 [%] +data=`#time,# < LDC (162.0) [h],# >= LDC (162.0) [h],#d < 230.0 [%],#d >= 230.0 [%],#d >= 250.0 [%] 09-2018,100, 0,100 , 0, 0 10-2018,100, 0, 80 , 20, 0 11-2018,100, 0, 0 , 100, 0 diff -r 970e90d3d5eb -r 32d3e0cecf4f client/src/components/fairway/AvailableFairwayDepth.vue --- a/client/src/components/fairway/AvailableFairwayDepth.vue Mon Sep 09 17:24:07 2019 +0200 +++ b/client/src/components/fairway/AvailableFairwayDepth.vue Mon Sep 09 17:46:51 2019 +0200 @@ -93,15 +93,6 @@ import { FREQUENCIES } from "@/store/fairwayavailability"; import { defaultDiagramTemplate } from "@/lib/DefaultDiagramTemplate"; -// FIXME This is a rounding methods that shows that we have fractions, -// because we are coming from hours. Users will understand the underlying -// math better and we can see if this is wanted. -// With the backend just giving us the summarized hours, we cannot do -// a classification of each day into a category. -// (The name of the function is kept to keep the diff more readable and -// should changed if this is more clarified.) -const hoursInDays = x => Math.round((x * 10) / 24) / 10; - export default { mixins: [diagram, pdfgen, templateLoader], components: { @@ -475,19 +466,15 @@ .querySelector(".diagram-container") .getBoundingClientRect().left; d3.select("#tooltip") - .text(hoursInDays(d.height)) + .text(d.height) .attr("y", y - 10) .attr("x", d3.event.pageX - dy); //d3.event.pageX gives coordinates relative to SVG //dy gives offset of svg on page }) - .attr("y", d => { - return ( - 2 * yScale(0) - yScale(hoursInDays(d.translateY)) + this.paddingTop - ); - }) + .attr("y", d => 2 * yScale(0) - yScale(d.translateY) + this.paddingTop) .attr("height", d => { - return yScale(0) - yScale(hoursInDays(d.height)); + return yScale(0) - yScale(d.height); }) .attr("x", ldcOffset + spaceBetween / 2) .attr("width", widthPerItem - ldcOffset - spaceBetween) @@ -500,19 +487,19 @@ .selectAll("g.bars") .data(d => d.lowerLevels) .enter() - .filter(d => hoursInDays(d.height) > 0) + .filter(d => d.height > 0) .insert("text") .attr("y", d => { return ( 2 * yScale(0) - - yScale(hoursInDays(d.translateY)) + + yScale(d.translateY) + this.paddingTop + - (yScale(0) - yScale(hoursInDays(d.height))) + + (yScale(0) - yScale(d.height)) + (yScale(0) - yScale(1.9)) //instead o alignment-baseline hanging ); }) .attr("x", widthPerItem / 2) - .text(d => hoursInDays(d.height)) + .text(d => d.height) // does not work with svg2pdf .attr("alignment-baseline", "hanging") .attr("text-anchor", "middle") .attr("font-size", "8") @@ -520,7 +507,7 @@ } }, fnheight({ name, yScale }) { - return d => yScale(0) - yScale(hoursInDays(d[name])); + return d => yScale(0) - yScale(d[name]); }, drawLDC({ everyBar, yScale, widthPerItem, spaceBetween, ldcOffset }) { const height = this.fnheight({ name: "ldc", yScale }); @@ -540,7 +527,7 @@ .querySelector(".diagram-container") .getBoundingClientRect().left; d3.select("#tooltip") - .text(hoursInDays(d.ldc)) + .text(d.ldc) .attr("y", y - 50) .attr("x", d3.event.pageX - dy); //d3.event.pageX gives coordinates relative to SVG @@ -558,11 +545,11 @@ .attr("id", "ldc"); if (this.showNumbers) { everyBar - .filter(d => hoursInDays(d.ldc) > 0) + .filter(d => d.ldc > 0) .append("text") .attr("y", yScale(0.5)) // some distance from the bar .attr("x", spaceBetween / 2) - .text(d => hoursInDays(d.ldc)) + .text(d => d.ldc) .attr("text-anchor", "left") .attr("font-size", "8") .attr( @@ -596,7 +583,7 @@ .querySelector(".diagram-container") .getBoundingClientRect().left; d3.select("#tooltip") - .text(hoursInDays(d.highestLevel)) + .text(d.highestLevel) .attr("y", y - 50) .attr("x", d3.event.pageX - dy); //d3.event.pageX gives coordinates relative to SVG @@ -613,11 +600,11 @@ .attr("fill", this.$options.COLORS.HIGHEST); if (this.showNumbers) { everyBar - .filter(d => hoursInDays(d.highestLevel) > 0) + .filter(d => d.highestLevel > 0) .append("text") .attr("y", yScale(0.5)) // some distance from the bar .attr("x", widthPerItem / 2) - .text(d => hoursInDays(d.highestLevel)) + .text(d => d.highestLevel) .attr("text-anchor", "middle") .attr("font-size", "8") .attr( diff -r 970e90d3d5eb -r 32d3e0cecf4f pkg/common/round.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/common/round.go Mon Sep 09 17:46:51 2019 +0200 @@ -0,0 +1,71 @@ +// This is Free Software under GNU Affero General Public License v >= 3.0 +// without warranty, see README.md and license for details. +// +// SPDX-License-Identifier: AGPL-3.0-or-later +// License-Filename: LICENSES/AGPL-3.0.txt +// +// Copyright (C) 2018 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha Wilde + +package common + +import ( + "math" + "sort" + "time" +) + +type Rest struct { + Key int + Rest float64 +} + +// Simple sum preserving rounding method: +func SumPreservingRound(arr []float64) []int { + var ( + sum float64 + rests []Rest + ) + result := make([]int, len(arr)) + + // floor all values + for i, v := range arr { + sum += v + result[i] = int(v) + rests = append(rests, Rest{Key: i, Rest: v - float64(result[i])}) + } + + // find the difference in summs + var newSum int + for _, v := range result { + newSum += v + } + delta := int(math.Round(sum)) - newSum + + // spread delta over values with highest rest + sort.Slice(rests, func(i, j int) bool { + return rests[i].Rest > rests[j].Rest + }) + for _, v := range rests { + if delta <= 0 { + break + } + result[v.Key]++ + delta-- + } + + return result +} + +// Round anarray of Duratons to full days +func RoundToFullDays(durations []time.Duration) []int { + days := make([]float64, len(durations)) + for i, v := range durations { + days[i] = v.Hours() / 24 + } + return SumPreservingRound(days) +} diff -r 970e90d3d5eb -r 32d3e0cecf4f pkg/controllers/bottlenecks.go --- a/pkg/controllers/bottlenecks.go Mon Sep 09 17:24:07 2019 +0200 +++ b/pkg/controllers/bottlenecks.go Mon Sep 09 17:46:51 2019 +0200 @@ -503,8 +503,8 @@ record := make([]string, 1+2+len(breaks)+1) record[0] = "#time" - record[1] = fmt.Sprintf("# < LDC (%.1f) [h]", ldcRefs[0]) - record[2] = fmt.Sprintf("# >= LDC (%.1f) [h]", ldcRefs[0]) + record[1] = fmt.Sprintf("# < LDC (%.1f) [%%]", ldcRefs[0]) + record[2] = fmt.Sprintf("# >= LDC (%.1f) [%%]", ldcRefs[0]) for i, v := range breaks { if i == 0 { record[3] = fmt.Sprintf("#d < %.1f [%%]", v) @@ -653,13 +653,13 @@ // label, ldc, classes record := make([]string, 1+2+len(breaks)+1) record[0] = "#time" - record[1] = fmt.Sprintf("# < LDC (%.1f) [h]", ldcRefs[0]) - record[2] = fmt.Sprintf("# >= LDC (%.1f) [h]", ldcRefs[0]) + record[1] = fmt.Sprintf("# < LDC (%.1f) [d]", ldcRefs[0]) + record[2] = fmt.Sprintf("# >= LDC (%.1f) [d]", ldcRefs[0]) for i, v := range breaks { if i == 0 { - record[3] = fmt.Sprintf("# < %.1f [h]", v) + record[3] = fmt.Sprintf("# < %.1f [d]", v) } - record[i+4] = fmt.Sprintf("# >= %.1f [h]", v) + record[i+4] = fmt.Sprintf("# >= %.1f [d]", v) } if err := out.Write(record); err != nil { @@ -701,13 +701,17 @@ access, ) + // Round to full days + ldcRounded := common.RoundToFullDays(ldc) + rangesRounded := common.RoundToFullDays(ranges) + record[0] = label - for i, v := range ldc { - record[i+1] = fmt.Sprintf("%.3f", v.Hours()) + for i, v := range ldcRounded { + record[i+1] = fmt.Sprintf("%d", v) } - for i, d := range ranges { - record[3+i] = fmt.Sprintf("%.3f", d.Hours()) + for i, d := range rangesRounded { + record[3+i] = fmt.Sprintf("%d", d) } if err := out.Write(record); err != nil { diff -r 970e90d3d5eb -r 32d3e0cecf4f pkg/controllers/stretches.go --- a/pkg/controllers/stretches.go Mon Sep 09 17:24:07 2019 +0200 +++ b/pkg/controllers/stretches.go Mon Sep 09 17:46:51 2019 +0200 @@ -27,6 +27,7 @@ "github.com/gorilla/mux" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/middleware" ) @@ -348,19 +349,19 @@ // label, lnwl, classes record := make([]string, 1+2+len(breaks)+1) record[0] = "# time" - record[1] = "# < LDC [h]" - record[2] = "# >= LDC [h]" + record[1] = "# < LDC [d]" + record[2] = "# >= LDC [d]" for i, v := range breaks { if useDepth && useWidth { if i == 0 { - record[3] = "# < break_1 [h]" + record[3] = "# < break_1 [d]" } record[i+4] = fmt.Sprintf("# >= break_%d", i+1) } else { if i == 0 { - record[3] = fmt.Sprintf("# < %.1f [h]", v) + record[3] = fmt.Sprintf("# < %.1f [d]", v) } - record[i+4] = fmt.Sprintf("# >= %.1f [h]", v) + record[i+4] = fmt.Sprintf("# >= %.1f [d]", v) } } @@ -379,13 +380,23 @@ } for _, r := range results { - record[0] = r.label + // Round to full days for i, v := range r.ldc { - record[1+i] = fmt.Sprintf("%.3f", v.Hours()*scale) + r.ldc[i] = time.Duration(float64(v) * scale) + } + for i, v := range r.breaks { + r.breaks[i] = time.Duration(float64(v) * scale) + } + ldcRounded := common.RoundToFullDays(r.ldc) + rangesRounded := common.RoundToFullDays(r.breaks) + + record[0] = r.label + for i, v := range ldcRounded { + record[1+i] = fmt.Sprintf("%d", v) } - for i, d := range r.breaks { - record[3+i] = fmt.Sprintf("%.3f", d.Hours()*scale) + for i, d := range rangesRounded { + record[3+i] = fmt.Sprintf("%d", d) } if err := out.Write(record); err != nil { diff -r 970e90d3d5eb -r 32d3e0cecf4f schema/default_sysconfig.sql --- a/schema/default_sysconfig.sql Mon Sep 09 17:24:07 2019 +0200 +++ b/schema/default_sysconfig.sql Mon Sep 09 17:46:51 2019 +0200 @@ -12,6 +12,7 @@ -- * Sascha Wilde -- * Bernhard Reiter -- * Fadi Abbund +-- * Tom Gottfried BEGIN; @@ -20,6 +21,24 @@ -- -- +-- Tables and views published via GeoServer +-- +INSERT INTO sys_admin.published_services (schema, name) VALUES + ('waterway', 'sections_geoserver'), + ('waterway', 'stretches_geoserver'), + ('waterway', 'fairway_dimensions'), + ('waterway', 'gauges_geoserver'), + ('waterway', 'distance_marks_ashore_geoserver'), + ('waterway', 'distance_marks_geoserver'), + ('waterway', 'sounding_results_contour_lines_geoserver'), + ('waterway', 'bottlenecks_geoserver'), + ('waterway', 'bottleneck_overview'), + ('waterway', 'waterway_axis'), + ('waterway', 'waterway_area'), + ('waterway', 'waterway_profiles'), + ('waterway', 'sounding_differences'); + +-- -- Settings -- INSERT INTO sys_admin.system_config VALUES ('ecdis_wms_url', 'https://service.d4d-portal.info/wms/'); diff -r 970e90d3d5eb -r 32d3e0cecf4f schema/demo-data/published_services.sql --- a/schema/demo-data/published_services.sql Mon Sep 09 17:24:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ --- This is Free Software under GNU Affero General Public License v >= 3.0 --- without warranty, see README.md and license for details. - --- SPDX-License-Identifier: AGPL-3.0-or-later --- License-Filename: LICENSES/AGPL-3.0.txt - --- Copyright (C) 2018 by via donau --- – Österreichische Wasserstraßen-Gesellschaft mbH --- Software engineering by Intevation GmbH - --- Author(s): --- * Tom Gottfried - -INSERT INTO sys_admin.published_services (schema, name, view_def) VALUES - ('waterway', 'sections_geoserver', NULL), - ('waterway', 'stretches_geoserver', NULL), - ('waterway', 'fairway_dimensions', NULL), - ('waterway', 'gauges_geoserver', NULL), - ('waterway', 'distance_marks_ashore_geoserver', NULL), - ('waterway', 'distance_marks_geoserver', NULL), - ('waterway', 'sounding_results_contour_lines_geoserver', NULL), - ('waterway', 'bottlenecks_geoserver', NULL), - ('waterway', 'bottleneck_overview', NULL), - ('waterway', 'waterway_axis', NULL), - ('waterway', 'waterway_area', NULL), - ('waterway', 'waterway_profiles', NULL), - ('waterway', 'sounding_differences', NULL) -ON CONFLICT DO NOTHING