Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FacetCalculator.java @ 9612:f8308db94634
#20 UI, Diagramme
author | dnt_bjoernsen <d.tironi@bjoernsen.de> |
---|---|
date | Wed, 09 Oct 2019 16:17:16 +0200 |
parents | |
children | d889ffe2fb05 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FacetCalculator.java Wed Oct 09 16:17:16 2019 +0200 @@ -0,0 +1,184 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ +package org.dive4elements.river.artifacts.sinfo.flood_duration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.common.GeneralResultType; +import org.dive4elements.river.artifacts.common.ResultRow; +import org.dive4elements.river.artifacts.model.Calculation; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; +import org.dive4elements.river.jfree.StickyAxisAnnotation; +import org.dive4elements.river.jfree.StickyAxisAnnotation.SimpleAxis; +import org.dive4elements.river.model.Attribute.AttributeKey; + +/** + * @author Domenico Nardi Tironi + * + */ +public class FacetCalculator { + + private static final double DELTA_KM = 0.0001; + + private final CallContext m_context; + + public FacetCalculator(final CallContext context) { + this.m_context = context; + } + + /** + * Calculates the data for the W main value lines in the duration curve chart + */ + public List<StickyAxisAnnotation> calcMainValueWAnnotations(final Calculation problems, final double station, final FloodDurationCalculationResult result) { + + final List<ResultRow> stationRows = searchStation(station, result.getAllRows(), AttributeKey.NONE); + if (stationRows.isEmpty()) + return Collections.emptyList(); + + final List<StickyAxisAnnotation> annotations = new ArrayList<>(); + final ResultRow row = stationRows.get(0); + final List<DurationWaterlevel> wqds = (List<DurationWaterlevel>) row.getValue(SInfoResultType.customMultiRowColWaterlevel); + for (final DurationWaterlevel wqd : wqds) { + final String label = !wqd.getBezeichnung().startsWith("W=") ? "W(" + wqd.getBezeichnung() + ")" : wqd.getBezeichnung(); + final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) wqd.getWaterlevel(), SimpleAxis.Y_AXIS, + FloodDurationCurveGenerator.YAXIS.W.idx); + annotation.setHitPoint((float) wqd.getFloodDurDaysPerYear()); + annotations.add(annotation); + } + return annotations; + } + + /** + * Calculates the data for the Q main value lines in the duration curve chart + * + * @param infrastructure + */ + public List<StickyAxisAnnotation> calcMainValueQAnnotations(final Calculation problems, final double station, final FloodDurationCalculationResult result) { + + final List<ResultRow> stationRows = searchStation(station, result.getAllRows(), AttributeKey.NONE); + if (stationRows.isEmpty()) + return Collections.emptyList(); + + final ResultRow row = stationRows.get(0); + final List<StickyAxisAnnotation> annotations = new ArrayList<>(); + final List<DurationWaterlevel> wqds = (List<DurationWaterlevel>) row.getValue(SInfoResultType.customMultiRowColWaterlevel); + for (final DurationWaterlevel wqd : wqds) { + final String label = wqd.getBezeichnung().startsWith("W=") ? "Q(" + wqd.getBezeichnung() + ")" : wqd.getBezeichnung(); + final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) wqd.getDischarge(), SimpleAxis.Y_AXIS, + FloodDurationCurveGenerator.YAXIS.Q.idx); + annotation.setHitPoint((float) wqd.getFloodDurDaysPerYear()); + annotations.add(annotation); + } + return annotations; + } + + /** + * Find and return the W or Q annotation(s) of a station and a riverside in a previously calculated result + * + * @param key + */ + public List<StickyAxisAnnotation> calcInfrastructureAnnotations(final Calculation problems, final double station, final boolean isW, + final FloodDurationCalculationResult result, final AttributeKey riverside) { + + final List<ResultRow> stationRows = searchStation(station, result.getAllRows(), riverside); + if (stationRows.isEmpty()) + return Collections.emptyList(); + + // Same way as in MainValueWFacet and ..QFacet + final List<StickyAxisAnnotation> annotations = new ArrayList<>(); + for (final ResultRow row : stationRows) { + if (isW) + annotations.add(calcInfrastructureWAnnotation(row)); + else + annotations.add(calcInfrastructureQAnnotation(row)); + } + return annotations; + } + + /** + * Calculates the Q annotation lines of an infrastructure + */ + private StickyAxisAnnotation calcInfrastructureQAnnotation(final ResultRow row) { + final String label = Resources.getMsg(this.m_context.getMeta(), "sinfo.chart.flood_duration.curve.infrastructure", + "sinfo.chart.flood_duration.curve.infrastructure", + SInfoResultType.infrastructuretype.exportValue(this.m_context, row.getValue(SInfoResultType.infrastructuretype)) + " - " + + SInfoResultType.infrastructurepart.exportValue(this.m_context, row.getValue(SInfoResultType.infrastructurepart)) + " (" + + SInfoResultType.riverside.exportValue(this.m_context, row.getValue(SInfoResultType.riverside)) + ")"); + final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) row.getDoubleValue(SInfoResultType.floodDischarge), SimpleAxis.Y_AXIS, + FloodDurationCurveGenerator.YAXIS.Q.idx); + annotation.setHitPoint((float) row.getDoubleValue(SInfoResultType.floodDuration)); + return annotation; + } + + /** + * Calculates the W annotation lines of an infrastructure + */ + private StickyAxisAnnotation calcInfrastructureWAnnotation(final ResultRow row) { + final String label = Resources.getMsg(this.m_context.getMeta(), "sinfo.chart.flood_duration.curve.infrastructure", + "sinfo.chart.flood_duration.curve.infrastructure", + SInfoResultType.infrastructuretype.exportValue(this.m_context, row.getValue(SInfoResultType.infrastructuretype)) + " - " + + SInfoResultType.infrastructurepart.exportValue(this.m_context, row.getValue(SInfoResultType.infrastructurepart)) + " (" + + SInfoResultType.riverside.exportValue(this.m_context, row.getValue(SInfoResultType.riverside)) + ")"); + final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) row.getDoubleValue(SInfoResultType.infrastructureHeight), + SimpleAxis.Y_AXIS, FloodDurationCurveGenerator.YAXIS.W.idx); + annotation.setHitPoint((float) row.getDoubleValue(SInfoResultType.floodDuration)); + return annotation; + } + + /** + * Searches the one or two rows of a station in a result rows collection + * + * @param m_riverside + */ + private List<ResultRow> searchStation(final double station, final Collection<ResultRow> rows, final AttributeKey riverside) { + + final double searchStation = findSearchStation(rows, station, riverside); + if (Double.isNaN(searchStation)) + return Collections.emptyList(); + + final List<ResultRow> found = new ArrayList<>(); + + for (final ResultRow row : rows) { // rows are not sorted + final String riversideStr = String.valueOf(row.getValue(SInfoResultType.riverside)); + if (riversideStr.equals("null")) + continue; + + if (Math.abs(row.getDoubleValue(GeneralResultType.station) - station) > DELTA_KM) + continue; + + if (riverside.equals(AttributeKey.NONE) || riverside.equals(AttributeKey.valueOf(String.valueOf(row.getValue(SInfoResultType.riverside))))) + found.add(row); + } + return found; + } + + @Deprecated + private double findSearchStation(final Collection<ResultRow> rows, final double station, final AttributeKey riverside) { + + if (!Double.isNaN(station)) + return station; + + for (final ResultRow row : rows) { + final String riversideStr = String.valueOf(row.getValue(SInfoResultType.riverside)); + if (riversideStr.equals("null")) + continue; + + if (riverside.equals(AttributeKey.NONE) || riverside.equals(AttributeKey.valueOf(riversideStr))) + return row.getDoubleValue(GeneralResultType.station); + } + + return Double.NaN; + } +}