comparison artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java @ 6601:5ecc6d4d73f2

Add official fixings to Waterlevel CSV Export (issue1384) This searches the collection for staticwqkms artifacts that contain official data and adds that data to the export. The data is filtered by the calculation range and sorted by the calculation direction.
author Andre Heinecke <aheinecke@intevation.de>
date Thu, 18 Jul 2013 13:16:33 +0200
parents c59a23183bc0
children 90756201c488
comparison
equal deleted inserted replaced
6600:df1140486ba4 6601:5ecc6d4d73f2
32 import net.sf.jasperreports.engine.JasperExportManager; 32 import net.sf.jasperreports.engine.JasperExportManager;
33 import net.sf.jasperreports.engine.JasperFillManager; 33 import net.sf.jasperreports.engine.JasperFillManager;
34 import net.sf.jasperreports.engine.JasperPrint; 34 import net.sf.jasperreports.engine.JasperPrint;
35 import net.sf.jasperreports.engine.JRException; 35 import net.sf.jasperreports.engine.JRException;
36 36
37 import org.dive4elements.artifacts.Artifact;
37 import org.dive4elements.artifacts.CallContext; 38 import org.dive4elements.artifacts.CallContext;
38 import org.dive4elements.artifacts.CallMeta; 39 import org.dive4elements.artifacts.CallMeta;
39 import org.dive4elements.artifacts.common.utils.Config; 40 import org.dive4elements.artifacts.common.utils.Config;
40 41
41 import org.dive4elements.river.model.Gauge; 42 import org.dive4elements.river.model.Gauge;
43 import org.dive4elements.river.artifacts.access.FixRealizingAccess; 44 import org.dive4elements.river.artifacts.access.FixRealizingAccess;
44 import org.dive4elements.river.artifacts.access.RangeAccess; 45 import org.dive4elements.river.artifacts.access.RangeAccess;
45 import org.dive4elements.river.artifacts.FixationArtifact; 46 import org.dive4elements.river.artifacts.FixationArtifact;
46 import org.dive4elements.river.artifacts.D4EArtifact; 47 import org.dive4elements.river.artifacts.D4EArtifact;
47 import org.dive4elements.river.artifacts.WINFOArtifact; 48 import org.dive4elements.river.artifacts.WINFOArtifact;
49 import org.dive4elements.river.artifacts.StaticWQKmsArtifact;
48 import org.dive4elements.river.artifacts.model.CalculationResult; 50 import org.dive4elements.river.artifacts.model.CalculationResult;
49 import org.dive4elements.river.artifacts.model.Segment; 51 import org.dive4elements.river.artifacts.model.Segment;
50 import org.dive4elements.river.artifacts.model.WQCKms; 52 import org.dive4elements.river.artifacts.model.WQCKms;
51 import org.dive4elements.river.artifacts.model.WQKms; 53 import org.dive4elements.river.artifacts.model.WQKms;
52 import org.dive4elements.river.artifacts.model.WKmsJRDataSource; 54 import org.dive4elements.river.artifacts.model.WKmsJRDataSource;
67 69
68 /** The logger used in this exporter.*/ 70 /** The logger used in this exporter.*/
69 private static Logger logger = Logger.getLogger(WaterlevelExporter.class); 71 private static Logger logger = Logger.getLogger(WaterlevelExporter.class);
70 72
71 public static final String FACET_WST = "wst"; 73 public static final String FACET_WST = "wst";
74
75 /* This should be the same as in the StaticWQKmsArtifact */
76 public static final String STATICWQKMSNAME = "staticwqkms";
72 77
73 public static final String CSV_KM_HEADER = 78 public static final String CSV_KM_HEADER =
74 "export.waterlevel.csv.header.km"; 79 "export.waterlevel.csv.header.km";
75 80
76 public static final String CSV_W_HEADER = 81 public static final String CSV_W_HEADER =
132 "außerhalb des gewählten Bezugspegels"; 137 "außerhalb des gewählten Bezugspegels";
133 138
134 public static final String PDF_HEADER_MODE = "export.waterlevel.pdf.mode"; 139 public static final String PDF_HEADER_MODE = "export.waterlevel.pdf.mode";
135 public static final String JASPER_FILE = "export.waterlevel.pdf.file"; 140 public static final String JASPER_FILE = "export.waterlevel.pdf.file";
136 141
137 /** The storage that contains all WQKms objects for the different facets.*/ 142 /** The storage that contains all WQKms objects that are calculated.*/
138 protected List<WQKms[]> data; 143 protected List<WQKms[]> data;
139 144
145 /** The storage that contains official fixings if available.*/
146 protected List<WQKms> officalFixings;
140 147
141 public void init(Document request, OutputStream out, CallContext context) { 148 public void init(Document request, OutputStream out, CallContext context) {
142 logger.debug("WaterlevelExporter.init"); 149 logger.debug("WaterlevelExporter.init");
143 150
144 super.init(request, out, context); 151 super.init(request, out, context);
150 @Override 157 @Override
151 public void generate() 158 public void generate()
152 throws IOException 159 throws IOException
153 { 160 {
154 logger.debug("WaterlevelExporter.generate"); 161 logger.debug("WaterlevelExporter.generate");
162
163 /* Check for official fixings. They should also be included in the
164 * export but only the calculation result is added with addData */
165
166 officalFixings = new ArrayList<WQKms>();
167
168 for (Artifact art: collection.getArtifactsByName(STATICWQKMSNAME, context)) {
169 if (art instanceof StaticWQKmsArtifact) {
170 StaticWQKmsArtifact sart = (StaticWQKmsArtifact) art;
171 if (!sart.isOfficial()) {
172 continue;
173 }
174
175 /* Check that we add the data only once */
176 WQKms toAdd = sart.getWQKms();
177 String newName = toAdd.getName();
178
179 boolean exists = false;
180 for (WQKms wqkm: officalFixings) {
181 /* The same official fixing could be in two
182 artifacts/outs so let's deduplicate */
183 if (wqkm.getName().equals(newName)) {
184 exists = true;
185 }
186 }
187 if (!exists) {
188 officalFixings.add(toAdd);
189 logger.debug("Adding additional offical fixing: " + newName);
190 }
191 }
192 }
155 193
156 if (facet != null && facet.equals(AbstractExporter.FACET_CSV)) { 194 if (facet != null && facet.equals(AbstractExporter.FACET_CSV)) {
157 generateCSV(); 195 generateCSV();
158 } 196 }
159 else if (facet != null && facet.equals(FACET_WST)) { 197 else if (facet != null && facet.equals(FACET_WST)) {
292 = RiverUtils.getWQInputMode((D4EArtifact)master); 330 = RiverUtils.getWQInputMode((D4EArtifact)master);
293 331
294 writeCSVMeta(writer); 332 writeCSVMeta(writer);
295 writeCSVHeader(writer, atGauge, isQ); 333 writeCSVHeader(writer, atGauge, isQ);
296 334
335 Double first = Double.NaN;
336 Double last = Double.NaN;
337
297 for (WQKms[] tmp: data) { 338 for (WQKms[] tmp: data) {
298 for (WQKms wqkms: tmp) { 339 for (WQKms wqkms: tmp) {
299 wQKms2CSV(writer, wqkms, atGauge, isQ); 340 wQKms2CSV(writer, wqkms, atGauge, isQ);
300 } 341 double[] firstLast = wqkms.getFirstLastKM();
301 } 342 if (first.isNaN()) {
302 } 343 /* Initialize */
303 344 first = firstLast[0];
345 last = firstLast[1];
346 }
347 if (firstLast[0] > firstLast[1]) {
348 /* Calculating upstream we assert that it is
349 * impossible that the direction changes during this
350 * loop */
351 first = Math.max(first, firstLast[0]);
352 last = Math.min(last, firstLast[1]);
353 } else if (firstLast[0] < firstLast[1]) {
354 first = Math.min(first, firstLast[0]);
355 last = Math.max(last, firstLast[1]);
356 } else {
357 first = last = firstLast[0];
358 }
359 }
360 }
361 /* Append the official fixing at the bottom */
362 for (WQKms wqkms: officalFixings) {
363 logger.debug("Exporting official fixing fromKM: " + first +
364 " toKM: " + last);
365 /* To handle upstream / downstream and to limit
366 * the officialFixings to the calculation distance
367 * we create a new wqkms object here and fill it only
368 * with the relevant data. */
369 if (first.isNaN() || last.isNaN()) {
370 logger.warn("Exporting official fixing without valid first/last.");
371 wQKms2CSV(writer, wqkms, atGauge, isQ);
372 return;
373 }
374 int firstIdx = first > last ? wqkms.size() - 1 : 0;
375 int lastIdx = first > last ? 0 : wqkms.size() -1;
376 WQKms filtered = new WQKms (wqkms.size());
377 filtered.setReferenceSystem(wqkms.getReferenceSystem());
378 filtered.setName(wqkms.getName());
379 double [] dp = new double [3];
380
381 if (first > last) {
382 for (int i = wqkms.size() - 1; i >= 0; i--) {
383 dp = wqkms.get(i, dp);
384 if (dp[2] < first && dp[2] > last) {
385 filtered.add(dp[0], dp[1], dp[2]);
386 }
387 }
388 } else {
389 for (int i = 0; i < wqkms.size(); i++) {
390 dp = wqkms.get(i, dp);
391 if (dp[2] < last && dp[2] > first) {
392 filtered.add(dp[0], dp[1], dp[2]);
393 }
394 }
395 }
396 wQKms2CSV(writer, filtered, atGauge, isQ);
397 }
398 }
399 /*
400 private WQKms filterWQKms (wkqm
401 */
304 402
305 protected void writeCSVMeta(CSVWriter writer) { 403 protected void writeCSVMeta(CSVWriter writer) {
306 logger.info("WaterlevelExporter.writeCSVMeta"); 404 logger.info("WaterlevelExporter.writeCSVMeta");
307 405
308 // TODO use Access instead of RiverUtils 406 // TODO use Access instead of RiverUtils

http://dive4elements.wald.intevation.org