Mercurial > dive4elements > river
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 |