# HG changeset patch # User mschaefer # Date 1530802182 -7200 # Node ID 0dcd1cd41915ac269617d79ea6366d778695461d # Parent dba14da43f234295d3730c2e7b3cb28126d62646 Different themes/facets for left bank and right bank infrastructures in S-Info flood durations, some fixmes done diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/doc/conf/artifacts/sinfo.xml --- a/artifacts/doc/conf/artifacts/sinfo.xml Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/doc/conf/artifacts/sinfo.xml Thu Jul 05 16:49:42 2018 +0200 @@ -359,13 +359,15 @@ - + + - + + diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/doc/conf/themes.xml --- a/artifacts/doc/conf/themes.xml Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/doc/conf/themes.xml Thu Jul 05 16:49:42 2018 +0200 @@ -445,9 +445,12 @@ - + + + + diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/doc/conf/themes/default.xml --- a/artifacts/doc/conf/themes/default.xml Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/doc/conf/themes/default.xml Thu Jul 05 16:49:42 2018 +0200 @@ -2812,6 +2812,24 @@ + + + + + + + + + + + + + + + + + + @@ -2839,7 +2857,7 @@ - + @@ -2848,6 +2866,15 @@ + + + + + + + + + diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/doc/conf/themes/second.xml --- a/artifacts/doc/conf/themes/second.xml Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/doc/conf/themes/second.xml Thu Jul 05 16:49:42 2018 +0200 @@ -2800,6 +2800,24 @@ + + + + + + + + + + + + + + + + + + @@ -2827,7 +2845,7 @@ - + @@ -2836,6 +2854,15 @@ + + + + + + + + + diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java Thu Jul 05 16:49:42 2018 +0200 @@ -24,6 +24,7 @@ import org.dive4elements.river.artifacts.common.IResultType; import org.dive4elements.river.artifacts.context.RiverContext; import org.dive4elements.river.artifacts.math.MovingAverage; +import org.dive4elements.river.artifacts.model.WQKms; import org.dive4elements.river.artifacts.model.ZoomScale; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; @@ -120,38 +121,29 @@ return metaData.get("Y"); } - // protected final String buildSeriesForType1(final DiagramGenerator generator, final ArtifactAndFacet bundle, final - // ThemeDocument theme, - // final boolean visible, final IResultType resultType, final Double gapDistance) { - // final CallContext context = generator.getContext(); - // final Map metaData = bundle.getFacet().getMetaData(); - // - // final Artifact artifact = bundle.getArtifact(); - // - // final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); - // series.putMetaData(metaData, artifact, context); - // - // final String facetName = bundle.getFacetName(); - // - // final AbstractCalculationResult data = (AbstractCalculationResult) bundle.getData(context); - // if (data == null) { - // // Check has been here before so we keep it for security reasons - // // this should never happen though. - // throw new IllegalStateException("Data is null for facet: " + facetName); - // } - // - // final double[][] points = generatePoints(context, artifact, data, facetName, resultType, - // bundle.getFacet().getIndex()); - // - // if (gapDistance == null) - // StyledSeriesBuilder.addPoints(series, points, true); - // else - // StyledSeriesBuilder.addPoints(series, points, true, gapDistance); - // - // generator.addAxisSeries(series, getAxisName(), visible); - // - // return metaData.get("Y"); - // } + protected final String buildStepLineSeriesForType(final double[][] points, final DiagramGenerator generator, final ArtifactAndFacet bundle, + final ThemeDocument theme, final boolean visible) { + + final CallContext context = generator.getContext(); + final Map metaData = bundle.getFacet().getMetaData(); + + final Artifact artifact = bundle.getArtifact(); + + final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); + series.putMetaData(metaData, artifact, context); + + final String facetName = bundle.getFacetName(); + + // Create WQKms to use the step points method + // REMARK: must have any values in w array; not sure whether the name is needed + final WQKms wqkms = new WQKms(points[0], points[1], points[1], facetName); + + StyledSeriesBuilder.addStepPointsKmQ(series, wqkms); + + generator.addAxisSeries(series, getAxisName(), visible); + + return metaData.get("Y"); + } protected final String buildSeriesForTkh(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) { @@ -202,19 +194,6 @@ return points; } - // private double[][] generatePoints(final CallContext context, final Artifact artifact, final AbstractCalculationResult - // data, final String facetName, - // final IResultType resultType, final int index) { - // - // final double[][] points = data.getStationPoints(resultType, index); - // if (facetName.endsWith(".filtered")) { - // final Double radius = findRadius(context, artifact); - // return movingAverage(radius, points); - // } - // - // return points; - // } - private double[][] movingAverage(final Double radius, final double[][] points) { if (radius == null) diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java Thu Jul 05 16:49:42 2018 +0200 @@ -93,6 +93,13 @@ return gauge == null ? this.notinrange : gauge.getName(); } + public String findGauge(final double km, final boolean allGauges) { + // REMARK: access the gauge once only during calculation + final Gauge gauge = getGauge(km, allGauges); + + return gauge == null ? this.notinrange : gauge.getName(); + } + private Gauge getGauge(final double km) { // REMARK: using same logic as in WaterlevelExporter here diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Thu Jul 05 16:49:42 2018 +0200 @@ -17,6 +17,7 @@ import org.dive4elements.river.artifacts.common.I18NStrings; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; +import org.dive4elements.river.model.Attribute.AttributeKey; import org.dive4elements.river.utils.Formatter; import org.dive4elements.river.utils.RiverUtils; @@ -328,7 +329,7 @@ @Override public String exportValue(final CallContext context, final Object value) { - return exportStringValue(value); + return localizeRiverside(context, (AttributeKey) value); } @Override @@ -337,6 +338,19 @@ } }; + /** + * Returns the localized text of a riverside + * FIXME: Find a better place for this common method + */ + public static final String localizeRiverside(final CallContext context, final AttributeKey riverside) { + if (riverside == AttributeKey.LEFT) + return Resources.getMsg(context.getMeta(), "riverside.left"); + else if (riverside == AttributeKey.RIGHT) + return Resources.getMsg(context.getMeta(), "riverside.right"); + else + return "?"; + } + public static final SInfoResultType gaugeLabel = new SInfoResultType(I18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_GAUGE_HEADER) { private static final long serialVersionUID = 1L; diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java Thu Jul 05 16:49:42 2018 +0200 @@ -14,6 +14,7 @@ import org.dive4elements.river.artifacts.access.RangeAccess; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode; +import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; /** * Access to the flood duration calculation type specific SInfo artifact data. @@ -40,7 +41,7 @@ return super.getStep(); } - public String getRiverside() { - return super.getString("riverside"); + public RiversideChoiceKey getRiverside() { + return RiversideChoiceKey.fromKey(super.getString("riverside")); } } \ No newline at end of file diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Thu Jul 05 16:49:42 2018 +0200 @@ -49,20 +49,20 @@ final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); - final String riverside = Resources.getMsg(this.context.getMeta(), access.getRiverside()); final Infrastructure infrasSeries = Infrastructure.getSeries(river); final String infrasType = (infrasSeries != null) ? infrasSeries.getType().getName() : "?"; + final String label = infrasType + ", " + Resources.getMsg(this.context.getMeta(), access.getRiverside().getKey()); final Calculation problems = new Calculation(); // Calculate the selected main values, if any /* misuse winfo-artifact to calculate waterlevels in the same way */ final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo); + // TODO Aktivieren wenn Step-Eingabe im Workflow weg: winfo.addStringData("ld_step", "100"); final FloodDurationCalculationResults results = new FloodDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange); - final FloodDurationCalculationResult result = calculateResult(infrasType, riverside, calcRange, infoProvider, - RiversideChoiceKey.fromKey(access.getRiverside()), problems, winfo); + final FloodDurationCalculationResult result = calculateResult(label, calcRange, infoProvider, access.getRiverside(), problems, winfo); results.addResult(result, problems); return new CalculationResult(results, problems); @@ -71,11 +71,10 @@ /** * Calculates the flood durations of the infrastructures of a km range of a river */ - private FloodDurationCalculationResult calculateResult(final String infrastructureType, final String riverside, final DoubleRange calcRange, - final RiverInfoProvider riverInfoProvider, final RiversideChoiceKey riversideKey, final Calculation problems, final WINFOArtifact winfo) { + private FloodDurationCalculationResult calculateResult(final String label, final DoubleRange calcRange, final RiverInfoProvider riverInfoProvider, + final RiversideChoiceKey riverside, final Calculation problems, final WINFOArtifact winfo) { final FloodDurationCalculator calculator = new FloodDurationCalculator(this.context, riverInfoProvider); - final String label = infrastructureType + ", " + riverside; - return calculator.execute(problems, label, calcRange, riversideKey, winfo); + return calculator.execute(problems, label, calcRange, riverside, winfo); } } \ No newline at end of file diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java Thu Jul 05 16:49:42 2018 +0200 @@ -27,6 +27,7 @@ import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.exports.DiagramGenerator; +import org.dive4elements.river.model.Attribute.AttributeKey; import gnu.trove.TDoubleArrayList; @@ -41,8 +42,8 @@ private final String[] mainvalueLabels; - private final int waterlevelCount; // private final WstInfo wstInfo; + private final int maxWaterlevelPdf = 3; public interface ValueGetter { @@ -56,20 +57,9 @@ public FloodDurationCalculationResult(final String label, final String[] mainvalueLabels, final Collection rows) { super(label, rows); this.mainvalueLabels = mainvalueLabels; - this.waterlevelCount = mainvalueLabels.length; } /** - * The label of one of the optional main values, or null - */ - // public String getMainValueLabel(final int index) { - // if (index <= this.mainvalueLabels.length - 1) - // return this.mainvalueLabels[index]; - // else - // return null; - // } - - /** * Collection of the result rows containing only the rows describing an infrastructure */ @Override @@ -81,38 +71,6 @@ return Collections.unmodifiableCollection(infrasOnlyRows); } - /** - * Fetches the km-longitudinal section of the infrastructures and one of their result fields - */ - public final double[][] fetchInfrastructurePoints(final IResultType type) { - final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); - for (final ResultRow row : this.rows) { - if (row.getValue(SInfoResultType.infrastructuretype) != null) { - xPoints.add(row.getDoubleValue(GeneralResultType.station)); - yPoints.add(row.getDoubleValue(type)); - } - } - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - - /** - * Fetches the km-longitudinal section of a main value - */ - public final double[][] fetchMainValuePoints(final IResultType type) { - final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); - // final IResultType check = new IResultType[] { SInfoResultType.mainValue1Duration, SInfoResultType.mainValue2Duration, - // SInfoResultType.mainValue3Duration }[index]; - for (final ResultRow row : this.rows) { - // if (!Double.isNaN(row.getDoubleValue(check))) { - xPoints.add(row.getDoubleValue(GeneralResultType.station)); - yPoints.add(row.getDoubleValue(type)); - // } - } - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - @Override protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV) { if (this.mainvalueLabels.length >= 1) { @@ -125,14 +83,17 @@ exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_NAME, String.format("%d: %s", i, label)); } // "# Bezugspegel: " - exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, "TODO: gauge"); + for (final ResultRow row : this.rows) { + exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, row.getValue(SInfoResultType.gaugeLabel)); + break; + } } exportContextCSV.writeBlankLine(); } @Override protected String getJasperFile() { - if (this.waterlevelCount <= 1) + if (this.getWaterlevelCount() <= 1) return "/jasper/templates/sinfo.floodduration.jrxml"; else return "/jasper/templates/sinfo.floodduration2.jrxml"; @@ -189,14 +150,11 @@ final int waterlevelCount = // results. getWaterlevelCount(); for (int i = 0; i < waterlevelCount; i++) { - final int naturalIndex = i + 1; - final String appendIndex = new StringBuilder().append("_").append(naturalIndex).toString(); - final Object[] args = new Object[] { appendIndex }; - // new StringBuilder().append('\u2081').toString(); // schlechter UTF-8-Support für subscript ints - header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderWCsv(), new Object[] { appendIndex, "results.getRiver().getWstUnit()" })); - header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderFloodDurPerYearCsv(), args)); - header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderQ(), args)); - header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderBezeichnCsv(), args)); + final String appendIndex = "_" + Integer.toString(i + 1); + header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderWCsv(), appendIndex, "results.getRiver().getWstUnit()")); + header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderFloodDurPerYearCsv(), appendIndex)); + header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderQ(), appendIndex)); + header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderBezeichnCsv(), appendIndex)); } header.add(exportContextCSV.formatCsvHeader(SInfoResultType.gaugeLabel)); @@ -229,39 +187,61 @@ exportContextPDF.addJRMetadata(source, "infrastructure_height_header", SInfoResultType.infrastructureHeight); exportContextPDF.addJRMetadata(source, "infrastructure_type_header", SInfoResultType.infrastructuretype); - for (int i = 0; i < this.waterlevelCount; i++) { - final int naturalIndex = i + 1; + for (int i = 1; i <= this.getWaterlevelCount(); i++) { - final Object[] args = new String[] { new StringBuilder().append("_").append(naturalIndex).toString() }; - exportContextPDF.addJRMetadata(source, getPdfHeader("w", naturalIndex), exportContextPDF.msg(DurationWaterlevel.getHeaderWPdf(), args)); - exportContextPDF.addJRMetadata(source, getPdfHeader("duration", naturalIndex), - exportContextPDF.msg(DurationWaterlevel.getHeaderFloodDurPerYearPdf(), args)); - exportContextPDF.addJRMetadata(source, getPdfHeader("q", naturalIndex), exportContextPDF.msg(DurationWaterlevel.getHeaderQ(), args)); - exportContextPDF.addJRMetadata(source, getPdfHeader("bezeichnung", naturalIndex), - exportContextPDF.msg(DurationWaterlevel.getHeaderBezeichnPdf(), args)); + final String appendIndex = "_" + Integer.toString(i); + exportContextPDF.addJRMetadata(source, getPdfHeader("w", i), exportContextPDF.msg(DurationWaterlevel.getHeaderWPdf(), appendIndex)); + exportContextPDF.addJRMetadata(source, getPdfHeader("duration", i), + exportContextPDF.msg(DurationWaterlevel.getHeaderFloodDurPerYearPdf(), appendIndex)); + exportContextPDF.addJRMetadata(source, getPdfHeader("q", i), exportContextPDF.msg(DurationWaterlevel.getHeaderQ(), appendIndex)); + exportContextPDF.addJRMetadata(source, getPdfHeader("bezeichnung", i), + exportContextPDF.msg(DurationWaterlevel.getHeaderBezeichnPdf(), appendIndex)); } exportContextPDF.addJRMetadata(source, "gauge_header", SInfoResultType.gaugeLabel); exportContextPDF.addJRMetadata(source, "location_header", SInfoResultType.location); } - public final int getWaterlevelCount() { - return this.waterlevelCount; - } - private final String getPdfHeader(final String rootStr, final int index) { final String hd = "_header"; final StringBuilder builder = new StringBuilder(); return builder.append(rootStr).append("_").append(index).append(hd).toString(); } + public final int getWaterlevelCount() { + return (this.mainvalueLabels != null) ? this.mainvalueLabels.length : 0; + } + public String getMainValueLabel(final int j) { - if (this.mainvalueLabels != null && j < this.mainvalueLabels.length) return this.mainvalueLabels[j]; return ""; } + /** + * Gets the longitudinal section of a result value type for one river side + */ + public final double[][] getInfrastructurePoints(final IResultType type, final AttributeKey riverside) { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final ResultRow row : this.rows) { + + final double station = row.getDoubleValue(GeneralResultType.station); + final double value = row.getDoubleValue(type); + if (row.getValue(SInfoResultType.riverside) == riverside) { + xPoints.add(station); + yPoints.add(value); + } + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + + /** + * Gets a longitudinal section of W, Q, or flood duration of one of the waterlevels + */ public final double[][] getMainValueDurationPoints(final DiagramGenerator generator, final ValueGetter valuegetter, final int dataIndex) { final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Thu Jul 05 16:49:42 2018 +0200 @@ -27,7 +27,6 @@ import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.model.WQKms; import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; -import org.dive4elements.river.artifacts.sinfo.common.GaugeMainValueFinder; import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.common.WQBaseTableFinder; @@ -35,7 +34,6 @@ import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; import org.dive4elements.river.model.Attribute.AttributeKey; import org.dive4elements.river.model.Gauge; -import org.dive4elements.river.model.MainValueType.MainValueTypeKey; import org.dive4elements.river.model.sinfo.InfrastructureValue; import gnu.trove.TDoubleArrayList; @@ -82,17 +80,19 @@ // Merge all stations (range/step, borders of gauge ranges, infrastructures) final Map allStations = new HashMap<>(); final Map secondBank = new HashMap<>(); // any second infrastructure in case of both-banks-option - // FIXME: check, do we really need all stations? compare with tkh... addRangeStations(allStations, winfo); addGaugeLimits(allStations, durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); addInfrastructures(allStations, secondBank, infras); final double[] stationsSorted = sortStations(allStations.keySet()); // Calculate W and Q for all stations and the selected discharge states + // TODO Laut Herrn Reiß: Q und D jeweils konstant für jedes Pegel-Intervall, Q-Änderungen (Zuflüsse etc.) aus .wst + // ignorieren final WQKms[] wqkmsArray = calculateWaterlevels(winfo, stationsSorted, problems); // Determine discharge state labels of the main values - final String[] mainValueLabels = findMainValueLabels(wqkmsArray, winfo.getQs(), firstGauge, problems); + final WaterlevelDescriptionBuilder wdescBuilder = new WaterlevelDescriptionBuilder(winfo, this.context); + final String[] mainValueLabels = findMainValueLabels(wqkmsArray, winfo.getQs(), wdescBuilder, problems); // Create a finder for Q in the {river}.wst km-w-q table final WQBaseTableFinder wqFinder = WQBaseTableFinder.loadValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), @@ -103,7 +103,7 @@ // Calculate the durations and create the result rows for (int i = 0; i <= stationsSorted.length - 1; i++) { final Gauge gauge = this.riverInfoProvider.getGauge(stationsSorted[i], true); - final ResultRow row = createRow(descBuilder, stationsSorted[i], gauge, wqkmsArray, durFinders.get(gauge), i); + final ResultRow row = createRow(descBuilder, stationsSorted[i], gauge, firstGauge, wqkmsArray, durFinders.get(gauge), i); if (allStations.containsKey(stationsSorted[i]) && (allStations.get(stationsSorted[i]) != null)) calculateInfrastructure(row, gauge, allStations.get(stationsSorted[i]), wqFinder, durFinders); this.rows.add(row); @@ -171,12 +171,13 @@ // REMARK aus TkhCalculation - move to WinfoArtifactWrapper? // TODO das ist ziemlich langsam - durch den WQBaseTableFinder ersetzen? (vorher W-Optionen in Q umrechnen) // (So funktioniert computeWaterlevelData wohl: - // Es sucht die Spalte(n) zum Bezugspegel-Q in der W-Q-Tabelle ({river}.wst in Wst etc.) - // und interpoliert für diese horizontale Tabellenposition jeweils die vertikale Tabellenposition der station; + // Es sucht die Spalte(n) zum Bezugspegel-Q in der W-Q-Tabelle ({river}.wst in Wst etc.), + // interpoliert die horizontale Tabellenposition (Q) und dann die vertikale Tabellenposition der station; // das ergibt das W einer station für einen Abflusszustand; // bei Vorgabe eines Pegel-W wird vorher anhand der W-Q-Tabelle des Pegels ({gauge}.at in DischargeTable) das Q // interpoliert; - // bei Vorgabe eines W auf freier Strecke wird wohl vorher noch die .wst-Interpolation eingesetzt. + // bei Vorgabe eines W auf freier Strecke wird wohl vorher noch die .wst-Interpolation eingesetzt, um das Q zu bekommen. + final CalculationResult waterlevelData = winfo.computeWaterlevelData(stations); /* copy all problems */ @@ -191,31 +192,14 @@ } /** - * Determines the discharge state labels for the selected Q or W values + * Determines the waterlevel/discharge state labels for the selected Q or W values */ - // FIXME: use WaterlevelDescriptionBuilder instead! - private String[] findMainValueLabels(final WQKms[] wqkmsArray, final double[] qs, final Gauge gauge, final Calculation problems) { + private String[] findMainValueLabels(final WQKms[] wqkmsArray, final double[] qs, final WaterlevelDescriptionBuilder descBuilder, + final Calculation problems) { final String[] mainValueLabels = new String[wqkmsArray.length]; - if (wqkmsArray.length >= 1) { - - // FIXME - // WaterlevelDescriptionBuilder builder = new WaterlevelDescriptionBuilder(artifact, context); - - // Labels like Q=123 or W=123 - for (int i = 0; i <= wqkmsArray.length - 1; i++) { - // FIXME - // String label = builder.getDesc(wqkmsArray[i]); - - mainValueLabels[i] = wqkmsArray[i].getName(); - } - // Replace labels for named main Q values - final GaugeMainValueFinder zoneFinder = GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, gauge, problems); - if ((zoneFinder != null) && (qs != null)) { - for (int i = 0; i <= qs.length - 1; i++) - mainValueLabels[i] = zoneFinder.findExactZoneName(qs[i], mainValueLabels[i]); - } - } + for (int i = 0; i <= wqkmsArray.length - 1; i++) + mainValueLabels[i] = descBuilder.getDesc(wqkmsArray[i]); return mainValueLabels; } @@ -224,16 +208,15 @@ * * @param descBuilder */ - private ResultRow createRow(final WaterlevelDescriptionBuilder descBuilder, final Double station, final Gauge gauge, final WQKms[] wqkmsArray, - final GaugeDurationValuesFinder durationFinder, final int kmIndex) { + private ResultRow createRow(final WaterlevelDescriptionBuilder descBuilder, final Double station, final Gauge gauge, final Gauge firstGauge, + final WQKms[] wqkmsArray, final GaugeDurationValuesFinder durationFinder, final int kmIndex) { final ResultRow row = ResultRow.create(); row.putValue(GeneralResultType.station, station); row.putValue(SInfoResultType.infrastructuretype, null); // is replaced later for an infrastructure row.putValue(SInfoResultType.floodDuration, Double.NaN); // is replaced later for an infrastructure - // row.putValue(SInfoResultType.gaugeLabel, gauge.getName()); - final String gaugeLabel = this.riverInfoProvider.findGauge(station); + final String gaugeLabel = this.riverInfoProvider.findGauge(station, (gauge == firstGauge)); row.putValue(SInfoResultType.gaugeLabel, gaugeLabel); final String location = this.riverInfoProvider.getLocation(station); @@ -265,7 +248,7 @@ final double q = wqFinder.getDischarge(infrastructure.getStation(), infrastructure.getHeight()); final double qOut = Double.isInfinite(q) ? Double.NaN : q; final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(q)); - row.putValue(SInfoResultType.riverside, infrastructure.getAttributeKey().getName()); // TODO i18n + row.putValue(SInfoResultType.riverside, infrastructure.getAttributeKey()); row.putValue(SInfoResultType.floodDuration, dur); row.putValue(SInfoResultType.floodDischarge, qOut); row.putValue(SInfoResultType.infrastructureHeight, infrastructure.getHeight()); diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationProcessor.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationProcessor.java Thu Jul 05 16:49:42 2018 +0200 @@ -19,10 +19,12 @@ import org.dive4elements.river.artifacts.common.AbstractCalculationResult; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoProcessor; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultFacet; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.ValueGetter; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; import org.dive4elements.river.exports.DiagramGenerator; +import org.dive4elements.river.model.Attribute.AttributeKey; import org.dive4elements.river.themes.ThemeDocument; /** @@ -33,7 +35,9 @@ */ public final class FloodDurationProcessor extends AbstractSInfoProcessor { - private static final String FACET_FLOOD_DURATION = "sinfo_facet_flood_duration"; + private static final String FACET_FLOOD_DURATION_LEFT = "sinfo_facet_flood_duration.left"; + + private static final String FACET_FLOOD_DURATION_RIGHT = "sinfo_facet_flood_duration.right"; private static final String FACET_FLOOD_DURATION_DESCRIPTION = "sinfo_facet_flood_duration.description"; @@ -46,9 +50,9 @@ private static final Set HANDLED_FACET_TYPES = new HashSet<>(); static { - HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION); + HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION_LEFT); + HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION_RIGHT); HANDLED_FACET_TYPES.add(FACET_MAIN_VALUE_DURATION); - } public FloodDurationProcessor() { @@ -56,10 +60,18 @@ } public static Facet createFloodDurationFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, - final int resultIndex) { + final int facetIndex, final int resultIndex) { - return AbstractSInfoProcessor.createFacet(context, hash, id, result, resultIndex, I18N_AXIS_LABEL, FACET_FLOOD_DURATION, - FACET_FLOOD_DURATION_DESCRIPTION); + if (facetIndex == 0) { + final String description = Resources.getMsg(context.getMeta(), FACET_FLOOD_DURATION_DESCRIPTION, FACET_FLOOD_DURATION_DESCRIPTION, + SInfoResultType.localizeRiverside(context, AttributeKey.LEFT)); + return new SInfoResultFacet(facetIndex, resultIndex, FACET_FLOOD_DURATION_LEFT, description, I18N_AXIS_LABEL, ComputeType.ADVANCE, id, hash); + } + else { + final String description = Resources.getMsg(context.getMeta(), FACET_FLOOD_DURATION_DESCRIPTION, FACET_FLOOD_DURATION_DESCRIPTION, + SInfoResultType.localizeRiverside(context, AttributeKey.RIGHT)); + return new SInfoResultFacet(facetIndex, resultIndex, FACET_FLOOD_DURATION_RIGHT, description, I18N_AXIS_LABEL, ComputeType.ADVANCE, id, hash); + } } public static Facet createMainValueDurationFacet(final CallContext context, final String hash, final String id, final FloodDurationCalculationResult result, @@ -74,10 +86,15 @@ @Override protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) { + final String facetName = bundle.getFacetName(); - if (FACET_FLOOD_DURATION.contentEquals(facetName)) - return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.floodDuration, null); + if (FACET_FLOOD_DURATION_LEFT.contentEquals(facetName)) { + return buildInfrastructureSeries(generator, bundle, theme, visible, AttributeKey.LEFT); + } + + if (FACET_FLOOD_DURATION_RIGHT.contentEquals(facetName)) + return buildInfrastructureSeries(generator, bundle, theme, visible, AttributeKey.RIGHT); if (FACET_MAIN_VALUE_DURATION.contentEquals(facetName)) { @@ -94,11 +111,21 @@ } }; final double[][] points = ((FloodDurationCalculationResult) data).getMainValueDurationPoints(generator, valuegetter, index); - return buildSeriesForType(points, generator, bundle, theme, visible, null); + return buildStepLineSeriesForType(points, generator, bundle, theme, visible); } } final String error = String.format("Unknown facet name: %s", facetName); throw new UnsupportedOperationException(error); } + + private String buildInfrastructureSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible, + final AttributeKey riverside) { + + final FloodDurationCalculationResult data = (FloodDurationCalculationResult) getResult(generator, bundle); + + final double[][] points = data.getInfrastructurePoints(SInfoResultType.floodDuration, riverside); + + return buildSeriesForType(points, generator, bundle, theme, visible, null); + } } \ No newline at end of file diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Thu Jul 05 16:49:42 2018 +0200 @@ -21,6 +21,7 @@ import org.dive4elements.river.artifacts.model.FacetTypes; import org.dive4elements.river.artifacts.model.ReportFacet; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; +import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; import org.dive4elements.river.artifacts.states.DefaultState; /** @@ -78,11 +79,18 @@ int themeCount = 0; for (final FloodDurationCalculationResult result : resultList) { - facets.add(FloodDurationProcessor.createFloodDurationFacet(context, hash, this.id, result, resultIndex)); + final FloodDurationAccess access = new FloodDurationAccess(sinfo); + if ((access.getRiverside() == RiversideChoiceKey.LEFT) || (access.getRiverside() == RiversideChoiceKey.BOTH)) + facets.add(FloodDurationProcessor.createFloodDurationFacet(context, hash, this.id, result, 0, resultIndex)); + if ((access.getRiverside() == RiversideChoiceKey.RIGHT) || (access.getRiverside() == RiversideChoiceKey.BOTH)) + facets.add(FloodDurationProcessor.createFloodDurationFacet(context, hash, this.id, result, 1, resultIndex)); final int waterlevelCount = result.getWaterlevelCount(); - facets.add(FloodHeightProcessor.createFloodHeightFacet(context, hash, this.id, result, resultIndex)); + if ((access.getRiverside() == RiversideChoiceKey.LEFT) || (access.getRiverside() == RiversideChoiceKey.BOTH)) + facets.add(FloodHeightProcessor.createFloodHeightFacet(context, hash, this.id, result, 0, resultIndex)); + if ((access.getRiverside() == RiversideChoiceKey.RIGHT) || (access.getRiverside() == RiversideChoiceKey.BOTH)) + facets.add(FloodHeightProcessor.createFloodHeightFacet(context, hash, this.id, result, 1, resultIndex)); for (int j = 0; j < waterlevelCount; j++) { diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodHeightProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodHeightProcessor.java Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodHeightProcessor.java Thu Jul 05 16:49:42 2018 +0200 @@ -19,11 +19,13 @@ import org.dive4elements.river.artifacts.common.AbstractCalculationResult; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoProcessor; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultFacet; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.ValueGetter; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; import org.dive4elements.river.exports.DiagramGenerator; import org.dive4elements.river.exports.LongitudinalSectionGenerator; +import org.dive4elements.river.model.Attribute.AttributeKey; import org.dive4elements.river.themes.ThemeDocument; /** @@ -34,7 +36,9 @@ */ public final class FloodHeightProcessor extends AbstractSInfoProcessor { - private static final String FACET_FLOOD_HEIGHT = "sinfo_facet_flood_height"; + private static final String FACET_FLOOD_HEIGHT_LEFT = "sinfo_facet_flood_height.left"; + + private static final String FACET_FLOOD_HEIGHT_RIGHT = "sinfo_facet_flood_height.right"; private static final String FACET_FLOOD_HEIGHT_DESCRIPTION = "sinfo_facet_flood_height.description"; @@ -47,7 +51,8 @@ private static final Set HANDLED_FACET_TYPES = new HashSet<>(); static { - HANDLED_FACET_TYPES.add(FACET_FLOOD_HEIGHT); + HANDLED_FACET_TYPES.add(FACET_FLOOD_HEIGHT_LEFT); + HANDLED_FACET_TYPES.add(FACET_FLOOD_HEIGHT_RIGHT); HANDLED_FACET_TYPES.add(FACET_MAIN_VALUE_HEIGHT); } @@ -56,8 +61,18 @@ } public static Facet createFloodHeightFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, - final int index) { - return AbstractSInfoProcessor.createFacet(context, hash, id, result, index, I18N_AXIS_LABEL, FACET_FLOOD_HEIGHT, FACET_FLOOD_HEIGHT_DESCRIPTION); + final int facetIndex, final int resultIndex) { + + if (facetIndex == 0) { + final String description = Resources.getMsg(context.getMeta(), FACET_FLOOD_HEIGHT_DESCRIPTION, FACET_FLOOD_HEIGHT_DESCRIPTION, + SInfoResultType.localizeRiverside(context, AttributeKey.LEFT)); + return new SInfoResultFacet(facetIndex, resultIndex, FACET_FLOOD_HEIGHT_LEFT, description, I18N_AXIS_LABEL, ComputeType.ADVANCE, id, hash); + } + else { + final String description = Resources.getMsg(context.getMeta(), FACET_FLOOD_HEIGHT_DESCRIPTION, FACET_FLOOD_HEIGHT_DESCRIPTION, + SInfoResultType.localizeRiverside(context, AttributeKey.RIGHT)); + return new SInfoResultFacet(facetIndex, resultIndex, FACET_FLOOD_HEIGHT_RIGHT, description, I18N_AXIS_LABEL, ComputeType.ADVANCE, id, hash); + } } public static Facet createMainValueHeightFacet(final CallContext context, final String hash, final String id, final FloodDurationCalculationResult result, @@ -73,8 +88,12 @@ final String facetName = bundle.getFacetName(); - if (FACET_FLOOD_HEIGHT.contentEquals(facetName)) - return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.infrastructureHeight, null); + if (FACET_FLOOD_HEIGHT_LEFT.contentEquals(facetName)) { + return buildInfrastructureSeries(generator, bundle, theme, visible, AttributeKey.LEFT); + } + + if (FACET_FLOOD_HEIGHT_RIGHT.contentEquals(facetName)) + return buildInfrastructureSeries(generator, bundle, theme, visible, AttributeKey.RIGHT); if (FACET_MAIN_VALUE_HEIGHT.contentEquals(facetName)) { @@ -98,4 +117,14 @@ final String error = String.format("Unknown facet name: %s", facetName); throw new UnsupportedOperationException(error); } + + private String buildInfrastructureSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible, + final AttributeKey riverside) { + + final FloodDurationCalculationResult data = (FloodDurationCalculationResult) getResult(generator, bundle); + + final double[][] points = data.getInfrastructurePoints(SInfoResultType.infrastructureHeight, riverside); + + return buildSeriesForType(points, generator, bundle, theme, visible, null); + } } \ No newline at end of file diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/resources/messages.properties Thu Jul 05 16:49:42 2018 +0200 @@ -95,6 +95,8 @@ state.sinfo.riverside.left = Linkes Ufer state.sinfo.riverside.right = Rechtes Ufer state.sinfo.riverside.both = Beide Ufer +riverside.left = left +riverside.right = right year=Year epoch=Epoch diff -r dba14da43f23 -r 0dcd1cd41915 artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Thu Jul 05 13:46:36 2018 +0200 +++ b/artifacts/src/main/resources/messages_de.properties Thu Jul 05 16:49:42 2018 +0200 @@ -95,6 +95,8 @@ state.sinfo.riverside.left = Linkes Ufer state.sinfo.riverside.right = Rechtes Ufer state.sinfo.riverside.both = Beide Ufer +riverside.left = links +riverside.right = rechts year=Jahr epoch=Epoche