# HG changeset patch # User mschaefer # Date 1570720314 -7200 # Node ID 26e113e8224f4ce1e7ec0088ba7f643f1fadcab6 # Parent 63bbd5e458390a18fbfa86466d51b3f0a4693428 Nachtrag Pos. 20: flood duration calculation for multiple infrastructure groups/types, local class FloodDurationCalculationResult.Infrastructure renamed and extracted into own class diff -r 63bbd5e45839 -r 26e113e8224f 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 Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Thu Oct 10 17:11:54 2019 +0200 @@ -20,11 +20,11 @@ import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.model.River; +import org.dive4elements.river.model.sinfo.Infrastructure; /** * Calculation of the flood durations of the infrastructures of the km range of a river @@ -76,10 +76,11 @@ final FloodDurationCalculator calculator = new FloodDurationCalculator(this.context, riverInfoProvider); - // FIXME: fetch from access; maybe we need database for that... whatever - final Set infrastructureKeys = null; + // FIXME: fetch from access (fetchInfrastructureTypes only for test purposes) + final Set infrastructureChoices = Infrastructure.fetchInfrastructureTypes(riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), + calcRange.getMaximumDouble(), access.getRiverside().getAttributeKey()); - calculator.execute(problems, label, calcRange, access.getRiverside(), infrastructureKeys, access.getIsWspl(), winfo, results); + calculator.execute(problems, label, calcRange, access.getRiverside().getAttributeKey(), infrastructureChoices, access.getIsWspl(), winfo, results); } /** diff -r 63bbd5e45839 -r 26e113e8224f 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 Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java Thu Oct 10 17:11:54 2019 +0200 @@ -9,7 +9,6 @@ */ package org.dive4elements.river.artifacts.sinfo.flood_duration; -import java.io.Serializable; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collection; @@ -19,9 +18,6 @@ import java.util.Set; import org.apache.commons.collections.Predicate; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.dive4elements.artifacts.CallContext; import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult; import org.dive4elements.river.artifacts.common.AbstractExportContext; import org.dive4elements.river.artifacts.common.ExportContextCSV; @@ -30,10 +26,8 @@ import org.dive4elements.river.artifacts.common.IResultType; import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource; import org.dive4elements.river.artifacts.common.ResultRow; -import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; -import org.dive4elements.river.model.Attribute.AttributeKey; import gnu.trove.TDoubleArrayList; @@ -44,18 +38,18 @@ */ public final class FloodDurationCalculationResult extends AbstractCalculationExportableResult { - private final static class InfrastructurePredicate implements Predicate { + private final static class IsInfrastructureChoicePredicate implements Predicate { - private final Infrastructure m_infrastructure; + private final FloodDurationInfrastructureChoice m_infrastructure; - public InfrastructurePredicate(final Infrastructure infrastructure) { + public IsInfrastructureChoicePredicate(final FloodDurationInfrastructureChoice infrastructure) { this.m_infrastructure = infrastructure; } @Override public boolean evaluate(final Object object) { final ResultRow row = (ResultRow) object; - final Infrastructure test = new Infrastructure(row); + final FloodDurationInfrastructureChoice test = new FloodDurationInfrastructureChoice(row); return this.m_infrastructure.equals(test); } } @@ -70,69 +64,6 @@ } } - public static final class Infrastructure implements Serializable { - - private static final long serialVersionUID = 1L; - - private final String m_group; - - private final String m_type; - - private final AttributeKey m_riverside; - - private static final String FACET_FLOOD_DURATION_DESCRIPTION = "sinfo_facet_flood_duration"; - - private static final String FACET_ABSOLUTE_HEIGHT = "sinfo.flood_duration.absolute.height"; - - public Infrastructure(final ResultRow row) { - this.m_group = String.valueOf(row.getValue(SInfoResultType.infrastructuregroup)); - this.m_type = String.valueOf(row.getValue(SInfoResultType.infrastructuretype)); - final String riversideStr = String.valueOf(row.getValue(SInfoResultType.riverside)); - this.m_riverside = riversideStr.equals("null") ? AttributeKey.NONE : AttributeKey.valueOf(riversideStr); - } - - public AttributeKey getRiverside() { - return this.m_riverside; - } - - @Override - public int hashCode() { - return new HashCodeBuilder() // - .append(this.m_group)// - .append(this.m_type)// - .append(this.m_riverside)// - .toHashCode(); - } - - @Override - public boolean equals(final Object obj) { - - if (obj == null) - return false; - if (obj == this) - return true; - if (obj.getClass() != getClass()) - return false; - - final Infrastructure other = (Infrastructure) obj; - return new EqualsBuilder() // - .append(this.m_group, other.m_group) // - .append(this.m_type, other.m_type) // - .append(this.m_riverside, other.m_riverside) // - .isEquals(); - } - - public String getFloodHeightLabel(final CallContext context) { - return Resources.getMsg(context.getMeta(), FACET_ABSOLUTE_HEIGHT, FACET_ABSOLUTE_HEIGHT) - + " " + SInfoResultType.getInfrastructureLabel(context, this.m_group, this.m_type, this.m_riverside); - } - - public String getFloodDurationLabel(final CallContext context) { - return Resources.getMsg(context.getMeta(), FACET_FLOOD_DURATION_DESCRIPTION, FACET_FLOOD_DURATION_DESCRIPTION) - + " " + SInfoResultType.getInfrastructureLabel(context, this.m_group, this.m_type, this.m_riverside); - } - } - private static final long serialVersionUID = 1L; private final boolean isUseWspl; @@ -141,7 +72,7 @@ private final int maxWaterlevelPdf = 3; - private final Set m_infrastructures; + private final Set m_infrastructures; public interface ValueGetter { double getValue(DurationWaterlevel waterlevel); @@ -152,14 +83,14 @@ } public FloodDurationCalculationResult(final String label, final String[] mainvalueLabels, final Collection rows, final boolean isUseWspl, - final Set infrastructures) { + final Set infrastructures) { super(label, rows); this.waterlevelLabels = mainvalueLabels; this.isUseWspl = isUseWspl; this.m_infrastructures = infrastructures; } - public Set getInfrastructureMap() { + public Set getInfrastructureMap() { return this.m_infrastructures; } @@ -346,9 +277,9 @@ /** * Gets the longitudinal section of a result value type for one river side */ - public final double[][] getInfrastructurePoints(final IResultType type, final Infrastructure infrastructure) { + public final double[][] getInfrastructurePoints(final IResultType type, final FloodDurationInfrastructureChoice infrastructure) { - return getPoints(GeneralResultType.station, type, new InfrastructurePredicate(infrastructure)); + return getPoints(GeneralResultType.station, type, new IsInfrastructureChoicePredicate(infrastructure)); } /** diff -r 63bbd5e45839 -r 26e113e8224f 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 Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Thu Oct 10 17:11:54 2019 +0200 @@ -33,8 +33,6 @@ import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; -import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; import org.dive4elements.river.model.Attribute.AttributeKey; import org.dive4elements.river.model.Gauge; @@ -54,6 +52,7 @@ private final RiverInfoProvider riverInfoProvider; private RiverInfoProvider riverInfoProvider2; + private final Map> stationInfras; private final CallContext context; @@ -61,18 +60,14 @@ this.context = context; this.riverInfoProvider = riverInfoProvider; this.riverInfoProvider2 = null; + this.stationInfras = new HashMap<>(); } /** * Calculate the infrastructures flood duration result rows */ - public void execute(final Calculation problems, final String label, final DoubleRange calcRange, final RiversideChoiceKey riverside, - final Set infrastruktureKey, final boolean withWspl, final WINFOArtifact winfo, final FloodDurationCalculationResults results) { - - // FIXME Schäfer: - // filter by infrastructureKey - // FIXME: Tironi: api gscheit benennen; - // Lösung finden für: Infrastructure enthält riverside, wird hier aber nicht benötigt (weil schon im choice) + public void execute(final Calculation problems, final String label, final DoubleRange calcRange, final AttributeKey riverside, + final Set infrastructureChoices, final boolean withWspl, final WINFOArtifact winfo, final FloodDurationCalculationResults results) { // Find all gauges of the calc range, and create the duration finders final Map durFinders = new HashMap<>(); @@ -81,17 +76,18 @@ } // Find all infrastructures within the calc range - final AttributeKey bankKey = riverside.getAttributeKey(); final List infras = InfrastructureValue.getValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), - calcRange.getMaximumDouble(), bankKey); + calcRange.getMaximumDouble(), riverside, infrastructureChoices); // 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 - addRangeStations(allStations, winfo); - addGaugeLimits(allStations, durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); - addInfrastructures(allStations, secondBank, infras); - final double[] stationsSorted = sortStations(allStations.keySet()); + // final Map allStations = new HashMap<>(); + this.stationInfras.clear(); + // final Map secondBank = new HashMap<>(); // any second infrastructure in case of + // both-banks-option + addRangeStations(winfo); + addGaugeLimits(durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); + addInfrastructures(infras); + final double[] stationsSorted = sortStations(this.stationInfras.keySet()); // Calculate W and Q for all stations and the selected discharge states/waterlevels final WQKms[] wqkmsArray = calculateWsts(winfo, withWspl, stationsSorted, problems); @@ -111,22 +107,18 @@ // (should be in cache since already used in calculateWaterlevels (winfo.computeWaterlevelData) final WstValueTable wst = WstValueTableFactory.getTable(this.riverInfoProvider2.getRiver()); - final Set infrastructures = new HashSet<>(); + final Set infrastructures = new HashSet<>(); // Create the result rows, and calculate and add the flood durations etc. for (int i = 0; i <= stationsSorted.length - 1; i++) { final Gauge gauge = this.riverInfoProvider2.getGauge(stationsSorted[i], true); - final ResultRow row = createRow(stationsSorted[i], wqkmsArray, gaugeWstDurations.get(gauge), i); - if (allStations.containsKey(stationsSorted[i]) && (allStations.get(stationsSorted[i]) != null)) - calculateInfrastructure(row, gauge, allStations.get(stationsSorted[i]), wst, durFinders, infrastructures); - - this.rows.add(row); - if (secondBank.containsKey(stationsSorted[i])) { - final ResultRow row2 = ResultRow.create(row); - calculateInfrastructure(row2, gauge, secondBank.get(stationsSorted[i]), wst, durFinders, infrastructures); - this.rows.add(row2); + if (this.stationInfras.containsKey(stationsSorted[i])) { + for (final InfrastructureValue infra : this.stationInfras.get(stationsSorted[i])) { + final ResultRow row = createRow(stationsSorted[i], wqkmsArray, gaugeWstDurations.get(gauge), i); + calculateInfrastructure(row, gauge, infra, wst, durFinders, infrastructures); + this.rows.add(row); + } } - } // Get the labels of the selected waterlevels @@ -158,36 +150,33 @@ /** * Adds to a stations map all stations corresponding to the active range and step */ - private void addRangeStations(final Map allStations, final WINFOArtifact winfo) { + private void addRangeStations(final WINFOArtifact winfo) { for (final double station : new ComputationRangeAccess(winfo).getKms()) - allStations.put(Double.valueOf(station), null); + this.stationInfras.put(Double.valueOf(station), new ArrayList()); } /** * Adds to a stations map all range limits of the gauges within the calc range */ - private void addGaugeLimits(final Map allStations, final Set gauges, final double fromKm, final double toKm) { + private void addGaugeLimits(final Set gauges, final double fromKm, final double toKm) { for (final Gauge gauge : gauges) { final Double kmA = Double.valueOf(gauge.getRange().getA().doubleValue()); final Double kmB = Double.valueOf(gauge.getRange().getB().doubleValue()); if (kmA > fromKm - 0.0001) - allStations.put(kmA, null); + this.stationInfras.put(kmA, new ArrayList()); if (kmB < toKm + 0.0001) - allStations.put(kmB, null); + this.stationInfras.put(kmB, new ArrayList()); } } /** - * Adds to a stations map all (first) infrastructures of a station, and the second, if any, to another map + * Adds all infrastructures of a station to the station map */ - private void addInfrastructures(final Map allStations, final Map secondBank, - final List infrastructures) { + private void addInfrastructures(final List infrastructures) { for (final InfrastructureValue infrastructure : infrastructures) { final Double station = infrastructure.getStation(); - if (!allStations.containsKey(station) || !(allStations.get(station) instanceof InfrastructureValue)) - allStations.put(station, infrastructure); - else - secondBank.put(station, infrastructure); + if (this.stationInfras.containsKey(station)) + this.stationInfras.get(station).add(infrastructure); } } @@ -312,7 +301,7 @@ * Calculate the result row fields for one infrastructure */ private void calculateInfrastructure(final ResultRow row, final Gauge gauge, final InfrastructureValue infrastructure, final WstValueTable wst, - final Map durFinders, final Set infrastructures) { + final Map durFinders, final Set infrastructures) { // Interpolate the infrastructure height in the wst table to get the corresponding Q final Calculation problems = new Calculation(); @@ -328,16 +317,15 @@ // Determine the relative column position of the Q of the infrastructure height final QPosition qPos = wst.getQPosition(infrastructure.getStation().doubleValue(), q); - if (qPos == null) - return; - // Get the Q for the found column position for the station of the gauge - final double qGauge = wst.getQ(qPos, gauge.getStation().doubleValue()); - // Interpolate the Q-D-table of the gauge - final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(qGauge)); - // Set D in the result row - row.putValue(SInfoResultType.floodDuration, dur); - - final FloodDurationCalculationResult.Infrastructure groupType = new FloodDurationCalculationResult.Infrastructure(row); + if (qPos != null) { + // Get the Q for the found column position for the station of the gauge + final double qGauge = wst.getQ(qPos, gauge.getStation().doubleValue()); + // Interpolate the Q-D-table of the gauge + final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(qGauge)); + // Set D in the result row + row.putValue(SInfoResultType.floodDuration, dur); + } + final FloodDurationInfrastructureChoice groupType = new FloodDurationInfrastructureChoice(row); infrastructures.add(groupType); } diff -r 63bbd5e45839 -r 26e113e8224f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveProcessor.java Thu Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveProcessor.java Thu Oct 10 17:11:54 2019 +0200 @@ -18,7 +18,6 @@ import org.dive4elements.river.artifacts.common.AbstractCalculationResult; import org.dive4elements.river.artifacts.model.FacetTypes; import org.dive4elements.river.artifacts.resources.Resources; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.exports.DiagramGenerator; import org.dive4elements.river.exports.DurationCurveGenerator; import org.dive4elements.river.exports.process.DefaultProcessor; @@ -85,7 +84,7 @@ } public static Facet createMainValuesQFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, - final int facetIndex, final int resultIndex, final String description, final Infrastructure infrastructure) { + final int facetIndex, final int resultIndex, final String description, final FloodDurationInfrastructureChoice infrastructure) { return new FloodDurationMainValuesQFacet(FACET_FLOOD_DURATION_MAINVALUES_Q, description, facetIndex, infrastructure); } diff -r 63bbd5e45839 -r 26e113e8224f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesQFacet.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesQFacet.java Thu Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesQFacet.java Thu Oct 10 17:11:54 2019 +0200 @@ -19,7 +19,6 @@ import org.dive4elements.river.artifacts.D4EArtifact; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.CalculationResult; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; import org.dive4elements.river.exports.fixings.FixChartGenerator; import org.dive4elements.river.jfree.RiverAnnotation; @@ -35,10 +34,11 @@ /** Own log. */ private static Logger log = Logger.getLogger(FloodDurationMainValuesQFacet.class); - private final Infrastructure m_infrastructure; + private final FloodDurationInfrastructureChoice m_infrastructure; /** Trivial Constructor. */ - public FloodDurationMainValuesQFacet(final String name, final String description, final int facetIndex, final Infrastructure infrastructure) { + public FloodDurationMainValuesQFacet(final String name, final String description, final int facetIndex, + final FloodDurationInfrastructureChoice infrastructure) { this.description = description; this.name = name; this.index = facetIndex; diff -r 63bbd5e45839 -r 26e113e8224f 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 Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationProcessor.java Thu Oct 10 17:11:54 2019 +0200 @@ -20,7 +20,6 @@ import org.dive4elements.river.artifacts.common.AbstractProcessor; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.ValueGetter; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; import org.dive4elements.river.exports.DiagramGenerator; @@ -58,7 +57,7 @@ } public static Facet createFloodDurationFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, - final int facetIndex, final int resultIndex, final Infrastructure infrastructure) { + final int facetIndex, final int resultIndex, final FloodDurationInfrastructureChoice infrastructure) { final String description = infrastructure.getFloodDurationLabel(context); final String facetName = infrastructure.getRiverside() == AttributeKey.LEFT ? FACET_FLOOD_DURATION_LEFT : FACET_FLOOD_DURATION_RIGHT; @@ -110,7 +109,7 @@ final boolean visible) { final InfrastructureResultFacet infFacet = (InfrastructureResultFacet) bundle.getFacet(); - final Infrastructure infrastructure = infFacet.getInfrastructure(); + final FloodDurationInfrastructureChoice infrastructure = infFacet.getInfrastructure(); final FloodDurationCalculationResult data = (FloodDurationCalculationResult) getResult(generator, bundle); diff -r 63bbd5e45839 -r 26e113e8224f 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 Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Thu Oct 10 17:11:54 2019 +0200 @@ -27,7 +27,6 @@ import org.dive4elements.river.artifacts.model.ReportFacet; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.artifacts.states.DefaultState; import org.dive4elements.river.model.Attribute.AttributeKey; @@ -128,8 +127,8 @@ facets.add(FloodDurationCurveProcessor.createInfrastructureFacet(context, hash, this.id, result, themeCount++, resultIndex, false, riversideC)); } - final Set infrastructures = result.getInfrastructureMap(); - for (final Infrastructure entry : infrastructures) { + final Set infrastructures = result.getInfrastructureMap(); + for (final FloodDurationInfrastructureChoice entry : infrastructures) { facets.add(FloodDurationProcessor.createFloodDurationFacet(context, hash, this.id, result, themeCount++, resultIndex, entry)); diff -r 63bbd5e45839 -r 26e113e8224f 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 Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodHeightProcessor.java Thu Oct 10 17:11:54 2019 +0200 @@ -20,7 +20,6 @@ import org.dive4elements.river.artifacts.common.AbstractProcessor; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.ValueGetter; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; import org.dive4elements.river.exports.DiagramGenerator; @@ -58,7 +57,7 @@ } public static Facet createFloodHeightFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, - final int facetIndex, final int resultIndex, final Infrastructure infrastructure) { + final int facetIndex, final int resultIndex, final FloodDurationInfrastructureChoice infrastructure) { final String facetName = infrastructure.getRiverside().equals(AttributeKey.LEFT) ? FACET_FLOOD_HEIGHT_LEFT : FACET_FLOOD_HEIGHT_RIGHT; final String description = infrastructure.getFloodHeightLabel(context); @@ -108,7 +107,7 @@ final boolean visible) { final InfrastructureResultFacet infFacet = (InfrastructureResultFacet) bundle.getFacet(); - final Infrastructure infrastructure = infFacet.getInfrastructure(); + final FloodDurationInfrastructureChoice infrastructure = infFacet.getInfrastructure(); final FloodDurationCalculationResult data = (FloodDurationCalculationResult) getResult(generator, bundle); diff -r 63bbd5e45839 -r 26e113e8224f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/InfrastructureResultFacet.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/InfrastructureResultFacet.java Thu Oct 10 16:08:47 2019 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/InfrastructureResultFacet.java Thu Oct 10 17:11:54 2019 +0200 @@ -10,7 +10,6 @@ package org.dive4elements.river.artifacts.sinfo.flood_duration; import org.dive4elements.river.artifacts.common.ResultFacet; -import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; /** @@ -21,15 +20,15 @@ private static final long serialVersionUID = 1L; - private final Infrastructure m_infrastructure; + private final FloodDurationInfrastructureChoice m_infrastructure; public InfrastructureResultFacet(final int facetIndex, final int resultIndex, final String name, final String description, final String axisLabel, - final String id, final String hash, final Infrastructure infrastructure) { + final String id, final String hash, final FloodDurationInfrastructureChoice infrastructure) { super(facetIndex, resultIndex, name, description, axisLabel, ComputeType.ADVANCE, id, hash); this.m_infrastructure = infrastructure; } - public Infrastructure getInfrastructure() { + public FloodDurationInfrastructureChoice getInfrastructure() { return this.m_infrastructure; } } diff -r 63bbd5e45839 -r 26e113e8224f backend/src/main/java/org/dive4elements/river/model/sinfo/Infrastructure.java --- a/backend/src/main/java/org/dive4elements/river/model/sinfo/Infrastructure.java Thu Oct 10 16:08:47 2019 +0200 +++ b/backend/src/main/java/org/dive4elements/river/model/sinfo/Infrastructure.java Thu Oct 10 17:11:54 2019 +0200 @@ -12,7 +12,9 @@ import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; @@ -228,10 +230,22 @@ } /** + * Fetches from the database the infrastructure groups and types of a river's km range and river side(s) + * as tab-separated strings ordered by the infrastructure group, then the type + */ + public static Set fetchInfrastructureTypes(final River river, final double kmLo, final double kmHi, + final AttributeKey riverside) { + final Set groupTypes = new HashSet<>(); + for (final Infrastructure ifs : fetchInfrastructureTypeList(river, kmLo, kmHi, riverside)) + groupTypes.add(ifs.getGroup().getName() + "\t" + ifs.getType().getName()); + return groupTypes; + } + + /** * Fetches from the database the list of infrastructure types of a river's km range and river side(s) * ordered by type group */ - public static List fetchInfrastructureTypes(final River river, final double kmLo, final double kmHi, + private static List fetchInfrastructureTypeList(final River river, final double kmLo, final double kmHi, final AttributeKey riverside) { final Session session = SessionHolder.HOLDER.get(); @@ -240,7 +254,7 @@ + " WHERE (river=:river)" + " AND (id IN (SELECT v.infrastructure.id FROM InfrastructureValue v" + " WHERE (v.station BETWEEN (:kmLo - 0.0001) AND (:kmHi + 0.0001))" - + InfrastructureValue.getRiversideClause(riverside, "v", "attr_id") + + InfrastructureValue.getRiversideClause(riverside, "v.", "attr_id") + "))" + " ORDER BY group, type"); query.setParameter("river", river); diff -r 63bbd5e45839 -r 26e113e8224f backend/src/main/java/org/dive4elements/river/model/sinfo/InfrastructureValue.java --- a/backend/src/main/java/org/dive4elements/river/model/sinfo/InfrastructureValue.java Thu Oct 10 16:08:47 2019 +0200 +++ b/backend/src/main/java/org/dive4elements/river/model/sinfo/InfrastructureValue.java Thu Oct 10 17:11:54 2019 +0200 @@ -12,6 +12,7 @@ import java.io.Serializable; import java.util.List; +import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; @@ -148,29 +149,49 @@ } /** - * Selects from the database the infrastructure values of a km range of a river and a river side + * Selects from the database the infrastructure values of a km range of a river and a group/type/river-side selection */ - public static List getValues(final River river, final double kmLo, final double kmHi, final AttributeKey riverside) { + public static List getValues(final River river, final double kmLo, final double kmHi, final AttributeKey riverside, + final Set groupTypes) { final Session session = SessionHolder.HOLDER.get(); - final Query query = session.createQuery("FROM InfrastructureValue v" - + " WHERE (v.infrastructure.river=:river)" - + " AND (v.station BETWEEN :kmLo - 0.0001 AND :kmHi + 0.0001)" - + getRiversideClause(riverside, "v", "attr_id") - + " ORDER BY v.station, v.attribute.id"); + final Query query = session.createQuery("FROM InfrastructureValue" + + " WHERE (infrastructure.river=:river)" + + " AND (station BETWEEN :kmLo - 0.0001 AND :kmHi + 0.0001)" + + getRiversideClause(riverside, "", "attr_id") + + getGroupTypeClause(groupTypes, "") + + " ORDER BY station, attribute.id"); query.setParameter("river", river); query.setParameter("kmLo", new Double(kmLo)); query.setParameter("kmHi", new Double(kmHi)); - if (!getRiversideClause(riverside, "v", "attr_id").isEmpty()) + if (!getRiversideClause(riverside, "", "attr_id").isEmpty()) query.setParameter("attr_id", riverside.getId()); return query.list(); } /** - * Gets a query's and-where-clause for a riverside key + * Gets a query's and-where-clause for a set of infrastructure group-type-pairs (as tab-separated strings) */ - public static String getRiversideClause(final AttributeKey riverside, final String tablealias, final String variable) { + private static String getGroupTypeClause(final Set groupTypes, final String tableprefix) { + if (groupTypes.size() == 0) + return ""; + String clause = " AND ("; + String sep = ""; + for (final String groupType : groupTypes) { + clause += sep + "(" + tableprefix + "infrastructure.group.name='" + groupType.split("\t")[0] + "'" + + " AND " + tableprefix + "infrastructure.type.name='" + groupType.split("\t")[1] + "')"; + sep = " OR "; + } + if (sep.length() >= 1) + clause += ")"; + return clause; + } + + /** + * Gets a query's and-where-clause for a riverside key (tableprefix empty or starting with a dot) + */ + public static String getRiversideClause(final AttributeKey riverside, final String tableprefix, final String variable) { if ((riverside == AttributeKey.LEFT) || (riverside == AttributeKey.RIGHT)) - return " AND (" + tablealias + ".attribute.id=:" + variable + ")"; + return " AND (" + tableprefix + "attribute.id=:" + variable + ")"; else return ""; }