# HG changeset patch # User Ingo Weinzierl # Date 1337157447 0 # Node ID 4c00cf83fff1fa1b839e8b0be32d297a5d7a9165 # Parent c553d4fa3957d7fa8989ac1f8f0a14dea717855c Added state, calculation and csv exporter for MINFO flow velociy calculation. flys-artifacts/trunk@4418 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/ChangeLog --- 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 + + * 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 * src/main/java/de/intevation/flys/artifacts/HYKArtifact.java, diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/doc/conf/artifacts/minfo.xml --- 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 @@ + + + + + + + + + + + + + + + + diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/doc/conf/conf.xml --- 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 @@ de.intevation.flys.exports.HistoricalDischargeCurveGenerator de.intevation.flys.exports.HistoricalDischargeCurveInfoGenerator de.intevation.flys.exports.HistoricalDischargeCurveExporter + de.intevation.flys.exports.FlowVelocityExporter de.intevation.flys.exports.ReportGenerator de.intevation.flys.exports.ReportGenerator diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java --- 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 : diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java --- /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 zones = getDischargeZones(mainIds, totalIds); + List models = getFlowVelocityModels(artifact, zones); + + return buildCalculationResult(artifact, models); + } + + + protected List getDischargeZones( + int[] mainIds, + int[] totalIds + ) { + List zones = new ArrayList(); + + 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 getFlowVelocityModels( + MINFOArtifact artifact, + List zones + ) { + River river = FLYSUtils.getRiver(artifact); + + List models = new ArrayList(); + + for (DischargeZone zone: zones) { + List 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 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 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 : diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityData.java --- /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(); + } +} diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FlowVelocityState.java --- /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 facets, + Object old + ) { + logger.debug("FlowVelocityState.computeAdvance"); + + List newFacets = new ArrayList(); + + 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 : diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/src/main/java/de/intevation/flys/exports/FlowVelocityExporter.java --- /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 Ingo Weinzierl + */ +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 data; + + + public void init(Document request, OutputStream out, CallContext cc) { + super.init(request, out, cc); + data = new ArrayList(); + } + + + @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 : diff -r c553d4fa3957 -r 4c00cf83fff1 flys-artifacts/src/main/java/de/intevation/flys/utils/Formatter.java --- 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 :