Mercurial > dive4elements > river
changeset 2702:4c00cf83fff1
Added state, calculation and csv exporter for MINFO flow velociy calculation.
flys-artifacts/trunk@4418 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Wed, 16 May 2012 08:37:27 +0000 |
parents | c553d4fa3957 |
children | aa4391648a05 |
files | flys-artifacts/ChangeLog flys-artifacts/doc/conf/artifacts/minfo.xml flys-artifacts/doc/conf/conf.xml flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityData.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FlowVelocityState.java flys-artifacts/src/main/java/de/intevation/flys/exports/FlowVelocityExporter.java flys-artifacts/src/main/java/de/intevation/flys/utils/Formatter.java |
diffstat | 9 files changed, 533 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog Wed May 16 08:21:02 2012 +0000 +++ b/flys-artifacts/ChangeLog Wed May 16 08:37:27 2012 +0000 @@ -1,3 +1,33 @@ +2012-05-16 Ingo Weinzierl <ingo@intevation.de> + + * doc/conf/artifacts/minfo.xml: Added new state and csv export for MINFO flow + velocity calculation. + + * doc/conf/conf.xml: Registered a new CSV exporter for flow velocity + values. + + * src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java: + New calculation for MINFO flow velocity. Actually, this is no + calculation but a bundling of data. + + * src/main/java/de/intevation/flys/artifacts/model/FlowVelocityData.java: + New model class that is used to store flow velocity relevant data. + + * src/main/java/de/intevation/flys/artifacts/states/FlowVelocityState.java: + New state that triggers the FlowVelocityCalculation and creates new + facets. Currently, only a CSV Facet is created. + + * src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java: Added + methods to retrieve the IDs of main channels and total channels for the + flow velocity calculation. + + * src/main/java/de/intevation/flys/utils/Formatter.java: New formatters + that are used in CSV exporter for flow velocity. + + * src/main/java/de/intevation/flys/exports/FlowVelocityExporter.java: New + concrete subclasses of AbstractExporter that currently implements the + path to export FlowVelocityData as CSV. + 2012-05-16 Ingo Weinzierl <ingo@intevation.de> * src/main/java/de/intevation/flys/artifacts/HYKArtifact.java,
--- a/flys-artifacts/doc/conf/artifacts/minfo.xml Wed May 16 08:21:02 2012 +0000 +++ b/flys-artifacts/doc/conf/artifacts/minfo.xml Wed May 16 08:37:27 2012 +0000 @@ -36,6 +36,24 @@ <data name="main.channel" type="intoptions"/> </state> + <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition"> + <from state="state.minfo.dischargestate"/> + <to state="state.minfo.flow_velocity"/> + </transition> + + <state id="state.minfo.flow_velocity" description="state.minfo.flow_velocity" state="de.intevation.flys.artifacts.states.FlowVelocityState" helpText="help.minfo.flowvelocity"> + <outputmodes> + <outputmode name="flow_velocity_export" description="output.flow_velocity_export" mime-type="text/plain" type="export"> + <facets> + <facet name="csv" description="facet.flow_velocity_export.csv" /> + <!-- + <facet name="pdf" description="facet.historical_discharge.pdf" /> + --> + </facets> + </outputmode> + </outputmodes> + </state> + </states> </artifact>
--- a/flys-artifacts/doc/conf/conf.xml Wed May 16 08:21:02 2012 +0000 +++ b/flys-artifacts/doc/conf/conf.xml Wed May 16 08:37:27 2012 +0000 @@ -227,6 +227,7 @@ <output-generator name="historical_discharge">de.intevation.flys.exports.HistoricalDischargeCurveGenerator</output-generator> <output-generator name="historical_discharge_chartinfo">de.intevation.flys.exports.HistoricalDischargeCurveInfoGenerator</output-generator> <output-generator name="historical_discharge_export">de.intevation.flys.exports.HistoricalDischargeCurveExporter</output-generator> + <output-generator name="flow_velocity_export">de.intevation.flys.exports.FlowVelocityExporter</output-generator> <!-- Error report generators. --> <output-generator name="discharge_longitudinal_section_report">de.intevation.flys.exports.ReportGenerator</output-generator> <output-generator name="waterlevel_report">de.intevation.flys.exports.ReportGenerator</output-generator>
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java Wed May 16 08:21:02 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java Wed May 16 08:37:27 2012 +0000 @@ -244,5 +244,29 @@ logger.warn("MINFOArtifact.getInitialFacetActivity: not implemented!"); return 1; } + + + public int[] getMainChannels() { + String data = getDataAsString("main.channel"); + + if (data == null) { + logger.warn("No 'main.channel' parameter specified!"); + return null; + } + + return FLYSUtils.intArrayFromString(data); + } + + + public int[] getTotalChannels() { + String data = getDataAsString("total.channel"); + + if (data == null) { + logger.warn("No 'total.channel' parameter specified!"); + return null; + } + + return FLYSUtils.intArrayFromString(data); + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java Wed May 16 08:37:27 2012 +0000 @@ -0,0 +1,155 @@ +package de.intevation.flys.artifacts.model; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import de.intevation.flys.model.DischargeZone; +import de.intevation.flys.model.FlowVelocityModel; +import de.intevation.flys.model.FlowVelocityModelValue; +import de.intevation.flys.model.River; + +import de.intevation.flys.artifacts.MINFOArtifact; +import de.intevation.flys.artifacts.model.FlowVelocityData; +import de.intevation.flys.utils.FLYSUtils; + + +public class FlowVelocityCalculation extends Calculation { + + private static final Logger logger = + Logger.getLogger(FlowVelocityCalculation.class); + + + public CalculationResult calculate(MINFOArtifact artifact) { + logger.info("FlowVelocityCalculation.calculate"); + + int[] mainIds = artifact.getMainChannels(); + int[] totalIds = artifact.getTotalChannels(); + + if (logger.isDebugEnabled()) { + logger.debug("Artifact '" + artifact.identifier() + "' contains:"); + if (mainIds != null) { + logger.debug(" " + mainIds.length + " main channel ids"); + } + + if (totalIds != null) { + logger.debug(" " + totalIds.length + " total channel ids"); + } + } + + List<DischargeZone> zones = getDischargeZones(mainIds, totalIds); + List<FlowVelocityModel> models = getFlowVelocityModels(artifact, zones); + + return buildCalculationResult(artifact, models); + } + + + protected List<DischargeZone> getDischargeZones( + int[] mainIds, + int[] totalIds + ) { + List<DischargeZone> zones = new ArrayList<DischargeZone>(); + + if (mainIds != null) { + for (int id: mainIds) { + DischargeZone zone = DischargeZone.getDischargeZoneById(id); + + if (zone != null) { + zones.add(zone); + } + } + } + + if (totalIds != null) { + for (int id: totalIds) { + DischargeZone zone = DischargeZone.getDischargeZoneById(id); + + if (zone != null) { + zones.add(zone); + } + } + } + + return zones; + } + + + protected List<FlowVelocityModel> getFlowVelocityModels( + MINFOArtifact artifact, + List<DischargeZone> zones + ) { + River river = FLYSUtils.getRiver(artifact); + + List<FlowVelocityModel> models = new ArrayList<FlowVelocityModel>(); + + for (DischargeZone zone: zones) { + List<FlowVelocityModel> model = + FlowVelocityModel.getModels(river, zone); + + if (model != null) { + models.addAll(model); + } + } + + return models; + } + + + protected void prepareData( + FlowVelocityData data, + FlowVelocityModel model, + double kmLo, + double kmHi + ) { + List<FlowVelocityModelValue> values = + FlowVelocityModelValue.getValues(model, kmLo, kmHi); + + logger.debug("Found " + values.size() + " values for model."); + + for (FlowVelocityModelValue value: values) { + data.addKM(value.getStation().doubleValue()); + data.addQ(value.getQ().doubleValue()); + data.addVTotal(value.getTotalChannel().doubleValue()); + data.addVMain(value.getMainChannel().doubleValue()); + data.addTauMain(value.getShearStress().doubleValue()); + } + + DischargeZone zone = model.getDischargeZone(); + String lo = zone.getLowerDischarge(); + String hi = zone.getUpperDischarge(); + + if (lo.equals(hi)) { + data.setZone(lo); + } + else { + data.setZone(lo + " - " + hi); + } + } + + + protected CalculationResult buildCalculationResult( + MINFOArtifact artifact, + List<FlowVelocityModel> models + ) { + double kmLo = artifact.getDataAsDouble("ld_from"); + double kmHi = artifact.getDataAsDouble("ld_to"); + + logger.debug("Prepare data for km range: " + kmLo + " - " + kmHi); + + FlowVelocityData[] data = new FlowVelocityData[models.size()]; + + for (int i = 0, n = models.size(); i < n; i++) { + FlowVelocityData d = new FlowVelocityData(); + + prepareData(d, models.get(i), kmLo, kmHi); + + data[i] = d; + } + + logger.debug("Calculation contains " + data.length + " data items."); + + return new CalculationResult(data, this); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityData.java Wed May 16 08:37:27 2012 +0000 @@ -0,0 +1,78 @@ +package de.intevation.flys.artifacts.model; + +import java.io.Serializable; + +import gnu.trove.TDoubleArrayList; + + +public class FlowVelocityData implements Serializable { + + private TDoubleArrayList km; + private TDoubleArrayList vMain; + private TDoubleArrayList vTotal; + private TDoubleArrayList tauMain; + private TDoubleArrayList q; + private String zone; + + + protected FlowVelocityData() { + this.km = new TDoubleArrayList(); + this.vMain = new TDoubleArrayList(); + this.vTotal = new TDoubleArrayList(); + this.tauMain = new TDoubleArrayList(); + this.q = new TDoubleArrayList(); + } + + + public void addKM(double km) { + this.km.add(km); + } + + public double getKM(int idx) { + return km.get(idx); + } + + public void addVMain(double vMain) { + this.vMain.add(vMain); + } + + public double getVMain(int idx) { + return vMain.get(idx); + } + + public void addVTotal(double vTotal) { + this.vTotal.add(vTotal); + } + + public double getVTotal(int idx) { + return vTotal.get(idx); + } + + public void addTauMain(double tauMain) { + this.tauMain.add(tauMain); + } + + public double getTauMain(int idx) { + return tauMain.get(idx); + } + + public void addQ(double q) { + this.q.add(q); + } + + public double getQ(int idx) { + return q.get(idx); + } + + public void setZone(String zone) { + this.zone = zone; + } + + public String getZone() { + return zone; + } + + public int size() { + return km.size(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FlowVelocityState.java Wed May 16 08:37:27 2012 +0000 @@ -0,0 +1,71 @@ +package de.intevation.flys.artifacts.states; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import de.intevation.artifactdatabase.state.Facet; + +import de.intevation.artifacts.CallContext; + +import de.intevation.flys.artifacts.FLYSArtifact; +import de.intevation.flys.artifacts.MINFOArtifact; +import de.intevation.flys.artifacts.model.CalculationResult; +import de.intevation.flys.artifacts.model.DataFacet; +import de.intevation.flys.artifacts.model.FacetTypes; +import de.intevation.flys.artifacts.model.FlowVelocityCalculation; +import de.intevation.flys.artifacts.model.FlowVelocityData; + + +public class FlowVelocityState extends DefaultState implements FacetTypes { + + private static Logger logger = Logger.getLogger(FlowVelocityState.class); + + + @Override + public Object computeAdvance( + FLYSArtifact artifact, + String hash, + CallContext context, + List<Facet> facets, + Object old + ) { + logger.debug("FlowVelocityState.computeAdvance"); + + List<Facet> newFacets = new ArrayList<Facet>(); + + CalculationResult res = old instanceof CalculationResult + ? (CalculationResult) old + : new FlowVelocityCalculation().calculate((MINFOArtifact) artifact); + + if (facets == null || res == null) { + return res; + } + + FlowVelocityData[] data = (FlowVelocityData[]) res.getData(); + + logger.debug("Calculated " + data.length + " FlowVelocityData objects"); + + String id = getID(); + + for (FlowVelocityData d: data) { + logger.error("TODO: Implement Facet creation for chart!"); + + } + + Facet csv = new DataFacet( + CSV, "CSV data", ComputeType.ADVANCE, hash, id); + + // TODO ADD PDF FACET + + newFacets.add(csv); + + logger.debug("Created " + newFacets.size() + " new Facets."); + + facets.addAll(newFacets); + + return res; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/FlowVelocityExporter.java Wed May 16 08:37:27 2012 +0000 @@ -0,0 +1,123 @@ +package de.intevation.flys.exports; + +import java.io.OutputStream; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Document; + +import org.apache.log4j.Logger; + +import au.com.bytecode.opencsv.CSVWriter; + +import de.intevation.artifacts.CallContext; + +import de.intevation.flys.artifacts.model.CalculationResult; +import de.intevation.flys.artifacts.model.FlowVelocityData; +import de.intevation.flys.utils.Formatter; + + +/** + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class FlowVelocityExporter extends AbstractExporter { + + private static final Logger logger = + Logger.getLogger(FlowVelocityExporter.class); + + + public static final String CSV_KM = + "export.flow_velocity.csv.header.km"; + + public static final String CSV_V_TOTAL = + "export.flow_velocity.csv.header.v_total"; + + public static final String CSV_V_MAIN = + "export.flow_velocity.csv.header.v_main"; + + public static final String CSV_TAU_MAIN = + "export.flow_velocity.csv.header.tau_main"; + + public static final String CSV_Q = + "export.flow_velocity.csv.header.q"; + + public static final String CSV_LOCATIONS = + "export.flow_velocity.csv.header.locations"; + + + protected List<FlowVelocityData[]> data; + + + public void init(Document request, OutputStream out, CallContext cc) { + super.init(request, out, cc); + data = new ArrayList<FlowVelocityData[]>(); + } + + + @Override + protected void addData(Object d) { + if (d instanceof CalculationResult) { + d = ((CalculationResult) d).getData(); + + if (d instanceof FlowVelocityData[]) { + logger.debug("Add new data of type FlowVelocityData"); + data.add((FlowVelocityData[]) d); + } + } + } + + + @Override + protected void writeCSVData(CSVWriter writer) { + logger.info("FlowVelocityExporter.writeCSVData"); + logger.debug("CSV gets " + data.size() + " FlowVelocityData objects."); + + writeCSVHeader(writer); + + for (FlowVelocityData[] d: data) { + data2CSV(writer, d); + } + } + + + protected void writeCSVHeader(CSVWriter writer) { + writer.writeNext(new String[] { + msg(CSV_KM, CSV_KM), + msg(CSV_V_TOTAL, CSV_V_TOTAL), + msg(CSV_V_MAIN, CSV_V_MAIN), + msg(CSV_TAU_MAIN, CSV_TAU_MAIN), + msg(CSV_Q, CSV_Q), + msg(CSV_LOCATIONS, CSV_LOCATIONS) + }); + } + + + protected void data2CSV(CSVWriter writer, FlowVelocityData[] fData) { + logger.debug("Add next FlowVelocityData to CSV"); + + for (FlowVelocityData data: fData) { + for (int i = 0, n = data.size(); i < n; i++) { + NumberFormat kmF = Formatter.getFlowVelocityKM(context); + NumberFormat valF = Formatter.getFlowVelocityValues(context); + NumberFormat qF = Formatter.getFlowVelocityQ(context); + + writer.writeNext(new String[] { + kmF.format(data.getKM(i)), + valF.format(data.getVMain(i)), + valF.format(data.getVTotal(i)), + valF.format(data.getTauMain(i)), + qF.format(data.getQ(i)) + "=" + data.getZone(), + "TODO: add Location for km"// TODO Add Locations + }); + } + } + } + + + @Override + protected void writePDF(OutputStream out) { + logger.error("TODO: Implement FlowVelocityExporter.writePDF"); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/Formatter.java Wed May 16 08:21:02 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/Formatter.java Wed May 16 08:37:27 2012 +0000 @@ -48,6 +48,15 @@ public static final int DURATION_D_MAX_DIGITS = 0; + // FLOW VELOCITY FORMATTER CONSTANTS + public static final int FLOW_VELOCITY_KM_MIN_DIGITS = 3; + public static final int FLOW_VELOCITY_KM_MAX_DIGITS = 3; + public static final int FLOW_VELOCITY_VALUES_MIN_DIGITS = 2; + public static final int FLOW_VELOCITY_VALUES_MAX_DIGITS = 2; + public static final int FLOW_VELOCITY_Q_MIN_DIGITS = 0; + public static final int FLOW_VELOCITY_Q_MAX_DIGITS = 2; + + public static NumberFormat getFormatter(CallMeta m, int min, int max){ Locale locale = Resources.getLocale(m); NumberFormat nf = NumberFormat.getInstance(locale); @@ -233,5 +242,29 @@ CALCULATION_REPORT_KM_MIN_DIGITS, CALCULATION_REPORT_KM_MAX_DIGITS); } + + + public static NumberFormat getFlowVelocityKM(CallContext context) { + return getFormatter( + context, + FLOW_VELOCITY_KM_MIN_DIGITS, + FLOW_VELOCITY_KM_MAX_DIGITS); + } + + + public static NumberFormat getFlowVelocityValues(CallContext context) { + return getFormatter( + context, + FLOW_VELOCITY_VALUES_MIN_DIGITS, + FLOW_VELOCITY_VALUES_MAX_DIGITS); + } + + + public static NumberFormat getFlowVelocityQ(CallContext context) { + return getFormatter( + context, + FLOW_VELOCITY_Q_MIN_DIGITS, + FLOW_VELOCITY_Q_MAX_DIGITS); + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :