mschaefer@9259: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde mschaefer@9259: * Software engineering by mschaefer@9259: * Björnsen Beratende Ingenieure GmbH mschaefer@9259: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@9050: * gernotbelger@9050: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9050: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9050: * documentation coming with Dive4Elements River for details. gernotbelger@9050: */ gernotbelger@9050: gernotbelger@9054: package org.dive4elements.river.artifacts.sinfo.flood_duration; gernotbelger@9050: d@9612: import java.util.HashSet; gernotbelger@9050: import java.util.List; d@9612: import java.util.Set; gernotbelger@9050: gernotbelger@9265: import org.apache.commons.lang.StringUtils; gernotbelger@9050: import org.dive4elements.artifactdatabase.state.Facet; gernotbelger@9050: import org.dive4elements.artifacts.CallContext; gernotbelger@9050: import org.dive4elements.river.artifacts.ChartArtifact; gernotbelger@9050: import org.dive4elements.river.artifacts.D4EArtifact; mschaefer@9176: import org.dive4elements.river.artifacts.model.Calculation; gernotbelger@9050: import org.dive4elements.river.artifacts.model.CalculationResult; gernotbelger@9145: import org.dive4elements.river.artifacts.model.DataFacet; gernotbelger@9050: import org.dive4elements.river.artifacts.model.EmptyFacet; gernotbelger@9145: import org.dive4elements.river.artifacts.model.FacetTypes; mschaefer@9176: import org.dive4elements.river.artifacts.model.ReportFacet; mschaefer@9252: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@9050: import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; gernotbelger@9050: import org.dive4elements.river.artifacts.states.DefaultState; mschaefer@9376: import org.dive4elements.river.model.Attribute.AttributeKey; gernotbelger@9050: mschaefer@9176: /** mschaefer@9176: * Last state of the S-Info flood duration workflow that calculates and outputs the result mschaefer@9176: */ gernotbelger@9054: public class FloodDurationState extends DefaultState { gernotbelger@9050: gernotbelger@9050: private static final long serialVersionUID = 1L; gernotbelger@9050: gernotbelger@9050: /** gernotbelger@9050: * From this state can only be continued trivially. gernotbelger@9050: */ gernotbelger@9050: @Override gernotbelger@9050: protected String getUIProvider() { gernotbelger@9050: return "continue"; gernotbelger@9050: } gernotbelger@9050: gernotbelger@9050: @Override gernotbelger@9050: public Object computeFeed(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) { gernotbelger@9050: if (artifact instanceof ChartArtifact) { gernotbelger@9050: facets.add(new EmptyFacet()); gernotbelger@9050: return null; gernotbelger@9050: } gernotbelger@9050: return compute((SINFOArtifact) artifact, context, hash, facets, old); gernotbelger@9050: } gernotbelger@9050: gernotbelger@9050: @Override gernotbelger@9050: public Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) { gernotbelger@9050: if (artifact instanceof ChartArtifact) { gernotbelger@9050: facets.add(new EmptyFacet()); gernotbelger@9050: return null; gernotbelger@9050: } gernotbelger@9050: return compute((SINFOArtifact) artifact, context, hash, facets, old); gernotbelger@9050: } gernotbelger@9050: gernotbelger@9050: /** gernotbelger@9050: * Compute result or returned object from cache, create facets. gernotbelger@9050: * gernotbelger@9050: * @param old gernotbelger@9050: * Object that was cached. gernotbelger@9050: */ gernotbelger@9050: private Object compute(final SINFOArtifact sinfo, final CallContext context, final String hash, final List facets, final Object old) { gernotbelger@9050: gernotbelger@9050: final CalculationResult res = doCompute(sinfo, context, old); gernotbelger@9050: gernotbelger@9050: if (facets == null) gernotbelger@9050: return res; gernotbelger@9050: gernotbelger@9145: final FloodDurationCalculationResults results = (FloodDurationCalculationResults) res.getData(); gernotbelger@9195: final List resultList = results.getResults(); gernotbelger@9265: gernotbelger@9205: int resultIndex = 0; gernotbelger@9205: int themeCount = 0; d@9612: gernotbelger@9195: for (final FloodDurationCalculationResult result : resultList) { gernotbelger@9145: gernotbelger@9265: if (resultIndex == 0) { gernotbelger@9265: /* we only have one result, but safety first... */ gernotbelger@9265: gernotbelger@9265: /* Setting the valid stations as data to the state, so the NaviChartOutputTab knows what are the valid stations */ gernotbelger@9265: final List validDurationChartKilometers = result.getValidDurationChartKilometers(); gernotbelger@9265: final String validKilometerString = StringUtils.join(validDurationChartKilometers, ','); gernotbelger@9265: sinfo.addStringData("validStations", validKilometerString); gernotbelger@9265: } gernotbelger@9265: mschaefer@9229: final FloodDurationAccess access = new FloodDurationAccess(sinfo); gernotbelger@9205: gernotbelger@9205: final int waterlevelCount = result.getWaterlevelCount(); gernotbelger@9205: gernotbelger@9205: for (int j = 0; j < waterlevelCount; j++) { gernotbelger@9205: mschaefer@9252: // final String waterlevelLabel = result.getMainValueLabel(j); gernotbelger@9205: // FIXME: use label as label for theme gernotbelger@9205: gernotbelger@9215: // final int facetIndex, final int resultIndex, final int dataIndex d@9612: facets.add(FloodDurationProcessor.createMainValueDurationFacet(context, hash, this.id, result, themeCount++, resultIndex, j)); d@9612: facets.add(FloodHeightProcessor.createMainValueHeightFacet(context, hash, this.id, result, themeCount++, resultIndex, j)); mschaefer@9631: facets.add(FloodQProcessor.createMainValueQFacet(context, hash, this.id, result, themeCount++, resultIndex, j)); gernotbelger@9205: mschaefer@9202: } gernotbelger@9145: mschaefer@9252: final String nameW = Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.w"); mschaefer@9252: final String nameQ = Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.q"); d@9612: facets.add(FloodDurationCurveProcessor.createFloodDurationWCurveFacet(context, hash, this.id, result, themeCount++, resultIndex, nameW)); d@9612: facets.add(FloodDurationCurveProcessor.createFloodDurationQCurveFacet(context, hash, this.id, result, themeCount++, resultIndex, nameQ)); mschaefer@9257: if (waterlevelCount >= 1) { d@9612: facets.add(FloodDurationCurveProcessor.createMainValuesWFacet(context, hash, this.id, result, themeCount++, resultIndex, mschaefer@9257: Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.mainw"))); d@9612: facets.add(FloodDurationCurveProcessor.createMainValuesQFacet(context, hash, this.id, result, themeCount++, resultIndex, d@9612: Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.mainq"), null)); mschaefer@9257: } d@9612: d@9612: final AttributeKey choice = access.getRiverside().getAttributeKey(); d@9612: d@9612: for (final AttributeKey riversideC : getRiversides(choice)) { d@9612: facets.add(FloodDurationCurveProcessor.createInfrastructureFacet(context, hash, this.id, result, themeCount++, resultIndex, true, riversideC)); d@9612: d@9612: facets.add(FloodDurationCurveProcessor.createInfrastructureFacet(context, hash, this.id, result, themeCount++, resultIndex, false, riversideC)); mschaefer@9376: } d@9612: mschaefer@9620: final Set infrastructures = result.getInfrastructureMap(); mschaefer@9620: for (final FloodDurationInfrastructureChoice entry : infrastructures) { d@9612: d@9612: facets.add(FloodDurationProcessor.createFloodDurationFacet(context, hash, this.id, result, themeCount++, resultIndex, entry)); d@9612: d@9612: facets.add(FloodHeightProcessor.createFloodHeightFacet(context, hash, this.id, result, themeCount++, resultIndex, entry)); mschaefer@9376: } mschaefer@9252: mschaefer@9176: facets.add(new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id)); mschaefer@9176: facets.add(new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id)); gernotbelger@9195: gernotbelger@9205: resultIndex++; gernotbelger@9145: } gernotbelger@9145: mschaefer@9176: final Calculation report = res.getReport(); mschaefer@9176: if (report.hasProblems()) mschaefer@9176: facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id)); gernotbelger@9050: gernotbelger@9050: return res; gernotbelger@9050: } gernotbelger@9050: d@9612: private Set getRiversides(final AttributeKey choice) { d@9612: final Set usedRiversides = new HashSet<>(); d@9612: if (choice.equals(AttributeKey.LEFT)) d@9612: usedRiversides.add(AttributeKey.LEFT); d@9612: else if (choice.equals(AttributeKey.RIGHT)) d@9612: usedRiversides.add(AttributeKey.RIGHT); d@9612: d@9612: else { d@9612: usedRiversides.add(AttributeKey.RIGHT); d@9612: usedRiversides.add(AttributeKey.LEFT); d@9612: } d@9612: return usedRiversides; d@9612: } d@9612: gernotbelger@9050: private CalculationResult doCompute(final SINFOArtifact sinfo, final CallContext context, final Object old) { gernotbelger@9050: if (old instanceof CalculationResult) gernotbelger@9050: return (CalculationResult) old; gernotbelger@9050: gernotbelger@9067: return new FloodDurationCalculation(context).calculate(sinfo); gernotbelger@9050: } gernotbelger@9050: }