[Dive4elements-commits] [PATCH 04 of 12] Rework ATWriter/Exporter
Wald Commits
scm-commit at wald.intevation.org
Wed Jun 12 17:47:17 CEST 2013
# HG changeset patch
# User Andre Heinecke <aheinecke at intevation.de>
# Date 1371046048 -7200
# Node ID 152e1ba8e5bdfe00fc88967f1ffc26421d6c1a5e
# Parent 5fda7065b74a9228a7020e7a3fb66c565f803db1
Rework ATWriter/Exporter
- Make the write function static as both data and gauge information
is necessary for writing.
- Use the rivers WST unit for the gauge datum
- Handle the case that we are at a gauge
- Differentiate between calculated values
- Always work with w in CM and thus avoid double number format problems
diff -r 5fda7065b74a -r 152e1ba8e5bd artifacts/src/main/java/org/dive4elements/river/exports/ATExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ATExporter.java Wed Jun 12 16:02:33 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ATExporter.java Wed Jun 12 16:07:28 2013 +0200
@@ -85,15 +85,6 @@
return;
}
- ATWriter at;
- try {
- at = new ATWriter(data);
- }
- catch (IllegalArgumentException iae) {
- logger.error("creating ATWriter failed", iae);
- throw new IOException(iae);
- }
-
River river = RiverUtils.getRiver(master);
RangeAccess rangeAccess = new RangeAccess(master);
double[] kms = rangeAccess.getLocations();
@@ -103,7 +94,8 @@
// at gauge.
TimeInterval interval =
gauge.fetchMasterDischargeTable().getTimeInterval();
- at.write(
+ ATWriter.write(
+ data,
new OutputStreamWriter(out, DEFAULT_ENCODING),
context.getMeta(),
river.getName(),
@@ -111,11 +103,12 @@
gauge.getName(),
gauge.getDatum(),
interval.getStartTime(),
- false);
+ river.getWstUnit().getName());
}
else {
// at km
- at.write(
+ ATWriter.write(
+ data,
new OutputStreamWriter(out),
context.getMeta(),
river.getName(),
@@ -123,7 +116,7 @@
null,
null,
null,
- true);
+ river.getWstUnit().getName());
}
}
diff -r 5fda7065b74a -r 152e1ba8e5bd artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java Wed Jun 12 16:02:33 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java Wed Jun 12 16:07:28 2013 +0200
@@ -46,30 +46,124 @@
public static final String I18N_AT_GAUGE_HEADER =
"export.discharge.curve.at.gauge.header";
+ public static final String I18N_AT_CALC_GAUGE_HEADER =
+ "export.discharge.curve.at.gauge.calc.header";
+
public static final String EMPTY = " ";
- protected double minW;
- protected double maxW;
- protected double minQ;
- protected double maxQ;
-
- protected UnivariateRealFunction qFunc;
-
- public ATWriter() {
+ public static double getQ(int w, UnivariateRealFunction qFunc) {
+ try {
+ double val = qFunc.value(w);
+ return val;
+ }
+ catch (FunctionEvaluationException aode) {
+ // should not happen
+ logger.error("spline interpolation failed", aode);
+ return Double.NaN;
+ }
}
- public ATWriter(WQ wq) throws IllegalArgumentException {
+ public static void printQ(PrintWriter out, double q) {
+ String format;
+ if (q < 1d) format = " % 8.3f";
+ else if (q < 10d) format = " % 8.2f";
+ else if (q < 100d) format = " % 8.1f";
+ else {
+ format = " % 8.0f";
+ if (q > 1000d) q = Math.rint(q/10d)*10d;
+ }
+ out.printf(Locale.US, format, q);
+ }
+
+ protected static void printCalculatedGaugeHeader(
+ PrintWriter out,
+ CallMeta callMeta,
+ String river,
+ double km,
+ String gName,
+ BigDecimal datum,
+ Date date,
+ String unit
+ ) {
+ out.print("*" + Resources.getMsg(
+ callMeta,
+ I18N_AT_CALC_GAUGE_HEADER,
+ I18N_AT_CALC_GAUGE_HEADER,
+ new Object[] { river, gName, datum, unit } ));
+ out.print("\r\n");
+ }
+
+ protected static void printGaugeHeader(
+ PrintWriter out,
+ CallMeta callMeta,
+ String river,
+ double km,
+ String gName,
+ BigDecimal datum,
+ Date date,
+ String unit
+ ) {
+ DateFormat f = DateFormat.getDateInstance(DateFormat.MEDIUM,
+ Resources.getLocale(callMeta));
+ out.print("*" + Resources.getMsg(
+ callMeta,
+ I18N_AT_GAUGE_HEADER,
+ I18N_AT_GAUGE_HEADER,
+ new Object[] { river, gName, f.format(date), datum, unit} ));
+ out.print("\r\n");
+ }
+
+ protected static void printHeader(
+ PrintWriter out,
+ CallMeta callMeta,
+ String river,
+ double km
+ ) {
+ out.print("*" + Resources.getMsg(
+ callMeta,
+ I18N_AT_HEADER,
+ I18N_AT_HEADER,
+ new Object[] { river, km } ));
+ out.print("\r\n");
+ }
+
+ public static void write(
+ WQ values,
+ Writer writer,
+ CallMeta meta,
+ String river,
+ double km,
+ String gName,
+ BigDecimal datum,
+ Date date,
+ String unit)
+ throws IOException
+ {
+ int minW;
+ int maxW;
+ double minQ;
+ double maxQ;
+
+ UnivariateRealFunction qFunc;
+
+ WQ wq = WQ.getFixedWQforExportAtGauge(values, datum);
+
+ // If we converted to centimeter we know that the WQ table is
+ // calculated because of the assumption that all calculations
+ // are in Meter and only the discharge tables data is in meter.
+ boolean isCalculation = wq.getReferenceSystem() != values.getReferenceSystem();
int [] bounds = wq.longestIncreasingWRangeIndices();
if (logger.isDebugEnabled()) {
- logger.debug("exporting w between indices " +
- bounds[0] + " and " + bounds[1] + " (" +
- wq.getW(bounds[0]) + ", " + wq.getW(bounds[1]));
+ logger.debug("exporting " + (isCalculation ? "calculated " : "") +
+ "w between indices " + bounds[0] + " and " + bounds[1] + " (" +
+ (int)Math.ceil(wq.getW(bounds[0])) + ", " +
+ (int)Math.floor(wq.getW(bounds[1]))+ ")");
}
if (bounds[1]-bounds[0] < 1) { // Only first w can be written out.
- minW = maxW = wq.getW(bounds[0]);
+ minW = maxW = (int)Math.round(wq.getW(bounds[0]));
minQ = maxQ = wq.getQ(bounds[0]);
// constant function
qFunc = new PolynomialFunction(new double [] { minQ });
@@ -89,117 +183,50 @@
? new LinearInterpolator().interpolate(ws, qs)
: new SplineInterpolator().interpolate(ws, qs);
- minW = wq.getW(bounds[0]);
- maxW = wq.getW(bounds[1]);
+ minW = (int)Math.ceil(wq.getW(bounds[0]));
+ maxW = (int)Math.floor(wq.getW(bounds[1]));
minQ = wq.getQ(bounds[0]);
maxQ = wq.getQ(bounds[1]);
- }
-
- public double getQ(double w) {
-
- try {
- return qFunc.value(w);
- }
- catch (FunctionEvaluationException aode) {
- // should not happen
- logger.warn("spline interpolation failed", aode);
- return w <= minW ? minQ : maxQ;
- }
- }
-
- public static void printQ(PrintWriter out, double q) {
- String format;
- if (q < 1d) format = " % 8.3f";
- else if (q < 10d) format = " % 8.2f";
- else if (q < 100d) format = " % 8.1f";
- else {
- format = " % 8.0f";
- if (q > 1000d) q = Math.rint(q/10d)*10d;
- }
- out.printf(Locale.US, format, q);
- }
-
-
- protected static void printGaugeHeader(
- PrintWriter out,
- CallMeta callMeta,
- String river,
- double km,
- String gName,
- BigDecimal datum,
- Date date
- ) {
- DateFormat f = DateFormat.getDateInstance();
- out.print("*" + Resources.getMsg(
- callMeta,
- I18N_AT_GAUGE_HEADER,
- I18N_AT_GAUGE_HEADER,
- new Object[] { river, gName, f.format(date), datum } ));
- out.print("\r\n");
- }
-
- protected static void printHeader(
- PrintWriter out,
- CallMeta callMeta,
- String river,
- double km
- ) {
- out.print("*" + Resources.getMsg(
- callMeta,
- I18N_AT_HEADER,
- I18N_AT_HEADER,
- new Object[] { river, km } ));
- out.print("\r\n");
- }
-
- public void write(
- Writer writer,
- CallMeta meta,
- String river,
- double km,
- String gName,
- BigDecimal datum,
- Date date,
- boolean wOutUnitIsMeter)
- throws IOException
- {
PrintWriter out = new PrintWriter(writer);
// A header is required, because the desktop version of FLYS will skip
// the first row.
if (gName != null) {
- printGaugeHeader(out, meta, river, km, gName, datum, date);
+ printGaugeHeader(out, meta, river, km, gName, datum, date, unit);
+ if (isCalculation) {
+ printCalculatedGaugeHeader(out, meta, river, km, gName, datum, date, unit);
+ }
}
else {
printHeader(out, meta, river, km);
}
- double rest = (minW * 100.0) % 10.0;
+ int rest = minW % 10;
- double startW = Math.rint((minW - rest*0.01)*10.0)*0.1;
+ int startW = minW - rest;
if (logger.isDebugEnabled()) {
logger.debug("startW: " + startW);
logger.debug("rest: " + rest);
+ logger.debug("maxW: " + maxW);
}
int col = 0;
- for (double w = startW; w <= maxW; w += 0.01) {
+ for (int w = startW; w < maxW; w++) {
if (col == 0) {
- if (wOutUnitIsMeter) {
- // For some crazy reason W's at a gauge should be in the
- // unit but W's exported elsewhere should be in Meter
- out.printf(Locale.US, "%5.2f", w);
- } else {
- out.printf(Locale.US, "%8d", (int)Math.round(w * 100d));
- }
+ out.printf(Locale.US, "%8d", w);
}
if (w < minW) {
out.print(EMPTY);
- }
- else {
- printQ(out, getQ(w));
+ } else {
+ double actQ = getQ(w, qFunc);
+ if (Double.isNaN(actQ)) {
+ // Can't happen™
+ break;
+ } else {
+ printQ(out, actQ);
+ }
}
if (++col >= COLUMNS) {
More information about the Dive4elements-commits
mailing list