teichmann@5844: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5844: * Software engineering by Intevation GmbH teichmann@5844: * teichmann@5992: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5844: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5992: * documentation coming with Dive4Elements River for details. teichmann@5844: */ teichmann@5844: teichmann@5829: package org.dive4elements.river.importer.parsers; ingo@2828: tom@5689: import java.io.File; tom@5689: import java.io.IOException; ingo@2828: import java.math.BigDecimal; ingo@2828: import java.text.NumberFormat; mschaefer@8991: import java.text.ParseException; ingo@2828: import java.util.ArrayList; ingo@2828: import java.util.List; teichmann@5707: import java.util.TreeSet; ingo@2828: import java.util.regex.Matcher; ingo@2828: import java.util.regex.Pattern; ingo@2828: ingo@2828: import org.apache.log4j.Logger; mschaefer@8989: import org.dive4elements.river.backend.utils.EpsilonComparator; teichmann@5829: import org.dive4elements.river.importer.ImportDischargeZone; teichmann@5829: import org.dive4elements.river.importer.ImportFlowVelocityModel; teichmann@5829: import org.dive4elements.river.importer.ImportFlowVelocityModelValue; mschaefer@8989: import org.dive4elements.river.importer.common.AbstractParser; ingo@2828: ingo@2828: ingo@2828: public class FlowVelocityModelParser extends LineParser { ingo@2828: ingo@2828: private static final Logger log = mschaefer@8989: Logger.getLogger(FlowVelocityModelParser.class); ingo@2828: ingo@2828: private static final Pattern META_REGEX = mschaefer@8989: Pattern.compile(".*Rechnung [unter ]*(.*) \\(Pegel (.*)\\).*"); ingo@2828: ingo@2833: private static final Pattern META_GAUGE = mschaefer@8989: Pattern.compile("(.*) Q=(\\w*)m3/s"); ingo@2833: ingo@2833: private static final Pattern META_MAINVALUE_A = mschaefer@8989: Pattern.compile("([a-zA-Z]+)+(\\d+)*[\\w()]*"); ingo@2833: ingo@2833: private static final Pattern META_MAINVALUE_B = mschaefer@8989: Pattern.compile( mschaefer@8989: "(([a-zA-Z]+)+(\\d+)*)\\s*-\\s*(([a-zA-Z]+)+(\\d+)*\\S*)"); ingo@2833: ingo@2833: private static final Pattern META_MAINVALUE_C = mschaefer@8989: Pattern.compile("([0-9]++)\\s?(\\S*)|([0-9]++,[0-9]++)\\s?(\\S*)"); ingo@2833: ingo@2833: private static final Pattern META_MAINVALUE_D = mschaefer@8989: Pattern.compile( mschaefer@8989: "(([0-9]*)\\s?(\\w*)|([0-9]++,[0-9]++)\\s?(\\w*))\\s*" mschaefer@8989: + "bis (([0-9]*)\\s?(\\S*)|([0-9]++,[0-9]++)\\s?(\\S*))"); ingo@2833: ingo@2833: private static final Pattern META_MAINVALUE_E = mschaefer@8989: Pattern.compile( mschaefer@8989: "(([a-zA-Z]+)+(\\d+)*)\\s*bis (([a-zA-Z]+)+(\\d+)*\\S*)"); ingo@2833: ingo@2828: private static final NumberFormat nf = mschaefer@8989: NumberFormat.getInstance(DEFAULT_LOCALE); ingo@2828: ingo@2828: mschaefer@8989: private final List models; ingo@2828: ingo@2828: private ImportFlowVelocityModel current; ingo@2828: tom@5689: protected String description; tom@5689: teichmann@5707: protected TreeSet kmExists; teichmann@5707: ingo@2828: ingo@2828: public FlowVelocityModelParser() { mschaefer@8989: this.models = new ArrayList<>(); mschaefer@8989: this.kmExists = new TreeSet<>(EpsilonComparator.CMP); ingo@2828: } ingo@2828: ingo@2828: ingo@2828: public List getModels() { mschaefer@8989: return this.models; ingo@2828: } ingo@2828: ingo@2828: @Override mschaefer@8989: public void parse(final File file) throws IOException { mschaefer@8989: this.description = file.getName(); tom@5689: tom@5689: super.parse(file); tom@5689: } tom@5689: tom@5689: @Override ingo@2828: protected void reset() { mschaefer@8989: this.current = new ImportFlowVelocityModel(this.description); mschaefer@8989: this.kmExists.clear(); ingo@2828: } ingo@2828: ingo@2828: ingo@2828: @Override ingo@2828: protected void finish() { mschaefer@8989: this.models.add(this.current); teichmann@7252: // description = null; ingo@2828: } ingo@2828: ingo@2828: ingo@2828: @Override mschaefer@8989: protected void handleLine(final int lineNum, final String line) { ingo@2828: if (line.startsWith(START_META_CHAR)) { ingo@2828: handleMetaLine(stripMetaLine(line)); ingo@2828: } ingo@2828: else { ingo@2828: handleDataLine(line); ingo@2828: } ingo@2828: } ingo@2828: ingo@2828: mschaefer@8989: protected void handleMetaLine(final String line) { mschaefer@8989: final Matcher m = META_REGEX.matcher(line); ingo@2828: ingo@2828: if (m.matches()) { mschaefer@8989: final String mainValueStr = m.group(1); teichmann@7376: log.debug("mainValueStr = '" + mainValueStr + "'"); mschaefer@8989: final String gaugeStr = m.group(2); ingo@2828: mschaefer@8989: final Object[] valueData = handleMainValueString(mainValueStr); mschaefer@8989: final Object[] gaugeData = handleGaugeString(gaugeStr); ingo@2828: ingo@2833: if (valueData == null || valueData.length < 2) { tom@6386: log.warn("skip invalid MainValue part in '" + line + "'"); ingo@2833: return; ingo@2833: } ingo@2833: ingo@2833: if (gaugeData == null || gaugeData.length < 2) { tom@6386: log.warn("skip invalid gauge part in '" + line + "'"); ingo@2833: return; ingo@2833: } ingo@2833: ingo@2833: if (log.isDebugEnabled()) { ingo@2833: log.debug("Found meta information:"); ingo@2833: log.debug(" Gauge: " + gaugeData[0]); ingo@2833: log.debug(" Value: " + gaugeData[1]); ingo@2833: log.debug(" Lower: " + valueData[0]); ingo@2833: log.debug(" upper: " + valueData[1]); ingo@2833: } ingo@2833: mschaefer@8989: this.current.setDischargeZone(new ImportDischargeZone( mschaefer@8989: (String) gaugeData[0], mschaefer@8989: (BigDecimal) gaugeData[1], mschaefer@8989: (String) valueData[0], mschaefer@8989: (String) valueData[1] mschaefer@8989: )); ingo@2828: } ingo@2828: } ingo@2828: ingo@2828: mschaefer@8989: protected Object[] handleMainValueString(final String mainValueStr) { mschaefer@8989: final Matcher mA = META_MAINVALUE_A.matcher(mainValueStr.trim()); ingo@2833: if (mA.matches()) { teichmann@7376: log.debug("mainValueStr matches META_MAINVALUE_A"); mschaefer@8989: final String name = mA.group(0); ingo@2833: ingo@2833: return new Object[] { name, name }; ingo@2833: } ingo@2833: mschaefer@8989: final Matcher mB = META_MAINVALUE_B.matcher(mainValueStr.trim()); ingo@2833: if (mB.matches()) { teichmann@7376: log.debug("mainValueStr matches META_MAINVALUE_B"); mschaefer@8989: final String lower = mB.group(1); mschaefer@8989: final String upper = mB.group(4); ingo@2833: ingo@2833: return new Object[] { lower, upper }; ingo@2833: } ingo@2833: mschaefer@8989: final Matcher mC = META_MAINVALUE_C.matcher(mainValueStr.trim()); ingo@2833: if (mC.matches()) { teichmann@7376: log.debug("mainValueStr matches META_MAINVALUE_C"); mschaefer@8989: final String facA = mC.group(1); mschaefer@8989: final String nameA = mC.group(2); mschaefer@8989: final String facB = mC.group(3); mschaefer@8989: final String nameB = mC.group(4); ingo@2833: mschaefer@8989: final String fac = facA != null ? facA : facB; mschaefer@8989: final String name = nameA != null ? nameA : nameB; ingo@2833: mschaefer@8989: final String mainValue = fac + " " + name; ingo@2833: ingo@2833: return new Object[] { mainValue, mainValue }; ingo@2833: } ingo@2833: mschaefer@8989: final Matcher mD = META_MAINVALUE_D.matcher(mainValueStr.trim()); ingo@2833: if (mD.matches()) { teichmann@7376: log.debug("mainValueStr matches META_MAINVALUE_D"); mschaefer@8989: final String loFacA = mD.group(2); mschaefer@8989: final String loNameA = mD.group(3); mschaefer@8989: final String loFacB = mD.group(4); mschaefer@8989: final String loNameB = mD.group(5); ingo@2833: mschaefer@8989: final String upFacA = mD.group(7); mschaefer@8989: final String upNameA = mD.group(8); mschaefer@8989: final String upFacB = mD.group(9); mschaefer@8989: final String upNameB = mD.group(10); ingo@2833: mschaefer@8989: final String loFac = loFacA != null ? loFacA : loFacB; mschaefer@8989: final String loName = loNameA != null ? loNameA : loNameB; ingo@2833: mschaefer@8989: final String upFac = upFacA != null ? upFacA : upFacB; mschaefer@8989: final String upName = upNameA != null ? upNameA : upNameB; ingo@2833: mschaefer@8989: final String loMainValue = loFac + " " + loName; mschaefer@8989: final String upMainValue = upFac + " " + upName; ingo@2833: ingo@2833: return new Object[] { loMainValue, upMainValue }; ingo@2833: } ingo@2833: mschaefer@8989: final Matcher mE = META_MAINVALUE_E.matcher(mainValueStr.trim()); ingo@2833: if (mE.matches()) { teichmann@7376: log.debug("mainValueStr matches META_MAINVALUE_E"); mschaefer@8989: final String lower = mE.group(1); mschaefer@8989: final String upper = mE.group(4); ingo@2833: ingo@2833: return new Object[] { lower, upper }; ingo@2833: } ingo@2833: mschaefer@8989: log.debug("mainValueStr not matched"); ingo@2833: return null; ingo@2833: } ingo@2833: ingo@2833: mschaefer@8989: protected Object[] handleGaugeString(final String gaugeStr) { mschaefer@8989: final Matcher m = META_GAUGE.matcher(gaugeStr); ingo@2833: ingo@2833: if (m.matches()) { mschaefer@8989: final String name = m.group(1); mschaefer@8989: final String qStr = m.group(2); ingo@2833: ingo@2833: try { ingo@2833: return new Object[] { mschaefer@8989: name, mschaefer@8989: AbstractParser.parseDecimal(qStr) }; ingo@2833: } mschaefer@8991: catch (final ParseException pe) { tom@5490: log.warn("Could not parse Q value: '" + qStr + "'"); ingo@2833: } ingo@2833: } ingo@2833: ingo@2833: return null; ingo@2833: } ingo@2833: ingo@2833: mschaefer@8989: protected void handleDataLine(final String line) { mschaefer@8989: final String[] cols = line.split(SEPERATOR_CHAR); ingo@2828: ingo@2828: if (cols.length < 5) { ingo@2828: log.warn("skip invalid data line: '" + line + "'"); ingo@2828: return; ingo@2828: } ingo@2828: ingo@2828: try { mschaefer@8989: final BigDecimal km = AbstractParser.parseDecimal(cols[0]); teichmann@5707: mschaefer@8989: final Double key = Double.valueOf(km.doubleValue()); teichmann@5707: mschaefer@8989: if (this.kmExists.contains(key)) { tom@6256: log.warn("duplicate station '" + km + "': -> ignored"); teichmann@5707: return; teichmann@5707: } teichmann@5707: mschaefer@8989: final BigDecimal q = AbstractParser.parseDecimal(cols[1]); mschaefer@8989: final BigDecimal total = AbstractParser.parseDecimal(cols[2]); mschaefer@8989: final BigDecimal main = AbstractParser.parseDecimal(cols[3]); mschaefer@8989: final BigDecimal stress = AbstractParser.parseDecimal(cols[4]); ingo@2828: mschaefer@8989: this.current.addValue(new ImportFlowVelocityModelValue(km, q, total, main, stress)); teichmann@5707: mschaefer@8989: this.kmExists.add(key); ingo@2828: } mschaefer@8991: catch (final ParseException pe) { tom@5490: log.warn("Unparseable flow velocity values:", pe); ingo@2828: } ingo@2828: } ingo@2828: } ingo@2828: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :