# HG changeset patch # User Felix Wolfsteller # Date 1314348558 0 # Node ID 07878836ee0d4760767af61ab0bd316f8a5a1329 # Parent 583314dafdb65cc167228567346432213fa08326 Plot "real" (respecting parameters) W and Q MainValues, yet in wrong scale. flys-artifacts/trunk@2588 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Fri Aug 26 08:07:47 2011 +0000 +++ b/flys-artifacts/ChangeLog Fri Aug 26 08:49:18 2011 +0000 @@ -1,3 +1,25 @@ +2011-08-26 Felix Wolfsteller + + Also plot "W"-MainValues (on vertical axis), take correct parameters, but + do not convert to correct scale (cm vs NN+m). + + * src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java: + Naive attempt at allowing the vertical axis to be sticked at. + + * src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java: + Store Q and W MainValues separately, add them to plot as annotations. + + * src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java: + Serve the MainValues, parameterized on river and location, Q and W. + Removed Facet-implementation. + + * src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java: + Updated Facet Types. + + * src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java: + src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java: + New, trivial facets, extracted from MainValuesArtifact. + 2011-08-26 Ingo Weinzierl * src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: Call diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java Fri Aug 26 08:07:47 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java Fri Aug 26 08:49:18 2011 +0000 @@ -7,21 +7,23 @@ import org.w3c.dom.Document; -import de.intevation.artifactdatabase.state.DefaultFacet; import de.intevation.artifactdatabase.state.Facet; import de.intevation.artifactdatabase.state.DefaultOutput; import de.intevation.artifactdatabase.state.State; +import de.intevation.artifactdatabase.data.StateData; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.ArtifactFactory; -import de.intevation.artifacts.CallContext; import de.intevation.artifacts.CallMeta; import de.intevation.flys.artifacts.model.RiverFactory; -import de.intevation.flys.artifacts.model.FacetTypes; +import de.intevation.flys.artifacts.model.MainValuesWFacet; +import de.intevation.flys.artifacts.model.MainValuesQFacet; +import de.intevation.artifactdatabase.data.DefaultStateData; import de.intevation.flys.artifacts.states.StaticState; import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.MainValue; import de.intevation.flys.model.River; @@ -73,17 +75,18 @@ protected void initialize(Artifact artifact, Object context, CallMeta meta) { logger.debug("MainValuesArtifact.initialize"); WINFOArtifact winfo = (WINFOArtifact) artifact; - River river = winfo.getRiver(); - double location = winfo.getLocations()[0]; // Ort der Abflusskurve - - logger.error("Location: " + location); - Gauge gauge = river.determineGaugeByPosition(location); + //River river = winfo.getRiver(); + double location = winfo.getLocations()[0]; + logger.debug("MainValues.location: " + location); + addData("location", new DefaultStateData("location", null, null, + String.valueOf(location))); + addData("river", winfo.getData("river")); } /** * Get a list containing the one and only State. - * @param context ignored. + * @param context ignored. * @return list with one and only state. */ @Override @@ -128,7 +131,10 @@ else { state = new StaticState(); List fs = new ArrayList(); - fs.add(new MainValuesFacet()); + Facet qfacet = new MainValuesQFacet(); + Facet wfacet = new MainValuesWFacet(); + fs.add(qfacet); + fs.add(wfacet); // TODO check if facets and outputs already exist. // TODO also check, this is usually done in initialize, too. facets.put(state.getID(), fs); @@ -148,67 +154,56 @@ return state; } + /** + * Get the river. + * @todo resolve, this is a duplicate of WINFOArtifact. + */ + public River getRiver() { + StateData dRiver = getData("river"); - public List getMainValues() { - River river = RiverFactory.getRiver("Saar"); - logger.warn("Go to river " + river); - double location = 5.0f; - Gauge gauge = river.determineGaugeByPosition(location); - return gauge.getMainValues(); + return dRiver != null + ? RiverFactory.getRiver((String) dRiver.getValue()) + : null; } + protected Gauge getGauge() { + River river = getRiver(); - /* FACET IMPLEMENTATION */ - // TODO evaluate whether DefaultFacet can do. - static class MainValuesFacet - extends DefaultFacet - implements FacetTypes { - - public MainValuesFacet() { - description = "facet.discharge_curves.mainvalues.description"; - name = COMPUTED_DISCHARGE_MAINVALUES; - //Resources.getMsg(meta, I18N_DESCRIPTION, I18N_DESCRIPTION)); - index = 0; + if (river == null) { + return null; } + double location = Double.parseDouble( + (String)getData("location").getValue()); - /** - * Returns the description of this facet. - * - * @return the description of this facet. - */ - @Override - public String getDescription() { - // TODO remove, is part of DefaultFacet. - return "facet.mainvalues"; + return river.determineGaugeByPosition(location); + } + + public List getMainValuesQ() { + List filteredList = new ArrayList(); + Gauge gauge = getGauge(); + if (gauge != null) { + List orig = gauge.getMainValues(); + for (MainValue mv : orig) { + if (mv.getMainValue().getType().getName().equals("Q")) { + filteredList.add(mv); + } + } } - - - /** - * Returns the data this facet requires. - * - * @param artifact the owner artifact. - * @param context the CallContext (ignored). - * - * @return the data. - */ - @Override - public Object getData(Artifact artifact, CallContext context) { - MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact; - return mvArtifact.getMainValues(); + return filteredList; + } + + public List getMainValuesW() { + List filteredList = new ArrayList(); + Gauge gauge = getGauge(); + if (gauge != null) { + List orig = gauge.getMainValues(); + for (MainValue mv : orig) { + if (mv.getMainValue().getType().getName().equals("W")) { + filteredList.add(mv); + } + } } - - - /** - * Create a deep copy of this Facet. - * @return a deep copy. - */ - @Override - public MainValuesFacet deepCopy() { - MainValuesFacet copy = new MainValuesFacet(); - copy.set(this); - return copy; - } + return filteredList; } - } diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java Fri Aug 26 08:07:47 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java Fri Aug 26 08:49:18 2011 +0000 @@ -15,7 +15,8 @@ String LONGITUDINAL_ANNOTATION = "longitudinal_section.annotations"; String COMPUTED_DISCHARGE_Q = "computed_discharge_curve.q"; - String COMPUTED_DISCHARGE_MAINVALUES = "computed_discharge_curve.mainvalues"; + String COMPUTED_DISCHARGE_MAINVALUES_Q = "computed_discharge_curve.mainvalues.q"; + String COMPUTED_DISCHARGE_MAINVALUES_W = "computed_discharge_curve.mainvalues.w"; String DISCHARGE_CURVE = "discharge_curve.curve"; diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java Fri Aug 26 08:49:18 2011 +0000 @@ -0,0 +1,50 @@ +package de.intevation.flys.artifacts.model; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.CallContext; +import de.intevation.artifactdatabase.state.DefaultFacet; +import de.intevation.flys.artifacts.model.FacetTypes; +import de.intevation.flys.artifacts.MainValuesArtifact; + +/** + * Facet to show Main Q Values. + */ +public class MainValuesQFacet +extends DefaultFacet +implements FacetTypes { + + /** Trivial Constructor. */ + public MainValuesQFacet() { + //Resources.getMsg(meta, I18N_DESCRIPTION, I18N_DESCRIPTION)); + description = "facet.discharge_curves.mainvalues.description"; + name = COMPUTED_DISCHARGE_MAINVALUES_Q; + index = 0; + } + + + /** + * Returns the data this facet requires. + * + * @param artifact the owner artifact. + * @param context the CallContext (ignored). + * + * @return the data. + */ + @Override + public Object getData(Artifact artifact, CallContext context) { + MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact; + return mvArtifact.getMainValuesQ(); + } + + + /** + * Create a deep copy of this Facet. + * @return a deep copy. + */ + @Override + public MainValuesQFacet deepCopy() { + MainValuesQFacet copy = new MainValuesQFacet(); + copy.set(this); + return copy; + } +} diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java Fri Aug 26 08:49:18 2011 +0000 @@ -0,0 +1,51 @@ +package de.intevation.flys.artifacts.model; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.CallContext; +import de.intevation.artifactdatabase.state.DefaultFacet; +import de.intevation.flys.artifacts.model.FacetTypes; +import de.intevation.flys.artifacts.MainValuesArtifact; + +/** + * Facet to show Main W Values. + */ +public class MainValuesWFacet +extends DefaultFacet +implements FacetTypes { + + /** Trivial Constructor. */ + public MainValuesWFacet() { + //Resources.getMsg(meta, I18N_DESCRIPTION, I18N_DESCRIPTION)); + description = "facet.discharge_curves.mainvalues.description"; + name = COMPUTED_DISCHARGE_MAINVALUES_W; + index = 0; + } + + + /** + * Returns the data this facet requires. + * + * @param artifact the owner artifact. + * @param context the CallContext (ignored). + * + * @return the data. + */ + @Override + public Object getData(Artifact artifact, CallContext context) { + MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact; + return mvArtifact.getMainValuesW(); + } + + + /** + * Create a deep copy of this Facet. + * @return a deep copy. + */ + @Override + public MainValuesWFacet deepCopy() { + MainValuesWFacet copy = new MainValuesWFacet(); + copy.set(this); + return copy; + } +} + diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java Fri Aug 26 08:07:47 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java Fri Aug 26 08:49:18 2011 +0000 @@ -1,5 +1,4 @@ package de.intevation.flys.exports; - import org.apache.log4j.Logger; import java.util.ArrayList; @@ -12,7 +11,6 @@ import org.jfree.data.xy.XYSeries; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.XYPlot; -import org.jfree.ui.TextAnchor; import de.intevation.artifacts.Artifact; @@ -21,6 +19,7 @@ import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.model.FacetTypes; import de.intevation.flys.artifacts.model.WQKms; + import de.intevation.flys.jfree.StickyAxisAnnotation; import de.intevation.flys.model.MainValue; @@ -51,14 +50,21 @@ public static final String I18N_CHART_TITLE_DEFAULT = "Abflusskurve"; public static final String I18N_YAXIS_LABEL_DEFAULT = "W [NN + m]"; - /** List of MainValues (Annotations in plot). */ - protected static List mainValues; + /** List of W MainValues (Annotations in plot). */ + protected static List mainValuesW; + + /** List of Q MainValues (Annotations in plot). */ + protected static List mainValuesQ; + + // TODO Add pseudodataseries for having mainvalue-text in legend. + // TODO Let theme pass through to annotations-facets. /** Trivial Constructor. */ public ComputedDischargeCurveGenerator () { super(); - mainValues = new ArrayList(); + mainValuesQ = new ArrayList(); + mainValuesW = new ArrayList(); } @@ -94,14 +100,22 @@ logger.debug("ComputedDischargeCurveGenerator.doOut: " + name); + if (name == null) { + logger.warn("Broken facet in computed discharge out generation."); + return; + } + FLYSArtifact flys = (FLYSArtifact) artifact; Facet f = flys.getNativeFacet(facet); if (name.equals(COMPUTED_DISCHARGE_Q)) { doQOut((WQKms) f.getData(artifact, context), attr); } - else if (name.equals(COMPUTED_DISCHARGE_MAINVALUES)) { - doMainValueAnnotations(f.getData(artifact, context), attr); + else if (name.equals(COMPUTED_DISCHARGE_MAINVALUES_Q)) { + doMainValueWAnnotations(f.getData(artifact, context), attr); + } + else if (name.equals(COMPUTED_DISCHARGE_MAINVALUES_W)) { + doMainValueQAnnotations(f.getData(artifact, context), attr); } else { logger.warn("Unknown facet type for computed discharge: " + name); @@ -111,10 +125,20 @@ /** - * Add MainValues as annotations to plot. + * Store W MainValues as annotations for later plotting. */ - protected void doMainValueAnnotations(Object o, Document theme) { - this.mainValues = (List) o; + protected void doMainValueWAnnotations(Object o, Document theme) { + logger.debug("ComputedDischargeCurveGenerator set W MainValues."); + this.mainValuesW = (List) o; + } + + + /** + * Store Q MainValues as annotations for later plotting. + */ + protected void doMainValueQAnnotations(Object o, Document theme) { + logger.debug("ComputedDischargeCurveGenerator set Q MainValues."); + this.mainValuesQ = (List) o; } @@ -136,27 +160,19 @@ */ protected void redoAnnotations(XYPlot plot, ValueAxis axis) { plot.clearAnnotations(); - ValueAxis yAxis = plot.getRangeAxis(); - float posY = 140.f; - if (yAxis != null) { - posY = (float) yAxis.getRange().getLowerBound(); - // Add some (2%) space between Text and axis. - // TODO have all the position logic in StickyAxisAnnotation - // (then merge LongitudinalSectioNGenerator). - posY += 0.02f * (yAxis.getRange().getUpperBound() - - yAxis.getRange().getLowerBound()); + // Add all MainValues as annotations. + for (MainValue mv: mainValuesQ) { + float pos = mv.getValue().floatValue(); + String text = mv.getMainValue().getName(); + StickyAxisAnnotation ta = new StickyAxisAnnotation(text, pos, + StickyAxisAnnotation.SimpleAxis.X_AXIS); + plot.getRenderer().addAnnotation(ta); } - // Add all MainValues as annotations. - // TODO Implement and handle second facet for annotations on - // vertical axis. - for (MainValue mv: mainValues) { - if (mv.getMainValue().getType().getName() == "W") { - continue; - } - float posX = mv.getValue().floatValue(); - + for (MainValue mv: mainValuesW) { + float pos = mv.getValue().floatValue(); String text = mv.getMainValue().getName(); - StickyAxisAnnotation ta = new StickyAxisAnnotation(text, posX, posY); + StickyAxisAnnotation ta = new StickyAxisAnnotation(text, pos, + StickyAxisAnnotation.SimpleAxis.Y_AXIS); plot.getRenderer().addAnnotation(ta); } } diff -r 583314dafdb6 -r 07878836ee0d flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java --- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java Fri Aug 26 08:07:47 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java Fri Aug 26 08:49:18 2011 +0000 @@ -11,7 +11,6 @@ import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.util.LineUtilities; -import org.jfree.text.TextUtilities; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.entity.XYAnnotationEntity; @@ -19,6 +18,10 @@ import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.plot.Plot; +import org.jfree.data.Range; + +import org.jfree.text.TextUtilities; + import org.jfree.ui.RectangleEdge; import org.jfree.ui.TextAnchor; @@ -43,6 +46,9 @@ /** Which axis to stick to. */ protected SimpleAxis stickyAxis = SimpleAxis.X_AXIS; + /** The 1-dimensional position of this annotation. */ + protected float pos; + /** * Trivial constructor. @@ -50,20 +56,39 @@ * @param text Text to display. * @param x X-position in dataspace (typical horizontal, in km). * @param y Y-position in dataspace (typical vertical, in m). + * @deprecated */ public StickyAxisAnnotation(String text, float x, float y) { super(text, x, y); setStickyAxis(SimpleAxis.X_AXIS); } + + /** + * Constructor with given explicit axis. + * @param text the text to display. + * @param pos the position at which to draw the text and mark. + * @param stickyAxis the axis at which to stick (and to which 'pos' is + * relative). + */ + public StickyAxisAnnotation(String text, float pos, SimpleAxis stickAxis) { + super(text, pos, pos); + setStickyAxis(stickAxis); + this.pos = pos; + } + + /** + * Legacy-Constructor. + * @deprecated + */ public StickyAxisAnnotation(String text, float x, float y, SimpleAxis stickAxis) { super(text, x, y); setStickyAxis(stickAxis); + this.pos = x; } - /** * Sets the "sticky axis" (whether to draw annotations at the * X- or the Y-Axis. @@ -76,6 +101,10 @@ this.setRotationAngle(270f * (Math.PI / 180f)); this.setRotationAnchor(TextAnchor.CENTER_LEFT); this.setTextAnchor(TextAnchor.CENTER_LEFT); + } else { + this.setRotationAngle(0f * (Math.PI / 180f)); + this.setRotationAnchor(TextAnchor.CENTER_LEFT); + this.setTextAnchor(TextAnchor.CENTER_LEFT); } } @@ -131,15 +160,28 @@ g2.setPaint(this.paint); g2.setStroke(this.stroke); */ - j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge); - double rangeLow = rangeAxis.getRange().getLowerBound(); - // Line ends at 1.5% of full distance. - j2DY2 = (float) rangeAxis.valueToJava2D( - (1f - 0.015f) * rangeLow + 0.015f * - rangeAxis.getRange().getUpperBound(), - dataArea, rangeEdge); - j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge); - j2DX2 = j2DX1; + if (this.stickyAxis == SimpleAxis.X_AXIS) { + j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge); + double rangeLow = rangeAxis.getRange().getLowerBound(); + // Line ends at 1.5% of full distance. + j2DY2 = (float) rangeAxis.valueToJava2D( + (1f - 0.015f) * rangeLow + 0.015f * + rangeAxis.getRange().getUpperBound(), + dataArea, rangeEdge); + j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge); + j2DX2 = j2DX1; + } else { + j2DX1 = (float) RectangleEdge.coordinate(dataArea, rangeEdge); + Range domainRange = domainAxis.getRange(); + double rangeLow = domainRange.getLowerBound(); + // Line ends at 1.5% of full distance. + j2DX2 = (float) domainAxis.valueToJava2D( + (1f - 0.015f) * rangeLow + 0.015f * + domainRange.getUpperBound(), + dataArea, domainEdge); + j2DY1 = (float) rangeAxis.valueToJava2D(pos, dataArea, rangeEdge); + j2DY2 = j2DY1; + } Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2); @@ -187,10 +229,29 @@ plot.getDomainAxisLocation(), orientation); RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation( plot.getRangeAxisLocation(), orientation); - float anchorX = (float) domainAxis.valueToJava2D( - getX(), dataArea, domainEdge); - float anchorY = (float) rangeAxis.valueToJava2D( - getY(), dataArea, rangeEdge); + float anchorX = 0f; + float anchorY = 0.0f; + if (this.stickyAxis == SimpleAxis.X_AXIS) { + // Text starts at 1.5% of full distance. + float rangeLow = (float) rangeAxis.getRange().getLowerBound(); + float y = rangeLow + 0.02f * ((float) + rangeAxis.getRange().getUpperBound() - rangeLow); + setY(y); + + anchorX = (float) domainAxis.valueToJava2D( + getX(), dataArea, domainEdge); + anchorY = (float) rangeAxis.valueToJava2D( + getY(), dataArea, rangeEdge); + } else { + float rangeLow = (float) domainAxis.getRange().getLowerBound(); + float x = rangeLow + 0.02f * ((float) + domainAxis.getRange().getUpperBound() - rangeLow); + setX(x); + anchorX = (float) domainAxis.valueToJava2D( + getX(), dataArea, domainEdge); + anchorY = (float) rangeAxis.valueToJava2D( + getY(), dataArea, rangeEdge); + } if (orientation == PlotOrientation.HORIZONTAL) { float tempAnchor = anchorX; anchorX = anchorY;